Merge with ContextualizeClosuresAndMacros, and
rename to ContextualizationWalker given that it
re-contextualizes a whole bunch of AST nodes now.
This ensures we correctly handle cases such as
decls in if/switch expressions within autoclosures.
Type annotations for instruction operands are omitted, e.g.
```
%3 = struct $S(%1, %2)
```
Operand types are redundant anyway and were only used for sanity checking in the SIL parser.
But: operand types _are_ printed if the definition of the operand value was not printed yet.
This happens:
* if the block with the definition appears after the block where the operand's instruction is located
* if a block or instruction is printed in isolation, e.g. in a debugger
The old behavior can be restored with `-Xllvm -sil-print-types`.
This option is added to many existing test files which check for operand types in their check-lines.
Find all the usages of `--enable-experimental-feature` or
`--enable-upcoming-feature` in the tests and replace some of the
`REQUIRES: asserts` to use `REQUIRES: swift-feature-Foo` instead, which
should correctly apply to depending on the asserts/noasserts mode of the
toolchain for each feature.
Remove some comments that talked about enabling asserts since they don't
apply anymore (but I might had miss some).
All this was done with an automated script, so some formatting weirdness
might happen, but I hope I fixed most of those.
There might be some tests that were `REQUIRES: asserts` that might run
in `noasserts` toolchains now. This will normally be because their
feature went from experimental to upcoming/base and the tests were not
updated.
Impose the same limit we impose on other
forms of control flow statements (e.g `break`,
`continue`, `return`), where it cannot transfer
control out of the expression. This fixes a crash
where we'd fail to find a fallthrough nested in an
`if` expression. It is technically source breaking,
as we would have allowed the case where the `if`
expression is a directly nested result of an outer
`switch` expression, but I would be very surprised
if anyone is relying on that.
rdar://133845101
Allow `fallthrough` to appear as the last statement
in the case of a `switch` expression. We already
allowed it in other positions, this was just an
oversight.
rdar://127670432
With `if`/`switch` expressions, we may now have
local bindings within lazy initializers, and
therefore need to ensure we correctly
re-contextualize them. Adjust the walker to set
the DeclContext for all decls it encounters,
and make sure it handles some cases that the
ASTWalker does not currently visit.
rdar://119158202
If we have an uninhabited branch, emit it as an
ignored expr followed by an unreachable.
Previously we would omit the unreachable and rely
on the SILOptimizer to infer it, but we ought to
just emit it here. Also check `isUninhabited()`
instead of `isStructurallyUninhabited` since this
better matches what we allow in Sema. For tuples
of uninhabited values, we can do a regular
initialization without issue.
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.
`Initialization` is stateful and not meant to be emitted into multiple times across different contexts.
If emitting into an initialization causes it to be split or aborted, that will carry over into
further uses of the initialization. This was happening during `if` and `switch` expression
emission, leading to miscompiles or compiler crashes. Fix this by saving only the buffer when
we prepare emission for a statement expression, and creating the initialization in the scope
where the expression for a branch actually gets emitted. Fixes rdar://112213253.
When emitting the underlying `switch` statement
for a `switch` expression, we emit an `unreachable`
if the subject is uninhabited. Statement emission
code can handle this, but expression emission expects
an RValue to handed back. To remedy this, emit
an unreachable block that we can emit the rest of
the expression emission code into. The SILOptimizer
will then drop this unreachable block.
Previously we would wait until CSApply, which
would trigger their type-checking in
`coercePatternToType`. This caused a number of
bugs, and hampered solver-based completion, which
does not run CSApply. Instead, form a conjunction
of all the ExprPatterns present, which preserves
some of the previous isolation behavior (though
does not provide complete isolation).
We can then modify `coercePatternToType` to accept
a closure, which allows the solver to take over
rewriting the ExprPatterns it has already solved.
This then sets the stage for the complete removal
of `coercePatternToType`, and doing all pattern
type-checking in the solver.
Make sure we look through a wrapping
`OptionalEvaluationExpr` and its injections when
looking for an assignment to mark a valid if/switch
source expression.
rdar://109305454
Previously we could miss the scopes present in
if/switch expressions if they were nested in
another expression, such as an AssignExpr. Fix
the logic such that we properly walk over a given
expression looking for if/switch scopes, the same
as what we do for closures.
rdar://109192116
- 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
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.