@@ -665,21 +665,21 @@ object TypeOps:
665
665
def minTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = false )
666
666
def maxTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = true )
667
667
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
+ //
670
671
// 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 ]
673
674
def apply (tp : Type ): Type = tp match {
674
675
case ThisType (tref : TypeRef ) if ! tref.symbol.isStaticOwner =>
675
676
if (tref.symbol.is(Module ))
676
677
TermRef (this (tref.prefix), tref.symbol.sourceModule)
677
- else if (prefixTVar != null )
678
- this (tref)
679
678
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
683
683
}
684
684
case tp => mapOver(tp)
685
685
}
@@ -693,14 +693,14 @@ object TypeOps:
693
693
}
694
694
}
695
695
696
- val removeThisType = new RemoveThisMap
696
+ val inferThisMap = new InferPrefixMap
697
697
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)
699
699
700
700
val force = new ForceDegree .Value (
701
701
tvar =>
702
702
! (ctx.typerState.constraint.entry(tvar.origin) `eq` tvar.origin.underlying) ||
703
- (tvar `eq` removeThisType.prefixTVar),
703
+ inferThisMap.tvars.contains (tvar), // always instantiate prefix
704
704
IfBottom .flip
705
705
)
706
706
0 commit comments