Since key path type is always bound by inference before the
constraint could be simplified, there is no need to search
for a contextual type or try to bind key path type if there
are errors in the path.
When providing a key-path literal for a parameter of function type
where that function type has a generic parameter for its thrown error
type, infer `Never` for the generic argument because key paths don't
throw.
Thanks to @xedin for realizing that this would be an issue.
This type will become the corresponding type that is resolved for an
`InverseTypeRepr`. This kind of type is not expected to appear past type
checking (currently, not even past requirement lowering!).
When comparing a requirement that uses typed throws and uses an
associated type for the thrown error type against a potential witness,
infer the associated type from the thrown error of the
witness---whether explicitly specified, untyped throws (`any Error`),
or non-throwing (`Never`).
Lift the subtyping check for thrown error types out of the constraint
solver, so we can re-use it elsewhere.
There is a minor diagnostic change, from one that is actively
misleading (it shows a legitimate conversion that's wrong) to one that
is correct, which comes from us not treating "dropping throws" as a
legitimate way to handle equality of function types.
If key path is connected to a disjunction directly or indirectly
(i.e. via ApplicableFunction constraint) do not attempt to bind
it until disjunction is taken, otherwise there is a risk to miss
a valid keypath-to-function conversion.
If there is something wrong with the context, let's assign a default
KeyPath type to the key path literal to avoid propagating placeholder
into the key path inference.
For methods there are two possibilities - force unwrap and
conditional, that's why we need a disjunction with two choices.
This is not the case for key path root type it could only
be force unwrapped.
`tryMatchRootAndValueFromType` anchored both root and value match
constraints directly on the key path expression. That is incorrect
because we have special locators for that.
If key path literal is passed as an argument to a function/subscript
application its type cannot be resolved until the overload for the
call is selected, otherwise it could prevent a valid keypath-to-function
conversion in cases were argument ends up being a function type.
Teach the constraint solver about the subtyping rule that permits
converting one function type to another when the effective thrown error
type of one is a subtype of the effective thrown error type of the
other, using `any Error` for untyped throws and `Never` for
non-throwing.
With minor other fixes, this allows us to use typed throws for generic
functions that carry a typed error from their arguments through to
themselves, which is in effect a typed `rethrows`:
```swift
func mapArray<T, U, E: Error>(_ array: [T], body: (T) throws(E) -> U)
throws(E) -> [U] {
var resultArray: [U] = .init()
for value in array {
resultArray.append(try body(value))
}
return resultArray
}
```
Instead of trying to get string representation of the type itself,
let's just get it based on the type name, which works well with the
list of types we have.
Resolves: rdar://113675093
I think from SIL's perspective, it should only worry about whether the
type is move-only. That includes MoveOnlyWrapped SILTypes and regular
types that cannot be copied.
Most of the code querying `SILType::isPureMoveOnly` is in SILGen, where
it's very likely that the original AST type is sitting around already.
In such cases, I think it's fine to ask the AST type if it is
noncopyable. The clarity of only asking the ASTType if it's noncopyable
is beneficial, I think.
`lookupConformance` request is not cached and constraint solver
performs a lot of them for the same type (i.e. during disjunction
solving), let's try to cache previously performed requests to
see whether additional memory use is worth the performance benefit.
getClosureActorIsolation.
This is preparation for changing AbstractClosureExpr to store
ActorIsolation instead of ClosureActorIsolation, and convert to
ClosureActorIsolation when needed to allow incrementally updating
callers. This change is NFC.
These allow multi-statement `if`/`switch` expression
branches that can produce a value at the end by
saying `then <expr>`. This is gated behind
`-enable-experimental-feature ThenStatements`
pending evolution discussion.
Checking type variables is no longer necessary because constraint
system now stores types of all closures it encountered, this makes
detection logic more reliable as well.
Resolves: rdar://112426330
The fix used incorrect locators for attempted argument conversions,
didn't check whether arguments are already re-ordered and allowed
fixes as visible side-effects from checking.
Resolves: rdar://114341979
A type variable that represents a key path literal cannot be bound
directly to `AnyKeyPath` or `PartialKeyPath`, such types could only
be used for conversions.
It used to be the task of the binding inference to infer `AnyKeyPath`
and `PartiaKeyPath` as a `KeyPath` using previously generated type
variables for a root and value associated with key path literal
(previously stored in the locator).
Recently we switched over to storing key path information in the
constraint system and introduced `resolveKeyPath` method to gain
more control over how key path type variable gets assigned.
Getting information from the constraint system creates a problem
for the inference because "undo" for some bindings would be run
after solver scope has been erased, so instead of modifying bindings
in `inferFromRelational`, let's do that in `resolveKeyPath` right
before the key path type variable gets bound which seems to be a
better place for that logic anyway.
Resolves: rdar://113760727
If type variable we are about to bind represents a pack
expansion type, allow the binding to happen regardless of
what the \c type is, because contextual type is just a hint
in this situation and type variable would be bound to its
opened type instead.
Resolves: rdar://112617922