mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[SR-14824] Improve diagnostic for multi-statement closures instead of saying "too complex closure return type"
This commit is contained in:
@@ -273,8 +273,8 @@ ERROR(cannot_infer_closure_parameter_type,none,
|
||||
ERROR(cannot_infer_closure_type,none,
|
||||
"unable to infer closure type in the current context", ())
|
||||
ERROR(cannot_infer_closure_result_type,none,
|
||||
"unable to infer%select{ complex|}0 closure return type; "
|
||||
"add explicit type to disambiguate", (bool))
|
||||
"cannot infer return type for closure with multiple statements; "
|
||||
"add explicit type to disambiguate", ())
|
||||
FIXIT(insert_closure_return_type_placeholder,
|
||||
"%select{| () }0-> <#Result#> %select{|in }0",
|
||||
(bool))
|
||||
|
||||
@@ -6845,8 +6845,7 @@ bool UnableToInferClosureParameterType::diagnoseAsError() {
|
||||
bool UnableToInferClosureReturnType::diagnoseAsError() {
|
||||
auto *closure = castToExpr<ClosureExpr>(getRawAnchor());
|
||||
|
||||
auto diagnostic = emitDiagnostic(diag::cannot_infer_closure_result_type,
|
||||
closure->hasSingleExpressionBody());
|
||||
auto diagnostic = emitDiagnostic(diag::cannot_infer_closure_result_type);
|
||||
|
||||
// If there is a location for an 'in' token, then the argument list was
|
||||
// specified somehow but no return type was. Insert a "-> ReturnType "
|
||||
|
||||
@@ -252,7 +252,7 @@ struct CC {}
|
||||
func callCC<U>(_ f: (CC) -> U) -> () {}
|
||||
|
||||
func typeCheckMultiStmtClosureCrash() {
|
||||
callCC { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{none}}
|
||||
callCC { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{none}}
|
||||
_ = $0
|
||||
return 1
|
||||
}
|
||||
@@ -313,7 +313,7 @@ struct Thing {
|
||||
init?() {}
|
||||
}
|
||||
// This throws a compiler error
|
||||
let things = Thing().map { thing in // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{34-34=-> <#Result#> }}
|
||||
let things = Thing().map { thing in // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{34-34=-> <#Result#> }}
|
||||
// Commenting out this makes it compile
|
||||
_ = thing
|
||||
return thing
|
||||
@@ -322,7 +322,7 @@ let things = Thing().map { thing in // expected-error {{unable to infer complex
|
||||
|
||||
// <rdar://problem/21675896> QoI: [Closure return type inference] Swift cannot find members for the result of inlined lambdas with branches
|
||||
func r21675896(file : String) {
|
||||
let x: String = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{20-20= () -> <#Result#> in }}
|
||||
let x: String = { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{20-20= () -> <#Result#> in }}
|
||||
if true {
|
||||
return "foo"
|
||||
}
|
||||
@@ -360,7 +360,7 @@ func someGeneric19997471<T>(_ x: T) {
|
||||
|
||||
|
||||
// <rdar://problem/20921068> Swift fails to compile: [0].map() { _ in let r = (1,2).0; return r }
|
||||
[0].map { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{5-5=-> <#Result#> }}
|
||||
[0].map { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{5-5=-> <#Result#> }}
|
||||
_ in
|
||||
let r = (1,2).0
|
||||
return r
|
||||
@@ -408,7 +408,7 @@ func r20789423() {
|
||||
print(p.f(p)()) // expected-error {{cannot convert value of type 'C' to expected argument type 'Int'}}
|
||||
// expected-error@-1:11 {{cannot call value of non-function type '()'}}
|
||||
|
||||
let _f = { (v: Int) in // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{23-23=-> <#Result#> }}
|
||||
let _f = { (v: Int) in // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{23-23=-> <#Result#> }}
|
||||
print("a")
|
||||
return "hi"
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ public func myMap<T, U>(_ x: T?, _ f: (T) -> U) -> U? {
|
||||
|
||||
// <rdar://problem/20142523>
|
||||
func rdar20142523() {
|
||||
myMap(0..<10, { x in // expected-error{{unable to infer complex closure return type; add explicit type to disambiguate}} {{21-21=-> <#Result#> }} {{educational-notes=complex-closure-inference}}
|
||||
myMap(0..<10, { x in // expected-error{{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{21-21=-> <#Result#> }} {{educational-notes=complex-closure-inference}}
|
||||
()
|
||||
return x
|
||||
})
|
||||
|
||||
@@ -230,14 +230,14 @@ func good(_ a: A<EE>) -> Int {
|
||||
}
|
||||
|
||||
func bad(_ a: A<EE>) {
|
||||
a.map { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{none}}
|
||||
a.map { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{none}}
|
||||
let _: EE = $0
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
func ugly(_ a: A<EE>) {
|
||||
a.map { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{none}}
|
||||
a.map { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{none}}
|
||||
switch $0 {
|
||||
case .A:
|
||||
return 1
|
||||
|
||||
@@ -128,7 +128,7 @@ foo(b:
|
||||
// CHECK: [[#LINE-1]] |
|
||||
// CHECK: [[#LINE]] | let x = { () -> Result in
|
||||
// CHECK: | +++++++++++++++++
|
||||
// CHECK: | ^ error: unable to infer complex closure return type; add explicit type to disambiguate
|
||||
// CHECK: | ^ error: cannot infer return type for closure with multiple statements; add explicit type to disambiguate
|
||||
// CHECK: [[#LINE+1]] | let y = 1
|
||||
|
||||
// CHECK: SOURCE_DIR{{[/\]+}}test{{[/\]+}}diagnostics{{[/\]+}}pretty-printed-diagnostics.swift:[[#LINE:]]:8
|
||||
@@ -152,7 +152,7 @@ foo(b:
|
||||
// CHECK: SOURCE_DIR{{[/\]+}}test{{[/\]+}}diagnostics{{[/\]+}}pretty-printed-diagnostics.swift:[[#LINE:]]:20
|
||||
// CHECK: [[#LINE-1]] |
|
||||
// CHECK: [[#LINE]] | let 👍👍👍 = {
|
||||
// CHECK: | --> error: unable to infer complex closure return type; add explicit type to disambiguate [insert ' () -> <#Result#> in ']
|
||||
// CHECK: | --> error: cannot infer return type for closure with multiple statements; add explicit type to disambiguate [insert ' () -> <#Result#> in ']
|
||||
// CHECK: [[#LINE+1]] | let y = 1
|
||||
|
||||
// CHECK: SOURCE_DIR{{[/\]+}}test{{[/\]+}}diagnostics{{[/\]+}}pretty-printed-diagnostics.swift:[[#LINE:]]:5
|
||||
|
||||
@@ -403,7 +403,7 @@ Void(0) // expected-error{{argument passed to call that takes no arguments}}
|
||||
_ = {0}
|
||||
|
||||
// <rdar://problem/22086634> "multi-statement closures require an explicit return type" should be an error not a note
|
||||
let samples = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }}
|
||||
let samples = { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }}
|
||||
if (i > 10) { return true }
|
||||
else { return false }
|
||||
}()
|
||||
@@ -485,7 +485,7 @@ func lvalueCapture<T>(c: GenericClass<T>) {
|
||||
}
|
||||
|
||||
// Don't expose @lvalue-ness in diagnostics.
|
||||
let closure = { // expected-error {{unable to infer complex closure return type; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }}
|
||||
let closure = { // expected-error {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}} {{16-16= () -> <#Result#> in }}
|
||||
var helper = true
|
||||
return helper
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ let doubler = {
|
||||
If a closure body is not a single expression, it will not be considered when inferring the closure type. This is consistent with how type inference works in other parts of the language, where it proceeds one statement at a time. For example, in the following code an error will be reported because the type of `evenDoubler` cannot be inferred from its surrounding context and no signature was provided:
|
||||
|
||||
```swift
|
||||
// error: unable to infer complex closure return type; add explicit type to disambiguate
|
||||
// error: cannot infer return type for closure with multiple statements; add explicit type to disambiguate
|
||||
let evenDoubler = { x in
|
||||
if x.isMultiple(of: 2) {
|
||||
return x * 2
|
||||
|
||||
@@ -43,4 +43,4 @@ struct X { var y: Int = 0 }
|
||||
var x = X()
|
||||
x ~> \X.y ≈> { a in a += 1; return 3 }
|
||||
// expected-error@-1 {{referencing operator function '~>' on 'P' requires that 'M<WritableKeyPath<X, Int>, R>' conform to 'P'}}
|
||||
// expected-error@-2 {{unable to infer complex closure return type; add explicit type to disambiguate}}
|
||||
// expected-error@-2 {{cannot infer return type for closure with multiple statements; add explicit type to disambiguate}}
|
||||
|
||||
Reference in New Issue
Block a user