Rust编译器为何无法识别Test<D>的实现以支持Test<C>递归调用?
为何Rust编译器无法识别
Test<D>的recursive_descent()实现,并用它处理Test<C>中的调用? 你编写了如下Rust代码,期望Test<C>的recursive_descent()方法能调用Test<D>的同名方法完成递归,但编译器抛出了 trait 约束未满足的错误,尽管Test<D>明明有自己的recursive_descent()实现。
use std::marker::PhantomData; struct C; struct D; trait Dereffable { type Next; } impl Dereffable for C { type Next = D; } // NOTE: D 未实现 Dereffable! #[repr(transparent)] struct Test<TYP> { addr: usize, _marker: PhantomData<TYP>, } impl<TYP: Dereffable> Test<TYP> { fn recursive_descent(&self) -> usize { let next = self.deref_inner(); next.recursive_descent() } fn deref_inner(&self) -> &Test<TYP::Next> { unsafe { &*(self.addr as *const Test<TYP::Next>) } } } impl Test<D> { fn recursive_descent(&self) -> usize { self.addr } } #[test] fn test() { let d = Test::<D> { addr: 1337, _marker: PhantomData, }; let c = Test::<C> { addr: &d as *const _ as usize, _marker: PhantomData, }; assert_eq!(c.recursive_descent(), 1337); }
错误信息:
error[E0599]: 引用`&Test<<TYP as Dereffable>::Next>`存在方法`recursive_descent`,但未满足其 trait 约束 --> src/tests2.rs | | next.recursive_descent() | ^^^^^^^^^^^^^^^^^ 无法在`&Test<<TYP as Dereffable>::Next>`上调用该方法,因未满足 trait 约束 | note: 未满足 trait 约束`<TYP as Dereffable>::Next: Dereffable` --> src/tests2.rs | | impl<TYP: Dereffable> Test<TYP> { | ^^^^^^^^^^ --------- | | | 此处引入未满足的 trait 约束 For more information about this error, try `rustc --explain E0599`.
问题原因
Rust编译器处理泛型代码时,必须保证所有符合约束的输入类型都能通过编译,而不是只针对某个特定类型生效。
在你的代码中,impl<TYP: Dereffable> Test<TYP>里的next.recursive_descent()调用,编译器会基于当前泛型上下文查找方法:
- 首先,编译器看到
next的类型是&Test<TYP::Next>,会先检查是否有泛型impl提供该方法——也就是impl<U: Dereffable> Test<U>中的recursive_descent(),但这个impl要求U必须实现Dereffable,而你的代码里TYP::Next(也就是D)并没有实现Dereffable,所以这个路径走不通。 - 其次,编译器不会在泛型上下文中提前预判
TYP::Next就是D,也不会优先匹配具体的impl Test<D>。泛型代码需要对所有满足TYP: Dereffable的类型都有效,比如如果有另一个类型E实现了Dereffable且Next是F,那Test<E>的recursive_descent()也必须能编译,而你当前的代码无法保证这一点。
简单来说,编译器在泛型impl里看不到Test<TYP::Next>的具体实现,只能依赖你给出的泛型约束来判断方法是否存在。
解决办法
可以通过定义一个独立的trait来抽象递归逻辑,用trait约束链让编译器确认每个环节都有对应的实现:
use std::marker::PhantomData; struct C; struct D; trait Dereffable { type Next; } impl Dereffable for C { type Next = D; } // 定义递归下降的trait trait RecursiveDescent { fn recursive_descent(&self) -> usize; } #[repr(transparent)] struct Test<TYP> { addr: usize, _marker: PhantomData<TYP>, } // 给Test<TYP>实现RecursiveDescent,同时约束Test<TYP::Next>也必须实现该trait impl<TYP: Dereffable> RecursiveDescent for Test<TYP> where Test<TYP::Next>: RecursiveDescent, { fn recursive_descent(&self) -> usize { let next = self.deref_inner(); next.recursive_descent() } } // 给Test<D>实现终止逻辑 impl RecursiveDescent for Test<D> { fn recursive_descent(&self) -> usize { self.addr } } impl<TYP: Dereffable> Test<TYP> { fn deref_inner(&self) -> &Test<TYP::Next> { unsafe { &*(self.addr as *const Test<TYP::Next>) } } } #[test] fn test() { let d = Test::<D> { addr: 1337, _marker: PhantomData, }; let c = Test::<C> { addr: &d as *const _ as usize, _marker: PhantomData, }; assert_eq!(c.recursive_descent(), 1337); }
这里通过where Test<TYP::Next>: RecursiveDescent的约束,让编译器明确知道Test<TYP::Next>一定有recursive_descent()方法,不管是泛型实现还是像Test<D>这样的具体实现,从而解决了约束不满足的问题。
内容的提问来源于stack exchange,提问作者Kristoffer
相关产品推荐
相关产品推荐

