@@ -18,7 +18,7 @@ import config.Feature
1818import typer .Applications ._
1919import typer .ProtoTypes ._
2020import typer .ForceDegree
21- import typer .Inferencing .isFullyDefined
21+ import typer .Inferencing ._
2222import typer .IfBottom
2323
2424import scala .annotation .internal .sharable
@@ -618,8 +618,9 @@ object TypeOps:
618618
619619 val childTp = if (child.isTerm) child.termRef else child.typeRef
620620
621- instantiateToSubType(childTp, parent)(using ctx.fresh.setNewTyperState())
622- .dealias
621+ inContext(ctx.fresh.setExploreTyperState().setFreshGADTBounds) {
622+ instantiateToSubType(childTp, parent).dealias
623+ }
623624 }
624625
625626 /** Instantiate type `tp1` to be a subtype of `tp2`
@@ -668,10 +669,11 @@ object TypeOps:
668669 def minTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = false )
669670 def maxTypeMap (implicit ctx : Context ) = new AbstractTypeMap (maximize = true )
670671
671- // Fix subtype checking for child instantiation,
672- // such that `Foo(Test.this.foo) <:< Foo(Foo.this)`
672+ // Prefix inference, replace `p.C.this.Child` with `X.Child` where `X <: p.C`
673+ // Note: we need to strip ThisType in `p` recursively.
674+ //
673675 // See tests/patmat/i3938.scala
674- class RemoveThisMap extends TypeMap {
676+ class InferPrefixMap extends TypeMap {
675677 var prefixTVar : Type = null
676678 def apply (tp : Type ): Type = tp match {
677679 case ThisType (tref : TypeRef ) if ! tref.symbol.isStaticOwner =>
@@ -688,22 +690,14 @@ object TypeOps:
688690 }
689691 }
690692
691- // replace uninstantiated type vars with WildcardType, check tests/patmat/3333.scala
692- def instUndetMap (implicit ctx : Context ) = new TypeMap {
693- def apply (t : Type ): Type = t match {
694- case tvar : TypeVar if ! tvar.isInstantiated => WildcardType (tvar.origin.underlying.bounds)
695- case _ => mapOver(t)
696- }
697- }
698-
699- val removeThisType = new RemoveThisMap
693+ val inferThisMap = new InferPrefixMap
700694 val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
701- val protoTp1 = removeThisType .apply(tp1).appliedTo(tvars)
695+ val protoTp1 = inferThisMap .apply(tp1).appliedTo(tvars)
702696
703697 val force = new ForceDegree .Value (
704698 tvar =>
705699 ! (ctx.typerState.constraint.entry(tvar.origin) `eq` tvar.origin.underlying) ||
706- (tvar `eq` removeThisType .prefixTVar),
700+ (tvar `eq` inferThisMap .prefixTVar), // always instantiate prefix
707701 IfBottom .flip
708702 )
709703
@@ -718,14 +712,15 @@ object TypeOps:
718712 }
719713 }
720714
721- if (protoTp1 <:< tp2)
722- if (isFullyDefined(protoTp1, force)) protoTp1
723- else instUndetMap.apply(protoTp1)
715+ if (protoTp1 <:< tp2) {
716+ maximizeType(protoTp1, NoSpan , fromScala2x = false )
717+ wildApprox(protoTp1)
718+ }
724719 else {
725720 val protoTp2 = maxTypeMap.apply(tp2)
726721 if (protoTp1 <:< protoTp2 || parentQualify)
727722 if (isFullyDefined(AndType (protoTp1, protoTp2), force)) protoTp1
728- else instUndetMap.apply (protoTp1)
723+ else wildApprox (protoTp1)
729724 else {
730725 typr.println(s " $protoTp1 <:< $protoTp2 = false " )
731726 NoType
0 commit comments