Skip to content

Commit

Permalink
Add message parameter to @experimental annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Mar 27, 2024
1 parent 43ed9fd commit 4972375
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 16 deletions.
30 changes: 19 additions & 11 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,7 @@ object Feature:

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

private def ccException(sym: Symbol)(using Context): Boolean =
ccEnabled && defn.ccExperimental.contains(sym)
Expand All @@ -146,12 +141,25 @@ object Feature:
if sym.hasAnnotation(defn.ExperimentalAnnot) then sym
else if sym.owner.hasAnnotation(defn.ExperimentalAnnot) then sym.owner
else NoSymbol
if !ccException(experimentalSym) then
val note =
if !isExperimentalEnabled && !ccException(experimentalSym) then
val msg =
import ast.untpd.*
import Constants.Constant
experimentalSym.getAnnotation(defn.ExperimentalAnnot).map(_.tree).collect {
case Apply(_, List(Literal(Constant(msg: String)))) => s": $msg"
}.getOrElse("")
val markedExperimental =
if experimentalSym.exists
then i"$experimentalSym is marked @experimental"
else i"$sym inherits @experimental"
checkExperimentalFeature("definition", srcPos, s"\n\n$note")
then i"$experimentalSym is marked @experimental$msg"
else i"$sym inherits @experimental$msg"
report.error(markedExperimental + "\n\n" + experimentalUseSite("definition"), srcPos)

private def experimentalUseSite(which: String): String =
s"""Experimental $which may only be used under experimental mode:
| 1. in a definition marked as @experimental, or
| 2. compiling with the -experimental compiler flag, or
| 3. with a nightly or snapshot version of the compiler.
|""".stripMargin

/** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */
def checkExperimentalSettings(using Context): Unit =
Expand Down
3 changes: 2 additions & 1 deletion library/src/scala/annotation/experimental.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ package scala.annotation
* @syntax markdown
*/
@deprecatedInheritance("Scheduled for being final in the future", "3.4.0")
class experimental extends StaticAnnotation
class experimental extends StaticAnnotation:
def this(message: String) = this()
2 changes: 1 addition & 1 deletion library/src/scala/runtime/stdLibPatches/language.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ object language:
object captureChecking

/** Experimental support for automatic conversions of arguments, without requiring
* a langauge import `import scala.language.implicitConversions`.
* a language import `import scala.language.implicitConversions`.
*
* @see [[https://dotty.epfl.ch/docs/reference/experimental/into-modifier]]
*/
Expand Down
1 change: 1 addition & 0 deletions project/MiMaFilters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ object MiMaFilters {
val ForwardsBreakingChanges: Map[String, Seq[ProblemFilter]] = Map(
// Additions that require a new minor version of the library
Build.previousDottyVersion -> Seq(
ProblemFilters.exclude[DirectMissingMethodProblem]("scala.annotation.experimental.this"),
),

// Additions since last LTS
Expand Down
9 changes: 9 additions & 0 deletions tests/neg/experimental-message.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Error: tests/neg/experimental-message.scala:8:10 --------------------------------------------------------------------
8 |def g() = f() // error
| ^
| method f is marked @experimental: not yet stable
|
| Experimental definition may only be used under experimental mode:
| 1. in a definition marked as @experimental, or
| 2. compiling with the -experimental compiler flag, or
| 3. with a nightly or snapshot version of the compiler.
8 changes: 8 additions & 0 deletions tests/neg/experimental-message.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//> using options -Yno-experimental

import scala.annotation.experimental

@experimental("not yet stable")
def f() = ???

def g() = f() // error
5 changes: 2 additions & 3 deletions tests/neg/use-experimental-def.check
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
-- Error: tests/neg/use-experimental-def.scala:7:15 --------------------------------------------------------------------
7 |def bar: Int = foo // error
| ^^^
| method foo is marked @experimental
|
| Experimental definition may only be used under experimental mode:
| 1. in a definition marked as @experimental, or
| 2. compiling with the -experimental compiler flag, or
| 3. with a nightly or snapshot version of the compiler.
|
| method foo is marked @experimental
|

0 comments on commit 4972375

Please sign in to comment.