在模板化类型上使用多个递归方法版本进行递归(例如,对于 PageTable<Level>)

问题描述 投票:0回答:1

为什么 Rust 编译器不能看到

Test<D>
有自己的
recursive_descent()
实现,然后在为
next.recursive_descent()
生成的
recursive_descent()
版本中将其用于
Test<C>

use std::marker::PhantomData;

struct C;
struct D;

trait Dereffable {
    type Next;
}

impl Dereffable for C {
    type Next = D;
}

// NOTE: D is not 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]: the method `recursive_descent` exists for reference `&Test<<TYP as Dereffable>::Next>`, but its trait bounds were not satisfied
  --> src/tests2.rs
   |
   |         next.recursive_descent()
   |              ^^^^^^^^^^^^^^^^^ method cannot be called on `&Test<<TYP as Dereffable>::Next>` due to unsatisfied trait bounds
   |
note: trait bound `<TYP as Dereffable>::Next: Dereffable` was not satisfied
  --> src/tests2.rs
   |
   | impl<TYP: Dereffable> Test<TYP> {
   |           ^^^^^^^^^^  ---------
   |           |
   |           unsatisfied trait bound introduced here

For more information about this error, try `rustc --explain E0599`.
recursion rust compiler-errors embedded osdev
1个回答
0
投票

在这个答案中我忽略了这个程序的安全性。

为了设置正确实现

recursive_descent
所需的边界,我们需要一个特质
RecursiveDescent
:

trait RecursiveDescent {
    fn recursive_descent(&self) -> usize;
}

这使我们能够在允许的情况下准确地实现

RecursiveDescent
进行测试:

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()
    }
}

整个节目(游乐场):

use std::marker::PhantomData;

struct C;
struct D;

trait Dereffable {
    type Next;
}

impl Dereffable for C {
    type Next = D;
}

// NOTE: D is not Dereffable!

#[repr(transparent)]
struct Test<TYP> {
    addr: usize,
    _marker: PhantomData<TYP>,
}

trait RecursiveDescent {
    fn recursive_descent(&self) -> usize;
}

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()
    }
}

impl<TYP: Dereffable> Test<TYP> {
    fn deref_inner(&self) -> &Test<TYP::Next> {
        unsafe { &*(self.addr as *const Test<TYP::Next>) }
    }
}

impl RecursiveDescent for 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);
}
© www.soinside.com 2019 - 2024. All rights reserved.