* [IRGen] Pass component generic sig when emitting key path component for external property
rdar://101179225
When no generic environment was present, we passed nullptr, which is not correct when the property uses an external associated type, causing crashes in IRGen. In those cases, we have to pass the component generic sig instead.
* Fix test
A "generic" case is any case whose payload type depends
on generic type parameters for the enum or any enclosing type.
Some examples:
```
struct S<T> {
enum E {
case a // Non-generic case
case b(Int) // Non-generic case
case c(T) // Generic case
case d([U]) // Generic case
case e([Int]) // Non-generic case
}
}
```
This is important for correctly distinguishing MPE versus
SPE layouts. A case is considered "empty" only if it
is either a non-payload case (`case a`) or if the payload
is zero-sized and non-generic. Generic cases are always
treated as non-zero-sized for purposes of determining
the layout strategy.
Correctly testing this is tricky, since some of the
layout strategies differ only in whether they export
extra tag values as XIs. The easiest way to verify is
to check whether wrapping the result in an `Optional<>`
adds another byte to the overall size.
This exercises a number of cases that the previous logic got
wrong, including cases where MPEs are laid out like SPEs,
and cases where we use the SPE or MPE layout strategies for enums
that have no non-empty payloads. (These cases are superficially
similar but differ in how they handle XIs.)
These new tests allowed me to correct a number logical flaws
about how layouts are selected. In particular, cases with
generic payloads are always considered to be non-empty for
purposes of selecting a layout strategy. Only cases that
are statically known to be empty are considered empty for
layout purposes.
When computing linkage, the compiler would treat unavailable declarations as if
they were "always available" when they lack an `introduced:` version:
```
// Library
@available(macOS, unavailable)
public func foo() {
// …
}
// Client
import Library
@available(macOS, unavailable)
func bar() {
// Even though foo() and bar() are unavalable on macOS the compiler still
// strongly links foo().
foo()
}
```
This created an unnecessary dependency between libraries and their clients and
also can interfere with back deployment, since unavailable declarations may not
be present in a library on all OS versions. Developers could work around these
issues by conditionally compiling the code that references an unavailable
declaration, but they shouldn't have to given that unavailable code is meant to
be provably unreachable at runtime. Additionally, it could improve library code
size if we allowed the compiler to strip unavailable declarations from a binary
completely.
Resolves rdar://106673713
The `@MainActor` global actor constraint on a declaration does not carry an
inherent ABI impact and therefore use of this constraint should not be limited
to OS versions where Swift concurrency is available.
Resolves rdar://105610970
It shares many of the same values as OpenBSD (which both inherited from 4.4BSD),
and we wouldn't expect those to diverge due to the respective platforms'
bincompat goals.
Previously, when creating availability attributes for synthesized declarations
we would identify some set of reference declarations that the synthesized
declaration should be as-available-as. The availability attributes of the
reference declarations would then be merged together to create the attributes
for the synthesized declaration. The problem with this approach is that the
reference declarations themselves may implicitly inherit availability from their
enclosing scopes, so the resulting merged attributes could be incomplete. The
fix is to walk though the enclosing scopes of the reference declarations,
merging the availability attributes found at each level.
Additionally, the merging algorithm that produces inferred availability
attributes failed to deal with conflicts between platform specific and platform
agnostic availability. Now the merging algorithm notices when platform agnostic
availability should take precedence and avoids generating conflicting platform
specific attributes.
Resolves rdar://106575142
For very large control flow graphs the markControllingTerminatorsLive can stack overflow.
Fix this by doing the work iteratively instead of recursively.
rdar://106198943
Current logic attempts simplification of the base type only if it's
a type variable or a dependent member type. That's valid for correct
code but not for invalid code e.g. `(($T) -> Void).Element` is not
going to be simplified even if `$T` is bound, which causes crashes
in diagnostic mode because `matchTypes` is going to re-introduce
constraint with partially resolved dependent member types and by
doing so make it stale forever which trips constraint system state
verification logic.
Resolves: rdar://105149979
The `isEscaping` function is called a lot from ARCSequenceOpt and ReleaseHoisting.
To avoid quadratic complexity for large functions, limit the amount of work what the EscapeUtils are allowed to to.
This keeps the complexity linear.
The arbitrary limit is good enough for almost all functions.
It lets the EscapeUtils do several hundred up/down walks which is much more than needed in most cases.
Fixes a compiler hang
https://github.com/apple/swift/issues/63846
rdar://105795976