diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-08-27 11:40:28 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-08-27 16:26:16 +0200 |
commit | 3eebc99432075fdffabf8859df3dc8b2ded8df9c (patch) | |
tree | 0b4f4413976a999f1cff1cbe28f0486693f74fa7 /test/files/pos/t7785.scala | |
parent | b67fecd0f178ea70e4fa9823c408e52437426403 (diff) | |
download | scala-3eebc99432075fdffabf8859df3dc8b2ded8df9c.tar.gz scala-3eebc99432075fdffabf8859df3dc8b2ded8df9c.tar.bz2 scala-3eebc99432075fdffabf8859df3dc8b2ded8df9c.zip |
SI-7785 Preserve TypeVar suspension through TypeMaps
During `findMember`, TypeVars in `this` are placed into suspended
animation. This is to avoid running into recursive types when
matching members to those in base classes.
However, the mechanism used to do this is superficial, and doesn't
work when TypeVars are copied by TypeMaps. This seems to crop up
when using `AppliedTypeVar` with higher-kinded type vars.
In the enclosed test case, the cyclic type led to a SOE in
CommonOwnerMap.
This commit allows a TypeVar to delegate its `suspended` attribute
to the TypeVar from which it was copied. This is done in
`TypeVar#applyArgs`, which is called by:
// TypeMap#mapOver
case tv@TypeVar(_, constr) =>
if (constr.instValid) this(constr.inst)
else tv.applyArgs(mapOverArgs(tv.typeArgs, tv.params))
We should review the other places this is called to make sure
that it make sense to link in this way:
Types#appliedType
TypeVar#normalize
Diffstat (limited to 'test/files/pos/t7785.scala')
-rw-r--r-- | test/files/pos/t7785.scala | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/test/files/pos/t7785.scala b/test/files/pos/t7785.scala new file mode 100644 index 0000000000..1de693d137 --- /dev/null +++ b/test/files/pos/t7785.scala @@ -0,0 +1,34 @@ +import scala.language._ + +trait R[+Repr] + +trait TraversableOps { + implicit val R: R[Nothing] = ??? + + // Removing the implicit parameter in both fixes the crash + // removing it into one only gives a valid compiler error. + trait OpsDup1[Repr] { + def force(implicit bf: R[Repr]): Any + } + + trait Ops[Repr] extends OpsDup1[Repr] { + def force(implicit bf: R[Repr], dummy: DummyImplicit): Any + } + + implicit def ct2ops[T, C[+X]](t: C[T]): + Ops[C[T]] + + def force[T](t: Option[T]) = + // ct2ops(t).force + t.force //Fails compilation on 2.10.2. + + + /* To get a closer look at the crash: + :power + val foo = typeOf[C].member(TermName("foo")) + val pt = analyzer.HasMember(TermName("force")) + val instantiated = foo.info.finalResultType.instantiateTypeParams(foo.typeParams, foo.typeParams.map(TypeVar(_))) + instantiated <:< pt + */ + def foo[T, C[+X]]: Ops[C[T]] +} |