From 10d49aad5d045f294f61f84dc150b7c0e7a6ded2 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 20 Mar 2025 16:23:17 -0700 Subject: [PATCH 01/12] Typecheck ABI-only VarDecls MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The decl checker was effectively not being run on these because we weren’t typechecking the PBD and typechecking the VarDecl itself is basically a no-op. --- lib/AST/NameLookup.cpp | 7 +++++++ lib/Sema/TypeCheckAttrABI.cpp | 15 +++++++++++---- lib/Sema/TypeCheckStorage.cpp | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index 1aeb3435d75bf..0b24e1f2210d8 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -2310,6 +2310,13 @@ void NominalTypeDecl::recordObjCMethod(AbstractFunctionDecl *method, if (!ObjCMethodLookup && !createObjCMethodLookup()) return; + // Only record API decls. + Decl *abiRoleDecl = method; + if (auto accessor = dyn_cast(method)) + abiRoleDecl = accessor->getStorage(); + if (!ABIRoleInfo(abiRoleDecl).providesAPI()) + return; + // Record the method. bool isInstanceMethod = method->isObjCInstanceMethod(); auto &vec = (*ObjCMethodLookup)[{selector, isInstanceMethod}].Methods; diff --git a/lib/Sema/TypeCheckAttrABI.cpp b/lib/Sema/TypeCheckAttrABI.cpp index d81c018ed7faa..cf8b97f3e3425 100644 --- a/lib/Sema/TypeCheckAttrABI.cpp +++ b/lib/Sema/TypeCheckAttrABI.cpp @@ -1153,6 +1153,7 @@ void checkABIAttrPBD(PatternBindingDecl *APBD, VarDecl *VD) { } // Check that each pattern has the same number of variables. + bool didDiagnose = false; for (auto i : range(PBD->getNumPatternEntries())) { SmallVector VDs; SmallVector AVDs; @@ -1162,18 +1163,24 @@ void checkABIAttrPBD(PatternBindingDecl *APBD, VarDecl *VD) { if (VDs.size() < AVDs.size()) { for (auto AVD : drop_begin(AVDs, VDs.size())) { - AVD->diagnose(diag::attr_abi_mismatched_var, - AVD, /*isABI=*/true); + AVD->diagnose(diag::attr_abi_mismatched_var, AVD, /*isABI=*/true); + didDiagnose = true; } } else if (VDs.size() > AVDs.size()) { for (auto VD : drop_begin(VDs, AVDs.size())) { - VD->diagnose(diag::attr_abi_mismatched_var, - VD, /*isABI=*/false); + VD->diagnose(diag::attr_abi_mismatched_var, VD, /*isABI=*/false); + didDiagnose = true; } } } + if (didDiagnose) + return; + + // Check the ABI PBD--this is what checks the underlying vars. + TypeChecker::typeCheckDecl(APBD); } + } // end anonymous namespace void TypeChecker::checkDeclABIAttribute(Decl *D, ABIAttr *attr) { diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 515032bd380aa..00dd1332687b5 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -3847,6 +3847,10 @@ void HasStorageRequest::cacheResult(bool hasStorage) const { StorageImplInfo StorageImplInfoRequest::evaluate(Evaluator &evaluator, AbstractStorageDecl *storage) const { + auto abiRole = ABIRoleInfo(storage); + if (!abiRole.providesAPI() && abiRole.getCounterpart()) + return abiRole.getCounterpart()->getImplInfo(); + if (auto *param = dyn_cast(storage)) { return StorageImplInfo::getSimpleStored( param->isImmutableInFunctionBody() From 23a7a5951e2d3e7f21307b229e24ee04bbe5dbe6 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Fri, 28 Mar 2025 19:18:29 -0700 Subject: [PATCH 02/12] =?UTF-8?q?Tweak=20redecl=20checking=E2=80=99s=20han?= =?UTF-8?q?dling=20of=20generated=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Macro expansions are now treated like a part of the source file they belong to, for purposes of the “second declaration is the one that’s diagnosed” rule. This helps stabilize a behavior that was easy to perturb. --- lib/Sema/TypeCheckDeclPrimary.cpp | 8 ++++---- test/Macros/macro_expand.swift | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index fb7f8d6e3c75d..98864dd784247 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -618,15 +618,15 @@ static void checkGenericParams(GenericContext *ownerCtx) { /// Returns \c true if \p current and \p other are in the same source file /// \em and \c current appears before \p other in that file. static bool isBeforeInSameFile(Decl *current, Decl *other) { - if (current->getDeclContext()->getParentSourceFile() != - other->getDeclContext()->getParentSourceFile()) + if (current->getDeclContext()->getOutermostParentSourceFile() != + other->getDeclContext()->getOutermostParentSourceFile()) return false; - if (!current->getLoc().isValid()) + if (current->getLoc().isInvalid() || other->getLoc().isInvalid()) return false; return current->getASTContext().SourceMgr - .isBeforeInBuffer(current->getLoc(), other->getLoc()); + .isBefore(current->getLoc(), other->getLoc()); } template diff --git a/test/Macros/macro_expand.swift b/test/Macros/macro_expand.swift index 4ca11c6b8335a..740c20b0461c9 100644 --- a/test/Macros/macro_expand.swift +++ b/test/Macros/macro_expand.swift @@ -135,6 +135,23 @@ class HasStoredPropertyClassInvalid { // CHECK-DIAGS: @__swiftmacro_9MacroUser0023macro_expandswift_elFCffMX[[@LINE-2]]_2_33_{{.*}}AddStoredPropertyfMf_.swift:1:22: error: covariant 'Self' type cannot be referenced from a stored property initializer } +// Redeclaration checking should behave as though expansions are part of the +// source file. +struct RedeclChecking { + #varValue + + // expected-error@+1 {{invalid redeclaration of 'value'}} + var value: Int { 0 } +} + +// CHECK-DIAGS: macro_expand.swift:[[@LINE-3]]:7: error: invalid redeclaration of 'value' +// CHECK-DIAGS: @__swiftmacro_9MacroUser0023macro_expandswift_elFCffMX[[@LINE-8]]_2_33_4361AD9339943F52AE6186DD51E04E91Ll8varValuefMf_.swift:1:5: note: 'value' previously declared here +// CHECK-DIAGS: CONTENTS OF FILE @__swiftmacro_9MacroUser0023macro_expandswift_elFCffMX[[@LINE-9]]_2_33_4361AD9339943F52AE6186DD51E04E91Ll8varValuefMf_.swift: +// CHECK-DIAGS: var value: Int { +// CHECK-DIAGS: 1 +// CHECK-DIAGS: } +// CHECK-DIAGS: END CONTENTS OF FILE + @attached(body) public macro ThrowCancellation() = #externalMacro(module: "MacroDefinition", type: "ThrowCancellationMacro") From a103e21d1160bbf85e170b2663d9692842e48e5d Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Fri, 18 Apr 2025 14:47:04 -0700 Subject: [PATCH 03/12] Diagnose CustomAttrs as needed in `@abi` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CustomAttr backs four different features, each of which requires a different behavior in `@abi`: • Global actors: Permitted (and permitted to vary) since they can affect mangling • Result builders: Forbidden inside an `@abi` since they have no ABI impact • Property wrappers: Forbidden both inside an `@abi` and on a decl with an `@abi` since it’s not clear how we would apply `@abi` to the auxiliary decls • Attached macros: Forbidden inside an `@abi` since an ABI-only decl has no body, accessors, members, peers, extensions, or (currently) conformances Implement these behaviors (outside of `ABIDeclChecker` since they can’t be described there). Macro-related tests are not included in this commit; they require matching swift-syntax changes which are being negotiated. --- include/swift/AST/DiagnosticsSema.def | 6 ++- lib/Sema/TypeCheckAttr.cpp | 23 ++++++++++++ lib/Sema/TypeCheckMacros.cpp | 6 +++ lib/Sema/TypeCheckPropertyWrapper.cpp | 10 ++++- test/attr/attr_abi.swift | 54 +++++++++++++++++++++++++++ 5 files changed, 96 insertions(+), 3 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 4ef66222f1542..1f04befc8d6e1 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -7437,7 +7437,7 @@ ERROR(property_wrapper_effectful,none, ERROR(property_with_wrapper_conflict_attribute,none, "property %0 with a wrapper cannot also be " - "%select{lazy|'@NSCopying'|'@NSManaged'|weak|unowned|unmanaged}1", + "%select{lazy|'@NSCopying'|'@NSManaged'|'@abi'|weak|unowned|unmanaged}1", (Identifier, int)) ERROR(property_wrapper_not_single_var, none, "property wrapper can only apply to a single variable", ()) @@ -8499,6 +8499,10 @@ ERROR(attr_abi_no_default_arguments,none, "affect the parameter's ABI", (Decl *)) +ERROR(attr_abi_no_macros,none, + "%kind0 cannot be expanded in '@abi' attribute", + (Decl *)) + // These macros insert 'final', 'non-final', or nothing depending on both the // current decl and its counterpart, such that 'non-final' is used if the // counterpart would be described as 'final' or 'static'. They must be kept in diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 46288ed8412e2..5990542332746 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -4401,6 +4401,12 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) { } } + // Macros can't be attached to ABI-only decls. (If we diagnosed above, + // don't bother with this.) + if (attr->isValid() && !ABIRoleInfo(D).providesAPI()) { + diagnoseAndRemoveAttr(attr, diag::attr_abi_no_macros, macro); + } + return; } @@ -4482,16 +4488,25 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) { // function, storage with an explicit getter, or parameter of function type. if (nominal->getAttrs().hasAttribute()) { ValueDecl *decl; + ValueDecl *abiRelevantDecl; if (auto param = dyn_cast(D)) { decl = param; + abiRelevantDecl = dyn_cast( + param->getDeclContext()->getAsDecl()); } else if (auto func = dyn_cast(D)) { decl = func; + abiRelevantDecl = func; } else if (auto storage = dyn_cast(D)) { decl = storage; + abiRelevantDecl = storage; // Check whether this is a storage declaration that is not permitted // to have a result builder attached. auto shouldDiagnose = [&]() -> bool { + // We'll diagnose use in @abi later. + if (!ABIRoleInfo(abiRelevantDecl).providesAPI()) + return false; + // An uninitialized stored property in a struct can have a function // builder attached. if (auto var = dyn_cast(decl)) { @@ -4535,6 +4550,14 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) { return; } + // Result builders shouldn't be applied to an ABI-only decl because they + // have no ABI effect. + if (!ABIRoleInfo(abiRelevantDecl).providesAPI()) { + diagnoseAndRemoveAttr(attr, diag::attr_abi_forbidden_attr, + nominal->getNameStr(), /*isModifier=*/false); + return; + } + // Diagnose and ignore arguments. if (attr->hasArgs()) { diagnose(attr->getLocation(), diag::result_builder_arguments) diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 305be67eb1557..2d5c237044671 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -1382,6 +1382,12 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, } } + // Macros are so spectacularly not valid in an `@abi` attribute that we cannot + // even attempt to expand them. + if (!ABIRoleInfo(attachedTo).providesAPI()) { + return nullptr; + } + ASTContext &ctx = dc->getASTContext(); auto moduleDecl = dc->getParentModule(); diff --git a/lib/Sema/TypeCheckPropertyWrapper.cpp b/lib/Sema/TypeCheckPropertyWrapper.cpp index 849ab5e26f27d..45879bdd056ac 100644 --- a/lib/Sema/TypeCheckPropertyWrapper.cpp +++ b/lib/Sema/TypeCheckPropertyWrapper.cpp @@ -484,11 +484,15 @@ AttachedPropertyWrappersRequest::evaluate(Evaluator &evaluator, continue; } + auto abiRole = ABIRoleInfo(var); + bool hasOrIsABI = !abiRole.providesAPI() || !abiRole.providesABI(); + // Note: Getting the semantic attrs here would trigger a request cycle. auto attachedAttrs = var->getAttrs(); // Check for conflicting attributes. - if (attachedAttrs.hasAttribute() || + if (hasOrIsABI || + attachedAttrs.hasAttribute() || attachedAttrs.hasAttribute() || attachedAttrs.hasAttribute() || (attachedAttrs.hasAttribute() && @@ -501,9 +505,11 @@ AttachedPropertyWrappersRequest::evaluate(Evaluator &evaluator, whichKind = 1; else if (attachedAttrs.hasAttribute()) whichKind = 2; + else if (hasOrIsABI) + whichKind = 3; else { auto attr = attachedAttrs.getAttribute(); - whichKind = 2 + static_cast(attr->get()); + whichKind = 3 + static_cast(attr->get()); } var->diagnose(diag::property_with_wrapper_conflict_attribute, var->getName(), whichKind); diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index 96be8a8d29105..009914f529f91 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1267,6 +1267,60 @@ nonisolated func isolation17() async {} @abi(@concurrent func isolation19() async) nonisolated(nonsending) func isolation19() async {} +// CustomAttr for property wrapper -- banned in and with '@abi' +// Banned because we would need to design behavior for its auxiliary decls. +@propertyWrapper struct PropertyWrapper { + var wrappedValue: Int { fatalError() } +} + +struct CustomAttrPropertyWrapper { + @abi(@PropertyWrapper var v1: Int) // expected-error {{property 'v1' with a wrapper cannot also be '@abi'}} + @PropertyWrapper var v1: Int // expected-error {{property 'v1' with a wrapper cannot also be '@abi'}} + + @abi(@PropertyWrapper var v2: Int) // expected-error {{property 'v2' with a wrapper cannot also be '@abi'}} + var v2: Int + + @abi(var v3: Int) + @PropertyWrapper var v3: Int // expected-error {{property 'v3' with a wrapper cannot also be '@abi'}} +} + +// CustomAttr for attached macro -- see Macros/macro_expand_peers.swift + +// CustomAttr for result builder -- banned in '@abi' +// Has no ABI impact on either a parameter or a decl. +@resultBuilder struct ResultBuilder { + static func buildBlock(_ values: Int...) -> Int { values.reduce(0, +) } +} + +struct CustomAttrResultBuilder { + @abi(@ResultBuilder var v1: Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{8-22=}} + @ResultBuilder var v1: Int { 0 } + + @abi(@ResultBuilder var v2: Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{8-22=}} + var v2: Int { 0 } + + @abi(var v3: Int) + @ResultBuilder var v3: Int { 0 } + + @abi(@ResultBuilder func fn11() -> Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{8-22=}} + @ResultBuilder func fn11() -> Int { 0 } + + @abi(@ResultBuilder func fn21() -> Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{8-22=}} + func fn21() -> Int { 0 } + + @abi(func fn31() -> Int) + @ResultBuilder func fn31() -> Int { 0 } + + @abi(func fn12(@ResultBuilder _: () -> Int) -> Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{18-32=}} + func fn12(@ResultBuilder _: () -> Int) -> Int { 0 } + + @abi(func fn22(@ResultBuilder _: () -> Int) -> Int) // expected-error {{unused 'ResultBuilder' attribute in '@abi'}} {{18-32=}} + func fn22(_: () -> Int) -> Int { 0 } + + @abi(func fn32(_: () -> Int) -> Int) + func fn32(@ResultBuilder _: () -> Int) -> Int { 0 } +} + // NSCopying - see attr/attr_abi_objc.swift // @LLDBDebuggerFunction -- banned in @abi From 31429fc52272b8b3da4139af9938bf0c57a0204b Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Fri, 18 Apr 2025 14:48:42 -0700 Subject: [PATCH 04/12] [Legacy parser] No freestanding macros in `@abi` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SwiftSyntaxParser is already doing this, and we already diagnosed it in Sema anyway, so we’re just moving that diagnostic earlier so the ASTGen testing mode is happy. Also adding compiler tests for it. Macro-related tests are not included in this commit; they require matching swift-syntax changes which are being negotiated. --- include/swift/AST/DiagnosticsParse.def | 5 +++++ lib/Parse/ParseDecl.cpp | 15 ++++++++++++--- test/attr/attr_abi.swift | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def index 76e73f3e16111..12a2af4b50694 100644 --- a/include/swift/AST/DiagnosticsParse.def +++ b/include/swift/AST/DiagnosticsParse.def @@ -1568,6 +1568,11 @@ ERROR(attr_unsupported_on_target, none, ERROR(attr_name_unsupported_on_target, none, "attribute '%0' is unsupported on target '%1'", (StringRef, StringRef)) +// abi attribute +ERROR(attr_abi_incompatible_kind,none, + "cannot use %0 in '@abi'", + (DescriptiveDeclKind)) + // availability ERROR(attr_availability_platform,none, "expected platform name or '*' for '%0' attribute", (StringRef)) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 8c821d20b5660..c0207b15dae01 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3357,9 +3357,18 @@ ParserStatus Parser::parseNewDeclAttribute(DeclAttributes &Attributes, } if (abiDecl) { - Attributes.add(new (Context) ABIAttr(abiDecl, - AtLoc, { Loc, rParenLoc }, - /*implicit=*/false)); + auto attr = new (Context) ABIAttr(abiDecl, AtLoc, { Loc, rParenLoc }, + /*implicit=*/false); + + // Diagnose syntactically invalid abiDecl kind here to match behavior of + // Swift parser. + if (!attr->canAppearOnDecl(abiDecl) && !isa(abiDecl)){ + diagnose(abiDecl->getLoc(), diag::attr_abi_incompatible_kind, + abiDecl->getDescriptiveKind()); + attr->setInvalid(); + } + + Attributes.add(attr); } break; diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index 009914f529f91..11208499e11fe 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1285,6 +1285,7 @@ struct CustomAttrPropertyWrapper { } // CustomAttr for attached macro -- see Macros/macro_expand_peers.swift +// Freestanding macro in @abi -- see Macros/macro_expand.swift // CustomAttr for result builder -- banned in '@abi' // Has no ABI impact on either a parameter or a decl. From c8db046cfc14e3cb40cb9cea388c9214a0f702b9 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 20 Mar 2025 17:15:03 -0700 Subject: [PATCH 05/12] Forbid `lazy` with `@abi` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It’s not clear how `@abi` would apply to the auxiliary decl used for `lazy`. --- include/swift/AST/DeclAttr.def | 2 +- include/swift/AST/DiagnosticsSema.def | 3 +++ lib/Sema/TypeCheckAttr.cpp | 5 +++++ test/attr/attr_abi.swift | 13 +++++++------ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 54f25db2a931c..c7280cc1623d9 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -143,7 +143,7 @@ SIMPLE_DECL_ATTR(NSManaged, NSManaged, CONTEXTUAL_SIMPLE_DECL_ATTR(lazy, Lazy, OnVar, - DeclModifier | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + DeclModifier | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | UnconstrainedInABIAttr, 16) SIMPLE_DECL_ATTR(LLDBDebuggerFunction, LLDBDebuggerFunction, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 1f04befc8d6e1..30c0904d3453c 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -8502,6 +8502,9 @@ ERROR(attr_abi_no_default_arguments,none, ERROR(attr_abi_no_macros,none, "%kind0 cannot be expanded in '@abi' attribute", (Decl *)) +ERROR(attr_abi_no_lazy,none, + "'lazy' is not compatible with '@abi' attribute", + ()) // These macros insert 'final', 'non-final', or nothing depending on both the // current decl and its counterpart, such that 'non-final' is used if the diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp index 5990542332746..1f68e714881d0 100644 --- a/lib/Sema/TypeCheckAttr.cpp +++ b/lib/Sema/TypeCheckAttr.cpp @@ -1094,6 +1094,11 @@ void AttributeChecker::visitLazyAttr(LazyAttr *attr) { // are already lazily initialized). if (VD->isStatic() || varDC->isModuleScopeContext()) diagnoseAndRemoveAttr(attr, diag::lazy_on_already_lazy_global); + + // 'lazy' can't be used in or with `@abi` because it has auxiliary decls. + auto abiRole = ABIRoleInfo(D); + if (!abiRole.providesABI() || !abiRole.providesAPI()) + diagnoseAndRemoveAttr(attr, diag::attr_abi_no_lazy); } bool AttributeChecker::visitAbstractAccessControlAttr( diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index 11208499e11fe..f9be07ef99d2a 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1946,16 +1946,17 @@ class Required { required init(i3: Void) { fatalError() } // expected-note {{should match modifier here}} } -// lazy -- automatically cloned into @abi +// lazy -- banned both in and with @abi +// This introduces auxiliary decls whose ABI could not be controlled. class Lazy { - @abi(lazy var v1: Int) - lazy var v1: Int = 0 + @abi(lazy var v1: Int) // expected-error {{'lazy' is not compatible with '@abi' attribute}} {{8-12=}} + lazy var v1: Int = 0 // expected-error {{'lazy' is not compatible with '@abi' attribute}} {{3-8=}} - @abi(lazy var v2: Int) // expected-error {{extra 'lazy' modifier in '@abi'}} {{8-12=}} + @abi(lazy var v2: Int) // expected-error {{'lazy' is not compatible with '@abi' attribute}} {{8-12=}} var v2: Int = 0 - @abi(var v3: Int) // expected-remark {{inferred 'lazy' in '@abi' to match modifier on API}} - lazy var v3: Int = 0 // expected-note {{matches modifier here}} + @abi(var v3: Int) + lazy var v3: Int = 0 // expected-error {{'lazy' is not compatible with '@abi' attribute}} {{3-8=}} } // @_fixed_layout -- banned in @abi From 51da65bebd964c4a6b300f77c1210878216a41ec Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 20 Mar 2025 18:52:03 -0700 Subject: [PATCH 06/12] Make inlinability non-ABI for `@abi` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inlinability doesn’t affect the mangling except in function specializations, which are applied after the fact and should never mangle in information from an ABI-only decl. That means we can simply ban these from `@abi` instead of inferring them. Also adds some assertions to help double-check that SIL never tries to directly mangle or retrieve inlinability info from an ABI-only decl. --- include/swift/AST/DeclAttr.def | 8 +++---- lib/SIL/IR/SILDeclRef.cpp | 19 ++++++++++++--- test/attr/attr_abi.swift | 43 ++++++++++++++++++---------------- 3 files changed, 43 insertions(+), 27 deletions(-) diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index c7280cc1623d9..fe1a163b7363f 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -163,7 +163,7 @@ SIMPLE_DECL_ATTR(unsafe_no_objc_tagged_pointer, UnsafeNoObjCTaggedPointer, DECL_ATTR(inline, Inline, OnVar | OnSubscript | OnAbstractFunction, - ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 20) DECL_ATTR(_semantics, Semantics, @@ -193,7 +193,7 @@ CONTEXTUAL_SIMPLE_DECL_ATTR(postfix, Postfix, SIMPLE_DECL_ATTR(_transparent, Transparent, OnFunc | OnAccessor | OnConstructor | OnVar | OnDestructor, - UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + UserInaccessible | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 26) SIMPLE_DECL_ATTR(requires_stored_property_inits, RequiresStoredPropertyInits, @@ -216,7 +216,7 @@ SIMPLE_DECL_ATTR(_fixed_layout, FixedLayout, SIMPLE_DECL_ATTR(inlinable, Inlinable, OnVar | OnSubscript | OnAbstractFunction, - ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 32) DECL_ATTR(_specialize, Specialize, @@ -465,7 +465,7 @@ DECL_ATTR(_private, PrivateImport, SIMPLE_DECL_ATTR(_alwaysEmitIntoClient, AlwaysEmitIntoClient, OnVar | OnSubscript | OnAbstractFunction, - UserInaccessible | ABIBreakingToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + UserInaccessible | ABIBreakingToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 83) SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly, diff --git a/lib/SIL/IR/SILDeclRef.cpp b/lib/SIL/IR/SILDeclRef.cpp index 134ecc7d77e8b..5c809011d2c53 100644 --- a/lib/SIL/IR/SILDeclRef.cpp +++ b/lib/SIL/IR/SILDeclRef.cpp @@ -883,6 +883,9 @@ SerializedKind_t SILDeclRef::getSerializedKind() const { auto *d = getDecl(); + ASSERT(ABIRoleInfo(d).providesAPI() + && "should not get serialization info from ABI-only decl"); + // Default and property wrapper argument generators are serialized if the // containing declaration is public. if (isDefaultArgGenerator() || (isPropertyWrapperBackingInitializer() && @@ -1021,6 +1024,9 @@ bool SILDeclRef::isNoinline() const { return false; auto *decl = getDecl(); + ASSERT(ABIRoleInfo(decl).providesAPI() + && "should not get inline attr from ABI-only decl"); + if (auto *attr = decl->getAttrs().getAttribute()) if (attr->getKind() == InlineKind::Never) return true; @@ -1051,6 +1057,9 @@ bool SILDeclRef::isAlwaysInline() const { return false; } + ASSERT(ABIRoleInfo(decl).providesAPI() + && "should not get inline attr from ABI-only decl"); + if (auto attr = decl->getAttrs().getAttribute()) if (attr->getKind() == InlineKind::Always) return true; @@ -1070,6 +1079,10 @@ bool SILDeclRef::isBackDeployed() const { return false; auto *decl = getDecl(); + + ASSERT(ABIRoleInfo(decl).providesAPI() + && "should not get backDeployed from ABI-only decl"); + if (auto afd = dyn_cast(decl)) return afd->isBackDeployed(getASTContext()); @@ -1198,6 +1211,9 @@ static std::string mangleClangDecl(Decl *decl, bool isForeign) { } std::string SILDeclRef::mangle(ManglingKind MKind) const { + ASSERT(!hasDecl() || ABIRoleInfo(getDecl()).providesAPI() + && "SILDeclRef mangling ABI decl directly?"); + using namespace Mangle; ASTMangler mangler(getASTContext()); @@ -1268,9 +1284,6 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const { if (auto *ACE = getAbstractClosureExpr()) return mangler.mangleClosureEntity(ACE, SKind); - ASSERT(ABIRoleInfo(getDecl()).providesAPI() - && "SILDeclRef mangling ABI decl directly?"); - // As a special case, functions can have manually mangled names. // Use the SILGen name only for the original non-thunked, non-curried entry // point. diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index f9be07ef99d2a..db989fbbf0417 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1868,45 +1868,48 @@ func section2() {} @abi(func section3()) @_section("fnord") func section3() {} -// @inlinable -- automatically cloned into @abi -@abi(@inlinable func inlinable1()) +// @inlinable -- banned in @abi +// Although the inlining *does* occasionally get mangled, it's only done in the +// SpecializationManglers, which shouldn't get their serialization from an ABI +// attribute. +@abi(@inlinable func inlinable1()) // expected-error {{unused 'inlinable' attribute in '@abi'}} {{6-16=}} @inlinable func inlinable1() {} -@abi(@inlinable func inlinable2()) // expected-error {{extra 'inlinable' attribute in '@abi'}} {{6-16=}} +@abi(@inlinable func inlinable2()) // expected-error {{unused 'inlinable' attribute in '@abi'}} {{6-16=}} func inlinable2() {} -@abi(func inlinable3()) // expected-remark {{inferred '@inlinable' in '@abi' to match attribute on API}} -@inlinable func inlinable3() {} // expected-note {{matches attribute here}} +@abi(func inlinable3()) +@inlinable func inlinable3() {} -// @inline -- automatically cloned into @abi -@abi(@inline(never) func inline1()) +// @inlinable -- banned in @abi +@abi(@inline(never) func inline1()) // expected-error {{unused 'inline(never)' attribute in '@abi'}} {{6-20=}} @inline(never) func inline1() {} -@abi(@inline(never) func inline2()) // expected-error {{extra 'inline(never)' attribute in '@abi'}} {{6-20=}} +@abi(@inline(never) func inline2()) // expected-error {{unused 'inline(never)' attribute in '@abi'}} {{6-20=}} func inline2() {} -@abi(func inline3()) // expected-remark {{inferred '@inline(never)' in '@abi' to match attribute on API}} -@inline(never) func inline3() {} // expected-note {{matches attribute here}} +@abi(func inline3()) +@inline(never) func inline3() {} -// @_transparent -- automatically cloned into @abi -@abi(@_transparent func transparent1()) +// @_transparent -- banned in @abi +@abi(@_transparent func transparent1()) // expected-error {{unused '_transparent' attribute in '@abi'}} {{6-19=}} @_transparent func transparent1() {} -@abi(@_transparent func transparent2()) // expected-error {{extra '_transparent' attribute in '@abi'}} {{6-19=}} +@abi(@_transparent func transparent2()) // expected-error {{unused '_transparent' attribute in '@abi'}} {{6-19=}} func transparent2() {} -@abi(func transparent3()) // expected-remark {{inferred '@_transparent' in '@abi' to match attribute on API}} -@_transparent func transparent3() {} // expected-note {{matches attribute here}} +@abi(func transparent3()) +@_transparent func transparent3() {} -// @_alwaysEmitIntoClient -- automatically cloned into @abi -@abi(@_alwaysEmitIntoClient func alwaysEmitIntoClient1()) +// @_alwaysEmitIntoClient -- banned in @abi +@abi(@_alwaysEmitIntoClient func alwaysEmitIntoClient1()) // expected-error {{unused '_alwaysEmitIntoClient' attribute in '@abi'}} {{6-28=}} @_alwaysEmitIntoClient func alwaysEmitIntoClient1() {} -@abi(@_alwaysEmitIntoClient func alwaysEmitIntoClient2()) // expected-error {{extra '_alwaysEmitIntoClient' attribute in '@abi'}} {{6-28=}} +@abi(@_alwaysEmitIntoClient func alwaysEmitIntoClient2()) // expected-error {{unused '_alwaysEmitIntoClient' attribute in '@abi'}} {{6-28=}} func alwaysEmitIntoClient2() {} -@abi(func alwaysEmitIntoClient3()) // expected-remark {{inferred '@_alwaysEmitIntoClient' in '@abi' to match attribute on API}} -@_alwaysEmitIntoClient func alwaysEmitIntoClient3() {} // expected-note {{matches attribute here}} +@abi(func alwaysEmitIntoClient3()) +@_alwaysEmitIntoClient func alwaysEmitIntoClient3() {} // @_optimize(none) -- banned in @abi @abi(@_optimize(none) func optimize1()) // expected-error {{unused '_optimize(none)' attribute in '@abi'}} {{6-22=}} From d59d2190788675ce731bf5cdf5fb45302822e2ae Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 20 Mar 2025 19:22:31 -0700 Subject: [PATCH 07/12] Forbid `@_borrowed` in `@abi` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It has indirect effects on the accessors, so it shouldn’t matter, but we can defensively redirect the query to the API counterpart anyway. This was the last `InferredInABIAttr` attribute, so we can now remove all of the infrastructure involved in supporting attribute inference. --- include/swift/AST/Attr.h | 11 ++--------- include/swift/AST/DeclAttr.def | 2 +- include/swift/AST/DiagnosticsSema.def | 3 --- include/swift/Basic/LangOptions.h | 3 --- include/swift/Option/Options.td | 4 ---- lib/AST/Attr.cpp | 2 +- lib/Frontend/CompilerInvocation.cpp | 2 -- lib/Sema/TypeCheckAttrABI.cpp | 20 -------------------- lib/Sema/TypeCheckStorage.cpp | 4 ++++ test/attr/attr_abi.swift | 12 ++++++------ test/attr/attr_abi_objc.swift | 2 +- 11 files changed, 15 insertions(+), 50 deletions(-) diff --git a/include/swift/AST/Attr.h b/include/swift/AST/Attr.h index e7a3b9d88353d..d7f3eb1c7f7d0 100644 --- a/include/swift/AST/Attr.h +++ b/include/swift/AST/Attr.h @@ -380,21 +380,14 @@ class DeclAttribute : public AttributeBase { /// valid if they match. EquivalentInABIAttr = 1ull << 18, - /// Attribute can be used in an \c \@abi attribute, but must match - /// equivalent on API decl; if omitted, API decl's attribute will be - /// cloned. Use where you would want to use \c EquivalentInABIAttr but - /// repeating the attribute is judged too burdensome. - InferredInABIAttr = 1ull << 19, - /// Use for attributes which are \em only valid on declarations that cannot /// have an \c @abi attribute, such as \c ImportDecl . - UnreachableInABIAttr = 1ull << 20, + UnreachableInABIAttr = 1ull << 19, }; enum : uint64_t { InABIAttrMask = ForbiddenInABIAttr | UnconstrainedInABIAttr - | EquivalentInABIAttr | InferredInABIAttr - | UnreachableInABIAttr + | EquivalentInABIAttr | UnreachableInABIAttr }; LLVM_READNONE diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index fe1a163b7363f..0912123e8e605 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -455,7 +455,7 @@ DECL_ATTR(_dynamicReplacement, DynamicReplacement, SIMPLE_DECL_ATTR(_borrowed, Borrowed, OnVar | OnSubscript, - UserInaccessible | NotSerialized | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove | InferredInABIAttr, + UserInaccessible | NotSerialized | ABIBreakingToAdd | ABIBreakingToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 81) DECL_ATTR(_private, PrivateImport, diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index 30c0904d3453c..c761bb3000aa5 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -8457,9 +8457,6 @@ ERROR(attr_abi_extra_attr,none, ERROR(attr_abi_forbidden_attr,none, "unused '%0' %select{attribute|modifier}1 in '@abi'", (StringRef, bool)) -REMARK(abi_attr_inferred_attribute,none, - "inferred '%0' in '@abi' to match %select{attribute|modifier}1 on API", - (StringRef, bool)) ERROR(attr_abi_mismatched_attr,none, "'%0' %select{attribute|modifier}1 in '@abi' should match '%2'", diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 8a73b09290079..5d9cac773637b 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -269,9 +269,6 @@ namespace swift { /// Emit a remark on early exit in explicit interface build bool EnableSkipExplicitInterfaceModuleBuildRemarks = false; - /// Emit a remark when \c \@abi infers an attribute or modifier. - bool EnableABIInferenceRemarks = false; - /// /// Support for alternate usage modes /// diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index 0f5b00ad5c07b..94910cf5d9d0b 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -468,10 +468,6 @@ def remark_module_serialization : Flag<["-"], "Rmodule-serialization">, Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, HelpText<"Emit remarks about module serialization">; -def remark_abi_inference : Flag<["-"], "Rabi-inference">, - Flags<[FrontendOption, DoesNotAffectIncrementalBuild]>, - HelpText<"Emit a remark when an '@abi' attribute adds an attribute or modifier to the ABI declaration based on its presence in the API">; - def emit_tbd : Flag<["-"], "emit-tbd">, HelpText<"Emit a TBD file">, Flags<[FrontendOption, NoInteractiveOption, SupplementaryOutput]>; diff --git a/lib/AST/Attr.cpp b/lib/AST/Attr.cpp index 12631530028cb..5e3f93ab8c77a 100644 --- a/lib/AST/Attr.cpp +++ b/lib/AST/Attr.cpp @@ -61,7 +61,7 @@ static_assert(IsTriviallyDestructible::value, DeclAttribute::APIBreakingToRemove | DeclAttribute::APIStableToRemove), \ #Name " needs to specify either APIBreakingToRemove or APIStableToRemove"); \ static_assert(DeclAttribute::hasOneBehaviorFor##Id(DeclAttribute::InABIAttrMask), \ - #Name " needs to specify exactly one of ForbiddenInABIAttr, UnconstrainedInABIAttr, EquivalentInABIAttr, InferredInABIAttr, or UnreachableInABIAttr"); + #Name " needs to specify exactly one of ForbiddenInABIAttr, UnconstrainedInABIAttr, EquivalentInABIAttr, or UnreachableInABIAttr"); #include "swift/AST/DeclAttr.def" #define TYPE_ATTR(_, Id) \ diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3584e18b96054..922c20cf589ec 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1422,8 +1422,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.EnableSkipExplicitInterfaceModuleBuildRemarks = Args.hasArg(OPT_remark_skip_explicit_interface_build); - Opts.EnableABIInferenceRemarks = Args.hasArg(OPT_remark_abi_inference); - if (Args.hasArg(OPT_experimental_skip_non_exportable_decls)) { // Only allow -experimental-skip-non-exportable-decls if either library // evolution is enabled (in which case the module's ABI is independent of diff --git a/lib/Sema/TypeCheckAttrABI.cpp b/lib/Sema/TypeCheckAttrABI.cpp index cf8b97f3e3425..1f85f61b644e0 100644 --- a/lib/Sema/TypeCheckAttrABI.cpp +++ b/lib/Sema/TypeCheckAttrABI.cpp @@ -881,26 +881,6 @@ class ABIDeclChecker : public ASTComparisonVisitor { return false; - case DeclAttribute::InferredInABIAttr: - if (!abi && api->canClone()) { - // Infer an identical attribute. - abi = api->clone(ctx); - abi->setImplicit(true); - abiDecl->getAttrs().add(abi); - - if (ctx.LangOpts.EnableABIInferenceRemarks) { - SmallString<64> scratch; - auto abiAttrAsString = printAttr(abi, abiDecl, scratch); - - abiDecl->diagnose(diag::abi_attr_inferred_attribute, - abiAttrAsString, api->isDeclModifier()); - noteAttrHere(api, apiDecl, /*isMatch=*/true); - } - } - - // Other than the cloning behavior, Inferred behaves like Equivalent. - LLVM_FALLTHROUGH; - case DeclAttribute::EquivalentInABIAttr: // Diagnose if API doesn't have attribute. if (!api) { diff --git a/lib/Sema/TypeCheckStorage.cpp b/lib/Sema/TypeCheckStorage.cpp index 00dd1332687b5..c8177979c7c78 100644 --- a/lib/Sema/TypeCheckStorage.cpp +++ b/lib/Sema/TypeCheckStorage.cpp @@ -849,6 +849,10 @@ IsSetterMutatingRequest::evaluate(Evaluator &evaluator, OpaqueReadOwnership OpaqueReadOwnershipRequest::evaluate(Evaluator &evaluator, AbstractStorageDecl *storage) const { + auto abiRole = ABIRoleInfo(storage); + if (!abiRole.providesAPI() && abiRole.getCounterpart()) + return abiRole.getCounterpart()->getOpaqueReadOwnership(); + enum class DiagKind { BorrowedAttr, NoncopyableType diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index db989fbbf0417..c8f6913ebf704 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -enable-experimental-feature ABIAttribute -enable-experimental-feature AddressableParameters -enable-experimental-feature NoImplicitCopy -enable-experimental-feature SymbolLinkageMarkers -enable-experimental-feature StrictMemorySafety -enable-experimental-feature LifetimeDependence -enable-experimental-feature CImplementation -import-bridging-header %S/Inputs/attr_abi.h -parse-as-library -Rabi-inference -debugger-support +// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -enable-experimental-feature ABIAttribute -enable-experimental-feature AddressableParameters -enable-experimental-feature NoImplicitCopy -enable-experimental-feature SymbolLinkageMarkers -enable-experimental-feature StrictMemorySafety -enable-experimental-feature LifetimeDependence -enable-experimental-feature CImplementation -import-bridging-header %S/Inputs/attr_abi.h -parse-as-library -debugger-support // REQUIRES: swift_feature_ABIAttribute // REQUIRES: swift_feature_AddressableParameters @@ -2034,15 +2034,15 @@ extension DynamicReplacement { // @_weakLinked -- tested in attr/attr_weaklinked.swift -// @_borrowed -- automatically cloned into @abi +// @_borrowed -- banned in @abi protocol BorrowedAttr { - @abi(@_borrowed var v1: Int) + @abi(@_borrowed var v1: Int) // expected-error {{unused '_borrowed' attribute in '@abi'}} {{8-18=}} @_borrowed var v1: Int { get set } - @abi(var v2: Int) // expected-remark {{inferred '@_borrowed' in '@abi' to match attribute on API}} - @_borrowed var v2: Int { get set } // expected-note {{matches attribute here}} + @abi(var v2: Int) + @_borrowed var v2: Int { get set } - @abi(@_borrowed var v3: Int) // expected-error {{extra '_borrowed' attribute in '@abi'}} {{8-18=}} + @abi(@_borrowed var v3: Int) // expected-error {{unused '_borrowed' attribute in '@abi'}} {{8-18=}} var v3: Int { get set } } diff --git a/test/attr/attr_abi_objc.swift b/test/attr/attr_abi_objc.swift index 3cb683e134a70..653e52a1b4989 100644 --- a/test/attr/attr_abi_objc.swift +++ b/test/attr/attr_abi_objc.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature ABIAttribute -parse-as-library -Rabi-inference +// RUN: %target-typecheck-verify-swift -enable-experimental-feature ABIAttribute -parse-as-library // REQUIRES: swift_feature_ABIAttribute // REQUIRES: objc_interop From ae936ac38489fb12b67bce95c9eda77926fcbfe8 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 17 Apr 2025 16:49:04 -0700 Subject: [PATCH 08/12] Prevent `#if` in `@abi` in module interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a language feature is used inside an `@abi` attribute, we should behave as though it was used on its counterpart. This was already half-implemented—we ensured the counterpart would use the feature—but we didn’t make the ABI decl aware that the counterpart was its parent for feature detection purposes. As a result, we would print `#if` inside the `@abi` attribute, which isn’t valid. --- lib/AST/FeatureSet.cpp | 6 +++++- test/ModuleInterface/attrs.swift | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 920a1d917a0c0..4ffeb986bd67a 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -700,8 +700,12 @@ FeatureSet swift::getUniqueFeaturesUsed(Decl *decl) { // Remove all the features used by all enclosing declarations. Decl *enclosingDecl = decl; while (!features.empty()) { + // If we were in an @abi attribute, collect from the API counterpart. + auto abiRole = ABIRoleInfo(enclosingDecl); + if (!abiRole.providesAPI() && abiRole.getCounterpart()) + enclosingDecl = abiRole.getCounterpart(); // Find the next outermost enclosing declaration. - if (auto accessor = dyn_cast(enclosingDecl)) + else if (auto accessor = dyn_cast(enclosingDecl)) enclosingDecl = accessor->getStorage(); else enclosingDecl = enclosingDecl->getDeclContext()->getAsDecl(); diff --git a/test/ModuleInterface/attrs.swift b/test/ModuleInterface/attrs.swift index 1360aae2a790f..e6aef42064184 100644 --- a/test/ModuleInterface/attrs.swift +++ b/test/ModuleInterface/attrs.swift @@ -85,6 +85,20 @@ public struct MutatingTest { @abi(func abiSpiFunc()) @_spi(spiGroup) public func abiSpiFunc() {} +// We should print feature guards outside, but not inside, an @abi attribute. +@abi(func sendingABI() -> sending Any?) +public func sendingABI() -> Any? { nil } +// CHECK: #if {{.*}} && $ABIAttribute +// CHECK: @abi(func sendingABI() -> sending Any?) +// CHECK: public func sendingABI() -> Any? +// CHECK: #elseif {{.*}} && $SendingArgsAndResults +// CHECK: @_silgen_name("$s5attrs10sendingABIypSgyF") +// CHECK: public func sendingABI() -> Any? +// CHECK: #else +// CHECK: @_silgen_name("$s5attrs10sendingABIypSgyF") +// CHECK: public func sendingABI() -> Any? +// CHECK: #endif + @concurrent public func testExecutionConcurrent() async {} // CHECK: @concurrent public func testExecutionConcurrent() async From 3595780f3db8db11fe96fa51a67fa15d991586f4 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Fri, 18 Apr 2025 14:47:36 -0700 Subject: [PATCH 09/12] Diagnose CustomAttrs as needed in `@abi` (macro tests) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additional tests for the previous commit “Diagnose CustomAttrs as needed in `@abi`”. --- test/Macros/macro_expand_peers.swift | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/test/Macros/macro_expand_peers.swift b/test/Macros/macro_expand_peers.swift index 99f8febe7fe7f..fa3c1cff4b234 100644 --- a/test/Macros/macro_expand_peers.swift +++ b/test/Macros/macro_expand_peers.swift @@ -1,4 +1,5 @@ // REQUIRES: swift_swift_parser, executable_test +// REQUIRES: swift_feature_ABIAttribute // For _Concurrency. // UNSUPPORTED: use_os_stdlib @@ -6,12 +7,12 @@ // RUN: %empty-directory(%t) // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DTEST_DIAGNOSTICS +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -enable-experimental-feature ABIAttribute -DTEST_DIAGNOSTICS // Check with the imported macro library vs. the local declaration of the macro. // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition) -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DIMPORT_MACRO_LIBRARY -I %t -DTEST_DIAGNOSTICS +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DIMPORT_MACRO_LIBRARY -I %t -enable-experimental-feature ABIAttribute -DTEST_DIAGNOSTICS // RUN: %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library %s -disable-availability-checking -dump-macro-expansions > %t/expansions-dump.txt 2>&1 @@ -309,3 +310,26 @@ func closuresInPeerMacroCrash() {} @trait(Trait {}) @trait(Trait {}) var closuresInPeerMacroOnVariableCrash: Int = 0 + +// Test that macros can't be used in @abi + +#if swift(>=5.3) && TEST_DIAGNOSTICS +struct ABIAttrWithAttachedMacro { + // expected-error@+1 {{macro 'addCompletionHandler()' cannot be expanded in '@abi' attribute}} + @abi(@addCompletionHandler func fn1() async) + @addCompletionHandler func fn1() async {} + // From diagnostics in the expansion: + // expected-note@-2 3{{in expansion of macro 'addCompletionHandler' on instance method 'fn1()' here}} + // expected-note@-4 {{'fn1()' previously declared here}} + + // expected-error@+1 {{macro 'addCompletionHandler()' cannot be expanded in '@abi' attribute}} + @abi(@addCompletionHandler func fn2() async) + func fn2() async {} + + @abi(func fn3() async) + @addCompletionHandler func fn3() async {} + // From diagnostics in the expansion: + // expected-note@-2 2{{in expansion of macro 'addCompletionHandler' on instance method 'fn3()' here}} + // expected-note@-4 {{'fn3()' previously declared here}} +} +#endif From c39e9eb3116bb40aa2effd9139e86384d4bb7daa Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Fri, 18 Apr 2025 14:49:32 -0700 Subject: [PATCH 10/12] [Legacy parser] No freestanding macros in `@abi` (macro tests) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Additional tests for the previous commit “[Legacy parser] No freestanding macros in `@abi`”. --- test/Macros/macro_expand.swift | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/test/Macros/macro_expand.swift b/test/Macros/macro_expand.swift index 740c20b0461c9..bd86cbef09982 100644 --- a/test/Macros/macro_expand.swift +++ b/test/Macros/macro_expand.swift @@ -1,23 +1,24 @@ // REQUIRES: swift_swift_parser, executable_test +// REQUIRES: swift_feature_ABIAttribute // RUN: %empty-directory(%t) // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift // Diagnostics testing -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -enable-experimental-feature ABIAttribute // Diagnostics testing by importing macros from a module // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library.swiftmodule %S/Inputs/freestanding_macro_library.swift -module-name freestanding_macro_library -load-plugin-library %t/%target-library-name(MacroDefinition) // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library_2.swiftmodule %S/Inputs/freestanding_macro_library_2.swift -module-name freestanding_macro_library_2 -load-plugin-library %t/%target-library-name(MacroDefinition) -I %t -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -I %t -DIMPORT_MACRO_LIBRARY +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -I %t -DIMPORT_MACRO_LIBRARY -enable-experimental-feature ABIAttribute -// RUN: not %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics -Rmacro-loading > %t/macro-printing.txt +// RUN: not %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics -Rmacro-loading > %t/macro-printing.txt -enable-experimental-feature ABIAttribute // RUN: c-index-test -read-diagnostics %t/macro_expand.dia 2>&1 | %FileCheck -check-prefix CHECK-DIAGS -dump-input=always %s // RUN: %FileCheck %s --check-prefix CHECK-MACRO-PRINTED < %t/macro-printing.txt -// RUN: not %target-swift-frontend -swift-version 5 -typecheck -diagnostic-style=swift -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS %s > %t/pretty-macro-diagnostics.txt 2>&1 +// RUN: not %target-swift-frontend -swift-version 5 -typecheck -diagnostic-style=swift -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS %s -enable-experimental-feature ABIAttribute > %t/pretty-macro-diagnostics.txt 2>&1 // RUN: %FileCheck %s --check-prefix PRETTY-DIAGS < %t/pretty-macro-diagnostics.txt // Debug info SIL testing @@ -719,6 +720,29 @@ func testPropertyWrapperMacro() { #hasPropertyWrapperParam($x: .init(wrappedValue: 0)) } +#if swift(>=1.0) && TEST_DIAGNOSTICS +// Test that macros can't be used in @abi + +struct ABIAttrWithFreestandingMacro1 { + // expected-error@+1 {{cannot use pound literal in '@abi'}} + @abi(#varValue) + #varValue + // expected-note@-1 {{in expansion of macro 'varValue' here}} +} + +struct ABIAttrWithFreestandingMacro2 { + // expected-error@+1 {{cannot use pound literal in '@abi'}} + @abi(#varValue) + var value: Int { 0 } +} + +struct ABIAttrWithFreestandingMacro3 { + @abi(var value: Int) + #varValue +} + +#endif + #if TEST_DIAGNOSTICS @freestanding(expression) macro missingMacro() = #externalMacro(module: "MacroDefinition", type: "BluhBlah") From 6007e783adb553d958357d296ee3cbcbbee92f45 Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 24 Apr 2025 21:47:21 -0700 Subject: [PATCH 11/12] Ban `@abi` on multi-var PBDs Per a comment in the review thread that the comma in a multi-variable pattern binding makes it look like the `@abi` attribute has several arguments. --- include/swift/AST/DiagnosticsSema.def | 12 ++---- lib/Sema/TypeCheckAttrABI.cpp | 55 ++++++--------------------- test/attr/attr_abi.swift | 15 +++++--- 3 files changed, 25 insertions(+), 57 deletions(-) diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index c761bb3000aa5..85179fad815bb 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -8434,14 +8434,10 @@ ERROR(attr_abi_mismatched_async,none, "cannot give %0 the ABI of %select{a non-async|an async}1 %kindonly0", (Decl *, /*abiIsAsync=*/bool)) -ERROR(attr_abi_mismatched_pbd_size,none, - "cannot give pattern binding the ABI of a binding with " - "%select{more|fewer}0 patterns", - (/*abiHasExtra=*/bool)) - -ERROR(attr_abi_mismatched_var,none, - "no match for %select{%kind0 in the ABI|ABI %kind0}1", - (Decl *, /*isABI=*/bool)) +ERROR(attr_abi_multiple_vars,none, + "'abi' attribute can only be applied to a single %0; declare each " + "%0 separately", + (DescriptiveDeclKind)) ERROR(attr_abi_incompatible_with_silgen_name,none, "cannot use '@_silgen_name' and '@abi' on the same %0 because they serve " diff --git a/lib/Sema/TypeCheckAttrABI.cpp b/lib/Sema/TypeCheckAttrABI.cpp index 1f85f61b644e0..2a91a575af455 100644 --- a/lib/Sema/TypeCheckAttrABI.cpp +++ b/lib/Sema/TypeCheckAttrABI.cpp @@ -1103,60 +1103,29 @@ class ABIDeclChecker : public ASTComparisonVisitor { }; void checkABIAttrPBD(PatternBindingDecl *APBD, VarDecl *VD) { - auto &diags = VD->getASTContext().Diags; auto PBD = VD->getParentPatternBinding(); - // To make sure we only diagnose this stuff once, check that VD is the first - // anchoring variable in the PBD. - bool isFirstAnchor = false; + Decl *anchorVD = nullptr; for (auto i : range(PBD->getNumPatternEntries())) { - auto anchorVD = PBD->getAnchoringVarDecl(i); - if (anchorVD) { - isFirstAnchor = (anchorVD == VD); + anchorVD = PBD->getAnchoringVarDecl(i); + if (anchorVD) break; - } } - if (!isFirstAnchor) + // To make sure we only diagnose this stuff once, check that VD is the + // first anchoring variable in the PBD. + if (anchorVD != VD) return; - // Check that the PBDs have the same number of patterns. - if (PBD->getNumPatternEntries() < APBD->getNumPatternEntries()) { - diags.diagnose(APBD->getPattern(PBD->getNumPatternEntries())->getLoc(), - diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/false); - return; - } - if (PBD->getNumPatternEntries() > APBD->getNumPatternEntries()) { - diags.diagnose(PBD->getPattern(APBD->getNumPatternEntries())->getLoc(), - diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/true); + // In the final approved feature, we only permit single-variable patterns. + // (However, the rest of the compiler tolerates them.) + if (!PBD->getSingleVar() || !APBD->getSingleVar()) { + PBD->diagnose(diag::attr_abi_multiple_vars, + anchorVD ? anchorVD->getDescriptiveKind() + : PBD->getDescriptiveKind()); return; } - // Check that each pattern has the same number of variables. - bool didDiagnose = false; - for (auto i : range(PBD->getNumPatternEntries())) { - SmallVector VDs; - SmallVector AVDs; - - PBD->getPattern(i)->collectVariables(VDs); - APBD->getPattern(i)->collectVariables(AVDs); - - if (VDs.size() < AVDs.size()) { - for (auto AVD : drop_begin(AVDs, VDs.size())) { - AVD->diagnose(diag::attr_abi_mismatched_var, AVD, /*isABI=*/true); - didDiagnose = true; - } - } - else if (VDs.size() > AVDs.size()) { - for (auto VD : drop_begin(VDs, AVDs.size())) { - VD->diagnose(diag::attr_abi_mismatched_var, VD, /*isABI=*/false); - didDiagnose = true; - } - } - } - if (didDiagnose) - return; - // Check the ABI PBD--this is what checks the underlying vars. TypeChecker::typeCheckDecl(APBD); } diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index c8f6913ebf704..3513e3ac42e5e 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -279,17 +279,20 @@ var async11Var: Int { get async { fatalError() } } // PBD shape checking // -@abi(var x1, y1: Int) // expected-error {{cannot give pattern binding the ABI of a binding with more patterns}} -var x1: Int = 0 +@abi(var x1, y1: Int) +var x1: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}} @abi(var x2: Int) -var x2 = 0, y2: Int = 0 // expected-error {{cannot give pattern binding the ABI of a binding with fewer patterns}} +var x2 = 0, y2: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}} -@abi(var (x3, y3): (Int, Int), (a3, b3): (Int, Int)) // expected-error {{no match for ABI var 'b3'}} -var (x3, y3): (Int, Int) = (0, 0), a3: Int = 0 +@abi(var (x3, y3): (Int, Int), (a3, b3): (Int, Int)) +var (x3, y3): (Int, Int) = (0, 0), a3: Int = 0 // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}} @abi(var (x4, y4): (Int, Int), a4: Int) -var (x4, y4): (Int, Int) = (0, 0), (a4, b4): (Int, Int) = (0, 0) // expected-error {{no match for var 'b4' in the ABI}} +var (x4, y4): (Int, Int) = (0, 0), (a4, b4): (Int, Int) = (0, 0) // expected-error {{'abi' attribute can only be applied to a single var; declare each var separately}} + +@abi(var x5: Int) +var x5: Int = 0 // // Redeclaration diagnostics From e831274256d6ff82aa75749a2c4446e676d6a2ec Mon Sep 17 00:00:00 2001 From: Becca Royal-Gordon Date: Thu, 24 Apr 2025 20:40:49 -0700 Subject: [PATCH 12/12] Make `@abi` non-experimental MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This includes changing the feature name so that compilers with the experimental feature don’t accidentally pick up content that only works in the final version. Resolves rdar://150065196. --- include/swift/AST/DeclAttr.def | 1 - include/swift/Basic/Features.def | 4 +--- lib/AST/ASTPrinter.cpp | 4 ++-- lib/AST/FeatureSet.cpp | 2 +- lib/ASTGen/Sources/ASTGen/SourceFile.swift | 1 - test/ASTGen/attrs.swift | 4 ---- test/IDE/complete_decl_attribute.swift | 21 ++++++++++++++++++- ...e_decl_attribute_feature_requirement.swift | 5 +++++ test/IRGen/asmname.swift | 3 +-- test/Macros/macro_expand.swift | 9 ++++---- test/Macros/macro_expand_peers.swift | 5 ++--- test/ModuleInterface/attrs.swift | 17 +++++++-------- test/ModuleInterface/attrs_objc.swift | 10 ++++----- test/attr/attr_abi.swift | 3 +-- test/attr/attr_abi_objc.swift | 3 +-- test/attr/attr_weaklinked.swift | 3 +-- test/attr/feature_requirement.swift | 12 +++++------ 17 files changed, 56 insertions(+), 51 deletions(-) diff --git a/include/swift/AST/DeclAttr.def b/include/swift/AST/DeclAttr.def index 0912123e8e605..2c428aa9586fc 100644 --- a/include/swift/AST/DeclAttr.def +++ b/include/swift/AST/DeclAttr.def @@ -860,7 +860,6 @@ DECL_ATTR(abi, ABI, OnConstructor | OnFunc | OnSubscript | OnVar, LongAttribute | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr, 165) -DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute) // Unused '166': Used to be `@execution(caller | concurrent)` replaced with `@concurrent` and `nonisolated(nonsending)` diff --git a/include/swift/Basic/Features.def b/include/swift/Basic/Features.def index bb3e216c828ca..365b9bb22ceb8 100644 --- a/include/swift/Basic/Features.def +++ b/include/swift/Basic/Features.def @@ -258,6 +258,7 @@ LANGUAGE_FEATURE(IsolatedConformances, 470, "Global-actor isolated conformances" LANGUAGE_FEATURE(AsyncExecutionBehaviorAttributes, 0, "@concurrent and nonisolated(nonsending)") LANGUAGE_FEATURE(GeneralizedIsSameMetaTypeBuiltin, 465, "Builtin.is_same_metatype with support for noncopyable/nonescapable types") LANGUAGE_FEATURE(ValueGenericsNameLookup, 452, "Value generics appearing as static members for namelookup") +SUPPRESSIBLE_LANGUAGE_FEATURE(ABIAttributeSE0479, 479, "@abi attribute on functions, initializers, properties, and subscripts") // Swift 6 UPCOMING_FEATURE(ConciseMagicFile, 274, 6) @@ -488,9 +489,6 @@ EXPERIMENTAL_FEATURE(CoroutineAccessorsUnwindOnCallerError, false) EXPERIMENTAL_FEATURE(AddressableParameters, true) SUPPRESSIBLE_EXPERIMENTAL_FEATURE(AddressableTypes, true) -/// Allow the @abi attribute. -SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ABIAttribute, true) - /// Allow custom availability domains to be defined and referenced. EXPERIMENTAL_FEATURE(CustomAvailability, true) diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 9de5705fec62e..6535ee16e714c 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -3289,8 +3289,8 @@ suppressingFeatureCoroutineAccessors(PrintOptions &options, } static void -suppressingFeatureABIAttribute(PrintOptions &options, - llvm::function_ref action) { +suppressingFeatureABIAttributeSE0479(PrintOptions &options, + llvm::function_ref action) { llvm::SaveAndRestore scope1(options.PrintSyntheticSILGenName, true); ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::ABI); action(); diff --git a/lib/AST/FeatureSet.cpp b/lib/AST/FeatureSet.cpp index 4ffeb986bd67a..10a1b1e335d71 100644 --- a/lib/AST/FeatureSet.cpp +++ b/lib/AST/FeatureSet.cpp @@ -389,7 +389,7 @@ static ABIAttr *getABIAttr(Decl *decl) { return decl->getAttrs().getAttribute(); } -static bool usesFeatureABIAttribute(Decl *decl) { +static bool usesFeatureABIAttributeSE0479(Decl *decl) { return getABIAttr(decl) != nullptr; } diff --git a/lib/ASTGen/Sources/ASTGen/SourceFile.swift b/lib/ASTGen/Sources/ASTGen/SourceFile.swift index d7692a4641607..ada0514e033a8 100644 --- a/lib/ASTGen/Sources/ASTGen/SourceFile.swift +++ b/lib/ASTGen/Sources/ASTGen/SourceFile.swift @@ -75,7 +75,6 @@ extension Parser.ExperimentalFeatures { mapFeature(.NonescapableTypes, to: .nonescapableTypes) mapFeature(.TrailingComma, to: .trailingComma) mapFeature(.CoroutineAccessors, to: .coroutineAccessors) - mapFeature(.ABIAttribute, to: .abiAttribute) mapFeature(.OldOwnershipOperatorSpellings, to: .oldOwnershipOperatorSpellings) mapFeature(.KeyPathWithMethodMembers, to: .keypathWithMethodMembers) mapFeature(.InlineArrayTypeSugar, to: .inlineArrayTypeSugar) diff --git a/test/ASTGen/attrs.swift b/test/ASTGen/attrs.swift index 39c8f5379eb9c..9b9c3aba5e497 100644 --- a/test/ASTGen/attrs.swift +++ b/test/ASTGen/attrs.swift @@ -1,7 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend-dump-parse \ -// RUN: -enable-experimental-feature ABIAttribute \ // RUN: -enable-experimental-feature Extern \ // RUN: -enable-experimental-feature LifetimeDependence \ // RUN: -enable-experimental-feature RawLayout \ @@ -12,7 +11,6 @@ // RUN: | %sanitize-address > %t/astgen.ast // RUN: %target-swift-frontend-dump-parse \ -// RUN: -enable-experimental-feature ABIAttribute \ // RUN: -enable-experimental-feature Extern \ // RUN: -enable-experimental-feature LifetimeDependence \ // RUN: -enable-experimental-feature RawLayout \ @@ -26,7 +24,6 @@ // RUN: %target-typecheck-verify-swift \ // RUN: -module-abi-name ASTGen \ // RUN: -enable-experimental-feature ParserASTGen \ -// RUN: -enable-experimental-feature ABIAttribute \ // RUN: -enable-experimental-feature Extern \ // RUN: -enable-experimental-feature LifetimeDependence \ // RUN: -enable-experimental-feature RawLayout \ @@ -38,7 +35,6 @@ // REQUIRES: executable_test // REQUIRES: swift_swift_parser // REQUIRES: swift_feature_ParserASTGen -// REQUIRES: swift_feature_ABIAttribute // REQUIRES: swift_feature_Extern // REQUIRES: swift_feature_LifetimeDependence // REQUIRES: swift_feature_RawLayout diff --git a/test/IDE/complete_decl_attribute.swift b/test/IDE/complete_decl_attribute.swift index b7fda6f209720..a7104e38d3dc3 100644 --- a/test/IDE/complete_decl_attribute.swift +++ b/test/IDE/complete_decl_attribute.swift @@ -19,6 +19,11 @@ // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_INDEPENDENT_2 | %FileCheck %s -check-prefix=KEYWORD_LAST // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_LAST | %FileCheck %s -check-prefix=KEYWORD_LAST +// NOTE: If you want to test code completion for an experimental feature, please +// put your tests in complete_decl_attribute_feature_requirement.swift, not +// here. That file has the infrastructure to test that completions are not +// offered when the feature is disabled. + struct MyStruct {} @propertyWrapper @@ -111,7 +116,10 @@ actor MyGenericGlobalActor { // KEYWORD2-NEXT: Keyword/None: Sendable[#Func Attribute#]; name=Sendable // KEYWORD2-NEXT: Keyword/None: preconcurrency[#Func Attribute#]; name=preconcurrency // KEYWORD2-NEXT: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed -// KEYWORD2-NEXT Keyword/None: lifetime[#Func Attribute#]; name=lifetime +// KEYWORD2-NEXT: Keyword/None: lifetime[#Func Attribute#]; name=lifetime +// KEYWORD2-NEXT: Keyword/None: abi[#Func Attribute#]; name=abi{{$}} +// KEYWORD2-NEXT: Keyword/None: concurrent[#Func Attribute#]; name=concurrent +// KEYWORD2-NOT: Keyword // KEYWORD2-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // KEYWORD2-DAG: Decl[Struct]/CurrModule: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper // KEYWORD2-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyResultBuilder[#Result Builder#]; name=MyResultBuilder @@ -167,6 +175,7 @@ actor MyGenericGlobalActor { // KEYWORD5-NEXT: Keyword/None: preconcurrency[#Struct Attribute#]; name=preconcurrency @#^ON_GLOBALVAR^# var globalVar +// ON_GLOBALVAR-DAG: Keyword/None: abi[#Var Attribute#]; name=abi // ON_GLOBALVAR-DAG: Keyword/None: available[#Var Attribute#]; name=available // ON_GLOBALVAR-DAG: Keyword/None: objc[#Var Attribute#]; name=objc // ON_GLOBALVAR-DAG: Keyword/None: NSCopying[#Var Attribute#]; name=NSCopying @@ -195,6 +204,7 @@ actor MyGenericGlobalActor { struct _S { @#^ON_INIT^# init() +// ON_INIT-DAG: Keyword/None: abi[#Constructor Attribute#]; name=abi // ON_INIT-DAG: Keyword/None: available[#Constructor Attribute#]; name=available // ON_INIT-DAG: Keyword/None: objc[#Constructor Attribute#]; name=objc // ON_INIT-DAG: Keyword/None: inline[#Constructor Attribute#]; name=inline @@ -205,6 +215,7 @@ struct _S { // ON_INIT-DAG: Keyword/None: preconcurrency[#Constructor Attribute#]; name=preconcurrency @#^ON_PROPERTY^# var foo +// ON_PROPERTY-DAG: Keyword/None: abi[#Var Attribute#]; name=abi // ON_PROPERTY-DAG: Keyword/None: available[#Var Attribute#]; name=available // ON_PROPERTY-DAG: Keyword/None: objc[#Var Attribute#]; name=objc // ON_PROPERTY-DAG: Keyword/None: NSCopying[#Var Attribute#]; name=NSCopying @@ -232,8 +243,12 @@ struct _S { // ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor // ON_PROPERTY-NOT: Decl[PrecedenceGroup] + @#^ON_SUBSCR^# subscript +// ON_SUBSCR-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi + @#^ON_METHOD^# private func foo() +// ON_METHOD-DAG: Keyword/None: abi[#Func Attribute#]; name=abi // ON_METHOD-DAG: Keyword/None: available[#Func Attribute#]; name=available // ON_METHOD-DAG: Keyword/None: objc[#Func Attribute#]; name=objc // ON_METHOD-DAG: Keyword/None: IBAction[#Func Attribute#]; name=IBAction @@ -291,6 +306,7 @@ struct _S { @#^ON_MEMBER_LAST^# +// ON_MEMBER_LAST-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi // ON_MEMBER_LAST-DAG: Keyword/None: available[#Declaration Attribute#]; name=available // ON_MEMBER_LAST-DAG: Keyword/None: objc[#Declaration Attribute#]; name=objc // ON_MEMBER_LAST-DAG: Keyword/None: dynamicCallable[#Declaration Attribute#]; name=dynamicCallable @@ -345,6 +361,8 @@ func takeClosure(_: () -> Void) { print("x") } } +// FIXME: Not valid in this position (but CompletionLookup can't tell that) +// IN_CLOSURE-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi // FIXME: We should mark MyPropertyWrapper and MyResultBuilder as Unrelated // IN_CLOSURE-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct // IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper @@ -363,6 +381,7 @@ func dummy2() {} @#^KEYWORD_LAST^# +// KEYWORD_LAST-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi // KEYWORD_LAST-DAG: Keyword/None: available[#Declaration Attribute#]; name=available{{$}} // KEYWORD_LAST-DAG: Keyword/None: freestanding[#Declaration Attribute#]; name=freestanding{{$}} // KEYWORD_LAST-DAG: Keyword/None: objc[#Declaration Attribute#]; name=objc{{$}} diff --git a/test/IDE/complete_decl_attribute_feature_requirement.swift b/test/IDE/complete_decl_attribute_feature_requirement.swift index f3d12029bc26e..461666a5e1f2f 100644 --- a/test/IDE/complete_decl_attribute_feature_requirement.swift +++ b/test/IDE/complete_decl_attribute_feature_requirement.swift @@ -3,6 +3,11 @@ // it's enabled. When a feature becomes non-experimental, move its test cases // into the normal complete_decl_attribute.swift test file. +// 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 + // REQUIRES: asserts // RUN: %batch-code-completion -filecheck-additional-suffix _DISABLED diff --git a/test/IRGen/asmname.swift b/test/IRGen/asmname.swift index 50d40110adfb7..6f1236dd4818d 100644 --- a/test/IRGen/asmname.swift +++ b/test/IRGen/asmname.swift @@ -1,9 +1,8 @@ -// RUN: %target-swift-frontend -enable-experimental-feature ABIAttribute %s -emit-ir > %t.ir +// RUN: %target-swift-frontend %s -emit-ir > %t.ir // RUN: %FileCheck --input-file %t.ir %s // RUN: %FileCheck --check-prefix NEGATIVE --input-file %t.ir %s // REQUIRES: CPU=i386 || CPU=x86_64 || CPU=arm64 -// REQUIRES: swift_feature_ABIAttribute // Non-Swift _silgen_name definitions diff --git a/test/Macros/macro_expand.swift b/test/Macros/macro_expand.swift index bd86cbef09982..074fcb5a6bd54 100644 --- a/test/Macros/macro_expand.swift +++ b/test/Macros/macro_expand.swift @@ -1,24 +1,23 @@ // REQUIRES: swift_swift_parser, executable_test -// REQUIRES: swift_feature_ABIAttribute // RUN: %empty-directory(%t) // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift // Diagnostics testing -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -enable-experimental-feature ABIAttribute +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS // Diagnostics testing by importing macros from a module // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library.swiftmodule %S/Inputs/freestanding_macro_library.swift -module-name freestanding_macro_library -load-plugin-library %t/%target-library-name(MacroDefinition) // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/freestanding_macro_library_2.swiftmodule %S/Inputs/freestanding_macro_library_2.swift -module-name freestanding_macro_library_2 -load-plugin-library %t/%target-library-name(MacroDefinition) -I %t -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -I %t -DIMPORT_MACRO_LIBRARY -enable-experimental-feature ABIAttribute +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -I %t -DIMPORT_MACRO_LIBRARY -// RUN: not %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics -Rmacro-loading > %t/macro-printing.txt -enable-experimental-feature ABIAttribute +// RUN: not %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -serialize-diagnostics-path %t/macro_expand.dia %s -emit-macro-expansion-files no-diagnostics -Rmacro-loading > %t/macro-printing.txt // RUN: c-index-test -read-diagnostics %t/macro_expand.dia 2>&1 | %FileCheck -check-prefix CHECK-DIAGS -dump-input=always %s // RUN: %FileCheck %s --check-prefix CHECK-MACRO-PRINTED < %t/macro-printing.txt -// RUN: not %target-swift-frontend -swift-version 5 -typecheck -diagnostic-style=swift -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS %s -enable-experimental-feature ABIAttribute > %t/pretty-macro-diagnostics.txt 2>&1 +// RUN: not %target-swift-frontend -swift-version 5 -typecheck -diagnostic-style=swift -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS %s > %t/pretty-macro-diagnostics.txt 2>&1 // RUN: %FileCheck %s --check-prefix PRETTY-DIAGS < %t/pretty-macro-diagnostics.txt // Debug info SIL testing diff --git a/test/Macros/macro_expand_peers.swift b/test/Macros/macro_expand_peers.swift index fa3c1cff4b234..dfd8a3cc0897a 100644 --- a/test/Macros/macro_expand_peers.swift +++ b/test/Macros/macro_expand_peers.swift @@ -1,5 +1,4 @@ // REQUIRES: swift_swift_parser, executable_test -// REQUIRES: swift_feature_ABIAttribute // For _Concurrency. // UNSUPPORTED: use_os_stdlib @@ -7,12 +6,12 @@ // RUN: %empty-directory(%t) // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -parse-as-library -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift -g -no-toolchain-stdlib-rpath -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -enable-experimental-feature ABIAttribute -DTEST_DIAGNOSTICS +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DTEST_DIAGNOSTICS // Check with the imported macro library vs. the local declaration of the macro. // RUN: %target-swift-frontend -swift-version 5 -emit-module -o %t/macro_library.swiftmodule %S/Inputs/macro_library.swift -module-name macro_library -load-plugin-library %t/%target-library-name(MacroDefinition) -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DIMPORT_MACRO_LIBRARY -I %t -enable-experimental-feature ABIAttribute -DTEST_DIAGNOSTICS +// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library -disable-availability-checking -DIMPORT_MACRO_LIBRARY -I %t -DTEST_DIAGNOSTICS // RUN: %target-swift-frontend -swift-version 5 -typecheck -load-plugin-library %t/%target-library-name(MacroDefinition) -parse-as-library %s -disable-availability-checking -dump-macro-expansions > %t/expansions-dump.txt 2>&1 diff --git a/test/ModuleInterface/attrs.swift b/test/ModuleInterface/attrs.swift index e6aef42064184..56da19cc2e346 100644 --- a/test/ModuleInterface/attrs.swift +++ b/test/ModuleInterface/attrs.swift @@ -1,6 +1,5 @@ // RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -module-name attrs \ -// RUN: -emit-private-module-interface-path %t.private.swiftinterface \ -// RUN: -enable-experimental-feature ABIAttribute +// RUN: -emit-private-module-interface-path %t.private.swiftinterface // RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -module-name attrs // RUN: %target-swift-typecheck-module-from-interface(%t.private.swiftinterface) -module-name attrs @@ -8,8 +7,6 @@ // RUN: %FileCheck %s --check-prefixes CHECK,PUBLIC-CHECK --input-file %t.swiftinterface // RUN: %FileCheck %s --check-prefixes CHECK,PRIVATE-CHECK --input-file %t.private.swiftinterface -// REQUIRES: swift_feature_ABIAttribute - // CHECK: @_transparent public func glass() -> Swift.Int { return 0 }{{$}} @_transparent public func glass() -> Int { return 0 } @@ -38,7 +35,7 @@ internal func __specialize_someGenericFunction(_ t: T) -> Int { @abi(func __abi__abiAttrOnFunction(param: Int)) public func abiAttrOnFunction(param: Int) {} -// CHECK: #if {{.*}} $ABIAttribute +// CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(func __abi__abiAttrOnFunction(param: Swift.Int)) // CHECK: public func abiAttrOnFunction(param: Swift.Int) // CHECK: #else @@ -48,7 +45,7 @@ public func abiAttrOnFunction(param: Int) {} @abi(let __abi__abiAttrOnVar: Int) public var abiAttrOnVar: Int = 42 -// CHECK: #if {{.*}} $ABIAttribute +// CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(var __abi__abiAttrOnVar: Swift.Int) // CHECK: public var abiAttrOnVar: Swift.Int // CHECK: #else @@ -57,7 +54,7 @@ public var abiAttrOnVar: Int = 42 // CHECK: #endif public struct MutatingTest { - // CHECK: #if {{.*}} $ABIAttribute + // CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(mutating func abiMutFunc()) // CHECK: public mutating func abiMutFunc() // CHECK: #else @@ -68,14 +65,14 @@ public struct MutatingTest { public mutating func abiMutFunc() {} } -// PUBLIC-CHECK-NOT: #if {{.*}} $ABIAttribute +// PUBLIC-CHECK-NOT: #if {{.*}} $ABIAttributeSE0479 // PUBLIC-CHECK-NOT: @abi(func abiSpiFunc()) // PUBLIC-CHECK-NOT: public func abiSpiFunc() // PUBLIC-CHECK-NOT: #else // PUBLIC-CHECK-NOT: @_silgen_name("$s5attrs10abiSpiFuncyyF") // PUBLIC-CHECK-NOT: public func abiSpiFunc() // PUBLIC-CHECK-NOT: #endif -// PRIVATE-CHECK: #if {{.*}} $ABIAttribute +// PRIVATE-CHECK: #if {{.*}} $ABIAttributeSE0479 // PRIVATE-CHECK: @abi(func abiSpiFunc()) // PRIVATE-CHECK: public func abiSpiFunc() // PRIVATE-CHECK: #else @@ -88,7 +85,7 @@ public struct MutatingTest { // We should print feature guards outside, but not inside, an @abi attribute. @abi(func sendingABI() -> sending Any?) public func sendingABI() -> Any? { nil } -// CHECK: #if {{.*}} && $ABIAttribute +// CHECK: #if {{.*}} && $ABIAttributeSE0479 // CHECK: @abi(func sendingABI() -> sending Any?) // CHECK: public func sendingABI() -> Any? // CHECK: #elseif {{.*}} && $SendingArgsAndResults diff --git a/test/ModuleInterface/attrs_objc.swift b/test/ModuleInterface/attrs_objc.swift index 37cb78318be05..0f8fd5b1f2ca0 100644 --- a/test/ModuleInterface/attrs_objc.swift +++ b/test/ModuleInterface/attrs_objc.swift @@ -1,19 +1,17 @@ // RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s \ -// RUN: -enable-objc-interop -module-name attrs_objc \ -// RUN: -enable-experimental-feature ABIAttribute +// RUN: -enable-objc-interop -module-name attrs_objc // RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -module-name attrs_objc // RUN: %FileCheck %s --input-file %t.swiftinterface // REQUIRES: objc_interop -// REQUIRES: swift_feature_ABIAttribute import Foundation @objcMembers public class ObjCTest: NSObject { - // CHECK: #if {{.*}} $ABIAttribute + // CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(func abiObjCFunc()) // CHECK: @objc public func abiObjCFunc() // CHECK: #else @@ -23,7 +21,7 @@ public class ObjCTest: NSObject { @abi(func abiObjCFunc()) @objc public func abiObjCFunc() {} - // CHECK: #if {{.*}} $ABIAttribute + // CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(func abiImplicitObjCFunc()) // CHECK: @objc public func abiImplicitObjCFunc() // CHECK: #else @@ -33,7 +31,7 @@ public class ObjCTest: NSObject { @abi(func abiImplicitObjCFunc()) public func abiImplicitObjCFunc() {} - // CHECK: #if {{.*}} $ABIAttribute + // CHECK: #if {{.*}} $ABIAttributeSE0479 // CHECK: @abi(func abiIBActionFunc(_: Any)) // CHECK: @objc @IBAction @_Concurrency.MainActor @preconcurrency public func abiIBActionFunc(_: Any) // CHECK: #else diff --git a/test/attr/attr_abi.swift b/test/attr/attr_abi.swift index 3513e3ac42e5e..49116208b3740 100644 --- a/test/attr/attr_abi.swift +++ b/test/attr/attr_abi.swift @@ -1,6 +1,5 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -enable-experimental-feature ABIAttribute -enable-experimental-feature AddressableParameters -enable-experimental-feature NoImplicitCopy -enable-experimental-feature SymbolLinkageMarkers -enable-experimental-feature StrictMemorySafety -enable-experimental-feature LifetimeDependence -enable-experimental-feature CImplementation -import-bridging-header %S/Inputs/attr_abi.h -parse-as-library -debugger-support +// RUN: %target-typecheck-verify-swift -enable-experimental-feature Extern -enable-experimental-feature AddressableParameters -enable-experimental-feature NoImplicitCopy -enable-experimental-feature SymbolLinkageMarkers -enable-experimental-feature StrictMemorySafety -enable-experimental-feature LifetimeDependence -enable-experimental-feature CImplementation -import-bridging-header %S/Inputs/attr_abi.h -parse-as-library -debugger-support -// REQUIRES: swift_feature_ABIAttribute // REQUIRES: swift_feature_AddressableParameters // REQUIRES: swift_feature_CImplementation // REQUIRES: swift_feature_Extern diff --git a/test/attr/attr_abi_objc.swift b/test/attr/attr_abi_objc.swift index 653e52a1b4989..b16e0ae6c440a 100644 --- a/test/attr/attr_abi_objc.swift +++ b/test/attr/attr_abi_objc.swift @@ -1,6 +1,5 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature ABIAttribute -parse-as-library +// RUN: %target-typecheck-verify-swift -parse-as-library -// REQUIRES: swift_feature_ABIAttribute // REQUIRES: objc_interop import Foundation diff --git a/test/attr/attr_weaklinked.swift b/test/attr/attr_weaklinked.swift index a56dbf4bf8ecb..831afa281d32d 100644 --- a/test/attr/attr_weaklinked.swift +++ b/test/attr/attr_weaklinked.swift @@ -1,7 +1,6 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-feature ABIAttribute +// RUN: %target-typecheck-verify-swift // UNSUPPORTED: OS=windows-msvc -// REQUIRES: swift_feature_ABIAttribute @_weakLinked public func f() { } diff --git a/test/attr/feature_requirement.swift b/test/attr/feature_requirement.swift index f568a707b91ad..d8e6121311bfc 100644 --- a/test/attr/feature_requirement.swift +++ b/test/attr/feature_requirement.swift @@ -1,16 +1,16 @@ // 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 ABIAttribute +// RUN: %target-typecheck-verify-swift -parse-as-library -verify-additional-prefix enabled- -enable-experimental-feature CompileTimeValues // REQUIRES: asserts // This test checks whether DECL_ATTR_FEATURE_REQUIREMENT is being applied correctly. // It is expected to need occasional edits as experimental features are stabilized. -@abi(func fn()) -func fn() {} // expected-disabled-error@-1 {{'abi' attribute is only valid when experimental feature ABIAttribute is enabled}} +@const +public let x = 1 // expected-disabled-error@-1 {{'const' attribute is only valid when experimental feature CompileTimeValues is enabled}} -#if hasAttribute(abi) - #error("does have @abi") // expected-enabled-error {{does have @abi}} +#if hasAttribute(const) + #error("does have @const") // expected-enabled-error {{does have @const}} #else - #error("doesn't have @abi") // expected-disabled-error {{doesn't have @abi}} + #error("doesn't have @const") // expected-disabled-error {{doesn't have @const}} #endif