Skip to content

Commit

Permalink
Simplify use of toFunctionType (#18429)
Browse files Browse the repository at this point in the history
Make `isJava` by default `false` and remove `dropLast` argument.

Part of #18305. Note that the use of `toFunctionType` will increase, and
most will not be java functions.
  • Loading branch information
odersky authored Aug 29, 2023
2 parents 8c311a0 + 3419d8a commit 8f621c6
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 14 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala
Original file line number Diff line number Diff line change
Expand Up @@ -698,7 +698,7 @@ class CheckCaptures extends Recheck, SymTransformer:

private def toDepFun(args: List[Type], resultType: Type, isContextual: Boolean)(using Context): Type =
MethodType.companion(isContextual = isContextual)(args, resultType)
.toFunctionType(isJava = false, alwaysDependent = true)
.toFunctionType(alwaysDependent = true)

/** Turn `expected` into a dependent function when `actual` is dependent. */
private def alignDependentFunction(expected: Type, actual: Type)(using Context): Type =
Expand Down Expand Up @@ -850,7 +850,7 @@ class CheckCaptures extends Recheck, SymTransformer:
adaptFun(actual, rinfo.paramInfos, rinfo.resType, expected, covariant, insertBox,
(aargs1, ares1) =>
rinfo.derivedLambdaType(paramInfos = aargs1, resType = ares1)
.toFunctionType(isJava = false, alwaysDependent = true))
.toFunctionType(alwaysDependent = true))
case actual: MethodType =>
adaptFun(actual, actual.paramInfos, actual.resType, expected, covariant, insertBox,
(aargs1, ares1) =>
Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dotty/tools/dotc/cc/Setup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ extends tpd.TreeTraverser:
MethodType.companion(
isContextual = defn.isContextFunctionClass(tycon.classSymbol),
)(argTypes, resType)
.toFunctionType(isJava = false, alwaysDependent = true)
.toFunctionType(alwaysDependent = true)

/** If `tp` is an unboxed capturing type or a function returning an unboxed capturing type,
* convert it to be boxed.
Expand All @@ -57,7 +57,7 @@ extends tpd.TreeTraverser:
case tp1 @ RefinedType(_, _, rinfo: MethodType) if defn.isFunctionType(tp1) =>
val boxedRinfo = recur(rinfo)
if boxedRinfo eq rinfo then tp
else boxedRinfo.toFunctionType(isJava = false, alwaysDependent = true)
else boxedRinfo.toFunctionType(alwaysDependent = true)
case tp1: MethodOrPoly =>
val res = tp1.resType
val boxedRes = recur(res)
Expand Down Expand Up @@ -151,7 +151,7 @@ extends tpd.TreeTraverser:
tp.derivedAppliedType(tycon1, args.mapConserve(arg => this(arg)))
case tp @ RefinedType(core, rname, rinfo: MethodType) if defn.isFunctionType(tp) =>
val rinfo1 = apply(rinfo)
if rinfo1 ne rinfo then rinfo1.toFunctionType(isJava = false, alwaysDependent = true)
if rinfo1 ne rinfo then rinfo1.toFunctionType(alwaysDependent = true)
else tp
case tp: MethodType =>
tp.derivedLambdaType(
Expand Down
8 changes: 3 additions & 5 deletions compiler/src/dotty/tools/dotc/core/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1878,22 +1878,20 @@ object Types {

/** Turn type into a function type.
* @pre this is a method type without parameter dependencies.
* @param dropLast the number of trailing parameters that should be dropped
* when forming the function type.
* @param isJava translate repeated params as as java `Array`s?
* @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 {
def toFunctionType(isJava: Boolean = false, alwaysDependent: Boolean = false)(using Context): Type = this match {
case mt: MethodType =>
assert(!mt.isParamDependent)
def nonDependentFunType =
val formals1 = if (dropLast == 0) mt.paramInfos else mt.paramInfos dropRight dropLast
val isContextual = mt.isContextualMethod && !ctx.erasedTypes
val result1 = mt.nonDependentResultApprox match {
case res: MethodType => res.toFunctionType(isJava)
case res => res
}
defn.FunctionOf(
formals1 mapConserve (_.translateFromRepeated(toArray = isJava)),
mt.paramInfos.mapConserve(_.translateFromRepeated(toArray = isJava)),
result1, isContextual)
if mt.hasErasedParams then
defn.PolyFunctionOf(mt)
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/transform/Recheck.scala
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ abstract class Recheck extends Phase, SymTransformer:

def recheckClosure(tree: Closure, pt: Type)(using Context): Type =
if tree.tpt.isEmpty then
tree.meth.tpe.widen.toFunctionType(tree.meth.symbol.is(JavaDefined))
tree.meth.tpe.widen.toFunctionType(isJava = tree.meth.symbol.is(JavaDefined))
else
recheck(tree.tpt)

Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/Splicing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ class Splicing extends MacroTransform:
if tree.isTerm then
if isCaptured(tree.symbol) then
val tpe = tree.tpe.widenTermRefExpr match {
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
case tpw: MethodicType => tpw.toFunctionType()
case tpw => tpw
}
spliced(tpe)(capturedTerm(tree))
Expand Down Expand Up @@ -291,7 +291,7 @@ class Splicing extends MacroTransform:

private def capturedTerm(tree: Tree)(using Context): Tree =
val tpe = tree.tpe.widenTermRefExpr match
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
case tpw: MethodicType => tpw.toFunctionType()
case tpw => tpw
capturedTerm(tree, tpe)

Expand Down
12 changes: 11 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,17 @@ trait TypeAssigner {

def assignType(tree: untpd.Closure, meth: Tree, target: Tree)(using Context): Closure =
tree.withType(
if (target.isEmpty) meth.tpe.widen.toFunctionType(isJava = meth.symbol.is(JavaDefined), tree.env.length)
if target.isEmpty then
def methTypeWithoutEnv(info: Type): Type = info match
case mt: MethodType =>
val dropLast = tree.env.length
val paramNames = mt.paramNames.dropRight(dropLast)
val paramInfos = mt.paramInfos.dropRight(dropLast)
mt.derivedLambdaType(paramNames, paramInfos)
case pt: PolyType =>
pt.derivedLambdaType(resType = methTypeWithoutEnv(pt.resType))
val methodicType = if tree.env.isEmpty then meth.tpe.widen else methTypeWithoutEnv(meth.tpe.widen)
methodicType.toFunctionType(isJava = meth.symbol.is(JavaDefined))
else target.tpe)

def assignType(tree: untpd.CaseDef, pat: Tree, body: Tree)(using Context): CaseDef = {
Expand Down

0 comments on commit 8f621c6

Please sign in to comment.