From eb494082a7debb405e68c8fb0ffdfed07c60914d Mon Sep 17 00:00:00 2001 From: Ellen Date: Wed, 25 May 2022 04:55:03 +0100 Subject: [PATCH] drop some impl candidates before evaluating candidates --- .../src/error_codes/E0275.md | 6 + .../src/traits/select/candidate_assembly.rs | 34 ++++-- .../ui/const-generics/issues/issue-90318.rs | 2 - .../const-generics/issues/issue-90318.stderr | 33 +---- src/test/ui/error-codes/E0275.rs | 5 +- src/test/ui/error-codes/E0275.stderr | 17 ++- src/test/ui/issues/issue-20413.rs | 6 - src/test/ui/issues/issue-20413.stderr | 115 +----------------- 8 files changed, 50 insertions(+), 168 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0275.md b/compiler/rustc_error_codes/src/error_codes/E0275.md index 2d12fcea4cafc..bd06b373c1501 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0275.md +++ b/compiler/rustc_error_codes/src/error_codes/E0275.md @@ -8,6 +8,12 @@ trait Foo {} struct Bar(T); impl Foo for T where Bar: Foo {} + +fn takes_foo() {} + +fn calls_takes_foo() { + takes_foo::<()>(); +} ``` This error occurs when there was a recursive trait requirement that overflowed diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 07720ba71ca95..f14aa2ee7beb9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -157,17 +157,33 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // Winnow, but record the exact outcome of evaluation, which // is needed for specialization. Propagate overflow if it occurs. + let mut eval_cand = |c| match self.evaluate_candidate(stack, &c) { + Ok(eval) if eval.may_apply() => { + Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) + } + Ok(_) => Ok(None), + Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), + Err(OverflowError::ErrorReporting) => Err(ErrorReporting), + Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), + }; + + // this is very not perf and should be fixed xd + let drop_impl_candidates = candidates + .iter() + .filter(|c| matches!(c, SelectionCandidate::ParamCandidate(_))) + .cloned() + .map(&mut eval_cand) + .flat_map(Result::transpose) + .try_fold(false, |should_drop, param_candidate| { + let cand = ¶m_candidate?.candidate; + Ok::<_, SelectionError<'_>>( + should_drop || !(cand.is_global() && !cand.has_late_bound_regions()), + ) + })?; let mut candidates = candidates .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c) { - Ok(eval) if eval.may_apply() => { - Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) - } - Ok(_) => Ok(None), - Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), - Err(OverflowError::ErrorReporting) => Err(ErrorReporting), - Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), - }) + .filter(|c| !matches!(c, SelectionCandidate::ImplCandidate(_) if drop_impl_candidates)) + .map(&mut eval_cand) .flat_map(Result::transpose) .collect::, _>>()?; diff --git a/src/test/ui/const-generics/issues/issue-90318.rs b/src/test/ui/const-generics/issues/issue-90318.rs index bebd0c6ac1202..5834d4d1edf01 100644 --- a/src/test/ui/const-generics/issues/issue-90318.rs +++ b/src/test/ui/const-generics/issues/issue-90318.rs @@ -13,7 +13,6 @@ fn consume(_val: T) where If<{ TypeId::of::() != TypeId::of::<()>() }>: True, //~^ ERROR: overly complex generic constant - //~| ERROR: cannot call non-const operator in constants { } @@ -21,7 +20,6 @@ fn test() where If<{ TypeId::of::() != TypeId::of::<()>() }>: True, //~^ ERROR: overly complex generic constant - //~| ERROR: cannot call non-const operator in constants { } diff --git a/src/test/ui/const-generics/issues/issue-90318.stderr b/src/test/ui/const-generics/issues/issue-90318.stderr index c8690ecd0da7e..f13fd795d7a10 100644 --- a/src/test/ui/const-generics/issues/issue-90318.stderr +++ b/src/test/ui/const-generics/issues/issue-90318.stderr @@ -9,22 +9,8 @@ LL | If<{ TypeId::of::() != TypeId::of::<()>() }>: True, = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future -error[E0015]: cannot call non-const operator in constants - --> $DIR/issue-90318.rs:14:10 - | -LL | If<{ TypeId::of::() != TypeId::of::<()>() }>: True, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - | -LL | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] - | ^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - error: overly complex generic constant - --> $DIR/issue-90318.rs:22:8 + --> $DIR/issue-90318.rs:21:8 | LL | If<{ TypeId::of::() != TypeId::of::<()>() }>: True, | ^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^ @@ -34,20 +20,5 @@ LL | If<{ TypeId::of::() != TypeId::of::<()>() }>: True, = help: consider moving this anonymous constant into a `const` function = note: this operation may be supported in the future -error[E0015]: cannot call non-const operator in constants - --> $DIR/issue-90318.rs:22:10 - | -LL | If<{ TypeId::of::() != TypeId::of::<()>() }>: True, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: impl defined here, but it is not `const` - --> $SRC_DIR/core/src/any.rs:LL:COL - | -LL | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] - | ^^^^^^^^^ - = note: calls in constants are limited to constant functions, tuple structs and tuple variants - = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. diff --git a/src/test/ui/error-codes/E0275.rs b/src/test/ui/error-codes/E0275.rs index 28a9676f03e39..9189960783b6b 100644 --- a/src/test/ui/error-codes/E0275.rs +++ b/src/test/ui/error-codes/E0275.rs @@ -2,7 +2,10 @@ trait Foo {} struct Bar(T); -impl Foo for T where Bar: Foo {} //~ ERROR E0275 +impl Foo for T where Bar: Foo {} + +fn takes_foo() {} fn main() { + takes_foo::<()>(); //~ ERROR E0275 } diff --git a/src/test/ui/error-codes/E0275.stderr b/src/test/ui/error-codes/E0275.stderr index dfffbb182ad31..1b4d874f8892b 100644 --- a/src/test/ui/error-codes/E0275.stderr +++ b/src/test/ui/error-codes/E0275.stderr @@ -1,17 +1,22 @@ -error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/E0275.rs:5:33 +error[E0275]: overflow evaluating the requirement `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` + --> $DIR/E0275.rs:10:5 | -LL | impl Foo for T where Bar: Foo {} - | ^^^ +LL | takes_foo::<()>(); + | ^^^^^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`) -note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` +note: required because of the requirements on the impl of `Foo` for `Bar>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` --> $DIR/E0275.rs:5:9 | LL | impl Foo for T where Bar: Foo {} | ^^^ ^ = note: 127 redundant requirements hidden - = note: required because of the requirements on the impl of `Foo` for `Bar` + = note: required because of the requirements on the impl of `Foo` for `()` +note: required by a bound in `takes_foo` + --> $DIR/E0275.rs:7:17 + | +LL | fn takes_foo() {} + | ^^^ required by this bound in `takes_foo` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-20413.rs b/src/test/ui/issues/issue-20413.rs index a4345ccdfbe81..99af085987756 100644 --- a/src/test/ui/issues/issue-20413.rs +++ b/src/test/ui/issues/issue-20413.rs @@ -6,8 +6,6 @@ struct NoData; //~^ ERROR: parameter `T` is never used impl Foo for T where NoData: Foo { - //~^ ERROR: overflow evaluating the requirement - //~| ERROR: overflow evaluating the requirement fn answer(self) { let val: NoData = NoData; } @@ -26,16 +24,12 @@ struct AlmostNoData(Option); struct EvenLessData(Option); impl Bar for T where EvenLessData: Baz { -//~^ ERROR: overflow evaluating the requirement -//~| ERROR: overflow evaluating the requirement fn answer(self) { let val: EvenLessData = EvenLessData(None); } } impl Baz for T where AlmostNoData: Bar { -//~^ ERROR: overflow evaluating the requirement -//~| ERROR: overflow evaluating the requirement fn answer(self) { let val: NoData = AlmostNoData(None); } diff --git a/src/test/ui/issues/issue-20413.stderr b/src/test/ui/issues/issue-20413.stderr index 2935214140419..3c0d47936ca88 100644 --- a/src/test/ui/issues/issue-20413.stderr +++ b/src/test/ui/issues/issue-20413.stderr @@ -7,117 +7,6 @@ LL | struct NoData; = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` = help: if you intended `T` to be a const parameter, use `const T: usize` instead -error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:8:36 - | -LL | impl Foo for T where NoData: Foo { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:8:9 - | -LL | impl Foo for T where NoData: Foo { - | ^^^ ^ - = note: 127 redundant requirements hidden - = note: required because of the requirements on the impl of `Foo` for `NoData` - -error[E0275]: overflow evaluating the requirement `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Foo` - --> $DIR/issue-20413.rs:8:36 - | -LL | impl Foo for T where NoData: Foo { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Foo` for `NoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:8:9 - | -LL | impl Foo for T where NoData: Foo { - | ^^^ ^ - = note: 127 redundant requirements hidden - = note: required because of the requirements on the impl of `Foo` for `NoData` - -error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz` - --> $DIR/issue-20413.rs:28:42 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Bar` for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:28:9 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ ^ -note: required because of the requirements on the impl of `Baz` for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:36:9 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ ^ - = note: 126 redundant requirements hidden - = note: required because of the requirements on the impl of `Baz` for `EvenLessData` - -error[E0275]: overflow evaluating the requirement `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Baz` - --> $DIR/issue-20413.rs:28:42 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Bar` for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:28:9 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ ^ -note: required because of the requirements on the impl of `Baz` for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:36:9 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ ^ - = note: 126 redundant requirements hidden - = note: required because of the requirements on the impl of `Baz` for `EvenLessData` - -error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar` - --> $DIR/issue-20413.rs:36:42 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Baz` for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:36:9 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ ^ -note: required because of the requirements on the impl of `Bar` for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:28:9 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ ^ - = note: 126 redundant requirements hidden - = note: required because of the requirements on the impl of `Bar` for `AlmostNoData` - -error[E0275]: overflow evaluating the requirement `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>: Bar` - --> $DIR/issue-20413.rs:36:42 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`) -note: required because of the requirements on the impl of `Baz` for `EvenLessData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:36:9 - | -LL | impl Baz for T where AlmostNoData: Bar { - | ^^^ ^ -note: required because of the requirements on the impl of `Bar` for `AlmostNoData>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` - --> $DIR/issue-20413.rs:28:9 - | -LL | impl Bar for T where EvenLessData: Baz { - | ^^^ ^ - = note: 126 redundant requirements hidden - = note: required because of the requirements on the impl of `Bar` for `AlmostNoData` - -error: aborting due to 7 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0275, E0392. -For more information about an error, try `rustc --explain E0275`. +For more information about this error, try `rustc --explain E0392`.