diff --git a/compiler/src/dotty/tools/dotc/typer/Namer.scala b/compiler/src/dotty/tools/dotc/typer/Namer.scala index e9264366dfc0..819b43fcec2c 100644 --- a/compiler/src/dotty/tools/dotc/typer/Namer.scala +++ b/compiler/src/dotty/tools/dotc/typer/Namer.scala @@ -1254,7 +1254,13 @@ class Namer { typer: Typer => newSymbol(cls, forwarderName, mbrFlags, mbrInfo, coord = span) forwarder.info = avoidPrivateLeaks(forwarder) - forwarder.addAnnotations(sym.annotations.filterConserve(_.symbol != defn.BodyAnnot)) + forwarder.addAnnotations(sym.annotations.filterConserve { annot => + annot.symbol != defn.BodyAnnot + && annot.symbol != defn.TailrecAnnot + && annot.symbol != defn.MainAnnot + && !annot.symbol.derivesFrom(defn.MacroAnnotationClass) + && !annot.symbol.derivesFrom(defn.MainAnnotationClass) + }) if forwarder.isType then buf += tpd.TypeDef(forwarder.asType).withSpan(span) diff --git a/tests/pos/export-main.scala b/tests/pos/export-main.scala new file mode 100644 index 000000000000..7ce0a23de76f --- /dev/null +++ b/tests/pos/export-main.scala @@ -0,0 +1,5 @@ +object Foo: + @main def baz: Int = 1 + +object Bar: + export Foo.baz // export Foo.baz but not create an new main entry point diff --git a/tests/pos/i19505.scala b/tests/pos/i19505.scala new file mode 100644 index 000000000000..69fb0217c1d7 --- /dev/null +++ b/tests/pos/i19505.scala @@ -0,0 +1,10 @@ +import scala.annotation.tailrec + +object Foo: + @tailrec + def foo(n: Int): Int = + if n == 0 then 0 + else foo(n-1) + +object Bar: + export Foo.foo // def foo here should not have `@tailrec` diff --git a/tests/run-macros/annot-export/Macro_1.scala b/tests/run-macros/annot-export/Macro_1.scala new file mode 100644 index 000000000000..9a8267bfae4b --- /dev/null +++ b/tests/run-macros/annot-export/Macro_1.scala @@ -0,0 +1,13 @@ +import scala.annotation.{experimental, MacroAnnotation} +import scala.quoted._ +import scala.collection.mutable.Map + +@experimental +class returnClassName extends MacroAnnotation { + def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] = + import quotes.reflect._ + tree match + case DefDef(name, params, tpt, _) => + val rhs = Literal(StringConstant(Symbol.spliceOwner.name.stripSuffix("$"))) + List(DefDef.copy(tree)(name, params, tpt, Some(rhs))) +} diff --git a/tests/run-macros/annot-export/Test_2.scala b/tests/run-macros/annot-export/Test_2.scala new file mode 100644 index 000000000000..abae5716bc5d --- /dev/null +++ b/tests/run-macros/annot-export/Test_2.scala @@ -0,0 +1,10 @@ +object Bar: + @returnClassName + def f(): String = ??? // def f(): String = "Bar" + +object Baz: + export Bar.f // def f(): String = Bar.f(n) + +@main def Test = + assert(Bar.f() == "Bar") + assert(Baz.f() == "Bar") diff --git a/tests/warn/i19505.scala b/tests/warn/i19505.scala new file mode 100644 index 000000000000..da0f859b24ad --- /dev/null +++ b/tests/warn/i19505.scala @@ -0,0 +1,8 @@ +import scala.annotation.tailrec + +object Foo: + @tailrec + def foo: Int = foo // warn: Infinite recursive call + +object Bar: + export Foo.foo // def foo here should not have `@tailrec`