ir: Handle NonZero and simplify Option<NonZero> like we simplify Option<NonNull>.
Fixes #646
This commit is contained in:
parent
f922f68531
commit
c47ee1516b
@ -517,6 +517,23 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_zeroable(&self) -> Option<Self> {
|
||||
let (kind, signed) = match *self {
|
||||
Type::Primitive(PrimitiveType::Integer {
|
||||
zeroable: false,
|
||||
kind,
|
||||
signed,
|
||||
}) => (kind, signed),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(Type::Primitive(PrimitiveType::Integer {
|
||||
kind,
|
||||
signed,
|
||||
zeroable: true,
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn make_nullable(&self) -> Option<Self> {
|
||||
match *self {
|
||||
Type::Ptr {
|
||||
@ -543,12 +560,52 @@ impl Type {
|
||||
}
|
||||
}
|
||||
|
||||
fn nonzero_to_primitive(&self) -> Option<Self> {
|
||||
let path = match *self {
|
||||
Type::Path(ref p) => p,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
if !path.generics().is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let name = path.name();
|
||||
if !name.starts_with("NonZero") {
|
||||
return None;
|
||||
}
|
||||
|
||||
let (kind, signed) = match path.name() {
|
||||
"NonZeroU8" => (IntKind::B8, false),
|
||||
"NonZeroU16" => (IntKind::B16, false),
|
||||
"NonZeroU32" => (IntKind::B32, false),
|
||||
"NonZeroU64" => (IntKind::B64, false),
|
||||
"NonZeroUSize" => (IntKind::Size, false),
|
||||
"NonZeroI8" => (IntKind::B8, true),
|
||||
"NonZeroI16" => (IntKind::B16, true),
|
||||
"NonZeroI32" => (IntKind::B32, true),
|
||||
"NonZeroI64" => (IntKind::B64, true),
|
||||
"NonZeroISize" => (IntKind::Size, true),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(Type::Primitive(PrimitiveType::Integer {
|
||||
zeroable: false,
|
||||
signed,
|
||||
kind,
|
||||
}))
|
||||
}
|
||||
|
||||
fn simplified_type(&self, config: &Config) -> Option<Self> {
|
||||
let path = match *self {
|
||||
Type::Path(ref p) => p,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
if path.generics().is_empty() {
|
||||
return self.nonzero_to_primitive();
|
||||
}
|
||||
|
||||
if path.generics().len() != 1 {
|
||||
return None;
|
||||
}
|
||||
@ -559,7 +616,15 @@ impl Type {
|
||||
None => Cow::Borrowed(unsimplified_generic),
|
||||
};
|
||||
match path.name() {
|
||||
"Option" => generic.make_nullable(),
|
||||
"Option" => {
|
||||
if let Some(nullable) = generic.make_nullable() {
|
||||
return Some(nullable);
|
||||
}
|
||||
if let Some(zeroable) = generic.make_zeroable() {
|
||||
return Some(zeroable);
|
||||
}
|
||||
None
|
||||
}
|
||||
"NonNull" => Some(Type::Ptr {
|
||||
ty: Box::new(generic.into_owned()),
|
||||
is_const: false,
|
||||
|
44
tests/expectations/nonzero.both.c
Normal file
44
tests/expectations/nonzero.both.c
Normal file
@ -0,0 +1,44 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Option_Option_NonZeroI64 Option_Option_NonZeroI64;
|
||||
|
||||
typedef struct NonZeroTest {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const struct Option_Option_NonZeroI64 *j;
|
||||
} NonZeroTest;
|
||||
|
||||
void root(struct NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const struct Option_Option_NonZeroI64 *j);
|
52
tests/expectations/nonzero.both.compat.c
Normal file
52
tests/expectations/nonzero.both.compat.c
Normal file
@ -0,0 +1,52 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Option_Option_NonZeroI64 Option_Option_NonZeroI64;
|
||||
|
||||
typedef struct NonZeroTest {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const struct Option_Option_NonZeroI64 *j;
|
||||
} NonZeroTest;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(struct NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const struct Option_Option_NonZeroI64 *j);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
44
tests/expectations/nonzero.c
Normal file
44
tests/expectations/nonzero.c
Normal file
@ -0,0 +1,44 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Option_Option_NonZeroI64 Option_Option_NonZeroI64;
|
||||
|
||||
typedef struct {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const Option_Option_NonZeroI64 *j;
|
||||
} NonZeroTest;
|
||||
|
||||
void root(NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const Option_Option_NonZeroI64 *j);
|
52
tests/expectations/nonzero.compat.c
Normal file
52
tests/expectations/nonzero.compat.c
Normal file
@ -0,0 +1,52 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct Option_Option_NonZeroI64 Option_Option_NonZeroI64;
|
||||
|
||||
typedef struct {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const Option_Option_NonZeroI64 *j;
|
||||
} NonZeroTest;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const Option_Option_NonZeroI64 *j);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
50
tests/expectations/nonzero.cpp
Normal file
50
tests/expectations/nonzero.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <ostream>
|
||||
#include <new>
|
||||
|
||||
template<typename T = void>
|
||||
struct Option;
|
||||
|
||||
struct NonZeroTest {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const Option<Option<NonZeroI64>> *j;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
void root(NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const Option<Option<NonZeroI64>> *j);
|
||||
|
||||
} // extern "C"
|
47
tests/expectations/nonzero.pyx
Normal file
47
tests/expectations/nonzero.pyx
Normal file
@ -0,0 +1,47 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
|
||||
cdef extern from *:
|
||||
ctypedef bint bool
|
||||
ctypedef struct va_list
|
||||
|
||||
cdef extern from *:
|
||||
|
||||
ctypedef struct Option_Option_NonZeroI64:
|
||||
pass
|
||||
|
||||
ctypedef struct NonZeroTest:
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const Option_Option_NonZeroI64 *j;
|
||||
|
||||
void root(NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const Option_Option_NonZeroI64 *j);
|
44
tests/expectations/nonzero.tag.c
Normal file
44
tests/expectations/nonzero.tag.c
Normal file
@ -0,0 +1,44 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Option_Option_NonZeroI64;
|
||||
|
||||
struct NonZeroTest {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const struct Option_Option_NonZeroI64 *j;
|
||||
};
|
||||
|
||||
void root(struct NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const struct Option_Option_NonZeroI64 *j);
|
52
tests/expectations/nonzero.tag.compat.c
Normal file
52
tests/expectations/nonzero.tag.compat.c
Normal file
@ -0,0 +1,52 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct Option_Option_NonZeroI64;
|
||||
|
||||
struct NonZeroTest {
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const struct Option_Option_NonZeroI64 *j;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void root(struct NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const struct Option_Option_NonZeroI64 *j);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
47
tests/expectations/nonzero.tag.pyx
Normal file
47
tests/expectations/nonzero.tag.pyx
Normal file
@ -0,0 +1,47 @@
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
|
||||
|
||||
from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t
|
||||
from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t
|
||||
cdef extern from *:
|
||||
ctypedef bint bool
|
||||
ctypedef struct va_list
|
||||
|
||||
cdef extern from *:
|
||||
|
||||
cdef struct Option_Option_NonZeroI64:
|
||||
pass
|
||||
|
||||
cdef struct NonZeroTest:
|
||||
uint8_t a;
|
||||
uint16_t b;
|
||||
uint32_t c;
|
||||
uint64_t d;
|
||||
int8_t e;
|
||||
int16_t f;
|
||||
int32_t g;
|
||||
int64_t h;
|
||||
int64_t i;
|
||||
const Option_Option_NonZeroI64 *j;
|
||||
|
||||
void root(NonZeroTest test,
|
||||
uint8_t a,
|
||||
uint16_t b,
|
||||
uint32_t c,
|
||||
uint64_t d,
|
||||
int8_t e,
|
||||
int16_t f,
|
||||
int32_t g,
|
||||
int64_t h,
|
||||
int64_t i,
|
||||
const Option_Option_NonZeroI64 *j);
|
30
tests/rust/nonzero.rs
Normal file
30
tests/rust/nonzero.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use std::num::*;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct NonZeroTest {
|
||||
pub a: NonZeroU8,
|
||||
pub b: NonZeroU16,
|
||||
pub c: NonZeroU32,
|
||||
pub d: NonZeroU64,
|
||||
pub e: NonZeroI8,
|
||||
pub f: NonZeroI16,
|
||||
pub g: NonZeroI32,
|
||||
pub h: NonZeroI64,
|
||||
pub i: Option<NonZeroI64>,
|
||||
pub j: *const Option<Option<NonZeroI64>>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn root(
|
||||
test: NonZeroTest,
|
||||
a: NonZeroU8,
|
||||
b: NonZeroU16,
|
||||
c: NonZeroU32,
|
||||
d: NonZeroU64,
|
||||
e: NonZeroI8,
|
||||
f: NonZeroI16,
|
||||
g: NonZeroI32,
|
||||
h: NonZeroI64,
|
||||
i: Option<NonZeroI64>,
|
||||
j: *const Option<Option<NonZeroI64>>,
|
||||
) {}
|
13
tests/rust/nonzero.toml
Normal file
13
tests/rust/nonzero.toml
Normal file
@ -0,0 +1,13 @@
|
||||
header = """
|
||||
#if 0
|
||||
''' '
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct NonZeroI64;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
' '''
|
||||
#endif
|
||||
"""
|
Loading…
x
Reference in New Issue
Block a user