Skip to content

Commit a0e0a73

Browse files
committed
Fix #11774: only enable experimental features for snapshot and nightly
1 parent 4035f51 commit a0e0a73

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

compiler/src/dotty/tools/dotc/Driver.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class Driver {
7777
val ictx = rootCtx.fresh
7878
val summary = command.distill(args, ictx.settings)(ictx.settingsState)(using ictx)
7979
ictx.setSettings(summary.sstate)
80+
Feature.checkExperimentalFlags(using ictx)
8081
MacroClassLoader.init(ictx)
8182
Positioned.init(using ictx)
8283

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
275275

276276
def isLanguageImport(path: Tree): Boolean = languageImport(path).isDefined
277277

278+
def isExperimentalImport(path: Tree): Boolean =
279+
languageImport(path) match
280+
case Some(nme.experimental) => true
281+
case _ => false
282+
278283
/** The underlying pattern ignoring any bindings */
279284
def unbind(x: Tree): Tree = unsplice(x) match {
280285
case Bind(_, y) => unbind(y)

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,16 @@ object Feature:
2727
val erasedDefinitions = experimental("erasedDefinitions")
2828
val symbolLiterals: TermName = deprecated("symbolLiterals")
2929

30-
/** Is `feature` enabled by by a command-line setting? The enabling setting is
30+
val experimentalWarningMessage = "Experimental features may only be used with nightly or snapshot version of compiler."
31+
32+
/** Experimental features are only enabled for snapshot and nightly version of compiler
33+
*/
34+
def checkExperimentalFeature(feature: TermName): Boolean =
35+
feature match
36+
case QualifiedName(nme.experimental, _) => Properties.experimental
37+
case _ => true
38+
39+
/** Is `feature` enabled by by a command-line setting? The enabling setting is
3140
*
3241
* -language:<prefix>feature
3342
*
@@ -55,9 +64,11 @@ object Feature:
5564
* @param feature The name of the feature
5665
* @param owner The prefix symbol (nested in `scala.language`) where the
5766
* feature is defined.
67+
*
68+
* Note: Experimental features are only enabled for snapshot and nightly version of compiler.
5869
*/
5970
def enabled(feature: TermName)(using Context): Boolean =
60-
enabledBySetting(feature) || enabledByImport(feature)
71+
checkExperimentalFeature(feature) && (enabledBySetting(feature) || enabledByImport(feature))
6172

6273
/** Is auto-tupling enabled? */
6374
def autoTuplingEnabled(using Context): Boolean = !enabled(nme.noAutoTupling)
@@ -70,6 +81,8 @@ object Feature:
7081

7182
def genericNumberLiteralsEnabled(using Context) = enabled(genericNumberLiterals)
7283

84+
def erasedEnabled(using Context) = enabled(Feature.erasedDefinitions)
85+
7386
def scala2ExperimentalMacroEnabled(using Context) = enabled(scala2macros)
7487

7588
def sourceVersionSetting(using Context): SourceVersion =
@@ -96,4 +109,14 @@ object Feature:
96109
else
97110
false
98111

112+
/** Check that experimental compiler options are only set with snapshot or nightly compiler version. */
113+
def checkExperimentalFlags(using Context): Unit =
114+
if !Properties.experimental then
115+
val features = ctx.settings.language.value.filter(_.contains(nme.experimental.toString))
116+
if features.nonEmpty then
117+
report.error(
118+
experimentalWarningMessage +
119+
"\nThe experimental language features are enabled via -language " + features.mkString(",")
120+
)
121+
99122
end Feature

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import config.Feature
3232
import config.Feature.{sourceVersion, migrateTo3}
3333
import config.SourceVersion._
3434
import config.SourceVersion
35+
import config.Properties
3536

3637
object Parsers {
3738

@@ -3035,6 +3036,8 @@ object Parsers {
30353036
val imp = Import(tree, selectors)
30363037
if isLanguageImport(tree) then
30373038
in.languageImportContext = in.languageImportContext.importContext(imp, NoSymbol)
3039+
if isExperimentalImport(tree) && !Properties.experimental then
3040+
report.error(Feature.experimentalWarningMessage, imp.srcPos)
30383041
for
30393042
case ImportSelector(id @ Ident(imported), EmptyTree, _) <- selectors
30403043
if allSourceVersionNames.contains(imported)

0 commit comments

Comments
 (0)