Skip to content

Commit

Permalink
Suppress import errors for traits that couldve applied in method look…
Browse files Browse the repository at this point in the history
…up on error
  • Loading branch information
compiler-errors committed Oct 14, 2024
1 parent f6648f2 commit c3b696d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 0 deletions.
2 changes: 2 additions & 0 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, _),
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/use/unused-trait-with-method-err.rs
Original file line number Diff line number Diff line change
@@ -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
}
19 changes: 19 additions & 0 deletions tests/ui/use/unused-trait-with-method-err.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit c3b696d

Please sign in to comment.