@@ -584,10 +584,9 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
584
584
// precondition: `tp1` should have the shape `path.Child`, thus `ThisType` is always covariant
585
585
val thisTypeMap = new TypeMap {
586
586
def apply (t : Type ): Type = t match {
587
- case tp @ ThisType (tref) if ! tref.symbol.isStaticOwner && ! tref.symbol.is(Module ) =>
588
- // TODO: stackoverflow here
589
- // newTypeVar(TypeBounds.upper(mapOver(tp.underlying)))
590
- newTypeVar(TypeBounds .upper(mapOver(tref & tref.classSymbol.asClass.givenSelfType)))
587
+ case tp @ ThisType (tref) if ! tref.symbol.isStaticOwner =>
588
+ if (tref.symbol.is(Module )) mapOver(tref)
589
+ else newTypeVar(TypeBounds .upper(tp.underlying))
591
590
case _ =>
592
591
mapOver(t)
593
592
}
@@ -596,7 +595,6 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
596
595
// replace type parameter references with bounds
597
596
val typeParamMap = new TypeMap {
598
597
def apply (t : Type ): Type = t match {
599
-
600
598
case tp : TypeRef if tp.symbol.is(TypeParam ) && tp.underlying.isInstanceOf [TypeBounds ] =>
601
599
// See tests/patmat/gadt.scala tests/patmat/exhausting.scala tests/patmat/t9657.scala
602
600
val exposed =
@@ -611,13 +609,32 @@ class SpaceEngine(implicit ctx: Context) extends SpaceLogic {
611
609
}
612
610
}
613
611
612
+ // replace uninstantiated type vars with WildcardType, check tests/patmat/3333.scala
613
+ val instUndetMap = new TypeMap {
614
+ def apply (t : Type ): Type = t match {
615
+ case tvar : TypeVar if ! tvar.isInstantiated => WildcardType (tvar.origin.underlying.bounds)
616
+ case _ => mapOver(t)
617
+ }
618
+ }
619
+
620
+ val force = new ForceDegree .Value (
621
+ tvar => ! (ctx.typerState.constraint.entry(tvar.origin) eq tvar.origin.underlying),
622
+ minimizeAll = false
623
+ )
624
+
614
625
val tvars = tp1.typeParams.map { tparam => newTypeVar(tparam.paramInfo.bounds) }
615
626
val protoTp1 = thisTypeMap(tp1.appliedTo(tvars))
616
627
617
- if (protoTp1 <:< tp2 && isFullyDefined(protoTp1, ForceDegree .noBottom)) protoTp1
628
+ if (protoTp1 <:< tp2) {
629
+ if (isFullyDefined(protoTp1, force)) protoTp1
630
+ else instUndetMap(protoTp1)
631
+ }
618
632
else {
619
633
val protoTp2 = typeParamMap(tp2)
620
- if (protoTp1 <:< protoTp2 && isFullyDefined(protoTp1 & protoTp2, ForceDegree .noBottom)) protoTp1
634
+ if (protoTp1 <:< protoTp2) {
635
+ if (isFullyDefined(AndType (protoTp1, protoTp2), force)) protoTp1
636
+ else instUndetMap(protoTp1)
637
+ }
621
638
else {
622
639
debug.println(s " $protoTp1 <:< $protoTp2 = false " )
623
640
NoType
0 commit comments