我正在Rust中编写一个固定大小的位序列类型,具有夜间功能generic_const_exprs
和int_roundings
,并且我能够按原样impl
BitAndAssign
(我没有包含正文,因为不需要验证第一个示例是否构建,第二个示例是否未构建(:
trait Bits {
const BITS: u32;
}
impl Bits for u32 {
const BITS: u32 = Self::BITS;
}
const fn bslen(x: u32, b: u32) -> usize {
x.div_ceil(b) as usize
}
struct BitSet<const X: u32, T: Bits = u32>
where
[(); bslen(X, T::BITS)]:
{
data: [T; bslen(X, T::BITS)]
}
use std::ops::BitAndAssign;
impl<const X: u32, const Y: u32, T: Bits>
BitAndAssign<&BitSet<Y, T>>
for BitSet<X, T>
where
[(); bslen(X, T::BITS)]:,
[(); bslen(Y, T::BITS)]:
{
fn bitand_assign(&mut self, other: &BitSet<Y, T>) {}
}
但当我尝试将其更改为使用Borrow<BitSet<Y, T>>
而不是&BitSet<Y, T>
时,就像这样:
use std::ops::BitAndAssign;
use std::borrow::Borrow;
impl<const X: u32, const Y: u32, T: Bits, BSY: Borrow<BitSet<Y, T>>>
BitAndAssign<BSY>
for BitSet<X, T>
where
[(); bslen(X, T::BITS)]:,
[(); bslen(Y, T::BITS)]:
{
fn bitand_assign(&mut self, other: BSY) {}
}
我得到一个错误:
error[E0207]: the const parameter `Y` is not constrained by the impl trait, self type, or predicates
--> src/minrep.rs:22:26
|
22 | impl<const X: u32, const Y: u32, T: Bits, BSY: Borrow<BitSet<Y, T>>>
| ^ unconstrained const parameter
|
我不知道这意味着什么,因为Y
是受约束的,也不知道为什么它只发生在第二种情况下。generic_const_exprs
不稳定,所以这可能只是一个编译器错误,但我想我应该问一下,以防我遗漏了一些明显或不太明显的东西。
一个BSY
类型可以为多个Y
s实现Borrow<BitSet<Y, T>>
。在这种情况下,知道BitSet<X, T>
实现BitAndAssign<BSY>
根本不足以让编译器推断Y
的值,因为有多个选项。
这就是编译器抱怨Y
不受约束的原因——给定类型BitSet<X, T>
及其对BitAndAssign<BSY>
特性的实现(对于特定类型BSY
(,编译器不一定能确定Y
的值。另一方面,给定类型BitSet<X, T>
及其对BitAndAssign<&BitSet<Y, T>>
特征的实现,编译器确切地知道在特征定义中使用Y
的什么值。