Skip to content

Commit 6667471

Browse files
authored
Merge pull request #81115 from beccadax/abi-let-you-graduate
Finish implementing `@abi` (SE-0476)
2 parents 1cdfd01 + 01431b8 commit 6667471

19 files changed

+113
-103
lines changed

include/swift/AST/DeclAttr.def

-1
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,6 @@ DECL_ATTR(abi, ABI,
861861
OnConstructor | OnFunc | OnSubscript | OnVar,
862862
LongAttribute | ABIStableToAdd | ABIStableToRemove | APIStableToAdd | APIStableToRemove | ForbiddenInABIAttr,
863863
165)
864-
DECL_ATTR_FEATURE_REQUIREMENT(ABI, ABIAttribute)
865864

866865
// Unused '166': Used to be `@execution(caller | concurrent)` replaced with `@concurrent` and `nonisolated(nonsending)`
867866

include/swift/AST/DiagnosticsSema.def

+4-8
Original file line numberDiff line numberDiff line change
@@ -8483,14 +8483,10 @@ ERROR(attr_abi_mismatched_async,none,
84838483
"cannot give %0 the ABI of %select{a non-async|an async}1 %kindonly0",
84848484
(Decl *, /*abiIsAsync=*/bool))
84858485

8486-
ERROR(attr_abi_mismatched_pbd_size,none,
8487-
"cannot give pattern binding the ABI of a binding with "
8488-
"%select{more|fewer}0 patterns",
8489-
(/*abiHasExtra=*/bool))
8490-
8491-
ERROR(attr_abi_mismatched_var,none,
8492-
"no match for %select{%kind0 in the ABI|ABI %kind0}1",
8493-
(Decl *, /*isABI=*/bool))
8486+
ERROR(attr_abi_multiple_vars,none,
8487+
"'abi' attribute can only be applied to a single %0; declare each "
8488+
"%0 separately",
8489+
(DescriptiveDeclKind))
84948490

84958491
ERROR(attr_abi_incompatible_with_silgen_name,none,
84968492
"cannot use '@_silgen_name' and '@abi' on the same %kindonly0 because "

include/swift/Basic/Features.def

+1-3
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ LANGUAGE_FEATURE(AsyncExecutionBehaviorAttributes, 0, "@concurrent and nonisolat
258258
LANGUAGE_FEATURE(IsolatedConformances, 407, "Global-actor isolated conformances")
259259
LANGUAGE_FEATURE(ValueGenericsNameLookup, 452, "Value generics appearing as static members for namelookup")
260260
LANGUAGE_FEATURE(GeneralizedIsSameMetaTypeBuiltin, 465, "Builtin.is_same_metatype with support for noncopyable/nonescapable types")
261+
SUPPRESSIBLE_LANGUAGE_FEATURE(ABIAttributeSE0479, 479, "@abi attribute on functions, initializers, properties, and subscripts")
261262

262263
// Swift 6
263264
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -483,9 +484,6 @@ EXPERIMENTAL_FEATURE(CoroutineAccessorsUnwindOnCallerError, false)
483484
EXPERIMENTAL_FEATURE(AddressableParameters, true)
484485
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(AddressableTypes, true)
485486

486-
/// Allow the @abi attribute.
487-
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(ABIAttribute, true)
488-
489487
/// Allow custom availability domains to be defined and referenced.
490488
EXPERIMENTAL_FEATURE(CustomAvailability, true)
491489

lib/AST/ASTPrinter.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3283,8 +3283,8 @@ suppressingFeatureCoroutineAccessors(PrintOptions &options,
32833283
}
32843284

32853285
static void
3286-
suppressingFeatureABIAttribute(PrintOptions &options,
3287-
llvm::function_ref<void()> action) {
3286+
suppressingFeatureABIAttributeSE0479(PrintOptions &options,
3287+
llvm::function_ref<void()> action) {
32883288
llvm::SaveAndRestore<bool> scope1(options.PrintSyntheticSILGenName, true);
32893289
ExcludeAttrRAII scope2(options.ExcludeAttrList, DeclAttrKind::ABI);
32903290
action();

lib/AST/FeatureSet.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ static ABIAttr *getABIAttr(Decl *decl) {
387387
return decl->getAttrs().getAttribute<ABIAttr>();
388388
}
389389

390-
static bool usesFeatureABIAttribute(Decl *decl) {
390+
static bool usesFeatureABIAttributeSE0479(Decl *decl) {
391391
return getABIAttr(decl) != nullptr;
392392
}
393393

lib/ASTGen/Sources/ASTGen/SourceFile.swift

-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ extension Parser.ExperimentalFeatures {
7575
mapFeature(.NonescapableTypes, to: .nonescapableTypes)
7676
mapFeature(.TrailingComma, to: .trailingComma)
7777
mapFeature(.CoroutineAccessors, to: .coroutineAccessors)
78-
mapFeature(.ABIAttribute, to: .abiAttribute)
7978
mapFeature(.OldOwnershipOperatorSpellings, to: .oldOwnershipOperatorSpellings)
8079
mapFeature(.KeyPathWithMethodMembers, to: .keypathWithMethodMembers)
8180
mapFeature(.InlineArrayTypeSugar, to: .inlineArrayTypeSugar)

lib/Sema/TypeCheckAttrABI.cpp

+12-43
Original file line numberDiff line numberDiff line change
@@ -1102,60 +1102,29 @@ class ABIDeclChecker : public ASTComparisonVisitor<ABIDeclChecker> {
11021102
};
11031103

11041104
void checkABIAttrPBD(PatternBindingDecl *APBD, VarDecl *VD) {
1105-
auto &diags = VD->getASTContext().Diags;
11061105
auto PBD = VD->getParentPatternBinding();
11071106

1108-
// To make sure we only diagnose this stuff once, check that VD is the first
1109-
// anchoring variable in the PBD.
1110-
bool isFirstAnchor = false;
1107+
Decl *anchorVD = nullptr;
11111108
for (auto i : range(PBD->getNumPatternEntries())) {
1112-
auto anchorVD = PBD->getAnchoringVarDecl(i);
1113-
if (anchorVD) {
1114-
isFirstAnchor = (anchorVD == VD);
1109+
anchorVD = PBD->getAnchoringVarDecl(i);
1110+
if (anchorVD)
11151111
break;
1116-
}
11171112
}
11181113

1119-
if (!isFirstAnchor)
1114+
// To make sure we only diagnose this stuff once, check that VD is the
1115+
// first anchoring variable in the PBD.
1116+
if (anchorVD != VD)
11201117
return;
11211118

1122-
// Check that the PBDs have the same number of patterns.
1123-
if (PBD->getNumPatternEntries() < APBD->getNumPatternEntries()) {
1124-
diags.diagnose(APBD->getPattern(PBD->getNumPatternEntries())->getLoc(),
1125-
diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/false);
1126-
return;
1127-
}
1128-
if (PBD->getNumPatternEntries() > APBD->getNumPatternEntries()) {
1129-
diags.diagnose(PBD->getPattern(APBD->getNumPatternEntries())->getLoc(),
1130-
diag::attr_abi_mismatched_pbd_size, /*abiHasExtra=*/true);
1119+
// In the final approved feature, we only permit single-variable patterns.
1120+
// (However, the rest of the compiler tolerates them.)
1121+
if (!PBD->getSingleVar() || !APBD->getSingleVar()) {
1122+
PBD->diagnose(diag::attr_abi_multiple_vars,
1123+
anchorVD ? anchorVD->getDescriptiveKind()
1124+
: PBD->getDescriptiveKind());
11311125
return;
11321126
}
11331127

1134-
// Check that each pattern has the same number of variables.
1135-
bool didDiagnose = false;
1136-
for (auto i : range(PBD->getNumPatternEntries())) {
1137-
SmallVector<VarDecl *, 8> VDs;
1138-
SmallVector<VarDecl *, 8> AVDs;
1139-
1140-
PBD->getPattern(i)->collectVariables(VDs);
1141-
APBD->getPattern(i)->collectVariables(AVDs);
1142-
1143-
if (VDs.size() < AVDs.size()) {
1144-
for (auto AVD : drop_begin(AVDs, VDs.size())) {
1145-
AVD->diagnose(diag::attr_abi_mismatched_var, AVD, /*isABI=*/true);
1146-
didDiagnose = true;
1147-
}
1148-
}
1149-
else if (VDs.size() > AVDs.size()) {
1150-
for (auto VD : drop_begin(VDs, AVDs.size())) {
1151-
VD->diagnose(diag::attr_abi_mismatched_var, VD, /*isABI=*/false);
1152-
didDiagnose = true;
1153-
}
1154-
}
1155-
}
1156-
if (didDiagnose)
1157-
return;
1158-
11591128
// Check the ABI PBD--this is what checks the underlying vars.
11601129
TypeChecker::typeCheckDecl(APBD);
11611130
}

test/ASTGen/attrs.swift

-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// RUN: %empty-directory(%t)
22

33
// RUN: %target-swift-frontend-dump-parse \
4-
// RUN: -enable-experimental-feature ABIAttribute \
54
// RUN: -enable-experimental-feature Extern \
65
// RUN: -enable-experimental-feature LifetimeDependence \
76
// RUN: -enable-experimental-feature RawLayout \
@@ -12,7 +11,6 @@
1211
// RUN: | %sanitize-address > %t/astgen.ast
1312

1413
// RUN: %target-swift-frontend-dump-parse \
15-
// RUN: -enable-experimental-feature ABIAttribute \
1614
// RUN: -enable-experimental-feature Extern \
1715
// RUN: -enable-experimental-feature LifetimeDependence \
1816
// RUN: -enable-experimental-feature RawLayout \
@@ -26,7 +24,6 @@
2624
// RUN: %target-typecheck-verify-swift \
2725
// RUN: -module-abi-name ASTGen \
2826
// RUN: -enable-experimental-feature ParserASTGen \
29-
// RUN: -enable-experimental-feature ABIAttribute \
3027
// RUN: -enable-experimental-feature Extern \
3128
// RUN: -enable-experimental-feature LifetimeDependence \
3229
// RUN: -enable-experimental-feature RawLayout \
@@ -38,7 +35,6 @@
3835
// REQUIRES: executable_test
3936
// REQUIRES: swift_swift_parser
4037
// REQUIRES: swift_feature_ParserASTGen
41-
// REQUIRES: swift_feature_ABIAttribute
4238
// REQUIRES: swift_feature_Extern
4339
// REQUIRES: swift_feature_LifetimeDependence
4440
// REQUIRES: swift_feature_RawLayout

test/IDE/complete_decl_attribute.swift

+17
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_INDEPENDENT_2 | %FileCheck %s -check-prefix=KEYWORD_LAST
2020
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=KEYWORD_LAST | %FileCheck %s -check-prefix=KEYWORD_LAST
2121

22+
// NOTE: If you want to test code completion for an experimental feature, please
23+
// put your tests in complete_decl_attribute_feature_requirement.swift, not
24+
// here. That file has the infrastructure to test that completions are not
25+
// offered when the feature is disabled.
26+
2227
struct MyStruct {}
2328

2429
@propertyWrapper
@@ -112,6 +117,7 @@ actor MyGenericGlobalActor<T> {
112117
// KEYWORD2-NEXT: Keyword/None: preconcurrency[#Func Attribute#]; name=preconcurrency
113118
// KEYWORD2-NEXT: Keyword/None: backDeployed[#Func Attribute#]; name=backDeployed
114119
// KEYWORD2-NEXT: Keyword/None: lifetime[#Func Attribute#]; name=lifetime
120+
// KEYWORD2-NEXT: Keyword/None: abi[#Func Attribute#]; name=abi{{$}}
115121
// KEYWORD2-NEXT: Keyword/None: concurrent[#Func Attribute#]; name=concurrent
116122
// KEYWORD2-NOT: Keyword
117123
// KEYWORD2-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
@@ -169,6 +175,7 @@ actor MyGenericGlobalActor<T> {
169175
// KEYWORD5-NEXT: Keyword/None: preconcurrency[#Struct Attribute#]; name=preconcurrency
170176

171177
@#^ON_GLOBALVAR^# var globalVar
178+
// ON_GLOBALVAR-DAG: Keyword/None: abi[#Var Attribute#]; name=abi
172179
// ON_GLOBALVAR-DAG: Keyword/None: available[#Var Attribute#]; name=available
173180
// ON_GLOBALVAR-DAG: Keyword/None: objc[#Var Attribute#]; name=objc
174181
// ON_GLOBALVAR-DAG: Keyword/None: NSCopying[#Var Attribute#]; name=NSCopying
@@ -197,6 +204,7 @@ actor MyGenericGlobalActor<T> {
197204

198205
struct _S {
199206
@#^ON_INIT^# init()
207+
// ON_INIT-DAG: Keyword/None: abi[#Constructor Attribute#]; name=abi
200208
// ON_INIT-DAG: Keyword/None: available[#Constructor Attribute#]; name=available
201209
// ON_INIT-DAG: Keyword/None: objc[#Constructor Attribute#]; name=objc
202210
// ON_INIT-DAG: Keyword/None: inline[#Constructor Attribute#]; name=inline
@@ -207,6 +215,7 @@ struct _S {
207215
// ON_INIT-DAG: Keyword/None: preconcurrency[#Constructor Attribute#]; name=preconcurrency
208216

209217
@#^ON_PROPERTY^# var foo
218+
// ON_PROPERTY-DAG: Keyword/None: abi[#Var Attribute#]; name=abi
210219
// ON_PROPERTY-DAG: Keyword/None: available[#Var Attribute#]; name=available
211220
// ON_PROPERTY-DAG: Keyword/None: objc[#Var Attribute#]; name=objc
212221
// ON_PROPERTY-DAG: Keyword/None: NSCopying[#Var Attribute#]; name=NSCopying
@@ -234,8 +243,12 @@ struct _S {
234243
// ON_PROPERTY-DAG: Decl[Actor]/CurrModule/TypeRelation[Convertible]: MyGenericGlobalActor[#Global Actor#]; name=MyGenericGlobalActor
235244
// ON_PROPERTY-NOT: Decl[PrecedenceGroup]
236245

246+
@#^ON_SUBSCR^# subscript
247+
// ON_SUBSCR-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
248+
237249
@#^ON_METHOD^# private
238250
func foo()
251+
// ON_METHOD-DAG: Keyword/None: abi[#Func Attribute#]; name=abi
239252
// ON_METHOD-DAG: Keyword/None: available[#Func Attribute#]; name=available
240253
// ON_METHOD-DAG: Keyword/None: objc[#Func Attribute#]; name=objc
241254
// ON_METHOD-DAG: Keyword/None: IBAction[#Func Attribute#]; name=IBAction
@@ -293,6 +306,7 @@ struct _S {
293306

294307

295308
@#^ON_MEMBER_LAST^#
309+
// ON_MEMBER_LAST-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
296310
// ON_MEMBER_LAST-DAG: Keyword/None: available[#Declaration Attribute#]; name=available
297311
// ON_MEMBER_LAST-DAG: Keyword/None: objc[#Declaration Attribute#]; name=objc
298312
// ON_MEMBER_LAST-DAG: Keyword/None: dynamicCallable[#Declaration Attribute#]; name=dynamicCallable
@@ -347,6 +361,8 @@ func takeClosure(_: () -> Void) {
347361
print("x")
348362
}
349363
}
364+
// FIXME: Not valid in this position (but CompletionLookup can't tell that)
365+
// IN_CLOSURE-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
350366
// FIXME: We should mark MyPropertyWrapper and MyResultBuilder as Unrelated
351367
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
352368
// IN_CLOSURE-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: MyPropertyWrapper[#Property Wrapper#]; name=MyPropertyWrapper
@@ -365,6 +381,7 @@ func dummy2() {}
365381

366382
@#^KEYWORD_LAST^#
367383

384+
// KEYWORD_LAST-DAG: Keyword/None: abi[#Declaration Attribute#]; name=abi
368385
// KEYWORD_LAST-DAG: Keyword/None: available[#Declaration Attribute#]; name=available{{$}}
369386
// KEYWORD_LAST-DAG: Keyword/None: freestanding[#Declaration Attribute#]; name=freestanding{{$}}
370387
// KEYWORD_LAST-DAG: Keyword/None: objc[#Declaration Attribute#]; name=objc{{$}}

test/IDE/complete_decl_attribute_feature_requirement.swift

+5
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
// it's enabled. When a feature becomes non-experimental, move its test cases
44
// into the normal complete_decl_attribute.swift test file.
55

6+
// NOTE: There are currently no experimental features that need code completion
7+
// testing, but this test file is being left in place for when it's needed
8+
// again. At that time, please remove the ABIAttribute tests.
9+
// REQUIRES: new_use_case
10+
611
// REQUIRES: asserts
712

813
// RUN: %batch-code-completion -filecheck-additional-suffix _DISABLED

test/IRGen/asmname.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
// RUN: %target-swift-frontend -enable-experimental-feature ABIAttribute %s -emit-ir > %t.ir
1+
// RUN: %target-swift-frontend %s -emit-ir > %t.ir
22
// RUN: %FileCheck --input-file %t.ir %s
33
// RUN: %FileCheck --check-prefix NEGATIVE --input-file %t.ir %s
44

55
// REQUIRES: CPU=i386 || CPU=x86_64 || CPU=arm64
6-
// REQUIRES: swift_feature_ABIAttribute
76

87
// Non-Swift _silgen_name definitions
98

test/Macros/macro_expand.swift

+23
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,29 @@ func testPropertyWrapperMacro() {
719719
#hasPropertyWrapperParam($x: .init(wrappedValue: 0))
720720
}
721721

722+
#if swift(>=1.0) && TEST_DIAGNOSTICS
723+
// Test that macros can't be used in @abi
724+
725+
struct ABIAttrWithFreestandingMacro1 {
726+
// expected-error@+1 {{cannot use pound literal in '@abi'}}
727+
@abi(#varValue)
728+
#varValue
729+
// expected-note@-1 {{in expansion of macro 'varValue' here}}
730+
}
731+
732+
struct ABIAttrWithFreestandingMacro2 {
733+
// expected-error@+1 {{cannot use pound literal in '@abi'}}
734+
@abi(#varValue)
735+
var value: Int { 0 }
736+
}
737+
738+
struct ABIAttrWithFreestandingMacro3 {
739+
@abi(var value: Int)
740+
#varValue
741+
}
742+
743+
#endif
744+
722745
#if TEST_DIAGNOSTICS
723746
@freestanding(expression)
724747
macro missingMacro() = #externalMacro(module: "MacroDefinition", type: "BluhBlah")

test/Macros/macro_expand_peers.swift

+23
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,26 @@ func closuresInPeerMacroCrash() {}
309309
@trait(Trait {})
310310
@trait(Trait {})
311311
var closuresInPeerMacroOnVariableCrash: Int = 0
312+
313+
// Test that macros can't be used in @abi
314+
315+
#if swift(>=5.3) && TEST_DIAGNOSTICS
316+
struct ABIAttrWithAttachedMacro {
317+
// expected-error@+1 {{macro 'addCompletionHandler()' cannot be expanded in '@abi' attribute}}
318+
@abi(@addCompletionHandler func fn1() async)
319+
@addCompletionHandler func fn1() async {}
320+
// From diagnostics in the expansion:
321+
// expected-note@-2 3{{in expansion of macro 'addCompletionHandler' on instance method 'fn1()' here}}
322+
// expected-note@-4 {{'fn1()' previously declared here}}
323+
324+
// expected-error@+1 {{macro 'addCompletionHandler()' cannot be expanded in '@abi' attribute}}
325+
@abi(@addCompletionHandler func fn2() async)
326+
func fn2() async {}
327+
328+
@abi(func fn3() async)
329+
@addCompletionHandler func fn3() async {}
330+
// From diagnostics in the expansion:
331+
// expected-note@-2 2{{in expansion of macro 'addCompletionHandler' on instance method 'fn3()' here}}
332+
// expected-note@-4 {{'fn3()' previously declared here}}
333+
}
334+
#endif

0 commit comments

Comments
 (0)