@@ -272,50 +272,24 @@ trait ConstraintHandling[AbstractContext] {
272
272
}
273
273
}
274
274
275
- /** Widen inferred type `tp` with upper bound `bound`, according to the following rules:
276
- * 1. If `tp` is a singleton type, yet `bound` is not a singleton type, nor a subtype
277
- * of `scala.Singleton`, widen `tp`.
278
- * 2. If `tp` is a union type, yet upper bound is not a union type,
279
- * approximate the union type from above by an intersection of all common base types.
275
+ /** Widen inferred type `inst` with upper `bound`, according to the following rules:
276
+ * 1. If `inst` is a singleton type, or a union containing some singleton types,
277
+ * widen (all) the singleton type(s), provied the result is a subtype of `bound`
278
+ * (i.e. `inst.widenSingletons <:< bound` succeeds with satisfiable constraint).
279
+ * 2. If `inst` is a union type, approximate the union type from above by an intersection
280
+ * of all common base types, provied the result is a subtype of `bound`.
280
281
*
281
282
* At this point we also drop the @Repeated annotation to avoid inferring type arguments with it,
282
283
* as those could leak the annotation to users (see run/inferred-repeated-result).
283
284
*/
284
- def widenInferred (tp : Type , bound : Type )(implicit actx : AbstractContext ): Type = {
285
- def isMultiSingleton (tp : Type ): Boolean = tp.stripAnnots match {
286
- case tp : SingletonType => true
287
- case AndType (tp1, tp2) => isMultiSingleton(tp1) | isMultiSingleton(tp2)
288
- case OrType (tp1, tp2) => isMultiSingleton(tp1) & isMultiSingleton(tp2)
289
- case tp : TypeRef => isMultiSingleton(tp.info.hiBound)
290
- case tp : TypeVar => isMultiSingleton(tp.underlying)
291
- case tp : TypeParamRef => isMultiSingleton(bounds(tp).hi)
292
- case _ => false
293
- }
294
- def isOrType (tp : Type ): Boolean = tp.dealias match {
295
- case tp : OrType => true
296
- case tp : RefinedOrRecType => isOrType(tp.parent)
297
- case AndType (tp1, tp2) => isOrType(tp1) | isOrType(tp2)
298
- case WildcardType (bounds : TypeBounds ) => isOrType(bounds.hi)
299
- case _ => false
300
- }
301
- def widenOr (tp : Type ) =
302
- if (isOrType(tp) && ! isOrType(bound)) tp.widenUnion
303
- else tp
304
- def widenSingle (tp : Type ) =
305
- if (isMultiSingleton(tp) && ! isMultiSingleton(bound) &&
306
- ! isSubTypeWhenFrozen(bound, defn.SingletonType )) tp.widen
307
- else tp
308
- widenOr(widenSingle(tp)).dropRepeatedAnnot
309
- }
310
-
311
- def widenInferred2 (inst : Type , param : TypeParamRef )(implicit actx : AbstractContext ): Type = {
285
+ def widenInferred (inst : Type , bound : Type )(implicit actx : AbstractContext ): Type = {
312
286
def widenSingle (tp : Type ) = {
313
- val tpw = tp.widen
314
- if ((tpw ne tp) && tpw <:< param ) tpw else tp
287
+ val tpw = tp.widenSingletons
288
+ if ((tpw ne tp) && tpw <:< bound ) tpw else tp
315
289
}
316
290
def widenOr (tp : Type ) = {
317
291
val tpw = tp.widenUnion
318
- if ((tpw ne tp) && tpw <:< param ) tpw else tp
292
+ if ((tpw ne tp) && tpw <:< bound ) tpw else tp
319
293
}
320
294
widenOr(widenSingle(inst)).dropRepeatedAnnot
321
295
}
@@ -328,7 +302,7 @@ trait ConstraintHandling[AbstractContext] {
328
302
*/
329
303
def instanceType (param : TypeParamRef , fromBelow : Boolean )(implicit actx : AbstractContext ): Type = {
330
304
val inst = approximation(param, fromBelow).simplified
331
- if (fromBelow) widenInferred2 (inst, /* constraint.fullUpperBound */ ( param) ) else inst
305
+ if (fromBelow) widenInferred (inst, param) else inst
332
306
}
333
307
334
308
/** Constraint `c1` subsumes constraint `c2`, if under `c2` as constraint we have
0 commit comments