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)
If both sides of an `OptionalObject` constraint are un-inferred, their
binding sets need to correctly reflect adjacency - a type variable
that represents optional would get "object" as an adjacency through
its potential binding (the binding is - "object" wrapped in a single
level of optional) and "object" type variable needs to get its parent
optional type variable added to its adjacency list explicitly.
Without this it would be possible to prematurely pick "object" before
its parent optional type variable.
Resolves: https://github.com/apple/swift/issues/73207
Resolves: rdar://126960579
Inference cannot be allowed in cases where both sides are type
variables and optional type is l-value capable because it results
in binding "optional" to an optional type and later discovering
a contextual type that is l-value optional i.e. if "optional type"
is resolved by selecting subscript overload.
Always marking generic parameter type variables as incomplete
is too aggressive. That was the way to make sure that they
are never attempted to eagerly, but really there are only a
couple of situations where that can cause issues:
```
1. Int <: $T_param
$T1 <: $T_param
2. $T2 conv Generic<$T_param>
$T2 conv Generic<Int?>
Int <: $T_param
```
Attempting $T_param before $T1 in 1. could result in a missed
optional type binding for example.
Attempting $T_param too early in this case (before $T2) could
miss some transitive bindings inferred through conversion
of `Generic` type.
If a type variable that represents a generic parameter is no longer
associated with any type variables (directly or indirectly) it's safe
to assume that its binding set is complete.
There's no good reason to permit them. Conformances like Copyable and
Sendable are pervasive, so it's as though we are permitting extensions
of `Any`. Until there's a good argument in favor of such extensions,
remove the capability now.
- Drop `mayHaveSuperclass` because it's too restrictive.
- Add logic to get superclass of existential and re-create
existential type with all of the protocol requirements.
If the underlying key path is not Sendable, the compiler generated
closure that captures the key path expression (as `{ [$kp$ = ...] in $0[keyPath: $kp$] }`)
cannot be marked as Sendable either.
Binding inference through a contextual root variable should include
marking contextual root and all of its adjacent variables as adjacent
to a key path root variable as well otherwise transitively inferred
bindings are ranked incorrectly.
Since generic arguments have to match exactly the inference could
be extended to transfer bindings through contextual root types if
they are sufficiently resolved (not delayed).
For example if key path expression is passed as an argument to
a parameter like `WritableKeyPath<$Root, $Value>` and `$Root`
is not yet bound but has a binding set of `{String}` its bindings
are transferable over to resolve the key path which would be
ultimately bound to the contextual type.
Follow-up to https://github.com/apple/swift/pull/70148
Just like with arrays it's advantageous to favor dictionary
literals over disjunctions to bind the elements together and
enable inference across elements and, as a consequence,
type pruning.
Resolves: rdar://119040159
If key path capability is not yet determined it cannot be favored
over a conjunction because:
1. There could be no other bindings and that would mean that
key path would be selected even though it's not yet ready.
2. A conjunction could be the source of type context for the key path.
Resolves: rdar://119055010
If array literal type is not delayed and doesn't have any type variables
associated with it, let's prefer it over a disjunction to facilitate
type propagation through its `Element` type to element expressions.
Resolves: rdar://118993030
If key path type has bindings and is no longer delayed it means
that it's fully resolved and ready to be bound (even though value
type might not be resolved yet).
When `InferSendableFromCaptures` feature is enabled `inferKeyPathLiteralCapability`
should examine subscript arguments to determine whether the key path type is
sendable or not, and if so, inform inference to produce `& Sendable` existential
type as a binding. Binding key path type is delayed until all subscript arguments
are fully resolved.
This parameter doesn't allow direct holes because it always replies
on the contextual type (if it's not present the hole should be
propagated to it), so if we know that the argument is some invalid
existential value (one without a superclass) let's allow binding to
it only in diagnostic mode which would be detected and diagnosed as
a contextual mismatch.
Capability couldn't be determined for expressions like that which
means that inference should be delayed until root becomes available.
Resolves: https://github.com/apple/swift/issues/69936
If key path literal type is converted to a function type, it's
always the best course of action to use such a binding and forego
adding a KeyPath type binding based on capability because it
would never match.
This applies to invalid key pathes as well because we'd want to
propagate as much contextual information from the key path literal
into the context as possible.
Since key path root is now transitively inferred. Key path type
inference can be delayed until key path is resolved enough to
infer its capability.
This solves multiple problems:
- Inference fully controls what key path type is bound to;
- KeyPath constraint simplification doesn't have to double-check
the capability and attempt to re-bind key path type;
- Custom logic to resolve key path type is no longer necessary;
- Diagnostics are improved because capability and root/value type
mismatch are diagnosed when key path is matched against the
contextual type.
As a first step in delaying key path type until all of the members are
resolved, attempt to infer a type of root based on bindings associated
with key path type.
This flag makes it easier to determine what binding to produce
from the default. In cases where some of the member references
are invalid it's better to produce a placeholder for a key
path type instead of letting the solver to attempt to fix more
contextual problems for a broken key path.
This is a very first step in attempt to move some of the logic
from `simplifyKeyPathConstraint` to the inference. This type is
going to be used as an anchor to trigger capability inference.
Inference cannot be allowed in cases where both sides are type
variables and optional type is l-value capable because it results
in binding "optional" to an optional type and later discovering
a contextual type that is l-value optional i.e. if "optional type"
is resolved by selecting subscript overload.