@@ -838,33 +838,34 @@ object TypeOps:
838838 }
839839 }
840840
841- /** Gather GADT symbols and `ThisType`s found in `tp2`, ie. the scrutinee. */
841+ /** Gather GADT symbols and singletons found in `tp2`, ie. the scrutinee. */
842842 object TraverseTp2 extends TypeTraverser :
843- val thisTypes = util.HashSet [ ThisType ]()
844- val gadtSyms = new mutable.ListBuffer [Symbol ]
843+ val singletons = util.HashMap [ Symbol , SingletonType ]()
844+ val gadtSyms = new mutable.ListBuffer [Symbol ]
845845
846- def traverse (tp : Type ) = {
846+ def traverse (tp : Type ) = try
847847 val tpd = tp.dealias
848848 if tpd ne tp then traverse(tpd)
849849 else tp match
850- case tp : ThisType if ! tp.tref.symbol.isStaticOwner && ! thisTypes.contains(tp) =>
851- thisTypes + = tp
850+ case tp : ThisType if ! singletons.contains( tp.tref.symbol) && ! tp.tref.symbol.isStaticOwner =>
851+ singletons(tp.tref.symbol) = tp
852852 traverseChildren(tp.tref)
853- case tp : TypeRef if tp.symbol.isAbstractOrParamType =>
853+ case tp : TermRef if tp.symbol.is(Param ) =>
854+ singletons(tp.typeSymbol) = tp
855+ traverseChildren(tp)
856+ case tp : TypeRef if ! gadtSyms.contains(tp.symbol) && tp.symbol.isAbstractOrParamType =>
854857 gadtSyms += tp.symbol
855858 traverseChildren(tp)
856- val owners = Iterator .iterate(tp.symbol)(_.maybeOwner).takeWhile(_.exists)
857- for sym <- owners do
858- // add ThisType's for the classes symbols in the ownership of `tp`
859- // for example, i16451.CanForward.scala, add `Namer.this`, as one of the owners of the type parameter `A1`
860- if sym.isClass && ! sym.isAnonymousClass && ! sym.isStaticOwner then
861- traverse(sym.thisType)
859+ // traverse abstract type infos, to add any singletons
860+ // for example, i16451.CanForward.scala, add `Namer.this`, from the info of the type parameter `A1`
861+ // also, i19031.ci-reg2.scala, add `out`, from the info of the type parameter `A1` (from synthetic applyOrElse)
862+ traverseChildren(tp.info)
862863 case _ =>
863864 traverseChildren(tp)
864- }
865+ catch case ex : Throwable => handleRecursive( " traverseTp2 " , tp.show, ex)
865866 TraverseTp2 .traverse(tp2)
866- val thisTypes = TraverseTp2 .thisTypes
867- val gadtSyms = TraverseTp2 .gadtSyms.toList
867+ val singletons = TraverseTp2 .singletons
868+ val gadtSyms = TraverseTp2 .gadtSyms.toList
868869
869870 // Prefix inference, given `p.C.this.Child`:
870871 // 1. return it as is, if `C.this` is found in `tp`, i.e. the scrutinee; or
@@ -874,10 +875,13 @@ object TypeOps:
874875 class InferPrefixMap extends TypeMap {
875876 var prefixTVar : Type | Null = null
876877 def apply (tp : Type ): Type = tp match {
877- case tp @ ThisType (tref) if ! tref.symbol.isStaticOwner =>
878+ case tp : TermRef if singletons.contains(tp.symbol) =>
879+ prefixTVar = singletons(tp.symbol) // e.g. tests/pos/i19031.ci-reg2.scala, keep out
880+ prefixTVar.uncheckedNN
881+ case ThisType (tref) if ! tref.symbol.isStaticOwner =>
878882 val symbol = tref.symbol
879- if thisTypes .contains(tp ) then
880- prefixTVar = tp // e.g. tests/pos/i16785.scala, keep Outer.this
883+ if singletons .contains(symbol ) then
884+ prefixTVar = singletons(symbol) // e.g. tests/pos/i16785.scala, keep Outer.this
881885 prefixTVar.uncheckedNN
882886 else if symbol.is(Module ) then
883887 TermRef (this (tref.prefix), symbol.sourceModule)
@@ -912,7 +916,8 @@ object TypeOps:
912916 }
913917
914918 def instantiate (): Type = {
915- for tp <- mixins.reverseIterator do protoTp1 <:< tp
919+ for tp <- mixins.reverseIterator do
920+ protoTp1 <:< tp
916921 maximizeType(protoTp1, NoSpan )
917922 wildApprox(protoTp1)
918923 }
0 commit comments