Skip to content

Commit

Permalink
Disable experimental on nightly/snapshot build without -experimental
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Sep 21, 2023
1 parent 025c211 commit cf55a31
Show file tree
Hide file tree
Showing 369 changed files with 517 additions and 295 deletions.
17 changes: 8 additions & 9 deletions compiler/src/dotty/tools/dotc/config/Feature.scala
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,9 @@ 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:
em"""$which may only be used under experimental mode:
| 1. In a definition marked as @experimental
| 2. Compiling with the -experimental compiler flag
| 3. With a nightly or snapshot version of the compiler$note
| 2. Compiling with the -experimental compiler flag$note
""", srcPos)

private def ccException(sym: Symbol)(using Context): Boolean =
Expand All @@ -153,18 +152,18 @@ object Feature:
if !ccException(experimentalSym) then
val symMsg =
if experimentalSym.exists
then i"$experimentalSym is marked @experimental"
else i"$sym inherits @experimental"
report.error(em"$symMsg and therefore may only be used in an experimental scope.", srcPos)
then i"$experimentalSym is marked @experimental, it"
else i"$sym inherits @experimental, it"
checkExperimentalFeature(symMsg, srcPos)

/** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */
/** Check that experimental compiler options are only set with `-experimental`. */
def checkExperimentalSettings(using Context): Unit =
for setting <- ctx.settings.language.value
if setting.startsWith("experimental.") && setting != "experimental.macros"
do checkExperimentalFeature(s"feature $setting", NoSourcePosition)
do checkExperimentalFeature(s"Experimental feature $setting", NoSourcePosition)

def isExperimentalEnabled(using Context): Boolean =
(Properties.experimental || ctx.settings.experimental.value) && !ctx.settings.YnoExperimental.value
ctx.settings.experimental.value

/** Handle language import `import language.<prefix>.<imported>` if it is one
* of the global imports `pureFunctions` or `captureChecking`. In this case
Expand Down
8 changes: 0 additions & 8 deletions compiler/src/dotty/tools/dotc/config/Properties.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,6 @@ trait PropertiesTrait {
*/
val versionString: String = "version " + simpleVersionString

/** Whether the current version of compiler is experimental
*
* 1. Snapshot, nightly releases and non-bootstrapped compiler are experimental.
* 2. Features supported by experimental versions of the compiler:
* - research plugins
*/
val experimental: Boolean = versionString.contains("SNAPSHOT") || versionString.contains("NIGHTLY") || versionString.contains("nonbootstrapped")

val copyrightString: String = scalaPropOrElse("copyright.string", "(c) 2002-2017 LAMP/EPFL")

/** This is the encoding to use reading in source files, overridden with -encoding
Expand Down
1 change: 0 additions & 1 deletion compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ private sealed trait YSettings:
val YretainTrees: Setting[Boolean] = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
val YshowTreeIds: Setting[Boolean] = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
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.")
val YnoExperimental: Setting[Boolean] = BooleanSetting("-Yno-experimental", "Disable experimental language features.")
val YlegacyLazyVals: Setting[Boolean] = BooleanSetting("-Ylegacy-lazy-vals", "Use legacy (pre 3.3.0) implementation of lazy vals.")
val Yscala2Stdlib: Setting[Boolean] = BooleanSetting("-Yscala2-stdlib", "Used when compiling the Scala 2 standard library.")
val YoutputOnlyTasty: Setting[Boolean] = BooleanSetting("-Youtput-only-tasty", "Used to only generate the TASTy file without the classfiles")
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/Checking.scala
Original file line number Diff line number Diff line change
Expand Up @@ -805,15 +805,15 @@ object Checking {
case Some(nme.experimental)
if !ctx.owner.isInExperimentalScope && !selectors.forall(isAllowedImport) =>
def check(stable: => String) =
Feature.checkExperimentalFeature("features", imp.srcPos,
Feature.checkExperimentalFeature("Experimental features", imp.srcPos,
s"\n\nNote: the scope enclosing the import is not considered experimental because it contains the\nnon-experimental $stable")
if ctx.owner.is(Package) then
// allow top-level experimental imports if all definitions are @experimental
nonExperimentalStat(trees) match
case EmptyTree =>
case tree: MemberDef => check(i"${tree.symbol}")
case tree => check(i"expression ${tree}")
else Feature.checkExperimentalFeature("features", imp.srcPos)
else Feature.checkExperimentalFeature("Experimental features", imp.srcPos)
case _ =>
end checkExperimentalImports
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ trait QuotesAndSplices {
getQuotedPatternTypeVariable(tree.name.asTypeName) match
case Some(typeSym) =>
checkExperimentalFeature(
"support for multiple references to the same type (without backticks) in quoted type patterns (SIP-53)",
"Experimental support for multiple references to the same type (without backticks) in quoted type patterns (SIP-53)",
tree.srcPos,
"\n\nSIP-53: https://docs.scala-lang.org/sips/quote-pattern-type-variable-syntax.html")
warnOnInferredBounds(typeSym)
Expand Down Expand Up @@ -225,7 +225,7 @@ trait QuotesAndSplices {

if quoted.isType && untpdTypeVariables.nonEmpty then
checkExperimentalFeature(
"explicit type variable declarations quoted type patterns (SIP-53)",
"Experimental explicit type variable declarations quoted type patterns (SIP-53)",
untpdTypeVariables.head.srcPos,
"\n\nSIP-53: https://docs.scala-lang.org/sips/quote-pattern-type-variable-syntax.html")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ class BootstrappedOnlyCompilationTests {
val targets = dirs.map { dir =>
val compileDir = createOutputDirsForDir(dir, sourceDir, outDir)
Files.copy(dir.toPath.resolve(pluginFile), compileDir.toPath.resolve(pluginFile), StandardCopyOption.REPLACE_EXISTING)
val flags = TestFlags(withCompilerClasspath, noCheckOptions).and("-Xplugin:" + compileDir.getAbsolutePath)
val flags = TestFlags(withCompilerClasspath, noCheckOptions).and("-Xplugin:" + compileDir.getAbsolutePath).and("-experimental")
SeparateCompilationSource("testPlugins", dir, flags, compileDir)
}

Expand Down
9 changes: 6 additions & 3 deletions compiler/test/dotty/tools/dotc/CompilationTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ class CompilationTests {
compileFilesInDir("tests/pos-special/sourcepath/outer", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")),
compileFile("tests/pos-special/sourcepath/outer/nested/Test4.scala", defaultOptions.and("-sourcepath", "tests/pos-special/sourcepath")),
compileFilesInDir("tests/pos-scala2", defaultOptions.and("-source", "3.0-migration")),
compileFilesInDir("tests/pos-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking")),
compileFilesInDir("tests/pos-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking", "-experimental")),
compileFilesInDir("tests/pos-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions", "-experimental", "-Ysafe-init")),
compileFile("tests/pos-special/utf8encoded.scala", defaultOptions.and("-encoding", "UTF8")),
compileFile("tests/pos-special/utf16encoded.scala", defaultOptions.and("-encoding", "UTF16")),
// Run tests for legacy lazy vals
Expand Down Expand Up @@ -125,7 +126,8 @@ class CompilationTests {
aggregateTests(
compileFilesInDir("tests/neg", defaultOptions),
compileFilesInDir("tests/neg-deep-subtype", allowDeepSubtypes),
compileFilesInDir("tests/neg-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking")),
compileFilesInDir("tests/neg-custom-args/captures", defaultOptions.and("-language:experimental.captureChecking", "-experimental")),
compileFilesInDir("tests/neg-custom-args/erased", defaultOptions.and("-language:experimental.erasedDefinitions", "-experimental")),
compileFile("tests/neg-custom-args/sourcepath/outer/nested/Test1.scala", defaultOptions.and("-sourcepath", "tests/neg-custom-args/sourcepath")),
compileDir("tests/neg-custom-args/sourcepath2/hi", defaultOptions.and("-sourcepath", "tests/neg-custom-args/sourcepath2", "-Xfatal-warnings")),
compileList("duplicate source", List(
Expand All @@ -148,7 +150,8 @@ class CompilationTests {
aggregateTests(
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init")),
compileFilesInDir("tests/run-deep-subtype", allowDeepSubtypes),
compileFilesInDir("tests/run-custom-args/captures", allowDeepSubtypes.and("-language:experimental.captureChecking")),
compileFilesInDir("tests/run-custom-args/captures", allowDeepSubtypes.and("-language:experimental.captureChecking", "-experimental")),
compileFilesInDir("tests/run-custom-args/erased", allowDeepSubtypes.and("-language:experimental.erasedDefinitions", "-experimental")),
// Run tests for legacy lazy vals.
compileFilesInDir("tests/run", defaultOptions.and("-Ysafe-init", "-Ylegacy-lazy-vals", "-Ycheck-constraint-deps"), FileFilter.include(TestSources.runLazyValsAllowlist)),
).checkRuns()
Expand Down
2 changes: 1 addition & 1 deletion docs/_docs/reference/changed-features/compiler-plugins.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For experimentation and research, Scala 3 introduces _research plugin_. Research
are more powerful than Scala 2 analyzer plugins as they let plugin authors customize
the whole compiler pipeline. One can easily replace the standard typer by a custom one or
create a parser for a domain-specific language. However, research plugins are only
enabled with the `-experimental` compiler flag or in nightly/snapshot releases of Scala 3.
enabled with the `-experimental` compiler flag.

Common plugins that add new phases to the compiler pipeline are called
_standard plugins_ in Scala 3. In terms of features, they are similar to
Expand Down
3 changes: 1 addition & 2 deletions docs/_docs/reference/other-new-features/experimental-defs.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,7 @@ Experimental definitions can only be referenced in an experimental scope. Experi

</details>

6. Any code compiled using a [_Nightly_](https://search.maven.org/artifact/org.scala-lang/scala3-compiler_3) or _Snapshot_ version of the compiler is considered to be in an experimental scope.
Can use the `-Yno-experimental` compiler flag to disable it and run as a proper release.
6. Any code compiled using the `-experimental` compiler flag considered to be in an experimental scope.

In any other situation, a reference to an experimental definition will cause a compilation error.

Expand Down
3 changes: 0 additions & 3 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2026,9 +2026,6 @@ object Build {
settings(
versionScheme := Some("semver-spec"),
libraryDependencies += "org.scala-lang" % "scala-library" % stdlibVersion,
// Make sure we do not refer to experimental features outside an experimental scope.
// In other words, disable NIGHTLY/SNAPSHOT experimental scope.
scalacOptions += "-Yno-experimental",
).
settings(dottyLibrarySettings)
if (mode == Bootstrapped) {
Expand Down
2 changes: 2 additions & 0 deletions tests/coverage/run/erased/test.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.language.experimental.erasedDefinitions

erased def parameterless: String = "y"
Expand Down
66 changes: 33 additions & 33 deletions tests/coverage/run/erased/test.scoverage.check
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ test$package$
Object
<empty>.test$package$
foo
181
203
6
214
236
8
println
Apply
false
Expand All @@ -42,9 +42,9 @@ test$package$
Object
<empty>.test$package$
foo
189
202
6
222
235
8
s
Apply
false
Expand All @@ -59,9 +59,9 @@ test$package$
Object
<empty>.test$package$
foo
132
139
5
165
172
7
foo
DefDef
false
Expand All @@ -76,9 +76,9 @@ test$package$
Object
<empty>.test$package$
identity
245
269
10
278
302
12
println
Apply
false
Expand All @@ -93,9 +93,9 @@ test$package$
Object
<empty>.test$package$
identity
253
268
10
286
301
12
s
Apply
false
Expand All @@ -110,9 +110,9 @@ test$package$
Object
<empty>.test$package$
identity
209
221
9
242
254
11
identity
DefDef
false
Expand All @@ -127,9 +127,9 @@ test$package$
Object
<empty>.test$package$
Test
300
323
15
333
356
17
foo
Apply
false
Expand All @@ -144,9 +144,9 @@ test$package$
Object
<empty>.test$package$
Test
326
342
16
359
375
18
foo
Apply
false
Expand All @@ -161,9 +161,9 @@ test$package$
Object
<empty>.test$package$
Test
345
374
17
378
407
19
foo
Apply
false
Expand All @@ -178,9 +178,9 @@ test$package$
Object
<empty>.test$package$
Test
357
373
17
390
406
19
identity
Apply
false
Expand All @@ -195,9 +195,9 @@ test$package$
Object
<empty>.test$package$
Test
275
289
14
308
322
16
Test
DefDef
false
Expand Down
2 changes: 2 additions & 0 deletions tests/init-global/pos/global-region1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.annotation.init.region

trait B { def foo(): Int }
Expand Down
2 changes: 2 additions & 0 deletions tests/init/pos/interleaving-overload.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.language.experimental.clauseInterleaving

class A{
Expand Down
2 changes: 2 additions & 0 deletions tests/init/pos/interleaving-params.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.collection.mutable.AbstractSet
import scala.collection.mutable.BitSet
import scala.language.experimental.clauseInterleaving
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions tests/neg-macros/BigFloat/BigFloat_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

package test
import language.experimental.genericNumberLiterals
import scala.util.FromDigits
Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/BigFloat/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import test.BigFloat
object Test extends App {
val x: BigFloat = 1234.45e3333333333 // error: exponent too large
Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/GenericNumLits/Even_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import language.experimental.genericNumberLiterals
import scala.util.FromDigits
import scala.quoted.*
Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/GenericNumLits/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import language.experimental.genericNumberLiterals
object Test extends App {

Expand Down
2 changes: 0 additions & 2 deletions tests/neg-macros/macro-experimental.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
//> using options -Yno-experimental

import scala.quoted.*
import scala.annotation.experimental

Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/newClassExtendsNoParents/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.quoted.*

inline def makeClass(inline name: String): Any = ${ makeClassExpr('name) }
Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/newClassExtendsNoParents/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//> using options -experimental

def test: Any = makeClass("foo") // error
2 changes: 2 additions & 0 deletions tests/neg-macros/newClassExtendsOnlyTrait/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.quoted.*

inline def makeClass(inline name: String): Foo = ${ makeClassExpr('name) }
Expand Down
2 changes: 2 additions & 0 deletions tests/neg-macros/newClassExtendsOnlyTrait/Test_2.scala
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//> using options -experimental

def test: Foo = makeClass("foo") // error
2 changes: 2 additions & 0 deletions tests/neg-macros/quote-pattern-type-var-bounds.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//> using options -experimental

import scala.quoted.*
def types(t: Type[?])(using Quotes) = t match {
case '[ type t; Int ] =>
Expand Down
Loading

0 comments on commit cf55a31

Please sign in to comment.