From 104557127ec82fc9237a0d7949fdcb737552ec18 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Thu, 11 Apr 2024 20:41:44 +0200 Subject: [PATCH] Retain default parameters with `export` Default parameters need to have the `HasDefault` flag set to work properly, it seems that without this flag they were still selected but only under join compilation. While we're at it, we define a full set of flags that might be exported. Note that Given/Implicit/Erased were already set by `tpd.DefDef` and Inlined doesn't seem to make a difference in practice since the body of the exported inline def is manually constructed and doesn't contain proxies either way. --- compiler/src/dotty/tools/dotc/core/Flags.scala | 3 +++ compiler/src/dotty/tools/dotc/typer/Namer.scala | 4 +++- tests/pos/export-param-flags/A_1.scala | 5 +++++ tests/pos/export-param-flags/B_2.scala | 2 ++ tests/printing/export-param-flags.check | 13 +++++++++++++ tests/printing/export-param-flags.scala | 5 +++++ 6 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 tests/pos/export-param-flags/A_1.scala create mode 100644 tests/pos/export-param-flags/B_2.scala create mode 100644 tests/printing/export-param-flags.check create mode 100644 tests/printing/export-param-flags.scala diff --git a/compiler/src/dotty/tools/dotc/core/Flags.scala b/compiler/src/dotty/tools/dotc/core/Flags.scala index 1f38289161cd..8110bc769d4f 100644 --- a/compiler/src/dotty/tools/dotc/core/Flags.scala +++ b/compiler/src/dotty/tools/dotc/core/Flags.scala @@ -535,6 +535,9 @@ object Flags { /** Flags retained in term export forwarders */ val RetainedExportTermFlags = Infix | Given | Implicit | Inline | Transparent | Erased | HasDefaultParams | NoDefaultParams | ExtensionMethod + /** Flags retained in parameters of term export forwarders */ + val RetainedExportTermParamFlags = Given | Implicit | Erased | HasDefault | Inline + val MandatoryExportTermFlags = Exported | Method | Final /** Flags retained in type export forwarders */ diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index 1016fe467a0a..bad78b6714e8 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1293,7 +1293,7 @@ class Namer { typer: Typer => getter => addForwarder( getter.name.asTermName, getter.asSeenFrom(path.tpe), span)) - // adding annotations at the parameter level + // adding annotations and flags at the parameter level // TODO: This probably needs to be filtered to avoid adding some annotation // such as MacroAnnotations if sym.is(Method) then @@ -1301,6 +1301,8 @@ class Namer { typer: Typer => (origParameter, exportedParameter) <- orig.lazyZip(forwarded) do exportedParameter.addAnnotations(origParameter.annotations) + if exportedParameter.isTerm then + exportedParameter.setFlag(origParameter.flags & RetainedExportTermParamFlags) end addForwarder def addForwardersNamed(name: TermName, alias: TermName, span: Span): Unit = diff --git a/tests/pos/export-param-flags/A_1.scala b/tests/pos/export-param-flags/A_1.scala new file mode 100644 index 000000000000..1ac8d10ba930 --- /dev/null +++ b/tests/pos/export-param-flags/A_1.scala @@ -0,0 +1,5 @@ +object A: + def defaultParam(x: Int = 1) = x + +object Exported: + export A.* diff --git a/tests/pos/export-param-flags/B_2.scala b/tests/pos/export-param-flags/B_2.scala new file mode 100644 index 000000000000..0387f66d7aa7 --- /dev/null +++ b/tests/pos/export-param-flags/B_2.scala @@ -0,0 +1,2 @@ +object B: + val x = Exported.defaultParam() diff --git a/tests/printing/export-param-flags.check b/tests/printing/export-param-flags.check new file mode 100644 index 000000000000..ffab6f77c93d --- /dev/null +++ b/tests/printing/export-param-flags.check @@ -0,0 +1,13 @@ +[[syntax trees at end of typer]] // tests/printing/export-param-flags.scala +package { + final lazy module val A: A = new A() + final module class A() extends Object() { this: A.type => + inline def inlinedParam(inline x: Int): Int = x.+(x):Int + } + final lazy module val Exported: Exported = new Exported() + final module class Exported() extends Object() { this: Exported.type => + export A.* + final inline def inlinedParam(inline x: Int): Int = A.inlinedParam(x) + } +} + diff --git a/tests/printing/export-param-flags.scala b/tests/printing/export-param-flags.scala new file mode 100644 index 000000000000..cad2d3c8fee8 --- /dev/null +++ b/tests/printing/export-param-flags.scala @@ -0,0 +1,5 @@ +object A: + inline def inlinedParam(inline x: Int): Int = x + x + +object Exported: + export A.*