Skip to content

Commit fff24b1

Browse files
authored
Do not propagate @tailrec to exported methods (#19509)
Fixes #19505
2 parents 21c2289 + ef4888b commit fff24b1

File tree

6 files changed

+53
-1
lines changed

6 files changed

+53
-1
lines changed

Diff for: compiler/src/dotty/tools/dotc/typer/Namer.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -1254,7 +1254,13 @@ class Namer { typer: Typer =>
12541254
newSymbol(cls, forwarderName, mbrFlags, mbrInfo, coord = span)
12551255

12561256
forwarder.info = avoidPrivateLeaks(forwarder)
1257-
forwarder.addAnnotations(sym.annotations.filterConserve(_.symbol != defn.BodyAnnot))
1257+
forwarder.addAnnotations(sym.annotations.filterConserve { annot =>
1258+
annot.symbol != defn.BodyAnnot
1259+
&& annot.symbol != defn.TailrecAnnot
1260+
&& annot.symbol != defn.MainAnnot
1261+
&& !annot.symbol.derivesFrom(defn.MacroAnnotationClass)
1262+
&& !annot.symbol.derivesFrom(defn.MainAnnotationClass)
1263+
})
12581264

12591265
if forwarder.isType then
12601266
buf += tpd.TypeDef(forwarder.asType).withSpan(span)

Diff for: tests/pos/export-main.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Foo:
2+
@main def baz: Int = 1
3+
4+
object Bar:
5+
export Foo.baz // export Foo.baz but not create an new main entry point

Diff for: tests/pos/i19505.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.annotation.tailrec
2+
3+
object Foo:
4+
@tailrec
5+
def foo(n: Int): Int =
6+
if n == 0 then 0
7+
else foo(n-1)
8+
9+
object Bar:
10+
export Foo.foo // def foo here should not have `@tailrec`

Diff for: tests/run-macros/annot-export/Macro_1.scala

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.annotation.{experimental, MacroAnnotation}
2+
import scala.quoted._
3+
import scala.collection.mutable.Map
4+
5+
@experimental
6+
class returnClassName extends MacroAnnotation {
7+
def transform(using Quotes)(tree: quotes.reflect.Definition): List[quotes.reflect.Definition] =
8+
import quotes.reflect._
9+
tree match
10+
case DefDef(name, params, tpt, _) =>
11+
val rhs = Literal(StringConstant(Symbol.spliceOwner.name.stripSuffix("$")))
12+
List(DefDef.copy(tree)(name, params, tpt, Some(rhs)))
13+
}

Diff for: tests/run-macros/annot-export/Test_2.scala

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Bar:
2+
@returnClassName
3+
def f(): String = ??? // def f(): String = "Bar"
4+
5+
object Baz:
6+
export Bar.f // def f(): String = Bar.f(n)
7+
8+
@main def Test =
9+
assert(Bar.f() == "Bar")
10+
assert(Baz.f() == "Bar")

Diff for: tests/warn/i19505.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.annotation.tailrec
2+
3+
object Foo:
4+
@tailrec
5+
def foo: Int = foo // warn: Infinite recursive call
6+
7+
object Bar:
8+
export Foo.foo // def foo here should not have `@tailrec`

0 commit comments

Comments
 (0)