Make sure we preserve the result expression for an out-of-place
`return`, or a non-`nil` result in an initializer. This ensures we
can still provide semantic functionality from them and fixes a crash
where we would fail to type-check a binding.
We know this is where the issue is so we can immediately bind to a hole,
ensuring we don't produce unnecessary downstream diagnostics from
things we can't infer.
These are tests that fail in the next commit without this flag. This
does not add -verify-ignore-unrelated to all tests with -verify, only
the ones that would fail without it. This is NFC since this flag is
currently a no-op.
This never worked correctly and would crash in SILGen, ban the use
of placeholder types. While here, ensure we replace any ErrorTypes
with holes when solving the closure in the constraint system.
We weren't substituting generic arguments into function types. In the
presence of parameter packs, this could mean that the parameter and
argument lists no longer match up, which would cause the effects
checker to prematurely bail out after treating this as "invalid" code.
The overall effect is that we would not properly check for throwing
behavior in this case, allowing invalid code (as in the example) and
miscompiling valid code by not treating the call as throwing.
Fixes rdar://153926820.
Skipping type-checking the body when the preamble fails to type-check
seems to be more of a historical artifact than intentional behavior.
Certain elements of the body may still get type-checked through
request evaluation, and as such may introduce autoclosures that won't
be properly contextualized.
Make sure we continue type-checking the body even if the preamble
fails. We already invalidate any variables bound in the element
pattern, so downstream type-checking should be able to handle it
just fine. This ensures autoclosures get contextualized, and that
we're still able to provide semantic diagnostics for other issues in
the body.
rdar://136500008
Check for unsafe constructs in all modes, so that we can emit the
"unsafe does not cover any unsafe constructs" warning consistently.
One does not need to write "unsafe" outside of strict memory safety
mode, but if you do... it needs to cover unsafe behavior.
Rather than fixing-up in the parser, adjust the ASTScope logic such
that a `try` element in a SequenceExpr is considered as covering all
elements to the right of it. Cases where this isn't true are invalid,
and will be diagnosed during sequence folding. e.g:
```
0 * try foo() + bar()
_ = try foo() ~~~ bar() // Assuming `~~~` has lower precedence than `=`
```
This ensures we correctly handle `try` in assignment sequences, and
allows ASTGen to get the behavior for free.
rdar://132872235
Previously we would check if we have a SwitchStmt,
and apply diagnostics such as `checkExistentialTypes`
to the CaseStmts individually. This however would
have been missed for `catch` statements. The change
to consistently call `performStmtDiagnostics` in
closures fixed this for `do-catch`'s in closures,
this commit fixes it for those outside of closures.
Because this is source breaking, the existential
diagnostic is downgraded to a warning until Swift
7 for catch statements specifically.
While here, also apply the ambiguous where clause
diagnostic to `catch` statements.
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.
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
Some editors use diagnostics from SourceKit to replace build issues. This causes issues if the diagnostics from SourceKit are formatted differently than the build issues. Make sure they are rendered the same way, removing most uses of `DiagnosticsEditorMode`.
To do so, always emit the `add stubs for conformance` note (which previously was only emitted in editor mode) and remove all `; add <something>` suffixes from notes that state which requirements are missing.
rdar://129283608
Previously we could end up with a
ContextualMismatch fix and a MissingConformance fix
for different elements of the `matchTypes` disjunction,
leading to an ambiguity. Instead, avoid recording
the ContextualMismatch if we're matching an
existential, and tweak the MissingConformance
failure to have a custom diagnostic for
EnumElementPattern matching.
throw `Never`.
Previously, this mistake slipped through the effects checker because it used
a fallback type of `any Error` if a catch node had a null thrown error type.
This change also fixes an issue where thrown error type mismatches were not
diagnosed at all in autoclosures.
If both sides of an `OptionalObject` constraint are un-inferred, their
binding sets need to correctly reflect adjacency - a type variable
that represents optional would get "object" as an adjacency through
its potential binding (the binding is - "object" wrapped in a single
level of optional) and "object" type variable needs to get its parent
optional type variable added to its adjacency list explicitly.
Without this it would be possible to prematurely pick "object" before
its parent optional type variable.
Resolves: https://github.com/apple/swift/issues/73207
Resolves: rdar://126960579
Previously code completion for 'catch' pattern bound values didn't work
correctly because code completion type checker fails to type check the
value decl in the pattern.
That was because the body of the 'do' statement is not type checked, so
the thrown error is not determined, then falled backed to the default
'Never', which doesn't matches any patterns.
To resolve this, always type check the body when typechecking 'catch'
patterns. Also, pretends 'do {}' throws 'any Error' even without
any throwing expressions in the body.
rdar://126699879
Prior to the introduction of typed throws, a `do..catch` always had a caught
error type of `any Error`, even if there were no throwing sites within
the `do` body. With typed throws, such a `do..catch` would have a
caught error type of `Never`, because it never throws. Unfortunately,
this causes code like the following to produce an error, because
`Never` cannot be pattern-matched to `HomeworkError.forgot`:
func test() {
do {
try nonthrowing()
} catch HomeworkError.forgot {
} catch {
}
}
For source-compatibility reasons, adjust the caught error type to
`any Error` in this case, so we continue to accept the code above.
Don't do this adjustment under `FullTypedThrows`, because it's only
there for compatibility.
Fixes rdar://121526201.
A reference to a subscript (whether instance or static) produces a
function type, which is then applied as part of an application
constraint. Make sure that we encode whether the subscript can throw,
and the thrown error type if present, in that function type. This lets
us correctly treat subscripts as a potential throw sites.
Start classifying all potential throw sites within a constraint
system and associate them with the nearest enclosing catch node. Then,
determine the thrown error type for a given catch node by taking the
union of the thrown errors at each potential throw site. Use this to
compute the error type thrown from the body of a `do..catch` block
within a closure.
This behavior is limited to the upcoming feature `FullTypedThrows`.
Teach the constraint system to use the same primitives as elsewhere to
determine the type context for a `throw` statement and the caught
error type within a `do..catch` statement. This makes
explicitly-specified `throws` work on `do..catch` that occurs in
closures.
Cleans up some redundant computations for caught error types.
Both `try?` and `try!` are catch nodes, because they catch an error
thrown in their subexpression and handle it. Introduce an ASTScope for
all `try/try?/try1` expressions so we can find them, and model them as
catch nodes.
Fixes rdar://119216455.
During the review of SE-0413, typed throws, the notion of a `do throws`
syntax for `do..catch` blocks came up. Implement that syntax and
semantics, as a way to explicitly specify the type of error that is
thrown from the `do` body in `do..catch` statement.
ASTGen always builds with the host Swift compiler, without requiring
bootstrapping, and is enabled in more places. Move the regex literal
parsing logic there so it is enabled in more host environments, and
makes use of CMake's Swift support. Enable all of the regex literal
tests when ASTGen is built, to ensure everything is working.
Remove the "AST" and "Parse" Swift modules from SwiftCompilerSources,
because they are no longer needed.
Allow a rethrows function to call a typed-throws function that has a
specific form that looks like it only rethrows, i.e., it is generic
over its thrown error type and carries the thrown error type from its
closure parameters to itself. This is a compatibility carve-out to
allow existing rethrows functions to move to typed throws without
breaking their clients.
Note that it is possible to write a sneaky function that passes this
check but throws when it shouldn't, so this compatibility carve-out is
phased out with the upcoming feature FullTypedThrows.
When "optional type" is a hole the simplification logic has to
simplify "object type" and mark all of its unresolved components
are potential holes, otherwise hole propagation won't work since
sometimes there is no other contextual information for such types
but "optional type".
Resolves: rdar://117871338
For any operation that can throw an error, such as calls, property
accesses, and non-exhaustive do..catch statements, record the thrown
error type along with the conversion from that thrown error to the
error type expected in context, as appropriate. This will prevent
later stages from having to re-compute the conversion sequences.