From 1e89b583c3bcf1757f57250a089450165e886049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 1 May 2021 17:18:04 -0700 Subject: [PATCH] Account for unsatisfied bounds in E0599 Fix #84769, follow up to #84499, #83667. --- .../rustc_typeck/src/check/method/suggest.rs | 6 +++++- .../import-trait-for-method-call.rs | 9 ++++++++- .../import-trait-for-method-call.stderr | 18 +++++++++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 73e35f0171aa7..b2e4e7a981d20 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -579,6 +579,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut restrict_type_params = false; + let mut unsatisfied_bounds = false; if !unsatisfied_predicates.is_empty() { let def_span = |def_id| { self.tcx.sess.source_map().guess_head_span(self.tcx.def_span(def_id)) @@ -739,6 +740,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note(&format!( "the following trait bounds were not satisfied:\n{bound_list}" )); + unsatisfied_bounds = true; } } @@ -752,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source, out_of_scope_traits, &unsatisfied_predicates, + unsatisfied_bounds, ); } @@ -984,9 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'tcx>, valid_out_of_scope_traits: Vec, unsatisfied_predicates: &[(ty::Predicate<'tcx>, Option>)], + unsatisfied_bounds: bool, ) { let mut alt_rcvr_sugg = false; - if let SelfSource::MethodCall(rcvr) = source { + if let (SelfSource::MethodCall(rcvr), false) = (source, unsatisfied_bounds) { debug!(?span, ?item_name, ?rcvr_ty, ?rcvr); let skippable = [ self.tcx.lang_items().clone_trait(), diff --git a/src/test/ui/suggestions/import-trait-for-method-call.rs b/src/test/ui/suggestions/import-trait-for-method-call.rs index 646f68dea14e8..4dbadbdf98206 100644 --- a/src/test/ui/suggestions/import-trait-for-method-call.rs +++ b/src/test/ui/suggestions/import-trait-for-method-call.rs @@ -6,4 +6,11 @@ fn next_u64() -> u64 { h.finish() //~ ERROR no method named `finish` found for struct `DefaultHasher` } -fn main() {} +trait Bar {} +impl Bar for String {} + +fn main() { + let s = String::from("hey"); + let x: &dyn Bar = &s; + x.as_ref(); //~ ERROR the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds +} diff --git a/src/test/ui/suggestions/import-trait-for-method-call.stderr b/src/test/ui/suggestions/import-trait-for-method-call.stderr index f3ae20552f3d5..a2b9b9d14ab09 100644 --- a/src/test/ui/suggestions/import-trait-for-method-call.stderr +++ b/src/test/ui/suggestions/import-trait-for-method-call.stderr @@ -15,6 +15,22 @@ help: the following trait is implemented but not in scope; perhaps add a `use` f LL | use std::hash::Hasher; | -error: aborting due to previous error +error[E0599]: the method `as_ref` exists for reference `&dyn Bar`, but its trait bounds were not satisfied + --> $DIR/import-trait-for-method-call.rs:15:7 + | +LL | trait Bar {} + | --------- doesn't satisfy `dyn Bar: AsRef<_>` +... +LL | x.as_ref(); + | ^^^^^^ method cannot be called on `&dyn Bar` due to unsatisfied trait bounds + | + = note: the following trait bounds were not satisfied: + `dyn Bar: AsRef<_>` + which is required by `&dyn Bar: AsRef<_>` + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `as_ref`, perhaps you need to implement it: + candidate #1: `AsRef` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0599`.