Skip to main content

Terminator

Enum Terminator 

Source
pub enum Terminator<'d> {
    Fallthrough(BlockId),
    Switch {
        on: SwitchOn<'d>,
        arms: Vec<BlockId>,
        default_blk: BlockId,
        report: Option<SourceLoc>,
    },
    Branch {
        cond: Expression<'d>,
        then_blk: BlockId,
        else_blk: BlockId,
    },
    Assertion {
        stmt: Statement<'d>,
        pass_blk: BlockId,
        fail_blk: BlockId,
        done_blk: BlockId,
    },
    Suspend {
        point: SuspendPoint<'d>,
        resume_blk: BlockId,
    },
    End {
        loop_back: Option<BlockId>,
    },
    Loop {
        header: BlockId,
        body: BlockId,
        exit: BlockId,
        entry: BlockId,
    },
    ForkJoin {
        kind: StatementBlockKind,
        branches: Vec<ProcessCfg<'d>>,
        join_blk: BlockId,
    },
    RepeatCheck {
        counter: RepeatCounterId,
        then_blk: BlockId,
        else_blk: BlockId,
    },
    Case {
        stmt: Statement<'d>,
        arms: Vec<BlockId>,
        default_blk: BlockId,
    },
}
Expand description

A BasicBlock’s single exit (PR-008, extended by Task 1).

Variants§

§

Fallthrough(BlockId)

Falls straight into BlockId with no branch/suspend (e.g. the merge point after an if/else).

§

Switch

Goes to arms[i] when on evaluates to i, else to default_blk – reporting an $error at source offset report first, when set (a wait_order with no else).

Fields

§on: SwitchOn<'d>
§arms: Vec<BlockId>
§default_blk: BlockId
§

Branch

if/case (PR-044 – expanded to a br-chain at the Terminator level; the ternary operator ?: never appears here, only inside a straight-line expression within a BasicBlock’s stmts).

Fields

§cond: Expression<'d>
§then_blk: BlockId
§else_blk: BlockId
§

Assertion

An immediate assertion (LRM 16.3) whose pass or fail statement waits, so the statement cannot stay a straight-line leaf. Goes to pass_blk (fail_blk) when the expression is true (not true) and the assertion is checking with that action on (20.11), else to done_blk; the default $error of an assert/assume with no fail statement is reported inline before done_blk.

Fields

§stmt: Statement<'d>
§pass_blk: BlockId
§fail_blk: BlockId
§done_blk: BlockId
§

Suspend

Fields

§point: SuspendPoint<'d>
§resume_blk: BlockId
§

End

PR-048: loop_back is None for initial/final procedures and Some(entry) for always/always_ff/always_comb/always_latch procedures – see ProcessLoopKind.

Fields

§loop_back: Option<BlockId>
§

Loop

PR-045 (Task 1): for/while/do-while/forever/foreach. header’s own terminator (a plain Branch for a real per-iteration condition, or Fallthrough when there is none – forever) carries the actual per-iteration decision, and body’s own terminator closes the back edge to header. entry is the block cur (the one this Terminator::Loop closes) actually transfers control to on first entry – header for while/for/forever/foreach (the condition, if any, is checked before the first iteration), but body for do-while (the body always runs once before any check) – a deviation from docs/design/process.md §2’s literal 3-field Loop{header,body,exit} (recorded in this task’s deviations): a do-while’s real entry edge genuinely cannot be recovered from header/body/exit alone once header is required (as this task’s own tests require) to remain a distinct, inspectable post-body recheck block rather than being aliased to body. Codegen may fully unroll a static-bound for, but the CFG representation itself always has a real Loop terminator so the liveness/segment- lowering passes never special-case “was this unrolled” (this file’s own lower_terminator maps it losslessly to SegTerminator::Goto(entry), since whichever real block entry names already carries its own correct terminator). foreach’s per-dimension bound is a ConstantRange, not an Expression slang exposes anywhere on the statement – see walk_foreach_loop’s own doc comment for why that one kind’s body is a chain of unrolled copies rather than a real back edge (a second, separately-recorded deviation).

Fields

§header: BlockId
§body: BlockId
§exit: BlockId
§entry: BlockId
§

ForkJoin

fork ... join/join_any/join_none (Task 1, PR-069/docs/design/ process.md §7): construction only, never scheduled. Each branches[i] is a full nested ProcessCfg (a fork branch can contain its own suspends). See contains_unschedulable_fork_join – a real caller must check this before calling lower_to_segments on a CFG that might contain one.

Fields

§branches: Vec<ProcessCfg<'d>>
§join_blk: BlockId
§

RepeatCheck

R-run Task 8 (PR-045/PR-006): a repeat(N) body; loop’s header terminator, when body contains a suspend point (see RepeatCounterId’s own doc comment for why this is a distinct shape from Branch, never a fabricated cond: Expression). Mirrors while’s own header/Branch role exactly – then_blk is the loop body, else_blk is the loop’s exit – except the re-checked condition is counter != 0 against this loop’s own compiler- synthesized RepeatCounterId slot, not a re-evaluated user expression.

Fields

§then_blk: BlockId
§else_blk: BlockId
§

Case

A case/casez/casex/case ... inside statement whose arms cannot stay one straight-line leaf (an arm suspends, or breaks / continues an enclosing process loop, or returns from an inlined task): stmt supplies the selector and labels, matched in item order, arms[i] is stmt.case_items()[i]’s block and default_blk runs when no item matches. Also a unique/unique0/priority if series: stmt is its first if (if_chain), arms[i] the then-statement of the i-th condition and default_blk the final else, so the dispatch can report a violation where the series executes. Also an if with a pattern-matching or &&&-chained predicate (one arm, is_clause_if) and a case ... matches (arms[i] is pattern_case_items()[i]’s block, default_blk its default).

Fields

§stmt: Statement<'d>
§arms: Vec<BlockId>
§default_blk: BlockId

Trait Implementations§

Source§

impl<'d> Clone for Terminator<'d>

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<'d> Debug for Terminator<'d>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'d> !RefUnwindSafe for Terminator<'d>

§

impl<'d> !UnwindSafe for Terminator<'d>

§

impl<'d> Freeze for Terminator<'d>

§

impl<'d> Send for Terminator<'d>

§

impl<'d> Sync for Terminator<'d>

§

impl<'d> Unpin for Terminator<'d>

§

impl<'d> UnsafeUnpin for Terminator<'d>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V