@@ -5534,13 +5534,16 @@ object Types extends TypeUtils {
5534
5534
* and PolyType not allowed!) according to `possibleSamMethods`.
5535
5535
* - can be instantiated without arguments or with just () as argument.
5536
5536
*
5537
+ * Additionally, a SAM type may contain type aliases refinements if they refine
5538
+ * an existing type member.
5539
+ *
5537
5540
* The pattern `SAMType(samMethod, samParent)` matches a SAM type, where `samMethod` is the
5538
5541
* type of the single abstract method and `samParent` is a subtype of the matched
5539
5542
* SAM type which has been stripped of wildcards to turn it into a valid parent
5540
5543
* type.
5541
5544
*/
5542
5545
object SAMType {
5543
- /** If possible, return a type which is both a subtype of `origTp` and a type
5546
+ /** If possible, return a type which is both a subtype of `origTp` and a (possibly refined) type
5544
5547
* application of `samClass` where none of the type arguments are
5545
5548
* wildcards (thus making it a valid parent type), otherwise return
5546
5549
* NoType.
@@ -5570,27 +5573,41 @@ object Types extends TypeUtils {
5570
5573
* we arbitrarily pick the upper-bound.
5571
5574
*/
5572
5575
def samParent (origTp : Type , samClass : Symbol , samMeth : Symbol )(using Context ): Type =
5573
- val tp = origTp.baseType(samClass)
5576
+ val tp0 = origTp.baseType(samClass)
5577
+
5578
+ /** Copy type aliases refinements to `toTp` from `fromTp` */
5579
+ def withRefinements (toType : Type , fromTp : Type ): Type = fromTp.dealias match
5580
+ case RefinedType (fromParent, name, info : TypeAlias ) if tp0.member(name).exists =>
5581
+ val parent1 = withRefinements(toType, fromParent)
5582
+ RefinedType (toType, name, info)
5583
+ case _ => toType
5584
+ val tp = withRefinements(tp0, origTp)
5585
+
5574
5586
if ! (tp <:< origTp) then NoType
5575
- else tp match
5576
- case tp @ AppliedType (tycon, args) if tp.hasWildcardArg =>
5577
- val accu = new TypeAccumulator [VarianceMap [Symbol ]]:
5578
- def apply (vmap : VarianceMap [Symbol ], t : Type ): VarianceMap [Symbol ] = t match
5579
- case tp : TypeRef if tp.symbol.isAllOf(ClassTypeParam ) =>
5580
- vmap.recordLocalVariance(tp.symbol, variance)
5581
- case _ =>
5582
- foldOver(vmap, t)
5583
- val vmap = accu(VarianceMap .empty, samMeth.info)
5584
- val tparams = tycon.typeParamSymbols
5585
- val args1 = args.zipWithConserve(tparams):
5586
- case (arg @ TypeBounds (lo, hi), tparam) =>
5587
- val v = vmap.computedVariance(tparam)
5588
- if v.uncheckedNN < 0 then lo
5589
- else hi
5590
- case (arg, _) => arg
5591
- tp.derivedAppliedType(tycon, args1)
5592
- case _ =>
5593
- tp
5587
+ else
5588
+ def approxWildcardArgs (tp : Type ): Type = tp match
5589
+ case tp @ AppliedType (tycon, args) if tp.hasWildcardArg =>
5590
+ val accu = new TypeAccumulator [VarianceMap [Symbol ]]:
5591
+ def apply (vmap : VarianceMap [Symbol ], t : Type ): VarianceMap [Symbol ] = t match
5592
+ case tp : TypeRef if tp.symbol.isAllOf(ClassTypeParam ) =>
5593
+ vmap.recordLocalVariance(tp.symbol, variance)
5594
+ case _ =>
5595
+ foldOver(vmap, t)
5596
+ val vmap = accu(VarianceMap .empty, samMeth.info)
5597
+ val tparams = tycon.typeParamSymbols
5598
+ val args1 = args.zipWithConserve(tparams):
5599
+ case (arg @ TypeBounds (lo, hi), tparam) =>
5600
+ val v = vmap.computedVariance(tparam)
5601
+ if v.uncheckedNN < 0 then lo
5602
+ else hi
5603
+ case (arg, _) => arg
5604
+ tp.derivedAppliedType(tycon, args1)
5605
+ case tp @ RefinedType (parent, name, info) =>
5606
+ tp.derivedRefinedType(approxWildcardArgs(parent), name, info)
5607
+ case _ =>
5608
+ tp
5609
+ approxWildcardArgs(tp)
5610
+ end samParent
5594
5611
5595
5612
def samClass (tp : Type )(using Context ): Symbol = tp match
5596
5613
case tp : ClassInfo =>
0 commit comments