@@ -300,6 +300,8 @@ trait ConstraintHandling[AbstractContext] {
300
300
* (i.e. `inst.widenSingletons <:< bound` succeeds with satisfiable constraint)
301
301
* 2. If `inst` is a union type, approximate the union type from above by an intersection
302
302
* of all common base types, provided the result is a subtype of `bound`.
303
+ * 3. If `inst` is an intersection with some protected base types, drop
304
+ * the protected base types from the intersection, provided the result is a subtype of `bound`.
303
305
*
304
306
* Don't do these widenings if `bound` is a subtype of `scala.Singleton`.
305
307
* Also, if the result of these widenings is a TypeRef to a module class,
@@ -309,26 +311,43 @@ trait ConstraintHandling[AbstractContext] {
309
311
* At this point we also drop the @Repeated annotation to avoid inferring type arguments with it,
310
312
* as those could leak the annotation to users (see run/inferred-repeated-result).
311
313
*/
312
- def widenInferred (inst : Type , bound : Type )(implicit actx : AbstractContext ): Type = {
313
- def widenOr (tp : Type ) = {
314
+ def widenInferred (inst : Type , bound : Type )(implicit actx : AbstractContext ): Type =
315
+
316
+ def isProtected (tp : Type ) = tp.typeSymbol == defn.EnumValueClass // for now, to be generalized later
317
+
318
+ def dropProtected (tp : Type ): Type = tp.dealias match
319
+ case tp @ AndType (tp1, tp2) =>
320
+ if isProtected(tp1) then tp2
321
+ else if isProtected(tp2) then tp1
322
+ else tp.derivedAndType(dropProtected(tp1), dropProtected(tp2))
323
+ case _ =>
324
+ tp
325
+
326
+ def widenProtected (tp : Type ) =
327
+ val tpw = dropProtected(tp)
328
+ if (tpw ne tp) && (tpw <:< bound) then tpw else tp
329
+
330
+ def widenOr (tp : Type ) =
314
331
val tpw = tp.widenUnion
315
332
if (tpw ne tp) && (tpw <:< bound) then tpw else tp
316
- }
317
- def widenSingle (tp : Type ) = {
333
+
334
+ def widenSingle (tp : Type ) =
318
335
val tpw = tp.widenSingletons
319
336
if (tpw ne tp) && (tpw <:< bound) then tpw else tp
320
- }
337
+
321
338
def isSingleton (tp : Type ): Boolean = tp match
322
339
case WildcardType (optBounds) => optBounds.exists && isSingleton(optBounds.bounds.hi)
323
340
case _ => isSubTypeWhenFrozen(tp, defn.SingletonType )
341
+
324
342
val wideInst =
325
- if isSingleton(bound) then inst else widenOr(widenSingle(inst))
343
+ if isSingleton(bound) then inst
344
+ else widenProtected(widenOr(widenSingle(inst)))
326
345
wideInst match
327
346
case wideInst : TypeRef if wideInst.symbol.is(Module ) =>
328
347
TermRef (wideInst.prefix, wideInst.symbol.sourceModule)
329
348
case _ =>
330
349
wideInst.dropRepeatedAnnot
331
- }
350
+ end widenInferred
332
351
333
352
/** The instance type of `param` in the current constraint (which contains `param`).
334
353
* If `fromBelow` is true, the instance type is the lub of the parameter's
0 commit comments