@@ -839,33 +839,34 @@ object TypeOps:
839839 }
840840 }
841841
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. */
843843 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 ]
846846
847- def traverse (tp : Type ) = {
847+ def traverse (tp : Type ) = try
848848 val tpd = tp.dealias
849849 if tpd ne tp then traverse(tpd)
850850 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
853853 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 =>
855858 gadtSyms += tp.symbol
856859 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)
863864 case _ =>
864865 traverseChildren(tp)
865- }
866+ catch case ex : Throwable => handleRecursive( " traverseTp2 " , tp.show, ex)
866867 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
869870
870871 // Prefix inference, given `p.C.this.Child`:
871872 // 1. return it as is, if `C.this` is found in `tp`, i.e. the scrutinee; or
@@ -875,10 +876,13 @@ object TypeOps:
875876 class InferPrefixMap extends TypeMap {
876877 var prefixTVar : Type | Null = null
877878 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 =>
879883 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
882886 prefixTVar.uncheckedNN
883887 else if symbol.is(Module ) then
884888 TermRef (this (tref.prefix), symbol.sourceModule)
@@ -913,7 +917,8 @@ object TypeOps:
913917 }
914918
915919 def instantiate (): Type = {
916- for tp <- mixins.reverseIterator do protoTp1 <:< tp
920+ for tp <- mixins.reverseIterator do
921+ protoTp1 <:< tp
917922 maximizeType(protoTp1, NoSpan )
918923 wildApprox(protoTp1)
919924 }
0 commit comments