Skip to main content

Ty

Enum Ty 

Source
pub enum Ty {
Show 28 variants Void, Bool, Char, SChar, UChar, Short, UShort, Int, UInt, Long, ULong, LongLong, ULongLong, Int128, UInt128, Float, Double, ComplexFloat, ComplexDouble, Pointer(PointerId), Array(ArrayId), Func(FuncTyId), Record(RecordId), Enum(EnumId), VaList, Vector(VecTy), Atomic(AtomicId), Error,
}
Expand description

A resolved C type.

long double is mapped onto Ty::Double when the type is resolved, because there is no portable Rust type with the layout of an x87 extended double; the mapping is documented rather than diagnosed, since a procedural macro has no stable way to raise a warning.

Variants§

§

Void

void

§

Bool

_Bool

§

Char

Plain char, whose signedness is the target’s business and which is a distinct type from both signed char and unsigned char.

§

SChar

signed char

§

UChar

unsigned char

§

Short

short

§

UShort

unsigned short

§

Int

int

§

UInt

unsigned int

§

Long

long

§

ULong

unsigned long

§

LongLong

long long

§

ULongLong

unsigned long long

§

Int128

GNU’s __int128 (also spelled __int128_t), which ranks above long long and is generated as Rust’s i128.

§

UInt128

unsigned __int128 (also spelled __uint128_t), generated as u128.

§

Float

float

§

Double

double (and long double)

§

ComplexFloat

float _Complex, generated as cinrs_rt::Complex<f32>.

C calls the complex types floating types and therefore arithmetic ones, but almost nothing in this crate wants them where a float or a double goes: Ty::is_floating is deliberately the real floating types only, and Ty::is_complex is the question to ask about these.

§

ComplexDouble

double _Complex (and long double _Complex), generated as cinrs_rt::Complex<f64>.

§

Pointer(PointerId)

A pointer, including a pointer to a function.

§

Array(ArrayId)

An array of a known length.

§

Func(FuncTyId)

A function type. Only ever reached through a pointer or as the type of a function designator.

§

Record(RecordId)

A struct or union, complete or not.

§

Enum(EnumId)

A file-scope enum with a tag, which becomes a named c_int alias. Every other enum is simply Ty::Int.

§

VaList

va_list (and its __builtin_va_list / __gnuc_va_list spellings), which becomes core::ffi::VaList.

The type is opaque: it has no size, nothing may point at it, and it may only be a local variable or a parameter — see crate::sema for why.

§

Vector(VecTy)

One of x86’s vector types: __m128, __m128i, __m128d, __m256, __m256i or __m256d.

Opaque, exactly as C sees it: there is no arithmetic on one, no conversion to or from one, and no way to reach a lane except through an intrinsic or through a union. What it is is an object of a known size and alignment — sixteen or thirty-two bytes, aligned to itself — which is what makes it a member, an element, a parameter, a return value and the thing a union { __m128i v; int i[4]; } punnes. Code generation writes ::core::arch::x86_64::__m128i, whose layout is the same.

§

Atomic(AtomicId)

_Atomic T, for a scalar T (C11 6.7.2.4).

It is the type of an object, never of a value: reading an atomic lvalue is an atomic load whose result has the underlying type, so ExprKind::Load of an atomic place is typed Types::unatomic of it and nothing downstream of the load ever meets this variant. Where it does appear is a declared object, a member, a pointee and sizeof — which is why it is a type rather than a flag on the declaration: _Atomic int * and int * are different types, and a store through the first one is atomic.

The alignment is the size (see Types::size_align), which is what makes _Atomic long long eight-byte aligned on a target whose plain long long is not.

§

Error

The type of something whose declaration was already reported as wrong.

It exists so that one bad declaration produces one diagnostic: an object declared int a[n] still enters the symbol table, and every later use of it is checked against a type that silences further complaints instead of “use of undeclared identifier”.

Implementations§

Source§

impl Ty

Source

pub fn scalar_name(self) -> &'static str

The C spelling of a scalar type.

Derived and tagged types need the arena; use Types::name for a type that may be one of those.

Source

pub fn is_void(self) -> bool

Whether this is void.

Source

pub fn is_bool(self) -> bool

Whether this is _Bool.

Source

pub fn is_pointer(self) -> bool

Whether this is a pointer.

Source

pub fn is_array(self) -> bool

Whether this is an array.

Source

pub fn is_record(self) -> bool

Whether this is a struct or union.

Source

pub fn is_func(self) -> bool

Whether this is a function type.

Source

pub fn is_enum(self) -> bool

Whether this is a named enum type.

Source

pub fn is_va_list(self) -> bool

Whether this is va_list.

Source

pub fn is_vector(self) -> bool

Whether this is one of x86’s vector types.

They are neither arithmetic nor scalar — nothing C does to a number can be done to one — so every operator asks this before complaining, and says “use an intrinsic” rather than the generic “invalid operands”.

Source

pub fn is_error(self) -> bool

Whether this stands for something already reported as ill formed.

Source

pub fn is_integer(self) -> bool

Whether this is an integer type (_Bool and enum included, as C requires).

Source

pub fn is_int128(self) -> bool

Whether this is one of the two 128-bit integer types.

They are the only integers whose values do not all fit in the i128 a constant is carried in, so the places that fold, print or emit one have to know; see Ty::wrap.

Source

pub fn is_floating(self) -> bool

Whether this is float or double — one of C’s real floating types.

The complex types are floating types too as far as the standard’s wording goes; Ty::is_complex is the question about those, and keeping them out of this one is what stops every existing floating-point path from silently treating a Complex<f64> as an f64.

Source

pub fn is_complex(self) -> bool

Whether this is one of the complex types.

Source

pub fn complex_component(self) -> Ty

The corresponding real type (C99 6.2.5p14) — the type of each part of a complex value, and the type itself for everything else.

Source

pub fn complex_of(self) -> Ty

The complex type whose parts have this real type (C99 6.2.5p13).

Anything that is not a real floating type gets double _Complex, which is what the usual arithmetic conversions give an integer operand.

Source

pub fn is_arithmetic(self) -> bool

Whether this is an arithmetic type: an integer, a real floating type, or a complex one (C99 6.2.5p18).

Source

pub fn is_scalar(self) -> bool

Whether this is a scalar, i.e. something C can compare against zero.

An Ty::Atomic is not one: it is the type of an object, and a value read out of one has the underlying type. Everything that asks this question about a declared type therefore has to take the _Atomic off first, with Types::unatomic.

Source

pub fn is_atomic(self) -> bool

Whether this is _Atomic T.

Source

pub fn is_signed(self, target: &TargetModel) -> bool

Whether values of this type are signed.

Source

pub fn bits(self, target: &TargetModel) -> u32

The width of this type in bits.

Source

pub fn size_bytes(self, target: &TargetModel) -> u64

sizeof this scalar type, in bytes.

Aggregates need the arena; use Types::size_of for a type that may be one.

Source

pub fn rank(self) -> u32

The conversion rank of an integer type (C99 6.3.1.1).

Only the ordering matters; the absolute values are arbitrary.

Source

pub fn to_unsigned(self) -> Ty

The unsigned type of the same rank.

Source

pub fn min_value(self, target: &TargetModel) -> i128

The smallest value this integer type can hold.

Source

pub fn max_value(self, target: &TargetModel) -> i128

The largest value this integer type can hold.

unsigned __int128 is the one type whose largest value does not fit in the i128 this returns, and it is clamped to i128::MAX. Nothing reads it: the only comparison of two maxima is the last step of the usual arithmetic conversions, which is reached only when the unsigned operand has the lower rank — and no integer type ranks above unsigned __int128.

Source

pub fn can_represent(self, value: i128, target: &TargetModel) -> bool

Whether value fits in this integer type without conversion.

Source

pub fn wrap(self, value: i128, target: &TargetModel) -> i128

Converts an integer value to this type the way C’s conversions do: modulo 2^N for unsigned types, and the same (implementation-defined) wrap-around for signed ones.

§How a 128-bit constant is carried

A folded constant is an i128, which holds every value of every type this models except those of unsigned __int128 above i128::MAX. Such a value is carried as its two’s-complement bit pattern, which is what this returns unchanged for a 128-bit type: for every narrower type the bit pattern and the mathematical value coincide, so the invariant is “the value, except that an unsigned __int128 is reinterpreted”. The places where the difference shows — division, remainder, a right shift, a comparison and the literal that is finally emitted — dispatch on Ty::is_signed instead of on the sign of the i128.

Source

pub fn promote(self, target: &TargetModel) -> Ty

The integer promotions (C99 6.3.1.1p2).

Anything of lower rank than int becomes int when int can hold every one of its values and unsigned int otherwise; an enum becomes int; everything else is unchanged.

Source

pub fn promote_bit_field( self, width: u32, signed: bool, target: &TargetModel, ) -> Ty

The integer promotions applied to a bit-field (C99 6.3.1.1p2, “as restricted by the width”).

The value of a bit-field of width width ranges over width bits rather than over the whole declared type, so unsigned x : 31 promotes to int — every value fits — while unsigned x : 32 promotes to unsigned int. The standard only defines the promotions for a type whose rank is at most int’s, which is the only case standard C allows a bit-field to have; GCC and Clang apply the same width-restricted rule to the wider types they accept as an extension, so unsigned long x : 31 is an int too and unsigned long x : 33 keeps its declared type. This follows them.

signed is the signedness of the field, which is the declared type’s except for an enum whose underlying type the implementation made unsigned.

Source

pub fn promote_argument(self, target: &TargetModel) -> Ty

The default argument promotions, applied to the variable part of a variadic call: float becomes double, and the integer promotions do the rest.

Source

pub fn usual_arithmetic(lhs: Ty, rhs: Ty, target: &TargetModel) -> Ty

The usual arithmetic conversions (C99 6.3.1.8): the common type two arithmetic operands are converted to.

With a complex operand the standard’s rule is in two steps: the common real type is worked out from the two operands’ corresponding real types, and the result is the complex type belonging to it if either operand was complex. float _Complex + long is therefore float _Complex, not double _Complex.

Source

pub fn size_ty(target: &TargetModel) -> Ty

size_t for target.

The narrowest unsigned type as wide as a pointer, which is how GCC picks it and therefore what __SIZE_TYPE__ says: unsigned int on i686, unsigned long on LP64, unsigned long long on 64-bit Windows, where long is only 32 bits.

Source

pub fn ptrdiff_ty(target: &TargetModel) -> Ty

ptrdiff_t for target, chosen the same way as Ty::size_ty.

Source

pub fn wchar_ty(target: &TargetModel) -> Ty

wchar_t for target: unsigned short on Windows, unsigned int on Arm outside Apple’s platforms, and int everywhere else.

This is the type L'x' and L"…" get, and what the bundled <stddef.h> typedefs from __WCHAR_TYPE__; the two have to agree, or a call passing L"…" to a const wchar_t * would be a type error.

Source

pub fn char16_ty() -> Ty

char16_t (C11 7.28), which is uint_least16_t — unsigned short on every target this models, and what the bundled <uchar.h> typedefs it to.

Source

pub fn char32_ty() -> Ty

char32_t (C11 7.28), which is uint_least32_t — unsigned int.

Trait Implementations§

Source§

impl Clone for Ty

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Ty

Source§

impl Debug for Ty

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for Ty

Source§

impl Hash for Ty

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Ty

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for Ty

Auto Trait Implementations§

§

impl Freeze for Ty

§

impl RefUnwindSafe for Ty

§

impl Send for Ty

§

impl Sync for Ty

§

impl Unpin for Ty

§

impl UnsafeUnpin for Ty

§

impl UnwindSafe for Ty

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.