Moving the query implementation up to the AST library from SIL will allow
conveniences to be written on specific AST element classes. For instance, this
will allow `EnumDecl` to expose a convenience that enumerates element decls
that are available during lowering.
Also, improve naming and documentation for these queries.
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.
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.
When constructing r-values during keypath setter emission, consider
whether the argument's type is trivial and construct the relevant
r-value based on that. This worked before without opaque values because
the value is always an address.
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.
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.
We can't really treat them as always-initialized because that makes move checking
think that there's a value to destroy even on initialization, causing deinits to
run on uninitialized memory. Remove my previous hack, and use a `zeroInitializer`
to initialize the value state when emitting `init`, which is where we really need
the bootstrapping-into-initialized behavior. rdar://113057256
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.
Initializations for all of the fields accessed by init accessor
should be emitted before init accessor property even if they are
declared after it in the source order.
Resolves: rdar://112984795
It is necessary for opaque values where for casts that will newly start
out as checked_cast_brs and be lowered to checked_cast_addr_brs, since
the latter has the source formal type, IRGen relies on being able to
access it, and there's no way in general to obtain the source formal
type from the source lowered type.
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.
Translating more llvm::Optional::transform calls to swift::transform.
`llvm::Optional` had a transform function that ran a lambda on the
element stored in the optional if it existed. After migrating to
std::optional under the hood, that function went away. Replacing it with
calls to swift::optional in STLExtras.h.
This attribute can be attached to a noncopyable struct to specify that its
storage is raw, meaning the type definition is (with some limitations)
able to do as it pleases with the storage. This provides a basis for
implementing types for things like atomics, locks, and data structures
that use inline storage to store conditionally-initialized values.
The example in `test/Prototypes/UnfairLock.swift` demonstrates the use
of a raw layout type to wrap Darwin's `os_unfair_lock` APIs, allowing
a lock value to be stored inside of classes or other types without
needing a separate allocation, and using the borrow model to enforce
safe access to lock-guarded storage.
Originally, we were relying on capture info to determine if we needed to insert
this mark_must_check. This ignored that the way that we are handling
escaping/non-escaping is something that is approximated in the AST but actually
determined at SIL level. With that in mind, rather than relying on the capture
info here, just rely on us having an inout argument. The later SIL level
checking for inout escapes is able to handle mark_must_check and knows how to
turn off noncopyable errors in the closure where we detect the error to prevent
us from emitting further errors due to the mark_must_check here.
I discovered this while playing with the previous commit.
rdar://112555589
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`.