@@ -5536,13 +5536,16 @@ object Types {
55365536 * and PolyType not allowed!) according to `possibleSamMethods`.
55375537 * - can be instantiated without arguments or with just () as argument.
55385538 *
5539+ * Additionally, a SAM type may contain type aliases refinements if they refine
5540+ * an existing type member.
5541+ *
55395542 * The pattern `SAMType(samMethod, samParent)` matches a SAM type, where `samMethod` is the
55405543 * type of the single abstract method and `samParent` is a subtype of the matched
55415544 * SAM type which has been stripped of wildcards to turn it into a valid parent
55425545 * type.
55435546 */
55445547 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
55465549 * application of `samClass` where none of the type arguments are
55475550 * wildcards (thus making it a valid parent type), otherwise return
55485551 * NoType.
@@ -5572,27 +5575,41 @@ object Types {
55725575 * we arbitrarily pick the upper-bound.
55735576 */
55745577 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+
55765588 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
55965613
55975614 def samClass (tp : Type )(using Context ): Symbol = tp match
55985615 case tp : ClassInfo =>
0 commit comments