Following on from updating regular member completion, this hooks up unresolved
member completion (i.e. .<complete here>) to the typeCheckForCodeCompletion API
to generate completions from all solutions the constraint solver produces (even
those requiring fixes), rather than relying on a single solution being applied
to the AST (if any). This lets us produce unresolved member completions even
when the contextual type is ambiguous or involves errors.
Whenever typeCheckExpression is called on an expression containing a code
completion expression and a CompletionCallback has been set, each solution
formed is passed to the callback so the type of the completion expression can
be extracted and used to lookup up the members to return.
Allow an 'async' function to overload a non-'async' one, e.g.,
func performOperation(_: String) throws -> String { ... }
func performOperation(_: String) async throws -> String { ... }
Extend the scoring system in the type checker to penalize cases where
code in an asynchronous context (e.g., an `async` function or closure)
references an asychronous declaration or vice-versa, so that
asynchronous code prefers the 'async' functions and synchronous code
prefers the non-'async' functions. This allows the above overloading
to be a legitimate approach to introducing asynchronous functionality
to existing (blocking) APIs and letting code migrate over.
This approach, suggested by Xiaodi Wu, provides better source
compatibility for existing Swift code, by breaking ties in favor of the
existing Swift semantics. Each time the backward-scan rule is needed
(and differs from the forward-scan result), we will produce a warning
+ Fix-It to prepare for Swift 6 where the backward rule can be
removed.
To better preserve source compatibility, teach the constraint
solver to try both the new forward scanning rule as well as the
backward scanning rule when matching a single, unlabeled trailing
closure. In the extreme case, where the unlabeled trailing closure
matches different parameters with the different rules, and yet both
produce a potential match, introduce a disjunction to explore both
possibilities.
Prefer solutions that involve forward scans to those that involve
backward scans, so we only use the backward scan as a fallback.
All callers can trivially be refactored to use ModuleDecl::lookupConformance()
instead. Since this was the last flag in ConformanceCheckOptions, we can remove
that, too.
A request is intended to be a pure function of its inputs. That function could, in theory, fail. In practice, there were basically no requests taking advantage of this ability - the few that were using it to explicitly detect cycles can just return reasonable defaults instead of forwarding the error on up the stack.
This is because cycles are checked by *the Evaluator*, and are unwound by the Evaluator.
Therefore, restore the idea that the evaluate functions are themselves pure, but keep the idea that *evaluation* of those requests may fail. This model enables the best of both worlds: we not only keep the evaluator flexible enough to handle future use cases like cancellation and diagnostic invalidation, but also request-based dependencies using the values computed at the evaluation points. These aforementioned use cases would use the llvm::Expected interface and the regular evaluation-point interface respectively.
Introduce `SK_Hole` which is used to count a number of "holes" in
a given solution. It is used to distinguish solutions with fewer holes.
Also it makes it possible to check whether a solution has holes but
no fixes, which is an issue and such solution shouldn't be applied
to AST.
If constraint system is underconstrained e.g. because there are
editor placeholders, it's possible to end up with multiple solutions
where each ambiguous declaration is going to have its own overload kind:
```swift
func foo(_: Int) -> [Int] { ... }
func foo(_: Double) -> (result: String, count: Int) { ... }
_ = foo(<#arg#>).count
```
In this case solver would produce 2 solutions: one where `count`
is a property reference on `[Int]` and another one is tuple access
for a `count:` element.
Resolves: rdar://problem/49712598
Single type of keypath dynamic member lookup could refer to different
member overlaods, we have to do a pair-wise comparison in such cases
otherwise ranking would miss some viable information e.g.
`_ = arr[0..<3]` could refer to subscript through writable or read-only
key path and each of them could also pick overload which returns `Slice<T>`
or `ArraySlice<T>` (assuming that `arr` is something like `Box<[Int]>`).
Instead of trying to hold a "global" set of type variable differences
let's use pair-wise comparison instead because in presence of generic
overloads such would be more precise.
If there are N solutions for a single generic overload we currently
relied on "local" comparison to detect the difference, but it's not
always possible to split the system to do one. Which means higher
level comparisons have to account for "local" (per overload choice)
differences as well otherwise ranking would loose precision.
Motivation: `GenericSignatureImpl::getCanonicalSignature` crashes for
`GenericSignature` with underlying `nullptr`. This led to verbose workarounds
when computing `CanGenericSignature` from `GenericSignature`.
Solution: `GenericSignature::getCanonicalSignature` is a wrapper around
`GenericSignatureImpl::getCanonicalSignature` that returns the canonical
signature, or `nullptr` if the underlying pointer is `nullptr`.
Rewrite all verbose workarounds using `GenericSignature::getCanonicalSignature`.
This commit changes the behaviour of the error for
passing a temporary pointer conversion to an
@_nonEphemeral parameter such that it doesn't
affect overload resolution. This is done by recording
the fix with an impact of zero, meaning that we don't
touch the solution's score.
In addition, this change means we no longer need
to perform the ranking hack where we favour
array-to-pointer, as the disjunction short-circuiting
will continue to happen even with the fix recorded.
Use ProtocolConformanceRef::forInvalid() in implementations only as a semantic signal. In one place, use the default constructor to drop the final use of Optional<ProtocolConformanceRef>.
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
Structurally prevent a number of common anti-patterns involving generic
signatures by separating the interface into GenericSignature and the
implementation into GenericSignatureBase. In particular, this allows
the comparison operators to be deleted which forces callers to
canonicalize the signature or ask to compare pointers explicitly.
This only comes into play when all other choices are coming from
constrained extensions, because there is no way to determine upfront
whether any are going to match it's better to be safe and add
key path dynamic member choice to the set too.
Resolves: [SR-11465](https://bugs.swift.org/browse/SR-11465)
Resolves: rdar://problem/55314724
While it's currently not possible for `isDeclAsSpecializedAs` to compare
decls that differ by having a curried self or having a parameter list,
tweak the logic slightly so it could handle that case if it needed to.
If one decl has a parameter list and the other doesn't, then just
compare their self types. If one decl is curried and the other isn't,
then add a curried self to the other and compare as normal.