Just like we do with SILFunction, allow a code generation model to be
specified on a SILGlobalVariable and maintain that through the printed
and serialized forms.
Declarations that are potentially used externally, including those
exposed to foreign languages (e.g., via `@c`), placed in a specific
section (`@section`), or explicitly marked used (`@used`) are
generally eagerly emitted in IR. Embedded Swift was overriding this in
a partial manner, applying specific linkage rules to them to force
them to have unique definitions (regardless of the code generation
model) and then overriding the behavior later on when it came to lazy
emission.
Remove the special cases for Embedded. These declarations will now
follow the same linkage rules as all other declarations, greatly
simplifying the "is non-unique definition" check, and will be
considered as being emitted non-lazily.
The code generation model for a particular declaration or conformance
can be defined explicitly with `@export(interface)`,
`@export(implementation)`, or `@inlinable` (for declarations),
indicating where the definition will occur.
Embedded Swift also has some limitations on what can be emitted into
IR. For example, a generic function cannot be `@export(interface)`
because Embedded Swift does not support unspecialized generics.
Compute the effective code generation model based on what was
explicitly specified, the limitations of the model, and the default
code generation model for the given module, which defaults to
"inlinable" but can be made "implementation" by the DeferredCodeGen
feature. Use the effective code generation model for IR- and SIL-level
determinations of linkage and where to emit symbols.
[WIP] Start computing and using the "effective" code generation model
FIXUP linkage of the alias symbol
* `assert` -> `ASSERT` for checking if an instruction is deleted twice. This will let us catch an error also with non-assert compiler builds.
* add checks that a deleted instructions is not used and is not using other values
This will hopefully give us more information for some rare non-deterministic compiler crashes.
rdar://176816390
This function is used by passes and salvages to facilitate adding
instructions to reconstruction blocks, even if no block exists on the
debug value yet.
We would try to take the `metatype` of the integer value, which doesn't work. If
a specialized parameter is an integer generic parameter, emit a code sequence
that compares the integer value. Fixes rdar://176876134.
HiddenType is a new TypeBase subclass that carries a mangled name
without leaking the actual type definition. It serves as a type-slot
placeholder for stored-property types that have been elided from a
serialized binary module, so that the client side can either
(1) resolve this mangled name to the real type if the client has access to the owning module, or
(2) use the mangled name as a key to query abstract layout information also serialized in the binary module.
As an example — a library with a hidden field of a bridging-imported type:
```
// Utility.h (internal bridging header)
// typedef struct { int value; } Wrapper;
public struct S {
private var w: Wrapper
public var weight: Double
}
In the serialized module, the client's view reconstructs as:
public struct S {
private var w: @_hidden("$sSo7Wrappera")
public var weight: Double
}
```
For consistency within SIL, we want to keep the information that the value
associated with an alloc_stack needs to be dereferenced to have access to
the variables value.
This should simplify passes that might conditionally remove an op_deref:
for address types, there should always be an op_deref.
IRGen then internally strips the op_deref so that when a dbg_declare is
created, it will not have an additional op_deref.
This commit changes SIL but should not affect the LLVM IR of a program.
Getting the loop header information requires that all blocks have terminators.
This is not necessarily true when printing a function which is e.g. currently under construction.
This check is disabled by default, and enabled with
`-Xllvm -verify-debug-value-expr`, while we fix the remaining problems
that are creating wrongly typed debug info.
Assisted-by: Claude
Protocol conformances normally have shared linkage in Embedded Swift.
However, allow the use of @export(interface) on conformances (by way
of their enclosing nominal type or extension), which will emit the
witness tables for those conformances as strong symbols in the owning
module, and references to these symbols from other modules.
At the SIL level, ensure that witness tables always have shared linked
when building Embedded Swift. This is the correct starting point, to be
revised for @export(interface).
We used unowned calling convention for all trivial C++ types, as a
result the move checker never diagnosed when an unintentional copy is
happened through a call. This PR changes move only types to use @owned
calling convention, matching what we do for native Swift types.
Now, we can no longer get away with these copies! Unfortunately, the fix
for now is turned off for types with the "destroy" attribute because the
synthesized code is triggering some errors. This can be fixed as a
follow-up.
rdar://135615824
Local computed variable accessors should get their isolation from the
context unless otherwise specified. This is a narrow fix to address
some "uknown pattern" failures in region-based isolation. A proper
fix would be to set the isolation correctly during type-checking but
that is a major change due to how closures are currently type-checked.
Resolves: rdar://175548302
Such closures have a specialized direct conversion to actual `nonisolated(nonsending)`
type. They gain an implicit isolation parameter that isn't marked as "isolated"
and gets ignored in the prolog.
Address results from borrow accessors should be treated as endpoint uses
in the move-only checker. The result address has its own mark_unresolved_non_copyable_value
that gets checked separately.
When an ApplyInst produces a @guaranteed result, the result's lifetime
depends on the self parameter. DestroyAddrHoisting was incorrectly hoisting
destroy_addr above uses of the @guaranteed result, destroying self while
the borrowed value was still live.
In visitApplyOperand used by GatherUniqueStorageUses, check hasGuaranteedResult()
and record all uses of the @guaranteed result as storage users.
This prevents destroy_addr from being hoisted above any use of the
@guaranteed result.
Opaque return types are special type declarations that have it
own nested generic signature. Thus, given this:
```
protocol P<A> { associatedtype A: ~Copyable }
func f<T: ~Copyable>() -> some P<T> {}
```
The generic signature for f is <T where T Escapable>, and
for the opaque return type, its nested signature ends up as
```
<X where X: P, X.A == T>
```
With SE-503, we will now also expand a default for the suppressed
primary associated type, so the signature after expansion becomes
```
<X where X: P, X.A == T, X.A: Copyable>
```
It would be smarter to effectively have this rule
```
X.A == T, T: ~Copyable
----------------------
X.A: ~Copyable
```
where we infer the inverse on X.A to cancel-out the
expanded default X.A: Copyable. We already do this for
two in-scope type parameters, and it would be better if
we did it if one side was out-of-scope, but that would
be source-breaking to do in general.
In the case of opaque return types, the fact that
it has a nested generic signature seems more an
artifact of the implementation. There also is little
risk of source break, as the only kinds of same-type
requirements that can appear are from parameterized
protocol type.
The experimental suppressed associated types prior to
SE-503 wouldn't be broken by this change, as they do
not infer defaults that need suppression, and we only
filter-out requirements from defaults expansion, rather
than explicitly-written ones.
rdar://175500824
There's a need for more control over how default requirements
for conformance to Copyable/Escapable are expanded, and
subsequently how inverses are applied or inferred to cancel-out
those defaults.
The pattern of `/*applyInverses*/BOOL` is insufficient, so this
is a refactoring to grow that into a proper type that carries
an option that can be used in some future scenario about inferring
inverses for opaque return types.