为什么 Y 是一个受约束的 const 泛型,在这里报告为不受约束?
Why is Y, a constrained const generic, reported as unconstrained here?
我正在用 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
实现 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
的什么值,因为它存在于特征定义中。
我正在用 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
实现 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
的什么值,因为它存在于特征定义中。