From 6f42bd6881f9b1a6fa25d744cded38f53058538c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 8 Dec 2013 22:37:38 +0100 Subject: SI-8046 Only use fast TypeRef#baseTypeSeq with concrete base types We can only compute the base type sequence (BTS) of a `TypeRef` by element-wise transforming the BTS of the referenced symbol if there are no abstract types in its BTS type symbols. In the now-working test case, `pos/t8046.scala`, the difference between the old and new calculation of the BTS is: this = Three.this.Alias[Int] sym.info.baseTypeSeq = BTS(One.this.Op[A],Any) mapped BTS = BTS(Three.this.Op[Int],Any) full BTS = BTS(Three.this.Op[Int],Int => Int,Object,Any) The change to account for PolyType in ArgsTypeRef#transform is now needed to avoid the full BTS of: BTS(Three.this.Op[A],A => A,Object,Any) Interestingly, everything actually works without that change. --- src/reflect/scala/reflect/internal/Types.scala | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index e483fa6ba8..44381e4ab2 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1999,7 +1999,9 @@ trait Types if (sym.typeParams.size != args.size) devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args") - asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args) + val GenPolyType(tparams, result) = asSeenFromOwner(tp) + assert((tparams eq Nil) || tparams == sym.typeParams, (tparams, sym.typeParams)) + result.instantiateTypeParams(sym.typeParams, args) } // note: does not go through typeRef. There's no need to because @@ -2309,7 +2311,14 @@ trait Types } thisInfo.decls } - protected[Types] def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform + protected[Types] def baseTypeSeqImpl: BaseTypeSeq = + if (sym.info.baseTypeSeq exists (_.typeSymbolDirect.isAbstractType)) + // SI-8046 base type sequence might have more elements in a subclass, we can't map it element wise. + transform(sym.info).baseTypeSeq + else + // Optimization: no abstract types, we can compute the BTS of this TypeRef as an element-wise map + // of the BTS of the referenced symbol. + sym.info.baseTypeSeq map transform override def baseTypeSeq: BaseTypeSeq = { val cache = baseTypeSeqCache -- cgit v1.2.3