Commit Graph

742 Commits

Author SHA1 Message Date
Joe Groff
1b5796ce90 SILGen: Treat projections from non-implicitly-copyable parameters as borrow bases. 2023-10-17 13:42:55 -07:00
Kavon Farvardin
f1142d5da4 [nfc] rename or eliminate isPureMoveOnly APIs
I think from SIL's perspective, it should only worry about whether the
type is move-only. That includes MoveOnlyWrapped SILTypes and regular
types that cannot be copied.

Most of the code querying `SILType::isPureMoveOnly` is in SILGen, where
it's very likely that the original AST type is sitting around already.
In such cases, I think it's fine to ask the AST type if it is
noncopyable. The clarity of only asking the ASTType if it's noncopyable
is beneficial, I think.
2023-09-20 15:23:17 -07:00
Michael Gottesman
37d60a08bb [move-only] Rename mark_must_check -> mark_unresolved_non_copyable_value.
I was originally hoping to reuse mark_must_check for multiple types of checkers.
In practice, this is not what happened... so giving it a name specifically to do
with non copyable types makes more sense and makes the code clearer.

Just a pure rename.
2023-08-30 22:29:30 -07:00
Michael Gottesman
543063ef0e [silgen] Make ManagedValue::forUnmanaged private and change users to use other more specific APIs.
I have been doing this over the past couple of days in preparation for changing
ManagedValue to specify the type of scope its cleanup is connected to.
2023-08-19 14:11:44 -07:00
Michael Gottesman
ff948f7309 [silgen] Convert even more cases of using trivial and values without ownership to use for*RValueWithoutOwnership APIs. 2023-08-15 11:04:01 -07:00
Nate Chandler
ded4d32c71 [OpaqueValues] Emit unowned copies.
In opaque values mode, emit the unowned copy instructions to convert as
follows:

strong_copy_unowned_value: `@owned $sil_unowned T` -> `@owned $T`
unowned_copy_value: `@owned T` -> `@owned $sil_unowned T`

Doing so is necessary in opaque values mode where it is needed to deal
with unowned values directly rather than indirectly via `load_unowned`s
and `store_unowned`s.
2023-08-08 15:49:17 -07:00
Nate Chandler
b616d14ff5 [OpaqueValues] Emit weak copies.
In opaque values mode, emit the new weak copy instructions to convert as
follows:

strong_copy_weak_value: `@owned $sil_weak T?` -> `@owned $T?`
weak_copy_value: `@owned $T?` -> `@owned $@sil_weak T?`

Doing so is necessary in opaque values mode where it is needed to deal
with weak values directly rather than indirectly via `load_weak`s and
`store_weak`s.
2023-08-08 15:47:13 -07:00
nate-chandler
0cfa74763f Merge pull request #67725 from nate-chandler/opaque-values/20230803/2/open-opaque-existential-value
[OpaqueValues] Open opaque existential value.
2023-08-08 06:57:00 -07:00
Slava Pestov
6ae2a1deee Merge pull request #67739 from slavapestov/var-decl-type-in-context
AST: Rename VarDecl::getType() to VarDecl::getTypeInContext()
2023-08-04 21:44:22 -04:00
Michael Gottesman
c9be4bda49 Merge pull request #67677 from gottesmm/borrowed-base-silgenlvalue
[move-only] Ensure that we properly nest accesses to base values if the base is noncopyable or the accessor result is noncopyable.
2023-08-04 12:26:19 -07:00
Slava Pestov
9ebb5f2e03 AST: Rename VarDecl::getType() to VarDecl::getTypeInContext()
This is a futile attempt to discourage future use of getType() by
giving it a "scary" name.

We want people to use getInterfaceType() like with the other decl kinds.
2023-08-04 14:19:25 -04:00
Nate Chandler
8c2ed17c9a [OpaqueValues] Open opaque existential value.
When a value's preferred existential representation is opaque, if the
value is not an address (which can only happen in opaque values mode),
emit open_existential_value rather than open_existential_addr.
2023-08-04 08:26:35 -07:00
Nate Chandler
4c6fc1ae8b [OpaqueValues] Skip keypath lvalue temporary.
When emitting key-path functions on behalf of a base that's an l-value,
copy the l-value into a temporary only when using lowered addresses.
2023-08-03 06:25:26 -07:00
Michael Gottesman
c3d2276241 [silgen] Eliminate two more cases around subscripts where we were not borrowing.
Also, the store_borrow work in the previous patch caused some additional issues
to crop up. I fixed them in this PR and added some tests in the process.
2023-08-02 11:09:31 -07:00
Nate Chandler
53522638fe [OpaqueValues] Skip temp when setting at key-path.
When setting a value at a key-path, in opaque values mode, don't create
a temporary and store the new value into it.  That is necessary when
using lowered addresses because intrinsic's signature is

```
sil @swift_setAtWritableKeyPath : $@convention(thin) <τ_0_0, τ_0_1> (@inout τ_0_0, @guaranteed WritableKeyPath<τ_0_0, τ_0_1>, @in τ_0_1) -> ()
```

but is incorrect in opaque values mode where values are passed directly
to `@in` parameters.
2023-08-01 17:16:51 -07:00
Michael Gottesman
26081ffb82 [silgen] Teach accessor projection to use store_borrow if it has a non-tuple.
This prevents another type of copy of noncopyable value error.

I also as a small change, changed the tuple version to use a formal access
temporary since we are projecting a component out implying that the lifetime of
the temporary must end within the formal access. Otherwise, we cause the
lifetime of the temporary to outlive the access. This can be seen in the change
to read_accessor.swift where we used to extend the lifetime of the destroy_addr
outside of the coroutine access we are performing.
2023-07-31 14:23:11 -07:00
Michael Gottesman
55892ef30d [silgen] Add a special visitor for accessing the base of noncopyable types.
We want these to be borrowed in most cases and to create an appropriate onion
wrapping. Since we are doing this in more cases now, we fix a bunch of cases
where we used to be forced to insert a copy since a coroutine or access would
end too early.
2023-07-27 10:00:28 -07:00
Pavel Yaskevich
c87daab11c [SILGen] InitAccessors: Don't use init accessor to initialize superclass properties
`super.init()` should fully initialize "super" which means that
such properties are mutated via a setter.
2023-07-18 17:19:42 -07:00
Pavel Yaskevich
1f87ee8ca3 [SILGen] InitAccessors: Extract emission of assign_or_init into a separate method
New method is going to be used to emit default value initializations
for user-defined constructors.
2023-07-18 17:19:42 -07:00
Pavel Yaskevich
5fd502b150 [SILGen] InitAccessors: Generalize AccessorComponent::emitValue
Instead of taking a setter type, let's switch over to a more general
`AccessorKind` which allows us to cover init accessors and simplify
`emitApplySetterToBase`.
2023-07-18 17:19:42 -07:00
Pavel Yaskevich
75ac13807e [SILGen] NFC: Extract application of setter to base into a method on SILGenFunction
This is a preliminary step towards enabling default initialization of
init accessor properties in user-defined initializers because this logic
would have to be shared by multiple places during SILGen.
2023-07-18 17:19:42 -07:00
Michael Gottesman
2abfa25bd4 Merge pull request #67354 from gottesmm/pr-45bdcac91308a0aa164064d4356f91a367ea00fa
[move-only] Fix lazily initialized global initializers.
2023-07-18 16:38:36 -07:00
Michael Gottesman
1f22f92170 [move-only] Fix lazily initialized global initializers.
Without this, we emit a copy of noncopyable type error since we do not insert a
mark_must_check on lazily initialized global initializers.

rdar://111402912
2023-07-17 19:17:43 -07:00
Joe Groff
c52ae08c7d SILGen: Don't reuse the Initialization across branches of an if or switch expression.
`Initialization` is stateful and not meant to be emitted into multiple times across different contexts.
If emitting into an initialization causes it to be split or aborted, that will carry over into
further uses of the initialization. This was happening during `if` and `switch` expression
emission, leading to miscompiles or compiler crashes. Fix this by saving only the buffer when
we prepare emission for a statement expression, and creating the initialization in the scope
where the expression for a branch actually gets emitted. Fixes rdar://112213253.
2023-07-14 14:21:57 -07:00
Pavel Yaskevich
135f2c2ea0 [SILGen] InitAccessors: Start supporting assign_or_init for properties without a setter
Implement "init accessor" component emission which is paired with
"init accessor" write strategy. Use `SILUndef` for a "setter" operand
of an "assign_or_init" instruction in cases when property with init
accessor doesn't have a setter. DI would detect re-initialization
attempts to produce diagnostics.
2023-07-03 22:07:19 -07:00
Pavel Yaskevich
511bd07574 [SILGen] InitAccessors: Split init accesssor handling into a separate component
The logic is going to be shared when we start supporting init accessor
properties without `set`.
2023-07-03 00:35:17 -07:00
Pavel Yaskevich
e49e4f985e [SILGen] NFC: Factor out logic from GetterSetterComponent to its base
Factor our following logic:

- Applying setter to its base value
- `newValue` emission

This would be useful for init accessor emission as well.
2023-06-30 11:48:08 -07:00
Pavel Yaskevich
fab9e4bc62 Merge pull request #66987 from xedin/refactor-init-accessors-to-carry-more-info
[SIL] InitAccessors: Refactor `assign_or_init` instruction to carry "self"
2023-06-30 11:46:01 -07:00
Pavel Yaskevich
80a1e2c2ba [SILGen] InitAccessors: Produce partial apply of init accessor ref to produce substituted closure
Instead of dealing with substitutions during raw SIL lowering,
let's produce a partial apply without argument to produce a
substituted reference that could be used by SILVerifier and
raw SIL lowering stages.
2023-06-28 12:28:15 -07:00
Pavel Yaskevich
3063e9d778 [SIL] InitAccessors: Reference "self" in assign_or_init instruction
First step on the path to remove dependence on "setter".
2023-06-27 09:45:05 -07:00
Evan Wilde
250082df25 [NFC] Reformat all the LLVMs
Reformatting everything now that we have `llvm` namespaces. I've
separated this from the main commit to help manage merge-conflicts and
for making it a bit easier to read the mega-patch.
2023-06-27 09:03:52 -07:00
Evan Wilde
f3ff561c6f [NFC] add llvm namespace to Optional and None
This is phase-1 of switching from llvm::Optional to std::optional in the
next rebranch. llvm::Optional was removed from upstream LLVM, so we need
to migrate off rather soon. On Darwin, std::optional, and llvm::Optional
have the same layout, so we don't need to be as concerned about ABI
beyond the name mangling. `llvm::Optional` is only returned from one
function in
```
getStandardTypeSubst(StringRef TypeName,
                     bool allowConcurrencyManglings);
```
It's the return value, so it should not impact the mangling of the
function, and the layout is the same as `std::optional`, so it should be
mostly okay. This function doesn't appear to have users, and the ABI was
already broken 2 years ago for concurrency and no one seemed to notice
so this should be "okay".

I'm doing the migration incrementally so that folks working on main can
cherry-pick back to the release/5.9 branch. Once 5.9 is done and locked
away, then we can go through and finish the replacement. Since `None`
and `Optional` show up in contexts where they are not `llvm::None` and
`llvm::Optional`, I'm preparing the work now by going through and
removing the namespace unwrapping and making the `llvm` namespace
explicit. This should make it fairly mechanical to go through and
replace llvm::Optional with std::optional, and llvm::None with
std::nullopt. It's also a change that can be brought onto the
release/5.9 with minimal impact. This should be an NFC change.
2023-06-27 09:03:52 -07:00
Joe Groff
ca7b8e2890 Merge pull request #66445 from jckarter/noncopyable-computed-property-address-only-base
SILGen: Don't copy a borrowed noncopyable address-only base of a computed property access.
2023-06-08 13:42:41 -07:00
Joe Groff
f06621907e SILGen: Don't copy a borrowed noncopyable address-only base of a computed property access.
We can probably avoid this copy in more circumstances, but make the change only for
noncopyable types for now, since that's the case where it's most semantically apparent.
rdar://109161396
2023-06-08 08:36:04 -07:00
Pavel Yaskevich
7b140f89b9 [SILGen] InitAccessors: AssignOrInit instruction should reference init accessor directly
Previously init accessor has been partially applied just like a setter but
that is no loger valid now that it operates on individual field references.
2023-06-06 18:59:13 -07:00
Pavel Yaskevich
5bac6e8538 [SILGen] NFC: Generalize isCurrentFunction{{ReadAccess, InitAccessor}} functions 2023-06-06 18:59:13 -07:00
Pavel Yaskevich
00a9ccfcc3 [SILGen] InitAccessors: Remap property references into argument references
A reference to an instance property in init accessor body
has to be remapped into an argument reference because all
of the properties from initialized/accesses lists are passed
to init accessors individually via arguments.
2023-06-06 18:59:13 -07:00
Holly Borla
7512f6e366 [SIL] Add an assignment mode to AssignOrInitInst that will be set by DI. 2023-06-06 18:59:13 -07:00
Holly Borla
eb3ed2b374 [SILGen] Emit AssignOrInitInst for assignment to a computed property with
an init accessor inside of an initializer.
2023-06-06 18:59:13 -07:00
Holly Borla
684ef9c482 [AST] Add a new accessor kind for init accessors. 2023-06-06 18:57:31 -07:00
Michael Gottesman
59c8cff917 [borrowing] Add support for borrowing/consuming copyable types to be a noimplicitcopy type.
rdar://108383660
2023-06-06 18:12:29 -04:00
Michael Gottesman
5d9ab63dbb [move-only] When we emit a noncopyable temporary allocation, always attach a mark_must_check [consumable_and_assignable].
Most of the time SILGen already emits these correctly without having extra
copies, but in certain situations SILGen will emit copies that we need the move
checker to eliminate (e.x.: when we generate a yield). An additional benefit is
that this also will catch places where the frontend makes a mistake.

This also removes a bunch of "copy of noncopyable" types error that showed up in
the implicit compiler generated modify.
2023-05-25 14:57:55 -07:00
Michael Gottesman
fd25cf379a Rename MoveExpr -> ConsumeExpr to reflect the final name.
NFC.
2023-05-17 22:42:42 -07:00
Michael Gottesman
e6f1691122 [copy-operator] Add support for the copy operator in preparation for making consuming and borrowing no implicit copy.
Some notes:

1. I implemented this as a contextual keyword that can only apply directly to
lvalues. This ensures that we can still call functions called copy, define
variables named copy, etc. I added tests for both the c++ and swift-syntax based
parsers to validate this. So there shouldn't be any source breaks.

2. I did a little bit of type checker work to ensure that we do not treat
copy_expr's result as an lvalue. Otherwise, one could call mutating functions on
it or assign to it, which we do not want since the result of copy_value is

3. As expected, by creating a specific expr, I was able to have much greater
control of the SILGen codegen and thus eliminate extraneous copies and other
weirdness than if we used a function and had to go through SILGenApply.

rdar://101862423
2023-05-17 22:42:42 -07:00
Michael Gottesman
e1f2a207bd Merge pull request #65604 from gottesmm/address-only-stuff
[move-only] Address Only Patches
2023-05-03 18:39:25 -07:00
Michael Gottesman
20958c90b5 [move-only] Add initial support for address only types.
Specifically, I changed emitRValueForDecl and SILGenProlog to do the right
thing. I also added some tests.

Some notes:

1. We currently consider using a copyable field of a move only address type to
be a consume of that type. I am going to fix that in the next commit to make it
easier to understand.

2. I am going to need to write more tests/flesh out the behavior more. I am sure
there is more here.

rdar://105106470
2023-05-02 16:30:24 -07:00
Andrew Trick
ea7b8055bc Rewrite some isPlusOne calls to isPlusOneOrTrivial.
Whenever we want to forward to a +1 value but don't need to destroy
the original memory, use isPlusOneOrTrivial.

This follows the existing naming scheme.

Fixes rdar://108001491 (SIL verification failed: Found mutating or
consuming use of an in_guaranteed parameter?!:
!ImmutableAddressUseVerifier().isMutatingOrConsuming(fArg))
2023-05-01 23:24:29 -07:00
Michael Gottesman
9a0b9665f1 [move-only] When emitting accesses to let boxes containing a noncopyable type, always emit mark_must_check.
The reason to do this is that:

1. Otherwise, we do not emit markers when someone attempts to consume the let.
We need the no_consume_or_assign to be there.
2. We need to insert assign_but_not_consuming so that DI can properly check lets
that are conditionally initialized and convert them to
initable_but_not_consuming.

I included a full definite_init SIL test that validates that we get the correct
codegen after DI in this case and emit the appropriate error as well.

rdar://108511534
2023-04-25 10:51:04 -07:00
Michael Gottesman
9252d5ea8b [move-only] Eliminate dead code that was not removed when re-projected move only types were removed. 2023-04-25 10:51:03 -07:00
Joe Groff
cb23187209 SILGen: Emit move-only bases for lvalues in a borrow scope.
Normally, if we project from a mutable class ivar or global variable, we'll
load a copy in a tight access scope and then project from the copy, in order to
minimize the potential for exclusivity violations while working with classes and
copyable values. However, this is undesirable when a value is move-only, since
copying is not allowed; borrowing the value in place is the expected and only possible
behavior. rdar://105794506
2023-04-19 14:50:34 -07:00