Performance optimization to help rule out generic overload choices sooner.
This is based on an observation of the constraint solver behavior,
consider following example:
```swift
func test<U: ExpressibleByStringLiteral>(_: U) {}
test(42)
```
Constraint System for call to `test` is going to look like this:
```
$T_test := ($T_U) -> $T_U
$T_U <conforms to> ExpressibleByStringLiteral
$T_42 <argument conversion> $T_U
$T_42 <literal conforms to> ExpressibleByIntegerLiteral
```
Currently to find out that `test` doesn't match, solver would have
to first find a binding for `$T_42`, then find a binding for `$T_U`
(through `<argument conversion>` constraint) and only later fail
while checking conformance of `Int` to `ExpressibleByStringLiteral`.
Instead of waiting for parameter to be bound, let's transfer conformance
requirements through a conversion constraint directly to an argument type,
since it has to conform to the same set of protocols as parameter to
be convertible (restrictions apply i.e. protocol composition types).
With that change it's possible to verify conformances early and reject
`test<U: ExpressibleByStringLiteral>` overload as soon as type of an
argument has been determined. This especially powerful for chained calls
because solver would only have to check as deep as first invald argument
binding.
Performance optimization.
If there is a concrete contextual type we could use, let's bind
it to the external type right away because internal type has to
be equal to that type anyway (through `BindParam` on external type
i.e. <internal> bind param <external> conv <concrete contextual>).
```swift
func test(_: ([String]) -> Void) {}
test { $0 == ["a", "b"] }
```
Without this optimization for almost all overloads of `==`
expect for one on `Equatable` and one on `Array` solver would
have to repeatedly try the same `[String]` type for `$0` and
fail, which does nothing expect hurts performance.
Resolves: rdar://19836070
Resolves: rdar://19357292
Resolves: rdar://75476311
Type inside of an editor placeholder is more of a hint than anything else,
so if it's incorrect let's diagnose that and use type variable instead to
allow solver to make forward progress.
Resolves: SR-14213
Resolves: rdar://74356736
- Prefer CGFloat -> Double over the other way around to avoid
ambiguities;
- Every new conversion impacts the score by factor of number of
previously applied conversions to make it possible to select
solutions that require the least such conversions.
- Prefer concrete overloads with Double <-> CGFloat conversion
over generic ones.
A lot of operators (and most likely regular functions a well) have
overloads that accept i.e. a generic parameter that conforms to
`StringProtocol`, so the best fix in situations when argument is
a raw representable type would be to check whether `.rawValue`
conforms to the expected protocol and use it if so.
Resolves rdar://problem/75367157
Since labels are considered part of the name, mismatches in labeling
should be invalidate overload choices. Let's prefer an overload with
correct labels but incorrect types over the one with incorrect labels.
This also means that it's possible to restore performance optimizations
related to early filtering in diagnostic mode, which is important for
deeply nested code i.e. SwiftUI views.
Is the same argument is out-of-order in multiple solutions, let's
diagnose it as if there was no ambiguity.
Resolves: SR-14093
Resolves: rdar://73600328
It's possible that different overload choices could have the same
conformance requirement, so diagnostics should be able to emit an
error in situations where multiple solutions point to the missing
conformance at the same location (both in AST and requirement list).
Resolves: rdar://74447308
Look through specifier (inout, l-value) and optional types while
checking for presence of dependent member types to avoid inferring
incorrect bindings (which could lead to infinite recursion in the
solver).
Resolves: SR-13856
Resolves: rdar://problem/71383770
It's possible that covariant result type is wrapped in l-value.
Just like currently preserved optionality, transformation should
maintain l-valueness of a result type as well.
Resolves: rdar://problem/71167129
If one of the statements in the result builder body fails to
apply solution, let's fail entire rewrite attempt, otherwise
type-checker would end up with AST that has null pointers for
some child nodes.
Resolves: rdar://problem/70256351
Instead of failing constraint generation upon encountering
an invalid declaration, let's turn that declaration into a
potential hole and keep going. Doing so enables the solver
to reach a solution and diagnose any other issue with
expression.
"Function builders" are being renamed to "result builders". Add the
corresponding `@resultBuilder` attribute, with `@_functionBuilder` as
an alias for it, Update test cases to use @resultBuilder.
Start visiting transitive fixed bindings for type
variables, and stop visiting adjacencies for
`gatherConstraint`'s `AllMentions` mode.
This improves performance and fixes a correctness
issue with the old implementation where we could
fail to re-activate a coercion constraint, and
then let invalid code get past Sema, causing
either miscompiles or crashes later down the
pipeline.
Unfortunately this change requires us to
temporarily drop the non-ephemeral fix for a couple
of fairly obscure cases where the overload hasn't
yet been resolved. The logic was previously relying
on stale adjacency state in order to re-activate
the fix when the overload is bound, but it's not
connected on the constraint graph. We need to find
a way to connect constraints to unresolved
overloads they depend on.
Resolves SR-12369.
Instead of always opening argument type represented by a collection
without type variables (to support subtyping when element is a labeled tuple),
let's try original type first and if that fails use a slower path with
indirection which attempts `array upcast`. Doing it this way helps to
propagate contextual information faster which fixes a performance regression.
Resolves: rdar://problem/54580247