Skip to content

Commit 8436db3

Browse files
authored
Merge pull request #78021 from jckarter/addressable-params-2
Add an `@_addressableSelf` attribute to mark the self param of methods as addressable.
2 parents 159259a + ac7a616 commit 8436db3

File tree

11 files changed

+60
-3
lines changed

11 files changed

+60
-3
lines changed

include/swift/AST/DeclAttr.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,11 @@ DECL_ATTR(lifetime, Lifetime,
513513
OnAccessor | OnConstructor | OnFunc | OnSubscript | LongAttribute | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove | AllowMultipleAttributes,
514514
161)
515515

516-
LAST_DECL_ATTR(Lifetime)
516+
SIMPLE_DECL_ATTR(_addressableSelf, AddressableSelf,
517+
OnAccessor | OnConstructor | OnFunc | OnSubscript | ABIBreakingToAdd | ABIStableToRemove | APIBreakingToAdd | APIStableToRemove | UserInaccessible,
518+
162)
519+
520+
LAST_DECL_ATTR(AddressableSelf)
517521

518522
#undef DECL_ATTR_ALIAS
519523
#undef CONTEXTUAL_DECL_ATTR_ALIAS

include/swift/AST/DiagnosticsSema.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,11 @@ ERROR(incorrect_explicit_closure_result_vs_return_type,none,
309309
"declared closure result %0 is incompatible with return type %1",
310310
(Type, Type))
311311

312+
ERROR(addressable_not_enabled,none,
313+
"@_addressable is an experimental feature", ())
314+
ERROR(addressableSelf_not_on_method,none,
315+
"@_addressableSelf cannot be applied to non-member declarations", ())
316+
312317
ERROR(unsupported_closure_attr,none,
313318
"%select{attribute |}0 '%1' is not supported on a closure",
314319
(bool, StringRef))

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4057,6 +4057,10 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
40574057
// The default flagless state.
40584058
break;
40594059
}
4060+
4061+
if (AFD->getAttrs().hasAttribute<AddressableSelfAttr>()) {
4062+
flags = flags.withAddressable(true);
4063+
}
40604064

40614065
return AnyFunctionType::Param(selfTy, Identifier(), flags);
40624066
}

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3735,6 +3735,7 @@ class PrintAttribute : public AttributeVisitor<PrintAttribute, void, StringRef>,
37353735
}
37363736

37373737
TRIVIAL_ATTR_PRINTER(Actor, actor)
3738+
TRIVIAL_ATTR_PRINTER(AddressableSelf, _addressableSelf)
37383739
TRIVIAL_ATTR_PRINTER(AlwaysEmitConformanceMetadata,
37393740
always_emit_conformance_metadata)
37403741
TRIVIAL_ATTR_PRINTER(AlwaysEmitIntoClient, always_emit_into_client)

lib/AST/Decl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9947,6 +9947,9 @@ ParamDecl *AbstractFunctionDecl::getImplicitSelfDecl(bool createIfNeeded) {
99479947
*selfDecl = new (ctx) ParamDecl(SourceLoc(), SourceLoc(), Identifier(),
99489948
getLoc(), ctx.Id_self, this);
99499949
(*selfDecl)->setImplicit();
9950+
if (getAttrs().hasAttribute<AddressableSelfAttr>()) {
9951+
(*selfDecl)->setAddressable(true);
9952+
}
99509953
return *selfDecl;
99519954
}
99529955

lib/AST/FeatureSet.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,10 @@ static bool usesFeatureIsolatedAny(Decl *decl) {
291291
}
292292

293293
static bool usesFeatureAddressableParameters(Decl *d) {
294+
if (d->getAttrs().hasAttribute<AddressableSelfAttr>()) {
295+
return true;
296+
}
297+
294298
auto fd = dyn_cast<AbstractFunctionDecl>(d);
295299
if (!fd) {
296300
return false;

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,8 @@ extension ASTGenVisitor {
186186
return handle(self.generateUnavailableFromAsyncAttr(attribute: node)?.asDeclAttribute)
187187

188188
// Simple attributes.
189-
case .alwaysEmitConformanceMetadata,
189+
case .addressableSelf,
190+
.alwaysEmitConformanceMetadata,
190191
.alwaysEmitIntoClient,
191192
.atReasync,
192193
.atRethrows,

lib/Sema/TypeCheckAttr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
388388
void visitSILGenNameAttr(SILGenNameAttr *attr);
389389
void visitUnsafeAttr(UnsafeAttr *attr);
390390
void visitLifetimeAttr(LifetimeAttr *attr);
391+
void visitAddressableSelfAttr(AddressableSelfAttr *attr);
391392
};
392393

393394
} // end anonymous namespace
@@ -7767,6 +7768,16 @@ void AttributeChecker::visitUnsafeAttr(UnsafeAttr *attr) {
77677768

77687769
void AttributeChecker::visitLifetimeAttr(LifetimeAttr *attr) {}
77697770

7771+
void AttributeChecker::visitAddressableSelfAttr(AddressableSelfAttr *attr) {
7772+
if (!Ctx.LangOpts.hasFeature(Feature::AddressableParameters)) {
7773+
Ctx.Diags.diagnose(attr->getLocation(), diag::addressable_not_enabled);
7774+
}
7775+
7776+
if (!D->getDeclContext()->isTypeContext()) {
7777+
Ctx.Diags.diagnose(attr->getLocation(), diag::addressableSelf_not_on_method);
7778+
}
7779+
}
7780+
77707781
namespace {
77717782

77727783
class ClosureAttributeChecker

lib/Sema/TypeCheckDeclOverride.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,7 @@ namespace {
17351735
UNINTERESTING_ATTR(StaticExclusiveOnly)
17361736
UNINTERESTING_ATTR(PreInverseGenerics)
17371737
UNINTERESTING_ATTR(Lifetime)
1738+
UNINTERESTING_ATTR(AddressableSelf)
17381739
#undef UNINTERESTING_ATTR
17391740

17401741
void visitAvailableAttr(AvailableAttr *attr) {

test/SILGen/addressable_params.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ func withUP<T>(to: borrowing @_addressable T, _ body: (UnsafePointer<T>) -> Void
88
// Forwarding an addressable parameter binding as an argument to another
99
// addressable parameter with matching ownership forwards the address without
1010
// copying or moving the value.
11-
// CHECK-LABEL: sil {{.*}}@$s{{.*}}14testForwarding{{.*}} : $@convention(thin) (@in_guaranteed String) -> ()
11+
// CHECK-LABEL: sil {{.*}}@$s{{.*}}14testForwarding{{.*}} :
12+
// CHECK-SAME: $@convention(thin) (@in_guaranteed String) -> ()
1213
func testForwarding(x: borrowing @_addressable String) {
1314
// CHECK: [[MO:%.*]] = copyable_to_moveonlywrapper_addr %0
1415
// CHECK: [[MOR:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[MO]]
@@ -29,3 +30,19 @@ func testUseAsNormalArgument(x: borrowing @_addressable String) {
2930
normalConsumingArgument(copy x)
3031
normalGenericArgument(x)
3132
}
33+
34+
struct Foo {
35+
var x: String
36+
37+
// CHECK-LABEL: sil {{.*}}@$s{{.*}}18testForwardingSelf{{.*}} :
38+
// CHECK-SAME: $@convention(method) (@in_guaranteed Foo) -> ()
39+
@_addressableSelf borrowing func testForwardingSelf() {
40+
// CHECK: [[MO:%.*]] = copyable_to_moveonlywrapper_addr %0
41+
// CHECK: [[MOR:%.*]] = mark_unresolved_non_copyable_value [no_consume_or_assign] [[MO]]
42+
// CHECK: [[MORC:%.*]] = moveonlywrapper_to_copyable_addr [[MOR]]
43+
// CHECK: apply {{.*}}([[MORC]],
44+
withUP(to: self) {
45+
_ = $0
46+
}
47+
}
48+
}

test/attr/attr_addressable.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,9 @@ func foo(_: @_addressable String) {}
66
func bar(_: (@_addressable String) -> Void) {}
77

88
func bas(_: @convention(c) (@_addressable String) -> Void) {} // expected-error{{_addressable is not allowed in C function conventions}} expected-error{{not representable in Objective-C}}
9+
10+
@_addressableSelf func doesNotHaveSelf() {} // expected-error{{cannot be applied to non-member declarations}}
11+
12+
struct Foo {
13+
@_addressableSelf func doesHaveSelf() {}
14+
}

0 commit comments

Comments
 (0)