From 30faeb2793fec47341b0f3f81460932a8c24648b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 21 Aug 2023 11:11:27 +0200 Subject: [PATCH 1/4] Add `MethodType.nonErasedParamCount` --- compiler/src/dotty/tools/dotc/core/TypeErasure.scala | 2 +- compiler/src/dotty/tools/dotc/core/Types.scala | 4 ++++ .../dotty/tools/dotc/transform/ContextFunctionResults.scala | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala index 94c7b2993b97..c201ecd06054 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala @@ -567,7 +567,7 @@ object TypeErasure { functionType(info.resultType) case info: MethodType => assert(!info.resultType.isInstanceOf[MethodicType]) - defn.FunctionType(n = info.erasedParams.count(_ == false)) + defn.FunctionType(n = info.nonErasedParamCount) } erasure(functionType(applyInfo)) } diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index fcf9d984bcf4..8655222284f8 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4021,6 +4021,10 @@ object Types { override def erasedParams(using Context): List[Boolean] = paramInfos.map(p => p.hasAnnotation(defn.ErasedParamAnnot)) + def nonErasedParamCount(using Context): Int = + paramInfos.count(p => !p.hasAnnotation(defn.ErasedParamAnnot)) + + protected def prefixString: String = companion.prefixString } diff --git a/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala b/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala index b4eb71c541d3..f9ffa9e772f8 100644 --- a/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala +++ b/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala @@ -85,13 +85,13 @@ object ContextFunctionResults: else val defn.ContextFunctionType(params, resTpe, erasedParams) = tp: @unchecked val rest = contextParamCount(resTpe, crCount - 1) - if erasedParams.contains(true) then erasedParams.count(_ == false) + rest else params.length + rest + if erasedParams.contains(true) then erasedParams.count(_ == false) + rest else params.length + rest // TODO use mt.nonErasedParamCount def normalParamCount(tp: Type): Int = tp.widenExpr.stripPoly match case mt @ MethodType(pnames) => val rest = normalParamCount(mt.resType) if mt.hasErasedParams then - mt.erasedParams.count(_ == false) + rest + mt.nonErasedParamCount + rest else pnames.length + rest case _ => contextParamCount(tp, contextResultCount(sym)) From 4774df567b08053184c8ab19287e1c18a472f0eb Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 3 Aug 2023 11:05:22 +0200 Subject: [PATCH 2/4] Improve `MethodType.hasErasedParams` --- compiler/src/dotty/tools/dotc/core/Types.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 8655222284f8..0059098c659d 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -4014,7 +4014,8 @@ object Types { final override def isImplicitMethod: Boolean = companion.eq(ImplicitMethodType) || isContextualMethod final override def hasErasedParams(using Context): Boolean = - erasedParams.contains(true) + paramInfos.exists(p => p.hasAnnotation(defn.ErasedParamAnnot)) + final override def isContextualMethod: Boolean = companion.eq(ContextualMethodType) From 785fe5a52bf2d3a60d25da00d0f0215d37a68345 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 3 Aug 2023 13:03:12 +0200 Subject: [PATCH 3/4] Move `erasedParams` into `MethodType` --- compiler/src/dotty/tools/dotc/core/Types.scala | 4 +--- compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Types.scala b/compiler/src/dotty/tools/dotc/core/Types.scala index 0059098c659d..ba7d4e7576c1 100644 --- a/compiler/src/dotty/tools/dotc/core/Types.scala +++ b/compiler/src/dotty/tools/dotc/core/Types.scala @@ -3721,8 +3721,6 @@ object Types { def companion: LambdaTypeCompanion[ThisName, PInfo, This] - def erasedParams(using Context) = List.fill(paramInfos.size)(false) - /** The type `[tparams := paramRefs] tp`, where `tparams` can be * either a list of type parameter symbols or a list of lambda parameters * @@ -4019,7 +4017,7 @@ object Types { final override def isContextualMethod: Boolean = companion.eq(ContextualMethodType) - override def erasedParams(using Context): List[Boolean] = + def erasedParams(using Context): List[Boolean] = paramInfos.map(p => p.hasAnnotation(defn.ErasedParamAnnot)) def nonErasedParamCount(using Context): Int = diff --git a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala index 4d87d6406567..b739bcf1b74d 100644 --- a/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala +++ b/compiler/src/dotty/tools/dotc/printing/PlainPrinter.scala @@ -297,10 +297,10 @@ class PlainPrinter(_ctx: Context) extends Printer { "(" ~ toTextRef(tp) ~ " : " ~ toTextGlobal(tp.underlying) ~ ")" protected def paramsText(lam: LambdaType): Text = { - val erasedParams = lam.erasedParams - def paramText(ref: ParamRef, erased: Boolean) = + def paramText(ref: ParamRef) = + val erased = ref.underlying.hasAnnotation(defn.ErasedParamAnnot) keywordText("erased ").provided(erased) ~ ParamRefNameString(ref) ~ lambdaHash(lam) ~ toTextRHS(ref.underlying, isParameter = true) - Text(lam.paramRefs.lazyZip(erasedParams).map(paramText), ", ") + Text(lam.paramRefs.map(paramText), ", ") } protected def ParamRefNameString(name: Name): String = nameString(name) From fa1f79d3b0ee5f9e2c4161a60cdd4ded4e481099 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 4 Aug 2023 10:23:21 +0200 Subject: [PATCH 4/4] Optimization computing erased argument counts --- .../tools/dotc/transform/ContextFunctionResults.scala | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala b/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala index f9ffa9e772f8..b9478fb893a0 100644 --- a/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala +++ b/compiler/src/dotty/tools/dotc/transform/ContextFunctionResults.scala @@ -85,14 +85,11 @@ object ContextFunctionResults: else val defn.ContextFunctionType(params, resTpe, erasedParams) = tp: @unchecked val rest = contextParamCount(resTpe, crCount - 1) + // TODO use mt.nonErasedParamCount if erasedParams.contains(true) then erasedParams.count(_ == false) + rest else params.length + rest // TODO use mt.nonErasedParamCount def normalParamCount(tp: Type): Int = tp.widenExpr.stripPoly match - case mt @ MethodType(pnames) => - val rest = normalParamCount(mt.resType) - if mt.hasErasedParams then - mt.nonErasedParamCount + rest - else pnames.length + rest + case mt @ MethodType(pnames) => mt.nonErasedParamCount + normalParamCount(mt.resType) case _ => contextParamCount(tp, contextResultCount(sym)) normalParamCount(sym.info)