about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/method/mod.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs8
-rw-r--r--tests/ui/use/unused-trait-with-method-err.rs17
-rw-r--r--tests/ui/use/unused-trait-with-method-err.stderr19
4 files changed, 46 insertions, 0 deletions
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`.