@@ -5534,13 +5534,16 @@ object Types extends TypeUtils {
55345534 * and PolyType not allowed!) according to `possibleSamMethods`.
55355535 * - can be instantiated without arguments or with just () as argument.
55365536 *
5537+ * Additionally, a SAM type may contain type aliases refinements if they refine
5538+ * an existing type member.
5539+ *
55375540 * The pattern `SAMType(samMethod, samParent)` matches a SAM type, where `samMethod` is the
55385541 * type of the single abstract method and `samParent` is a subtype of the matched
55395542 * SAM type which has been stripped of wildcards to turn it into a valid parent
55405543 * type.
55415544 */
55425545 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
55445547 * application of `samClass` where none of the type arguments are
55455548 * wildcards (thus making it a valid parent type), otherwise return
55465549 * NoType.
@@ -5570,27 +5573,41 @@ object Types extends TypeUtils {
55705573 * we arbitrarily pick the upper-bound.
55715574 */
55725575 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+
55745586 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
55945611
55955612 def samClass (tp : Type )(using Context ): Symbol = tp match
55965613 case tp : ClassInfo =>
0 commit comments