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