Skip to content

Commit f2c1b24

Browse files
committed
Allow pureFunctions and captureChecking only at the toplevel
1 parent a2dd16f commit f2c1b24

File tree

3 files changed

+28
-18
lines changed

3 files changed

+28
-18
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ object Feature:
3131
val pureFunctions = experimental("pureFunctions")
3232
val captureChecking = experimental("captureChecking")
3333

34+
val globalOnlyImports: Set[TermName] = Set(pureFunctions, captureChecking)
35+
3436
/** Is `feature` enabled by by a command-line setting? The enabling setting is
3537
*
3638
* -language:<prefix>feature

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

+20-18
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import core._
1515
import Flags._
1616
import Contexts._
1717
import Names._
18-
import NameKinds.WildcardParamName
18+
import NameKinds.{WildcardParamName, QualifiedName}
1919
import NameOps._
2020
import ast.{Positioned, Trees}
2121
import ast.Trees._
@@ -30,7 +30,7 @@ import scala.annotation.tailrec
3030
import rewrites.Rewrites.{patch, overlapsPatch}
3131
import reporting._
3232
import config.Feature
33-
import config.Feature.{sourceVersion, migrateTo3}
33+
import config.Feature.{sourceVersion, migrateTo3, globalOnlyImports}
3434
import config.SourceVersion._
3535
import config.SourceVersion
3636

@@ -3307,23 +3307,25 @@ object Parsers {
33073307
in.languageImportContext = in.languageImportContext.importContext(imp, NoSymbol)
33083308
for
33093309
case ImportSelector(id @ Ident(imported), EmptyTree, _) <- selectors
3310-
if allSourceVersionNames.contains(imported)
33113310
do
3312-
if !outermost then
3313-
syntaxError(i"source version import is only allowed at the toplevel", id.span)
3314-
else if ctx.compilationUnit.sourceVersion.isDefined then
3315-
syntaxError(i"duplicate source version import", id.span)
3316-
else if illegalSourceVersionNames.contains(imported) then
3317-
val candidate =
3318-
val nonMigration = imported.toString.replace("-migration", "")
3319-
validSourceVersionNames.find(_.show == nonMigration)
3320-
val baseMsg = i"`$imported` is not a valid source version"
3321-
val msg = candidate match
3322-
case Some(member) => i"$baseMsg, did you mean language.`$member`?"
3323-
case _ => baseMsg
3324-
syntaxError(msg, id.span)
3325-
else
3326-
ctx.compilationUnit.sourceVersion = Some(SourceVersion.valueOf(imported.toString))
3311+
if globalOnlyImports.contains(QualifiedName(prefix, imported.asTermName)) && !outermost then
3312+
syntaxError(i"this language import is only allowed at the toplevel", id.span)
3313+
if allSourceVersionNames.contains(imported) && prefix.isEmpty then
3314+
if !outermost then
3315+
syntaxError(i"source version import is only allowed at the toplevel", id.span)
3316+
else if ctx.compilationUnit.sourceVersion.isDefined then
3317+
syntaxError(i"duplicate source version import", id.span)
3318+
else if illegalSourceVersionNames.contains(imported) then
3319+
val candidate =
3320+
val nonMigration = imported.toString.replace("-migration", "")
3321+
validSourceVersionNames.find(_.show == nonMigration)
3322+
val baseMsg = i"`$imported` is not a valid source version"
3323+
val msg = candidate match
3324+
case Some(member) => i"$baseMsg, did you mean language.`$member`?"
3325+
case _ => baseMsg
3326+
syntaxError(msg, id.span)
3327+
else
3328+
ctx.compilationUnit.sourceVersion = Some(SourceVersion.valueOf(imported.toString))
33273329
case None =>
33283330
imp
33293331

tests/neg/language-imports.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
def test =
2+
import language.experimental.captureChecking // error
3+
import language.experimental.pureFunctions // error
4+
1
5+
6+

0 commit comments

Comments
 (0)