Description
The following does compile (surprisingly - as opposed to #53191):
#![allow(incomplete_features)]
// Without `generic_const_exprs`, this fails to compile and `T` is reported as "never unused",
// regardless of whether the array size below is a (`const`) expression (`0*0`) or a literal (`0`).
//
// Note that `generic_const_exprs` "shouldn't" need to be required for this at all - there are no
// `const` generic parameters here.
#![feature(generic_const_exprs)]
// Based on LeafNode and InternalNode in BTreeMap's internals.
pub struct Node<T> {
// When we change the array size from a `const` expression (such as `0*0`) to a literal (such
// as `0`), we get an error: parameter `T` is never used.
//
// For anyone using this as a workaround (instead of `PhantomData`): Even if you have `0*0` as
// the array size here (and hence it takes no space), such an empty array field can affect
// alignment its owner struct.
_links: [Option<Box<Node<T>>>; 0*0],
}
However, the same code (without comments), and with the only change being in the array size changed from a (const) expression 0*0
to a literal 0
, then fails to compile:
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
pub struct Node<T> {
_links: [Option<Box<Node<T>>>; 0], // <-- array size changed from 0*0 to 0
}
The problem reported here is not whether this should compile or not. Rather, it's the inconsistency depending on the array size's being an expression vs. literal.
But while you're at it, please also shed some light on the the intended behavior, or planned behavior.
Side note: Putting the array size within braces makes it compile, too:
#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
pub struct Node<T> {
#[allow(unused_braces)]
_links: [Option<Box<Node<T>>>; {0}],
}
Motivation: This took hours to pinpoint/minimize (while I was hoping to minimize another issue, so that I can progress with co-allocation in library/alloc). So I hope this will save people's time.
Update: The above minimization is not fully narrowed down - beyond my current bandwidth. Under some circumstances, recursive types with a generic parameter that is used solely for recursion (that is, not in any PhantomData
-based field) do compile even without generic_const_exprs
. See LeafNode
and InternalNode
in BTreeMap's internals: it compiles, even though library/alloc/src/lib.rs
does not use generic_const_exprs
. (NodeRef
itself does use PhantomData
, but the (indirectly) recursive types LeafNode
and InternalNode
themselves do not.)
However, that doesn't affect the inconsistency reported in this ticket.