尽管有适当的特征约束,特征相关的 const 在特征定义上下文中不可用

Trait associated const is not available in trait definition context despite appropriate trait bound

这是我正在做的事情 (playground):

pub trait DisplayWidth {
    const DISPLAY_WIDTH: usize;

    fn chunks<'a>(s: &'a str) -> Chunks<'a, Self> {
        Chunks(s.chars(), PhantomData)
    }
}

pub struct Chunks<'a, T: ?Sized>(std::str::Chars<'a>, PhantomData<T>);

impl<'a, T: DisplayWidth> Iterator for Chunks<'a, T> {
    // 4 bytes in a max-width char
    type Item = SmallString<[u8; 4 * T::DISPLAY_WIDTH]>;

    fn next(&mut self) -> Option<Self::Item> {
        let mut s = SmallString::new();
        for _ in 0..T::DISPLAY_WIDTH {
            s.push(self.0.next()?);
        }
        Some(s)
    }
}

这会生成一个 E0599,但仅针对 type Item 定义:

error[E0599]: no associated item named `DISPLAY_WIDTH` found for type parameter `T` in the current scope
  --> src/geometry/tile.rs:23:41
   |
23 |     type Item = SmallString<[u8; 4 * T::DISPLAY_WIDTH]>;
   |                                         ^^^^^^^^^^^^^ associated item not found in `T`
   |
   = help: items from traits can only be used if the type parameter is bounded by the trait

有趣的是,rustc 根本不抱怨在 for 循环中使用关联的 const;就在关联的类型定义处。

我怀疑这是一个编译器错误:假设 TDisplayWidth 约束,它应该在特征关联类型定义上下文中可用,但事实并非如此。但是,我在提交针对 rustc 的错误报告之前在这里询问,因为我不是 100% 确定这一点。

我目前使用的解决方法很简单:定义一个单独的常量并使用它:

pub const CHUNK_WIDTH: usize = 4;
    type Item = SmallString<[u8; 4 * CHUNK_WIDTH]>;

有没有允许使用 DisplayWidth::DISPLAY_WIDTH 的解决方案?

这是数组长度的限制;它不能使用任何参数或通用边界,即使它们是作用域。这个问题是在稳定相关常量的过程中出现的,因此决定在没有它的情况下稳定它们。

此限制特定于数组长度参数,其他一切正常:

pub trait Shape {
    const SIDES: usize;
}

pub trait SimpleIter {
    const Item: usize;    
}

impl<T: Shape> SimpleIter for T {
    // this is fine
    const Item: usize = T::SIDES;
}

问题可以跟踪here and here