The substituted witness type may depend on a tentative type witness
indirectly. In this case, we would incorrectly cache the result.
The outcome was that associated type inference would fail because
the first attempted witness would "lock in" a cached substituted
witness in some other specialized conformance.
Fix two inter-related issues with extension macros that provide
conformances to a protocol, the combined effect of which is that one
cannot meaningfully provide extension macros that implement
conformances to a protocol like Equatable or Hashable that also
supports auto-synthesis.
The first issue involves name lookup of operators provided by macro
expansions. The logic for performing qualified lookup in addition to
unqualified lookup (for operators) did not account for extension
macros in the same manner as it did for member macros, so we would not
find a macro-produced operator (such as operator==) in witness
matching.
The second issue is more fundamental, which is that the conformance
lookup table would create `NormalProtocolConformance` instances for
pre-macro-expansion conformance entries, even though these should
always have been superseded by explicit conformances within the macro
expansion buffers. The end result is that we could end up with two
`NormalProtocolConformance` records for the same conformance. Some
code was taught to ignore the pre-expansion placeholder conformances,
other code was not. Instead, we now refuse to create a
`NormalProtocolConformance` for the pre-expansion entries, and remove
all of the special-case checks for this, so we always using the
superseding explicit conformances produced by the macro expansions (or
error if the macros don't produce them).
Fixes rdar://113994346 / https://github.com/apple/swift/issues/66348
stated in the original source.
If an extension macro can introduce protocol conformances, macro expansion
will check which of those protocols already have a stated conformance in the
original source. The protocols that don't will be passed as arguments to
extension macro expansion, indicating to the macro that it should only add
conformances to those protocols.
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.
There are a lot of problems caused by our highly-abstract substitution
subsystem. Most of them would be solved by a more semantic / holistic
understanding of the active transformation, but that's difficult to do
because we just pass around function_refs. The first step in fixing
that is to pass around a better currency type. For now, it can just
hold the function_refs (and the SubstOptions).
I've set it up so that the places that just apply SubstitutionMaps
are constructing the IFS in a standard way; that should make it easy
to change those places in the future.
The _Copyable constraint was implemented as a marker protocol.
That protocol is part of the KnownProtocol's in the compiler.
When `ASTContext::getProtocol(KnownProtocolKind kind)` tries
to find the ProtocolDecl for Copyable, it will look in the
stdlib module (i.e., Swift module), which is where I initially
planned to put it.
That created problems initially when some regression tests
use `-parse-stdlib` failed to do that protocol lookup, which is
essential for adding the constraint (given the current implementation).
That led to believe we need to pull Copyable out of the stdlib, but that's
wrong. In fact, when building the Swift module itself, we do `-parse-stdlib`
but we also include `-module-name Swift`. This causes the _Copyable protocol
defined in the Stdlib to be correctly discovered while building the stdlib
itself (see the test case in this commit). So, the only downside of
having the Copyable protocol in the Stdlib is that `-parse-stdlib` tests
in the compiler can't use move-only types correctly, as they'll be
allowed in generic contexts. No real program would build like this.
Until I have time to do a further refactoring, this is an acceptable trade-off.
fixes rdar://104898230
enums with only cases that have no associated values
automatically get Equatable and Hashable synthesized.
That's not valid for move-only enums, so we were
just getting errors about broken conformances when
we hadn't specified any explicitly.
This PR just prevents the synthesis from the start
so we don't get any errors.
fixes rdar://104986597
Since values of generic type are currently assumed to always
support copying, we need to prevent move-only types from
being substituted for generic type parameters.
This approach leans on a `_Copyable` marker protocol to which
all generic type parameters implicitly must conform.
A few other changes in this initial implementation:
- Now every concrete type that can conform to Copyable will do so. This fixes issues with conforming to a protocol that requires Copyable.
- Narrowly ban writing a concrete type `[T]` when `T` is move-only.
It turns out they aren't always canonical by construction (and they don't
really need to be), so we should canonicalize the type and requirements
when we canonical a conformance ref. Fixes rdar://94877954.
This fixes an AST verifier failure where code that we otherwise
accept (because of loose Sendable checking) causes an assertion
because an invalid conformance shows up in the signature
conformances list of a valid (from the type checker's POV)
normal conformance.
Remove the allowUnavailable parameter to lookupConformance(), and instead
explicitly check the result for hasUnavailableConformance() in the places
where we used to pass 'false'.
Also, narrow down this check in those places to the Sendable protocol
only, fixing a regression with Hashable conformance synthesis.
Fixes rdar://problem/94460143.
When a synchronous, actor-isolated declaration witnesses an
asynchronous, not-similarly-isolated requirement, emit an actor hop
within the witness thunk to ensure that we properly enter the context
of the actor.
Fixes#58517 / rdar://92881539.
When a class has an unavailable conformance to a protocol, do not
inherit that unavailable conformance, because it can get in the way of
subclasses defining their own (properly-available) conformance.
Fixes rdar://89992569.
When determining whether a superclass conforms to a particular protocol,
skip unavailable conformances. This way, we don't minimize away a
constraint that might only apply to subclasses of the specified
superclass.
Fixes rdar://91853658.
This was benign with `Sendable`, but is not benign for the `Encodable`
and `Decodable` synthesis for distributed actors, which results in a
crash in TBD generation.
Fixes rdar://92008955.
This fixes a `static_assert` by converting it to an `assert`. The
address-of on a function is not a compile time constant and can only be
checked at runtime. This will reduce the check to !NDEBUG builds only
but actually performs the intended check.
The RequirementSignature generalizes the old ArrayRef<Requirement>
which stores the minimal requirements that a conforming type's
witnesses must satisfy, to also record the protocol typealiases
defined in the protocol.
When SILGenWitnessTable creates a decl ref for the witness of a derivative function requirement, it is using the requirement's derivative generic signature in the resulting witness decl ref. This is wrong because the witness may have a different derivative generic signature than the requirement, leading to a crash. This bug was never discovered because GSB's dark magic made it "just work", until requirement machine.
The fix is to store the matched witness derivative generic signature in `Witness` during type checking, and during witness table generation, use the witness' generic signature to create a witness decl ref.
Resolves rdar://84716758, rdar://84213107 and rdar://84987079.
Many, many, many types in the Swift compiler are intended to only be allocated in the ASTContext. We have previously implemented this by writing several `operator new` and `operator delete` implementations into these types. Factor those out into a new base class instead.
Rework Sendable checking to be completely based on "missing"
conformances, so that we can individually diagnose missing Sendable
conformances based on both the module in which the conformance check
happened as well as where the type was declared. The basic rules here
are to only diagnose if either the module where the non-Sendable type
was declared or the module where it was checked was compiled with a
mode that consistently diagnoses `Sendable`, either by virtue of
being Swift 6 or because `-warn-concurrency` was provided on the
command line. And have that diagnostic be an error in Swift 6 or
warning in Swift 5.x.
There is much tuning to be done here.
It's been quite a long time since this unused parameter was introduced.
The intent is to produce the module as a root for the search - that is,
computing the set of conformances visible from that module, not the set
of conformances inside of that module. Callers have since been providing
all manner of module-scoped contexts to it.
Let's just get rid of it. When we want to teach protocol conformance
lookup to do this, we can revert this commit as a starting point and try
again.