We had an exploded form of conformance attributes (@unchecked,
@preconcurrency, @unsafe) at several different places in the compiler.
Pull these into a single structure so it's easier to manage and extend.
Should have done this a long time ago.
Check for unsafe conformances for type erasure and opaque type
erasure.
This also uncovered an issue where we were making every conformance of
an unsafe type to an unsafe protocol @unsafe implicitly, even though
that's not really what we want.
Protocol conformances have a handful attributes that can apply to them
directly, including @unchecked (for Sendable), @preconcurrency, and
@retroactive. Generalize this into an option set that we carry around,
so it's a bit easier to add them, as well as reworking the
serialization logic to deal with an arbitrary number of such options.
Use this generality to add support for @unsafe conformances, which are
needed when unsafe witnesses are used to conform to safe requirements.
Implement general support for @unsafe conformances, including
producing a single diagnostic per missing @unsafe that provides a
Fix-It and collects together all of the unsafe witnesses as notes.
Sendable conformances for source compatibility.
If conformance lookup always prefers the conformance from the defining module,
libraries introducing unavailable Sendable conformances can break source in
clients that declare retroactive Sendable conformances. Instead, still prefer
the available conformance, and always diagnose the client conformance as
redundant (as a warning). Then, when the retroactive conformance is removed,
the errors will surface, so the programmer has to take explicit action to
experience the source break.
defining module, and diagnose redundant Sendable conformances.
We still allow re-stating inherited unchecked Sendable conformances in
subclasses because inherited Sendable conformances are surprising when
they opt out of static checking. Otherwise, warning on redundant Sendable
conformances nudges programmers toward cleaning up unnecessary retroactive
Sendable conformances over time as libraries incrementally add the
conformances directly.
in favor of explicit available ones.
The type checker does not support the notion of multiple protocol
conformances; there can only be one conformance, and if that conformance
is unavailable, you cannot specify your own available conformance. This
is important for Sendable checking; if a framework specifies that a type
is explicitly not Sendable with an unavailable Sendable conformance,
clients cannot ignore Sendable violations involving that type. If a
superclass wants to allow subclasses to add a Sendable conformance, it
should not declare an unavailable Sendable conformance.
Although I don't plan to bring over new assertions wholesale
into the current qualification branch, it's entirely possible
that various minor changes in main will use the new assertions;
having this basic support in the release branch will simplify that.
(This is why I'm adding the includes as a separate pass from
rewriting the individual assertions)
When diagnosing a case where an actor-isolated witness cannot satisfy
a non-isolated requirement, also suggest that the conformance could be
annotated with `@preconcurrency`.
Add the machinery to support suppression of inference of conformance to
protocols that would otherwise be derived automatically.
This commit does not enable any conformances to be suppressed.
One of the request triggers added to `ConformanceLookupTable` in
https://github.com/apple/swift/pull/68384 can cause circular request
evaluation. Revert the request trigger since it doesn't appear to be necessary
for the test cases introduced in that PR.
Resolves rdar://115314044
Previously, conformances inherited through a base class could be missed in lazy
typechecking mode if types in the inheritance clause were not already resolved.
Provide member macros with similar information about conformances to
what extension macros receive, allowing member macros to document
which conformances they care about (e.g., Decodable) and then
receiving the list of conformances that aren't already available for
the type in question. For example, a macro such as
@attached(member, conformances: Decodable, Encodable, names:
named(init(from:), encode(to:)))
macro Codable() = ...
Expanded on a type that is not already Decodable/Encodable would be
provided with Decodable and Encodable (via the new
`missingConformancesTo:` argument to the macro implementation) when
the type itself does not conform to those types.
Member macros still cannot produce conformances, so this is likely to
be used in conjunction with extension macros most of the time. The
extension macro declares the conformance, and can also declare any
members that shouldn't be part of the primary type definition---such
as initializers that shouldn't suppress the memberwise initializer. On
the other hand, the member macro will need to define any members that
must be in the primary definition, such as required initializers,
members that must be overridable by subclasses, and stored properties.
Codable synthesis is an example that benefits from member macros with
conformances, because for classes it wants to introduce a required
initializer for decoding and an overridable encode operation, and
these must be members of the nominal type itself. Specifically, the
`Codable` macro above is likely to have two attached member roles:
@attached(member, conformances: Decodable, Encodable, names:
named(init(from:), encode(to:)))
@attached(extension, conformances: Decodable, Encodable, names:
named(init(from:), encode(to:)))
macro Codable() = ...
where the "extension" role is responsible for defining the conformance
(always), and the "member" creates the appropriate members for classes
(`init` vs. `required init`).
Tracked by rdar://112532829.
Wrap the `InheritedEntry` array available on both `ExtensionDecl` and
`TypeDecl` in a new `InheritedTypes` class. This class will provide shared
conveniences for working with inherited type clauses. NFC.
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.
The conformance lookup table is the central point of truth to
establish which protocols a nominal type conforms to. Ensure that we
expand conformance macros into that table.
Fixes rdar://106886651.
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 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.
A recent change to `Sendable` conformance handling resulted in subclasses of global-actor-confined classes being rejected if they explicitly declared a conformance to `Sendable`.
This behavior is technically correct because actor-isolated types are implicitly `Sendable`, but the source compatibility regression was not desirable. We are also considering requiring subclasses to explicitly repeat their superclass's `Sendable` conformance, so it makes sense to allow these redundant conformances in the general case to ease that potential transition.
Fixes rdar://88700507.