diff options
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 | ||||
-rw-r--r-- | test/files/pos/t5127.scala | 8 |
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]] +} |