summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-10-31 13:29:10 +0000
committerMartin Odersky <odersky@gmail.com>2011-10-31 13:29:10 +0000
commit1f3fe09a786b389adcc1425cfd166bc6c3e361b0 (patch)
treebe678b8a7c7621de2cdffc56750e812e5932fb32
parent2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a (diff)
downloadscala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.tar.gz
scala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.tar.bz2
scala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.zip
Closes #5127. Review by extempore.
-rw-r--r--src/compiler/scala/reflect/internal/Types.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--test/files/pos/t5127.scala8
3 files changed, 22 insertions, 10 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala
index f82e025a38..bc739e58a9 100644
--- a/src/compiler/scala/reflect/internal/Types.scala
+++ b/src/compiler/scala/reflect/internal/Types.scala
@@ -3342,12 +3342,16 @@ A type's typeSymbol should never be inspected directly.
case TypeRef(pre, sym, args) =>
val pre1 = this(pre)
//val args1 = args mapConserve this(_)
- val args1 = if (args.isEmpty) args
- else {
- val tparams = sym.typeParams
- if (tparams.isEmpty) args
- else mapOverArgs(args, tparams)
- }
+ val args1 =
+ if (args.isEmpty)
+ args
+ else if (variance == 0) // fast & safe path: don't need to look at typeparams
+ args mapConserve this
+ else {
+ val tparams = sym.typeParams
+ if (tparams.isEmpty) args
+ else mapOverArgs(args, tparams)
+ }
if ((pre1 eq pre) && (args1 eq args)) tp
else copyTypeRef(tp, pre1, coevolveSym(pre, pre1, sym), args1)
case ThisType(_) => tp
@@ -3394,7 +3398,7 @@ A type's typeSymbol should never be inspected directly.
if (bounds1 eq bounds) tp
else BoundedWildcardType(bounds1.asInstanceOf[TypeBounds])
case rtp @ RefinedType(parents, decls) =>
- val parents1 = parents mapConserve (this)
+ val parents1 = parents mapConserve this
val decls1 = mapOver(decls)
//if ((parents1 eq parents) && (decls1 eq decls)) tp
//else refinementOfClass(tp.typeSymbol, parents1, decls1)
@@ -3441,7 +3445,7 @@ A type's typeSymbol should never be inspected directly.
// throw new Error("mapOver inapplicable for " + tp);
}
- def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] =
+ protected final def mapOverArgs(args: List[Type], tparams: List[Symbol]): List[Type] =
map2Conserve(args, tparams) { (arg, tparam) =>
val v = variance
if (tparam.isContravariant) variance = -variance
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 54a3e12ce0..f9c5e843b1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3271,10 +3271,10 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}}
val tp = tpt1.tpe
- val sym = tp.typeSymbol
+ val sym = tp.typeSymbol.initialize
if (sym.isAbstractType || sym.hasAbstractFlag)
error(tree.pos, sym + " is abstract; cannot be instantiated")
- else if (!( tp == sym.initialize.thisSym.tpe // when there's no explicit self type -- with (#3612) or without self variable
+ else if (!( tp == sym.thisSym.tpe // when there's no explicit self type -- with (#3612) or without self variable
// sym.thisSym.tpe == tp.typeOfThis (except for objects)
|| narrowRhs(tp) <:< tp.typeOfThis
|| phase.erasedTypes
diff --git a/test/files/pos/t5127.scala b/test/files/pos/t5127.scala
new file mode 100644
index 0000000000..c562025302
--- /dev/null
+++ b/test/files/pos/t5127.scala
@@ -0,0 +1,8 @@
+package foo {
+ trait Abstract1[C <: Abstract2[C]]
+ trait Abstract2[C <: Abstract2[C]] extends Abstract1[C]
+ class Parametrized1[T] extends Abstract1[Parametrized2[T]] {
+ def bar(a: AnyRef) { a match { case d: Parametrized1[_] => println("ok") } }
+ }
+ class Parametrized2[T] extends Parametrized1[T] with Abstract2[Parametrized2[T]]
+}