我试图使用特性进行某种类型级别的编程,遇到一个边缘情况,编译器在证明约束的同时无限扩展一个类型,而我希望它能够收敛。
这个错误也是不稳定的,因为小的变化,我不期望会造成改变,突然导致程序编译成功。
我很难理解第一个让编译器疯狂的程序有什么特别之处。是不是缺少了某种约束?
有错误的原始程序
这是最初的节目。为了重现错误,这已经大大减少了。最初的代码实际上是由一个名为typ的实验性类型级编程机箱生成的。
// Just setting up some simple type level lists.
pub struct HCons<H, T> {
pub head: H,
pub tail: T,
}
pub struct HNil;
pub trait HList {}
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}
// Trait-encoded type level function that maps over these lists
pub trait MapList<L> {
type Output;
}
impl MapList<HNil> for () {
type Output = HNil;
}
impl<X, T: HList> MapList<HCons<X, T>> for () where (): DoMapList<T> {
type Output = HCons<X, <() as DoMapList<T>>::Output>;
}
// Trait-encoded type level function that calls the other function
pub trait DoMapList<L: HList> where Self::Output: HList {
type Output;
}
impl<L: HList> DoMapList<L> for () where
(): MapList<L>,
<() as MapList<L>>::Output: HList
{
type Output = <() as MapList<L>>::Output;
}
// Helper type
type DoMapListOp<L> = <() as DoMapList<L>>::Output;
pub struct Intermediate<A: HList> where (): DoMapList<A> {
pub foo: DoMapListOp<A>,
}
pub trait Tester<A: HList> where (): DoMapList<A> {
fn foo() -> Intermediate<A>;
}
struct Bar;
impl Tester<HCons<i32, HNil>> for Bar {
fn foo() -> Intermediate<HCons<i32, HNil>> {
return Intermediate { foo: HCons { head: 5, tail: HNil {} } }
}
}error[E0275]: overflow evaluating the requirement `(): DoMapList<_>`
--> <source>:55:16
|
55 | return Intermediate { foo: HCons { head: 5, tail: HNil {} } }
| ^^^^^^^^^^^^
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`example`)
note: required because of the requirements on the impl of `MapList<HCons<_, _>>` for `()`
--> <source>:20:19
|
20 | impl<X, T: HList> MapList<HCons<X, T>> for () where (): DoMapList<T> {
| ^^^^^^^^^^^^^^^^^^^^ ^^
note: required because of the requirements on the impl of `DoMapList<HCons<_, _>>` for `()`
--> <source>:30:16
|
30 | impl<L: HList> DoMapList<L> for () where
| ^^^^^^^^^^^^ ^^
= note: 126 redundant requirements hidden
= note: required because of the requirements on the impl of `DoMapList<HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, HCons<_, _>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` for `()`
note: required by a bound in `Intermediate`
--> <source>:43:45
|
43 | pub struct Intermediate<A: HList> where (): DoMapList<A> {
| ^^^^^^^^^^^^ required by this bound in `Intermediate`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.
Compiler returned: 1删除Intermediate新类型,编译
下面是我删除Intermediate新类型的版本。这是由于某种原因成功构建的。
// Just setting up some simple type level lists.
pub struct HCons<H, T> {
pub head: H,
pub tail: T,
}
pub struct HNil;
pub trait HList {}
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}
// Trait-encoded type level function that maps over these lists
pub trait MapList<L> {
type Output;
}
impl MapList<HNil> for () {
type Output = HNil;
}
impl<X, T: HList> MapList<HCons<X, T>> for () where (): DoMapList<T> {
type Output = HCons<X, <() as DoMapList<T>>::Output>;
}
// Trait-encoded type level function that calls the other function
pub trait DoMapList<L: HList> where Self::Output: HList {
type Output;
}
impl<L: HList> DoMapList<L> for () where
(): MapList<L>,
<() as MapList<L>>::Output: HList
{
type Output = <() as MapList<L>>::Output;
}
// Helper type
type DoMapListOp<L> = <() as DoMapList<L>>::Output;
pub trait Tester<A: HList> where (): DoMapList<A> {
fn foo() -> DoMapListOp<A>;
}
struct Bar;
impl Tester<HCons<i32, HNil>> for Bar {
fn foo() -> DoMapListOp<HCons<i32, HNil>> {
return HCons { head: 5, tail: HNil {} }
}
}删除DoMapList特性,编译
接下来是一个删除中间DoMapList特性的版本。这也是成功构建的。
// Just setting up some simple type level lists.
pub struct HCons<H, T> {
pub head: H,
pub tail: T,
}
pub struct HNil;
pub trait HList {}
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}
// Trait-encoded type level function that maps over these lists
pub trait MapList<L> {
type Output;
}
impl MapList<HNil> for () {
type Output = HNil;
}
impl<X, T: HList> MapList<HCons<X, T>> for () where (): MapList<T> {
type Output = HCons<X, <() as MapList<T>>::Output>;
}
// Helper type
type DoMapListOp<L> = <() as MapList<L>>::Output;
pub struct Intermediate<A: HList> where (): MapList<A> {
pub foo: DoMapListOp<A>,
}
pub trait Tester<A: HList> where (): MapList<A> {
fn foo() -> Intermediate<A>;
}
struct Bar;
impl Tester<HCons<i32, HNil>> for Bar {
fn foo() -> Intermediate<HCons<i32, HNil>> {
return Intermediate { foo: HCons { head: 5, tail: HNil {} } }
}
}MapList特性调用自身,编译
最后,我有一个版本,我保留了DoMapList特性,但是让MapList特性直接调用自己。这也是成功构建的。
// Just setting up some simple type level lists.
pub struct HCons<H, T> {
pub head: H,
pub tail: T,
}
pub struct HNil;
pub trait HList {}
impl HList for HNil {}
impl<H, T: HList> HList for HCons<H, T> {}
// Trait-encoded type level function that maps over these lists
pub trait MapList<L> {
type Output;
}
impl MapList<HNil> for () {
type Output = HNil;
}
impl<X, T: HList> MapList<HCons<X, T>> for () where (): MapList<T> {
type Output = HCons<X, <() as MapList<T>>::Output>;
}
// Trait-encoded type level function that calls the other function
pub trait DoMapList<L: HList> where Self::Output: HList {
type Output;
}
impl<L: HList> DoMapList<L> for () where
(): MapList<L>,
<() as MapList<L>>::Output: HList
{
type Output = <() as MapList<L>>::Output;
}
// Helper type
type DoMapListOp<L> = <() as DoMapList<L>>::Output;
pub struct Intermediate<A: HList> where (): DoMapList<A> {
pub foo: DoMapListOp<A>,
}
pub trait Tester<A: HList> where (): DoMapList<A> {
fn foo() -> Intermediate<A>;
}
struct Bar;
impl Tester<HCons<i32, HNil>> for Bar {
fn foo() -> Intermediate<HCons<i32, HNil>> {
return Intermediate { foo: HCons { head: 5, tail: HNil {} } }
}
}发布于 2022-06-07 12:29:58
有人在铁锈编程的不和告诉我,这是一个缺陷的特点系统。
https://stackoverflow.com/questions/72519759
复制相似问题