mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 18:08:55 +03:00
Improve test for unwrapped nullable tag union bindgen
This commit is contained in:
parent
d687c2397b
commit
b2b5f8cf93
@ -41,8 +41,13 @@ pub fn write_types(types: &Types, buf: &mut String) -> fmt::Result {
|
||||
RocTagUnion::NullableWrapped { .. } => {
|
||||
todo!();
|
||||
}
|
||||
RocTagUnion::NullableUnwrapped { .. } => {
|
||||
todo!();
|
||||
RocTagUnion::NullableUnwrapped {
|
||||
name,
|
||||
null_tag,
|
||||
non_null_tag,
|
||||
non_null_payload,
|
||||
} => {
|
||||
todo!("Write nullable unwrapped tag union.")
|
||||
}
|
||||
RocTagUnion::NonNullableUnwrapped { .. } => {
|
||||
todo!();
|
||||
|
@ -526,234 +526,89 @@ fn cons_list_of_strings() {
|
||||
r#"
|
||||
#[derive(Clone, PartialEq, PartialOrd, Copy, Eq, Ord, Hash, Debug)]
|
||||
#[repr(u8)]
|
||||
pub enum tag_MyTagUnion {
|
||||
Bar = 0,
|
||||
Baz = 1,
|
||||
Blah = 2,
|
||||
Foo = 3,
|
||||
pub enum tag_StrConsList {
|
||||
Cons = 0,
|
||||
Nil = 1,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub union union_MyTagUnion {
|
||||
Bar: u128,
|
||||
Blah: i32,
|
||||
Foo: core::mem::ManuallyDrop<roc_std::RocStr>,
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct StrConsList {
|
||||
pointer: *mut core::mem::ManuallyDrop<roc_std::RocStr>,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct MyTagUnion {
|
||||
variant: union_MyTagUnion,
|
||||
tag: tag_MyTagUnion,
|
||||
}
|
||||
|
||||
impl MyTagUnion {
|
||||
pub fn tag(&self) -> tag_MyTagUnion {
|
||||
self.tag
|
||||
}
|
||||
|
||||
/// Construct a tag named Bar, with the appropriate payload
|
||||
pub fn Bar(payload: u128) -> Self {
|
||||
Self {
|
||||
tag: tag_MyTagUnion::Bar,
|
||||
variant: union_MyTagUnion {
|
||||
Bar: payload
|
||||
},
|
||||
impl StrConsList {
|
||||
pub fn tag(&self) -> tag_StrConsList {
|
||||
if self.pointer.is_null() {
|
||||
tag_StrConsList::Nil
|
||||
} else {
|
||||
tag_StrConsList::Cons
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Bar and convert it to Bar's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Bar(self) -> u128 {
|
||||
self.variant.Bar
|
||||
}
|
||||
/// Construct a tag named Cons, with the appropriate payload
|
||||
pub fn Cons(payload: roc_std::RocStr) -> Self {
|
||||
let size = core::mem::size_of::<roc_std::RocStr>();
|
||||
let align = core::mem::align_of::<roc_std::RocStr>();
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Bar and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Bar(&self) -> u128 {
|
||||
self.variant.Bar
|
||||
}
|
||||
unsafe {
|
||||
let pointer =
|
||||
roc_alloc(size, align as u32) as *mut core::mem::ManuallyDrop<roc_std::RocStr>;
|
||||
|
||||
/// Construct a tag named Baz
|
||||
pub fn Baz() -> Self {
|
||||
Self {
|
||||
tag: tag_MyTagUnion::Baz,
|
||||
variant: unsafe {
|
||||
core::mem::transmute::<
|
||||
core::mem::MaybeUninit<union_MyTagUnion>,
|
||||
union_MyTagUnion,
|
||||
>(core::mem::MaybeUninit::uninit())
|
||||
},
|
||||
*pointer = core::mem::ManuallyDrop::new(payload);
|
||||
|
||||
Self { pointer }
|
||||
}
|
||||
}
|
||||
|
||||
/// Other `into_` methods return a payload, but since the Baz tag
|
||||
/// Unsafely assume the given StrConsList has a .tag() of Cons and convert it to Cons's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Cons(self) -> roc_std::RocStr {
|
||||
let payload = core::mem::ManuallyDrop::take(&mut *self.pointer);
|
||||
let align = core::mem::align_of::<roc_std::RocStr>() as u32;
|
||||
|
||||
roc_dealloc(self.pointer as *mut core::ffi::c_void, align);
|
||||
|
||||
payload
|
||||
}
|
||||
|
||||
/// Unsafely assume the given StrConsList has a .tag() of Cons and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Cons(&self) -> &roc_std::RocStr {
|
||||
&*self.pointer
|
||||
}
|
||||
|
||||
/// Construct a tag named Nil
|
||||
pub fn Nil() -> Self {
|
||||
Self {
|
||||
pointer: core::ptr::null_mut(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Other `into_` methods return a payload, but since the Nil tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub fn into_Baz(self) -> () {
|
||||
pub fn into_Nil(self) -> () {
|
||||
()
|
||||
}
|
||||
|
||||
/// Other `as` methods return a payload, but since the Baz tag
|
||||
/// Other `as` methods return a payload, but since the Nil tag
|
||||
/// has no payload, this does nothing and is only here for completeness.
|
||||
pub unsafe fn as_Baz(&self) -> () {
|
||||
pub unsafe fn as_Nil(&self) -> () {
|
||||
()
|
||||
}
|
||||
|
||||
/// Construct a tag named Blah, with the appropriate payload
|
||||
pub fn Blah(payload: i32) -> Self {
|
||||
Self {
|
||||
tag: tag_MyTagUnion::Blah,
|
||||
variant: union_MyTagUnion {
|
||||
Blah: payload
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Blah and convert it to Blah's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Blah(self) -> i32 {
|
||||
self.variant.Blah
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Blah and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Blah(&self) -> i32 {
|
||||
self.variant.Blah
|
||||
}
|
||||
|
||||
/// Construct a tag named Foo, with the appropriate payload
|
||||
pub fn Foo(payload: roc_std::RocStr) -> Self {
|
||||
Self {
|
||||
tag: tag_MyTagUnion::Foo,
|
||||
variant: union_MyTagUnion {
|
||||
Foo: core::mem::ManuallyDrop::new(payload)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and convert it to Foo's payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn into_Foo(mut self) -> roc_std::RocStr {
|
||||
core::mem::ManuallyDrop::take(&mut self.variant.Foo)
|
||||
}
|
||||
|
||||
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and return its payload.
|
||||
/// (always examine .tag() first to make sure this is the correct variant!)
|
||||
pub unsafe fn as_Foo(&self) -> &roc_std::RocStr {
|
||||
&self.variant.Foo
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MyTagUnion {
|
||||
impl Drop for StrConsList {
|
||||
fn drop(&mut self) {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => {}
|
||||
tag_MyTagUnion::Baz => {}
|
||||
tag_MyTagUnion::Blah => {}
|
||||
tag_MyTagUnion::Foo => unsafe { core::mem::ManuallyDrop::drop(&mut self.variant.Foo) },
|
||||
}
|
||||
}
|
||||
}
|
||||
if !self.pointer.is_null() {
|
||||
let payload = unsafe { &*self.pointer };
|
||||
let align = core::mem::align_of::<roc_std::RocStr>() as u32;
|
||||
|
||||
impl PartialEq for MyTagUnion {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
if self.tag != other.tag {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => self.variant.Bar == other.variant.Bar,
|
||||
tag_MyTagUnion::Baz => true,
|
||||
tag_MyTagUnion::Blah => self.variant.Blah == other.variant.Blah,
|
||||
tag_MyTagUnion::Foo => self.variant.Foo == other.variant.Foo,
|
||||
unsafe {
|
||||
roc_dealloc(self.pointer as *mut core::ffi::c_void, align);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for MyTagUnion {}
|
||||
|
||||
impl PartialOrd for MyTagUnion {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
|
||||
match self.tag.partial_cmp(&other.tag) {
|
||||
Some(core::cmp::Ordering::Equal) => {}
|
||||
not_eq => return not_eq,
|
||||
}
|
||||
|
||||
unsafe {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => self.variant.Bar.partial_cmp(&other.variant.Bar),
|
||||
tag_MyTagUnion::Baz => Some(core::cmp::Ordering::Equal),
|
||||
tag_MyTagUnion::Blah => self.variant.Blah.partial_cmp(&other.variant.Blah),
|
||||
tag_MyTagUnion::Foo => self.variant.Foo.partial_cmp(&other.variant.Foo),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for MyTagUnion {
|
||||
fn cmp(&self, other: &Self) -> core::cmp::Ordering {
|
||||
match self.tag.cmp(&other.tag) {
|
||||
core::cmp::Ordering::Equal => {}
|
||||
not_eq => return not_eq,
|
||||
}
|
||||
|
||||
unsafe {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => self.variant.Bar.cmp(&other.variant.Bar),
|
||||
tag_MyTagUnion::Baz => core::cmp::Ordering::Equal,
|
||||
tag_MyTagUnion::Blah => self.variant.Blah.cmp(&other.variant.Blah),
|
||||
tag_MyTagUnion::Foo => self.variant.Foo.cmp(&other.variant.Foo),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for MyTagUnion {
|
||||
fn clone(&self) -> Self {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => Self {
|
||||
variant: union_MyTagUnion {
|
||||
Bar: unsafe { self.variant.Bar.clone() },
|
||||
},
|
||||
tag: tag_MyTagUnion::Bar,
|
||||
},
|
||||
tag_MyTagUnion::Baz => Self {
|
||||
variant: unsafe {
|
||||
core::mem::transmute::<
|
||||
core::mem::MaybeUninit<union_MyTagUnion>,
|
||||
union_MyTagUnion,
|
||||
>(core::mem::MaybeUninit::uninit())
|
||||
},
|
||||
tag: tag_MyTagUnion::Baz,
|
||||
},
|
||||
tag_MyTagUnion::Blah => Self {
|
||||
variant: union_MyTagUnion {
|
||||
Blah: unsafe { self.variant.Blah.clone() },
|
||||
},
|
||||
tag: tag_MyTagUnion::Blah,
|
||||
},
|
||||
tag_MyTagUnion::Foo => Self {
|
||||
variant: union_MyTagUnion {
|
||||
Foo: unsafe { self.variant.Foo.clone() },
|
||||
},
|
||||
tag: tag_MyTagUnion::Foo,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for MyTagUnion {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.write_str("MyTagUnion::")?;
|
||||
|
||||
unsafe {
|
||||
match self.tag {
|
||||
tag_MyTagUnion::Bar => f.debug_tuple("Bar").field(&self.variant.Bar).finish(),
|
||||
tag_MyTagUnion::Baz => f.write_str("Baz"),
|
||||
tag_MyTagUnion::Blah => f.debug_tuple("Blah").field(&self.variant.Blah).finish(),
|
||||
tag_MyTagUnion::Foo => f.debug_tuple("Foo").field(&self.variant.Foo).finish(),
|
||||
}
|
||||
drop(payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user