diff --git a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala index 039a9623ff5f..4d41ee55f3a9 100644 --- a/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala +++ b/compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala @@ -630,7 +630,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 = @@ -774,7 +774,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) => diff --git a/compiler/src/dotty/tools/dotc/cc/Setup.scala b/compiler/src/dotty/tools/dotc/cc/Setup.scala index 94219da31bdf..463919e85893 100644 --- a/compiler/src/dotty/tools/dotc/cc/Setup.scala +++ b/compiler/src/dotty/tools/dotc/cc/Setup.scala @@ -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. @@ -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) @@ -233,7 +233,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( diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 0bae5ce07722..755214954e61 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -1858,20 +1858,18 @@ 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 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 { case res: MethodType => res.toFunctionType(isJava) case res => res } val funType = defn.FunctionOf( - formals1 mapConserve (_.translateFromRepeated(toArray = isJava)), + mt.paramInfos.mapConserve(_.translateFromRepeated(toArray = isJava)), result1, isContextual) if alwaysDependent || mt.isResultDependent then RefinedType(funType, nme.apply, mt) diff --git a/compiler/src/dotty/tools/dotc/transform/Recheck.scala b/compiler/src/dotty/tools/dotc/transform/Recheck.scala index f75c8f00dd16..503045779dce 100644 --- a/compiler/src/dotty/tools/dotc/transform/Recheck.scala +++ b/compiler/src/dotty/tools/dotc/transform/Recheck.scala @@ -324,7 +324,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) diff --git a/compiler/src/dotty/tools/dotc/transform/Splicing.scala b/compiler/src/dotty/tools/dotc/transform/Splicing.scala index ff5dc5042eaf..f5d8e82de78e 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicing.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicing.scala @@ -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)) @@ -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) diff --git a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala index 4a81e6ff017d..b57866d43a37 100644 --- a/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala +++ b/compiler/src/dotty/tools/dotc/typer/TypeAssigner.scala @@ -401,7 +401,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 = {