if let Ok(src) = self.tcx.sess.source_map().span_to_snippet(span) {
// Don't care about `&mut` because `DerefMut` is used less
// often and user will not expect autoderef happens.
- if src.starts_with("&") {
+ if src.starts_with("&") && !src.starts_with("&mut ") {
let derefs = "*".repeat(steps);
err.span_suggestion(
span,
--- /dev/null
+// run-rustfix
+use std::ops::Deref;
+
+trait Happy {}
+struct LDM;
+impl Happy for &LDM {}
+
+struct Foo(LDM);
+struct Bar(Foo);
+struct Baz(Bar);
+impl Deref for Foo {
+ type Target = LDM;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Bar {
+ type Target = Foo;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Baz {
+ type Target = Bar;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+fn foo<T>(_: T) where T: Happy {}
+
+fn main() {
+ let baz = Baz(Bar(Foo(LDM)));
+ foo(&***baz);
+ //~^ ERROR the trait bound `&Baz: Happy` is not satisfied
+}
--- /dev/null
+// run-rustfix
+use std::ops::Deref;
+
+trait Happy {}
+struct LDM;
+impl Happy for &LDM {}
+
+struct Foo(LDM);
+struct Bar(Foo);
+struct Baz(Bar);
+impl Deref for Foo {
+ type Target = LDM;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Bar {
+ type Target = Foo;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Baz {
+ type Target = Bar;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+
+fn foo<T>(_: T) where T: Happy {}
+
+fn main() {
+ let baz = Baz(Bar(Foo(LDM)));
+ foo(&baz);
+ //~^ ERROR the trait bound `&Baz: Happy` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `&Baz: Happy` is not satisfied
+ --> $DIR/trait-suggest-deferences-multiple-0.rs:34:9
+ |
+LL | fn foo<T>(_: T) where T: Happy {}
+ | ----- required by this bound in `foo`
+...
+LL | foo(&baz);
+ | ^^^^
+ | |
+ | the trait `Happy` is not implemented for `&Baz`
+ | help: consider adding dereference here: `&***baz`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
--- /dev/null
+use std::ops::{Deref, DerefMut};
+
+trait Happy {}
+struct LDM;
+impl Happy for &mut LDM {}
+
+struct Foo(LDM);
+struct Bar(Foo);
+struct Baz(Bar);
+impl Deref for Foo {
+ type Target = LDM;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Bar {
+ type Target = Foo;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl Deref for Baz {
+ type Target = Bar;
+ fn deref(&self) -> &Self::Target {
+ &self.0
+ }
+}
+impl DerefMut for Foo {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+impl DerefMut for Bar {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+impl DerefMut for Baz {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.0
+ }
+}
+
+
+fn foo<T>(_: T) where T: Happy {}
+
+fn main() {
+ // Currently the compiler doesn't try to suggest dereferences for situations
+ // where DerefMut involves. So this test is meant to ensure compiler doesn't
+ // generate incorrect help message.
+ let mut baz = Baz(Bar(Foo(LDM)));
+ foo(&mut baz);
+ //~^ ERROR the trait bound `&mut Baz: Happy` is not satisfied
+}
--- /dev/null
+error[E0277]: the trait bound `&mut Baz: Happy` is not satisfied
+ --> $DIR/trait-suggest-deferences-multiple-1.rs:52:9
+ |
+LL | fn foo<T>(_: T) where T: Happy {}
+ | ----- required by this bound in `foo`
+...
+LL | foo(&mut baz);
+ | ^^^^^^^^ the trait `Happy` is not implemented for `&mut Baz`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
+++ /dev/null
-// run-rustfix
-use std::ops::Deref;
-
-trait Happy {}
-struct LDM;
-impl Happy for &LDM {}
-
-struct Foo(LDM);
-struct Bar(Foo);
-struct Baz(Bar);
-impl Deref for Foo {
- type Target = LDM;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-impl Deref for Bar {
- type Target = Foo;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-impl Deref for Baz {
- type Target = Bar;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-fn foo<T>(_: T) where T: Happy {}
-
-fn main() {
- let baz = Baz(Bar(Foo(LDM)));
- foo(&***baz);
- //~^ ERROR the trait bound `&Baz: Happy` is not satisfied
-}
+++ /dev/null
-// run-rustfix
-use std::ops::Deref;
-
-trait Happy {}
-struct LDM;
-impl Happy for &LDM {}
-
-struct Foo(LDM);
-struct Bar(Foo);
-struct Baz(Bar);
-impl Deref for Foo {
- type Target = LDM;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-impl Deref for Bar {
- type Target = Foo;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-impl Deref for Baz {
- type Target = Bar;
- fn deref(&self) -> &Self::Target {
- &self.0
- }
-}
-
-fn foo<T>(_: T) where T: Happy {}
-
-fn main() {
- let baz = Baz(Bar(Foo(LDM)));
- foo(&baz);
- //~^ ERROR the trait bound `&Baz: Happy` is not satisfied
-}
+++ /dev/null
-error[E0277]: the trait bound `&Baz: Happy` is not satisfied
- --> $DIR/trait-suggest-deferences-multiple.rs:34:9
- |
-LL | fn foo<T>(_: T) where T: Happy {}
- | ----- required by this bound in `foo`
-...
-LL | foo(&baz);
- | ^^^^
- | |
- | the trait `Happy` is not implemented for `&Baz`
- | help: consider adding dereference here: `&***baz`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.