Skip to content

Commit

Permalink
Unrolled build for rust-lang#131024
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#131024 - compiler-errors:deref-sugg, r=estebank

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 rust-lang#131003.
  • Loading branch information
rust-timer authored Oct 4, 2024
2 parents 9ff5fc4 + 486440f commit 1dea325
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 1dea325

Please sign in to comment.