Open
Description
So my current understanding is that all constants used in types must be well formed.
I wasn't able to find any discussion on what exactly that means though 😅
I think that for concrete constants the following must hold:
Constants evaluate successfully
This means that all of 1usize - 2
, panic!()
, loop {}
and [1, 2, 3][3]
are not well formed as constants.
An evaluated constant must satisfy all lang invariants of its type
So something like unsafe { std::mem::transmute::<u8, bool>(2) }
is not wf.
I do think that the following would be well formed though, as it only breaks library invariants:
const V: &'static str = unsafe { std::mem::transmute::<&[u8], &str>(&[0xff, 0xff, 0xff, 0xff]) };
The more interesting case are polymorphic constants as we can't just evaluate them.
For these I think the following rule is appropriate
A polymorphic constant is well formed, iff all possible concrete instances are well formed
Some examples:
use std::mem::size_of;
fn foo<T>() -> [u8; size_of::<T>()] {}
// well formed, as `size_of::<T>()` returns a wf constant no matter the type of `T`.
fn bar<T>() -> [u8; 64 / size_of::<T>()] {}
// not well formed, as `64 / size_of::<()>()` does not evaluate successfully and is therefore not wf.
struct Baz<const V: bool>;
fn baz<T>() -> Baz<{ unsafe { std::mem::transmute::<u8, bool>(size_of::<T>() as u8) }> {}
// not well formed, for any `T` with `size_of::<T>() > 3` the final value is not a valid bool.
Does this definition make sense?
Metadata
Metadata
Assignees
Labels
No labels