@@ -839,33 +839,34 @@ object TypeOps:
839
839
}
840
840
}
841
841
842
- /** Gather GADT symbols and `ThisType`s found in `tp2`, ie. the scrutinee. */
842
+ /** Gather GADT symbols and singletons found in `tp2`, ie. the scrutinee. */
843
843
object TraverseTp2 extends TypeTraverser :
844
- val thisTypes = util.HashSet [ ThisType ]()
845
- val gadtSyms = new mutable.ListBuffer [Symbol ]
844
+ val singletons = util.HashMap [ Symbol , SingletonType ]()
845
+ val gadtSyms = new mutable.ListBuffer [Symbol ]
846
846
847
- def traverse (tp : Type ) = {
847
+ def traverse (tp : Type ) = try
848
848
val tpd = tp.dealias
849
849
if tpd ne tp then traverse(tpd)
850
850
else tp match
851
- case tp : ThisType if ! tp.tref.symbol.isStaticOwner && ! thisTypes.contains(tp) =>
852
- thisTypes + = tp
851
+ case tp : ThisType if ! singletons.contains( tp.tref.symbol) && ! tp.tref.symbol.isStaticOwner =>
852
+ singletons(tp.tref.symbol) = tp
853
853
traverseChildren(tp.tref)
854
- case tp : TypeRef if tp.symbol.isAbstractOrParamType =>
854
+ case tp : TermRef if tp.symbol.is(Param ) =>
855
+ singletons(tp.typeSymbol) = tp
856
+ traverseChildren(tp)
857
+ case tp : TypeRef if ! gadtSyms.contains(tp.symbol) && tp.symbol.isAbstractOrParamType =>
855
858
gadtSyms += tp.symbol
856
859
traverseChildren(tp)
857
- val owners = Iterator .iterate(tp.symbol)(_.maybeOwner).takeWhile(_.exists)
858
- for sym <- owners do
859
- // add ThisType's for the classes symbols in the ownership of `tp`
860
- // for example, i16451.CanForward.scala, add `Namer.this`, as one of the owners of the type parameter `A1`
861
- if sym.isClass && ! sym.isAnonymousClass && ! sym.isStaticOwner then
862
- traverse(sym.thisType)
860
+ // traverse abstract type infos, to add any singletons
861
+ // for example, i16451.CanForward.scala, add `Namer.this`, from the info of the type parameter `A1`
862
+ // also, i19031.ci-reg2.scala, add `out`, from the info of the type parameter `A1` (from synthetic applyOrElse)
863
+ traverseChildren(tp.info)
863
864
case _ =>
864
865
traverseChildren(tp)
865
- }
866
+ catch case ex : Throwable => handleRecursive( " traverseTp2 " , tp.show, ex)
866
867
TraverseTp2 .traverse(tp2)
867
- val thisTypes = TraverseTp2 .thisTypes
868
- val gadtSyms = TraverseTp2 .gadtSyms.toList
868
+ val singletons = TraverseTp2 .singletons
869
+ val gadtSyms = TraverseTp2 .gadtSyms.toList
869
870
870
871
// Prefix inference, given `p.C.this.Child`:
871
872
// 1. return it as is, if `C.this` is found in `tp`, i.e. the scrutinee; or
@@ -875,10 +876,13 @@ object TypeOps:
875
876
class InferPrefixMap extends TypeMap {
876
877
var prefixTVar : Type | Null = null
877
878
def apply (tp : Type ): Type = tp match {
878
- case tp @ ThisType (tref) if ! tref.symbol.isStaticOwner =>
879
+ case tp : TermRef if singletons.contains(tp.symbol) =>
880
+ prefixTVar = singletons(tp.symbol) // e.g. tests/pos/i19031.ci-reg2.scala, keep out
881
+ prefixTVar.uncheckedNN
882
+ case ThisType (tref) if ! tref.symbol.isStaticOwner =>
879
883
val symbol = tref.symbol
880
- if thisTypes .contains(tp ) then
881
- prefixTVar = tp // e.g. tests/pos/i16785.scala, keep Outer.this
884
+ if singletons .contains(symbol ) then
885
+ prefixTVar = singletons(symbol) // e.g. tests/pos/i16785.scala, keep Outer.this
882
886
prefixTVar.uncheckedNN
883
887
else if symbol.is(Module ) then
884
888
TermRef (this (tref.prefix), symbol.sourceModule)
@@ -913,7 +917,8 @@ object TypeOps:
913
917
}
914
918
915
919
def instantiate (): Type = {
916
- for tp <- mixins.reverseIterator do protoTp1 <:< tp
920
+ for tp <- mixins.reverseIterator do
921
+ protoTp1 <:< tp
917
922
maximizeType(protoTp1, NoSpan )
918
923
wildApprox(protoTp1)
919
924
}
0 commit comments