Frontend: Downgrade 'already enabled' to a warning for experimental features.

If an upcoming feature was enabled by passing it via `-enable-experimental-feature`,
downgrade the `already enabled` diagnostic to a warning.

Resolves rdar://139087679.
This commit is contained in:
Allan Shortlidge
2024-11-01 15:18:56 -07:00
parent 0c364a79a6
commit 2fa75bd0bd
2 changed files with 20 additions and 16 deletions

View File

@@ -1015,13 +1015,16 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.EnableExperimentalStringProcessing = true; Opts.EnableExperimentalStringProcessing = true;
} }
auto enableUpcomingFeature = [&Opts, &Diags](Feature feature) -> bool { auto enableUpcomingFeature = [&Opts, &Diags](Feature feature,
bool downgradeDiag) -> bool {
// Check if this feature was introduced already in this language version. // Check if this feature was introduced already in this language version.
if (auto firstVersion = getFeatureLanguageVersion(feature)) { if (auto firstVersion = getFeatureLanguageVersion(feature)) {
if (Opts.isSwiftVersionAtLeast(*firstVersion)) { if (Opts.isSwiftVersionAtLeast(*firstVersion)) {
Diags.diagnose(SourceLoc(), diag::error_upcoming_feature_on_by_default, Diags
getFeatureName(feature), *firstVersion); .diagnose(SourceLoc(), diag::error_upcoming_feature_on_by_default,
return true; getFeatureName(feature), *firstVersion)
.limitBehaviorIf(downgradeDiag, DiagnosticBehavior::Warning);
return !downgradeDiag;
} }
} }
@@ -1062,7 +1065,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
// -enable-experimental-feature flag too since the feature may have // -enable-experimental-feature flag too since the feature may have
// graduated from being experimental. // graduated from being experimental.
if (auto feature = getUpcomingFeature(value)) { if (auto feature = getUpcomingFeature(value)) {
if (enableUpcomingFeature(*feature)) if (enableUpcomingFeature(*feature, /*downgradeDiag=*/true))
HadError = true; HadError = true;
} }
@@ -1087,7 +1090,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (!feature) if (!feature)
continue; continue;
if (enableUpcomingFeature(*feature)) if (enableUpcomingFeature(*feature, /*downgradeDiag=*/false))
HadError = true; HadError = true;
} }

View File

@@ -1,29 +1,30 @@
// Make sure that hasFeature(ConciseMagicFile) evaluates true when provided // Make sure that hasFeature(ConciseMagicFile) evaluates true when provided
// explicitly. // explicitly.
// RUN: %target-swift-frontend -typecheck -enable-upcoming-feature ConciseMagicFile %s // RUN: %target-typecheck-verify-swift -enable-upcoming-feature ConciseMagicFile
// Make sure that hasFeature(ConciseMagicFile) evaluates true in Swift 6. // Make sure that hasFeature(ConciseMagicFile) evaluates true in Swift 6.
// RUN: %target-swift-frontend -typecheck -swift-version 6 %s // RUN: %target-typecheck-verify-swift -swift-version 6
// Make sure that hasFeature(ConciseMagicFile) is off prior to Swift 6 // Make sure that hasFeature(ConciseMagicFile) is off prior to Swift 6
// RUN: %target-typecheck-verify-swift %s // RUN: %target-typecheck-verify-swift -verify-additional-prefix swift5-
// It's fine to provide a feature that we don't know about // It's fine to provide a feature that we don't know about
// RUN: %target-swift-frontend -typecheck -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature UnknownFeature %s // RUN: %target-typecheck-verify-swift -enable-upcoming-feature ConciseMagicFile -enable-upcoming-feature UnknownFeature
// RUN: %target-swift-frontend -typecheck -enable-upcoming-feature UnknownFeature -enable-upcoming-feature ConciseMagicFile %s // RUN: %target-typecheck-verify-swift -enable-upcoming-feature UnknownFeature -enable-upcoming-feature ConciseMagicFile
// For compatibility when a feature graduates, it's fine to refer to an // For compatibility when a feature graduates, it's fine to refer to an
// upcoming feature as an experimental feature. // upcoming feature as an experimental feature.
// RUN: %target-swift-frontend -typecheck -enable-experimental-feature ConciseMagicFile %s // RUN: %target-typecheck-verify-swift -enable-experimental-feature ConciseMagicFile
// It's not fine to provide a feature that's in the specified language version. // It's not fine to provide a feature that's in the specified language version.
// RUN: not %target-swift-frontend -typecheck -enable-upcoming-feature ConciseMagicFile -swift-version 6 %s 2>&1 | %FileCheck %s // RUN: not %target-swift-frontend -typecheck -enable-upcoming-feature ConciseMagicFile -swift-version 6 %s 2>&1 | %FileCheck %s --check-prefix=CHECK-ERROR
// RUN: not %target-swift-frontend -typecheck -enable-experimental-feature ConciseMagicFile -swift-version 6 %s 2>&1 | %FileCheck %s // RUN: %target-swift-frontend -typecheck -enable-experimental-feature ConciseMagicFile -swift-version 6 %s 2>&1 | %FileCheck %s --check-prefix=CHECK-WARN
// CHECK: error: upcoming feature 'ConciseMagicFile' is already enabled as of Swift version 6 // CHECK-ERROR: error: upcoming feature 'ConciseMagicFile' is already enabled as of Swift version 6
// CHECK-WARN: warning: upcoming feature 'ConciseMagicFile' is already enabled as of Swift version 6
#if hasFeature(ConciseMagicFile) #if hasFeature(ConciseMagicFile)
let x = 0 let x = 0
#else #else
let y = boom // expected-error{{'boom'}} let y = boom // expected-swift5-error{{'boom'}}
#endif #endif