-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[borrowing/consuming] Make borrowing and consuming parameters no implicit copy. #66381
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
[borrowing/consuming] Make borrowing and consuming parameters no implicit copy. #66381
Conversation
… `borrowing`" This reverts commit 8899d3b.
…modifiers" This reverts commit 87f190b.
…() instead of getASTType() to prevent us from looking through no implicit copy types while serializing. This change makes sense since, in general, when serializing we do not want to look through no implicit copy types since we are trying to 1-1 preserve the SIL.
…h the AST serialization machinery. This looks like a thinko from the early part of the implementation. Without this, the machinery doesn't recognize the layout and just asserts.
…uming/Borrowing. I also added a static_assert to make sure that we always catch this in the future.
…e_addr. The reason why I am using a different instruction for addresses and objects here is that the object checker doesnt have to deal with things like initialization.
…lywrapper_addr. Just the $*T -> $*@moveOnly T variant for addresses. Unlike the object version this acts like a cast rather than something that provides semantics from the frontend to the optimizer.
…r_to_copyable_addr.
I am going to use this to unwrap ${ @moveOnly T } so that I can pass it to
partial_apply that expect a ${ T }
|
@swift-ci smoke test |
jckarter
left a comment
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.
Looks good.
6b38d73 to
23b439a
Compare
|
@swift-ci smoke test |
…a noimplicitcopy type. rdar://108383660
23b439a to
59c8cff
Compare
|
@swift-ci smoke test |
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.
These are identical except for the isa<...> tests on the instructions. You could define one bool isPartialApplyUser(SILInstruction* user, bool isUser) and replace those tests with isa<PartialApplyInst>(...) == isUser
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.
is this one not suppose to raise any errors since it's not an escaping closure?
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.
Yes. I am going to fix that in a subsequent commit. This is providing the initial support. There will not be a source break when I fix it since we are removing an error.
| // We want to specifically use getASTType() here instead of getRawASTType() | ||
| // to ensure that we can correctly get our substituted field type. If we | ||
| // need to rewrap the type layer, we do it below. | ||
| substFieldTy = | ||
| getASTType()->getTypeOfMember(&TC.M, field)->getCanonicalType(); |
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.
As an aside: I think we ought to do something about this getASTType / getRawASTType thing since it's a bit confusing from a naming perspective alone; the only difference is with removing any move-only wrapper. That wrapper type needs to be more widely supported, since it's now being serialized and carried through the pipeline.
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.
From working with it, I think that the only way to do this is to have a lot of tests that exercise the behavior. If you have a better name, I am more than happy to rename it.
| } | ||
| // CHECK: Doing something MyOtherName | ||
| f2() | ||
| } |
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.
we should test copy x being passed to a consuming parameter here too.
| func testAddressOnlyBorrowingEnum<T>(_ x: borrowing AddressOnlyEnum<T>) { | ||
| // expected-error @-1 {{'x' is borrowed and cannot be consumed}} | ||
| switch x { // expected-note {{consumed here}} | ||
| case let .x(y): | ||
| _ = y | ||
| break | ||
| case let .y(z): | ||
| _ = z | ||
| break | ||
| } | ||
| } |
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 we really need to tune these diagnostics to tell users that they can and are required to make an explicit copy.
| func testLoadableBorrowingEnum(_ x: borrowing LoadableEnum) { | ||
| // expected-error @-1 {{'x' is borrowed and cannot be consumed}} | ||
| switch x { // expected-note {{consumed here}} | ||
| case let .x(y): | ||
| _ = y | ||
| break | ||
| case .y: | ||
| break | ||
| } | ||
| } | ||
|
|
||
| func testLoadableBorrowingCopyOperator(_ x: borrowing NonTrivialStruct) { | ||
| _ = copy x | ||
| let _ = copy x | ||
| consumeVal(copy x) | ||
| } |
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 we should mix copy x into more situations to make sure its got coverage, since that's what makes it different from the noncopyable types. For example, we could take this switch test and write a positive / corrected version with switch copy x which I don't think we've tried to ensure it's fine with it.
| func testTrivialConsumingConsumeAndUseReinit(_ x: consuming TrivialStruct) { | ||
| let _ = x | ||
| x = TrivialStruct() | ||
| borrowValBorrowing(x) | ||
| } |
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.
something I haven't seen yet is that we're still preventing implicit copies on the parameter binding even after you've reassigned it, whether it's a consuming or borrowing parameter. Also makes me wonder what happens when you do x = x... does it require you to write x = copy x ?
Also, a test that entures we still enforce no-implicit-copy after an explicit copy of the param.
rdar://108383660