The new type, called ExistentialType, is not yet used in type resolution.
Later, existential types written with `any` will resolve to this type, and
bare protocol names will resolve to this type depending on context.
The functions in llvm-project `AttributeList` have been
renamed/refactored to help remove uses of `AttributeList::*Index`.
Update to use these new functions where possible. There's one use of
`AttrIndex` remaining as `replaceAttributeTypeAtIndex` still takes the
index and there is no `param` equivalent. We could add one locally, but
presumably that will be added eventually.
One of the places where we ask whether a type's metadata should
be obtained via its mangled name was missing the newer, more
robust checking for minimum deployment target.
When back-deploying, create global-actor-qualified function types via a
separate entrypoint
(`swift_getFunctionTypeMetadataGlobalActorBackDeploy`) in the
compatibility library, which checks whether it is running with a
new-enough runtime to use `swift_getFunctionTypeMetadataGlobalActor`.
Failing that, it calls into a separate copy of the implementation that
exists only in the back-deployed concurrency library.
Fixes rdar://79153988.
Classes using the type-erased Objective-C generics model are represented in parts of IRGen as UnboundGenericTypes, which is a problem because a number of code paths expect all generic types to be bound. Update some of these that are involved in extensions on ObjC generic types.
Isolated parameters are part of function types. Encode them in function
type manglings and metadata, and ensure that they round-trip through
the various mangling and metadata facilities. This nails down the ABI
for isolated parameters.
* Move differentiability kinds from target function type metadata to trailing objects so that we don't exhaust all remaining bits of function type metadata.
* Differentiability kind is now stored in a tail-allocated word when function type flags say it's differentiable, located immediately after the normal function type metadata's contents (with proper alignment in between).
* Add new runtime function `swift_getFunctionTypeMetadataDifferentiable` which handles differentiable function types.
* Fix mangling of different differentiability kinds in function types. Mangle it like `ConcurrentFunctionType` so that we can drop special cases for escaping functions.
```
function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
...
differentiable ::= 'jf' // @differentiable(_forward) on function type
differentiable ::= 'jr' // @differentiable(reverse) on function type
differentiable ::= 'jd' // @differentiable on function type
differentiable ::= 'jl' // @differentiable(_linear) on function type
```
Resolves rdar://75240064.
While it is very convenient to default the ExtInfo state when creating
new function types, it also make the intent unclear to those looking to
extend ExtInfo state. For example, did a given call site intend to have
the default ExtInfo state or does it just happen to work? This matters a
lot because function types are regularly unpacked and rebuilt and it's
really easy to accidentally drop ExtInfo state.
By changing the ExtInfo state to an optional, we can track when it is
actually needed.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.
ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.
_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.
Resolves rdar://69980056.
Since these types have an implicit stored property, this requires
adding an abstraction over fields to IRGen, at least throughout
the class code. In some ways I think this significantly improves
the code, especially in how we approach missing members.
Fixes rdar://72202671.
When emitting the metadata accessor for a generic type for which
canonical prespecialized metadata records have been formed, rather than
calling getGenericMetadata, instead call
getCanonicalPrespecializedGenericMetadata and pass to it the once token
which will guard that the canonical prespecialized metadata records
attached to the nominal type descriptor are only added to the metadata
cache once.
Previously, the metadata accessor for which canonical prespecializations
had been formed included checks against the passed-in arguments to
determine whether the access matched a prespecialized record or not.
Now that the prespecialized records are attached to the nominal type
descriptor for the type, eliminate this hard-coded generated code and
instead let swift_getGenericMetadata do the work of looking through the
prespecializations.
Previously, noncanonical records were only allowed if one of the
arguments was from the module where the record was to be emitted.
Here, that restriction is lifted. Now getSpecializedGenericMetadata
will, on first run, register all canonical metadata with the global
cache before attempting to bless the passed-in noncanonical record,
allowing noncanonical records to be for the same arguments as a
canonical record (since in the case that a canonical record does exist,
it will be returned).
The metadata accessor and type context descriptor for a nominal type
both depend on canonical metadata--the former because it returns those
metadata, the latter because it has them as trailing objects.
Here, the work is done to reemit those values when new canonical
prespecialized metadata are encountered.
several more places to use getOrCreateHelperFunction.
This means that several of these places are now emitting
shared functions rather than private ones, which I've
verified is okay. There are some other places where
privacy is still unfortunately necessary.
I've also fixed the name of the store-extra-inhabitants
helper function to say "store" instead of "get", which
is longstanding (but harmless because it's private).
Fixes rdar://66707994.
Add `async` to the type system. `async` can be written as part of a
function type or function declaration, following the parameter list, e.g.,
func doSomeWork() async { ... }
`async` functions are distinct from non-`async` functions and there
are no conversions amongst them. At present, `async` functions do not
*do* anything, but this commit fully supports them as a distinct kind
of function throughout:
* Parsing of `async`
* AST representation of `async` in declarations and types
* Syntactic type representation of `async`
* (De-/re-)mangling of function types involving 'async'
* Runtime type representation and reconstruction of function types
involving `async`.
* Dynamic casting restrictions for `async` function types
* (De-)serialization of `async` function types
* Disabling overriding, witness matching, and conversions with
differing `async`
When a generic type from a different module is not resilient within the
current module and at least one of its arguments is from the current
module, emit a non-canonical prespecialized record, and access that
metadata via a call to swift_getCanonicalSpecializedMetadata, passing in
the non-canonical record.
rdar://problem/56996727
rdar://problem/56997022
Two protocol conformance descriptors are passed to
swift_compareProtocolConformanceDecriptors from generic metadata
accessors when there is a canonical prespecialization and one of the
generic arguments has a protocol requirement.
Previously, the descriptors were incorrectly being passed without
ptrauth processing: one from the witness table in the arguments that are
passed in to the accessor and one known statically.
Here, the descriptor in the witness table is authed using the
ProtocolConformanceDescriptor schema. Then, both descriptors are signed
using the ProtocolConformanceDescriptorsAsArguments schema. Finally, in
the runtime function, the descriptors are authed.
Previously, the metadata accessor for a generic type for which some
metadata prespecialization was done only tested that the type metadata
arguments were equal to those of the prespecialization. If the generic
type had an argument which was constrained to conform to a protocol, the
particular conformance to that protocol was determined at compile time,
but the conformance was ignored in the metadata accessor. As a result
it was possible--in certain multi-module cases--for the metadata
accessor to incorrectly return a prespecialized metadata record whose
type arguments matched the type arguments passed to the accessor but
whose conformance arguments did not.
For example, given the following,
Base:
struct K {}
protocol P {}
Conformance1:
import Base
struct G<T : P> {}
extension K : P {} // first conformance
prespecialize( G<K>.self )
Conformance2:
import Base
extension K : P {} // second conformance
the metadata accessor for G defined in Conformance1 would behave like
MetadataResponse `metadata accessor for G`(
MetadataRequest request,
const Metadata *M,
const WitnessTable *WT) {
if (M == `type metadata for K`) {
return `canonical prespecialized type metadata for G<K>`
}
return swift_getGenericMetadata(request, {M, WT});
}
Here, the WitnessTable argument is the witness table describing a
conformance of the type whose metadata is provided to the protocol P.
The incorrect behavior occurs when calling the metadata accessor with
these arguments:
`some request`
`type metadata for K`
`protocol witness table for Base.K : Base.P in Conformance2`
The accessor would return the `canonical prespecialized type metadata
for G<K>`. The problem is that the prespecialized metadata contains the
following generic arguments:
`type metadata for K`
`protocol witness table for Base.K : Base.P in Conformance1`
Specificallly, the witness table is for the conformance from
Conformance1, not the conformance from Conformance2.
Here, the problem is addressed by testing that the witness tables passed
into the accessor are for the same conformance as the witness table
referred to by the prespecialized record. Now, the metadata accessor
for G will behave like
MetadataResponse `metadata accessor for G`(
MetadataRequest request,
const Metadata *M,
const WitnessTable *WT) {
if (M == `type metadata for K`
swift_compareProtocolConformanceDescriptors(
WT->getDescription(),
`protocol conformance descriptor for Base.K : Base.P in Conformance1`)
) {
return `canonical prespecialized type metadata for G<K>`
}
return swift_getGenericMetadata(request, {M, WT});
}
Consequently, when the accessor is called with the same arguments as
before, the call to swift_compareProtocolConformanceDescriptors will
return false and the non-matching prespecialized metadata will not be
returned.