@@ -665,21 +665,21 @@ object TypeOps:
665665 def minTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = false )
666666 def maxTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = true )
667667
668- // Fix subtype checking for child instantiation,
669- // such that `Foo(Test.this.foo) <:< Foo(Foo.this)`
668+ // Prefix inference, replace `p.C.this.Child` with `X.Child` where `X <: p.C`
669+ // Note: we need to handle `p` recursively.
670+ //
670671 // See tests/patmat/i3938.scala
671- class RemoveThisMap extends TypeMap {
672- var prefixTVar : Type = null
672+ class InferPrefixMap extends TypeMap {
673+ var tvars = Set .empty[ TypeVar ]
673674 def apply (tp : Type ): Type = tp match {
674675 case ThisType (tref : TypeRef ) if ! tref.symbol.isStaticOwner =>
675676 if (tref.symbol.is(Module ))
676677 TermRef (this (tref.prefix), tref.symbol.sourceModule)
677- else if (prefixTVar != null )
678- this (tref)
679678 else {
680- prefixTVar = WildcardType // prevent recursive call from assigning it
681- prefixTVar = newTypeVar(TypeBounds .upper(this (tref)))
682- prefixTVar
679+ val bound = TypeRef (this (tref.prefix), tref.symbol)
680+ val tvar = newTypeVar(TypeBounds .upper(bound))
681+ tvars = tvars + tvar
682+ tvar
683683 }
684684 case tp => mapOver(tp)
685685 }
@@ -693,14 +693,14 @@ object TypeOps:
693693 }
694694 }
695695
696- val removeThisType = new RemoveThisMap
696+ val inferThisMap = new InferPrefixMap
697697 val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
698- val protoTp1 = removeThisType .apply(tp1).appliedTo(tvars)
698+ val protoTp1 = inferThisMap .apply(tp1).appliedTo(tvars)
699699
700700 val force = new ForceDegree .Value (
701701 tvar =>
702702 ! (ctx.typerState.constraint.entry(tvar.origin) `eq` tvar.origin.underlying) ||
703- (tvar `eq` removeThisType.prefixTVar),
703+ inferThisMap.tvars.contains (tvar), // always instantiate prefix
704704 IfBottom .flip
705705 )
706706
0 commit comments