@@ -77,19 +77,6 @@ object TypeTestsCasts {
77
77
}
78
78
}.apply(tp)
79
79
80
- /** Approximate type parameters depending on variance */
81
- def stripTypeParam (tp : Type )(using Context ) = new ApproximatingTypeMap {
82
- val boundTypeParams = util.HashMap [TypeRef , TypeVar ]()
83
- def apply (tp : Type ): Type = tp match {
84
- case _ : MatchType =>
85
- tp // break cycles
86
- case tp : TypeRef if ! tp.symbol.isClass =>
87
- boundTypeParams.getOrElseUpdate(tp, newTypeVar(tp.underlying.toBounds))
88
- case _ =>
89
- mapOver(tp)
90
- }
91
- }.apply(tp)
92
-
93
80
/** Returns true if the type arguments of `P` can be determined from `X` */
94
81
def typeArgsTrivial (X : Type , P : AppliedType )(using Context ) = inContext(ctx.fresh.setExploreTyperState().setFreshGADTBounds) {
95
82
val AppliedType (tycon, _) = P
@@ -102,6 +89,7 @@ object TypeTestsCasts {
102
89
val tvars = constrained(typeLambda, untpd.EmptyTree , alwaysAddTypeVars = true )._2.map(_.tpe)
103
90
val P1 = tycon.appliedTo(tvars)
104
91
92
+ debug.println(" before " + ctx.typerState.constraint.show)
105
93
debug.println(" P : " + P .show)
106
94
debug.println(" P1 : " + P1 .show)
107
95
debug.println(" X : " + X .show)
@@ -111,18 +99,23 @@ object TypeTestsCasts {
111
99
// conforms to the type skeleton pre.F[_]. Then it goes on to check
112
100
// if P1 <: P, which means the type arguments in P are trivial,
113
101
// thus no runtime checks are needed for them.
114
- P1 <:< X
102
+ P1 <:< X || withMode(Mode .GadtConstraintInference ) {
103
+ TypeComparer .constrainPatternType(P1 , X )
104
+ debug.println(TypeComparer .explained(_.constrainPatternType(P1 , X )))
105
+ true
106
+ }
115
107
116
108
// Maximization of the type means we try to cover all possible values
117
109
// which conform to the skeleton pre.F[_] and X. Then we have to make
118
110
// sure all of them are actually of the type P, which implies that the
119
111
// type arguments in P are trivial (no runtime check needed).
120
112
maximizeType(P1 , span, fromScala2x = false )
121
113
114
+ debug.println(" after " + ctx.typerState.constraint.show)
115
+
122
116
val res = P1 <:< P
123
117
124
118
debug.println(TypeComparer .explained(_.isSubType(P1 , P )))
125
-
126
119
debug.println(" P1 : " + P1 .show)
127
120
debug.println(" P1 <:< P = " + res)
128
121
@@ -151,10 +144,8 @@ object TypeTestsCasts {
151
144
case _ =>
152
145
// always false test warnings are emitted elsewhere
153
146
X .classSymbol.exists && P .classSymbol.exists &&
154
- ! X .classSymbol.asClass.mayHaveCommonChild(P .classSymbol.asClass) ||
155
- // first try without striping type parameters for performance
156
- typeArgsTrivial(X , tpe) ||
157
- typeArgsTrivial(stripTypeParam(X ), tpe)
147
+ ! X .classSymbol.asClass.mayHaveCommonChild(P .classSymbol.asClass)
148
+ || typeArgsTrivial(X , tpe)
158
149
}
159
150
case AndType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
160
151
case OrType (tp1, tp2) => recur(X , tp1) && recur(X , tp2)
0 commit comments