@@ -24,6 +24,7 @@ import reporting.trace
2424import annotation .constructorOnly
2525import cc .*
2626import NameKinds .WildcardParamName
27+ import MatchTypes .isConcrete
2728
2829/** Provides methods to compare types.
2930 */
@@ -3402,58 +3403,6 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) {
34023403
34033404 // See https://docs.scala-lang.org/sips/match-types-spec.html#matching
34043405 def matchSpeccedPatMat (spec : MatchTypeCaseSpec .SpeccedPatMat ): MatchResult =
3405- /* Concreteness checking
3406- *
3407- * When following a baseType and reaching a non-wildcard, in-variant-pos type capture,
3408- * we have to make sure that the scrutinee is concrete enough to uniquely determine
3409- * the values of the captures. This comes down to checking that we do not follow any
3410- * upper bound of an abstract type.
3411- *
3412- * See notably neg/wildcard-match.scala for examples of this.
3413- *
3414- * See neg/i13780.scala, neg/i13780-1.scala and neg/i19746.scala for
3415- * ClassCastException reproducers if we disable this check.
3416- */
3417-
3418- def isConcrete (tp : Type ): Boolean =
3419- val tp1 = tp.normalized
3420-
3421- tp1 match
3422- case tp1 : TypeRef =>
3423- if tp1.symbol.isClass then true
3424- else
3425- tp1.info match
3426- case info : AliasingBounds => isConcrete(info.alias)
3427- case _ => false
3428- case tp1 : AppliedType =>
3429- isConcrete(tp1.tycon) && isConcrete(tp1.superType)
3430- case tp1 : HKTypeLambda =>
3431- true
3432- case tp1 : TermRef =>
3433- ! tp1.symbol.is(Param ) && isConcrete(tp1.underlying)
3434- case tp1 : TermParamRef =>
3435- false
3436- case tp1 : SingletonType =>
3437- isConcrete(tp1.underlying)
3438- case tp1 : ExprType =>
3439- isConcrete(tp1.underlying)
3440- case tp1 : AnnotatedType =>
3441- isConcrete(tp1.parent)
3442- case tp1 : RefinedType =>
3443- isConcrete(tp1.underlying)
3444- case tp1 : RecType =>
3445- isConcrete(tp1.underlying)
3446- case tp1 : AndOrType =>
3447- isConcrete(tp1.tp1) && isConcrete(tp1.tp2)
3448- case tp1 : FlexibleType =>
3449- isConcrete(tp1.hi)
3450- case _ =>
3451- val tp2 = tp1.stripped.stripLazyRef
3452- (tp2 ne tp) && isConcrete(tp2)
3453- end isConcrete
3454-
3455- // Actual matching logic
3456-
34573406 val instances = Array .fill[Type ](spec.captureCount)(NoType )
34583407 val noInstances = mutable.ListBuffer .empty[(TypeName , TypeBounds )]
34593408
0 commit comments