Skip to content

Don't give method suggestions when method probe fails due to bad implementation of Deref #131024

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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`.
Loading