diff options
Diffstat (limited to 'src/compiler/scala/reflect/internal/Types.scala')
-rw-r--r-- | src/compiler/scala/reflect/internal/Types.scala | 82 |
1 files changed, 42 insertions, 40 deletions
diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index 67c858356c..a839e44182 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -749,12 +749,18 @@ trait Types extends api.Types { self: SymbolTable => def substThis(from: Symbol, to: Symbol): Type = substThis(from, to.thisType) - /** Performs both substThis and substSym in one traversal. + /** Performs both substThis and substSym, in that order. + * + * [JZ] Reverted `SubstThisAndSymMap` from 334872, which was not the same as + * `substThis(from, to).substSym(symsFrom, symsTo)`. + * + * `SubstThisAndSymMap` performs a breadth-first map over this type, which meant that + * symbol substitution occured before `ThisType` substitution. Consequently, in substitution + * of a `SingleType(ThisType(`from`), sym), symbols were rebound to `from` rather than `to`. */ - def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type = { + def substThisAndSym(from: Symbol, to: Type, symsFrom: List[Symbol], symsTo: List[Symbol]): Type = if (symsFrom eq symsTo) substThis(from, to) - else new SubstThisAndSymMap(from, to, symsFrom, symsTo) apply this - } + else substThis(from, to).substSym(symsFrom, symsTo) /** Returns all parts of this type which satisfy predicate `p` */ def filter(p: Type => Boolean): List[Type] = new FilterTypeCollector(p) collect this @@ -4518,13 +4524,6 @@ trait Types extends api.Types { self: SymbolTable => case _ => mapOver(tp) } } - class SubstThisAndSymMap(fromThis: Symbol, toThis: Type, fromSyms: List[Symbol], toSyms: List[Symbol]) - extends SubstSymMap(fromSyms, toSyms) { - override def apply(tp: Type): Type = tp match { - case ThisType(sym) if sym == fromThis => apply(toThis) - case _ => super.apply(tp) - } - } class SubstWildcardMap(from: List[Symbol]) extends TypeMap { def apply(tp: Type): Type = try { @@ -6572,47 +6571,50 @@ trait Types extends api.Types { self: SymbolTable => else Some(typeRef(pre, sym, List(lub(args)))) } } - else { - val args = map2(sym.typeParams, argss.transpose) { (tparam, as) => - if (depth == 0) { - if (tparam.variance == variance) { - // Take the intersection of the upper bounds of the type parameters - // rather than falling all the way back to "Any", otherwise we end up not - // conforming to bounds. - val bounds0 = sym.typeParams map (_.info.bounds.hi) filterNot (_.typeSymbol == AnyClass) - if (bounds0.isEmpty) AnyClass.tpe - else intersectionType(bounds0 map (b => b.asSeenFrom(tps.head, sym))) + else transposeSafe(argss) match { + case None => + // transpose freaked out because of irregular argss + // catching just in case (shouldn't happen, but also doesn't cost us) + // [JZ] It happens: see SI-5683. + debuglog("transposed irregular matrix!?" +(tps, argss)) + None + case Some(argsst) => + val args = map2(sym.typeParams, argsst) { (tparam, as) => + if (depth == 0) { + if (tparam.variance == variance) { + // Take the intersection of the upper bounds of the type parameters + // rather than falling all the way back to "Any", otherwise we end up not + // conforming to bounds. + val bounds0 = sym.typeParams map (_.info.bounds.hi) filterNot (_.typeSymbol == AnyClass) + if (bounds0.isEmpty) AnyClass.tpe + else intersectionType(bounds0 map (b => b.asSeenFrom(tps.head, sym))) + } + else if (tparam.variance == -variance) NothingClass.tpe + else NoType } - else if (tparam.variance == -variance) NothingClass.tpe - else NoType - } - else { - if (tparam.variance == variance) lub(as, decr(depth)) - else if (tparam.variance == -variance) glb(as, decr(depth)) else { - val l = lub(as, decr(depth)) - val g = glb(as, decr(depth)) - if (l <:< g) l + if (tparam.variance == variance) lub(as, decr(depth)) + else if (tparam.variance == -variance) glb(as, decr(depth)) + else { + val l = lub(as, decr(depth)) + val g = glb(as, decr(depth)) + if (l <:< g) l else { // Martin: I removed this, because incomplete. Not sure there is a good way to fix it. For the moment we // just err on the conservative side, i.e. with a bound that is too high. // if(!(tparam.info.bounds contains tparam)) //@M can't deal with f-bounds, see #2251 - val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l) - capturedParams += qvar - qvar.tpe + val qvar = commonOwner(as) freshExistential "" setInfo TypeBounds(g, l) + capturedParams += qvar + qvar.tpe + } } } } - } - if (args contains NoType) None - else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))) + if (args contains NoType) None + else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))) } } catch { case ex: MalformedType => None - case ex: IndexOutOfBoundsException => // transpose freaked out because of irregular argss - // catching just in case (shouldn't happen, but also doesn't cost us) - debuglog("transposed irregular matrix!?"+ (tps, argss)) - None } case SingleType(_, sym) :: rest => val pres = tps map (_.prefix) |