diff options
author | Martin Odersky <odersky@gmail.com> | 2011-10-31 13:29:10 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-10-31 13:29:10 +0000 |
commit | 1f3fe09a786b389adcc1425cfd166bc6c3e361b0 (patch) | |
tree | be678b8a7c7621de2cdffc56750e812e5932fb32 /src | |
parent | 2d3fe5733cbc6bcf06892c8ee3cb19f7987f6b6a (diff) | |
download | scala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.tar.gz scala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.tar.bz2 scala-1f3fe09a786b389adcc1425cfd166bc6c3e361b0.zip |
Closes #5127. Review by extempore.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 20 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 4 |
2 files changed, 14 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 |