Skip to content

Commit

Permalink
Add -experimental compiler flags
Browse files Browse the repository at this point in the history
When enabled, all top-level definitions are annotated as `@experimental`.
This implies that all experimental language features and definitions can
be used in this project.

Note that this does not change the strong guarantees on stability of
non-experimental code. The experimental features can only be used in a
experimental scope (transitively).
  • Loading branch information
nicolasstucki committed Sep 19, 2023
1 parent a37dac6 commit 8719eaf
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ trait CommonScalaSettings:
val explainTypes: Setting[Boolean] = BooleanSetting("-explain-types", "Explain type errors in more detail (deprecated, use -explain instead).", aliases = List("--explain-types", "-explaintypes"))
val unchecked: Setting[Boolean] = BooleanSetting("-unchecked", "Enable additional warnings where generated code depends on assumptions.", initialValue = true, aliases = List("--unchecked"))
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.", aliases = List("--language"))
val experimental: Setting[Boolean] = BooleanSetting("-experimental", "Annotate all top-level definitions with @experimental. This enables the use of experimental features anywhere in the project.")

/* Coverage settings */
val coverageOutputDir = PathSetting("-coverage-out", "Destination for coverage classfiles and instrumentation data.", "", aliases = List("--coverage-out"))
Expand Down
11 changes: 9 additions & 2 deletions compiler/src/dotty/tools/dotc/transform/PostTyper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -379,13 +379,15 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
)
}
case tree: ValDef =>
annotateExperimental(tree.symbol)
registerIfHasMacroAnnotations(tree)
checkErasedDef(tree)
val tree1 = cpy.ValDef(tree)(rhs = normalizeErasedRhs(tree.rhs, tree.symbol))
if tree1.removeAttachment(desugar.UntupledParam).isDefined then
checkStableSelection(tree.rhs)
processValOrDefDef(super.transform(tree1))
case tree: DefDef =>
annotateExperimental(tree.symbol)
registerIfHasMacroAnnotations(tree)
checkErasedDef(tree)
annotateContextResults(tree)
Expand Down Expand Up @@ -537,9 +539,14 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
report.error("`erased` definition cannot be implemented with en expression of type Null", tree.srcPos)

private def annotateExperimental(sym: Symbol)(using Context): Unit =
if sym.is(Module) && sym.companionClass.hasAnnotation(defn.ExperimentalAnnot) then
def isTopLevelDefinitionInSource(sym: Symbol) =
!sym.is(Package) && !sym.name.isPackageObjectName &&
(sym.owner.is(Package) || (sym.owner.name.isPackageObjectName && !sym.isConstructor))
if !sym.hasAnnotation(defn.ExperimentalAnnot)
&& (ctx.settings.experimental.value && isTopLevelDefinitionInSource(sym))
|| (sym.is(Module) && sym.companionClass.hasAnnotation(defn.ExperimentalAnnot))
then
sym.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span))
sym.companionModule.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span))

private def scala2LibPatch(tree: TypeDef)(using Context) =
val sym = tree.symbol
Expand Down
4 changes: 4 additions & 0 deletions docs/_docs/reference/experimental/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ They are enabled by importing the feature or using the `-language` compiler flag
In general, experimental language features can be imported in an experimental scope (see [experimental definitions](../other-new-features/experimental-defs.md)).
They can be imported at the top-level if all top-level definitions are `@experimental`.

### `-experimental` compiler flag

This flag will make all top-level definitions have the `@experimental` annotation. This effectively enables the use of any experimental language feature in the project.

## Experimental language features supported by special compiler options

Some experimental language features that are still in research and development can be enabled with special compiler options. These include
Expand Down
4 changes: 4 additions & 0 deletions docs/_docs/reference/other-new-features/experimental-defs.md
Original file line number Diff line number Diff line change
Expand Up @@ -309,3 +309,7 @@ class MyExperimentalTests {
```

</details>

## `-experimental` compiler flag

This flag will make all top-level definitions have the `@experimental` annotation. This effectively enables the use of any experimental definition or language feature in the project.
10 changes: 10 additions & 0 deletions tests/pos/expeimental-flag-with-lang-feature.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//> using options -experimental -Yno-experimental

import scala.language.experimental.erasedDefinitions
import scala.language.experimental.namedTypeArguments

erased def erasedFun(erased x: Int): Int = x

def namedTypeArgumentsFun[T, U]: Int =
namedTypeArgumentsFun[T = Int, U = Int]
namedTypeArgumentsFun[U = Int, T = Int]
18 changes: 18 additions & 0 deletions tests/pos/expeimental-flag.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//> using options -experimental -Yno-experimental

import scala.annotation.experimental

class Foo:
def foo: Int = experimentalDef

class Bar:
def bar: Int = experimentalDef
object Bar:
def bar: Int = experimentalDef

object Baz:
def bar: Int = experimentalDef

def toplevelMethod: Int = experimentalDef

@experimental def experimentalDef: Int = 1

0 comments on commit 8719eaf

Please sign in to comment.