Do not report an excessive number of overflow errors for an ever-growing deref impl
This commit is contained in:
parent
394c4060d2
commit
d8a646fe77
@ -2942,7 +2942,18 @@ pub(crate) fn get_field_candidates_considering_privacy(
|
||||
) -> Vec<(Vec<&'tcx ty::FieldDef>, GenericArgsRef<'tcx>)> {
|
||||
debug!("get_field_candidates(span: {:?}, base_t: {:?}", span, base_ty);
|
||||
|
||||
self.autoderef(span, base_ty)
|
||||
let mut autoderef = self.autoderef(span, base_ty).silence_errors();
|
||||
let deref_chain: Vec<_> = autoderef.by_ref().collect();
|
||||
|
||||
// Don't probe if we hit the recursion limit, since it may result in
|
||||
// quadratic blowup if we then try to further deref the results of this
|
||||
// function. This is a best-effort method, after all.
|
||||
if autoderef.reached_recursion_limit() {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
deref_chain
|
||||
.into_iter()
|
||||
.filter_map(move |(base_t, _)| {
|
||||
match base_t.kind() {
|
||||
ty::Adt(base_def, args) if !base_def.is_enum() => {
|
||||
|
@ -375,7 +375,7 @@ pub(crate) fn probe_op<OP, R>(
|
||||
// If our autoderef loop had reached the recursion limit,
|
||||
// report an overflow error, but continue going on with
|
||||
// the truncated autoderef list.
|
||||
if steps.reached_recursion_limit {
|
||||
if steps.reached_recursion_limit && !is_suggestion.0 {
|
||||
self.probe(|_| {
|
||||
let ty = &steps
|
||||
.steps
|
||||
|
@ -672,7 +672,7 @@ fn report_no_match_method_error(
|
||||
let mut ty_str_reported = ty_str.clone();
|
||||
if let ty::Adt(_, generics) = rcvr_ty.kind() {
|
||||
if generics.len() > 0 {
|
||||
let mut autoderef = self.autoderef(span, rcvr_ty);
|
||||
let mut autoderef = self.autoderef(span, rcvr_ty).silence_errors();
|
||||
let candidate_found = autoderef.any(|(ty, _)| {
|
||||
if let ty::Adt(adt_def, _) = ty.kind() {
|
||||
self.tcx
|
||||
|
17
tests/ui/methods/probe-error-on-infinite-deref.rs
Normal file
17
tests/ui/methods/probe-error-on-infinite-deref.rs
Normal file
@ -0,0 +1,17 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
// Make sure that method probe error reporting doesn't get too tangled up
|
||||
// on this infinite deref impl. See #130224.
|
||||
|
||||
struct Wrap<T>(T);
|
||||
impl<T> Deref for Wrap<T> {
|
||||
type Target = Wrap<Wrap<T>>;
|
||||
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`
|
||||
}
|
30
tests/ui/methods/probe-error-on-infinite-deref.stderr
Normal file
30
tests/ui/methods/probe-error-on-infinite-deref.stderr
Normal file
@ -0,0 +1,30 @@
|
||||
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`)
|
||||
|
||||
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
|
||||
|
|
||||
LL | struct Wrap<T>(T);
|
||||
| -------------- method `lmao` not found for this struct
|
||||
...
|
||||
LL | Wrap(1).lmao();
|
||||
| ^^^^ method not found in `Wrap<{integer}>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0055, E0599.
|
||||
For more information about an error, try `rustc --explain E0055`.
|
Loading…
Reference in New Issue
Block a user