When using shorthand syntax for optional binding,
if the variable we are binding is accessed asynchronously,
provide an insertion fixIt of the form: ' = await (identifier)'.
Previously, we would suggest only adding the 'await'
which resulted in an error since the identifier is required.
Remove keypath subtype asserts; always use cached root type
Add tests for keypaths converted to funcs with inout param
Add unit test for overload selection
This removes the distinction between argument completions and postfix expr paren completions, which was meaningless since solver-based completion.
It then determines whether to suggest the entire function call pattern (with all argument labels) or only a single argument based on whether there are any existing arguments in the call.
For this to work properly, we need to improve parser recovery a little bit so that it parsers arguments after the code completion token properly.
This should make call pattern heuristics obsolete.
rdar://84809503
In asserts builds this hits an assert that the
feature isn't enabled, and in no-asserts builds
this incorrectly allows `do` expressions to be
used with the feature disabled. Note this only
affects their use when nested in an `if`/`switch`
that is used in a binding, we correctly handled
the other cases.
rdar://121193678
If root type of a key path has been determined to be a hole there
is no reason to delay the inference decision which should be a
failure because none of the components would be inferrable from
a placeholder root.
Produce a tailored diagnostic that omits a fully unresolved key path
type (`KeyPath<_, _>`) when key path without an explicit root type is
passed as an argument to non-keypath parameter type (i.e. `Int`).
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.
Covariant conversions between explicit and contextual/inferred root
types of a key path are simulated through a subtype constraint which
has to be attached to a `KeyPathRoot` element.
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.
A key path without an explicit root cannot be unwrapped since the
optionality is inferred from context and we cannot suggest removing
that, adding explicit type is not going to change anything and
`!` and `?` after the leading dot is not supported.
`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.
If type of the key path expression is convertible to an existential
value with a superclass constraint represented as a known key path
type, we can use it to inform key path inference.
Resolves: rdar://93103421
Previously we allowed an attached `try` or `await`
on an `if`/`switch` expression to cover the branches,
which does not match what was proposed, and is
especially harmful for multi-statement cases. Fix
the effect handling logic such that we reset
effect coverage for `if`/`switch` expressions
similar to closures, but continue to maintain the
state needed for rethrows checking.
rdar://116066748
Move out-of-place SingleValueStmtExpr checking into
`performSyntacticExprDiagnostics`, to ensure we
catch all expressions. Previously we did the walk
as a part of Decl-based MiscDiagnostics, but it
turns out that can miss expressions in property
initializers, subscript default arguments, and
custom attrs.
This does mean that we'll now no longer diagnose
out-of-place if/switch exprs if the expression
didn't type-check, but that's consistent with the
rest of MiscDiagnostics, and I don't think it will
be a major issue in practice. We probably ought to
consider moving this checking into PreCheckExpr,
but that would require first separating out
SequenceExpr folding, which has other consequences,
and so I'm leaving as future work for now.
Previously we would only look through a handful of
AST node types when determining if an if/switch
expression is in a valid position. However this
doesn't handle cases where we synthesize code
around an if/switch expression, such as
`init(erasing:)` calls. As such, relax the logic
such that it can look through any implicit
expression.
rdar://113435870
- Allow an if/switch expression to become an
implicit return of a function that has a `#if`
body with a single active element that is an `if`
or `switch`.
- Allow `#if` branches of an if/switch expression,
as long as there is a single active expression
element.
rdar://107487977
Look through `try`/`await` markers when looking for
out of place if/switch expressions, and customize
the effect checking diagnostic such that we error
that `try`/`await` are redundant on `if`/`switch`
expressions.
Introduce SingleValueStmtExpr, which allows the
embedding of a statement in an expression context.
This then allows us to parse and type-check `if`
and `switch` statements as expressions, gated
behind the `IfSwitchExpression` experimental
feature for now. In the future,
SingleValueStmtExpr could also be used for e.g
`do` expressions.
For now, only single expression branches are
supported for producing a value from an
`if`/`switch` expression, and each branch is
type-checked independently. A multi-statement
branch may only appear if it ends with a `throw`,
and it may not `break`, `continue`, or `return`.
The placement of `if`/`switch` expressions is also
currently limited by a syntactic use diagnostic.
Currently they're only allowed in bindings,
assignments, throws, and returns. But this could
be lifted in the future if desired.
If all solutions point to the same overload choice that needs
re-labeling it's safe to diagnose it as if there was no ambiguity
because the call site is static.