-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[moveOnly] Add an @_noImplicitCopy decl attribute and allow it to be only attached to local lets. #39927
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
gottesmm
merged 1 commit into
swiftlang:main
from
gottesmm:pr-7b7eae43b3c94f52f927ce574f94861e33da7f4a
Oct 26, 2021
Merged
[moveOnly] Add an @_noImplicitCopy decl attribute and allow it to be only attached to local lets. #39927
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
f// RUN: %target-typecheck-verify-swift -parse -parse-stdlib -disable-availability-checking -verify-syntax-tree | ||
|
||
import Swift | ||
|
||
class Klass {} | ||
|
||
func argumentsAndReturns(@_noImplicitCopy _ x: Klass) -> Klass { | ||
return x | ||
} | ||
|
||
func letDecls(@_noImplicitCopy _ x: Klass) -> () { | ||
@_noImplicitCopy let y: Klass = x | ||
print(y) | ||
} | ||
|
||
func varDecls(@_noImplicitCopy _ x: Klass, @_noImplicitCopy _ x2: Klass) -> () { | ||
@_noImplicitCopy var y: Klass = x | ||
y = x2 | ||
print(y) | ||
} | ||
|
||
func getKlass() -> Builtin.NativeObject { | ||
let k = Klass() | ||
let b = Builtin.unsafeCastToNativeObject(k) | ||
return Builtin.move(b) | ||
} | ||
|
||
@_noImplicitCopy var g: Builtin.NativeObject = getKlass() | ||
@_noImplicitCopy let g2: Builtin.NativeObject = getKlass() | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
// RUN: %target-typecheck-verify-swift -parse-stdlib -disable-availability-checking -verify-syntax-tree | ||
|
||
import Swift | ||
|
||
class Klass {} | ||
|
||
func argumentsAndReturns(@_noImplicitCopy _ x: Klass) -> Klass { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
return x | ||
} | ||
func letDecls(_ x: Klass) -> () { | ||
@_noImplicitCopy let y: Klass = x | ||
print(y) | ||
} | ||
|
||
func varDecls(_ x: Klass, _ x2: Klass) -> () { | ||
@_noImplicitCopy var y: Klass = x // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
y = x2 | ||
print(y) | ||
} | ||
|
||
func getKlass() -> Builtin.NativeObject { | ||
let k = Klass() | ||
let b = Builtin.unsafeCastToNativeObject(k) | ||
return Builtin.move(b) | ||
} | ||
|
||
@_noImplicitCopy var g: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
@_noImplicitCopy let g2: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
@_noImplicitCopy var g3: Builtin.NativeObject { getKlass() } // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
|
||
struct MyStruct { | ||
// Error if @_noImplicitCopy on struct fields. We do not have move only types and | ||
// these are part of MyStruct. | ||
// | ||
// TODO: Make error specific for move only on struct/enum. | ||
@_noImplicitCopy var x: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
@_noImplicitCopy let y: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
|
||
@_noImplicitCopy var myMoveOnly: Builtin.NativeObject { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return getKlass() | ||
} | ||
|
||
func foo<T>(@_noImplicitCopy _ t: T) { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
} | ||
} | ||
|
||
struct MyGenericStruct<T> { | ||
func foo(@_noImplicitCopy _ t: T) { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
} | ||
} | ||
|
||
protocol P { | ||
@_noImplicitCopy var x: Builtin.NativeObject { get } // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
} | ||
|
||
func foo<T>(@_noImplicitCopy _ t: T) { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
} | ||
|
||
// Do not error on class fields. The noImplicitCopy field is separate from the | ||
// underlying class itself so the fact the class is not move only does not | ||
// suggest that the binding inside the class can be. | ||
class MyClass { | ||
@_noImplicitCopy var x: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
@_noImplicitCopy let y: Builtin.NativeObject = getKlass() // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
|
||
@_noImplicitCopy var myMoveOnly: Builtin.NativeObject { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return getKlass() | ||
} | ||
|
||
func foo<T>(@_noImplicitCopy _ t: T) { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
} | ||
} | ||
|
||
class MyGenericClass<T> { | ||
@_noImplicitCopy var x: T? = nil // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
@_noImplicitCopy let y: T? = nil // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
|
||
@_noImplicitCopy var myMoveOnly: T? { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return nil | ||
} | ||
|
||
@_noImplicitCopy var myMoveOnly2: Builtin.NativeObject? { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return nil | ||
} | ||
|
||
func foo(@_noImplicitCopy _ t: T) { // expected-error {{@_noImplicitCopy may only be used on 'var' declarations}} | ||
} | ||
} | ||
|
||
// We need to error on Enums since the case is part of the value and we do not | ||
// support move only types. | ||
enum MyEnum { | ||
case none | ||
case noImplicitCopyCase(Klass) | ||
|
||
// We suport doing it on computed properties though. | ||
@_noImplicitCopy var myMoveOnly: Builtin.NativeObject { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return getKlass() | ||
} | ||
} | ||
|
||
// We need to error on Enums since the case is part of the value and we do not | ||
// support move only types. | ||
enum MyGenericEnum<T> { | ||
case none | ||
case noImplicitCopyCase(Klass) | ||
|
||
// We suport doing it on computed properties though. | ||
@_noImplicitCopy var myMoveOnly: Builtin.NativeObject { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return getKlass() | ||
} | ||
|
||
// We suport doing it on computed properties though. | ||
@_noImplicitCopy var myMoveOnly2: T? { // expected-error {{'@_noImplicitCopy' attribute can only be applied to local lets}} | ||
return nil | ||
} | ||
} | ||
|
||
struct UnsafePointerWithOwner<T> { | ||
var owner: AnyObject? = nil | ||
var data: UnsafePointer<T>? = nil | ||
|
||
func doNothing() {} | ||
} | ||
|
||
func useUnsafePointerWithOwner<T>(_ x: UnsafePointerWithOwner<T>) { | ||
// We allow for this here (even without opaque values, since we check this | ||
// at the SIL level in SILGen). | ||
@_noImplicitCopy let y = x | ||
y.doNothing() | ||
let z = y | ||
print(z) | ||
} | ||
|
||
func useGeneric<T>(_ x: T) { | ||
// We allow for this here (even without opaque values, since we check this | ||
// at the SIL level in SILGen). | ||
@_noImplicitCopy let y = x | ||
let z = y | ||
print(z) | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you want
!dc->isLocalContext()
here. It should be able to subsume this check and the one below as well. (You'll likely want a separate check forstatic
).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I'll do that in a subsequent PR.