Skip to content

Commit f1e0710

Browse files
committed
Prevent incorrect help message for dereference suggestion
1 parent ef68bf3 commit f1e0710

6 files changed

+68
-2
lines changed

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
500500
if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
501501
// Don't care about `&mut` because `DerefMut` is used less
502502
// often and user will not expect autoderef happens.
503-
if src.starts_with("&") {
503+
if src.starts_with("&") && !src.starts_with("&mut ") {
504504
let derefs = "*".repeat(steps);
505505
err.span_suggestion(
506506
span,

src/test/ui/traits/trait-suggest-deferences-multiple.stderr renamed to src/test/ui/traits/trait-suggest-deferences-multiple-0.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0277]: the trait bound `&Baz: Happy` is not satisfied
2-
--> $DIR/trait-suggest-deferences-multiple.rs:34:9
2+
--> $DIR/trait-suggest-deferences-multiple-0.rs:34:9
33
|
44
LL | fn foo<T>(_: T) where T: Happy {}
55
| ----- required by this bound in `foo`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
use std::ops::{Deref, DerefMut};
2+
3+
trait Happy {}
4+
struct LDM;
5+
impl Happy for &mut LDM {}
6+
7+
struct Foo(LDM);
8+
struct Bar(Foo);
9+
struct Baz(Bar);
10+
impl Deref for Foo {
11+
type Target = LDM;
12+
fn deref(&self) -> &Self::Target {
13+
&self.0
14+
}
15+
}
16+
impl Deref for Bar {
17+
type Target = Foo;
18+
fn deref(&self) -> &Self::Target {
19+
&self.0
20+
}
21+
}
22+
impl Deref for Baz {
23+
type Target = Bar;
24+
fn deref(&self) -> &Self::Target {
25+
&self.0
26+
}
27+
}
28+
impl DerefMut for Foo {
29+
fn deref_mut(&mut self) -> &mut Self::Target {
30+
&mut self.0
31+
}
32+
}
33+
impl DerefMut for Bar {
34+
fn deref_mut(&mut self) -> &mut Self::Target {
35+
&mut self.0
36+
}
37+
}
38+
impl DerefMut for Baz {
39+
fn deref_mut(&mut self) -> &mut Self::Target {
40+
&mut self.0
41+
}
42+
}
43+
44+
45+
fn foo<T>(_: T) where T: Happy {}
46+
47+
fn main() {
48+
// Currently the compiler doesn't try to suggest dereferences for situations
49+
// where DerefMut involves. So this test is meant to ensure compiler doesn't
50+
// generate incorrect help message.
51+
let mut baz = Baz(Bar(Foo(LDM)));
52+
foo(&mut baz);
53+
//~^ ERROR the trait bound `&mut Baz: Happy` is not satisfied
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0277]: the trait bound `&mut Baz: Happy` is not satisfied
2+
--> $DIR/trait-suggest-deferences-multiple-1.rs:52:9
3+
|
4+
LL | fn foo<T>(_: T) where T: Happy {}
5+
| ----- required by this bound in `foo`
6+
...
7+
LL | foo(&mut baz);
8+
| ^^^^^^^^ the trait `Happy` is not implemented for `&mut Baz`
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)