Skip to content

Commit cacac0b

Browse files
committed
[SILGen] Allow annotating self @_noImplicitCopy.
Allow @_noImplicitCopy to be applied to methods. Applying it there means that the self argument will have the attribute.
1 parent 9dbdfa8 commit cacac0b

File tree

5 files changed

+32
-1
lines changed

5 files changed

+32
-1
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,7 @@ SIMPLE_DECL_ATTR(_noImplicitCopy, NoImplicitCopy,
698698
UserInaccessible |
699699
ABIStableToAdd | ABIBreakingToRemove |
700700
APIStableToAdd | APIBreakingToRemove |
701-
OnParam | OnVar,
701+
OnFunc | OnParam | OnVar,
702702
122)
703703

704704
SIMPLE_DECL_ATTR(_noLocks, NoLocks,

lib/SILGen/SILGenProlog.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ struct ArgumentInitHelper {
360360
if (pd->isSelfParameter()) {
361361
if (auto *afd = dyn_cast<AbstractFunctionDecl>(pd->getDeclContext())) {
362362
lifetimeAnnotation = afd->getLifetimeAnnotation();
363+
isNoImplicitCopy = afd->isNoImplicitCopy();
363364
}
364365
} else {
365366
lifetimeAnnotation = pd->getLifetimeAnnotation();

lib/Sema/TypeCheckAttr.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,19 @@ void AttributeChecker::visitNoImplicitCopyAttr(NoImplicitCopyAttr *attr) {
343343
return;
344344
}
345345

346+
if (auto *funcDecl = dyn_cast<FuncDecl>(D)) {
347+
if (visitLifetimeAttr(attr))
348+
return;
349+
350+
// We only handle non-lvalue arguments today.
351+
if (funcDecl->isMutating()) {
352+
auto error = diag::noimplicitcopy_attr_valid_only_on_local_let_params;
353+
diagnoseAndRemoveAttr(attr, error);
354+
return;
355+
}
356+
return;
357+
}
358+
346359
auto *dc = D->getDeclContext();
347360

348361
// If we have a param decl that is marked as no implicit copy, change our

test/SILGen/noimplicitcopy_attr.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,13 @@ public func arguments(@_noImplicitCopy _ x: Klass) {
1818
public func argumentsOwned(@_noImplicitCopy _ x: __owned Klass) {
1919
x.doSomething()
2020
}
21+
22+
extension Klass {
23+
// CHECK-LABEL: sil hidden [ossa] @noimplicitcopy_method_attr : $@convention(method) (@owned Klass) -> () {
24+
// CHECK: {{bb[0-9]+}}({{%[^,]+}} : @noImplicitCopy @owned $Klass):
25+
// CHECK-LABEL: } // end sil function 'noimplicitcopy_method_attr'
26+
@_silgen_name("noimplicitcopy_method_attr")
27+
@_noImplicitCopy
28+
__consuming
29+
func noimplicitcopy_method_attr() {}
30+
}

test/attr/noimplicitcopy.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-move-only
2+
3+
struct S {
4+
func bar(@_noImplicitCopy s: S) {} // okay
5+
@_noImplicitCopy func foo(s: S) {} // okay
6+
@_noImplicitCopy mutating func nopers() {} // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets and params}}
7+
}

0 commit comments

Comments
 (0)