[英]Why does Rust want Self to be Sized when implementing an associated const with an associated type?
Consider the following code: 请考虑以下代码:
pub trait Trait {
type Type;
const CONST: Self::Type;
}
impl<T> Trait for T {
type Type = u8;
const CONST: u8 = 42;
}
My (incorrect?) understanding of Rust is that this code should work and that all Sized
types should now implement Trait
and have an associated type ( Type = u8
) and const ( CONST = 42
). 我(不正确?)对Rust的理解是这个代码应该工作,并且所有Sized
类型现在应该实现Trait
并且具有关联类型( Type = u8
)和const( CONST = 42
)。 Unsized types shouldn't implement this trait since impl<T>
implicitly assumes T
to be Sized
. Unsized类型不应该实现此特征,因为impl<T>
隐式假设T
为Sized
。
However, when I try to compile the code I get the error message: 但是,当我尝试编译代码时,我收到错误消息:
error[E0277]: the size for value values of type `T` cannot be known at compilation time
--> src/main.rs:8:3
|
8 | const CONST: u8 = 42;
| ^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `T`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types--sized>
= help: consider adding a `where T: std::marker::Sized` bound
= note: required because of the requirements on the impl of `Trait` for `T`
My questions: 我的问题:
T
isn't Sized
here? 为什么Rust认为T
在这里没有Sized
? Explicitly stating T: Sized
doesn't help . 明确说明T: Sized
并没有帮助 。 T
isn't Sized
. 让我们假装T
没有Sized
。 Why does Rust care whether T
is sized or not here? 为什么Rust会关注T
是否大小? Nothing depends on it, as far as I can tell (the associated type and const aren't related to T
). 就我所知,没有任何东西取决于它(相关的类型和const与T
无关)。 Changing the code to T: ?Sized
works, so clearly T
being unsized isn't actually problematic. 代码更改为T: ?Sized
的作品,这么清楚T
被未施胶实际上不是问题。 According to this GitHub issue , this appears to be a known bug that has been around at least since Rust 1.23 (longer, I suspect). 根据这个GitHub问题 ,这似乎是一个已知的错误,至少从Rust 1.23开始(我怀疑更长)。
It is not clear what is causing the problem and when/if it will be fixed. 目前尚不清楚导致问题的原因以及何时/是否会解决问题。 There is only a rather vague hypothesis: 只有一个相当模糊的假设:
I'm not familiar with the compiler internals, but my hypothesis is that associated types and constants depending on a type parameter are not evaluated properly in the constant expression evaluator . 我不熟悉编译器内部,但我的假设是,在常量表达式求值程序中不能正确评估依赖于类型参数的关联类型和常量 。 In this case, it's associated types that do not reduce well:
const VAL: Self::T = 5;
在这种情况下,它的关联类型不能很好地减少:const VAL: Self::T = 5;
forces Rust to do some fancy type of computation at compile time in order to type check, but there's a bug in the code for such computations. 强制Rust在编译时进行一些奇特的计算类型以便进行类型检查,但是代码中存在这样的计算错误。
There are a few ways to work around the issue: 有几种方法可以解决这个问题:
Specifying a concrete type in the trait: 在特征中指定具体类型:
pub trait Trait { // type Type; // no longer used const CONST: u8; }
Opting T
out of Sized
: 选择T
Sized
:
impl<T: ?Sized> Trait for T { type Type = u8; const CONST: u8 = 42; }
Use a function instead of a constant (credit goes to @PeterHall): 使用函数而不是常量(信用转到@PeterHall):
pub trait Trait { type Type; fn const_val() -> Self::Type; } impl<T> Trait for T { type Type = u8; fn const_val() -> Self::Type { 42 } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.