Skip to content

Commit 46aef0e

Browse files
authored
Rollup merge of #81990 - matsujika:suggest-mut-reference, r=estebank
Make suggestion of changing mutability of arguments broader Fix #81421 Previously rustc tries to emit the suggestion of changing mutablity unless `!trait_ref.has_infer_types_or_consts() && self.predicate_can_apply(obligation.param_env, trait_ref)` and this led to some false negatives to occur.
2 parents 459dda9 + e03f097 commit 46aef0e

File tree

3 files changed

+71
-16
lines changed

3 files changed

+71
-16
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+15-16
Original file line numberDiff line numberDiff line change
@@ -468,22 +468,21 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
468468
trait_ref,
469469
obligation.cause.body_id,
470470
);
471-
} else {
472-
if !have_alt_message {
473-
// Can't show anything else useful, try to find similar impls.
474-
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
475-
self.report_similar_impl_candidates(impl_candidates, &mut err);
476-
}
477-
// Changing mutability doesn't make a difference to whether we have
478-
// an `Unsize` impl (Fixes ICE in #71036)
479-
if !is_unsize {
480-
self.suggest_change_mut(
481-
&obligation,
482-
&mut err,
483-
trait_ref,
484-
points_at_arg,
485-
);
486-
}
471+
} else if !have_alt_message {
472+
// Can't show anything else useful, try to find similar impls.
473+
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
474+
self.report_similar_impl_candidates(impl_candidates, &mut err);
475+
}
476+
477+
// Changing mutability doesn't make a difference to whether we have
478+
// an `Unsize` impl (Fixes ICE in #71036)
479+
if !is_unsize {
480+
self.suggest_change_mut(
481+
&obligation,
482+
&mut err,
483+
trait_ref,
484+
points_at_arg,
485+
);
487486
}
488487

489488
// If this error is due to `!: Trait` not implemented but `(): Trait` is
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#![allow(warnings)]
2+
3+
use std::io::{BufRead, BufReader, Read, Write};
4+
5+
fn issue_81421<T: Read + Write>(mut stream: T) {
6+
let initial_message = format!("Hello world");
7+
let mut buffer: Vec<u8> = Vec::new();
8+
let bytes_written = stream.write_all(initial_message.as_bytes());
9+
let flush = stream.flush();
10+
11+
loop {
12+
let mut stream_reader = BufReader::new(&stream);
13+
//~^ ERROR the trait bound `&T: std::io::Read` is not satisfied [E0277]
14+
//~| HELP consider removing the leading `&`-reference
15+
//~| HELP consider changing this borrow's mutability
16+
stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
17+
//~^ ERROR the method `read_until` exists for struct `BufReader<&T>`,
18+
}
19+
}
20+
21+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
error[E0277]: the trait bound `&T: std::io::Read` is not satisfied
2+
--> $DIR/suggest-change-mut.rs:12:48
3+
|
4+
LL | let mut stream_reader = BufReader::new(&stream);
5+
| ^^^^^^^ the trait `std::io::Read` is not implemented for `&T`
6+
|
7+
= note: required by `BufReader::<R>::new`
8+
help: consider removing the leading `&`-reference
9+
|
10+
LL | let mut stream_reader = BufReader::new(stream);
11+
| --
12+
help: consider changing this borrow's mutability
13+
|
14+
LL | let mut stream_reader = BufReader::new(&mut stream);
15+
| ^^^^
16+
17+
error[E0599]: the method `read_until` exists for struct `BufReader<&T>`, but its trait bounds were not satisfied
18+
--> $DIR/suggest-change-mut.rs:16:23
19+
|
20+
LL | stream_reader.read_until(b'\n', &mut buffer).expect("Reading into buffer failed");
21+
| ^^^^^^^^^^ method cannot be called on `BufReader<&T>` due to unsatisfied trait bounds
22+
|
23+
::: $SRC_DIR/std/src/io/buffered/bufreader.rs:LL:COL
24+
|
25+
LL | pub struct BufReader<R> {
26+
| ----------------------- doesn't satisfy `BufReader<&T>: BufRead`
27+
|
28+
= note: the following trait bounds were not satisfied:
29+
`&T: std::io::Read`
30+
which is required by `BufReader<&T>: BufRead`
31+
32+
error: aborting due to 2 previous errors
33+
34+
Some errors have detailed explanations: E0277, E0599.
35+
For more information about an error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)