@@ -3072,64 +3072,86 @@ object Types {
3072
3072
3073
3073
protected var variance = 1
3074
3074
3075
+ protected def derivedSelect (tp : NamedType , pre : Type ): Type =
3076
+ tp.derivedSelect(pre)
3077
+ protected def derivedRefinedType (tp : RefinedType , parent : Type , info : Type ): Type =
3078
+ tp.derivedRefinedType(parent, tp.refinedName, info)
3079
+ protected def derivedTypeAlias (tp : TypeAlias , alias : Type ): Type =
3080
+ tp.derivedTypeAlias(alias)
3081
+ protected def derivedTypeBounds (tp : TypeBounds , lo : Type , hi : Type ): Type =
3082
+ tp.derivedTypeBounds(lo, hi)
3083
+ protected def derivedSuperType (tp : SuperType , thistp : Type , supertp : Type ): Type =
3084
+ tp.derivedSuperType(thistp, supertp)
3085
+ protected def derivedAndOrType (tp : AndOrType , tp1 : Type , tp2 : Type ): Type =
3086
+ tp.derivedAndOrType(tp1, tp2)
3087
+ protected def derivedSkolemType (tp : SkolemType , info : Type ): Type =
3088
+ tp.derivedSkolemType(info)
3089
+ protected def derivedAnnotatedType (tp : AnnotatedType , underlying : Type , annot : Annotation ): Type =
3090
+ tp.derivedAnnotatedType(underlying, annot)
3091
+ protected def derivedWildcardType (tp : WildcardType , bounds : Type ): Type =
3092
+ tp.derivedWildcardType(bounds)
3093
+ protected def derivedClassInfo (tp : ClassInfo , pre : Type ): Type =
3094
+ tp.derivedClassInfo(pre)
3095
+ protected def derivedJavaArrayType (tp : JavaArrayType , elemtp : Type ): Type =
3096
+ tp.derivedJavaArrayType(elemtp)
3097
+ protected def derivedMethodType (tp : MethodType , formals : List [Type ], restpe : Type ): Type =
3098
+ tp.derivedMethodType(tp.paramNames, formals, restpe)
3099
+ protected def derivedExprType (tp : ExprType , restpe : Type ): Type =
3100
+ tp.derivedExprType(restpe)
3101
+ protected def derivedPolyType (tp : PolyType , pbounds : List [TypeBounds ], restpe : Type ): Type =
3102
+ tp.derivedPolyType(tp.paramNames, pbounds, restpe)
3103
+
3075
3104
/** Map this function over given type */
3076
3105
def mapOver (tp : Type ): Type = {
3077
3106
implicit val ctx : Context = this .ctx // Dotty deviation: implicits need explicit type
3078
3107
tp match {
3079
3108
case tp : NamedType =>
3080
3109
if (stopAtStatic && tp.symbol.isStatic) tp
3081
- else {
3082
- val saved = variance
3083
- variance = 0
3084
- val result = tp.derivedSelect(this (tp.prefix))
3085
- variance = saved
3086
- result
3087
- }
3110
+ else derivedSelect(tp, this (tp.prefix))
3088
3111
3089
3112
case _ : ThisType
3090
3113
| _ : BoundType
3091
3114
| NoPrefix => tp
3092
3115
3093
3116
case tp : RefinedType =>
3094
- tp. derivedRefinedType(this (tp.parent), tp.refinedName , this (tp.refinedInfo))
3117
+ derivedRefinedType(tp, this (tp.parent), this (tp.refinedInfo))
3095
3118
3096
3119
case tp : TypeAlias =>
3097
3120
val saved = variance
3098
3121
variance = variance * tp.variance
3099
3122
val alias1 = this (tp.alias)
3100
3123
variance = saved
3101
- tp. derivedTypeAlias(alias1)
3124
+ derivedTypeAlias(tp, alias1)
3102
3125
3103
3126
case tp : TypeBounds =>
3104
3127
variance = - variance
3105
3128
val lo1 = this (tp.lo)
3106
3129
variance = - variance
3107
- tp. derivedTypeBounds(lo1, this (tp.hi))
3130
+ derivedTypeBounds(tp, lo1, this (tp.hi))
3108
3131
3109
3132
case tp : MethodType =>
3110
3133
def mapOverMethod = {
3111
3134
variance = - variance
3112
3135
val ptypes1 = tp.paramTypes mapConserve this
3113
3136
variance = - variance
3114
- tp. derivedMethodType(tp.paramNames , ptypes1, this (tp.resultType))
3137
+ derivedMethodType(tp, ptypes1, this (tp.resultType))
3115
3138
}
3116
3139
mapOverMethod
3117
3140
3118
3141
case tp : ExprType =>
3119
- tp. derivedExprType(this (tp.resultType))
3142
+ derivedExprType(tp, this (tp.resultType))
3120
3143
3121
3144
case tp : PolyType =>
3122
3145
def mapOverPoly = {
3123
3146
variance = - variance
3124
3147
val bounds1 = tp.paramBounds.mapConserve(this ).asInstanceOf [List [TypeBounds ]]
3125
3148
variance = - variance
3126
- tp.derivedPolyType(
3127
- tp.paramNames, bounds1, this (tp.resultType))
3149
+ derivedPolyType(tp, bounds1, this (tp.resultType))
3128
3150
}
3129
3151
mapOverPoly
3130
3152
3131
3153
case tp @ SuperType (thistp, supertp) =>
3132
- tp. derivedSuperType(this (thistp), this (supertp))
3154
+ derivedSuperType(tp, this (thistp), this (supertp))
3133
3155
3134
3156
case tp : LazyRef =>
3135
3157
LazyRef (() => this (tp.ref))
@@ -3142,20 +3164,21 @@ object Types {
3142
3164
if (inst.exists) apply(inst) else tp
3143
3165
3144
3166
case tp : AndOrType =>
3145
- tp. derivedAndOrType(this (tp.tp1), this (tp.tp2))
3167
+ derivedAndOrType(tp, this (tp.tp1), this (tp.tp2))
3146
3168
3147
3169
case tp : SkolemType =>
3148
- tp. derivedSkolemType(this (tp.info))
3170
+ derivedSkolemType(tp, this (tp.info))
3149
3171
3150
3172
case tp @ AnnotatedType (underlying, annot) =>
3151
3173
val underlying1 = this (underlying)
3152
- if (underlying1 eq underlying) tp else tp.derivedAnnotatedType(underlying1, mapOver(annot))
3174
+ if (underlying1 eq underlying) tp
3175
+ else derivedAnnotatedType(tp, underlying1, mapOver(annot))
3153
3176
3154
3177
case tp @ WildcardType =>
3155
- tp. derivedWildcardType(mapOver(tp.optBounds))
3178
+ derivedWildcardType(tp, mapOver(tp.optBounds))
3156
3179
3157
3180
case tp : JavaArrayType =>
3158
- tp. derivedJavaArrayType(this (tp.elemType))
3181
+ derivedJavaArrayType(tp, this (tp.elemType))
3159
3182
3160
3183
case tp : ProtoType =>
3161
3184
tp.map(this )
@@ -3182,8 +3205,8 @@ object Types {
3182
3205
def mapOver (tree : Tree ): Tree = treeTypeMap(tree)
3183
3206
3184
3207
/** Can be overridden. By default, only the prefix is mapped. */
3185
- protected def mapClassInfo (tp : ClassInfo ): ClassInfo =
3186
- tp. derivedClassInfo(this (tp.prefix))
3208
+ protected def mapClassInfo (tp : ClassInfo ): Type =
3209
+ derivedClassInfo(tp, this (tp.prefix))
3187
3210
3188
3211
def andThen (f : Type => Type ): TypeMap = new TypeMap {
3189
3212
override def stopAtStatic = thisMap.stopAtStatic
@@ -3209,6 +3232,55 @@ object Types {
3209
3232
def apply (tp : Type ) = tp
3210
3233
}
3211
3234
3235
+ abstract class ApproximatingTypeMap (implicit ctx : Context ) extends TypeMap { thisMap =>
3236
+ def approx (lo : Type = defn.NothingType , hi : Type = defn.AnyType ) =
3237
+ if (variance == 0 ) NoType
3238
+ else apply(if (variance < 0 ) lo else hi)
3239
+
3240
+ override protected def derivedSelect (tp : NamedType , pre : Type ) =
3241
+ if (pre eq tp.prefix) tp
3242
+ else tp.info match {
3243
+ case TypeAlias (alias) => apply(alias) // try to heal by following aliases
3244
+ case _ =>
3245
+ if (pre.exists && ! pre.isRef(defn.NothingClass ) && variance > 0 ) tp.derivedSelect(pre)
3246
+ else tp.info match {
3247
+ case TypeBounds (lo, hi) => approx(lo, hi)
3248
+ case _ => approx()
3249
+ }
3250
+ }
3251
+ override protected def derivedRefinedType (tp : RefinedType , parent : Type , info : Type ) =
3252
+ if (parent.exists && info.exists) tp.derivedRefinedType(parent, tp.refinedName, info)
3253
+ else approx(hi = parent)
3254
+ override protected def derivedTypeAlias (tp : TypeAlias , alias : Type ) =
3255
+ if (alias.exists) tp.derivedTypeAlias(alias)
3256
+ else approx(NoType , TypeBounds .empty)
3257
+ override protected def derivedTypeBounds (tp : TypeBounds , lo : Type , hi : Type ) =
3258
+ if (lo.exists && hi.exists) tp.derivedTypeBounds(lo, hi)
3259
+ else approx(NoType ,
3260
+ if (lo.exists) TypeBounds .lower(lo)
3261
+ else if (hi.exists) TypeBounds .upper(hi)
3262
+ else TypeBounds .empty)
3263
+ override protected def derivedSuperType (tp : SuperType , thistp : Type , supertp : Type ) =
3264
+ if (thistp.exists && supertp.exists) tp.derivedSuperType(thistp, supertp)
3265
+ else NoType
3266
+ override protected def derivedAndOrType (tp : AndOrType , tp1 : Type , tp2 : Type ) =
3267
+ if (tp1.exists && tp2.exists) tp.derivedAndOrType(tp1, tp2)
3268
+ else if (tp.isAnd) approx(hi = tp1 & tp2) // if one of tp1d, tp2d exists, it is the result of tp1d & tp2d
3269
+ else approx(lo = tp1 & tp2)
3270
+ override protected def derivedSkolemType (tp : SkolemType , info : Type ) =
3271
+ if (info.exists) tp.derivedSkolemType(info)
3272
+ else NoType
3273
+ override protected def derivedAnnotatedType (tp : AnnotatedType , underlying : Type , annot : Annotation ) =
3274
+ if (underlying.exists) tp.derivedAnnotatedType(underlying, annot)
3275
+ else NoType
3276
+ override protected def derivedWildcardType (tp : WildcardType , bounds : Type ) =
3277
+ if (bounds.exists) tp.derivedWildcardType(bounds)
3278
+ else WildcardType
3279
+ override protected def derivedClassInfo (tp : ClassInfo , pre : Type ): Type =
3280
+ if (pre.exists) tp.derivedClassInfo(pre)
3281
+ else NoType
3282
+ }
3283
+
3212
3284
// ----- TypeAccumulators ----------------------------------------------------
3213
3285
3214
3286
abstract class TypeAccumulator [T ](implicit protected val ctx : Context ) extends ((T , Type ) => T ) {
0 commit comments