Fix a regression introduced by moving the type checking of closure
captures into the constraint system. The pattern-type optimization for
initializations was causing inference of a double-optional where there
shouldn't be one, manifesting in a failure involving implicitly
unwrapped optionals and `weak self` captures.
Fixes rdar://problem/67351438.
```swift
func foo(f: Void) -> ()) {}
```
This compiler currently suggests we change this to:
```swift
func foo(f: (Void) -> ()) {}
```
That's `(()) -> ()`, almost certainly not what someone wants in Swift
4. We should suggest changing that to:
```swift
func foo(f: () -> ()) {}
```
Additionally,
```swift
func foo(f: (Void) -> ()) {}
```
Should trigger a warning that the `(Void)` input type is `(())`, and you
can't supply `()` to it in Swift 4, and suggest a fix-it change it to:
```swift
func foo(f: () -> ()) {}
```
rdar://problem/32143617
This fixes a usability regression with the removal of @noreturn
in Swift 3. Previously, it was legal to write this:
let callback: () -> Int = { fatalError() }
Now that the special @noreturn attribute has been replaced with
a Never type, the above fails to typecheck, because the expression
now has type 'Never', and we expect a value of type 'Int'.
Getting around this behavior requires ugly workarounds to force the
parser to treat the body as a statement rather than an expression;
for example,
let callback: () -> Int = { _ = (); fatalError() }
This patch generalized single-expression closures to allow
the 'Never to T' conversion. Note that this is rather narrow
in scope -- it only applies to closure *literals*, single-expression
ones at that, not arbitrary function *values*.
In fact, it is not really a conversion at all, but more of a
desugaring rule for single-expression closures. They can now be
summarized as follows:
- If the closure literal has contextual return type T and
the expression has Never type, the closure desugars as
{ _ = <expr> }, with no ReturnStmt.
- If the closure literal has contextual return type T for some
non-void type T, the closure desugars as { return <expr> };
the expression type must be convertible to T.
- If the closure literal has contextual return type Void, and
the expression has some non-Void type T, the closure
desugars as { _ = <expr>; return () }.
Fixes <rdar://problem/28269358> and <https://bugs.swift.org/browse/SR-2661>.
* [Fixit] Add a fixit for converting non-trailing closures to trailing closures.
* [test] Update test to reflect the added note about converting to trailing closures.
When assigning discriminators to autoclosure expressions, make sure to
walk into single-expression closures even when they have been converted
to return void, because they aren't type-checked separately.
<rdar://problem/22441425> Swift compiler "INTERNAL ERROR: this diagnostic should not be produced"
Swift SVN r31654
- If the closure being rewritten was nested inside of another
closure, we would rewrite the nested closure into a new closure
having cs.DC as its parent, rather than the DeclContext of the
outer closure as required.
- If the closure being rewritten had nested closures, the parent
DeclContext of the nested closures was set to the old closure,
not the new one.
Fix both problems by having coerceClosureExprToVoid() modify the
closure in place instead of creating a new closure.
Fixes <rdar://problem/20931915>.
Swift SVN r29563
The rule changes are as follows:
* All functions (introduced with the 'func' keyword) have argument
labels for arguments beyond the first, by default. Methods are no
longer special in this regard.
* The presence of a default argument no longer implies an argument
label.
The actual changes to the parser and printer are fairly simple; the
rest of the noise is updating the standard library, overlays, tests,
etc.
With the standard library, this change is intended to be API neutral:
I've added/removed #'s and _'s as appropriate to keep the user
interface the same. If we want to separately consider using argument
labels for more free functions now that the defaults in the language
have shifted, we can tackle that separately.
Fixes rdar://problem/17218256.
Swift SVN r27704
Most tests were using %swift or similar substitutions, which did not
include the target triple and SDK. The driver was defaulting to the
host OS. Thus, we could not run the tests when the standard library was
not built for OS X.
Swift SVN r24504
This commit implements closure syntax that places the (optional)
parameter list in pipes within the curly braces of a closure. This
syntax "slides" well from very simple closures with anonymous
arguments, e.g.,
sort(array, {$1 > $0})
to naming the arguments
sort(array, {|x, y| x > y})
to adding a return type and/or parameter types
sort(array, {|x : String, y : String| -> Bool x > y})
and with multiple statements in the body:
sort(array, {|x, y|
print("Comparing \(x) and \(y)\n")
return x > y
})
When the body contains only a single expression, that expression
participates in type inference with its enclosing expression, which
allows one to type-check, e.g.,
map(strings, {|x| x.toUpper()})
without context. If one has multiple statements, however, one will
need to provide additional type information either with context
strings = map(strings, {
return $0.toUpper()
})
or via annotations
map(strings, {|x| -> String
return x.toUpper()
}
because we don't perform inter-statement type inference.
The new closure expressions are only available with the new type
checker, where they completely displace the existing { $0 + $1 }
anonymous closures. 'func' expressions remain unchanged.
The tiny test changes (in SIL output and the constraint-checker test)
are due to the PipeClosureExpr AST storing anonymous closure arguments
($0, $1, etc.) within a pattern in the AST. It's far cleaner to
implement this way.
The testing here is still fairly light. In particular, we need better
testing of parser recovery, name lookup for closures with local types,
more deduction scenarios, and multi-statement closures (which don't
get exercised beyond the unit tests).
Swift SVN r5169