mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Rollup merge of #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 #131003.
This commit is contained in:
commit
0d65f121a1
@ -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};
|
||||
@ -46,17 +46,17 @@ 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,
|
||||
@ -64,8 +64,11 @@ pub(crate) enum MethodError<'tcx> {
|
||||
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
|
||||
@ -120,6 +123,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
Err(PrivateMatch(..)) => false,
|
||||
Err(IllegalSizedBound { .. }) => true,
|
||||
Err(BadReturnType) => false,
|
||||
Err(ErrorReported(_)) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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!(
|
||||
@ -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) => {
|
||||
@ -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 } => {
|
||||
@ -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"),
|
||||
}
|
||||
}
|
||||
|
13
tests/ui/methods/dont-suggest-import-on-deref-err.rs
Normal file
13
tests/ui/methods/dont-suggest-import-on-deref-err.rs
Normal file
@ -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
tests/ui/methods/dont-suggest-import-on-deref-err.stderr
Normal file
12
tests/ui/methods/dont-suggest-import-on-deref-err.stderr
Normal file
@ -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…
Reference in New Issue
Block a user