about summary refs log tree commit diff
diff options
context:
space:
mode:
authorHirochika Matsumoto <matsujika@gmail.com>2021-02-11 15:13:06 +0900
committerHirochika Matsumoto <matsujika@gmail.com>2021-02-11 17:03:03 +0900
commite03f09730faab8083f991827f0cd02040d171d4e (patch)
tree116479091be5f28bd9573450ba7361a25b22484c
parent9ce7268bcfc17265bd05e4c08713d170d39618ad (diff)
downloadrust-e03f09730faab8083f991827f0cd02040d171d4e.tar.gz
rust-e03f09730faab8083f991827f0cd02040d171d4e.zip
Make suggestion of changing mutability of arguments broader
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs31
-rw-r--r--src/test/ui/suggestions/suggest-change-mut.rs21
-rw-r--r--src/test/ui/suggestions/suggest-change-mut.stderr35
3 files changed, 71 insertions, 16 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 756281450d7..3233d1e048b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -468,22 +468,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                 trait_ref,
                                 obligation.cause.body_id,
                             );
-                        } else {
-                            if !have_alt_message {
-                                // Can't show anything else useful, try to find similar impls.
-                                let impl_candidates = self.find_similar_impl_candidates(trait_ref);
-                                self.report_similar_impl_candidates(impl_candidates, &mut err);
-                            }
-                            // Changing mutability doesn't make a difference to whether we have
-                            // an `Unsize` impl (Fixes ICE in #71036)
-                            if !is_unsize {
-                                self.suggest_change_mut(
-                                    &obligation,
-                                    &mut err,
-                                    trait_ref,
-                                    points_at_arg,
-                                );
-                            }
+                        } else if !have_alt_message {
+                            // Can't show anything else useful, try to find similar impls.
+                            let impl_candidates = self.find_similar_impl_candidates(trait_ref);
+                            self.report_similar_impl_candidates(impl_candidates, &mut err);
+                        }
+
+                        // Changing mutability doesn't make a difference to whether we have
+                        // an `Unsize` impl (Fixes ICE in #71036)
+                        if !is_unsize {
+                            self.suggest_change_mut(
+                                &obligation,
+                                &mut err,
+                                trait_ref,
+                                points_at_arg,
+                            );
                         }
 
                         // If this error is due to `!: Trait` not implemented but `(): Trait` is
diff --git a/src/test/ui/suggestions/suggest-change-mut.rs b/src/test/ui/suggestions/suggest-change-mut.rs
new file mode 100644
index 00000000000..8b465aae66b
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-change-mut.rs
@@ -0,0 +1,21 @@
+#![allow(warnings)]
+
+use std::io::{BufRead, BufReader, Read, Write};
+
+fn issue_81421<T: Read + Write>(mut stream: T) {
+    let initial_message = format!("Hello world");
+    let mut buffer: Vec<u8> = Vec::new();
+    let bytes_written = stream.write_all(initial_message.as_bytes());
+    let flush = stream.flush();
+
+    loop {
+        let mut stream_reader = BufReader::new(&stream);
+        //~^ ERROR the trait bound `&T: std::io::Read` is not satisfied [E0277]
+        //~| HELP consider removing the leading `&`-reference
+        //~| HELP consider changing this borrow's mutability
+        stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
+        //~^ ERROR the method `read_until` exists for struct `BufReader<&T>`,
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/suggest-change-mut.stderr b/src/test/ui/suggestions/suggest-change-mut.stderr
new file mode 100644
index 00000000000..cb156f7c787
--- /dev/null
+++ b/src/test/ui/suggestions/suggest-change-mut.stderr
@@ -0,0 +1,35 @@
+error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
+  --> $DIR/suggest-change-mut.rs:12:48
+   |
+LL |         let mut stream_reader = BufReader::new(&stream);
+   |                                                ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
+   |
+   = note: required by `BufReader::<R>::new`
+help: consider removing the leading `&`-reference
+   |
+LL |         let mut stream_reader = BufReader::new(stream);
+   |                                               --
+help: consider changing this borrow's mutability
+   |
+LL |         let mut stream_reader = BufReader::new(&mut stream);
+   |                                                ^^^^
+
+error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its trait bounds were not satisfied
+  --> $DIR/suggest-change-mut.rs:16:23
+   |
+LL |         stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
+   |                       ^^^^^^^^^^ method cannot be called on `BufReader<&T>` due to unsatisfied trait bounds
+   | 
+  ::: $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
+   |
+LL | pub struct BufReader<R> {
+   | ----------------------- doesn't satisfy `BufReader<&T>: BufRead`
+   |
+   = note: the following trait bounds were not satisfied:
+           `&T: std::io::Read`
+           which is required by `BufReader<&T>: BufRead`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.