Skip to content

Refactor function type logic #18193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 13, 2023
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,7 @@ class Definitions {
def PolyFunctionType = PolyFunctionClass.typeRef

lazy val ErasedFunctionClass = requiredClass("scala.runtime.ErasedFunction")
def ErasedFunctionType = ErasedFunctionClass.typeRef

/** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */
def scalaClassName(cls: Symbol)(using Context): TypeName = cls.denot match
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1875,7 +1875,7 @@ object Types {
* @param alwaysDependent if true, always create a dependent function type.
*/
def toFunctionType(isJava: Boolean, dropLast: Int = 0, alwaysDependent: Boolean = false)(using Context): Type = this match {
case mt: MethodType if !mt.isParamDependent =>
case mt: MethodType if !mt.isParamDependent && !mt.hasErasedParams =>
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
val result1 = mt.nonDependentResultApprox match {
Expand All @@ -1888,6 +1888,9 @@ object Types {
if alwaysDependent || mt.isResultDependent then
RefinedType(funType, nme.apply, mt)
else funType
case mt: MethodType if !mt.isParamDependent =>
assert(mt.hasErasedParams)
RefinedType(defn.ErasedFunctionType, nme.apply, mt)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding a case, I suggest changing the existing case mt: MethodType if !mt.isParamDependent => case to contain an if mt.hasErasedParams then ... else ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also moved !mt.isParamDependent into assertions to make it clear that this is unexpected.

case poly @ PolyType(_, mt: MethodType) if !mt.isParamDependent =>
RefinedType(defn.PolyFunctionType, nme.apply, poly)
}
Expand Down
8 changes: 4 additions & 4 deletions tests/run-custom-args/erased/quotes-reflection.check
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ method m2: (i: scala.Int) isGiven=false isImplicit=false erasedArgs=List(true)
method m3: (i: scala.Int, j: scala.Int) isGiven=false isImplicit=false erasedArgs=List(false, true)
method m4: (i: EC) isGiven=false isImplicit=false erasedArgs=List(true)
val l1: scala.ContextFunction1[scala.Int, scala.Int]
val l2: scala.runtime.ErasedFunction with apply: (x$0: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(true)
val l3: scala.runtime.ErasedFunction with apply: (x$0: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=true erasedParams=List(true)
val l4: scala.runtime.ErasedFunction with apply: (x$0: scala.Int, x$1: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(false, true)
val l5: scala.runtime.ErasedFunction with apply: (x$0: EC @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(true)
val l2: scala.runtime.ErasedFunction with apply: (x: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(true)
val l3: scala.runtime.ErasedFunction with apply: (x: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=true erasedParams=List(true)
val l4: scala.runtime.ErasedFunction with apply: (x: scala.Int, y: scala.Int @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(false, true)
val l5: scala.runtime.ErasedFunction with apply: (x: EC @scala.annotation.internal.ErasedParam) isImplicit=false erasedParams=List(true)