From f1e07103d3ebac4e820311254e077481d00bed49 Mon Sep 17 00:00:00 2001 From: Donough Liu Date: Sat, 20 Jun 2020 20:00:36 +0800 Subject: [PATCH] Prevent incorrect help message for dereference suggestion --- .../traits/error_reporting/suggestions.rs | 2 +- ...trait-suggest-deferences-multiple-0.fixed} | 0 ...=> trait-suggest-deferences-multiple-0.rs} | 0 ...rait-suggest-deferences-multiple-0.stderr} | 2 +- .../trait-suggest-deferences-multiple-1.rs | 54 +++++++++++++++++++ ...trait-suggest-deferences-multiple-1.stderr | 12 +++++ 6 files changed, 68 insertions(+), 2 deletions(-) rename src/test/ui/traits/{trait-suggest-deferences-multiple.fixed => trait-suggest-deferences-multiple-0.fixed} (100%) rename src/test/ui/traits/{trait-suggest-deferences-multiple.rs => trait-suggest-deferences-multiple-0.rs} (100%) rename src/test/ui/traits/{trait-suggest-deferences-multiple.stderr => trait-suggest-deferences-multiple-0.stderr} (89%) create mode 100644 src/test/ui/traits/trait-suggest-deferences-multiple-1.rs create mode 100644 src/test/ui/traits/trait-suggest-deferences-multiple-1.stderr diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 0c86e33884d6..176bd90303dd 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -500,7 +500,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { 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, diff --git a/src/test/ui/traits/trait-suggest-deferences-multiple.fixed b/src/test/ui/traits/trait-suggest-deferences-multiple-0.fixed similarity index 100% rename from src/test/ui/traits/trait-suggest-deferences-multiple.fixed rename to src/test/ui/traits/trait-suggest-deferences-multiple-0.fixed diff --git a/src/test/ui/traits/trait-suggest-deferences-multiple.rs b/src/test/ui/traits/trait-suggest-deferences-multiple-0.rs similarity index 100% rename from src/test/ui/traits/trait-suggest-deferences-multiple.rs rename to src/test/ui/traits/trait-suggest-deferences-multiple-0.rs diff --git a/src/test/ui/traits/trait-suggest-deferences-multiple.stderr b/src/test/ui/traits/trait-suggest-deferences-multiple-0.stderr similarity index 89% rename from src/test/ui/traits/trait-suggest-deferences-multiple.stderr rename to src/test/ui/traits/trait-suggest-deferences-multiple-0.stderr index f9b8bba4b412..add34a553bc9 100644 --- a/src/test/ui/traits/trait-suggest-deferences-multiple.stderr +++ b/src/test/ui/traits/trait-suggest-deferences-multiple-0.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `&Baz: Happy` is not satisfied - --> $DIR/trait-suggest-deferences-multiple.rs:34:9 + --> $DIR/trait-suggest-deferences-multiple-0.rs:34:9 | LL | fn foo(_: T) where T: Happy {} | ----- required by this bound in `foo` diff --git a/src/test/ui/traits/trait-suggest-deferences-multiple-1.rs b/src/test/ui/traits/trait-suggest-deferences-multiple-1.rs new file mode 100644 index 000000000000..91c6c7924a40 --- /dev/null +++ b/src/test/ui/traits/trait-suggest-deferences-multiple-1.rs @@ -0,0 +1,54 @@ +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) 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 +} diff --git a/src/test/ui/traits/trait-suggest-deferences-multiple-1.stderr b/src/test/ui/traits/trait-suggest-deferences-multiple-1.stderr new file mode 100644 index 000000000000..e90278fa16f0 --- /dev/null +++ b/src/test/ui/traits/trait-suggest-deferences-multiple-1.stderr @@ -0,0 +1,12 @@ +error[E0277]: the trait bound `&mut Baz: Happy` is not satisfied + --> $DIR/trait-suggest-deferences-multiple-1.rs:52:9 + | +LL | fn foo(_: 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`.