@@ -112,6 +112,8 @@ object Types {
112112 def isProvisional (using Context ): Boolean = mightBeProvisional && testProvisional
113113
114114 private def testProvisional (using Context ): Boolean =
115+ class ProAcc extends TypeAccumulator [Boolean ]:
116+ override def apply (x : Boolean , t : Type ) = x || test(t, this )
115117 def test (t : Type , theAcc : TypeAccumulator [Boolean ]): Boolean =
116118 if t.mightBeProvisional then
117119 t.mightBeProvisional = t match
@@ -127,16 +129,14 @@ object Types {
127129 }
128130 case t : TermRef =>
129131 ! t.currentSymbol.isStatic && test(t.prefix, theAcc)
132+ case t : AppliedType =>
133+ t.fold(false , (x, tp) => x || test(tp, theAcc))
130134 case t : TypeVar =>
131135 ! t.inst.exists || test(t.inst, theAcc)
132136 case t : LazyRef =>
133137 ! t.completed || test(t.ref, theAcc)
134138 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)
140140 end if
141141 t.mightBeProvisional
142142 end test
@@ -3218,17 +3218,21 @@ object Types {
32183218
32193219 def newLikeThis (paramNames : List [ThisName ], paramInfos : List [PInfo ], resType : Type )(using Context ): This =
32203220 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))
32263223 case nil =>
32273224 nil
32283225 companion(paramNames)(
32293226 x => substParams(paramInfos, x),
32303227 x => resType.subst(this , x))
32313228
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+
32323236 protected def prefixString : String
32333237 override def toString : String = s " $prefixString( $paramNames, $paramInfos, $resType) "
32343238 }
@@ -3287,6 +3291,8 @@ object Types {
32873291 private var myParamDependencyStatus : DependencyStatus = Unknown
32883292
32893293 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 )
32903296 def combine (x : DependencyStatus , y : DependencyStatus ) =
32913297 val status = (x & StatusMask ) max (y & StatusMask )
32923298 val provisional = (x | y) & Provisional
@@ -3305,16 +3311,13 @@ object Types {
33053311 case _ =>
33063312 status1
33073313 }
3314+ case tp : TermRef => applyPrefix(tp)
3315+ case tp : AppliedType => tp.fold(status, compute(_, _, theAcc))
33083316 case tp : TypeVar if ! tp.isInstantiated => combine(status, Provisional )
33093317 case TermParamRef (`thisLambdaType`, _) => TrueDeps
3310- case tp : TermRef => applyPrefix(tp)
33113318 case _ : ThisType | _ : BoundType | NoPrefix => status
33123319 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)
33183321 compute(initial, tp, null )
33193322 end depStatus
33203323
@@ -3849,6 +3852,18 @@ object Types {
38493852 superType
38503853 }
38513854
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+
38523867 override def tryNormalize (using Context ): Type = tycon match {
38533868 case tycon : TypeRef =>
38543869 def tryMatchAlias = tycon.info match {
@@ -4954,10 +4969,29 @@ object Types {
49544969 protected def derivedLambdaType (tp : LambdaType )(formals : List [tp.PInfo ], restpe : Type ): Type =
49554970 tp.derivedLambdaType(tp.paramNames, formals, restpe)
49564971
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+
49574991 /** Map this function over given type */
49584992 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" )
49614995 val ctx = this .mapCtx // optimization for performance
49624996 given Context = ctx
49634997 tp match {
@@ -4972,27 +5006,12 @@ object Types {
49725006 // if `p <: q` then `p.A <: q.A`, and well-formedness requires that `A` is a member
49735007 // of `p`'s upper bound.
49745008 derivedSelect(tp, prefix1)
4975- case _ : ThisType
4976- | _ : BoundType
4977- | NoPrefix => tp
49785009
49795010 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- }
49925011 derivedAppliedType(tp, this (tp.tycon), mapArgs(tp.args, tp.tyconTypeParams))
49935012
4994- case tp : RefinedType =>
4995- derivedRefinedType (tp, this (tp.parent), this (tp.refinedInfo) )
5013+ case tp : LambdaType =>
5014+ mapOverLambda (tp)
49965015
49975016 case tp : AliasingBounds =>
49985017 derivedAlias(tp, atVariance(0 )(this (tp.alias)))
@@ -5003,26 +5022,32 @@ object Types {
50035022 variance = - variance
50045023 derivedTypeBounds(tp, lo1, this (tp.hi))
50055024
5006- case tp : RecType =>
5007- derivedRecType(tp, this (tp.parent))
5008-
50095025 case tp : TypeVar =>
50105026 val inst = tp.instanceOpt
50115027 if (inst.exists) apply(inst) else tp
50125028
50135029 case tp : ExprType =>
50145030 derivedExprType(tp, this (tp.resultType))
50155031
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))
50265051
50275052 case tp @ SuperType (thistp, supertp) =>
50285053 derivedSuperType(tp, this (thistp), this (supertp))
@@ -5056,20 +5081,12 @@ object Types {
50565081 case tp : SkolemType =>
50575082 derivedSkolemType(tp, this (tp.info))
50585083
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-
50645084 case tp : WildcardType =>
50655085 derivedWildcardType(tp, mapOver(tp.optBounds))
50665086
50675087 case tp : JavaArrayType =>
50685088 derivedJavaArrayType(tp, this (tp.elemType))
50695089
5070- case tp : ProtoType =>
5071- tp.map(this )
5072-
50735090 case _ =>
50745091 tp
50755092 }
0 commit comments