Skip to main content

TargetModel

Struct TargetModel 

Source
pub struct TargetModel {
Show 17 fields pub arch: Arch, pub os: Os, pub env: Env, pub char_signed: bool, pub short_bits: u32, pub int_bits: u32, pub long_bits: u32, pub long_long_bits: u32, pub ptr_bits: u32, pub max_scalar_align: u64, pub int128_align: u64, pub has_int128: bool, pub big_endian: bool, pub wchar_bits: u32, pub wchar_signed: bool, pub wint_bits: u32, pub wint_signed: bool,
}
Expand description

Widths, signedness, endianness and identity of the machine the generated code runs on.

Everything the front end computes at expansion time — sizeof, _Alignof, member offsets, bit-field storage, the type of an integer constant, the value of an #if, the predefined macros and therefore the branch each bundled header takes — comes from here.

Fields§

§arch: Arch

The architecture family, which decides the __x86_64__-style macros.

§os: Os

The operating system, which decides the __linux__-style macros and so the branch every bundled header takes.

§env: Env

The C library the triple’s environment component names, which on Linux is the difference between glibc’s layouts and musl’s; see Env.

§char_signed: bool

Whether plain char is a signed type.

This follows core::ffi::c_char exactly, because the generated code uses that alias: unsigned on AArch64, Arm, PowerPC, RISC-V and s390x — except on Windows and on Apple’s platforms, which make it signed whatever the architecture — and signed everywhere else, LoongArch and wasm32 included.

§short_bits: u32

Width of short.

§int_bits: u32

Width of int.

§long_bits: u32

Width of long: 64 on a 64-bit system that is not Windows (LP64), 32 otherwise (LLP64 and ILP32).

§long_long_bits: u32

Width of long long.

§ptr_bits: u32

Width of a pointer; also the width size_t and ptrdiff_t follow.

§max_scalar_align: u64

The strictest alignment any scalar but __int128 gets, in bytes.

4 on 32-bit x86 outside Windows and 8 everywhere else: the one place where two targets of the same data model lay a struct out differently, since the i386 System V ABI aligns long long and double to four bytes and the Microsoft one to eight. rustc splits the same way — align_of::<u64>() really is 4 on i686-unknown-linux-gnu and 8 on i686-pc-windows-msvc — so a #[repr(C)] item laid out with this is the one the compiler will build.

§int128_align: u64

Alignment of __int128, in bytes.

The width is not a knob: GCC’s __int128 is 128 bits wherever it exists at all. The alignment is, and it is the one place where the generated Rust could disagree with the model, __int128 becoming i128, whose ABI Rust settled in 1.77.

§has_int128: bool

Whether __int128 exists at all.

GCC has it on the 64-bit architectures only and refuses it on a 32-bit one rather than emulating it; so does this.

§big_endian: bool

Whether the byte order is big-endian.

Only bit-fields can tell, and cinrs allocates them from the least significant end, so a big-endian target refuses a bit-field rather than laying it out the wrong way round.

§wchar_bits: u32

Width of wchar_t: 16 on Windows, 32 everywhere else.

§wchar_signed: bool

Whether wchar_t is signed: int on most systems, unsigned int on Arm and AArch64 outside Apple’s platforms, unsigned short on Windows.

§wint_bits: u32

Width of wint_t: 16 on Windows, 32 everywhere else.

§wint_signed: bool

Whether wint_t is signed, which it is only on Apple’s platforms, where it is int.

Implementations§

Source§

impl TargetModel

Source

pub const LP64: Self

The LP64 model 64-bit Unix uses, as x86_64-unknown-linux-gnu has it: 32-bit int, 64-bit long and pointers, signed char.

Source

pub const ILP32: Self

The ILP32 model 32-bit systems use, as i686-unknown-linux-gnu has it: 32-bit int, long and pointers, long long and double aligned to four bytes, and no __int128.

Source

pub const LLP64: Self

The LLP64 model 64-bit Windows uses: 32-bit int and long, 64-bit pointers, and a 16-bit wchar_t.

Source

pub const fn host() -> Self

The model of the machine this crate was compiled for.

See the module documentation for when that is the right answer and what happens when it is not.

Source

pub fn from_triple(triple: &str) -> Result<Self, UnknownTarget>

The model of the machine triple names.

The triple is a Rust one — arch-vendor-os-env, or arch-os-env where the vendor is left out — read the way rustc writes them: the first component is the architecture, and the operating system is whichever of the rest names one. The environment matters only where it changes the ABI: gnux32 and gnu_ilp32 narrow the pointer to 32 bits while leaving the architecture 64-bit.

§Errors

An architecture or an operating system the table does not have, and the handful recognised only to be refused because their data model is one this crate does not implement — avr’s 16-bit int, say.

Source

pub fn is_msvc(&self) -> bool

Whether the C library is the Microsoft one: an -msvc environment on Windows.

True of *-windows-msvc and *-uwp-windows-msvc, and of a host this crate was itself compiled for with target_env = "msvc". Not true of mingw-w64 — *-windows-gnu and *-windows-gnullvm — which is Windows with its own runtime libraries in front of the system’s, so a rule that holds for the Microsoft toolchain must not reach it.

There are two such rules, both in codegen: the printf family, which the UCRT defines inline rather than exporting, so a unit declaring one links legacy_stdio_definitions (LEGACY_STDIO); and the names the UCRT exports under another spelling, time as _time64 and the rest, which a declaration links by (MSVC_RENAMED). The data model is the same either way, which is why nothing else here asks.

Source

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

The name of the data model this is: LP64, LLP64 or ILP32.

Source

pub fn describe(&self, source: &TargetSource) -> String

One line naming the model and the knob that chose it, for the data-model assertion.

Source

pub fn macros(&self) -> Vec<(&'static str, String)>

Every macro the target’s identity predefines: the architecture, the operating system, the object format.

The data-model family — __LP64__, __ILP32__, __CHAR_UNSIGNED__, the __SIZEOF_*__ and __*_MAX__ sets, __BYTE_ORDER__ — is arithmetic rather than identity, and the preprocessor builds it from the widths above.

Trait Implementations§

Source§

impl Clone for TargetModel

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 TargetModel

Source§

impl Debug for TargetModel

Source§

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

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

impl Default for TargetModel

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl Eq for TargetModel

Source§

impl PartialEq for TargetModel

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 TargetModel

Auto Trait Implementations§

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.