-
Notifications
You must be signed in to change notification settings - Fork 13.5k
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
?Sized
bound is removed fromE
inTypedHandle
. - If the
where NodeHandle<T>: Sized
bound 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`.