From 52379b66f96bf7e0ca22f7835ddb06c58d94d4a0 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 22 Jan 2014 16:05:29 +0100 Subject: SI-8170 Fix regression in TypeRef#transform w. PolyTypes Regressed in SI-8046 / edc9edb7, by my hand. At the time, I noticed the problem: transform wasn't accounting for the potential Poly-Type-ness of its argument, and this would lead to under-substituted types. The commit comment of edc9edb7 shows an example. But the remedy wasn't the right one. The root problem is that a TypeMap over a PolyType can return one with cloned type parameter symbols, which means we've lose the ability to substitute the type arguments into the result. This commit detects up front whether the type-under-transform is a PolyType with the current TypeRef's type parameters, and just runs the `asSeenFrom` over its result type. --- src/reflect/scala/reflect/internal/Types.scala | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 9ddaea4c62..209d31c5af 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1988,12 +1988,23 @@ trait Types // too little information is known to determine its kind, and // it later turns out not to have kind *. See SI-4070. Only // logging it for now. - if (sym.typeParams.size != args.size) + val tparams = sym.typeParams + if (tparams.size != args.size) devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args") - - val GenPolyType(tparams, result) = asSeenFromOwner(tp) - assert((tparams eq Nil) || tparams == sym.typeParams, (tparams, sym.typeParams)) - result.instantiateTypeParams(sym.typeParams, args) + def asSeenFromInstantiated(tp: Type) = + asSeenFromOwner(tp).instantiateTypeParams(tparams, args) + // If we're called with a poly type, and we were to run the `asSeenFrom`, over the entire + // type, we can end up with new symbols for the type parameters (clones from TypeMap). + // The subsequent substitution of type arguments would fail. This problem showed up during + // the fix for SI-8046, however the solution taken there wasn't quite right, and led to + // SI-8170. + // + // Now, we detect the PolyType before both the ASF *and* the substitution, and just operate + // on the result type. + tp match { + case PolyType(`tparams`, result) => PolyType(tparams, asSeenFromInstantiated(result)) + case _ => asSeenFromInstantiated(tp) + } } // note: does not go through typeRef. There's no need to because -- cgit v1.2.3