首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试着理解编译失败的周边特征

试着理解编译失败的周边特征
EN

Stack Overflow用户
提问于 2022-06-06 15:14:42
回答 1查看 62关注 0票数 1

我试图使用特性进行某种类型级别的编程,遇到一个边缘情况,编译器在证明约束的同时无限扩展一个类型,而我希望它能够收敛。

这个错误也是不稳定的,因为小的变化,我不期望会造成改变,突然导致程序编译成功。

我很难理解第一个让编译器疯狂的程序有什么特别之处。是不是缺少了某种约束?

有错误的原始程序

这是最初的节目。为了重现错误,这已经大大减少了。最初的代码实际上是由一个名为typ的实验性类型级编程机箱生成的。

代码语言:javascript
复制
// 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 {} } }
    }
}
代码语言:javascript
复制
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新类型的版本。这是由于某种原因成功构建的。

代码语言:javascript
复制
// 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特性的版本。这也是成功构建的。

代码语言:javascript
复制
// 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特性直接调用自己。这也是成功构建的。

代码语言:javascript
复制
// 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 {} } }
    }
}

哥德波特

EN

回答 1

Stack Overflow用户

发布于 2022-06-07 12:29:58

有人在铁锈编程的不和告诉我,这是一个缺陷的特点系统。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72519759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档