Skip to content

Can an Option<T> with a niche be treated as if it were a T for initialization? #583

@ruriww

Description

@ruriww

See the following example code

let mut x = None::<&str>;

const { assert!(
  size_of::<&str>() == size_of::<Option<&str>>() &&
  align_of::<&str>() == align_of::<Option<&str>>()
) };

unsafe {
  // because Option contains a &str and their sizes are equal, the field offset is zero
  let ptr = &mut x as *mut Option<_> as *mut &str;

  // use ptr::write if T needs drop
  // rationale: &str has a niche at null, and since `&mut Option<T>` can produce `&mut T`
  // the option must contain `T` exactly,  given their sizes are the same there cannot be 
  // hidden padding/discriminant bytes, and the `None` value must use a value invalid for `&str`
  *ptr = "hello world";
}

assert_eq!(x, Some("hello world"));

Currently, I can only imagine the comment above to be a logical proof and not a guarantee.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions