Commit Graph

785 Commits

Author SHA1 Message Date
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
Adrian Prantl
829491b230 Merge pull request #64551 from adrian-prantl/88274783
Rebase SILScope generation on top of ASTScope
2023-04-05 08:30:13 -07:00
Adrian Prantl
158772c2ab Rebase SILScope generation on top of ASTScope.
This patch replaces the stateful generation of SILScope information in
SILGenFunction with data derived from the ASTScope hierarchy, which should be
100% in sync with the scopes needed for local variables. The goal is to
eliminate the surprising effects that the stack of cleanup operations can have
on the current state of SILBuilder leading to a fully deterministic (in the
sense of: predictible by a human) association of SILDebugScopes with
SILInstructions. The patch also eliminates the need to many workarounds. There
are still some accomodations for several Sema transformation passes such as
ResultBuilders, which don't correctly update the source locations when moving
around nodes. If these were implemented as macros, this problem would disappear.

This necessary rewrite of the macro scope handling included in this patch also
adds proper support nested macro expansions.

This fixes

rdar://88274783

and either fixes or at least partially addresses the following:

rdar://89252827
rdar://105186946
rdar://105757810
rdar://105997826
rdar://105102288
2023-04-04 15:20:11 -07:00
John McCall
9c9671b349 Merge pull request #64887 from rjmccall/vanishing-tuple-silgen
SILGen and SIL type lowering support for vanishing tuples
2023-04-04 12:41:29 -04:00
John McCall
5942049c83 Set substitutions on storage abstraction patterns in l-value access.
Fixes a host of problems with stored type members with types dependent
on a type parameter pack; I ran into it specifically with vanishing
tuples.

Test to follow.
2023-04-03 23:09:36 -04:00
Joe Groff
8e21bfcc47 MoveOnlyAddressChecker: Confine analysis to current formal access.
Code can only locally interact with a mutable memory location within a
formal access, and is only responsible for maintaining its invariants
during that access, so the move-only address checker does not need to,
and should not, observe operations that occur outside of the access
marked with the `mark_must_check` instruction. And for immutable
memory locations, although there are no explicit formal accesses, that's
because every access must be read-only, so although individual
accesses are not delimited, they are all compatible as far as
move-only checking is concerned. So we can back out the changes to SILGen
to re-project a memory location from its origin on every access, a
change which breaks invariants assumed by other SIL passes.
2023-04-02 16:33:57 -07:00
Michael Gottesman
02a12d4142 [move-only] Make sure to treat ref_element_addr mutable address accesses similar to inout.
I also slightly changed the codegen around where we insert the mark_must_check.
Specifically, before we would emit the mark_must_check directly on the
ref_element_addr and then insert the access. This had the unfortunate effect
that we would hoist any destroy_addr that were actually needed out of the access
scope. Rather than do that, I now insert the mark_must_check on the access
itself. This results in the destroy_addr being within the scope (like the
mark_must_check itself).

rdar://105910066
2023-03-14 14:03:20 -07:00
Holly Borla
dce70f373f [SILGen] Emit MaterializePackExprs.
The subexpression of a MaterializePackExpr (which is always a tuple value
currently) is emitted while preparing to emit a pack expansion expr, and its
elements are projected from within the dynamic pack loop. This means that a
materialized pack is only evaluated once, rather than being evaluated on
every iteration over the pack elements.
2023-03-09 21:44:03 -08:00