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 /// trait or region sub-obligations. (presumably we could, but it's not
/// particularly important for diagnostics...) /// particularly important for diagnostics...)
pub(crate) fn deref_once_mutably_for_diagnostic(&self, expr_ty: Ty<'tcx>) -> Option<Ty<'tcx>> { 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 self.infcx
.type_implements_trait( .type_implements_trait(
self.tcx.lang_items().deref_mut_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`, // 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, // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
// type resolution always gives a "maybe" here. // 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); info!("check deref {:?} error", ty);
matches!(ty.kind(), ty::Error(_) | ty::Infer(_)) matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
}) { }) {
return false; return false;
} }
self.autoderef(span, ty).any(|(ty, _)| { self.autoderef(span, ty).silence_errors().any(|(ty, _)| {
info!("check deref {:?} impl FnOnce", ty); info!("check deref {:?} impl FnOnce", ty);
self.probe(|_| { self.probe(|_| {
let trait_ref = 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 { 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( 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 impl_ty = self.tcx.type_of(*impl_did).instantiate_identity();
let target_ty = self let target_ty = self
.autoderef(sugg_span, rcvr_ty) .autoderef(sugg_span, rcvr_ty)
.silence_errors()
.find(|(rcvr_ty, _)| { .find(|(rcvr_ty, _)| {
DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify(*rcvr_ty, impl_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<'_>, err: &mut Diag<'_>,
) -> bool { ) -> bool {
let tcx = self.tcx; let tcx = self.tcx;
let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() { let field_receiver =
ty::Adt(def, args) if !def.is_enum() => { self.autoderef(span, rcvr_ty).silence_errors().find_map(|(ty, _)| match ty.kind() {
let variant = &def.non_enum_variant(); ty::Adt(def, args) if !def.is_enum() => {
tcx.find_field_index(item_name, variant).map(|index| { let variant = &def.non_enum_variant();
let field = &variant.fields[index]; tcx.find_field_index(item_name, variant).map(|index| {
let field_ty = field.ty(tcx, args); let field = &variant.fields[index];
(field, field_ty) let field_ty = field.ty(tcx, args);
}) (field, field_ty)
} })
_ => None, }
}); _ => None,
});
if let Some((field, field_ty)) = field_receiver { if let Some((field, field_ty)) = field_receiver {
let scope = tcx.parent_module_from_def_id(self.body_id); let scope = tcx.parent_module_from_def_id(self.body_id);
let is_accessible = field.vis.is_accessible_from(scope, tcx); 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 { let SelfSource::QPath(ty) = self_source else {
return; 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( if let Ok(pick) = self.probe_for_name(
Mode::Path, Mode::Path,
item_name, item_name,
@ -4224,7 +4228,7 @@ fn is_local(ty: Ty<'_>) -> bool {
return is_local(rcvr_ty); 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"); err.help("the semantics of slice patterns changed recently; see issue #62254");
} else if self } else if self
.autoderef(span, expected_ty) .autoderef(span, expected_ty)
.silence_errors()
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..))) .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
&& let Some(span) = ti.span && let Some(span) = ti.span
&& let Some(_) = ti.origin_expr && let Some(_) = ti.origin_expr

View File

@ -12,6 +12,5 @@ fn deref(&self) -> &Wrap<Wrap<T>> { todo!() }
fn main() { fn main() {
Wrap(1).lmao(); Wrap(1).lmao();
//~^ ERROR reached the recursion limit //~^ ERROR reached the recursion limit
//~| ERROR reached the recursion limit
//~| ERROR no method named `lmao` //~| 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`) = 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 error[E0599]: no method named `lmao` found for struct `Wrap<{integer}>` in the current scope
--> $DIR/probe-error-on-infinite-deref.rs:13:13 --> $DIR/probe-error-on-infinite-deref.rs:13:13
| |
@ -24,7 +15,7 @@ LL | struct Wrap<T>(T);
LL | Wrap(1).lmao(); LL | Wrap(1).lmao();
| ^^^^ method not found in `Wrap<{integer}>` | ^^^^ 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. Some errors have detailed explanations: E0055, E0599.
For more information about an error, try `rustc --explain E0055`. For more information about an error, try `rustc --explain E0055`.