Skip to content

Commit 4972375

Browse files
committed
Add message parameter to @experimental annotation
1 parent 43ed9fd commit 4972375

File tree

7 files changed

+42
-16
lines changed

7 files changed

+42
-16
lines changed

compiler/src/dotty/tools/dotc/config/Feature.scala

+19-11
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,7 @@ object Feature:
131131

132132
def checkExperimentalFeature(which: String, srcPos: SrcPos, note: => String = "")(using Context) =
133133
if !isExperimentalEnabled then
134-
report.error(
135-
em"""Experimental $which may only be used under experimental mode:
136-
| 1. in a definition marked as @experimental, or
137-
| 2. compiling with the -experimental compiler flag, or
138-
| 3. with a nightly or snapshot version of the compiler.$note
139-
""", srcPos)
134+
report.error(experimentalUseSite(which) + note, srcPos)
140135

141136
private def ccException(sym: Symbol)(using Context): Boolean =
142137
ccEnabled && defn.ccExperimental.contains(sym)
@@ -146,12 +141,25 @@ object Feature:
146141
if sym.hasAnnotation(defn.ExperimentalAnnot) then sym
147142
else if sym.owner.hasAnnotation(defn.ExperimentalAnnot) then sym.owner
148143
else NoSymbol
149-
if !ccException(experimentalSym) then
150-
val note =
144+
if !isExperimentalEnabled && !ccException(experimentalSym) then
145+
val msg =
146+
import ast.untpd.*
147+
import Constants.Constant
148+
experimentalSym.getAnnotation(defn.ExperimentalAnnot).map(_.tree).collect {
149+
case Apply(_, List(Literal(Constant(msg: String)))) => s": $msg"
150+
}.getOrElse("")
151+
val markedExperimental =
151152
if experimentalSym.exists
152-
then i"$experimentalSym is marked @experimental"
153-
else i"$sym inherits @experimental"
154-
checkExperimentalFeature("definition", srcPos, s"\n\n$note")
153+
then i"$experimentalSym is marked @experimental$msg"
154+
else i"$sym inherits @experimental$msg"
155+
report.error(markedExperimental + "\n\n" + experimentalUseSite("definition"), srcPos)
156+
157+
private def experimentalUseSite(which: String): String =
158+
s"""Experimental $which may only be used under experimental mode:
159+
| 1. in a definition marked as @experimental, or
160+
| 2. compiling with the -experimental compiler flag, or
161+
| 3. with a nightly or snapshot version of the compiler.
162+
|""".stripMargin
155163

156164
/** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */
157165
def checkExperimentalSettings(using Context): Unit =

library/src/scala/annotation/experimental.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ package scala.annotation
66
* @syntax markdown
77
*/
88
@deprecatedInheritance("Scheduled for being final in the future", "3.4.0")
9-
class experimental extends StaticAnnotation
9+
class experimental extends StaticAnnotation:
10+
def this(message: String) = this()

library/src/scala/runtime/stdLibPatches/language.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ object language:
8484
object captureChecking
8585

8686
/** Experimental support for automatic conversions of arguments, without requiring
87-
* a langauge import `import scala.language.implicitConversions`.
87+
* a language import `import scala.language.implicitConversions`.
8888
*
8989
* @see [[https://dotty.epfl.ch/docs/reference/experimental/into-modifier]]
9090
*/

project/MiMaFilters.scala

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ object MiMaFilters {
88
val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(
99
// Additions that require a new minor version of the library
1010
Build.previousDottyVersion -> Seq(
11+
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.annotation.experimental.this"),
1112
),
1213

1314
// Additions since last LTS

tests/neg/experimental-message.check

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Error: tests/neg/experimental-message.scala:8:10 --------------------------------------------------------------------
2+
8 |def g() = f() // error
3+
| ^
4+
| method f is marked @experimental: not yet stable
5+
|
6+
| Experimental definition may only be used under experimental mode:
7+
| 1. in a definition marked as @experimental, or
8+
| 2. compiling with the -experimental compiler flag, or
9+
| 3. with a nightly or snapshot version of the compiler.

tests/neg/experimental-message.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//> using options -Yno-experimental
2+
3+
import scala.annotation.experimental
4+
5+
@experimental("not yet stable")
6+
def f() = ???
7+
8+
def g() = f() // error

tests/neg/use-experimental-def.check

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
-- Error: tests/neg/use-experimental-def.scala:7:15 --------------------------------------------------------------------
22
7 |def bar: Int = foo // error
33
| ^^^
4+
| method foo is marked @experimental
5+
|
46
| Experimental definition may only be used under experimental mode:
57
| 1. in a definition marked as @experimental, or
68
| 2. compiling with the -experimental compiler flag, or
79
| 3. with a nightly or snapshot version of the compiler.
8-
|
9-
| method foo is marked @experimental
10-
|

0 commit comments

Comments
 (0)