@@ -5093,6 +5093,7 @@ object Types extends TypeUtils {
50935093 case TypeTest (tpe : Type )
50945094 case BaseTypeTest (classType : TypeRef , argPatterns : List [MatchTypeCasePattern ], needsConcreteScrut : Boolean )
50955095 case CompileTimeS (argPattern : MatchTypeCasePattern )
5096+ case AbstractTypeConstructor (tycon : Type , argPatterns : List [MatchTypeCasePattern ])
50965097
50975098 def isTypeTest : Boolean =
50985099 this .isInstanceOf [TypeTest ]
@@ -5167,25 +5168,15 @@ object Types extends TypeUtils {
51675168 case pat @ AppliedType (tycon : TypeRef , args) if variance == 1 =>
51685169 val tyconSym = tycon.symbol
51695170 if tyconSym.isClass then
5170- val cls = tyconSym.asClass
5171- if cls.name.startsWith(" Tuple" ) && defn.isTupleNType(pat) then
5171+ if tyconSym.name.startsWith(" Tuple" ) && defn.isTupleNType(pat) then
51725172 rec(pat.toNestedPairs, variance)
51735173 else
5174- val tparams = tycon.typeParams
5175- val argPatterns = args.zip(tparams).map { (arg, tparam) =>
5176- rec(arg, tparam.paramVarianceSign)
5174+ recArgPatterns(pat) { argPatterns =>
5175+ val needsConcreteScrut = argPatterns.zip(tycon.typeParams).exists {
5176+ (argPattern, tparam) => tparam.paramVarianceSign != 0 && argPattern.needsConcreteScrutInVariantPos
5177+ }
5178+ MatchTypeCasePattern .BaseTypeTest (tycon, argPatterns, needsConcreteScrut)
51775179 }
5178- if argPatterns.exists(_ == null ) then
5179- null
5180- else
5181- val argPatterns1 = argPatterns.asInstanceOf [List [MatchTypeCasePattern ]] // they are not null
5182- if argPatterns1.forall(_.isTypeTest) then
5183- MatchTypeCasePattern .TypeTest (pat)
5184- else
5185- val needsConcreteScrut = argPatterns1.zip(tparams).exists {
5186- (argPattern, tparam) => tparam.paramVarianceSign != 0 && argPattern.needsConcreteScrutInVariantPos
5187- }
5188- MatchTypeCasePattern .BaseTypeTest (tycon, argPatterns1, needsConcreteScrut)
51895180 else if defn.isCompiletime_S(tyconSym) && args.sizeIs == 1 then
51905181 val argPattern = rec(args.head, variance)
51915182 if argPattern == null then
@@ -5195,12 +5186,39 @@ object Types extends TypeUtils {
51955186 else
51965187 MatchTypeCasePattern .CompileTimeS (argPattern)
51975188 else
5198- null
5189+ tycon.info match
5190+ case _ : RealTypeBounds => recAbstractTypeConstructor(pat)
5191+ case _ => null
5192+
5193+ case pat @ AppliedType (tycon : TypeParamRef , _) if variance == 1 =>
5194+ recAbstractTypeConstructor(pat)
51995195
52005196 case _ =>
52015197 MatchTypeCasePattern .TypeTest (pat)
52025198 end rec
52035199
5200+ def recAbstractTypeConstructor (pat : AppliedType ): MatchTypeCasePattern | Null =
5201+ recArgPatterns(pat) { argPatterns =>
5202+ MatchTypeCasePattern .AbstractTypeConstructor (pat.tycon, argPatterns)
5203+ }
5204+ end recAbstractTypeConstructor
5205+
5206+ def recArgPatterns (pat : AppliedType )(whenNotTypeTest : List [MatchTypeCasePattern ] => MatchTypeCasePattern | Null ): MatchTypeCasePattern | Null =
5207+ val AppliedType (tycon, args) = pat
5208+ val tparams = tycon.typeParams
5209+ val argPatterns = args.zip(tparams).map { (arg, tparam) =>
5210+ rec(arg, tparam.paramVarianceSign)
5211+ }
5212+ if argPatterns.exists(_ == null ) then
5213+ null
5214+ else
5215+ val argPatterns1 = argPatterns.asInstanceOf [List [MatchTypeCasePattern ]] // they are not null
5216+ if argPatterns1.forall(_.isTypeTest) then
5217+ MatchTypeCasePattern .TypeTest (pat)
5218+ else
5219+ whenNotTypeTest(argPatterns1)
5220+ end recArgPatterns
5221+
52045222 val result = rec(pat, variance = 1 )
52055223 if typeParamRefsAccountedFor == caseLambda.paramNames.size then result
52065224 else null
0 commit comments