-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Open
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)A-inferenceArea: Type inferenceArea: Type inferenceC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.Fixed by the next-generation trait solver, `-Znext-solver`.
Description
The following code causes the latest nightly (2023-05-16) to choke, it can also be seen on the playground.
#![feature(ptr_metadata)]
use core::ptr::Pointee;
struct TypedHandle<E: ?Sized> {
metadata: <E as Pointee>::Metadata,
}
type NodeHandle<T> = TypedHandle<Node<T>>;
struct Node<T> {
element: T,
next: NodeHandle<T>,
prev: NodeHandle<T>,
}Credits to Chayim Friedman for this reduced example.
And the compiler, much confused it appears, spits out the following error:
error[[E0284]](https://doc.rust-lang.org/nightly/error_codes/E0284.html): type annotations needed
--> src/lib.rs:13:11
|
13 | next: NodeHandle<T>,
| ^^^^^^^^^^^^^ cannot infer type
|
= note: cannot satisfy `<Node<T> as Pointee>::Metadata == _`
note: required because it appears within the type `TypedHandle<Node<T>>`
--> src/lib.rs:5:8
|
5 | struct TypedHandle<E: ?Sized> {
| ^^^^^^^^^^^
= note: only the last field of a struct may have a dynamically sized type
= help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
|
13 | next: &NodeHandle<T>,
| +
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
13 | next: Box<NodeHandle<T>>,
| ++++ +The compiler accepts the code:
- If the metadata is stored in a
NonNull<E>inTypedHandle. - If the
?Sizedbound is removed fromEinTypedHandle. - If the
where NodeHandle<T>: Sizedbound is added onNode.
Given the messages, and the fixes, it appears that the compiler fails to realize that <E as Pointee>::Metadata is always Sized, regardless of whether E is Sized or not, even though Metadata is necessarily Sized since its bounds do not specify ?Sized. This in turn would lead the compiler to expect that TypedHandle may be unsized, and thus reject any code where it is not the last field of a struct.
Metadata
Metadata
Assignees
Labels
A-associated-itemsArea: Associated items (types, constants & functions)Area: Associated items (types, constants & functions)A-inferenceArea: Type inferenceArea: Type inferenceC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.Fixed by the next-generation trait solver, `-Znext-solver`.