diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 5a5d40dc56920..90fe21ba558c6 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -735,7 +735,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated, public Swi HasAnyUnavailableDuringLoweringValues : 1 ); - SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8, + SWIFT_INLINE_BITFIELD(ModuleDecl, TypeDecl, 1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+1+8, /// If the module is compiled as static library. StaticLibrary : 1, @@ -804,10 +804,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated, public Swi SerializePackageEnabled : 1, /// Whether this module has enabled strict memory safety checking. - StrictMemorySafety : 1, - - /// Whether this module has enabled `ExtensibleEnums` feature. - ExtensibleEnums : 1 + StrictMemorySafety : 1 ); SWIFT_INLINE_BITFIELD(PrecedenceGroupDecl, Decl, 1+2, diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 654d9cf221688..7e40507ef6072 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -879,7 +879,12 @@ SIMPLE_DECL_ATTR(constInitialized, ConstInitialized, 168) DECL_ATTR_FEATURE_REQUIREMENT(ConstInitialized, CompileTimeValues) -LAST_DECL_ATTR(ConstInitialized) +SIMPLE_DECL_ATTR(extensible, Extensible, + OnEnum, + ABIStableToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove | ForbiddenInABIAttr, + 169) + +LAST_DECL_ATTR(Extensible) #undef DECL_ATTR_ALIAS #undef CONTEXTUAL_DECL_ATTR_ALIAS diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index ca975820763c1..d131bac2b3785 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -8572,6 +8572,19 @@ GROUPED_WARNING( "behavior", (StringRef, DeclAttribute)) +//===----------------------------------------------------------------------===// +// MARK: @extensible Attribute +//===----------------------------------------------------------------------===// + +ERROR(extensible_attr_on_frozen_type,none, + "cannot use '@extensible' together with '@frozen'", ()) + +ERROR(extensible_attr_on_internal_type,none, + "'@extensible' attribute can only be applied to public or package " + "declarations, but %0 is " + "%select{private|fileprivate|internal|%error|%error|%error}1", + (DeclName, AccessLevel)) + //===----------------------------------------------------------------------===// // MARK: SwiftSettings //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/Module.h b/include/swift/AST/Module.h index bf1a462f308a8..c2909a0174a08 100644 --- a/include/swift/AST/Module.h +++ b/include/swift/AST/Module.h @@ -840,14 +840,6 @@ class ModuleDecl Bits.ModuleDecl.ObjCNameLookupCachePopulated = value; } - bool supportsExtensibleEnums() const { - return Bits.ModuleDecl.ExtensibleEnums; - } - - void setSupportsExtensibleEnums(bool value = true) { - Bits.ModuleDecl.ExtensibleEnums = value; - } - /// For the main module, retrieves the list of primary source files being /// compiled, that is, the files we're generating code for. ArrayRef getPrimarySourceFiles() const; diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index 2f889e2fefc7b..153393a495a65 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -492,11 +492,6 @@ ADOPTABLE_EXPERIMENTAL_FEATURE(AsyncCallerExecution, false) /// Allow custom availability domains to be defined and referenced. SUPPRESSIBLE_EXPERIMENTAL_FEATURE(CustomAvailability, true) -/// Allow public enumerations to be extensible by default -/// regardless of whether the module they are declared in -/// is resilient or not. -EXPERIMENTAL_FEATURE(ExtensibleEnums, true) - /// Allow isolated conformances. EXPERIMENTAL_FEATURE(IsolatedConformances, true) diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h index 545e1900dd4c6..7d5eeb4c635df 100644 --- a/include/swift/Serialization/Validation.h +++ b/include/swift/Serialization/Validation.h @@ -150,7 +150,6 @@ class ExtendedValidationInfo { unsigned AllowNonResilientAccess: 1; unsigned SerializePackageEnabled: 1; unsigned StrictMemorySafety: 1; - unsigned SupportsExtensibleEnums : 1; } Bits; public: @@ -272,11 +271,6 @@ class ExtendedValidationInfo { version, SourceLoc(), /*Diags=*/nullptr)) SwiftInterfaceCompilerVersion = genericVersion.value(); } - - bool supportsExtensibleEnums() const { return Bits.SupportsExtensibleEnums; } - void setSupportsExtensibleEnums(bool val) { - Bits.SupportsExtensibleEnums = val; - } }; struct SearchPath { diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index adecada4369f0..e1aae1f69c96b 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -4925,6 +4925,7 @@ class PrintAttribute : public AttributeVisitor, TRIVIAL_ATTR_PRINTER(Used, used) TRIVIAL_ATTR_PRINTER(WarnUnqualifiedAccess, warn_unqualified_access) TRIVIAL_ATTR_PRINTER(WeakLinked, weak_linked) + TRIVIAL_ATTR_PRINTER(Extensible, extensible) #undef TRIVIAL_ATTR_PRINTER diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 765b5d7b498db..8caa03b7d5e1f 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -402,6 +402,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint, DeclAttrKind::RestatedObjCConformance, DeclAttrKind::NonSendable, DeclAttrKind::AllowFeatureSuppression, + DeclAttrKind::Extensible, }; return result; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index cdacf78f9c0a0..a1199483f07f7 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -6854,14 +6854,11 @@ bool EnumDecl::treatAsExhaustiveForDiags(const DeclContext *useDC) const { if (enumModule->inSamePackage(useDC->getParentModule())) return true; - // If the module where enum is declared supports extensible enumerations - // and this enum is not explicitly marked as "@frozen", cross-module - // access cannot be exhaustive and requires `@unknown default:`. - if (enumModule->supportsExtensibleEnums() && - !getAttrs().hasAttribute()) { - if (useDC != enumModule->getDeclContext()) - return false; - } + // When the enum is marked as `@extensible` cross-module access + // cannot be exhaustive and requires `@unknown default:`. + if (getAttrs().hasAttribute() && + enumModule != useDC->getParentModule()) + return false; } return isFormallyExhaustive(useDC); diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 2197edead58e8..e787264356c93 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -124,7 +124,6 @@ UNINTERESTING_FEATURE(SuppressedAssociatedTypes) UNINTERESTING_FEATURE(StructLetDestructuring) UNINTERESTING_FEATURE(MacrosOnImports) UNINTERESTING_FEATURE(AsyncCallerExecution) -UNINTERESTING_FEATURE(ExtensibleEnums) UNINTERESTING_FEATURE(KeyPathWithMethodMembers) static bool usesFeatureNonescapableTypes(Decl *decl) { diff --git a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift index 7d80b663340f0..d7e2445569136 100644 --- a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift +++ b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift @@ -228,6 +228,7 @@ extension ASTGenVisitor { .dynamicCallable, .eagerMove, .exported, + .extensible, .discardableResult, .disfavoredOverload, .dynamicMemberLookup, diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 7bbf3f94cf29b..c57de51d1f70e 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -1469,8 +1469,6 @@ ModuleDecl *CompilerInstance::getMainModule() const { MainModule->setSerializePackageEnabled(); if (Invocation.getLangOptions().hasFeature(Feature::StrictMemorySafety)) MainModule->setStrictMemorySafety(true); - if (Invocation.getLangOptions().hasFeature(Feature::ExtensibleEnums)) - MainModule->setSupportsExtensibleEnums(true); configureAvailabilityDomains(getASTContext(), Invocation.getFrontendOptions(), MainModule); diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index d7f2b76851f37..d44f51feaaa94 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -241,6 +241,21 @@ class AttributeChecker : public AttributeVisitor { } } + void visitExtensibleAttr(ExtensibleAttr *attr) { + auto *E = cast(D); + + if (D->getAttrs().hasAttribute()) { + diagnoseAndRemoveAttr(attr, diag::extensible_attr_on_frozen_type); + return; + } + + if (E->getFormalAccess() < AccessLevel::Package) { + diagnoseAndRemoveAttr(attr, diag::extensible_attr_on_internal_type, + E->getName(), E->getFormalAccess()); + return; + } + } + void visitAlignmentAttr(AlignmentAttr *attr) { // Alignment must be a power of two. auto value = attr->getValue(); diff --git a/lib/Sema/TypeCheckDeclOverride.cpp b/lib/Sema/TypeCheckDeclOverride.cpp index 85a113951a1e4..157d613f1e1d0 100644 --- a/lib/Sema/TypeCheckDeclOverride.cpp +++ b/lib/Sema/TypeCheckDeclOverride.cpp @@ -1615,6 +1615,7 @@ namespace { UNINTERESTING_ATTR(Isolated) UNINTERESTING_ATTR(Optimize) UNINTERESTING_ATTR(Exclusivity) + UNINTERESTING_ATTR(Extensible) UNINTERESTING_ATTR(NoLocks) UNINTERESTING_ATTR(NoAllocation) UNINTERESTING_ATTR(NoRuntime) diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp index 5e5faf5d0b3e9..cb87f469c97e5 100644 --- a/lib/Sema/TypeCheckSwitchStmt.cpp +++ b/lib/Sema/TypeCheckSwitchStmt.cpp @@ -1159,10 +1159,7 @@ namespace { auto *enumModule = theEnum->getParentModule(); shouldIncludeFutureVersionComment = enumModule->isSystemModule() || - enumModule->supportsExtensibleEnums(); - // Since the module enabled `ExtensibleEnums` feature they - // opted-in all of their clients into exhaustivity errors. - shouldDowngradeToWarning = !enumModule->supportsExtensibleEnums(); + theEnum->getAttrs().hasAttribute(); } DE.diagnose(startLoc, diag::non_exhaustive_switch_unknown_only, subjectType, shouldIncludeFutureVersionComment) diff --git a/lib/Serialization/ModuleFile.h b/lib/Serialization/ModuleFile.h index 3d46bdb0a6d71..2226b88d8036b 100644 --- a/lib/Serialization/ModuleFile.h +++ b/lib/Serialization/ModuleFile.h @@ -714,11 +714,6 @@ class ModuleFile /// \c true if this module was built with strict memory safety. bool strictMemorySafety() const { return Core->strictMemorySafety(); } - /// \c true if this module was built with `ExtensibleEnums` feature enabled. - bool supportsExtensibleEnums() const { - return Core->supportsExtensibleEnums(); - } - /// Associates this module file with the AST node representing it. /// /// Checks that the file is compatible with the AST module it's being loaded diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index e79aa78e20455..9084428196498 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -224,9 +224,6 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor, case options_block::STRICT_MEMORY_SAFETY: extendedInfo.setStrictMemorySafety(true); break; - case options_block::EXTENSIBLE_ENUMS: - extendedInfo.setSupportsExtensibleEnums(true); - break; default: // Unknown options record, possibly for use by a future version of the // module format. @@ -1508,7 +1505,6 @@ ModuleFileSharedCore::ModuleFileSharedCore( Bits.AllowNonResilientAccess = extInfo.allowNonResilientAccess(); Bits.SerializePackageEnabled = extInfo.serializePackageEnabled(); Bits.StrictMemorySafety = extInfo.strictMemorySafety(); - Bits.SupportsExtensibleEnums = extInfo.supportsExtensibleEnums(); MiscVersion = info.miscVersion; SDKVersion = info.sdkVersion; ModuleABIName = extInfo.getModuleABIName(); diff --git a/lib/Serialization/ModuleFileSharedCore.h b/lib/Serialization/ModuleFileSharedCore.h index 278561f859e2d..3d33ed8015c91 100644 --- a/lib/Serialization/ModuleFileSharedCore.h +++ b/lib/Serialization/ModuleFileSharedCore.h @@ -421,11 +421,8 @@ class ModuleFileSharedCore { /// Whether this module enabled strict memory safety. unsigned StrictMemorySafety : 1; - /// Whether this module enabled has `ExtensibleEnums` feature enabled. - unsigned SupportsExtensibleEnums : 1; - // Explicitly pad out to the next word boundary. - unsigned : 1; + unsigned : 2; } Bits = {}; static_assert(sizeof(ModuleBits) <= 8, "The bit set should be small"); @@ -684,8 +681,6 @@ class ModuleFileSharedCore { bool strictMemorySafety() const { return Bits.StrictMemorySafety; } - bool supportsExtensibleEnums() const { return Bits.SupportsExtensibleEnums; } - /// How should \p dependency be loaded for a transitive import via \c this? /// /// If \p importNonPublicDependencies, more transitive dependencies diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 5a15e14d29fd8..fa5c9a4f2adfc 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -58,7 +58,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 933; // isConstantValue +const uint16_t SWIFTMODULE_VERSION_MINOR = 935; // remove ExtensibleEnums feature /// A standard hash seed used for all string hashes in a serialized module. /// @@ -974,8 +974,7 @@ namespace options_block { CXX_STDLIB_KIND, PUBLIC_MODULE_NAME, SWIFT_INTERFACE_COMPILER_VERSION, - STRICT_MEMORY_SAFETY, - EXTENSIBLE_ENUMS, + STRICT_MEMORY_SAFETY }; using SDKPathLayout = BCRecordLayout< @@ -1085,10 +1084,6 @@ namespace options_block { SWIFT_INTERFACE_COMPILER_VERSION, BCBlob // version tuple >; - - using ExtensibleEnumsLayout = BCRecordLayout< - EXTENSIBLE_ENUMS - >; } /// The record types within the input block. diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 5fcd564217888..754af4946986f 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -1186,11 +1186,6 @@ void Serializer::writeHeader() { static_cast(M->getCXXStdlibKind())); } - if (M->supportsExtensibleEnums()) { - options_block::ExtensibleEnumsLayout ExtensibleEnums(Out); - ExtensibleEnums.emit(ScratchRecord); - } - if (Options.SerializeOptionsForDebugging) { options_block::SDKPathLayout SDKPath(Out); options_block::XCCLayout XCC(Out); diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp index c0d81d8d45b79..7973372e613bc 100644 --- a/lib/Serialization/SerializedModuleLoader.cpp +++ b/lib/Serialization/SerializedModuleLoader.cpp @@ -1100,8 +1100,6 @@ LoadedFile *SerializedModuleLoaderBase::loadAST( if (!loadedModuleFile->getModulePackageName().empty()) { M.setPackageName(Ctx.getIdentifier(loadedModuleFile->getModulePackageName())); } - if (loadedModuleFile->supportsExtensibleEnums()) - M.setSupportsExtensibleEnums(); M.setUserModuleVersion(loadedModuleFile->getUserModuleVersion()); M.setSwiftInterfaceCompilerVersion( loadedModuleFile->getSwiftInterfaceCompilerVersion()); diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index 6cf7505401f2c..fb24931965970 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -325,6 +325,7 @@ struct _S { // ON_MEMBER_LAST-DAG: Keyword/None: freestanding[#Declaration Attribute#]; name=freestanding // ON_MEMBER_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions // ON_MEMBER_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime +// ON_MEMBER_LAST-DAG: Keyword/None: extensible[#Declaration Attribute#]; name=extensible // ON_MEMBER_LAST-NOT: Keyword // ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // ON_MEMBER_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper @@ -397,6 +398,7 @@ func dummy2() {} // KEYWORD_LAST-DAG: Keyword/None: attached[#Declaration Attribute#]; name=attached // KEYWORD_LAST-DAG: Keyword/None: storageRestrictions[#Declaration Attribute#]; name=storageRestrictions // KEYWORD_LAST-DAG: Keyword/None: lifetime[#Declaration Attribute#]; name=lifetime +// KEYWORD_LAST-DAG: Keyword/None: extensible[#Declaration Attribute#]; name=extensible // KEYWORD_LAST-NOT: Keyword // KEYWORD_LAST-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // KEYWORD_LAST-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyGenericPropertyWrapper[#Property Wrapper#]; name=MyGenericPropertyWrapper diff --git a/test/ModuleInterface/attrs.swift b/test/ModuleInterface/attrs.swift index effaa641cc9b7..022ac15ff4a26 100644 --- a/test/ModuleInterface/attrs.swift +++ b/test/ModuleInterface/attrs.swift @@ -94,3 +94,11 @@ public func testExecutionConcurrent() async {} @execution(caller) public func testExecutionCaller() async {} // CHECK: @execution(caller) public func testExecutionCaller() async + +// CHECK-NOT: @extensible +// CHECK: public enum TestExtensible +@extensible +public enum TestExtensible { + case a + case b +} diff --git a/test/ModuleInterface/extensible_enums.swift b/test/ModuleInterface/extensible_enums.swift index 8f3d985a32ab6..e23a19b6eff2d 100644 --- a/test/ModuleInterface/extensible_enums.swift +++ b/test/ModuleInterface/extensible_enums.swift @@ -5,8 +5,7 @@ /// 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 ExtensibleEnums +// RUN: -emit-module-path %t/Lib.swiftmodule // Check that the errors are produced when using enums from module with `ExtensibleEnums` feature enabled. // RUN: %target-swift-frontend -typecheck %t/src/TestChecking.swift \ @@ -19,8 +18,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 ExtensibleEnums +// RUN: -emit-module-path %t/Lib.swiftmodule // Different module but the same package // RUN: %target-swift-frontend -typecheck %t/src/TestSamePackage.swift \ @@ -28,10 +26,9 @@ // RUN: -package-name Test \ // RUN: -verify -// REQUIRES: swift_feature_ExtensibleEnums - //--- Lib.swift +@extensible public enum E { case a } @@ -57,10 +54,10 @@ func test_same_module(e: E, f: F) { import Lib func test(e: E, f: F) { - // `E` is not marked as `@frozen` which means it gets new semantics + // `E` is marked as `@extensible` which means it gets new semantics switch e { - // expected-error@-1 {{switch covers known cases, but 'E' may have additional unknown values, possibly added in future versions}} + // expected-warning@-1 {{switch covers known cases, but 'E' may have additional unknown values, possibly added in future versions; this is an error in the Swift 6 language mode}} // expected-note@-2 {{handle unknown values using "@unknown default"}} case .a: break } @@ -70,7 +67,7 @@ func test(e: E, f: F) { @unknown default: break } - // `F` is marked as `@frozen` which means regular rules apply even with `ExtensibleEnums` feature enabled. + // `F` is marked as `@frozen` which means regular rules apply. switch f { // Ok (no errors because `F` is `@frozen`) case .a: break diff --git a/test/attr/attr_extensible.swift b/test/attr/attr_extensible.swift new file mode 100644 index 0000000000000..60eabf9574c49 --- /dev/null +++ b/test/attr/attr_extensible.swift @@ -0,0 +1,38 @@ +// RUN: %target-typecheck-verify-swift + +@extensible +public enum E1 { // Ok +} + +@extensible // expected-error {{'@extensible' attribute can only be applied to public or package declarations, but 'E2' is fileprivate}} +fileprivate enum E2 {} + +@extensible // expected-error {{cannot use '@extensible' together with '@frozen'}} +@frozen +public enum E3 { +} + +@extensible // expected-error {{'@extensible' attribute can only be applied to public or package declarations, but 'E4' is internal}} +@usableFromInline +enum E4 {} + +@extensible // expected-error {{@extensible may only be used on 'enum' declarations}} +struct Test { + @extensible // expected-error {{@extensible may only be used on 'enum' declarations}} + var v: Int { + @extensible // expected-error {{@extensible may only be used on 'enum' declarations}} + get { 0 } + } + + @extensible // expected-error {{@extensible may only be used on 'enum' declarations}} + var v2: String = "" + + @extensible // expected-error {{@extensible may only be used on 'enum' declarations}} + func test() {} + + @extensible // expected-error {{@extensible may only be used on 'enum' declarations}} + subscript(a: Int) -> Bool { + get { false } + set { } + } +}