Skip to content

Commit ab2664f

Browse files
authored
Merge pull request #11852 from dotty-staging/fix-11774
Fix #11774: only enable experimental features for snapshot and nightly
2 parents bf98ec5 + 9f62255 commit ab2664f

File tree

66 files changed

+138
-67
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+138
-67
lines changed

community-build/src/scala/dotty/communitybuild/projects.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ lazy val compilerVersion: String =
1010
val file = communitybuildDir.resolve("scala3-bootstrapped.version")
1111
new String(Files.readAllBytes(file), UTF_8)
1212

13+
lazy val compilerSupportExperimental: Boolean =
14+
compilerVersion.contains("SNAPSHOT") || compilerVersion.contains("NIGHTLY")
15+
1316
lazy val sbtPluginFilePath: String =
1417
// Workaround for https://github.com/sbt/sbt/issues/4395
1518
new File(sys.props("user.home") + "/.sbt/1.0/plugins").mkdirs()

community-build/test/scala/dotty/communitybuild/CommunityBuildTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class CommunityBuildTestB extends CommunityBuildTest:
116116
@Test def disciplineSpecs2 = projects.disciplineSpecs2.run()
117117
@Test def munit = projects.munit.run()
118118
@Test def perspective = projects.perspective.run()
119-
@Test def scodec = projects.scodec.run()
119+
@Test def scodec = if (compilerSupportExperimental) projects.scodec.run()
120120
@Test def scodecBits = projects.scodecBits.run()
121121
@Test def simulacrumScalafixAnnotations = projects.simulacrumScalafixAnnotations.run()
122122
end CommunityBuildTestB

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
@@ -279,6 +279,11 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
279279

280280
def isLanguageImport(path: Tree): Boolean = languageImport(path).isDefined
281281

282+
def isExperimentalImport(path: Tree): Boolean =
283+
languageImport(path) match
284+
case Some(nme.experimental) => true
285+
case _ => false
286+
282287
/** The underlying pattern ignoring any bindings */
283288
def unbind(x: Tree): Tree = unsplice(x) match {
284289
case Bind(_, y) => unbind(y)

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,19 @@ object Feature:
2828
val symbolLiterals = deprecated("symbolLiterals")
2929
val fewerBraces = experimental("fewerBraces")
3030

31-
/** Is `feature` enabled by by a command-line setting? The enabling setting is
31+
val experimentalWarningMessage = "Experimental features may only be used with nightly or snapshot version of compiler."
32+
33+
/** Experimental features are only enabled for snapshot and nightly compiler versions
34+
*/
35+
def experimentalEnabled(using Context): Boolean =
36+
Properties.experimental && !ctx.settings.YnoExperimental.value
37+
38+
def isExperimental(feature: TermName): Boolean =
39+
feature != scala2macros && feature.match
40+
case QualifiedName(nme.experimental, _) => true
41+
case _ => false
42+
43+
/** Is `feature` enabled by by a command-line setting? The enabling setting is
3244
*
3345
* -language:<prefix>feature
3446
*
@@ -56,9 +68,12 @@ object Feature:
5668
* @param feature The name of the feature
5769
* @param owner The prefix symbol (nested in `scala.language`) where the
5870
* feature is defined.
71+
*
72+
* Note: Experimental features are only enabled for snapshot and nightly version of compiler.
5973
*/
6074
def enabled(feature: TermName)(using Context): Boolean =
61-
enabledBySetting(feature) || enabledByImport(feature)
75+
(experimentalEnabled || !isExperimental(feature))
76+
&& (enabledBySetting(feature) || enabledByImport(feature))
6277

6378
/** Is auto-tupling enabled? */
6479
def autoTuplingEnabled(using Context): Boolean = !enabled(nme.noAutoTupling)
@@ -71,6 +86,8 @@ object Feature:
7186

7287
def genericNumberLiteralsEnabled(using Context) = enabled(genericNumberLiterals)
7388

89+
def erasedEnabled(using Context) = enabled(Feature.erasedDefinitions)
90+
7491
def scala2ExperimentalMacroEnabled(using Context) = enabled(scala2macros)
7592

7693
def sourceVersionSetting(using Context): SourceVersion =
@@ -97,4 +114,16 @@ object Feature:
97114
else
98115
false
99116

117+
/** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */
118+
def checkExperimentalFlags(using Context): Unit =
119+
if !experimentalEnabled then
120+
val features = ctx.settings.language.value.filter { feature =>
121+
feature.contains(nme.experimental.toString) && !feature.contains("macros")
122+
}
123+
if features.nonEmpty then
124+
report.error(
125+
experimentalWarningMessage +
126+
"\nThe experimental language features are enabled via -language:" + features.mkString(",")
127+
)
128+
100129
end Feature

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import java.nio.charset.StandardCharsets
1111
/** Loads `library.properties` from the jar. */
1212
object Properties extends PropertiesTrait {
1313
protected def propCategory: String = "compiler"
14-
protected def pickJarBasedOn: Class[Option[?]] = classOf[Option[?]]
14+
protected def pickJarBasedOn: Class[PropertiesTrait] = classOf[PropertiesTrait]
1515

1616
/** Scala manifest attributes.
1717
*/

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ class ScalaSettings extends Settings.SettingGroup with CommonScalaSettings {
215215
val YretainTrees: Setting[Boolean] = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
216216
val YshowTreeIds: Setting[Boolean] = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
217217
val YfromTastyIgnoreList: Setting[List[String]] = MultiStringSetting("-Yfrom-tasty-ignore-list", "file", "List of `tasty` files in jar files that will not be loaded when using -from-tasty")
218+
val YnoExperimental: Setting[Boolean] = BooleanSetting("-Yno-experimental", "Disable experimental language features")
218219

219220
val YprofileEnabled: Setting[Boolean] = BooleanSetting("-Yprofile-enabled", "Enable profiling.")
220221
val YprofileDestination: Setting[String] = StringSetting("-Yprofile-destination", "file", "Where to send profiling output - specify a file, default is to the console.", "")

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ object StdNames {
520520
val longHash: N = "longHash"
521521
val macroThis : N = "_this"
522522
val macroContext : N = "c"
523+
val macros: N = "macros"
523524
val main: N = "main"
524525
val manifest: N = "manifest"
525526
val ManifestFactory: N = "ManifestFactory"

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

Lines changed: 6 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

@@ -3079,6 +3080,11 @@ object Parsers {
30793080
val imp = Import(tree, selectors)
30803081
if isLanguageImport(tree) then
30813082
in.languageImportContext = in.languageImportContext.importContext(imp, NoSymbol)
3083+
if isExperimentalImport(tree)
3084+
&& !Feature.experimentalEnabled
3085+
&& selectors.exists(_.name != nme.macros)
3086+
then
3087+
report.error(Feature.experimentalWarningMessage, imp.srcPos)
30823088
for
30833089
case ImportSelector(id @ Ident(imported), EmptyTree, _) <- selectors
30843090
if allSourceVersionNames.contains(imported)

0 commit comments

Comments
 (0)