1
Fork 0

distinguish recursion limit based overflow for diagnostics

also change the number of allowed fixpoint steps to be fixed instead
of using the `log` of the total recursion depth.
This commit is contained in:
lcnr 2024-02-23 10:12:08 +01:00
parent d3d145ea1c
commit 5ec9b8d778
25 changed files with 91 additions and 125 deletions

View file

@ -135,16 +135,18 @@ pub struct FulfillmentError<'tcx> {
#[derive(Clone)] #[derive(Clone)]
pub enum FulfillmentErrorCode<'tcx> { pub enum FulfillmentErrorCode<'tcx> {
/// Inherently impossible to fulfill; this trait is implemented if and only if it is already implemented. /// Inherently impossible to fulfill; this trait is implemented if and only
/// if it is already implemented.
Cycle(Vec<PredicateObligation<'tcx>>), Cycle(Vec<PredicateObligation<'tcx>>),
SelectionError(SelectionError<'tcx>), SelectionError(SelectionError<'tcx>),
ProjectionError(MismatchedProjectionTypes<'tcx>), ProjectionError(MismatchedProjectionTypes<'tcx>),
SubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate SubtypeError(ExpectedFound<Ty<'tcx>>, TypeError<'tcx>), // always comes from a SubtypePredicate
ConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>), ConstEquateError(ExpectedFound<Const<'tcx>>, TypeError<'tcx>),
Ambiguity { Ambiguity {
/// Overflow reported from the new solver `-Znext-solver`, which will /// Overflow is only `Some(suggest_recursion_limit)` when using the next generation
/// be reported as an regular error as opposed to a fatal error. /// trait solver `-Znext-solver`. With the old solver overflow is eagerly handled by
overflow: bool, /// emitting a fatal error instead.
overflow: Option<bool>,
}, },
} }

View file

@ -47,8 +47,10 @@ impl<'tcx> fmt::Debug for traits::FulfillmentErrorCode<'tcx> {
ConstEquateError(ref a, ref b) => { ConstEquateError(ref a, ref b) => {
write!(f, "CodeConstEquateError({a:?}, {b:?})") write!(f, "CodeConstEquateError({a:?}, {b:?})")
} }
Ambiguity { overflow: false } => write!(f, "Ambiguity"), Ambiguity { overflow: None } => write!(f, "Ambiguity"),
Ambiguity { overflow: true } => write!(f, "Overflow"), Ambiguity { overflow: Some(suggest_increasing_limit) } => {
write!(f, "Overflow({suggest_increasing_limit})")
}
Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"), Cycle(ref cycle) => write!(f, "Cycle({cycle:?})"),
} }
} }

View file

@ -60,7 +60,6 @@ pub enum Certainty {
impl Certainty { impl Certainty {
pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity); pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
pub const OVERFLOW: Certainty = Certainty::Maybe(MaybeCause::Overflow);
/// Use this function to merge the certainty of multiple nested subgoals. /// Use this function to merge the certainty of multiple nested subgoals.
/// ///
@ -79,15 +78,12 @@ impl Certainty {
(Certainty::Yes, Certainty::Yes) => Certainty::Yes, (Certainty::Yes, Certainty::Yes) => Certainty::Yes,
(Certainty::Yes, Certainty::Maybe(_)) => other, (Certainty::Yes, Certainty::Maybe(_)) => other,
(Certainty::Maybe(_), Certainty::Yes) => self, (Certainty::Maybe(_), Certainty::Yes) => self,
(Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Ambiguity)) => { (Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
Certainty::Maybe(MaybeCause::Ambiguity)
}
(Certainty::Maybe(MaybeCause::Ambiguity), Certainty::Maybe(MaybeCause::Overflow))
| (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Ambiguity))
| (Certainty::Maybe(MaybeCause::Overflow), Certainty::Maybe(MaybeCause::Overflow)) => {
Certainty::Maybe(MaybeCause::Overflow)
} }
} }
pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
} }
} }
@ -99,7 +95,21 @@ pub enum MaybeCause {
/// or we hit a case where we just don't bother, e.g. `?x: Trait` goals. /// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
Ambiguity, Ambiguity,
/// We gave up due to an overflow, most often by hitting the recursion limit. /// We gave up due to an overflow, most often by hitting the recursion limit.
Overflow, Overflow { suggest_increasing_limit: bool },
}
impl MaybeCause {
fn unify_with(self, other: MaybeCause) -> MaybeCause {
match (self, other) {
(MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
(MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
(MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
(
MaybeCause::Overflow { suggest_increasing_limit: a },
MaybeCause::Overflow { suggest_increasing_limit: b },
) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
}
}
} }
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)] #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]

View file

@ -36,11 +36,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
let Goal { param_env, predicate: (lhs, rhs, direction) } = goal; let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
let Some(lhs) = self.try_normalize_term(param_env, lhs)? else { let Some(lhs) = self.try_normalize_term(param_env, lhs)? else {
return self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW); return self
.evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
}; };
let Some(rhs) = self.try_normalize_term(param_env, rhs)? else { let Some(rhs) = self.try_normalize_term(param_env, rhs)? else {
return self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW); return self
.evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
}; };
let variance = match direction { let variance = match direction {

View file

@ -7,6 +7,7 @@ use rustc_infer::infer::{
BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt, BoundRegionConversionTime, DefineOpaqueTypes, InferCtxt, InferOk, TyCtxtInferExt,
}; };
use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::query::NoSolution;
use rustc_infer::traits::solve::MaybeCause;
use rustc_infer::traits::ObligationCause; use rustc_infer::traits::ObligationCause;
use rustc_middle::infer::canonical::CanonicalVarInfos; use rustc_middle::infer::canonical::CanonicalVarInfos;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
@ -29,7 +30,7 @@ use std::ops::ControlFlow;
use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment}; use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
use super::inspect::ProofTreeBuilder; use super::inspect::ProofTreeBuilder;
use super::{search_graph, GoalEvaluationKind}; use super::{search_graph, GoalEvaluationKind, FIXPOINT_STEP_LIMIT};
use super::{search_graph::SearchGraph, Goal}; use super::{search_graph::SearchGraph, Goal};
use super::{GoalSource, SolverMode}; use super::{GoalSource, SolverMode};
pub use select::InferCtxtSelectExt; pub use select::InferCtxtSelectExt;
@ -154,10 +155,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
self.search_graph.solver_mode() self.search_graph.solver_mode()
} }
pub(super) fn local_overflow_limit(&self) -> usize {
self.search_graph.local_overflow_limit()
}
/// Creates a root evaluation context and search graph. This should only be /// Creates a root evaluation context and search graph. This should only be
/// used from outside of any evaluation, and other methods should be preferred /// used from outside of any evaluation, and other methods should be preferred
/// over using this manually (such as [`InferCtxtEvalExt::evaluate_root_goal`]). /// over using this manually (such as [`InferCtxtEvalExt::evaluate_root_goal`]).
@ -167,7 +164,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R, f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> R,
) -> (R, Option<inspect::GoalEvaluation<'tcx>>) { ) -> (R, Option<inspect::GoalEvaluation<'tcx>>) {
let mode = if infcx.intercrate { SolverMode::Coherence } else { SolverMode::Normal }; let mode = if infcx.intercrate { SolverMode::Coherence } else { SolverMode::Normal };
let mut search_graph = search_graph::SearchGraph::new(infcx.tcx, mode); let mut search_graph = search_graph::SearchGraph::new(mode);
let mut ecx = EvalCtxt { let mut ecx = EvalCtxt {
search_graph: &mut search_graph, search_graph: &mut search_graph,
@ -388,9 +385,12 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
&& source != GoalSource::ImplWhereBound && source != GoalSource::ImplWhereBound
}; };
if response.value.certainty == Certainty::OVERFLOW && !keep_overflow_constraints() { if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty
(Certainty::OVERFLOW, false) && !keep_overflow_constraints()
} else { {
return (response.value.certainty, false);
}
let has_changed = !response.value.var_values.is_identity_modulo_regions() let has_changed = !response.value.var_values.is_identity_modulo_regions()
|| !response.value.external_constraints.opaque_types.is_empty(); || !response.value.external_constraints.opaque_types.is_empty();
@ -398,7 +398,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
self.instantiate_and_apply_query_response(param_env, original_values, response); self.instantiate_and_apply_query_response(param_env, original_values, response);
(certainty, has_changed) (certainty, has_changed)
} }
}
fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> { fn compute_goal(&mut self, goal: Goal<'tcx, ty::Predicate<'tcx>>) -> QueryResult<'tcx> {
let Goal { param_env, predicate } = goal; let Goal { param_env, predicate } = goal;
@ -466,8 +465,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
let inspect = self.inspect.new_evaluate_added_goals(); let inspect = self.inspect.new_evaluate_added_goals();
let inspect = core::mem::replace(&mut self.inspect, inspect); let inspect = core::mem::replace(&mut self.inspect, inspect);
let mut response = Ok(Certainty::OVERFLOW); let mut response = Ok(Certainty::overflow(false));
for _ in 0..self.local_overflow_limit() { for _ in 0..FIXPOINT_STEP_LIMIT {
// FIXME: This match is a bit ugly, it might be nice to change the inspect // FIXME: This match is a bit ugly, it might be nice to change the inspect
// stuff to use a closure instead. which should hopefully simplify this a bit. // stuff to use a closure instead. which should hopefully simplify this a bit.
match self.evaluate_added_goals_step() { match self.evaluate_added_goals_step() {

View file

@ -80,11 +80,14 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
.0 .0
{ {
Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => { Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
FulfillmentErrorCode::Ambiguity { overflow: false } FulfillmentErrorCode::Ambiguity { overflow: None }
}
Ok((_, Certainty::Maybe(MaybeCause::Overflow))) => {
FulfillmentErrorCode::Ambiguity { overflow: true }
} }
Ok((
_,
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit }),
)) => FulfillmentErrorCode::Ambiguity {
overflow: Some(suggest_increasing_limit),
},
Ok((_, Certainty::Yes)) => { Ok((_, Certainty::Yes)) => {
bug!("did not expect successful goal when collecting ambiguity errors") bug!("did not expect successful goal when collecting ambiguity errors")
} }

View file

@ -42,6 +42,17 @@ pub use fulfill::FulfillmentCtxt;
pub(crate) use normalize::deeply_normalize_for_diagnostics; pub(crate) use normalize::deeply_normalize_for_diagnostics;
pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes}; pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes};
/// How many fixpoint iterations we should attempt inside of the solver before bailing
/// with overflow.
///
/// We previously used `tcx.recursion_limit().0.checked_ilog2().unwrap_or(0)` for this.
/// However, it feels unlikely that uncreasing the recursion limit by a power of two
/// to get one more itereation is every useful or desirable. We now instead used a constant
/// here. If there ever ends up some use-cases where a bigger number of fixpoint iterations
/// is required, we can add a new attribute for that or revert this to be dependant on the
/// recursion limit again. However, this feels very unlikely.
const FIXPOINT_STEP_LIMIT: usize = 8;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
enum SolverMode { enum SolverMode {
/// Ordinary trait solving, using everywhere except for coherence. /// Ordinary trait solving, using everywhere except for coherence.

View file

@ -1,3 +1,5 @@
use crate::solve::FIXPOINT_STEP_LIMIT;
use super::inspect; use super::inspect;
use super::inspect::ProofTreeBuilder; use super::inspect::ProofTreeBuilder;
use super::SolverMode; use super::SolverMode;
@ -99,7 +101,6 @@ impl<'tcx> ProvisionalCacheEntry<'tcx> {
pub(super) struct SearchGraph<'tcx> { pub(super) struct SearchGraph<'tcx> {
mode: SolverMode, mode: SolverMode,
local_overflow_limit: usize,
/// The stack of goals currently being computed. /// The stack of goals currently being computed.
/// ///
/// An element is *deeper* in the stack if its index is *lower*. /// An element is *deeper* in the stack if its index is *lower*.
@ -116,10 +117,9 @@ pub(super) struct SearchGraph<'tcx> {
} }
impl<'tcx> SearchGraph<'tcx> { impl<'tcx> SearchGraph<'tcx> {
pub(super) fn new(tcx: TyCtxt<'tcx>, mode: SolverMode) -> SearchGraph<'tcx> { pub(super) fn new(mode: SolverMode) -> SearchGraph<'tcx> {
Self { Self {
mode, mode,
local_overflow_limit: tcx.recursion_limit().0.checked_ilog2().unwrap_or(0) as usize,
stack: Default::default(), stack: Default::default(),
provisional_cache: Default::default(), provisional_cache: Default::default(),
cycle_participants: Default::default(), cycle_participants: Default::default(),
@ -130,10 +130,6 @@ impl<'tcx> SearchGraph<'tcx> {
self.mode self.mode
} }
pub(super) fn local_overflow_limit(&self) -> usize {
self.local_overflow_limit
}
/// Update the stack and reached depths on cache hits. /// Update the stack and reached depths on cache hits.
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) { fn on_cache_hit(&mut self, additional_depth: usize, encountered_overflow: bool) {
@ -277,7 +273,7 @@ impl<'tcx> SearchGraph<'tcx> {
} }
inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow); inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::Overflow);
return Self::response_no_constraints(tcx, input, Certainty::OVERFLOW); return Self::response_no_constraints(tcx, input, Certainty::overflow(true));
}; };
// Try to fetch the goal from the global cache. // Try to fetch the goal from the global cache.
@ -370,7 +366,7 @@ impl<'tcx> SearchGraph<'tcx> {
} else if is_coinductive_cycle { } else if is_coinductive_cycle {
Self::response_no_constraints(tcx, input, Certainty::Yes) Self::response_no_constraints(tcx, input, Certainty::Yes)
} else { } else {
Self::response_no_constraints(tcx, input, Certainty::OVERFLOW) Self::response_no_constraints(tcx, input, Certainty::overflow(false))
}; };
} else { } else {
// No entry, we push this goal on the stack and try to prove it. // No entry, we push this goal on the stack and try to prove it.
@ -398,7 +394,7 @@ impl<'tcx> SearchGraph<'tcx> {
// of this we continuously recompute the cycle until the result // of this we continuously recompute the cycle until the result
// of the previous iteration is equal to the final result, at which // of the previous iteration is equal to the final result, at which
// point we are done. // point we are done.
for _ in 0..self.local_overflow_limit() { for _ in 0..FIXPOINT_STEP_LIMIT {
let result = prove_goal(self, inspect); let result = prove_goal(self, inspect);
let stack_entry = self.pop_stack(); let stack_entry = self.pop_stack();
debug_assert_eq!(stack_entry.input, input); debug_assert_eq!(stack_entry.input, input);
@ -431,7 +427,8 @@ impl<'tcx> SearchGraph<'tcx> {
} else if stack_entry.has_been_used == HasBeenUsed::COINDUCTIVE_CYCLE { } else if stack_entry.has_been_used == HasBeenUsed::COINDUCTIVE_CYCLE {
Self::response_no_constraints(tcx, input, Certainty::Yes) == result Self::response_no_constraints(tcx, input, Certainty::Yes) == result
} else if stack_entry.has_been_used == HasBeenUsed::INDUCTIVE_CYCLE { } else if stack_entry.has_been_used == HasBeenUsed::INDUCTIVE_CYCLE {
Self::response_no_constraints(tcx, input, Certainty::OVERFLOW) == result Self::response_no_constraints(tcx, input, Certainty::overflow(false))
== result
} else { } else {
false false
}; };
@ -452,7 +449,7 @@ impl<'tcx> SearchGraph<'tcx> {
debug!("canonical cycle overflow"); debug!("canonical cycle overflow");
let current_entry = self.pop_stack(); let current_entry = self.pop_stack();
debug_assert!(current_entry.has_been_used.is_empty()); debug_assert!(current_entry.has_been_used.is_empty());
let result = Self::response_no_constraints(tcx, input, Certainty::OVERFLOW); let result = Self::response_no_constraints(tcx, input, Certainty::overflow(false));
(current_entry, result) (current_entry, result)
}); });

View file

@ -335,12 +335,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
); );
} }
fn report_overflow_no_abort(&self, obligation: PredicateObligation<'tcx>) -> ErrorGuaranteed { fn report_overflow_no_abort(
&self,
obligation: PredicateObligation<'tcx>,
suggest_increasing_limit: bool,
) -> ErrorGuaranteed {
let obligation = self.resolve_vars_if_possible(obligation); let obligation = self.resolve_vars_if_possible(obligation);
let mut err = self.build_overflow_error( let mut err = self.build_overflow_error(
OverflowCause::TraitSolver(obligation.predicate), OverflowCause::TraitSolver(obligation.predicate),
obligation.cause.span, obligation.cause.span,
true, suggest_increasing_limit,
); );
self.note_obligation_cause(&mut err, &obligation); self.note_obligation_cause(&mut err, &obligation);
self.point_at_returns_when_relevant(&mut err, &obligation); self.point_at_returns_when_relevant(&mut err, &obligation);
@ -1422,11 +1426,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
FulfillmentErrorCode::ProjectionError(ref e) => { FulfillmentErrorCode::ProjectionError(ref e) => {
self.report_projection_error(&error.obligation, e) self.report_projection_error(&error.obligation, e)
} }
FulfillmentErrorCode::Ambiguity { overflow: false } => { FulfillmentErrorCode::Ambiguity { overflow: None } => {
self.maybe_report_ambiguity(&error.obligation) self.maybe_report_ambiguity(&error.obligation)
} }
FulfillmentErrorCode::Ambiguity { overflow: true } => { FulfillmentErrorCode::Ambiguity { overflow: Some(suggest_increasing_limit) } => {
self.report_overflow_no_abort(error.obligation.clone()) self.report_overflow_no_abort(error.obligation.clone(), suggest_increasing_limit)
} }
FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => self FulfillmentErrorCode::SubtypeError(ref expected_found, ref err) => self
.report_mismatched_types( .report_mismatched_types(

View file

@ -138,7 +138,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
_infcx: &InferCtxt<'tcx>, _infcx: &InferCtxt<'tcx>,
) -> Vec<FulfillmentError<'tcx>> { ) -> Vec<FulfillmentError<'tcx>> {
self.predicates self.predicates
.to_errors(FulfillmentErrorCode::Ambiguity { overflow: false }) .to_errors(FulfillmentErrorCode::Ambiguity { overflow: None })
.into_iter() .into_iter()
.map(to_fulfillment_error) .map(to_fulfillment_error)
.collect() .collect()

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `for<'a> &'a mut Bar well-form
LL | for<'a> &'a mut Self:; LL | for<'a> &'a mut Self:;
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_95230`)
note: required by a bound in `Bar` note: required by a bound in `Bar`
--> $DIR/issue-95230.rs:9:13 --> $DIR/issue-95230.rs:9:13
| |

View file

@ -3,8 +3,6 @@ error[E0275]: overflow evaluating the requirement `Loop == _`
| |
LL | impl Loop {} LL | impl Loop {}
| ^^^^ | ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`)
error[E0392]: type parameter `T` is never used error[E0392]: type parameter `T` is never used
--> $DIR/inherent-impls-overflow.rs:13:12 --> $DIR/inherent-impls-overflow.rs:13:12

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `String: Copy`
LL | type Item = String where String: Copy; LL | type Item = String where String: Copy;
| ^^^^ | ^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type note: the requirement `String: Copy` appears on the `impl`'s associated type `Item` but not on the corresponding trait's associated type
--> $DIR/alias-bound-unsound.rs:8:10 --> $DIR/alias-bound-unsound.rs:8:10
| |
@ -18,32 +17,24 @@ error[E0275]: overflow evaluating the requirement `String <: <() as Foo>::Item`
| |
LL | drop(<() as Foo>::copy_me(&x)); LL | drop(<() as Foo>::copy_me(&x));
| ^^ | ^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
--> $DIR/alias-bound-unsound.rs:24:10 --> $DIR/alias-bound-unsound.rs:24:10
| |
LL | drop(<() as Foo>::copy_me(&x)); LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed` error[E0275]: overflow evaluating the requirement `&<() as Foo>::Item well-formed`
--> $DIR/alias-bound-unsound.rs:24:31 --> $DIR/alias-bound-unsound.rs:24:31
| |
LL | drop(<() as Foo>::copy_me(&x)); LL | drop(<() as Foo>::copy_me(&x));
| ^^ | ^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed` error[E0275]: overflow evaluating the requirement `<() as Foo>::Item well-formed`
--> $DIR/alias-bound-unsound.rs:24:10 --> $DIR/alias-bound-unsound.rs:24:10
| |
LL | drop(<() as Foo>::copy_me(&x)); LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _` error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
--> $DIR/alias-bound-unsound.rs:24:10 --> $DIR/alias-bound-unsound.rs:24:10
@ -51,7 +42,6 @@ error[E0275]: overflow evaluating the requirement `<() as Foo>::Item == _`
LL | drop(<() as Foo>::copy_me(&x)); LL | drop(<() as Foo>::copy_me(&x));
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`alias_bound_unsound`)
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View file

@ -6,6 +6,9 @@ LL | impl<T: Copy> Trait for T {}
LL | struct LocalTy; LL | struct LocalTy;
LL | impl Trait for <LocalTy as Overflow>::Assoc {} LL | impl Trait for <LocalTy as Overflow>::Assoc {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
= note: overflow evaluating the requirement `_ == <LocalTy as Overflow>::Assoc`
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized` error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized`
--> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18 --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
LL | impls::<W<_>>(); LL | impls::<W<_>>();
| ^^^^ | ^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
note: required by a bound in `impls` note: required by a bound in `impls`
--> $DIR/fixpoint-exponential-growth.rs:30:13 --> $DIR/fixpoint-exponential-growth.rs:30:13
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): Trait`
LL | impls_trait::<()>(); LL | impls_trait::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
note: required by a bound in `impls_trait` note: required by a bound in `impls_trait`
--> $DIR/double-cycle-inductive-coinductive.rs:17:19 --> $DIR/double-cycle-inductive-coinductive.rs:17:19
| |
@ -17,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `(): TraitRev`
LL | impls_trait_rev::<()>(); LL | impls_trait_rev::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
note: required by a bound in `impls_trait_rev` note: required by a bound in `impls_trait_rev`
--> $DIR/double-cycle-inductive-coinductive.rs:29:23 --> $DIR/double-cycle-inductive-coinductive.rs:29:23
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
LL | impls_trait::<W<_>>(); LL | impls_trait::<W<_>>();
| ^^^^ | ^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_fixpoint_hang`)
note: required by a bound in `impls_trait` note: required by a bound in `impls_trait`
--> $DIR/inductive-fixpoint-hang.rs:28:19 --> $DIR/inductive-fixpoint-hang.rs:28:19
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
LL | impls_a::<()>(); LL | impls_a::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
note: required by a bound in `impls_a` note: required by a bound in `impls_a`
--> $DIR/inductive-not-on-stack.rs:25:15 --> $DIR/inductive-not-on-stack.rs:25:15
| |
@ -17,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `(): AR`
LL | impls_ar::<()>(); LL | impls_ar::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
note: required by a bound in `impls_ar` note: required by a bound in `impls_ar`
--> $DIR/inductive-not-on-stack.rs:38:16 --> $DIR/inductive-not-on-stack.rs:38:16
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
LL | impls_a::<()>(); LL | impls_a::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`mixed_cycles_1`)
note: required by a bound in `impls_a` note: required by a bound in `impls_a`
--> $DIR/mixed-cycles-1.rs:34:15 --> $DIR/mixed-cycles-1.rs:34:15
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `(): A`
LL | impls_a::<()>(); LL | impls_a::<()>();
| ^^ | ^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`mixed_cycles_2`)
note: required by a bound in `impls_a` note: required by a bound in `impls_a`
--> $DIR/mixed-cycles-2.rs:27:15 --> $DIR/mixed-cycles-2.rs:27:15
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
LL | Self::Assoc: A<T>, LL | Self::Assoc: A<T>,
| ^^^^ | ^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
note: the requirement `<() as A<T>>::Assoc: A<T>` appears on the `impl`'s method `f` but not on the corresponding trait's method note: the requirement `<() as A<T>>::Assoc: A<T>` appears on the `impl`'s method `f` but not on the corresponding trait's method
--> $DIR/normalize-param-env-2.rs:12:8 --> $DIR/normalize-param-env-2.rs:12:8
| |
@ -19,24 +18,18 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
| |
LL | Self::Assoc: A<T>, LL | Self::Assoc: A<T>,
| ^^^^ | ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed` error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
--> $DIR/normalize-param-env-2.rs:24:22 --> $DIR/normalize-param-env-2.rs:24:22
| |
LL | Self::Assoc: A<T>, LL | Self::Assoc: A<T>,
| ^^^^ | ^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
error[E0275]: overflow evaluating the requirement `(): A<T>` error[E0275]: overflow evaluating the requirement `(): A<T>`
--> $DIR/normalize-param-env-2.rs:27:10 --> $DIR/normalize-param-env-2.rs:27:10
| |
LL | <() as A<T>>::f(); LL | <() as A<T>>::f();
| ^^ | ^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>` error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
--> $DIR/normalize-param-env-2.rs:27:9 --> $DIR/normalize-param-env-2.rs:27:9
@ -44,7 +37,6 @@ error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
LL | <() as A<T>>::f(); LL | <() as A<T>>::f();
| ^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
note: required by a bound in `A::f` note: required by a bound in `A::f`
--> $DIR/normalize-param-env-2.rs:14:22 --> $DIR/normalize-param-env-2.rs:14:22
| |

View file

@ -3,16 +3,12 @@ error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
| |
LL | <T as Trait>::Assoc: Trait, LL | <T as Trait>::Assoc: Trait,
| ^^^^^ | ^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed` error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
--> $DIR/normalize-param-env-4.rs:18:26 --> $DIR/normalize-param-env-4.rs:18:26
| |
LL | <T as Trait>::Assoc: Trait, LL | <T as Trait>::Assoc: Trait,
| ^^^^^ | ^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
error[E0275]: overflow evaluating the requirement `T: Trait` error[E0275]: overflow evaluating the requirement `T: Trait`
--> $DIR/normalize-param-env-4.rs:31:19 --> $DIR/normalize-param-env-4.rs:31:19
@ -20,7 +16,6 @@ error[E0275]: overflow evaluating the requirement `T: Trait`
LL | impls_trait::<T>(); LL | impls_trait::<T>();
| ^ | ^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
note: required by a bound in `impls_trait` note: required by a bound in `impls_trait`
--> $DIR/normalize-param-env-4.rs:14:19 --> $DIR/normalize-param-env-4.rs:14:19
| |

View file

@ -4,7 +4,6 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
LL | impls::<W<_>>(); LL | impls::<W<_>>();
| ^^^^ | ^^^^
| |
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`exponential_trait_goals`)
note: required by a bound in `impls` note: required by a bound in `impls`
--> $DIR/exponential-trait-goals.rs:14:13 --> $DIR/exponential-trait-goals.rs:14:13
| |

View file

@ -1,12 +1,7 @@
//~ ERROR overflow evaluating the requirement `Self well-formed`
//~| ERROR overflow evaluating the requirement `Self: Trait`
// This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE. // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
//@ compile-flags: -Znext-solver --crate-type=lib //@ compile-flags: -Znext-solver --crate-type=lib
//@ check-fail //@ check-pass
#![recursion_limit = "0"] #![recursion_limit = "0"]
trait Trait {} trait Trait {}
impl Trait for u32 {} impl Trait for u32 {}
//~^ ERROR overflow evaluating the requirement `u32: Trait`
//~| ERROR overflow evaluating the requirement `u32 well-formed`

View file

@ -1,27 +0,0 @@
error[E0275]: overflow evaluating the requirement `Self: Trait`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
error[E0275]: overflow evaluating the requirement `Self well-formed`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
error[E0275]: overflow evaluating the requirement `u32: Trait`
--> $DIR/recursion-limit-zero-issue-115351.rs:10:16
|
LL | impl Trait for u32 {}
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
error[E0275]: overflow evaluating the requirement `u32 well-formed`
--> $DIR/recursion-limit-zero-issue-115351.rs:10:16
|
LL | impl Trait for u32 {}
| ^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0275`.