pub enum ExprKind {
Show 35 variants
IntLit(i64),
FloatLit(f64),
BoolLit(bool),
StrLit(String),
CharLit(char),
Unit,
Local(LocalId),
MakeClosure {
func: DefId,
type_args: Vec<Ty>,
captures: Vec<Expr>,
},
Call {
func: Callee,
type_args: Vec<Ty>,
args: Vec<Expr>,
},
MakeVariant {
sum: DefId,
variant: u32,
args: Vec<Expr>,
},
MakeRecord {
record: DefId,
fields: Vec<Expr>,
},
FieldGet {
target: Box<Expr>,
index: u32,
},
FieldSet {
target: Box<Expr>,
index: u32,
value: Box<Expr>,
},
MakeArray {
elems: Vec<Expr>,
},
ArrayRepeat {
init: Box<Expr>,
len: Box<Expr>,
},
Index {
target: Box<Expr>,
index: Box<Expr>,
},
IndexSet {
target: Box<Expr>,
index: Box<Expr>,
value: Box<Expr>,
},
ArrayLen {
target: Box<Expr>,
},
TraitCall {
trait_id: DefId,
method: u32,
self_ty: Ty,
type_args: Vec<Ty>,
receiver: Option<Box<Expr>>,
args: Vec<Expr>,
},
Binary {
op: BinOp,
lhs: Box<Expr>,
rhs: Box<Expr>,
},
LogicalAnd {
lhs: Box<Expr>,
rhs: Box<Expr>,
},
LogicalOr {
lhs: Box<Expr>,
rhs: Box<Expr>,
},
Unary {
op: UnOp,
expr: Box<Expr>,
},
Let {
local: LocalId,
init: Box<Expr>,
},
Assign {
local: LocalId,
value: Box<Expr>,
},
Block {
stmts: Vec<Expr>,
trailing: Option<Box<Expr>>,
},
If {
cond: Box<Expr>,
then: Box<Expr>,
else_: Option<Box<Expr>>,
},
While {
cond: Box<Expr>,
body: Box<Expr>,
},
Break,
Continue,
Match {
scrutinee: Box<Expr>,
arms: Vec<Arm>,
},
Return(Option<Box<Expr>>),
ToStr(Box<Expr>),
StrConcat(Vec<Expr>),
Await(Box<Expr>),
}Expand description
Expression kinds. Desugared relative to the AST: no string interpolation,
no compound assignment, no for (Phase 1 defers iterators).
Variants§
IntLit(i64)
FloatLit(f64)
BoolLit(bool)
StrLit(String)
CharLit(char)
Unit
The unit value ().
Local(LocalId)
Read a local variable.
MakeClosure
Build a function value (fat pointer { code, env }). func is the
code function (a closure body or a bare-fn wrapper), instantiated
with type_args; captures are the environment’s values in order
(empty for a bare-fn wrapper).
Call
Call a function. type_args instantiate the callee’s generics when
func is Callee::Def.
MakeVariant
Construct a sum type variant. The expression’s ty carries the
concrete Sum { args, .. } instantiation.
MakeRecord
Construct a record value. fields are in the record’s declared
field order; the expression’s ty is the Record { args, .. }
instantiation.
FieldGet
Read field index of a record value.
FieldSet
Store record.field = value. index is the field’s position, so the
store offset is 8 * index — the same layout FieldGet reads.
Unit-typed.
MakeArray
Construct a heap array { len, elems... }; the expression’s ty
is the Array(elem) type.
ArrayRepeat
[init; len] — a heap array of len slots, every one holding init,
where len is a runtime Int. Unlike MakeArray the element count is
not known statically, so MIR lowering allocates and then fills with a
loop. The expression’s ty is the Array(elem) type.
init is evaluated once, and that single value is stored into every
slot — these are not len copies. For a heap element type the slots are
therefore one object rather than len objects: [Vec::new(); 2] is a
single Vec in both slots, so a push through one is visible through
the other. That follows from Nova’s reference semantics (there is no
Copy and no clone to insert per slot), and
tests/runtime/array_repeat.nova executes the case so a change to
per-slot evaluation cannot happen silently.
Index
Read target[index] (bounds-checked). target is an array.
IndexSet
Assign target[index] = value (bounds-checked); unit-typed.
ArrayLen
The length of an array (arr.len()).
TraitCall
A trait method call, resolved to a concrete impl during monomorphization
(static dispatch). self_ty is the Self type — concrete for a call on
a known type, or Param(k) inside a generic function (dispatch through
that parameter’s bound) until substitution makes it concrete.
Fields
type_args: Vec<Ty>The method’s own generic arguments (Param(1..)), inferred per call
site; empty for a non-generic trait method.
receiver: Option<Box<Expr>>The receiver of receiver.method(args), or None for a trait
associated function called as Type::method(args) — one that
declares no self (see TraitMethod::has_self). None rather
than a flag beside a placeholder expression so that lowering a
receiver that does not exist is not representable: there is nothing
to lower, so no consumer can accidentally pass one.
Binary
A non-short-circuit binary operation.
LogicalAnd
Short-circuit &&.
LogicalOr
Short-circuit ||.
Unary
Let
let binding as a unit-typed statement expression.
Assign
Assignment to a mutable local; unit-typed.
Block
{ stmts; trailing } — value is trailing or unit.
If
While
Break
Exit the innermost enclosing loop; diverging (Never).
Continue
Skip to the next iteration of the innermost loop; diverging.
Match
Return(Option<Box<Expr>>)
ToStr(Box<Expr>)
Convert a primitive to String (from string interpolation).
StrConcat(Vec<Expr>)
Concatenate String parts (from string interpolation).
Await(Box<Expr>)
e.await inside an async fn. e has type Future<T> and the
Await expression has type T.
Only ever appears inside an async fn’s body, which nova-typeck’s
fcx.in_async is what enforces — so nothing downstream needs a guard
against one outside a function that is Function::is_async.
What this node becomes is nova-mir’s: lower.rs emits a Stmt::Await
marker and async_lower.rs’s block split turns that into suspend/resume
control flow. Deliberately not described further here. A description
of another crate’s behaviour, kept in this one, goes false the moment that
behaviour changes and has nothing to keep it honest — so this doc holds
only the two facts above, both of which are about this node and this
crate, and nova-mir’s own docs carry the contract.