From c3b696dec99e7646b84d8b43c05a113acf7d249c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Oct 2024 14:40:07 -0400 Subject: [PATCH] Suppress import errors for traits that couldve applied in method lookup on error --- compiler/rustc_hir_typeck/src/method/mod.rs | 2 ++ .../rustc_hir_typeck/src/method/suggest.rs | 8 ++++++++ tests/ui/use/unused-trait-with-method-err.rs | 17 +++++++++++++++++ .../use/unused-trait-with-method-err.stderr | 19 +++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 tests/ui/use/unused-trait-with-method-err.rs create mode 100644 tests/ui/use/unused-trait-with-method-err.stderr diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index cb8b1df2c6e..1b65dc8214c 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -199,6 +199,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty, segment, span, call_expr, self_expr, &pick, args, ); + // NOTE: on the failure path, we also record the possibly-used trait methods + // since an unused import warning is kinda distracting from the method error. for &import_id in &pick.import_ids { debug!("used_trait_import: {:?}", import_id); self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 4f726f3ed38..05c8912aec1 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -191,6 +191,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected: Expectation<'tcx>, trait_missing_method: bool, ) -> ErrorGuaranteed { + // NOTE: Reporting a method error should also suppress any unused trait errors, + // since the method error is very possibly the reason why the trait wasn't used. + for &import_id in + self.tcx.in_scope_traits(call_id).into_iter().flatten().flat_map(|c| &c.import_ids) + { + self.typeck_results.borrow_mut().used_trait_imports.insert(import_id); + } + let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) { hir::Node::Expr(&hir::Expr { kind: hir::ExprKind::MethodCall(segment, rcvr, args, _), diff --git a/tests/ui/use/unused-trait-with-method-err.rs b/tests/ui/use/unused-trait-with-method-err.rs new file mode 100644 index 00000000000..37684e1bf81 --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.rs @@ -0,0 +1,17 @@ +// Test that we don't issue an unused import warning when there's +// a method lookup error and that trait was possibly applicable. + +use foo::Bar; + +mod foo { + pub trait Bar { + fn uwu(&self) {} + } +} + +struct Foo; + +fn main() { + Foo.uwu(); + //~^ ERROR no method named `uwu` found for struct `Foo` in the current scope +} diff --git a/tests/ui/use/unused-trait-with-method-err.stderr b/tests/ui/use/unused-trait-with-method-err.stderr new file mode 100644 index 00000000000..7ca4563673b --- /dev/null +++ b/tests/ui/use/unused-trait-with-method-err.stderr @@ -0,0 +1,19 @@ +error[E0599]: no method named `uwu` found for struct `Foo` in the current scope + --> $DIR/unused-trait-with-method-err.rs:15:9 + | +LL | struct Foo; + | ---------- method `uwu` not found for this struct +... +LL | Foo.uwu(); + | ^^^ method not found in `Foo` + | + = help: items from traits can only be used if the trait is implemented and in scope +note: `Bar` defines an item `uwu`, perhaps you need to implement it + --> $DIR/unused-trait-with-method-err.rs:7:5 + | +LL | pub trait Bar { + | ^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0599`.