Skip to content

Commit

Permalink
Rollup merge of #131024 - compiler-errors:deref-sugg, r=estebank
Browse files Browse the repository at this point in the history
Don't give method suggestions when method probe fails due to bad implementation of `Deref`

If we have a bad `Deref` impl, we used to bail with `MethodError::NoMatch`, which makes the error reporting code think that there was no applicable method (and thus try to suggest importing something, even if it's in scope).

Suppress this error, which fixes #131003.
  • Loading branch information
matthiaskrgr authored Oct 3, 2024
2 parents 56e35a5 + 486440f commit 0d65f12
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 31 deletions.
18 changes: 11 additions & 7 deletions compiler/rustc_hir_typeck/src/method/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use rustc_middle::ty::{
self, GenericArgs, GenericArgsRef, GenericParamDefKind, Ty, TypeVisitableExt,
};
use rustc_middle::{bug, span_bug};
use rustc_span::Span;
use rustc_span::symbol::Ident;
use rustc_span::{ErrorGuaranteed, Span};
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
use rustc_trait_selection::traits::{self, NormalizeExt};
use tracing::{debug, instrument};
Expand All @@ -46,26 +46,29 @@ pub(crate) struct MethodCallee<'tcx> {

#[derive(Debug)]
pub(crate) enum MethodError<'tcx> {
// Did not find an applicable method, but we did find various near-misses that may work.
/// Did not find an applicable method, but we did find various near-misses that may work.
NoMatch(NoMatchData<'tcx>),

// Multiple methods might apply.
/// Multiple methods might apply.
Ambiguity(Vec<CandidateSource>),

// Found an applicable method, but it is not visible. The third argument contains a list of
// not-in-scope traits which may work.
/// Found an applicable method, but it is not visible. The third argument contains a list of
/// not-in-scope traits which may work.
PrivateMatch(DefKind, DefId, Vec<DefId>),

// Found a `Self: Sized` bound where `Self` is a trait object.
/// Found a `Self: Sized` bound where `Self` is a trait object.
IllegalSizedBound {
candidates: Vec<DefId>,
needs_mut: bool,
bound_span: Span,
self_expr: &'tcx hir::Expr<'tcx>,
},

// Found a match, but the return type is wrong
/// Found a match, but the return type is wrong
BadReturnType,

/// Error has already been emitted, no need to emit another one.
ErrorReported(ErrorGuaranteed),
}

// Contains a list of static methods that may apply, a list of unsatisfied trait predicates which
Expand Down Expand Up @@ -120,6 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Err(PrivateMatch(..)) => false,
Err(IllegalSizedBound { .. }) => true,
Err(BadReturnType) => false,
Err(ErrorReported(_)) => false,
}
}

Expand Down
8 changes: 1 addition & 7 deletions compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -446,13 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
_ => bug!("unexpected bad final type in method autoderef"),
};
self.demand_eqtype(span, ty, Ty::new_error(self.tcx, guar));
return Err(MethodError::NoMatch(NoMatchData {
static_candidates: Vec::new(),
unsatisfied_predicates: Vec::new(),
out_of_scope_traits: Vec::new(),
similar_candidate: None,
mode,
}));
return Err(MethodError::ErrorReported(guar));
}
}

Expand Down
34 changes: 17 additions & 17 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,20 +229,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}

match error {
MethodError::NoMatch(mut no_match_data) => {
return self.report_no_match_method_error(
span,
rcvr_ty,
item_name,
call_id,
source,
args,
sugg_span,
&mut no_match_data,
expected,
trait_missing_method,
);
}
MethodError::NoMatch(mut no_match_data) => self.report_no_match_method_error(
span,
rcvr_ty,
item_name,
call_id,
source,
args,
sugg_span,
&mut no_match_data,
expected,
trait_missing_method,
),

MethodError::Ambiguity(mut sources) => {
let mut err = struct_span_code_err!(
Expand All @@ -263,7 +261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&mut sources,
Some(sugg_span),
);
return err.emit();
err.emit()
}

MethodError::PrivateMatch(kind, def_id, out_of_scope_traits) => {
Expand All @@ -284,7 +282,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or_else(|| self.tcx.def_span(def_id));
err.span_label(sp, format!("private {kind} defined here"));
self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
return err.emit();
err.emit()
}

MethodError::IllegalSizedBound { candidates, needs_mut, bound_span, self_expr } => {
Expand Down Expand Up @@ -383,9 +381,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
return err.emit();
err.emit()
}

MethodError::ErrorReported(guar) => guar,

MethodError::BadReturnType => bug!("no return type expectations but got BadReturnType"),
}
}
Expand Down
13 changes: 13 additions & 0 deletions tests/ui/methods/dont-suggest-import-on-deref-err.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use std::clone::Clone;
use std::ops::Deref;

#[derive(Clone)]
pub struct Foo {}

impl Deref for Foo {}
//~^ ERROR not all trait items implemented

pub fn main() {
let f = Foo {};
let _ = f.clone();
}
12 changes: 12 additions & 0 deletions tests/ui/methods/dont-suggest-import-on-deref-err.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error[E0046]: not all trait items implemented, missing: `Target`, `deref`
--> $DIR/dont-suggest-import-on-deref-err.rs:7:1
|
LL | impl Deref for Foo {}
| ^^^^^^^^^^^^^^^^^^ missing `Target`, `deref` in implementation
|
= help: implement the missing item: `type Target = /* Type */;`
= help: implement the missing item: `fn deref(&self) -> &<Self as Deref>::Target { todo!() }`

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0046`.

0 comments on commit 0d65f12

Please sign in to comment.