diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-01-22 16:05:29 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-01-22 16:05:29 +0100 |
commit | 52379b66f96bf7e0ca22f7835ddb06c58d94d4a0 (patch) | |
tree | 45003ff926db4fa8e5b08eeadb5dd67fa86ef678 /src | |
parent | 115cd16aca35c8b4000b86f4affd4df243202fd2 (diff) | |
download | scala-52379b66f96bf7e0ca22f7835ddb06c58d94d4a0.tar.gz scala-52379b66f96bf7e0ca22f7835ddb06c58d94d4a0.tar.bz2 scala-52379b66f96bf7e0ca22f7835ddb06c58d94d4a0.zip |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 21 |
1 files changed, 16 insertions, 5 deletions
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 |