From 03cce1d81ea17639167681c42ae1afa4c67a2fd2 Mon Sep 17 00:00:00 2001
From: Jad Ghalayini <jad.ghalayini@hotmail.com>
Date: Sun, 26 May 2019 16:48:02 -0400
Subject: [PATCH 1/2] Added error message for E0284

---
 src/librustc/error_codes.rs | 47 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index a1bfd417566..ef4d13096ba 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1207,6 +1207,52 @@ fn main() {
 ```
 "##,
 
+E0284: r##"
+This error occurs when the compiler is unable to unambiguously infer the
+return type of a function or method which is generic on return type, such
+as the `collect` method for `Iterator`s.
+
+For example:
+
+```compile_fail,E0284
+fn foo() -> Result<bool, ()> {
+    let results = [Ok(true), Ok(false), Err(())].iter().cloned();
+    let v : Vec<bool> = results.collect()?;
+    // Do things with v...
+    Ok(true)
+}
+```
+
+Here we have an iterator `results` over `Result<bool, ()>`.
+Hence, `results.collect()` can return any type implementing
+`FromIterator<Result<bool, ()>>`. On the other hand, the
+`?` operator can accept any type implementing `Try`.
+
+The user of this code probably wants `collect()` to return a
+`Result<Vec<bool>, ()>`, but the compiler can't be sure
+that there isn't another type `T` implementing both `Try` and
+`FromIterator<Result<bool, ()>>` in scope such that
+`T::Ok == Vec<bool>`. Hence, this code is ambiguous and an error
+is returned.
+
+To resolve this error, use a concrete type for the intermediate expression:
+
+```
+fn foo() -> Result<bool, ()> {
+    let results = [Ok(true), Ok(false), Err(())].iter().cloned();
+    let v = {
+        let temp : Result<Vec<bool>, ()> = results.collect();
+        temp?
+    };
+    // Do things with v...
+    Ok(true)
+}
+```
+Note that the type of `v` can now be inferred from the type of `temp`
+
+
+"##,
+
 E0308: r##"
 This error occurs when the compiler was unable to infer the concrete type of a
 variable. It can occur for several cases, the most common of which is a
@@ -2158,7 +2204,6 @@ register_diagnostics! {
     E0278, // requirement is not satisfied
     E0279, // requirement is not satisfied
     E0280, // requirement is not satisfied
-    E0284, // cannot resolve type
 //  E0285, // overflow evaluation builtin bounds
 //  E0296, // replaced with a generic attribute input check
 //  E0300, // unexpanded macro

From b3480126d4acbd197836089257e9a4c751a78f5b Mon Sep 17 00:00:00 2001
From: Jad Ghalayini <jad.ghalayini@hotmail.com>
Date: Mon, 27 May 2019 19:37:20 -0400
Subject: [PATCH 2/2] Incorporated suggested changes

---
 src/librustc/error_codes.rs                              | 9 ++++-----
 .../associated-types-overridden-binding.stderr           | 1 +
 .../associated-types-unconstrained.stderr                | 1 +
 src/test/ui/issues/issue-12028.stderr                    | 1 +
 src/test/ui/question-mark-type-infer.stderr              | 1 +
 5 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index ef4d13096ba..6243e911bd5 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1217,7 +1217,7 @@ For example:
 ```compile_fail,E0284
 fn foo() -> Result<bool, ()> {
     let results = [Ok(true), Ok(false), Err(())].iter().cloned();
-    let v : Vec<bool> = results.collect()?;
+    let v: Vec<bool> = results.collect()?;
     // Do things with v...
     Ok(true)
 }
@@ -1228,7 +1228,7 @@ Hence, `results.collect()` can return any type implementing
 `FromIterator<Result<bool, ()>>`. On the other hand, the
 `?` operator can accept any type implementing `Try`.
 
-The user of this code probably wants `collect()` to return a
+The author of this code probably wants `collect()` to return a
 `Result<Vec<bool>, ()>`, but the compiler can't be sure
 that there isn't another type `T` implementing both `Try` and
 `FromIterator<Result<bool, ()>>` in scope such that
@@ -1241,16 +1241,15 @@ To resolve this error, use a concrete type for the intermediate expression:
 fn foo() -> Result<bool, ()> {
     let results = [Ok(true), Ok(false), Err(())].iter().cloned();
     let v = {
-        let temp : Result<Vec<bool>, ()> = results.collect();
+        let temp: Result<Vec<bool>, ()> = results.collect();
         temp?
     };
     // Do things with v...
     Ok(true)
 }
 ```
-Note that the type of `v` can now be inferred from the type of `temp`
-
 
+Note that the type of `v` can now be inferred from the type of `temp`.
 "##,
 
 E0308: r##"
diff --git a/src/test/ui/associated-types/associated-types-overridden-binding.stderr b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
index fced38caaba..a26ee23894f 100644
--- a/src/test/ui/associated-types/associated-types-overridden-binding.stderr
+++ b/src/test/ui/associated-types/associated-types-overridden-binding.stderr
@@ -12,3 +12,4 @@ LL | trait Foo: Iterator<Item = i32> {}
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/associated-types/associated-types-unconstrained.stderr b/src/test/ui/associated-types/associated-types-unconstrained.stderr
index 26e5a6a503c..da14a69ae30 100644
--- a/src/test/ui/associated-types/associated-types-unconstrained.stderr
+++ b/src/test/ui/associated-types/associated-types-unconstrained.stderr
@@ -6,3 +6,4 @@ LL |     let x: isize = Foo::bar();
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/issues/issue-12028.stderr b/src/test/ui/issues/issue-12028.stderr
index b9e2e80492b..64694c7a8d0 100644
--- a/src/test/ui/issues/issue-12028.stderr
+++ b/src/test/ui/issues/issue-12028.stderr
@@ -6,3 +6,4 @@ LL |         self.input_stream(&mut stream);
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.
diff --git a/src/test/ui/question-mark-type-infer.stderr b/src/test/ui/question-mark-type-infer.stderr
index 2a1bdf57a88..f62a540572c 100644
--- a/src/test/ui/question-mark-type-infer.stderr
+++ b/src/test/ui/question-mark-type-infer.stderr
@@ -6,3 +6,4 @@ LL |     l.iter().map(f).collect()?
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0284`.