normalizing where-clauses is also coinductive, add tests
This commit is contained in:
parent
a7970c0b27
commit
7eb677e7eb
17 changed files with 255 additions and 20 deletions
|
@ -264,7 +264,10 @@ where
|
||||||
|
|
||||||
pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind {
|
pub(super) fn step_kind_for_source(&self, source: GoalSource) -> PathKind {
|
||||||
match (self.current_goal_kind, source) {
|
match (self.current_goal_kind, source) {
|
||||||
(CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => PathKind::Coinductive,
|
(_, GoalSource::NormalizeGoal(step_kind)) => step_kind,
|
||||||
|
(CurrentGoalKind::CoinductiveTrait, GoalSource::ImplWhereBound) => {
|
||||||
|
PathKind::Coinductive
|
||||||
|
}
|
||||||
_ => PathKind::Inductive,
|
_ => PathKind::Inductive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -670,8 +673,11 @@ where
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal<I, ty::NormalizesTo<I>>) {
|
pub(super) fn add_normalizes_to_goal(&mut self, mut goal: Goal<I, ty::NormalizesTo<I>>) {
|
||||||
goal.predicate =
|
goal.predicate = goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(
|
||||||
goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, goal.param_env));
|
self,
|
||||||
|
GoalSource::Misc,
|
||||||
|
goal.param_env,
|
||||||
|
));
|
||||||
self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal);
|
self.inspect.add_normalizes_to_goal(self.delegate, self.max_input_universe, goal);
|
||||||
self.nested_goals.normalizes_to_goals.push(goal);
|
self.nested_goals.normalizes_to_goals.push(goal);
|
||||||
}
|
}
|
||||||
|
@ -679,7 +685,7 @@ where
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
pub(super) fn add_goal(&mut self, source: GoalSource, mut goal: Goal<I, I::Predicate>) {
|
pub(super) fn add_goal(&mut self, source: GoalSource, mut goal: Goal<I, I::Predicate>) {
|
||||||
goal.predicate =
|
goal.predicate =
|
||||||
goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, goal.param_env));
|
goal.predicate.fold_with(&mut ReplaceAliasWithInfer::new(self, source, goal.param_env));
|
||||||
self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal);
|
self.inspect.add_goal(self.delegate, self.max_input_universe, source, goal);
|
||||||
self.nested_goals.goals.push((source, goal));
|
self.nested_goals.goals.push((source, goal));
|
||||||
}
|
}
|
||||||
|
@ -1100,6 +1106,7 @@ where
|
||||||
{
|
{
|
||||||
ecx: &'me mut EvalCtxt<'a, D>,
|
ecx: &'me mut EvalCtxt<'a, D>,
|
||||||
param_env: I::ParamEnv,
|
param_env: I::ParamEnv,
|
||||||
|
normalization_goal_source: GoalSource,
|
||||||
cache: HashMap<I::Ty, I::Ty>,
|
cache: HashMap<I::Ty, I::Ty>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1108,8 +1115,18 @@ where
|
||||||
D: SolverDelegate<Interner = I>,
|
D: SolverDelegate<Interner = I>,
|
||||||
I: Interner,
|
I: Interner,
|
||||||
{
|
{
|
||||||
fn new(ecx: &'me mut EvalCtxt<'a, D>, param_env: I::ParamEnv) -> Self {
|
fn new(
|
||||||
ReplaceAliasWithInfer { ecx, param_env, cache: Default::default() }
|
ecx: &'me mut EvalCtxt<'a, D>,
|
||||||
|
for_goal_source: GoalSource,
|
||||||
|
param_env: I::ParamEnv,
|
||||||
|
) -> Self {
|
||||||
|
let step_kind = ecx.step_kind_for_source(for_goal_source);
|
||||||
|
ReplaceAliasWithInfer {
|
||||||
|
ecx,
|
||||||
|
param_env,
|
||||||
|
normalization_goal_source: GoalSource::NormalizeGoal(step_kind),
|
||||||
|
cache: Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,7 +1149,7 @@ where
|
||||||
ty::AliasRelationDirection::Equate,
|
ty::AliasRelationDirection::Equate,
|
||||||
);
|
);
|
||||||
self.ecx.add_goal(
|
self.ecx.add_goal(
|
||||||
GoalSource::Misc,
|
self.normalization_goal_source,
|
||||||
Goal::new(self.cx(), self.param_env, normalizes_to),
|
Goal::new(self.cx(), self.param_env, normalizes_to),
|
||||||
);
|
);
|
||||||
infer_ty
|
infer_ty
|
||||||
|
@ -1161,7 +1178,7 @@ where
|
||||||
ty::AliasRelationDirection::Equate,
|
ty::AliasRelationDirection::Equate,
|
||||||
);
|
);
|
||||||
self.ecx.add_goal(
|
self.ecx.add_goal(
|
||||||
GoalSource::Misc,
|
self.normalization_goal_source,
|
||||||
Goal::new(self.cx(), self.param_env, normalizes_to),
|
Goal::new(self.cx(), self.param_env, normalizes_to),
|
||||||
);
|
);
|
||||||
infer_ct
|
infer_ct
|
||||||
|
|
|
@ -438,7 +438,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
|
||||||
|
|
||||||
let obligation;
|
let obligation;
|
||||||
match (child_mode, nested_goal.source()) {
|
match (child_mode, nested_goal.source()) {
|
||||||
(ChildMode::Trait(_) | ChildMode::Host(_), GoalSource::Misc) => {
|
(
|
||||||
|
ChildMode::Trait(_) | ChildMode::Host(_),
|
||||||
|
GoalSource::Misc | GoalSource::NormalizeGoal(_),
|
||||||
|
) => {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
(ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => {
|
(ChildMode::Trait(parent_trait_pred), GoalSource::ImplWhereBound) => {
|
||||||
|
|
|
@ -19,6 +19,8 @@ use std::marker::PhantomData;
|
||||||
|
|
||||||
use derive_where::derive_where;
|
use derive_where::derive_where;
|
||||||
use rustc_index::{Idx, IndexVec};
|
use rustc_index::{Idx, IndexVec};
|
||||||
|
#[cfg(feature = "nightly")]
|
||||||
|
use rustc_macros::HashStable_NoContext;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::data_structures::HashMap;
|
use crate::data_structures::HashMap;
|
||||||
|
@ -109,7 +111,8 @@ pub trait Delegate {
|
||||||
/// In the initial iteration of a cycle, we do not yet have a provisional
|
/// In the initial iteration of a cycle, we do not yet have a provisional
|
||||||
/// result. In the case we return an initial provisional result depending
|
/// result. In the case we return an initial provisional result depending
|
||||||
/// on the kind of cycle.
|
/// on the kind of cycle.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(HashStable_NoContext))]
|
||||||
pub enum PathKind {
|
pub enum PathKind {
|
||||||
Coinductive,
|
Coinductive,
|
||||||
Inductive,
|
Inductive,
|
||||||
|
|
|
@ -8,6 +8,7 @@ use derive_where::derive_where;
|
||||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||||
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||||
|
|
||||||
|
use crate::search_graph::PathKind;
|
||||||
use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
|
use crate::{self as ty, Canonical, CanonicalVarValues, Interner, Upcast};
|
||||||
|
|
||||||
pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
|
pub type CanonicalInput<I, T = <I as Interner>::Predicate> =
|
||||||
|
@ -78,6 +79,14 @@ pub enum GoalSource {
|
||||||
/// This is used in two places: projecting to an opaque whose hidden type
|
/// This is used in two places: projecting to an opaque whose hidden type
|
||||||
/// is already registered in the opaque type storage, and for rigid projections.
|
/// is already registered in the opaque type storage, and for rigid projections.
|
||||||
AliasWellFormed,
|
AliasWellFormed,
|
||||||
|
|
||||||
|
/// In case normalizing aliases in nested goals cycles, eagerly normalizing these
|
||||||
|
/// aliases in the context of the parent may incorrectly change the cycle kind.
|
||||||
|
/// Normalizing aliases in goals therefore tracks the original path kind for this
|
||||||
|
/// nested goal.
|
||||||
|
///
|
||||||
|
/// This is necessary for tests/ui/sized/coinductive-1.rs to compile.
|
||||||
|
NormalizeGoal(PathKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
|
#[derive_where(Clone; I: Interner, Goal<I, P>: Clone)]
|
||||||
|
|
|
@ -6,30 +6,90 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
|
||||||
|
|
|
|
||||||
= help: remove one of these features
|
= help: remove one of these features
|
||||||
|
|
||||||
error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
error[E0275]: overflow evaluating the requirement `&T: ~const ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:19:49
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `&T: ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:19:49
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||||
|
| ^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||||
--> $DIR/issue-88119.rs:21:5
|
--> $DIR/issue-88119.rs:21:5
|
||||||
|
|
|
|
||||||
LL | [(); name_len::<T>()]:,
|
LL | [(); name_len::<T>()]:,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `<&T as ConstName>`
|
note: required by a bound in `<&T as ConstName>`
|
||||||
|
--> $DIR/issue-88119.rs:21:5
|
||||||
|
|
|
||||||
|
LL | [(); name_len::<T>()]:,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||||
--> $DIR/issue-88119.rs:21:10
|
--> $DIR/issue-88119.rs:21:10
|
||||||
|
|
|
|
||||||
LL | [(); name_len::<T>()]:,
|
LL | [(); name_len::<T>()]:,
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required by a bound in `<&T as ConstName>`
|
||||||
|
--> $DIR/issue-88119.rs:21:5
|
||||||
|
|
|
||||||
|
LL | [(); name_len::<T>()]:,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&T as ConstName>`
|
||||||
|
|
||||||
error[E0284]: type annotations needed: cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
error[E0275]: overflow evaluating the requirement `&mut T: ~const ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:26:49
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `&mut T: ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:26:49
|
||||||
|
|
|
||||||
|
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||||
--> $DIR/issue-88119.rs:28:5
|
--> $DIR/issue-88119.rs:28:5
|
||||||
|
|
|
|
||||||
LL | [(); name_len::<T>()]:,
|
LL | [(); name_len::<T>()]:,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `the constant `name_len::<T>()` can be evaluated`
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required by a bound in `<&mut T as ConstName>`
|
note: required by a bound in `<&mut T as ConstName>`
|
||||||
|
--> $DIR/issue-88119.rs:28:5
|
||||||
|
|
|
||||||
|
LL | [(); name_len::<T>()]:,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `[(); name_len::<T>()] well-formed`
|
||||||
--> $DIR/issue-88119.rs:28:10
|
--> $DIR/issue-88119.rs:28:10
|
||||||
|
|
|
|
||||||
LL | [(); name_len::<T>()]:,
|
LL | [(); name_len::<T>()]:,
|
||||||
| ^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required by a bound in `<&mut T as ConstName>`
|
||||||
|
--> $DIR/issue-88119.rs:28:5
|
||||||
|
|
|
||||||
|
LL | [(); name_len::<T>()]:,
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `<&mut T as ConstName>`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error[E0275]: overflow evaluating the requirement `&&mut u8: ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:33:35
|
||||||
|
|
|
||||||
|
LL | pub const ICE_1: &'static [u8] = <&&mut u8 as ConstName>::NAME_BYTES;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0284`.
|
error[E0275]: overflow evaluating the requirement `&mut &u8: ConstName`
|
||||||
|
--> $DIR/issue-88119.rs:34:35
|
||||||
|
|
|
||||||
|
LL | pub const ICE_2: &'static [u8] = <&mut &u8 as ConstName>::NAME_BYTES;
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
struct Node<C: Trait<Self>>(C::Assoc);
|
struct Node<C: Trait<Self>>(C::Assoc);
|
||||||
|
|
||||||
trait Trait<T> {
|
trait Trait<T> {
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
error[E0275]: overflow evaluating the requirement `Vec<u8>: Trait<String>`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
note: required for `Vec<u8>` to implement `Trait<String>`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:22:12
|
||||||
|
|
|
||||||
|
LL | impl<L, R> Trait<R> for L
|
||||||
|
| ^^^^^^^^ ^
|
||||||
|
LL | where
|
||||||
|
LL | L: Trait<R>,
|
||||||
|
| -------- unsatisfied trait bound introduced here
|
||||||
|
note: required by a bound in `transmute`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:29:17
|
||||||
|
|
|
||||||
|
LL | fn transmute<L: Trait<R>, R>(r: L) -> <L::Proof as Trait<R>>::Proof { r }
|
||||||
|
| ^^^^^^^^ required by this bound in `transmute`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
|
@ -0,0 +1,49 @@
|
||||||
|
error[E0275]: overflow evaluating the requirement `Vec<u8>: Trait<String>`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:33
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^
|
||||||
|
|
|
||||||
|
note: required by a bound in `transmute`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:29:17
|
||||||
|
|
|
||||||
|
LL | fn transmute<L: Trait<R>, R>(r: L) -> <L::Proof as Trait<R>>::Proof { r }
|
||||||
|
| ^^^^^^^^ required by this bound in `transmute`
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == String`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof: Sized`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: the return type of a function must have a statically known size
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof well-formed`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
|
||||||
|
--> $DIR/item-bound-via-impl-where-clause.rs:31:21
|
||||||
|
|
|
||||||
|
LL | let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
|
@ -0,0 +1,39 @@
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
// A variation of #135246 where the cyclic bounds are part of
|
||||||
|
// the impl instead of the impl associated item.
|
||||||
|
|
||||||
|
trait Trait<R>: Sized {
|
||||||
|
type Proof: Trait<R, Proof = Self>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to use indirection here as we otherwise normalize
|
||||||
|
// `<L::Proof as Trait<R>>::Proof` before recursing into
|
||||||
|
// `R: Trait<R, Proof = <L::Proof as Trait<R>>::Proof>`.
|
||||||
|
trait Indir<L: Trait<R>, R>: Trait<R, Proof = <L::Proof as Trait<R>>::Proof> {}
|
||||||
|
impl<L, R> Indir<L, R> for R
|
||||||
|
where
|
||||||
|
L: Trait<R>,
|
||||||
|
R: Trait<R, Proof = <L::Proof as Trait<R>>::Proof>,
|
||||||
|
{}
|
||||||
|
|
||||||
|
impl<L, R> Trait<R> for L
|
||||||
|
where
|
||||||
|
L: Trait<R>,
|
||||||
|
R: Indir<L, R>,
|
||||||
|
{
|
||||||
|
type Proof = R;
|
||||||
|
}
|
||||||
|
fn transmute<L: Trait<R>, R>(r: L) -> <L::Proof as Trait<R>>::Proof { r }
|
||||||
|
fn main() {
|
||||||
|
let s: String = transmute::<_, String>(vec![65_u8, 66, 67]);
|
||||||
|
//~^ ERROR overflow evaluating the requirement `Vec<u8>: Trait<String>`
|
||||||
|
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
|
||||||
|
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == String`
|
||||||
|
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof: Sized`
|
||||||
|
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof well-formed`
|
||||||
|
//[next]~| ERROR overflow evaluating the requirement `<<Vec<u8> as Trait<String>>::Proof as Trait<String>>::Proof == _`
|
||||||
|
println!("{}", s); // ABC
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
error[E0391]: cycle detected when computing layout of `<[Hello] as Normalize>::Assoc`
|
||||||
|
|
|
||||||
|
= note: ...which requires computing layout of `Hello`...
|
||||||
|
= note: ...which again requires computing layout of `<[Hello] as Normalize>::Assoc`, completing the cycle
|
||||||
|
= note: cycle used when computing layout of `Hello`
|
||||||
|
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0391`.
|
|
@ -1,6 +1,10 @@
|
||||||
// Regression test for #129541
|
// Regression test for #129541
|
||||||
//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391]
|
//~^ ERROR cycle detected when computing layout of `<[Hello] as Normalize>::Assoc` [E0391]
|
||||||
|
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
trait Bound {}
|
trait Bound {}
|
||||||
trait Normalize {
|
trait Normalize {
|
||||||
type Assoc;
|
type Assoc;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// Regression test for #129541
|
// Regression test for #129541
|
||||||
|
|
||||||
//@ revisions: unique multiple
|
//@ revisions: unique_curr unique_next multiple_curr multiple_next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[unique_next] compile-flags: -Znext-solver
|
||||||
|
//@[multiple_next] compile-flags: -Znext-solver
|
||||||
//@ error-pattern: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
|
//@ error-pattern: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
|
||||||
|
|
||||||
trait Bound {}
|
trait Bound {}
|
||||||
|
@ -8,7 +11,7 @@ trait Normalize {
|
||||||
type Assoc;
|
type Assoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(multiple)]
|
#[cfg(any(multiple_curr, multiple_next))]
|
||||||
impl<T: Bound> Normalize for T {
|
impl<T: Bound> Normalize for T {
|
||||||
type Assoc = T;
|
type Assoc = T;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
error: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
error: reached the recursion limit finding the struct tail for `<[Hello] as Normalize>::Assoc`
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
|
||||||
|
|
||||||
|
error: aborting due to 1 previous error
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue