Skip to main content

Context

Struct Context 

Source
pub struct Context<'a> {
    pub tast: &'a Tast,
    pub types: &'a Types,
    pub target: &'a TargetInfo,
    pub names: &'a mut Interner,
    pub visibility: Visibility,
    pub protector: Protector,
    pub wrapping: Wrapping,
    pub aliasing: bool,
    pub padding: bool,
    pub contract: FpContract,
    pub read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>,
}
Expand description

Everything the walk reads, which is a checked translation unit and the target it is for.

The interner is mutable because the walk invents names the program never wrote: the label a string literal is emitted under, and the mangled name of a function-scope static.

Fields§

§tast: &'a Tast

The typed tree.

§types: &'a Types

The types it points into.

§target: &'a TargetInfo

What is being compiled for, which is where every width and every alignment comes from.

§names: &'a mut Interner

The name table.

§visibility: Visibility

What a name that no declaration of it said anything about gets, which is -fvisibility=.

A fact about the compilation rather than about any declaration, which is why it arrives here rather than on the tree: the checker knows what was written and this knows what the command line asked for, and the answer is the first of those where there is one.

§protector: Protector

Which functions get a stack protector, which is -fstack-protector and its relatives.

§wrapping: Wrapping

What overflows rather than being undefined, which is -fwrapv and its relatives.

A fact about the compilation for the same reason the two above it are: what was written is on the tree and what was asked for is on the command line.

§aliasing: bool

Whether an access carries the node for the type it goes through, which is -fstrict-aliasing and is on unless -fno-strict-aliasing cleared it.

Clearing it here rather than in the optimizer is what makes the flag one condition in one place: an access with no node conflicts with every other access, so a unit built with the flag off is a unit whose IR says less rather than a unit the passes are told something extra about. That is also what keeps it right across link time optimization, the way Context::wrapping is: a body from a unit that named its types and a body from one that did not keep their own answers when they end up in the same module.

§padding: bool

Whether an access says how far the padding after it reaches, which is -fsafety-init=nopadding and is what a build with no safety tier gets too, since nothing reads the number then.

Here rather than in the safety pass for the reason Context::aliasing is here: what the number is takes a record’s layout, and the layout is a thing the walk has in hand and the pass over the IR does not. The pass reads it and does not decide anything, which keeps the flag one condition in one place and keeps it right across link time optimization.

§contract: FpContract

How far a multiply and an addition may be fused into one rounding, which is -ffp-contract=.

A fact about the compilation like the ones above it, and the one of them that is written down rather than acted on: it goes onto every function with a body as rucc_ir::Attrs::fp_contract, because the place that would fuse anything is the code generator and by the time it runs the command line is gone and the two operations it might fuse may have come from different statements.

§read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>

How a file named by a .incbin in an asm at file scope is read, given the name as the template wrote it and handing back either the bytes or what went wrong.

Passed in rather than reached for, because the walk has no business opening files and because a caller that put its sources somewhere other than a disk has put this file there too. The name is resolved the way an assembler resolves it, which is against the directory the compiler was run in and not against the directory the source was found in.

Trait Implementations§

Source§

impl Debug for Context<'_>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> !RefUnwindSafe for Context<'a>

§

impl<'a> !Send for Context<'a>

§

impl<'a> !Sync for Context<'a>

§

impl<'a> !UnwindSafe for Context<'a>

§

impl<'a> Freeze for Context<'a>

§

impl<'a> Unpin for Context<'a>

§

impl<'a> UnsafeUnpin for Context<'a>

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> 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, 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.