Skip to content

Commit 20db47a

Browse files
committed
WIP
1 parent 1d9e1fd commit 20db47a

File tree

233 files changed

+281
-347
lines changed

Some content is hidden

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

233 files changed

+281
-347
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ class Driver {
7474
val ictx = rootCtx.fresh
7575
val summary = command.distill(args, ictx.settings)(ictx.settingsState)(using ictx)
7676
ictx.setSettings(summary.sstate)
77-
Feature.checkExperimentalSettings(using ictx)
7877
MacroClassLoader.init(ictx)
7978
Positioned.init(using ictx)
8079

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

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ object Feature:
2323
private val genericNumberLiterals = experimental("genericNumberLiterals")
2424
val scala2macros = experimental("macros")
2525

26+
val mode = experimental("mode")
2627
val dependent = experimental("dependent")
2728
val erasedDefinitions = experimental("erasedDefinitions")
2829
val symbolLiterals = deprecated("symbolLiterals")
@@ -32,6 +33,23 @@ object Feature:
3233
val pureFunctions = experimental("pureFunctions")
3334
val captureChecking = experimental("captureChecking")
3435
val into = experimental("into")
36+
val relaxedExtensionImports = experimental("relaxedExtensionImports")
37+
38+
// TODO compute this list
39+
// TODO remove features that do not enable experimental mode
40+
val experimentalAutoEnableFeatures: List[TermName] = List(
41+
mode,
42+
namedTypeArguments,
43+
genericNumberLiterals,
44+
erasedDefinitions,
45+
fewerBraces,
46+
saferExceptions,
47+
clauseInterleaving,
48+
pureFunctions,
49+
captureChecking,
50+
into,
51+
relaxedExtensionImports,
52+
)
3553

3654
val globalOnlyImports: Set[TermName] = Set(pureFunctions, captureChecking)
3755

@@ -132,14 +150,13 @@ object Feature:
132150
false
133151

134152
def checkExperimentalFeature(which: String, srcPos: SrcPos, note: => String = "")(using Context) =
135-
if !isExperimentalEnabled then
153+
if !isExperimentalEnabledBySetting && !isExperimentalEnabledByImport then
136154
report.error(
137155
em"""Experimental $which may only be used under experimental mode:
138156
| 1. in a definition marked as @experimental, or
139157
| 2. an experimental feature is imported in at the package level, or
140-
| 3. compiling with the -experimental compiler flag, or
141-
| 4. with a nightly or snapshot version of the compiler.$note
142-
""", srcPos)
158+
| 3. compiling with the -experimental compiler flag.$note
159+
|""", srcPos)
143160

144161
private def ccException(sym: Symbol)(using Context): Boolean =
145162
ccEnabled && defn.ccExperimental.contains(sym)
@@ -156,14 +173,12 @@ object Feature:
156173
else i"$sym inherits @experimental"
157174
checkExperimentalFeature("definition", srcPos, s"\n\n$note")
158175

159-
/** Check that experimental compiler options are only set for snapshot or nightly compiler versions. */
160-
def checkExperimentalSettings(using Context): Unit =
161-
for setting <- ctx.settings.language.value
162-
if setting.startsWith("experimental.") && setting != "experimental.macros"
163-
do checkExperimentalFeature(s"feature $setting", NoSourcePosition)
176+
def isExperimentalEnabledBySetting(using Context): Boolean =
177+
ctx.settings.experimental.value ||
178+
experimentalAutoEnableFeatures.exists(enabledBySetting)
164179

165-
def isExperimentalEnabled(using Context): Boolean =
166-
(Properties.unstableExperimentalEnabled && !ctx.settings.YnoExperimental.value) || ctx.settings.experimental.value
180+
def isExperimentalEnabledByImport(using Context): Boolean =
181+
experimentalAutoEnableFeatures.exists(enabledByImport)
167182

168183
/** Handle language import `import language.<prefix>.<imported>` if it is one
169184
* of the global imports `pureFunctions` or `captureChecking`. In this case

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,6 @@ trait PropertiesTrait {
8484
*/
8585
val versionString: String = "version " + simpleVersionString
8686

87-
/** Whether the current version of compiler is experimental
88-
*
89-
* Snapshot, nightly releases and non-bootstrapped compiler are experimental.
90-
*/
91-
val unstableExperimentalEnabled: Boolean = versionString.contains("SNAPSHOT") || versionString.contains("NIGHTLY") || versionString.contains("nonbootstrapped")
92-
9387
/** Whether the current version of compiler supports research plugins. */
9488
val researchPluginEnabled: Boolean = versionString.contains("SNAPSHOT") || versionString.contains("NIGHTLY") || versionString.contains("nonbootstrapped")
9589

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,6 @@ private sealed trait YSettings:
399399
val YretainTrees: Setting[Boolean] = BooleanSetting("-Yretain-trees", "Retain trees for top-level classes, accessible from ClassSymbol#tree")
400400
val YshowTreeIds: Setting[Boolean] = BooleanSetting("-Yshow-tree-ids", "Uniquely tag all tree nodes in debugging output.")
401401
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.")
402-
val YnoExperimental: Setting[Boolean] = BooleanSetting("-Yno-experimental", "Disable experimental language features by default in NIGHTLY/SNAPSHOT versions of the compiler.")
403402
val YlegacyLazyVals: Setting[Boolean] = BooleanSetting("-Ylegacy-lazy-vals", "Use legacy (pre 3.3.0) implementation of lazy vals.")
404403
val YcompileScala2Library: Setting[Boolean] = BooleanSetting("-Ycompile-scala2-library", "Used when compiling the Scala 2 standard library.")
405404
val YoutputOnlyTasty: Setting[Boolean] = BooleanSetting("-Youtput-only-tasty", "Used to only generate the TASTy file without the classfiles")

compiler/src/dotty/tools/dotc/transform/PostTyper.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,8 +513,8 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
513513
}
514514

515515
override def transformStats[T](trees: List[Tree], exprOwner: Symbol, wrapResult: List[Tree] => Context ?=> T)(using Context): T =
516-
try super.transformStats(trees, exprOwner, wrapResult)
517-
finally Checking.checkExperimentalImports(trees)
516+
Checking.checkExperimentalImports(trees)
517+
super.transformStats(trees, exprOwner, wrapResult)
518518

519519
/** Transforms the rhs tree into a its default tree if it is in an `erased` val/def.
520520
* Performed to shrink the tree that is known to be erased later.
@@ -549,7 +549,7 @@ class PostTyper extends MacroTransform with InfoTransformer { thisPhase =>
549549
!sym.is(Package) && !sym.name.isPackageObjectName &&
550550
(sym.owner.is(Package) || (sym.owner.isPackageObject && !sym.isConstructor))
551551
if !sym.hasAnnotation(defn.ExperimentalAnnot)
552-
&& (ctx.settings.experimental.value && isTopLevelDefinitionInSource(sym))
552+
&& (Feature.isExperimentalEnabledBySetting && isTopLevelDefinitionInSource(sym))
553553
|| (sym.is(Module) && sym.companionClass.hasAnnotation(defn.ExperimentalAnnot))
554554
then
555555
sym.addAnnotation(Annotation(defn.ExperimentalAnnot, sym.span))

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,7 @@ object Checking {
827827
def isAllowedImport(sel: untpd.ImportSelector) =
828828
val name = Feature.experimental(sel.name)
829829
name == Feature.scala2macros
830-
|| name == Feature.erasedDefinitions
830+
// || name == Feature.erasedDefinitions
831831
|| name == Feature.captureChecking
832832

833833
languageImport(qual) match
@@ -836,7 +836,7 @@ object Checking {
836836
def check(stable: => String) =
837837
Feature.checkExperimentalFeature("features", imp.srcPos,
838838
s"\n\nNote: the scope enclosing the import is not considered experimental because it contains the\nnon-experimental $stable")
839-
if ctx.owner.is(Package) then
839+
if ctx.owner.is(Package) || ctx.owner.name.startsWith(str.REPL_SESSION_LINE) then
840840
// mark all top-level definitions as @experimental
841841
for tree <- nonExperimentalStats(trees) do
842842
tree match
@@ -847,7 +847,7 @@ object Checking {
847847
sym.addAnnotation(Annotations.Annotation(defn.ExperimentalAnnot, sym.span))
848848
case tree =>
849849
check(i"expression ${tree}")
850-
else Feature.checkExperimentalFeature("features", imp.srcPos)
850+
else Feature.checkExperimentalFeature("feature local import", imp.srcPos)
851851
case _ =>
852852
end checkExperimentalImports
853853

compiler/src/dotty/tools/dotc/typer/CrossVersionChecks.scala

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,14 @@ class CrossVersionChecks extends MiniPhase:
172172
}
173173

174174
override def transformOther(tree: Tree)(using Context): Tree =
175-
tree.foreachSubTree { // Find references in type trees and imports
176-
case tree: Ident => transformIdent(tree)
177-
case tree: Select => transformSelect(tree)
178-
case tree: TypeTree => transformTypeTree(tree)
179-
case _ =>
180-
}
175+
val inPackage = ctx.owner.is(Package) || ctx.owner.isPackageObject
176+
if !(inPackage && tree.isInstanceOf[ImportOrExport] && Feature.isExperimentalEnabledByImport) then
177+
tree.foreachSubTree { // Find references in type trees and imports
178+
case tree: Ident => transformIdent(tree)
179+
case tree: Select => transformSelect(tree)
180+
case tree: TypeTree => transformTypeTree(tree)
181+
case _ =>
182+
}
181183
tree
182184

183185
end CrossVersionChecks

compiler/test/dotty/tools/backend/jvm/PublicInBinaryTests.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class PublicInBinaryTests extends DottyBytecodeTest {
4242
override def initCtx =
4343
val ctx0 = super.initCtx
4444
ctx0.setSetting(ctx0.settings.experimental, true)
45-
ctx0.setSetting(ctx0.settings.YnoExperimental, true)
4645

4746
@Test
4847
def publicInBinaryDef(): Unit = {

compiler/test/dotty/tools/dotc/TastyBootstrapTests.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ class TastyBootstrapTests {
6060
val lib =
6161
compileList("lib", librarySources,
6262
defaultOptions.and("-Ycheck-reentrant",
63-
"-language:experimental.erasedDefinitions", // support declaration of scala.compiletime.erasedValue
6463
// "-source", "future", // TODO: re-enable once library uses updated syntax for vararg splices, wildcard imports, and import renaming
6564
))(libGroup)
6665

docs/_docs/reference/other-new-features/experimental-defs.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,6 @@ Experimental definitions can only be referenced in an experimental scope. Experi
267267

268268
6. An experimental language feature is imported in at the package level
269269

270-
7. 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.
271-
Can use the `-Yno-experimental` compiler flag to disable it and run as a proper release.
272-
273270
In any other situation, a reference to an experimental definition will cause a compilation error.
274271

275272
## Experimental overriding

docs/_spec/TODOreference/other-new-features/experimental-defs.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ Experimental definitions can only be referenced in an experimental scope. Experi
216216

217217
<details>
218218
<summary>Example 1</summary>
219-
219+
220220
```scala
221221
import scala.annotation.experimental
222222

@@ -242,7 +242,7 @@ Experimental definitions can only be referenced in an experimental scope. Experi
242242
}
243243
}
244244
```
245-
245+
246246
</details>
247247

248248
5. Annotations of an experimental definition are in experimental scopes. Examples:
@@ -265,8 +265,6 @@ Experimental definitions can only be referenced in an experimental scope. Experi
265265

266266
</details>
267267

268-
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.
269-
Can use the `-Yno-experimental` compiler flag to disable it and run as a proper release.
270268

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

project/Build.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,6 +1759,9 @@ object Build {
17591759
SourceLinksIntegrationTest / scalaSource := baseDirectory.value / "test-source-links",
17601760
SourceLinksIntegrationTest / test:= ((SourceLinksIntegrationTest / test) dependsOn generateScalaDocumentation.toTask("")).value,
17611761
).
1762+
settings(
1763+
scalacOptions += "-experimental" // workaround use of experimental .info in Scaladoc2AnchorCreator
1764+
).
17621765
settings(
17631766
Compile / resourceGenerators ++= Seq(
17641767
generateStaticAssetsTask.taskValue,
@@ -2167,9 +2170,6 @@ object Build {
21672170
settings(
21682171
versionScheme := Some("semver-spec"),
21692172
libraryDependencies += "org.scala-lang" % "scala-library" % stdlibVersion,
2170-
// Make sure we do not refer to experimental features outside an experimental scope.
2171-
// In other words, disable NIGHTLY/SNAPSHOT experimental scope.
2172-
scalacOptions += "-Yno-experimental",
21732173
).
21742174
settings(dottyLibrarySettings)
21752175
if (mode == Bootstrapped) {

scaladoc-testcases/src/tests/hugetype.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ trait E:
3030
@deprecated
3131
protected implicit def same[A](a: A): A
3232

33-
trait XD extends E:
33+
@experimental trait XD extends E:
3434
/**
3535
* Some important information :o
3636
*

scaladoc-testcases/src/tests/methodsAndConstructors.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package tests.methodsAndConstructors
22

3+
import scala.language.experimental.clauseInterleaving
4+
35
class A
46
class B extends A
57
class C
@@ -60,8 +62,6 @@ class Methods:
6062
def withImplicitParam2(v: String)(implicit ab: Double, a: Int, b: String): String
6163
= ???
6264

63-
import scala.language.experimental.clauseInterleaving
64-
6565
def clauseInterleaving[T](x: T)[U](y: U)(using (T, U)): (T, U)
6666
= ???
6767

scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class SnippetCompiler(
2727
object SnippetDriver extends Driver:
2828
val currentCtx =
2929
val rootCtx = initCtx.fresh.addMode(Mode.ReadPositions).addMode(Mode.Interactive)
30+
rootCtx.setSetting(rootCtx.settings.experimental, true)
3031
rootCtx.setSetting(rootCtx.settings.YretainTrees, true)
3132
rootCtx.setSetting(rootCtx.settings.YcookComments, true)
3233
rootCtx.setSetting(rootCtx.settings.YreadComments, true)

tests/init-global/pos/global-region1.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//> using options -experimental
2+
13
import scala.annotation.init.region
24

35
trait B { def foo(): Int }

tests/init-global/warn/i18628_3.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//> using options -experimental
2+
13
import scala.annotation.init.widen
24

35
object Test:

tests/neg-macros/i18677-a/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
import annotation.MacroAnnotation
44
import quoted.*
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
@extendFoo
44
class AFoo // error

tests/neg-macros/i18677-b/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
import annotation.MacroAnnotation
44
import quoted.*
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
@extendFoo
44
class AFoo // error

tests/neg-macros/i19842/Macro.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//> using options -experimental
12

23
import scala.annotation.{experimental, targetName}
34
import scala.quoted.*

tests/neg-macros/macro-experimental.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Yno-experimental
2-
31
import scala.quoted.*
42
import scala.annotation.experimental
53

tests/neg-macros/newClassExtendsNoParents/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
import scala.quoted.*
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
def test: Any = makeClass("foo") // error

tests/neg-macros/newClassExtendsOnlyTrait/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
import scala.quoted.*
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
//> using options -experimental -Yno-experimental
1+
//> using options -experimental
22

33
def test: Foo = makeClass("foo") // error

tests/neg/14034.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Yno-experimental
2-
31
import annotation.experimental
42

53
@experimental trait Exp

tests/neg/expeimental-flag-with-lang-feature-1.scala

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/neg/expeimental-flag.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Yno-experimental
2-
31
import scala.annotation.experimental
42

53
class Foo:

tests/neg/experimental-2.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Yno-experimental
2-
31
class Test7 {
42
import scala.language.experimental
53
import experimental.genericNumberLiterals // error: no aliases can be used to refer to a language import

tests/neg/experimental-imports.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//> using options -Yno-experimental
2-
31
import annotation.experimental
42

53
@experimental
@@ -14,7 +12,7 @@ object Object2:
1412
import language.experimental.fewerBraces // error
1513
import language.experimental.namedTypeArguments // error
1614
import language.experimental.genericNumberLiterals // error
17-
import language.experimental.erasedDefinitions
15+
import language.experimental.erasedDefinitions // error
1816
erased def f = 1
1917

2018
@experimental
@@ -29,7 +27,7 @@ object Class2:
2927
import language.experimental.fewerBraces // error
3028
import language.experimental.namedTypeArguments // error
3129
import language.experimental.genericNumberLiterals // error
32-
import language.experimental.erasedDefinitions
30+
import language.experimental.erasedDefinitions // error
3331
erased def f = 1
3432

3533
@experimental
@@ -44,5 +42,5 @@ def fun2 =
4442
import language.experimental.fewerBraces // error
4543
import language.experimental.namedTypeArguments // error
4644
import language.experimental.genericNumberLiterals // error
47-
import language.experimental.erasedDefinitions
45+
import language.experimental.erasedDefinitions // error
4846
erased def f = 1

0 commit comments

Comments
 (0)