Skip to content

Commit

Permalink
Change scheme again
Browse files Browse the repository at this point in the history
  • Loading branch information
odersky committed Sep 16, 2024
1 parent 24916b0 commit 4696911
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
21 changes: 21 additions & 0 deletions compiler/src/dotty/tools/dotc/core/TypeUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Names.{Name, TermName}
import Constants.Constant

import Names.Name
import StdNames.nme
import config.Feature

class TypeUtils:
Expand Down Expand Up @@ -189,5 +190,25 @@ class TypeUtils:
def stripRefinement: Type = self match
case self: RefinedOrRecType => self.parent.stripRefinement
case seld => self

def applicableConstructors(argTypes: List[Type], adaptVarargs: Boolean)(using Context): List[Symbol] =
def isApplicable(constr: Symbol): Boolean =
def recur(ctpe: Type): Boolean = ctpe match
case ctpe: PolyType =>
if argTypes.isEmpty then recur(ctpe.resultType) // no need to know instances
else recur(ctpe.instantiate(self.argTypes))
case ctpe: MethodType =>
var paramInfos = ctpe.paramInfos
if adaptVarargs && paramInfos.length == argTypes.length + 1
&& atPhaseNoLater(Phases.elimRepeatedPhase)(constr.info.isVarArgsMethod)
then // accept missing argument for varargs parameter
paramInfos = paramInfos.init
argTypes.corresponds(paramInfos)(_ <:< _)
case _ =>
false
recur(constr.info)

self.decl(nme.CONSTRUCTOR).altsWith(isApplicable).map(_.symbol)

end TypeUtils

20 changes: 5 additions & 15 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5954,27 +5954,17 @@ object Types extends TypeUtils {
// `ContextFunctionN` does not have constructors
!ctor.exists || zeroParamsOLD(ctor.info)

def zeroParams(tp: Type): Boolean = tp.stripPoly match
case mt: MethodType =>
val noArgsNeeded = mt.paramInfos match
case Nil => true
case info :: Nil => info.isRepeatedParam
case _ => false
noArgsNeeded && !mt.resultType.isInstanceOf[MethodType]
case et: ExprType => true
case _ => false
def takesNoArgs(tp: Type) =
val constrs = tp.decl(nme.CONSTRUCTOR)
!constrs.exists // `ContextFunctionN` does not have constructors
|| constrs.hasAltWith(constr => zeroParams(constr.info))
def firstParentCls = cls.info.parents.head.classSymbol
!tp.classSymbol.primaryConstructor.exists // `ContextFunctionN` does not have constructors
|| tp.applicableConstructors(Nil, adaptVarargs = true).nonEmpty
def firstParentCls = tp.parents.head.classSymbol
val noArgsNeeded: Boolean =
takesNoArgs(tp)
&& (!tp.cls.is(Trait) || takesNoArgs(tp.cls.info.parents.head))
&& (!tp.cls.is(Trait) || takesNoArgs(tp.parents.head))

if noArgsNeeded != validCtorOLD then
println(
i"""SAM change for $tp / ${tp.cls.fullName} with parent ${firstParentCls.fullName}, now $noArgsNeeded
i"""SAM change for $tp with parent ${firstParentCls.fullName}, now $noArgsNeeded
|takesNoArgs: ${takesNoArgs(tp)}
|takesNoArgsParent: ${takesNoArgs(tp.cls.info.parents.head)}
|primary: ${firstParentCls.primaryConstructor.info}""")
Expand Down

0 comments on commit 4696911

Please sign in to comment.