Skip to content

Commit 99ba6de

Browse files
committed
Align SAM test and expansion
1 parent 4696911 commit 99ba6de

File tree

2 files changed

+9
-37
lines changed

2 files changed

+9
-37
lines changed

compiler/src/dotty/tools/dotc/ast/tpd.scala

+5-17
Original file line numberDiff line numberDiff line change
@@ -328,21 +328,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
328328
superArgs: List[Tree] = Nil, adaptVarargs: Boolean = false)(using Context): TypeDef =
329329
val firstParent :: otherParents = cls.info.parents: @unchecked
330330

331-
def isApplicable(constr: Symbol): Boolean =
332-
def recur(ctpe: Type): Boolean = ctpe match
333-
case ctpe: PolyType =>
334-
recur(ctpe.instantiate(firstParent.argTypes))
335-
case ctpe: MethodType =>
336-
var paramInfos = ctpe.paramInfos
337-
if adaptVarargs && paramInfos.length == superArgs.length + 1
338-
&& atPhaseNoLater(Phases.elimRepeatedPhase)(constr.info.isVarArgsMethod)
339-
then // accept missing argument for varargs parameter
340-
paramInfos = paramInfos.init
341-
superArgs.corresponds(paramInfos)(_.tpe <:< _)
342-
case _ =>
343-
false
344-
recur(constr.info)
345-
346331
def adaptedSuperArgs(ctpe: Type): List[Tree] = ctpe match
347332
case ctpe: PolyType =>
348333
adaptedSuperArgs(ctpe.instantiate(firstParent.argTypes))
@@ -357,8 +342,11 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
357342
val superRef =
358343
if cls.is(Trait) then TypeTree(firstParent)
359344
else
360-
val constr = firstParent.decl(nme.CONSTRUCTOR).suchThat(isApplicable)
361-
New(firstParent, constr.symbol.asTerm, adaptedSuperArgs(constr.info))
345+
val parentConstr = firstParent.applicableConstructors(superArgs.tpes, adaptVarargs) match
346+
case Nil => assert(false, i"no applicable parent constructor of $firstParent for supercall arguments $superArgs")
347+
case constr :: Nil => constr
348+
case _ => assert(false, i"multiple applicable parent constructors of $firstParent for supercall arguments $superArgs")
349+
New(firstParent, parentConstr.asTerm, adaptedSuperArgs(parentConstr.info))
362350

363351
ClassDefWithParents(cls, constr, superRef :: otherParents.map(TypeTree(_)), body)
364352
end ClassDef

compiler/src/dotty/tools/dotc/core/Types.scala

+4-20
Original file line numberDiff line numberDiff line change
@@ -5945,30 +5945,14 @@ object Types extends TypeUtils {
59455945
def samClass(tp: Type)(using Context): Symbol = tp match
59465946
case tp: ClassInfo =>
59475947
val cls = tp.cls
5948-
def zeroParamsOLD(tp: Type): Boolean = tp.stripPoly match
5949-
case mt: MethodType => mt.paramInfos.isEmpty && !mt.resultType.isInstanceOf[MethodType]
5950-
case et: ExprType => true
5951-
case _ => false
5952-
val validCtorOLD =
5953-
val ctor = cls.primaryConstructor
5954-
// `ContextFunctionN` does not have constructors
5955-
!ctor.exists || zeroParamsOLD(ctor.info)
5956-
59575948
def takesNoArgs(tp: Type) =
5958-
!tp.classSymbol.primaryConstructor.exists // `ContextFunctionN` does not have constructors
5959-
|| tp.applicableConstructors(Nil, adaptVarargs = true).nonEmpty
5960-
def firstParentCls = tp.parents.head.classSymbol
5949+
!tp.classSymbol.primaryConstructor.exists
5950+
// e.g. `ContextFunctionN` does not have constructors
5951+
|| tp.applicableConstructors(Nil, adaptVarargs = true).lengthCompare(1) == 0
5952+
// we require a unique constructor so that SAM expansion is deterministic
59615953
val noArgsNeeded: Boolean =
59625954
takesNoArgs(tp)
59635955
&& (!tp.cls.is(Trait) || takesNoArgs(tp.parents.head))
5964-
5965-
if noArgsNeeded != validCtorOLD then
5966-
println(
5967-
i"""SAM change for $tp with parent ${firstParentCls.fullName}, now $noArgsNeeded
5968-
|takesNoArgs: ${takesNoArgs(tp)}
5969-
|takesNoArgsParent: ${takesNoArgs(tp.cls.info.parents.head)}
5970-
|primary: ${firstParentCls.primaryConstructor.info}""")
5971-
59725956
def isInstantiable =
59735957
!tp.cls.isOneOf(FinalOrSealed) && (tp.appliedRef <:< tp.selfType)
59745958
if noArgsNeeded && isInstantiable then tp.cls

0 commit comments

Comments
 (0)