Skip to content

Commit be7a427

Browse files
committed
Centralize global language import set in Feature
Move the set of global language features (pureFunctions, captureChecking, separationChecking, safe) into Feature.globalLanguageImports so that ReplDriver and WrappedSnippet derive from a single source of truth.
1 parent 73d6095 commit be7a427

File tree

3 files changed

+26
-22
lines changed

3 files changed

+26
-22
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,10 +248,17 @@ object Feature:
248248
def isExperimentalEnabledByImport(using Context): Boolean =
249249
experimentalAutoEnableFeatures.exists(enabledByImport)
250250

251-
/** Handle language import `import language.<prefix>.<imported>` if it is one
252-
* of the global imports `pureFunctions` or `captureChecking`. In this case
253-
* make the compilation unit's and current run's fields accordingly.
254-
* @return true iff import that was handled
251+
/** Global language imports that affect parsing and must be handled specially.
252+
* These need per-compilation-unit flags (set in `handleGlobalLanguageImport`)
253+
* and also require propagation to rootCtx in the REPL and hoisting in the
254+
* snippet compiler so they take effect across inputs (i16250).
255+
*/
256+
val globalLanguageImports: Set[TermName] =
257+
Set(pureFunctions, captureChecking, separationChecking, safe)
258+
259+
/** Handle a global language import `import language.<prefix>.<imported>`.
260+
* Sets the compilation unit's and current run's fields accordingly.
261+
* @return true iff the import was handled
255262
*/
256263
def handleGlobalLanguageImport(prefix: TermName, imported: Name)(using Context): Boolean =
257264
QualifiedName(prefix, imported.asTermName) match

repl/src/dotty/tools/repl/ReplDriver.scala

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import dotc.reporting.Diagnostic
3232
import dotc.util.Spans.Span
3333
import dotc.util.{SourceFile, SourcePosition}
3434
import dotc.{CompilationUnit, Driver}
35-
import dotc.config.CompilerCommand
35+
import dotc.config.{CompilerCommand, Feature}
3636
import dotty.tools.io.{AbstractFileClassLoader => _, *}
3737
import dotty.tools.repl.ScalaClassLoader.*
3838

@@ -309,23 +309,18 @@ class ReplDriver(settings: Array[String],
309309
val summary = rootCtx.settings.processArguments(List(s"-language:$feature"), true, rootCtx.settingsState)
310310
rootCtx = rootCtx.fresh.setSettings(summary.sstate)
311311

312-
/** Global language features that affect parsing and must be propagated to rootCtx (i16250). */
313-
private val globalLanguageFeatures = Set(
314-
"experimental.captureChecking", "experimental.pureFunctions",
315-
"experimental.separationChecking", "experimental.safe")
316-
317-
/** Detect global language imports in parsed trees and enable them as settings (i16250). */
312+
/** Detect global language imports in parsed trees and enable them in rootCtx
313+
* so subsequent parses and compilations see them (i16250).
314+
*/
318315
private def propagateLanguageImports(trees: List[untpd.Tree]): Unit =
319-
for tree <- trees do
320-
tree match
321-
case untpd.Import(expr, selectors) =>
322-
untpd.languageImport(expr) match
323-
case Some(prefix) =>
324-
for case untpd.ImportSelector(untpd.Ident(imported), untpd.EmptyTree, _) <- selectors do
325-
val qual = if prefix.isEmpty then imported.toString else s"$prefix.$imported"
326-
if globalLanguageFeatures.contains(qual) then
327-
enableLanguageFeature(qual)
328-
case _ =>
316+
import dotc.core.NameKinds.QualifiedName
317+
for case untpd.Import(expr, selectors) <- trees do
318+
untpd.languageImport(expr) match
319+
case Some(prefix) =>
320+
for case untpd.ImportSelector(untpd.Ident(imported), untpd.EmptyTree, _) <- selectors do
321+
val qual = QualifiedName(prefix, imported.asTermName)
322+
if Feature.globalLanguageImports.contains(qual) then
323+
enableLanguageFeature(qual.toString)
329324
case _ =>
330325

331326
private def stripBackTicks(label: String) =

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package snippets
33

44
import java.io.ByteArrayOutputStream
55
import java.io.PrintStream
6+
import dotty.tools.dotc.config.Feature
67

78
case class WrappedSnippet(snippet: String, outerLineOffset: Int, outerColumnOffset: Int, innerLineOffset: Int, innerColumnOffset: Int)
89

@@ -12,7 +13,8 @@ object WrappedSnippet:
1213

1314
/** Matches import lines for global language features that must be at the toplevel. */
1415
private val globalLanguageImport =
15-
raw"import\s+language\s*\.\s*experimental\s*\.\s*(captureChecking|pureFunctions|separationChecking|safe)\b".r.unanchored
16+
val names = Feature.globalLanguageImports.map(_.toString.stripPrefix("experimental."))
17+
raw"import\s+language\s*\.\s*experimental\s*\.\s*(${names.mkString("|")})\b".r.unanchored
1618

1719
private def isGlobalLanguageImport(line: String): Boolean =
1820
globalLanguageImport.matches(line.trim)

0 commit comments

Comments
 (0)