From 97358878489891d88fe25a275ae6c19893a0d3f2 Mon Sep 17 00:00:00 2001 From: odersky Date: Tue, 1 Oct 2024 16:07:34 +0200 Subject: [PATCH 1/2] Standardize how previously experimental features are handled If a feature was previously experimental and is now standard, we change any tests for that feature to be only dependent on the source version where the feature was standardized. Language imports in old source versions will no longer enable the feature. (And these language imports also come with a deprecation message). If a feature was previously experimental and is now dropped, the feature becomes unavailable also in old versions. The motivation to do it this way is to insist that experimental features are ephemeral. We should not be able to rely on an experimental feature forever in an old version. This commit implements this policy for fewerBraces and clauseInterleaving. Two implemented extensions (relaxedExtensionImports, betterMatchTypeExtractors) already implemented it before. --- compiler/src/dotty/tools/dotc/config/Feature.scala | 9 --------- compiler/src/dotty/tools/dotc/config/SourceVersion.scala | 5 +++++ compiler/src/dotty/tools/dotc/parsing/Parsers.scala | 6 +++--- compiler/src/dotty/tools/dotc/parsing/Scanners.scala | 4 ++-- tests/pos/interleavingExperimental.scala | 4 +--- 5 files changed, 11 insertions(+), 17 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/config/Feature.scala b/compiler/src/dotty/tools/dotc/config/Feature.scala index 8b9a64924ace..444771366726 100644 --- a/compiler/src/dotty/tools/dotc/config/Feature.scala +++ b/compiler/src/dotty/tools/dotc/config/Feature.scala @@ -28,7 +28,6 @@ object Feature: val dependent = experimental("dependent") val erasedDefinitions = experimental("erasedDefinitions") val symbolLiterals = deprecated("symbolLiterals") - val fewerBraces = experimental("fewerBraces") val saferExceptions = experimental("saferExceptions") val clauseInterleaving = experimental("clauseInterleaving") val pureFunctions = experimental("pureFunctions") @@ -60,9 +59,7 @@ object Feature: (dependent, "Allow dependent method types"), (erasedDefinitions, "Allow erased definitions"), (symbolLiterals, "Allow symbol literals"), - (fewerBraces, "Enable support for using indentation for arguments"), (saferExceptions, "Enable safer exceptions"), - (clauseInterleaving, "Enable clause interleaving"), (pureFunctions, "Enable pure functions for capture checking"), (captureChecking, "Enable experimental capture checking"), (into, "Allow into modifier on parameter types"), @@ -124,9 +121,6 @@ object Feature: def namedTypeArgsEnabled(using Context) = enabled(namedTypeArguments) - def clauseInterleavingEnabled(using Context) = - sourceVersion.isAtLeast(`3.6`) || enabled(clauseInterleaving) - def betterForsEnabled(using Context) = enabled(betterFors) def genericNumberLiteralsEnabled(using Context) = enabled(genericNumberLiterals) @@ -169,9 +163,6 @@ object Feature: def migrateTo3(using Context): Boolean = sourceVersion == `3.0-migration` - def fewerBracesEnabled(using Context) = - sourceVersion.isAtLeast(`3.3`) || enabled(fewerBraces) - /** If current source migrates to `version`, issue given warning message * and return `true`, otherwise return `false`. */ diff --git a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala index caf1187614b7..1b796c699cb0 100644 --- a/compiler/src/dotty/tools/dotc/config/SourceVersion.scala +++ b/compiler/src/dotty/tools/dotc/config/SourceVersion.scala @@ -28,6 +28,11 @@ enum SourceVersion: def isAtMost(v: SourceVersion) = stable.ordinal <= v.ordinal + def enablesFewerBraces = isAtLeast(`3.3`) + def enablesClauseInterleaving = isAtLeast(`3.6`) + def enablesNewGivens = isAtLeast(`3.6`) + def enablesNamedTuples = isAtLeast(`3.6`) + object SourceVersion extends Property.Key[SourceVersion]: def defaultSourceVersion = `3.6` diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index 8a173faa3cec..370c06e9a33d 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -868,7 +868,7 @@ object Parsers { } }) canRewrite &= (in.isAfterLineEnd || statCtdTokens.contains(in.token)) // test (5) - if canRewrite && (!underColonSyntax || Feature.fewerBracesEnabled) then + if canRewrite && (!underColonSyntax || sourceVersion.enablesFewerBraces) then val openingPatchStr = if !colonRequired then "" else if testChar(startOpening - 1, Chars.isOperatorPart(_)) then " :" @@ -1119,7 +1119,7 @@ object Parsers { * body */ def isColonLambda = - Feature.fewerBracesEnabled && in.token == COLONfollow && followingIsLambdaAfterColon() + sourceVersion.enablesFewerBraces && in.token == COLONfollow && followingIsLambdaAfterColon() /** operand { infixop operand | MatchClause } [postfixop], * @@ -3914,7 +3914,7 @@ object Parsers { val ident = termIdent() var name = ident.name.asTermName val paramss = - if Feature.clauseInterleavingEnabled(using in.languageImportContext) then + if sourceVersion.enablesClauseInterleaving then typeOrTermParamClauses(ParamOwner.Def, numLeadParams) else val tparams = typeParamClauseOpt(ParamOwner.Def) diff --git a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala index 2dc0a1a8d805..5c90bb97e6db 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Scanners.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Scanners.scala @@ -17,7 +17,7 @@ import scala.collection.mutable import scala.collection.immutable.SortedMap import rewrites.Rewrites.patch import config.Feature -import config.Feature.{migrateTo3, fewerBracesEnabled} +import config.Feature.migrateTo3 import config.SourceVersion.{`3.0`, `3.0-migration`} import config.MigrationVersion import reporting.{NoProfile, Profile, Message} @@ -663,7 +663,7 @@ object Scanners { if token == COLONop && inTemplate then report.deprecationWarning(em"`:` after symbolic operator is deprecated; use backticks around operator instead", sourcePos(offset)) true - else token == COLONfollow && (inTemplate || fewerBracesEnabled) + else token == COLONfollow && (inTemplate || sourceVersion.enablesFewerBraces) if enabled then peekAhead() val atEOL = isAfterLineEnd || token == EOF diff --git a/tests/pos/interleavingExperimental.scala b/tests/pos/interleavingExperimental.scala index 63227ef1ebfe..a6b60a237dc3 100644 --- a/tests/pos/interleavingExperimental.scala +++ b/tests/pos/interleavingExperimental.scala @@ -1,5 +1,3 @@ -//> using options --source 3.5 - -import scala.language.experimental.clauseInterleaving +//> using options --source 3.6 def ba[A](x: A)[B](using B): B = summon[B] \ No newline at end of file From 99ff991be5ceeba984863c7381a00d65696599a0 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 2 Oct 2024 13:56:55 +0200 Subject: [PATCH 2/2] Update intent CB project to drop fewerBraces setting --- community-build/community-projects/intent | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/community-build/community-projects/intent b/community-build/community-projects/intent index 466662fb36ed..c0c4a1939b04 160000 --- a/community-build/community-projects/intent +++ b/community-build/community-projects/intent @@ -1 +1 @@ -Subproject commit 466662fb36ed38d1f045449682bdc109496c6b2d +Subproject commit c0c4a1939b04a6ce4ae5de3aa8949f04674af1f7