mirror of https://github.com/rust-lang/rust.git
Higher ranked goal source, do overflow handling less badly
This commit is contained in:
parent
3e03b1b190
commit
34e91ece90
|
@ -273,6 +273,8 @@ pub enum GoalSource {
|
|||
/// they are from an impl where-clause. This is necessary due to
|
||||
/// backwards compatability, cc trait-system-refactor-initiatitive#70.
|
||||
ImplWhereBound,
|
||||
/// Instantiating a higher-ranked goal and re-proving it.
|
||||
InstantiateHigherRanked,
|
||||
}
|
||||
|
||||
/// Possible ways the given goal can be proven.
|
||||
|
|
|
@ -127,6 +127,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
|
|||
let source = match source {
|
||||
GoalSource::Misc => "misc",
|
||||
GoalSource::ImplWhereBound => "impl where-bound",
|
||||
GoalSource::InstantiateHigherRanked => "higher-ranked goal",
|
||||
};
|
||||
writeln!(this.f, "ADDED GOAL ({source}): {goal:?}")?
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
|||
} else {
|
||||
self.infcx.enter_forall(kind, |kind| {
|
||||
let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
|
||||
self.add_goal(GoalSource::ImplWhereBound, goal);
|
||||
self.add_goal(GoalSource::InstantiateHigherRanked, goal);
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ use rustc_infer::traits::solve::inspect::ProbeKind;
|
|||
use rustc_infer::traits::solve::{CandidateSource, GoalSource, MaybeCause};
|
||||
use rustc_infer::traits::{
|
||||
self, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, Obligation,
|
||||
PredicateObligation, SelectionError, TraitEngine,
|
||||
ObligationCause, PredicateObligation, SelectionError, TraitEngine,
|
||||
};
|
||||
use rustc_middle::ty;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
|
||||
use super::eval_ctxt::GenerateProofTree;
|
||||
use super::inspect::{ProofTreeInferCtxtExt, ProofTreeVisitor};
|
||||
|
@ -219,14 +219,14 @@ fn fulfillment_error_for_no_solution<'tcx>(
|
|||
}
|
||||
ty::PredicateKind::Subtype(pred) => {
|
||||
let (a, b) = infcx.enter_forall_and_leak_universe(
|
||||
root_obligation.predicate.kind().rebind((pred.a, pred.b)),
|
||||
obligation.predicate.kind().rebind((pred.a, pred.b)),
|
||||
);
|
||||
let expected_found = ExpectedFound::new(true, a, b);
|
||||
FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
|
||||
}
|
||||
ty::PredicateKind::Coerce(pred) => {
|
||||
let (a, b) = infcx.enter_forall_and_leak_universe(
|
||||
root_obligation.predicate.kind().rebind((pred.a, pred.b)),
|
||||
obligation.predicate.kind().rebind((pred.a, pred.b)),
|
||||
);
|
||||
let expected_found = ExpectedFound::new(false, a, b);
|
||||
FulfillmentErrorCode::SubtypeError(expected_found, TypeError::Sorts(expected_found))
|
||||
|
@ -272,6 +272,20 @@ fn fulfillment_error_for_stalled<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
fn find_best_leaf_obligation<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let obligation = infcx.resolve_vars_if_possible(obligation.clone());
|
||||
infcx
|
||||
.visit_proof_tree(
|
||||
obligation.clone().into(),
|
||||
&mut BestObligation { obligation: obligation.clone() },
|
||||
)
|
||||
.break_value()
|
||||
.unwrap_or(obligation)
|
||||
}
|
||||
|
||||
struct BestObligation<'tcx> {
|
||||
obligation: PredicateObligation<'tcx>,
|
||||
}
|
||||
|
@ -279,10 +293,9 @@ struct BestObligation<'tcx> {
|
|||
impl<'tcx> BestObligation<'tcx> {
|
||||
fn with_derived_obligation(
|
||||
&mut self,
|
||||
derive_obligation: impl FnOnce(&mut Self) -> PredicateObligation<'tcx>,
|
||||
derived_obligation: PredicateObligation<'tcx>,
|
||||
and_then: impl FnOnce(&mut Self) -> <Self as ProofTreeVisitor<'tcx>>::Result,
|
||||
) -> <Self as ProofTreeVisitor<'tcx>>::Result {
|
||||
let derived_obligation = derive_obligation(self);
|
||||
let old_obligation = std::mem::replace(&mut self.obligation, derived_obligation);
|
||||
let res = and_then(self);
|
||||
self.obligation = old_obligation;
|
||||
|
@ -298,13 +311,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
}
|
||||
|
||||
fn visit_goal(&mut self, goal: &super::inspect::InspectGoal<'_, 'tcx>) -> Self::Result {
|
||||
// FIXME: Throw out candidates that have no failing WC and >0 failing misc goal.
|
||||
// This most likely means that the goal just didn't unify at all, e.g. a param
|
||||
// candidate with an alias in it.
|
||||
let candidates = goal.candidates();
|
||||
// FIXME: Throw out candidates that have no failing WC and >1 failing misc goal.
|
||||
|
||||
// HACK:
|
||||
if self.obligation.recursion_depth > 3 {
|
||||
return ControlFlow::Break(self.obligation.clone());
|
||||
}
|
||||
|
||||
let [candidate] = candidates.as_slice() else {
|
||||
return ControlFlow::Break(self.obligation.clone());
|
||||
|
@ -320,80 +330,71 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
|||
let tcx = goal.infcx().tcx;
|
||||
let mut impl_where_bound_count = 0;
|
||||
for nested_goal in candidate.instantiate_nested_goals(self.span()) {
|
||||
if matches!(nested_goal.source(), GoalSource::ImplWhereBound) {
|
||||
impl_where_bound_count += 1;
|
||||
} else {
|
||||
continue;
|
||||
let obligation;
|
||||
match nested_goal.source() {
|
||||
GoalSource::Misc => {
|
||||
continue;
|
||||
}
|
||||
GoalSource::ImplWhereBound => {
|
||||
obligation = Obligation {
|
||||
cause: derive_cause(
|
||||
tcx,
|
||||
candidate.kind(),
|
||||
self.obligation.cause.clone(),
|
||||
impl_where_bound_count,
|
||||
parent_trait_pred,
|
||||
),
|
||||
param_env: nested_goal.goal().param_env,
|
||||
predicate: nested_goal.goal().predicate,
|
||||
recursion_depth: self.obligation.recursion_depth + 1,
|
||||
};
|
||||
impl_where_bound_count += 1;
|
||||
}
|
||||
GoalSource::InstantiateHigherRanked => {
|
||||
obligation = self.obligation.clone();
|
||||
}
|
||||
}
|
||||
|
||||
// Skip nested goals that hold.
|
||||
//FIXME: We should change the max allowed certainty based on if we're
|
||||
// visiting an ambiguity or error obligation.
|
||||
if matches!(nested_goal.result(), Ok(Certainty::Yes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.with_derived_obligation(
|
||||
|self_| {
|
||||
let mut cause = self_.obligation.cause.clone();
|
||||
cause = match candidate.kind() {
|
||||
ProbeKind::TraitCandidate {
|
||||
source: CandidateSource::Impl(impl_def_id),
|
||||
result: _,
|
||||
} => {
|
||||
let idx = impl_where_bound_count - 1;
|
||||
if let Some((_, span)) = tcx
|
||||
.predicates_of(impl_def_id)
|
||||
.instantiate_identity(tcx)
|
||||
.iter()
|
||||
.nth(idx)
|
||||
{
|
||||
cause.derived_cause(parent_trait_pred, |derived| {
|
||||
traits::ImplDerivedObligation(Box::new(
|
||||
traits::ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: impl_def_id,
|
||||
impl_def_predicate_index: Some(idx),
|
||||
span,
|
||||
},
|
||||
))
|
||||
})
|
||||
} else {
|
||||
cause
|
||||
}
|
||||
}
|
||||
ProbeKind::TraitCandidate {
|
||||
source: CandidateSource::BuiltinImpl(..),
|
||||
result: _,
|
||||
} => {
|
||||
cause.derived_cause(parent_trait_pred, traits::BuiltinDerivedObligation)
|
||||
}
|
||||
_ => cause,
|
||||
};
|
||||
|
||||
Obligation {
|
||||
cause,
|
||||
param_env: nested_goal.goal().param_env,
|
||||
predicate: nested_goal.goal().predicate,
|
||||
recursion_depth: self_.obligation.recursion_depth + 1,
|
||||
}
|
||||
},
|
||||
|self_| self_.visit_goal(&nested_goal),
|
||||
)?;
|
||||
self.with_derived_obligation(obligation, |this| nested_goal.visit_with(this))?;
|
||||
}
|
||||
|
||||
ControlFlow::Break(self.obligation.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn find_best_leaf_obligation<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
) -> PredicateObligation<'tcx> {
|
||||
let obligation = infcx.resolve_vars_if_possible(obligation.clone());
|
||||
infcx
|
||||
.visit_proof_tree(
|
||||
obligation.clone().into(),
|
||||
&mut BestObligation { obligation: obligation.clone() },
|
||||
)
|
||||
.break_value()
|
||||
.unwrap_or(obligation)
|
||||
fn derive_cause<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
candidate_kind: ProbeKind<'tcx>,
|
||||
mut cause: ObligationCause<'tcx>,
|
||||
idx: usize,
|
||||
parent_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> ObligationCause<'tcx> {
|
||||
match candidate_kind {
|
||||
ProbeKind::TraitCandidate { source: CandidateSource::Impl(impl_def_id), result: _ } => {
|
||||
if let Some((_, span)) =
|
||||
tcx.predicates_of(impl_def_id).instantiate_identity(tcx).iter().nth(idx)
|
||||
{
|
||||
cause = cause.derived_cause(parent_trait_pred, |derived| {
|
||||
traits::ImplDerivedObligation(Box::new(traits::ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: impl_def_id,
|
||||
impl_def_predicate_index: Some(idx),
|
||||
span,
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
ProbeKind::TraitCandidate { source: CandidateSource::BuiltinImpl(..), result: _ } => {
|
||||
cause = cause.derived_cause(parent_trait_pred, traits::BuiltinDerivedObligation);
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
cause
|
||||
}
|
||||
|
|
|
@ -128,10 +128,8 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
|
|||
/// back their inference constraints. This function modifies
|
||||
/// the state of the `infcx`.
|
||||
pub fn visit_nested_no_probe<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
|
||||
if self.goal.depth < visitor.config().max_depth {
|
||||
for goal in self.instantiate_nested_goals(visitor.span()) {
|
||||
try_visit!(visitor.visit_goal(&goal));
|
||||
}
|
||||
for goal in self.instantiate_nested_goals(visitor.span()) {
|
||||
try_visit!(goal.visit_with(visitor));
|
||||
}
|
||||
|
||||
V::Result::output()
|
||||
|
@ -360,6 +358,14 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
|
|||
source,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn visit_with<V: ProofTreeVisitor<'tcx>>(&self, visitor: &mut V) -> V::Result {
|
||||
if self.depth < visitor.config().max_depth {
|
||||
try_visit!(visitor.visit_goal(self));
|
||||
}
|
||||
|
||||
V::Result::output()
|
||||
}
|
||||
}
|
||||
|
||||
/// The public API to interact with proof trees.
|
||||
|
|
|
@ -6,7 +6,7 @@ LL | impl<T: ?Sized + TwoW> Trait for W<T> {}
|
|||
LL | impl<T: ?Sized + TwoW> Trait for T {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>>>>>>>>>`
|
||||
|
|
||||
= note: overflow evaluating the requirement `W<W<W<W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>>>>: TwoW`
|
||||
= note: overflow evaluating the requirement `W<W<W<W<_>>>>: TwoW`
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`coherence_fulfill_overflow`)
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
error[E0275]: overflow evaluating the requirement `(): Trait`
|
||||
error[E0275]: overflow evaluating the requirement `(): Inductive`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:32:19
|
||||
|
|
||||
LL | impls_trait::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `Inductive`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:12:16
|
||||
|
|
||||
LL | impl<T: Trait> Inductive for T {}
|
||||
| ----- ^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `Trait`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:9:34
|
||||
|
|
||||
|
@ -18,7 +11,14 @@ LL | impl<T: Inductive + Coinductive> Trait for T {}
|
|||
| --------- ^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 2 redundant requirements hidden
|
||||
note: required for `()` to implement `Inductive`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:12:16
|
||||
|
|
||||
LL | impl<T: Trait> Inductive for T {}
|
||||
| ----- ^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 7 redundant requirements hidden
|
||||
= note: required for `()` to implement `Trait`
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
|
||||
|
@ -26,19 +26,12 @@ note: required by a bound in `impls_trait`
|
|||
LL | fn impls_trait<T: Trait>() {}
|
||||
| ^^^^^ required by this bound in `impls_trait`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `(): TraitRev`
|
||||
error[E0275]: overflow evaluating the requirement `(): CoinductiveRev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:35:23
|
||||
|
|
||||
LL | impls_trait_rev::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `CoinductiveRev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:27:19
|
||||
|
|
||||
LL | impl<T: TraitRev> CoinductiveRev for T {}
|
||||
| -------- ^^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `TraitRev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:21:40
|
||||
|
|
||||
|
@ -46,7 +39,14 @@ LL | impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
|
|||
| -------------- ^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 2 redundant requirements hidden
|
||||
note: required for `()` to implement `CoinductiveRev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:27:19
|
||||
|
|
||||
LL | impl<T: TraitRev> CoinductiveRev for T {}
|
||||
| -------- ^^^^^^^^^^^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 7 redundant requirements hidden
|
||||
= note: required for `()` to implement `TraitRev`
|
||||
note: required by a bound in `impls_trait_rev`
|
||||
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
|
||||
error[E0275]: overflow evaluating the requirement `W<W<_>>: Trait`
|
||||
--> $DIR/inductive-fixpoint-hang.rs:31:19
|
||||
|
|
||||
LL | impls_trait::<W<_>>();
|
||||
| ^^^^
|
||||
|
|
||||
note: required for `W<W<_>>` to implement `Trait`
|
||||
note: required for `W<W<W<_>>>` to implement `Trait`
|
||||
--> $DIR/inductive-fixpoint-hang.rs:22:17
|
||||
|
|
||||
LL | impl<T: ?Sized> Trait for W<W<T>>
|
||||
|
@ -12,8 +12,8 @@ LL | impl<T: ?Sized> Trait for W<W<T>>
|
|||
LL | where
|
||||
LL | W<T>: Trait,
|
||||
| ----- unsatisfied trait bound introduced here
|
||||
= note: 3 redundant requirements hidden
|
||||
= note: required for `W<W<W<W<W<_>>>>>` to implement `Trait`
|
||||
= note: 8 redundant requirements hidden
|
||||
= note: required for `W<W<W<W<W<W<W<W<W<W<W<_>>>>>>>>>>>` to implement `Trait`
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/inductive-fixpoint-hang.rs:28:19
|
||||
|
|
||||
|
|
|
@ -39,8 +39,8 @@ fn impls_ar<T: AR>() {}
|
|||
|
||||
fn main() {
|
||||
impls_a::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): A`
|
||||
//~^ ERROR overflow evaluating the requirement `(): B`
|
||||
|
||||
impls_ar::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): CR`
|
||||
//~^ ERROR overflow evaluating the requirement `(): AR`
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
error[E0275]: overflow evaluating the requirement `(): A`
|
||||
error[E0275]: overflow evaluating the requirement `(): B`
|
||||
--> $DIR/inductive-not-on-stack.rs:41:15
|
||||
|
|
||||
LL | impls_a::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `B`
|
||||
--> $DIR/inductive-not-on-stack.rs:22:12
|
||||
|
|
||||
LL | impl<T: A> B for T {}
|
||||
| - ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `A`
|
||||
--> $DIR/inductive-not-on-stack.rs:21:16
|
||||
|
|
||||
|
@ -18,7 +11,14 @@ LL | impl<T: B + C> A for T {}
|
|||
| - ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 2 redundant requirements hidden
|
||||
note: required for `()` to implement `B`
|
||||
--> $DIR/inductive-not-on-stack.rs:22:12
|
||||
|
|
||||
LL | impl<T: A> B for T {}
|
||||
| - ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 7 redundant requirements hidden
|
||||
= note: required for `()` to implement `A`
|
||||
note: required by a bound in `impls_a`
|
||||
--> $DIR/inductive-not-on-stack.rs:25:15
|
||||
|
@ -26,19 +26,12 @@ note: required by a bound in `impls_a`
|
|||
LL | fn impls_a<T: A>() {}
|
||||
| ^ required by this bound in `impls_a`
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `(): CR`
|
||||
error[E0275]: overflow evaluating the requirement `(): AR`
|
||||
--> $DIR/inductive-not-on-stack.rs:44:16
|
||||
|
|
||||
LL | impls_ar::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `AR`
|
||||
--> $DIR/inductive-not-on-stack.rs:34:18
|
||||
|
|
||||
LL | impl<T: CR + BR> AR for T {}
|
||||
| -- ^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `BR`
|
||||
--> $DIR/inductive-not-on-stack.rs:35:13
|
||||
|
|
||||
|
@ -53,7 +46,14 @@ LL | impl<T: BR> CR for T {}
|
|||
| -- ^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
note: required for `()` to implement `AR`
|
||||
--> $DIR/inductive-not-on-stack.rs:34:18
|
||||
|
|
||||
LL | impl<T: CR + BR> AR for T {}
|
||||
| -- ^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 6 redundant requirements hidden
|
||||
= note: required for `()` to implement `AR`
|
||||
note: required by a bound in `impls_ar`
|
||||
--> $DIR/inductive-not-on-stack.rs:38:16
|
||||
|
|
|
@ -35,5 +35,5 @@ fn impls_a<T: A>() {}
|
|||
|
||||
fn main() {
|
||||
impls_a::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): C`
|
||||
//~^ ERROR overflow evaluating the requirement `(): CInd`
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
error[E0275]: overflow evaluating the requirement `(): C`
|
||||
error[E0275]: overflow evaluating the requirement `(): CInd`
|
||||
--> $DIR/mixed-cycles-1.rs:37:15
|
||||
|
|
||||
LL | impls_a::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `CInd`
|
||||
--> $DIR/mixed-cycles-1.rs:28:21
|
||||
|
|
||||
LL | impl<T: ?Sized + C> CInd for T {}
|
||||
| - ^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `B`
|
||||
--> $DIR/mixed-cycles-1.rs:31:28
|
||||
|
|
||||
|
@ -18,6 +11,22 @@ LL | impl<T: ?Sized + CInd + C> B for T {}
|
|||
| ---- ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `C`
|
||||
--> $DIR/mixed-cycles-1.rs:32:25
|
||||
|
|
||||
LL | impl<T: ?Sized + B + A> C for T {}
|
||||
| - ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `CInd`
|
||||
--> $DIR/mixed-cycles-1.rs:28:21
|
||||
|
|
||||
LL | impl<T: ?Sized + C> CInd for T {}
|
||||
| - ^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 4 redundant requirements hidden
|
||||
= note: required for `()` to implement `B`
|
||||
note: required for `()` to implement `BInd`
|
||||
--> $DIR/mixed-cycles-1.rs:23:21
|
||||
|
|
||||
|
|
|
@ -28,5 +28,5 @@ fn impls_a<T: A>() {}
|
|||
|
||||
fn main() {
|
||||
impls_a::<()>();
|
||||
//~^ ERROR overflow evaluating the requirement `(): B`
|
||||
//~^ ERROR overflow evaluating the requirement `(): BInd`
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
error[E0275]: overflow evaluating the requirement `(): B`
|
||||
error[E0275]: overflow evaluating the requirement `(): BInd`
|
||||
--> $DIR/mixed-cycles-2.rs:30:15
|
||||
|
|
||||
LL | impls_a::<()>();
|
||||
| ^^
|
||||
|
|
||||
note: required for `()` to implement `BInd`
|
||||
--> $DIR/mixed-cycles-2.rs:22:21
|
||||
|
|
||||
LL | impl<T: ?Sized + B> BInd for T {}
|
||||
| - ^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
note: required for `()` to implement `B`
|
||||
--> $DIR/mixed-cycles-2.rs:25:24
|
||||
|
|
||||
|
@ -18,7 +11,14 @@ LL | impl<T: ?Sized + BInd> B for T {}
|
|||
| ---- ^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
note: required for `()` to implement `BInd`
|
||||
--> $DIR/mixed-cycles-2.rs:22:21
|
||||
|
|
||||
LL | impl<T: ?Sized + B> BInd for T {}
|
||||
| - ^^^^ ^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 6 redundant requirements hidden
|
||||
= note: required for `()` to implement `BInd`
|
||||
note: required for `()` to implement `A`
|
||||
--> $DIR/mixed-cycles-2.rs:24:28
|
||||
|
|
|
@ -5,14 +5,14 @@ LL | impls_trait::<Four<Four<Four<Four<()>>>>>();
|
|||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "18"]` attribute to your crate (`global_cache`)
|
||||
note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>>>` to implement `Trait`
|
||||
note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>` to implement `Trait`
|
||||
--> $DIR/global-cache.rs:12:16
|
||||
|
|
||||
LL | impl<T: Trait> Trait for Inc<T> {}
|
||||
| ----- ^^^^^ ^^^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 3 redundant requirements hidden
|
||||
= note: 5 redundant requirements hidden
|
||||
= note: required for `Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<Inc<()>>>>>>>>>>>>>>>>` to implement `Trait`
|
||||
note: required by a bound in `impls_trait`
|
||||
--> $DIR/global-cache.rs:15:19
|
||||
|
|
Loading…
Reference in New Issue