[SR-14824] Improve diagnostic for multi-statement closures instead of saying "too complex closure return type"

This commit is contained in:
jiaren wang
2021-06-30 11:18:19 +08:00
parent 340c85503e
commit c5de1f0800
9 changed files with 17 additions and 18 deletions

View File

@@ -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))

View File

@@ -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 "

View File

@@ -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"
}

View File

@@ -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
})

View File

@@ -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

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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}}