@@ -112,6 +112,8 @@ object Types {
112
112
def isProvisional (using Context ): Boolean = mightBeProvisional && testProvisional
113
113
114
114
private def testProvisional (using Context ): Boolean =
115
+ class ProAcc extends TypeAccumulator [Boolean ]:
116
+ override def apply (x : Boolean , t : Type ) = x || test(t, this )
115
117
def test (t : Type , theAcc : TypeAccumulator [Boolean ]): Boolean =
116
118
if t.mightBeProvisional then
117
119
t.mightBeProvisional = t match
@@ -127,16 +129,14 @@ object Types {
127
129
}
128
130
case t : TermRef =>
129
131
! t.currentSymbol.isStatic && test(t.prefix, theAcc)
132
+ case t : AppliedType =>
133
+ t.fold(false , (x, tp) => x || test(tp, theAcc))
130
134
case t : TypeVar =>
131
135
! t.inst.exists || test(t.inst, theAcc)
132
136
case t : LazyRef =>
133
137
! t.completed || test(t.ref, theAcc)
134
138
case _ =>
135
- val acc =
136
- if theAcc != null then theAcc
137
- else new TypeAccumulator [Boolean ]:
138
- override def apply (x : Boolean , t : Type ) = x || test(t, this )
139
- acc.foldOver(false , t)
139
+ (if theAcc != null then theAcc else ProAcc ()).foldOver(false , t)
140
140
end if
141
141
t.mightBeProvisional
142
142
end test
@@ -3218,17 +3218,21 @@ object Types {
3218
3218
3219
3219
def newLikeThis (paramNames : List [ThisName ], paramInfos : List [PInfo ], resType : Type )(using Context ): This =
3220
3220
def substParams (pinfos : List [PInfo ], to : This ): List [PInfo ] = pinfos match
3221
- case pinfo :: rest =>
3222
- val pinfo1 = pinfo.subst(this , to).asInstanceOf [PInfo ]
3223
- val rest1 = substParams(rest, to)
3224
- if (pinfo1 eq pinfo) && (rest1 eq rest) then pinfos
3225
- else pinfo1 :: rest1
3221
+ case pinfos @ (pinfo :: rest) =>
3222
+ pinfos.derivedCons(pinfo.subst(this , to).asInstanceOf [PInfo ], substParams(rest, to))
3226
3223
case nil =>
3227
3224
nil
3228
3225
companion(paramNames)(
3229
3226
x => substParams(paramInfos, x),
3230
3227
x => resType.subst(this , x))
3231
3228
3229
+ inline def map (inline op : Type => Type )(using Context ) =
3230
+ def mapParams (pinfos : List [PInfo ]): List [PInfo ] = pinfos match
3231
+ case pinfos @ (pinfo :: rest) =>
3232
+ pinfos.derivedCons(op(pinfo).asInstanceOf [PInfo ], mapParams(rest))
3233
+ case nil => nil
3234
+ derivedLambdaType(paramNames, mapParams(paramInfos), op(resType))
3235
+
3232
3236
protected def prefixString : String
3233
3237
override def toString : String = s " $prefixString( $paramNames, $paramInfos, $resType) "
3234
3238
}
@@ -3287,6 +3291,8 @@ object Types {
3287
3291
private var myParamDependencyStatus : DependencyStatus = Unknown
3288
3292
3289
3293
private def depStatus (initial : DependencyStatus , tp : Type )(using Context ): DependencyStatus =
3294
+ class DepAcc extends TypeAccumulator [DependencyStatus ]:
3295
+ def apply (status : DependencyStatus , tp : Type ) = compute(status, tp, this )
3290
3296
def combine (x : DependencyStatus , y : DependencyStatus ) =
3291
3297
val status = (x & StatusMask ) max (y & StatusMask )
3292
3298
val provisional = (x | y) & Provisional
@@ -3305,16 +3311,13 @@ object Types {
3305
3311
case _ =>
3306
3312
status1
3307
3313
}
3314
+ case tp : TermRef => applyPrefix(tp)
3315
+ case tp : AppliedType => tp.fold(status, compute(_, _, theAcc))
3308
3316
case tp : TypeVar if ! tp.isInstantiated => combine(status, Provisional )
3309
3317
case TermParamRef (`thisLambdaType`, _) => TrueDeps
3310
- case tp : TermRef => applyPrefix(tp)
3311
3318
case _ : ThisType | _ : BoundType | NoPrefix => status
3312
3319
case _ =>
3313
- val acc =
3314
- if theAcc != null then theAcc
3315
- else new TypeAccumulator [DependencyStatus ]:
3316
- def apply (status : DependencyStatus , tp : Type ) = compute(status, tp, this )
3317
- acc.foldOver(status, tp)
3320
+ (if theAcc != null then theAcc else DepAcc ()).foldOver(status, tp)
3318
3321
compute(initial, tp, null )
3319
3322
end depStatus
3320
3323
@@ -3849,6 +3852,18 @@ object Types {
3849
3852
superType
3850
3853
}
3851
3854
3855
+ inline def map (inline op : Type => Type )(using Context ) =
3856
+ def mapArgs (args : List [Type ]): List [Type ] = args match
3857
+ case args @ (arg :: rest) => args.derivedCons(op(arg), mapArgs(rest))
3858
+ case nil => nil
3859
+ derivedAppliedType(op(tycon), mapArgs(args))
3860
+
3861
+ inline def fold [T ](x : T , inline op : (T , Type ) => T )(using Context ): T =
3862
+ def foldArgs (x : T , args : List [Type ]): T = args match
3863
+ case arg :: rest => foldArgs(op(x, arg), rest)
3864
+ case nil => x
3865
+ foldArgs(op(x, tycon), args)
3866
+
3852
3867
override def tryNormalize (using Context ): Type = tycon match {
3853
3868
case tycon : TypeRef =>
3854
3869
def tryMatchAlias = tycon.info match {
@@ -4954,10 +4969,29 @@ object Types {
4954
4969
protected def derivedLambdaType (tp : LambdaType )(formals : List [tp.PInfo ], restpe : Type ): Type =
4955
4970
tp.derivedLambdaType(tp.paramNames, formals, restpe)
4956
4971
4972
+ protected def mapArgs (args : List [Type ], tparams : List [ParamInfo ]): List [Type ] = args match
4973
+ case arg :: otherArgs if tparams.nonEmpty =>
4974
+ val arg1 = arg match
4975
+ case arg : TypeBounds => this (arg)
4976
+ case arg => atVariance(variance * tparams.head.paramVarianceSign)(this (arg))
4977
+ val otherArgs1 = mapArgs(otherArgs, tparams.tail)
4978
+ if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
4979
+ else arg1 :: otherArgs1
4980
+ case nil =>
4981
+ nil
4982
+
4983
+ protected def mapOverLambda (tp : LambdaType ) =
4984
+ val restpe = tp.resultType
4985
+ val saved = variance
4986
+ variance = if (defn.MatchCase .isInstance(restpe)) 0 else - variance
4987
+ val ptypes1 = tp.paramInfos.mapConserve(this ).asInstanceOf [List [tp.PInfo ]]
4988
+ variance = saved
4989
+ derivedLambdaType(tp)(ptypes1, this (restpe))
4990
+
4957
4991
/** Map this function over given type */
4958
4992
def mapOver (tp : Type ): Type = {
4959
- record(s " mapOver ${getClass}" )
4960
- record(" mapOver total" )
4993
+ record(s " TypeMap mapOver ${getClass}" )
4994
+ record(" TypeMap mapOver total" )
4961
4995
val ctx = this .mapCtx // optimization for performance
4962
4996
given Context = ctx
4963
4997
tp match {
@@ -4972,27 +5006,12 @@ object Types {
4972
5006
// if `p <: q` then `p.A <: q.A`, and well-formedness requires that `A` is a member
4973
5007
// of `p`'s upper bound.
4974
5008
derivedSelect(tp, prefix1)
4975
- case _ : ThisType
4976
- | _ : BoundType
4977
- | NoPrefix => tp
4978
5009
4979
5010
case tp : AppliedType =>
4980
- def mapArgs (args : List [Type ], tparams : List [ParamInfo ]): List [Type ] = args match {
4981
- case arg :: otherArgs if tparams.nonEmpty =>
4982
- val arg1 = arg match {
4983
- case arg : TypeBounds => this (arg)
4984
- case arg => atVariance(variance * tparams.head.paramVarianceSign)(this (arg))
4985
- }
4986
- val otherArgs1 = mapArgs(otherArgs, tparams.tail)
4987
- if ((arg1 eq arg) && (otherArgs1 eq otherArgs)) args
4988
- else arg1 :: otherArgs1
4989
- case nil =>
4990
- nil
4991
- }
4992
5011
derivedAppliedType(tp, this (tp.tycon), mapArgs(tp.args, tp.tyconTypeParams))
4993
5012
4994
- case tp : RefinedType =>
4995
- derivedRefinedType (tp, this (tp.parent), this (tp.refinedInfo) )
5013
+ case tp : LambdaType =>
5014
+ mapOverLambda (tp)
4996
5015
4997
5016
case tp : AliasingBounds =>
4998
5017
derivedAlias(tp, atVariance(0 )(this (tp.alias)))
@@ -5003,26 +5022,32 @@ object Types {
5003
5022
variance = - variance
5004
5023
derivedTypeBounds(tp, lo1, this (tp.hi))
5005
5024
5006
- case tp : RecType =>
5007
- derivedRecType(tp, this (tp.parent))
5008
-
5009
5025
case tp : TypeVar =>
5010
5026
val inst = tp.instanceOpt
5011
5027
if (inst.exists) apply(inst) else tp
5012
5028
5013
5029
case tp : ExprType =>
5014
5030
derivedExprType(tp, this (tp.resultType))
5015
5031
5016
- case tp : LambdaType =>
5017
- def mapOverLambda = {
5018
- val restpe = tp.resultType
5019
- val saved = variance
5020
- variance = if (defn.MatchCase .isInstance(restpe)) 0 else - variance
5021
- val ptypes1 = tp.paramInfos.mapConserve(this ).asInstanceOf [List [tp.PInfo ]]
5022
- variance = saved
5023
- derivedLambdaType(tp)(ptypes1, this (restpe))
5024
- }
5025
- mapOverLambda
5032
+ case tp @ AnnotatedType (underlying, annot) =>
5033
+ val underlying1 = this (underlying)
5034
+ if (underlying1 eq underlying) tp
5035
+ else derivedAnnotatedType(tp, underlying1, mapOver(annot))
5036
+
5037
+ case _ : ThisType
5038
+ | _ : BoundType
5039
+ | NoPrefix =>
5040
+ tp
5041
+
5042
+ case tp : ProtoType =>
5043
+ tp.map(this )
5044
+
5045
+ case tp : RefinedType =>
5046
+ derivedRefinedType(tp, this (tp.parent), this (tp.refinedInfo))
5047
+
5048
+ case tp : RecType =>
5049
+ record(" TypeMap.RecType" )
5050
+ derivedRecType(tp, this (tp.parent))
5026
5051
5027
5052
case tp @ SuperType (thistp, supertp) =>
5028
5053
derivedSuperType(tp, this (thistp), this (supertp))
@@ -5056,20 +5081,12 @@ object Types {
5056
5081
case tp : SkolemType =>
5057
5082
derivedSkolemType(tp, this (tp.info))
5058
5083
5059
- case tp @ AnnotatedType (underlying, annot) =>
5060
- val underlying1 = this (underlying)
5061
- if (underlying1 eq underlying) tp
5062
- else derivedAnnotatedType(tp, underlying1, mapOver(annot))
5063
-
5064
5084
case tp : WildcardType =>
5065
5085
derivedWildcardType(tp, mapOver(tp.optBounds))
5066
5086
5067
5087
case tp : JavaArrayType =>
5068
5088
derivedJavaArrayType(tp, this (tp.elemType))
5069
5089
5070
- case tp : ProtoType =>
5071
- tp.map(this )
5072
-
5073
5090
case _ =>
5074
5091
tp
5075
5092
}
0 commit comments