Commit Graph

40 Commits

Author SHA1 Message Date
Hamish Knight 7350671733 [Sema] Catch use-before-declarations in nested closures
Previously we would allow these in Sema and diagnose them in SILGen,
but allowing them in Sema is unsound because it means the constraint
system ends up kicking interface type requests for declarations that
should be type-checked as part of the closure itself. Adjust the
name lookup logic to look through parent closures when detecting
invalid forward references.

For now we don't fallback to an outer result on encountering a
use-before-declaration to preserve the current behavior. I'm planning
on changing that in the next commit though.

rdar://74430478
2026-03-03 21:59:12 +00:00
Pavel Yaskevich cfea0d3d22 [TypeChecker] NFC: Add XFAIL'ed test-case for https://github.com/apple/swift/issues/67363 2023-08-14 10:06:52 -07:00
Pavel Yaskevich 64a654dc0d Revert "[CSBindings] Prefer conjunctions over closure variables without bindings"
This reverts commit 11ee82de7b.
2023-08-14 10:02:05 -07:00
Pavel Yaskevich 11ee82de7b [CSBindings] Prefer conjunctions over closure variables without bindings
If a closure doesn't have a contextual type inferred yet it should
be delayed in favor of already resolved closure conjunction because
"resolving" such a closure early could miss result builder attribute
attached to a parameter the closure is passed to.

Partially resolves https://github.com/apple/swift/issues/67363
2023-07-21 09:46:09 -07:00
Slava Pestov 1957bd6065 Sema: Reword diagnostics to say 'without a type annotation' instead of 'without more context' 2023-06-09 17:44:42 -04:00
Pavel Yaskevich 20d7642ca4 [CSGen] Allow expression pattern types to be holes 2023-04-24 10:02:00 -07:00
Michael Gottesman 0ad5a18d40 Update test output. 2023-03-03 18:19:26 -08:00
Michael Gottesman c97121d3ee [reference-binding] Add support for inout binding parsing/serialization. 2023-03-01 20:48:54 -08:00
Pavel Yaskevich 8e82f1d68b [CSGen] Detect nested out-of-scope variables in recursive declarations
Follow-up to https://github.com/apple/swift/pull/63505

Since, when the type is not stated, a variable assumes the
type of its initializer that enables out-of-scope variables
to be nested inside of some other concrete type i.e. Optional.

Resolves: https://github.com/apple/swift/issues/63455
2023-02-11 19:19:09 -08:00
Pavel Yaskevich bffb8d9ee2 Revert "[CSGen] Handle recursive use of variable declarations" 2023-02-10 16:45:59 -08:00
Pavel Yaskevich 83dd93ad2e [CSGen] Handle recursive use of variable declarations
It's possible for out-of-scope type variable to be the type of
declaration if such declaration is recursively referenced in
the body of a closure located in its initializer expression.
In such cases type of the variable declaration cannot be connected
to the closure because its not known in advance (determined by the
initializer itself).

Resolves: https://github.com/apple/swift/issues/63455
2023-02-07 17:48:26 -08:00
Pavel Yaskevich 65e7eec62f [CSSolver] Solve multi-statement closures in source order
Currently solver picks the first conjunction it can find,
which means - the earliest resolved closure. This is not
always correct because when calls are chained closures
passed to the lower members could be resolved sooner
than the ones higher up but at the same time they depend
on types inferred from members higher in the chain.

Let's make sure that multi-statement closures are always
solved in order they appear in the AST to make sure that
types are available to members lower in the chain.
2022-12-12 10:57:21 -08:00
Pavel Yaskevich 61d3a9f786 [CSClosure] Always pre-check init targets of wrapped vars
If a variable with attached property wrapper has an initializer
expression it could be modified by implicit wrapper application,
if there is no initializer - one would be synthesized by the
compiler (without arguments). In both cases target has to be
pre-checked before constraints are generated for it.

Resolves: https://github.com/apple/swift/issues/61024
2022-09-12 16:08:36 -07:00
Pavel Yaskevich 3e791dd169 [CSClosure] Use correct type for implicit wrapper variables
Using `computeWrappedValueType` is incorrect because
that return a type of the wrapped variable and not
the *wrapper* variable (one that starts with `_`).

Resolves: https://github.com/apple/swift/issues/61017
2022-09-12 09:53:24 -07:00
Pavel Yaskevich 3ebc541fd5 [CSDiagnostics] Verify that member is in collection context
`MissingMemberFailure::diagnoseInLiteralCollectionContext`
should verify that a parent (or parent of a parent) expression
is indeed a collection expression instead of checking types.

Resolves: rdar://91452726
2022-08-17 12:12:27 -07:00
Alex Hoppen e14fa7291f [CS] Don’t fail constraint generation for ErrorExpr or if type fails to resolve
Instead of failing constraint generation by returning `nullptr` for an `ErrorExpr` or returning a null type when a type fails to be resolved, return a fresh type variable. This allows the constraint solver to continue further and produce more meaningful diagnostics.

Most importantly, it allows us to produce a solution where previously constraint generation for a syntactic element had failed, which is required to type check multi-statement closures in result builders inside the constraint system.
2022-07-20 09:46:12 +02:00
Pavel Yaskevich 9c8bebe4f8 [CSClosure] Detect and diagnose conflicting pattern variables in case statements
Avoid mutating case label items while solving, instead let's use types
recorded in the constraint system for each pattern variable and use
that for var reference in the case body. This also helps to detect
and diagnose type conflicts while solving.
2022-06-03 16:35:18 -07:00
Pavel Yaskevich 1099cca050 Merge pull request #59238 from xedin/rdar-92757114-test
[CSClosure] NFC: Add a test-case for rdar://92757114
2022-06-03 16:28:04 -07:00
Pavel Yaskevich c581497bd4 [CSClosure] NFC: Add a test-case for rdar://92757114
Used to produce a fallback `type of expression ...` diagnostic
2022-06-03 12:21:06 -07:00
Pavel Yaskevich df1e38ff36 [TypeChecker] NFC: Add test-case for rdar://93061432 2022-05-30 23:17:41 -07:00
Pavel Yaskevich 953095a9ce [CSClosure] Perform syntactic checks on rewritten statements
Fix an oversight where syntactic checking was not performed on
any statements in a body of a multi-statement after successful
solution application.

Resolves: rdar://94049113
2022-05-27 14:51:27 -07:00
Pavel Yaskevich 4e9992c261 [CSClosure] Fix crash in fallthrough statement checking
`fallthrough` requires both source and destination `case`
"preambles" be type-checked before it could be validated,
which means that solution application for `case` statements
in a `switch` has to be split in two - preamble first and
bodies afterwards.

Resolves: https://github.com/apple/swift/issues/59035
Resolves: rdar://93796211
2022-05-24 14:20:42 -07:00
Pavel Yaskevich 0e8ece615f Merge pull request #58834 from xedin/var-finder-return-handling
[CSClosure] Fix per-element variable finder to correctly handle retur…
2022-05-18 18:02:14 -07:00
Pavel Yaskevich 569333135c Merge pull request #58768 from xedin/redecl-check-in-multi-closures
[CSClosure] Diagnose invalid re-declarations in multi-statement closures
2022-05-18 15:03:41 -07:00
Pavel Yaskevich ddd7e495dd [CSClosure] Fix per-element variable finder to correctly handle return statements
Type finder is still allowed to walk into closures to find any
referenced variables, but it should bring external result type
into scope only if a particular `return` belongs to the same
closure as the element.
2022-05-18 13:52:34 -07:00
Pavel Yaskevich dfadee3731 [CSDiagnostics] Attach missing member diagnostic to a pattern/statement
If missing member is found in e.g. case statement or a pattern,
let's attach diagnostic directly to it.
2022-05-18 00:28:08 -07:00
Pavel Yaskevich 854f64eff5 [CSClosure] Diagnose invalid re-declarations in multi-statement closures
Calling `typeCheckDecl` on `VarDecl` is what triggers re-declaration
checking and that was skipped by the solution application logic.
2022-05-09 12:50:39 -07:00
Pavel Yaskevich 67895c2927 [CSClosure] Mark partially inferred external declarations as invalid
If a syntactic element references an external declaration (relative
to its own context), let's check whether it has any type variables,
and if so, replace them with errors to remove any possibility of
bringing external constraints into element's scope.

Resolves: rdar://92347054
2022-05-05 11:44:26 -07:00
Pavel Yaskevich 48e70ed6cc [ConstraintSystem] Fail ~= synthesis if constraint generation fails
If constraint generation for application of `~=` failed that should
result in an immediate synthesis failure.

Resolves: rdar://92366212
2022-04-28 18:02:19 -07:00
Pavel Yaskevich 6db0001863 [TypeChecker] NFC: Remove -experimental-multi-statement-closures flag
SE-0326 has been enabled by default, so this flag is no longer necessary.
2022-04-20 10:40:27 -07:00
Pavel Yaskevich 869a413aae [CSClosure] Handle wrapped variables without explicit initializers
All variables without explicit initializers were considered to be
uninitialized which is incorrect because if a variable has a property
wrapper attached to it that wrapper needs its initializer type-checked,
for example:

```
@propertyWrapper
struct Wrapper {
  var name: String

  ...
}

test {
  @wrapper(name: "wrapper")
  var v;
}
```

`v` gets initialized via a call to `Wrapper(name: "wrapper")`.

Resolves: rdar://91225620
2022-04-06 14:36:31 -07:00
Pavel Yaskevich 3c5a6f93e9 Merge pull request #41864 from xedin/improvements-for-diagnoseAmbiguity
[ConstraintSystem] Augment `diagnoseAmbiguity` to handle non-expression anchors
2022-03-21 10:00:19 -07:00
Pavel Yaskevich ebdef12fe1 [ContraintSystem] Augment diagnoseAmbiguity to diagnose non-expression ambiguities
Since constraint solver can now handle statements, patterns, and declarations,
it's possible to that ambiguity could be detected in a non-expression context,
for example - pattern matching in switch statements. Augment `diagnoseAmbiguity`
to accept overloads with non-expression anchors and diagnose them in order of
their appearance in a solution.
2022-03-17 13:02:20 -07:00
Pavel Yaskevich 613fdca3a8 [CSDiagnostics] Fix trailing closure ambiguity note to not expect that anchor is expression
`TrailingClosureAmbiguityFailure::diagnoseAsNote()` is used by
`diagnoseAmbiguity` opportunistically, which means that anchor
could be a pattern or a statement condition element.
2022-03-17 12:20:23 -07:00
Pavel Yaskevich 2dd97748f3 [CSGen] Use correct locator for member references in enum element patterns
Referencing a member in pattern context is not a regular member reference,
it should use only enum element declarations, just like leading-dot syntax
does, so both locators should end with `pattern matching` element to indicate
that to the member lookup.

Resolves: rdar://90347159
2022-03-17 11:54:40 -07:00
Pavel Yaskevich 894c932ad0 [CSApply] Use decl context of target when applying solution to it
Solution application target can have its declaration context differ
from one used for constraint system, since target could be e.g. a
pattern associated with pattern binding declaration, a statement or
a sub-element of one (e.g. where clause) used in a closure etc.
2022-03-14 10:09:35 -07:00
Pavel Yaskevich e9f7a6a8f5 [CSClosure] Delay type-checking of local functions until body is rewritten
A local function can capture a variable that has been declared after it,
which means that type-checking such declaration in-order would trigger
sub-typecheck that would corrupt AST underness the solution application
walker.
2022-03-02 16:37:12 -08:00
Pavel Yaskevich 59154d6d71 [ConstraintSystem] Support solving expression patterns via injecting call to ~= operator
Augment the constraint solver to fallback to implicit `~=` application
when member couldn't be found for `EnumElement` patterns because
`case` statement should be able to match enum member directly, as well
as through an implicit `~=` operator application.
2022-02-28 17:02:28 -08:00
Pavel Yaskevich f287f7e6e4 [CSClosure] Support empty return when closure result is optional Void
Source compatibility workaround.

func test<T>(_: () -> T?) {
  ...
}

A multi-statement closure passed to `test` that has an optional
`Void` result type inferred from the body allows:
  - empty `return`(s);
  - to skip `return nil` or `return ()` at the end.

Implicit `return ()` has to be inserted as the last element
of the body if there is none. This wasn't needed before SE-0326
because result type was (incorrectly) inferred as `Void` due to
the body being skipped.

Resolves: rdar://85840941
2021-12-08 13:27:21 -08:00
Pavel Yaskevich 42b1a3992e [TypeChecker] NFC: Add some test-cases for extended multi-statement closure inference 2021-10-14 12:00:31 -07:00