Use Autoderef::silence_errors more liberally throughout diagnostics code

This commit is contained in:
Michael Goulet 2024-09-12 14:47:22 -04:00
parent f95059b715
commit 575c15a72e
5 changed files with 23 additions and 28 deletions

View File

@ -1049,7 +1049,7 @@ pub(crate) fn deref_steps(&self, expr_ty: Ty<'tcx>, target: Ty<'tcx>) -> Option<
/// trait or region sub-obligations. (presumably we could, but it's not
/// particularly important for diagnostics...)
pub(crate) fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
self.autoderef(DUMMY_SP, expr_ty).nth(1).and_then(|(deref_ty, _)| {
self.autoderef(DUMMY_SP, expr_ty).silence_errors().nth(1).and_then(|(deref_ty, _)| {
self.infcx
.type_implements_trait(
self.tcx.lang_items().deref_mut_trait()?,

View File

@ -62,14 +62,14 @@ fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
// It might seem that we can use `predicate_must_hold_modulo_regions`,
// but since a Dummy binder is used to fill in the FnOnce trait's arguments,
// type resolution always gives a "maybe" here.
if self.autoderef(span, ty).any(|(ty, _)| {
if self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
info!("check deref {:?} error", ty);
matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
}) {
return false;
}
self.autoderef(span, ty).any(|(ty, _)| {
self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
info!("check deref {:?} impl FnOnce", ty);
self.probe(|_| {
let trait_ref =
@ -90,7 +90,9 @@ fn is_fn_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
}
fn is_slice_ty(&self, ty: Ty<'tcx>, span: Span) -> bool {
self.autoderef(span, ty).any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
self.autoderef(span, ty)
.silence_errors()
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
}
fn impl_into_iterator_should_be_iterator(
@ -2237,6 +2239,7 @@ fn suggest_associated_call_syntax(
let impl_ty = self.tcx.type_of(*impl_did).instantiate_identity();
let target_ty = self
.autoderef(sugg_span, rcvr_ty)
.silence_errors()
.find(|(rcvr_ty, _)| {
DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify(*rcvr_ty, impl_ty)
})
@ -2352,17 +2355,18 @@ fn suggest_calling_field_as_fn(
err: &mut Diag<'_>,
) -> bool {
let tcx = self.tcx;
let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
ty::Adt(def, args) if !def.is_enum() => {
let variant = &def.non_enum_variant();
tcx.find_field_index(item_name, variant).map(|index| {
let field = &variant.fields[index];
let field_ty = field.ty(tcx, args);
(field, field_ty)
})
}
_ => None,
});
let field_receiver =
self.autoderef(span, rcvr_ty).silence_errors().find_map(|(ty, _)| match ty.kind() {
ty::Adt(def, args) if !def.is_enum() => {
let variant = &def.non_enum_variant();
tcx.find_field_index(item_name, variant).map(|index| {
let field = &variant.fields[index];
let field_ty = field.ty(tcx, args);
(field, field_ty)
})
}
_ => None,
});
if let Some((field, field_ty)) = field_receiver {
let scope = tcx.parent_module_from_def_id(self.body_id);
let is_accessible = field.vis.is_accessible_from(scope, tcx);
@ -3198,7 +3202,7 @@ fn note_derefed_ty_has_method(
let SelfSource::QPath(ty) = self_source else {
return;
};
for (deref_ty, _) in self.autoderef(DUMMY_SP, rcvr_ty).skip(1) {
for (deref_ty, _) in self.autoderef(DUMMY_SP, rcvr_ty).silence_errors().skip(1) {
if let Ok(pick) = self.probe_for_name(
Mode::Path,
item_name,
@ -4224,7 +4228,7 @@ fn is_local(ty: Ty<'_>) -> bool {
return is_local(rcvr_ty);
}
self.autoderef(span, rcvr_ty).any(|(ty, _)| is_local(ty))
self.autoderef(span, rcvr_ty).silence_errors().any(|(ty, _)| is_local(ty))
}
}

View File

@ -2533,6 +2533,7 @@ fn error_expected_array_or_slice(
err.help("the semantics of slice patterns changed recently; see issue #62254");
} else if self
.autoderef(span, expected_ty)
.silence_errors()
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
&& let Some(span) = ti.span
&& let Some(_) = ti.origin_expr

View File

@ -12,6 +12,5 @@ fn deref(&self) -> &Wrap<Wrap<T>> { todo!() }
fn main() {
Wrap(1).lmao();
//~^ ERROR reached the recursion limit
//~| ERROR reached the recursion limit
//~| ERROR no method named `lmao`
}

View File

@ -6,15 +6,6 @@ LL | Wrap(1).lmao();
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`probe_error_on_infinite_deref`)
error[E0055]: reached the recursion limit while auto-dereferencing `Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<Wrap<{integer}>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
--> $DIR/probe-error-on-infinite-deref.rs:13:13
|
LL | Wrap(1).lmao();
| ^^^^ deref recursion limit reached
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`probe_error_on_infinite_deref`)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0599]: no method named `lmao` found for struct `Wrap<{integer}>` in the current scope
--> $DIR/probe-error-on-infinite-deref.rs:13:13
|
@ -24,7 +15,7 @@ LL | struct Wrap<T>(T);
LL | Wrap(1).lmao();
| ^^^^ method not found in `Wrap<{integer}>`
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0055, E0599.
For more information about an error, try `rustc --explain E0055`.