Merge pull request #16059 from AnthonyLatsis/unused-result-closure-warning

[DiagnosticsSema] SR-5983
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index ec01394..9c6c449 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -2909,7 +2909,7 @@
 WARNING(expression_unused_result_operator,none,
         "result of operator %0 is unused", (DeclName))
 WARNING(expression_unused_result_unknown, none,
-        "result of call is unused, but produces %0", (Type))
+        "result of call to %select{function|closure}0 returning %1 is unused", (bool, Type))
 WARNING(expression_unused_result, none,
         "expression of type %0 is unused", (Type))
 WARNING(expression_unused_init_result,none,
diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp
index 0ed25a7..6e34e24 100644
--- a/lib/Sema/TypeCheckStmt.cpp
+++ b/lib/Sema/TypeCheckStmt.cpp
@@ -1322,7 +1322,7 @@
         .highlight(SR1).highlight(SR2);
     } else
       diagnose(fn->getLoc(), diag::expression_unused_result_unknown,
-               valueE->getType())
+               isa<ClosureExpr>(fn), valueE->getType())
         .highlight(SR1).highlight(SR2);
 
     return;
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 5e1d0e6..cd1a7cb 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -215,7 +215,7 @@
 
 func testId(_ x: AnyObject) {
   x.perform!("foo:", with: x) // expected-warning{{no method declared with Objective-C selector 'foo:'}}
-  // expected-warning @-1 {{result of call is unused, but produces 'Unmanaged<AnyObject>?'}}
+  // expected-warning @-1 {{result of call to function returning 'Unmanaged<AnyObject>?' is unused}}
 
   _ = x.performAdd(1, withValue: 2, withValue: 3, withValue2: 4)
   _ = x.performAdd!(1, withValue: 2, withValue: 3, withValue2: 4)
diff --git a/test/Constraints/diagnostics.swift b/test/Constraints/diagnostics.swift
index 6701990..a3a4645 100644
--- a/test/Constraints/diagnostics.swift
+++ b/test/Constraints/diagnostics.swift
@@ -335,7 +335,7 @@
 
 let f8 = f7(2)
 _ = f8(1)
-f8(10)          // expected-warning {{result of call is unused, but produces 'Int'}}
+f8(10)          // expected-warning {{result of call to function returning 'Int' is unused}}
 f8(1.0)         // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}}
 f8(b: 1.0)         // expected-error {{extraneous argument label 'b:' in call}}
 
diff --git a/test/Constraints/dynamic_lookup.swift b/test/Constraints/dynamic_lookup.swift
index ec38785..70b789a 100644
--- a/test/Constraints/dynamic_lookup.swift
+++ b/test/Constraints/dynamic_lookup.swift
@@ -117,7 +117,7 @@
 obj.foo!("hello")
 obj.wibble!()
 obj.wobble!() // expected-error{{value of type 'Id' (aka 'AnyObject') has no member 'wobble'}}
-obj.ext1!()  // expected-warning {{result of call is unused}}
+obj.ext1!()  // expected-warning {{result of call to function returning 'A' is unused}}
 obj.wonka!()
 
 // Same as above but without the '!'
@@ -126,7 +126,7 @@
 obj.foo("hello")
 obj.wibble()
 obj.wobble() // expected-error{{value of type 'Id' (aka 'AnyObject') has no member 'wobble'}}
-obj.ext1()  // expected-warning {{result of call is unused}}
+obj.ext1()  // expected-warning {{result of call to function returning 'A' is unused}}
 obj.wonka()
 
 // Find class methods via dynamic method lookup.
@@ -144,7 +144,7 @@
 ovl1Result = A() // verify that we got an A, not a B
 
 // Same as above but without the '!'
-obj.ovl1()  // expected-warning {{result of call is unused}}
+obj.ovl1()  // expected-warning {{result of call to function returning 'A' is unused}}
 
 // Don't allow overload resolution between declarations from different
 // classes.
@@ -163,7 +163,7 @@
 var ovl5Result = obj.ovl5!() // expected-error{{ambiguous use of 'ovl5()'}}
 
 // Same as above but without the '!'
-obj.ovl4()  // expected-warning {{result of call is unused}}
+obj.ovl4()  // expected-warning {{result of call to function returning 'B' is unused}}
 
 // Generics
 
diff --git a/test/Parse/recovery.swift b/test/Parse/recovery.swift
index 48c3707..9543bae 100644
--- a/test/Parse/recovery.swift
+++ b/test/Parse/recovery.swift
@@ -128,7 +128,7 @@
   }
 
   repeat {
-  } while { true }() // expected-error{{missing condition in a 'while' statement}} expected-error{{consecutive statements on a line must be separated by ';'}} {{10-10=;}} expected-warning {{result of call is unused, but produces 'Bool'}}
+  } while { true }() // expected-error{{missing condition in a 'while' statement}} expected-error{{consecutive statements on a line must be separated by ';'}} {{10-10=;}} expected-warning {{result of call to closure returning 'Bool' is unused}}
 }
 
 // SR-165
diff --git a/test/Parse/toplevel_library_invalid.swift b/test/Parse/toplevel_library_invalid.swift
index 422e89d..7b2eb68 100644
--- a/test/Parse/toplevel_library_invalid.swift
+++ b/test/Parse/toplevel_library_invalid.swift
@@ -7,7 +7,7 @@
 // Make sure we don't crash on closures at the top level
 ({ }) // expected-error {{expressions are not allowed at the top level}} expected-error{{expression resolves to an unused function}}
 ({ 5 }()) // expected-error {{expressions are not allowed at the top level}}
-// expected-warning @-1 {{result of call is unused}}
+// expected-warning @-1 {{result of call to closure returning 'Int' is unused}}
 
 
 // expected-error @+3 {{expected 'in' after for-each pattern}}
diff --git a/test/Parse/try.swift b/test/Parse/try.swift
index 895a3f4..df5c0ce 100644
--- a/test/Parse/try.swift
+++ b/test/Parse/try.swift
@@ -151,7 +151,7 @@
 
 // <rdar://problem/21427855> Swift 2: Omitting try from call to throwing closure in rethrowing function crashes compiler
 func callThrowingClosureWithoutTry(closure: (Int) throws -> Int) rethrows {
-  closure(0)  // expected-error {{call can throw but is not marked with 'try'}} expected-warning {{result of call is unused}}
+  closure(0)  // expected-error {{call can throw but is not marked with 'try'}} expected-warning {{result of call to function returning 'Int' is unused}}
               // expected-note@-1 {{did you mean to use 'try'?}} {{3-3=try }}
               // expected-note@-2 {{did you mean to handle error as optional value?}} {{3-3=try? }}
               // expected-note@-3 {{did you mean to disable error propagation?}} {{3-3=try! }}
diff --git a/test/attr/attr_discardableResult.swift b/test/attr/attr_discardableResult.swift
index e78cef0..294bc80 100644
--- a/test/attr/attr_discardableResult.swift
+++ b/test/attr/attr_discardableResult.swift
@@ -149,7 +149,7 @@
   42  // expected-warning {{integer literal is unused}}
   
   4 + 5 // expected-warning {{result of operator '+' is unused}}
-  a() // expected-warning {{result of call is unused, but produces 'Int'}}
+  a() // expected-warning {{result of call to function returning 'Int' is unused}}
 }
 
 @warn_unused_result func g() -> Int { } // expected-warning {{'warn_unused_result' attribute behavior is now the default}} {{1-21=}}
diff --git a/test/decl/ext/protocol_objc.swift b/test/decl/ext/protocol_objc.swift
index 806a8dc..af6e3a0 100644
--- a/test/decl/ext/protocol_objc.swift
+++ b/test/decl/ext/protocol_objc.swift
@@ -16,7 +16,7 @@
 
 func testOP1(_ oc1: OC1, ao: AnyObject) {
   _ = oc1.extOP1a()
-  // expected-warning @+1 {{result of call is unused}}
+  // expected-warning @+1 {{result of call to function returning 'Bool' is unused}}
   ao.reqOP1a!() // okay
 
   // Extension of @objc protocol does not have @objc members.
diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift
index 38300df..0f5cb1f 100644
--- a/test/expr/expressions.swift
+++ b/test/expr/expressions.swift
@@ -258,7 +258,7 @@
   { () -> protocol<Int> in
     // expected-warning @-1 {{'protocol<...>' composition syntax is deprecated and not needed here}} {{11-24=Int}}
     // expected-error @-2 {{non-protocol, non-class type 'Int' cannot be used within a protocol-constrained type}}
-    // expected-warning @-3 {{result of call is unused}}
+    // expected-warning @-3 {{result of call to closure returning 'Any' is unused}}
     return 1
   }()
 }
@@ -669,7 +669,7 @@
 
   var n = 42
   fn(n, 12)  // expected-error {{passing value of type 'Int' to an inout parameter requires explicit '&'}} {{6-6=&}}
-  fn(&n, 12) // expected-warning {{result of call is unused, but produces 'Int'}}
+  fn(&n, 12) // expected-warning {{result of call to function returning 'Int' is unused}}
 
   n +-+= 12