From a7ecd309d4577b7974a2c912db3f3b23f83a61be Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Wed, 20 Aug 2025 00:13:34 -0700 Subject: [PATCH] [AST] SE-0487: Promote `NonexhaustiveAttribute` to a language feature The proposal [has been accepted](https://forums.swift.org/t/accepted-se-0487-nonexhaustive-enums/81508) which makes the feature experimental no longer. --- include/swift/Basic/Features.def | 4 +--- ...lete_decl_attribute_feature_requirement.swift | 15 ++++++--------- test/IDE/complete_nonexhaustive.swift | 4 +--- test/ModuleInterface/nonexhaustive_attr.swift | 5 +---- test/ModuleInterface/nonexhaustive_enums.swift | 10 ++-------- test/attr/attr_nonexhaustive.swift | 4 +--- test/attr/feature_requirement.swift | 16 ++++++---------- 7 files changed, 18 insertions(+), 40 deletions(-) diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index d5c0427d352fb..4d231d95fd492 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -275,6 +275,7 @@ BASELINE_LANGUAGE_FEATURE(IsolatedDeinit, 371, "isolated deinit") LANGUAGE_FEATURE(InlineArrayTypeSugar, 483, "Type sugar for InlineArray") LANGUAGE_FEATURE(LifetimeDependenceMutableAccessors, 0, "Support mutable accessors returning ~Escapable results") LANGUAGE_FEATURE(InoutLifetimeDependence, 0, "Support @_lifetime(&)") +SUPPRESSIBLE_LANGUAGE_FEATURE(NonexhaustiveAttribute, 487, "Nonexhaustive Enums") // Swift 6 UPCOMING_FEATURE(ConciseMagicFile, 274, 6) @@ -522,9 +523,6 @@ EXPERIMENTAL_FEATURE(AllowRuntimeSymbolDeclarations, true) /// Allow use of `@cdecl` EXPERIMENTAL_FEATURE(CDecl, false) -/// Allow use of `@nonexhaustive` on public enums -SUPPRESSIBLE_EXPERIMENTAL_FEATURE(NonexhaustiveAttribute, false) - /// Allow use of `Module::name` syntax EXPERIMENTAL_FEATURE(ModuleSelector, false) diff --git a/test/IDE/complete_decl_attribute_feature_requirement.swift b/test/IDE/complete_decl_attribute_feature_requirement.swift index 8394b4c620651..5332d1f693d13 100644 --- a/test/IDE/complete_decl_attribute_feature_requirement.swift +++ b/test/IDE/complete_decl_attribute_feature_requirement.swift @@ -3,18 +3,15 @@ // it's enabled. When a feature becomes non-experimental, move its test cases // into the normal complete_decl_attribute.swift test file. -// REQUIRES: swift_feature_NonexhaustiveAttribute - // RUN: %batch-code-completion -filecheck-additional-suffix _DISABLED -// RUN: %batch-code-completion -filecheck-additional-suffix _ENABLED \ -// RUN: -enable-experimental-feature NonexhaustiveAttribute +// RUN: %batch-code-completion -filecheck-additional-suffix _ENABLED + +// NOTE: There are currently no experimental features that need code completion +// testing, but this test file is being left in place for when it's needed +// again. At that time, please remove the ABIAttribute tests. +// REQUIRES: new_use_case // NOTE: Please do not include the ", N items" after "Begin completions". The // item count creates needless merge conflicts given that an "End completions" // line exists for each test. -@#^KEYWORD4^# enum E {} -// KEYWORD4: Begin completions -// KEYWORD4_ENABLED-DAG: Keyword/None: nonexhaustive[#{{.*}} Attribute#]; name=nonexhaustive -// KEYWORD4_DISABLED-NOT: Keyword/None: nonexhaustive[#{{.*}} Attribute#]; name=nonexhaustive -// KEYWORD4: End completions diff --git a/test/IDE/complete_nonexhaustive.swift b/test/IDE/complete_nonexhaustive.swift index 003bce451db02..549a333544990 100644 --- a/test/IDE/complete_nonexhaustive.swift +++ b/test/IDE/complete_nonexhaustive.swift @@ -1,6 +1,4 @@ -// RUN: %batch-code-completion -enable-experimental-feature NonexhaustiveAttribute - -// REQUIRES: swift_feature_NonexhaustiveAttribute +// RUN: %batch-code-completion // NONEXHAUSTIVE-DAG: Keyword/None: warn; name=warn diff --git a/test/ModuleInterface/nonexhaustive_attr.swift b/test/ModuleInterface/nonexhaustive_attr.swift index c4151e36d5177..78c4484d1d241 100644 --- a/test/ModuleInterface/nonexhaustive_attr.swift +++ b/test/ModuleInterface/nonexhaustive_attr.swift @@ -1,11 +1,8 @@ // RUN: %empty-directory(%t) -// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -enable-experimental-feature NonexhaustiveAttribute -module-name Library -// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -enable-experimental-feature NonexhaustiveAttribute -module-name Library +// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library // RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library // RUN: %FileCheck %s < %t/Library.swiftinterface -// REQUIRES: swift_feature_NonexhaustiveAttribute - // CHECK: #if compiler(>=5.3) && $NonexhaustiveAttribute // CHECK-NEXT: @nonexhaustive public enum E { // CHECK-NEXT: } diff --git a/test/ModuleInterface/nonexhaustive_enums.swift b/test/ModuleInterface/nonexhaustive_enums.swift index 7f28cd5202187..c44ad74bdfab9 100644 --- a/test/ModuleInterface/nonexhaustive_enums.swift +++ b/test/ModuleInterface/nonexhaustive_enums.swift @@ -5,10 +5,8 @@ /// Build the library // RUN: %target-swift-frontend -emit-module %t/src/Lib.swift \ // RUN: -module-name Lib \ -// RUN: -emit-module-path %t/Lib.swiftmodule \ -// RUN: -enable-experimental-feature NonexhaustiveAttribute +// RUN: -emit-module-path %t/Lib.swiftmodule -// Check that the errors are produced when using enums from module with `NonexhaustiveEnums` feature enabled. // RUN: %target-swift-frontend -typecheck %t/src/TestChecking.swift \ // RUN: -swift-version 5 -module-name Client -I %t \ // RUN: -verify @@ -19,9 +17,7 @@ // RUN: %target-swift-frontend -emit-module %t/src/Lib.swift \ // RUN: -module-name Lib \ // RUN: -package-name Test \ -// RUN: -emit-module-path %t/Lib.swiftmodule \ -// RUN: -enable-experimental-feature NonexhaustiveAttribute - +// RUN: -emit-module-path %t/Lib.swiftmodule // Different module but the same package // RUN: %target-swift-frontend -typecheck %t/src/TestSamePackage.swift \ @@ -34,8 +30,6 @@ // RUN: -swift-version 6 -module-name Client -I %t \ // RUN: -verify -// REQUIRES: swift_feature_NonexhaustiveAttribute - //--- Lib.swift @nonexhaustive diff --git a/test/attr/attr_nonexhaustive.swift b/test/attr/attr_nonexhaustive.swift index 48dfa19270efc..5829e38df1f2f 100644 --- a/test/attr/attr_nonexhaustive.swift +++ b/test/attr/attr_nonexhaustive.swift @@ -1,6 +1,4 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature NonexhaustiveAttribute - -// REQUIRES: swift_feature_NonexhaustiveAttribute +// RUN: %target-typecheck-verify-swift @nonexhaustive public enum E1 { // Ok diff --git a/test/attr/feature_requirement.swift b/test/attr/feature_requirement.swift index b69c42026340f..31612d2850c7c 100644 --- a/test/attr/feature_requirement.swift +++ b/test/attr/feature_requirement.swift @@ -1,17 +1,13 @@ // RUN: %target-typecheck-verify-swift -parse-as-library -disable-experimental-parser-round-trip -verify-additional-prefix disabled- -// RUN: %target-typecheck-verify-swift -parse-as-library -verify-additional-prefix enabled- -enable-experimental-feature NonexhaustiveAttribute +// RUN: %target-typecheck-verify-swift -parse-as-library -verify-additional-prefix enabled- // REQUIRES: asserts +// NOTE: There are currently no experimental features that need code completion +// testing, but this test file is being left in place for when it's needed +// again. At that time, please remove the ABIAttribute tests. +// REQUIRES: new_use_case + // This test checks whether DECL_ATTR_FEATURE_REQUIREMENT is being applied correctly. // It is expected to need occasional edits as experimental features are stabilized. -@nonexhaustive -public enum E {} // expected-disabled-error@-1 {{'nonexhaustive' attribute is only valid when experimental feature NonexhaustiveAttribute is enabled}} - -#if hasAttribute(nonexhaustive) - #error("does have @nonexhaustive") // expected-enabled-error {{does have @nonexhaustive}} -#else - #error("doesn't have @nonexhaustive") // expected-disabled-error {{doesn't have @nonexhaustive}} -#endif -