fix(tvix/eval): fix doc comment syntax where applicable

As pointed out by grfn on cl/6091

Change-Id: I28308577b7cf99dffb4a4fd3cc8783eb9ab4d0d6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6460
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
Vincent Ambo 2022-09-05 01:30:58 +03:00 committed by tazjin
parent 83dd706a3a
commit 06909f1821
10 changed files with 122 additions and 110 deletions

View file

@ -36,6 +36,9 @@ macro_rules! force {
};
}
/// Return all pure builtins, that is all builtins that do not rely on
/// I/O outside of the VM and which can be used in any contexts (e.g.
/// WASM).
fn pure_builtins() -> Vec<Builtin> {
vec![
Builtin::new("add", 2, |mut args, _| {

View file

@ -26,6 +26,9 @@ struct SourceSpan {
count: usize,
}
/// A chunk is a representation of a sequence of bytecode
/// instructions, associated constants and additional metadata as
/// emitted by the compiler.
#[derive(Clone, Debug, Default)]
pub struct Chunk {
pub code: Vec<OpCode>,

View file

@ -433,12 +433,13 @@ impl Compiler<'_, '_> {
}
}
// Compile list literals into equivalent bytecode. List
// construction is fairly simple, consisting of pushing code for
// each literal element and an instruction with the element count.
//
// The VM, after evaluating the code for each element, simply
// constructs the list from the given number of elements.
/// Compile list literals into equivalent bytecode. List
/// construction is fairly simple, consisting of pushing code for
/// each literal element and an instruction with the element
/// count.
///
/// The VM, after evaluating the code for each element, simply
/// constructs the list from the given number of elements.
fn compile_list(&mut self, slot: LocalIdx, node: ast::List) {
let mut count = 0;
@ -450,14 +451,14 @@ impl Compiler<'_, '_> {
self.push_op(OpCode::OpList(Count(count)), &node);
}
// Compile attribute set literals into equivalent bytecode.
//
// This is complicated by a number of features specific to Nix
// attribute sets, most importantly:
//
// 1. Keys can be dynamically constructed through interpolation.
// 2. Keys can refer to nested attribute sets.
// 3. Attribute sets can (optionally) be recursive.
/// Compile attribute set literals into equivalent bytecode.
///
/// This is complicated by a number of features specific to Nix
/// attribute sets, most importantly:
///
/// 1. Keys can be dynamically constructed through interpolation.
/// 2. Keys can refer to nested attribute sets.
/// 3. Attribute sets can (optionally) be recursive.
fn compile_attr_set(&mut self, slot: LocalIdx, node: ast::AttrSet) {
if node.rec_token().is_some() {
todo!("recursive attribute sets are not yet implemented")
@ -632,16 +633,18 @@ impl Compiler<'_, '_> {
self.compile(slot, node.body().unwrap());
}
// Compile conditional expressions using jumping instructions in the VM.
//
// ┌────────────────────┐
// │ 0 [ conditional ] │
// │ 1 JUMP_IF_FALSE →┼─┐
// │ 2 [ main body ] │ │ Jump to else body if
// ┌┼─3─← JUMP │ │ condition is false.
// Jump over else body ││ 4 [ else body ]←┼─┘
// if condition is true.└┼─5─→ ... │
// └────────────────────┘
/// Compile conditional expressions using jumping instructions in the VM.
///
/// ```notrust
/// ┌────────────────────┐
/// │ 0 [ conditional ] │
/// │ 1 JUMP_IF_FALSE →┼─┐
/// │ 2 [ main body ] │ │ Jump to else body if
/// ┌┼─3─← JUMP │ │ condition is false.
/// Jump over else body ││ 4 [ else body ]←┼─┘
/// if condition is true.└┼─5─→ ... │
/// └────────────────────┘
/// ```
fn compile_if_else(&mut self, slot: LocalIdx, node: ast::IfElse) {
self.compile(slot, node.condition().unwrap());
self.emit_force(&node.condition().unwrap());
@ -663,7 +666,7 @@ impl Compiler<'_, '_> {
self.patch_jump(else_idx); // patch jump *over* else body
}
// Compile an `inherit` node of a `let`-expression.
/// Compile an `inherit` node of a `let`-expression.
fn compile_let_inherit<I: Iterator<Item = ast::Inherit>>(
&mut self,
slot: LocalIdx,
@ -714,11 +717,11 @@ impl Compiler<'_, '_> {
}
}
// Compile a standard `let ...; in ...` statement.
//
// Unless in a non-standard scope, the encountered values are
// simply pushed on the stack and their indices noted in the
// entries vector.
/// Compile a standard `let ...; in ...` statement.
///
/// Unless in a non-standard scope, the encountered values are
/// simply pushed on the stack and their indices noted in the
/// entries vector.
fn compile_let_in(&mut self, slot: LocalIdx, node: ast::LetIn) {
self.begin_scope();
@ -837,9 +840,9 @@ impl Compiler<'_, '_> {
};
}
// Compile `with` expressions by emitting instructions that
// pop/remove the indices of attribute sets that are implicitly in
// scope through `with` on the "with-stack".
/// Compile `with` expressions by emitting instructions that
/// pop/remove the indices of attribute sets that are implicitly
/// in scope through `with` on the "with-stack".
fn compile_with(&mut self, slot: LocalIdx, node: ast::With) {
self.begin_scope();
// TODO: Detect if the namespace is just an identifier, and
@ -1298,9 +1301,9 @@ impl Compiler<'_, '_> {
}
}
// Normalises identifier fragments into a single string vector for
// `let`-expressions; fails if fragments requiring dynamic computation
// are encountered.
/// Normalises identifier fragments into a single string vector
/// for `let`-expressions; fails if fragments requiring dynamic
/// computation are encountered.
fn normalise_ident_path<I: Iterator<Item = ast::Attr>>(
&self,
path: I,

View file

@ -32,25 +32,25 @@ enum LocalName {
/// Represents a single local already known to the compiler.
#[derive(Debug)]
pub struct Local {
// Identifier of this local. This is always a statically known
// value (Nix does not allow dynamic identifier names in locals),
// or a "phantom" value not accessible by users.
/// Identifier of this local. This is always a statically known
/// value (Nix does not allow dynamic identifier names in locals),
/// or a "phantom" value not accessible by users.
name: LocalName,
// Source span at which this local was declared.
/// Source span at which this local was declared.
pub span: codemap::Span,
// Scope depth of this local.
/// Scope depth of this local.
pub depth: usize,
// Is this local initialised?
/// Is this local initialised?
pub initialised: bool,
// Is this local known to have been used at all?
/// Is this local known to have been used at all?
pub used: bool,
// Does this local need to be finalised after the enclosing scope
// is completely constructed?
/// Does this local need to be finalised after the enclosing scope
/// is completely constructed?
pub needs_finaliser: bool,
}
@ -135,18 +135,18 @@ pub struct Scope {
pub locals: Vec<Local>,
pub upvalues: Vec<Upvalue>,
// How many scopes "deep" are these locals?
/// How many scopes "deep" are these locals?
pub scope_depth: usize,
// Current size of the `with`-stack at runtime.
/// Current size of the `with`-stack at runtime.
with_stack_size: usize,
// Users are allowed to override globally defined symbols like
// `true`, `false` or `null` in scopes. We call this "scope
// poisoning", as it requires runtime resolution of those tokens.
//
// To support this efficiently, the depth at which a poisoning
// occured is tracked here.
/// Users are allowed to override globally defined symbols like
/// `true`, `false` or `null` in scopes. We call this "scope
/// poisoning", as it requires runtime resolution of those tokens.
///
/// To support this efficiently, the depth at which a poisoning
/// occured is tracked here.
poisoned_tokens: HashMap<&'static str, usize>,
}

View file

@ -20,37 +20,37 @@ pub enum ErrorKind {
rhs: &'static str,
},
// Resolving a user-supplied path literal failed in some way.
/// Resolving a user-supplied path literal failed in some way.
PathResolution(String),
// Dynamic keys are not allowed in let.
/// Dynamic keys are not allowed in let.
DynamicKeyInLet(rnix::SyntaxNode),
// Unknown variable in statically known scope.
/// Unknown variable in statically known scope.
UnknownStaticVariable,
// Unknown variable in dynamic scope (with, rec, ...).
/// Unknown variable in dynamic scope (with, rec, ...).
UnknownDynamicVariable(String),
// User is defining the same variable twice at the same depth.
/// User is defining the same variable twice at the same depth.
VariableAlreadyDefined(String),
// Attempt to call something that is not callable.
/// Attempt to call something that is not callable.
NotCallable,
// Infinite recursion encountered while forcing thunks.
/// Infinite recursion encountered while forcing thunks.
InfiniteRecursion,
ParseErrors(Vec<rnix::parser::ParseError>),
AssertionFailed,
// These are user-generated errors through builtins.
/// These are user-generated errors through builtins.
Throw(String),
Abort(String),
// An error occured while forcing a thunk, and needs to be chained
// up.
/// An error occured while forcing a thunk, and needs to be
/// chained up.
ThunkForce(Box<Error>),
}

View file

@ -35,10 +35,10 @@ pub struct Count(pub usize);
#[warn(variant_size_differences)]
#[derive(Clone, Copy, Debug)]
pub enum OpCode {
// Push a constant onto the stack.
/// Push a constant onto the stack.
OpConstant(ConstantIdx),
// Discard a value from the stack.
/// Discard a value from the stack.
OpPop,
// Push a literal value.
@ -93,13 +93,13 @@ pub enum OpCode {
// Type assertion operators
OpAssertBool,
// Access local identifiers with statically known positions.
/// Access local identifiers with statically known positions.
OpGetLocal(StackIdx),
// Close scopes while leaving their expression value around.
/// Close scopes while leaving their expression value around.
OpCloseScope(Count), // number of locals to pop
// Asserts stack top is a boolean, and true.
/// Asserts stack top is a boolean, and true.
OpAssert,
// Lambdas & closures

View file

@ -150,7 +150,8 @@ impl PartialEq for NixAttrs {
}
impl NixAttrs {
// Update one attribute set with the values of the other.
/// Return an attribute set containing the merge of the two
/// provided sets. Keys from the `other` set have precedence.
pub fn update(self, other: Self) -> Self {
// Short-circuit on some optimal cases:
match (&self.0, &other.0) {
@ -301,17 +302,19 @@ impl NixAttrs {
}
}
// In Nix, name/value attribute pairs are frequently constructed from
// literals. This particular case should avoid allocation of a map,
// additional heap values etc. and use the optimised `KV` variant
// instead.
//
// `slice` is the top of the stack from which the attrset is being
// constructed, e.g.
//
// slice: [ "value" 5 "name" "foo" ]
// index: 0 1 2 3
// stack: 3 2 1 0
/// In Nix, name/value attribute pairs are frequently constructed from
/// literals. This particular case should avoid allocation of a map,
/// additional heap values etc. and use the optimised `KV` variant
/// instead.
///
/// ```norust
/// `slice` is the top of the stack from which the attrset is being
/// constructed, e.g.
///
/// slice: [ "value" 5 "name" "foo" ]
/// index: 0 1 2 3
/// stack: 3 2 1 0
/// ```
fn attempt_optimise_kv(slice: &mut [Value]) -> Option<NixAttrs> {
let (name_idx, value_idx) = {
match (&slice[2], &slice[0]) {
@ -340,8 +343,8 @@ fn attempt_optimise_kv(slice: &mut [Value]) -> Option<NixAttrs> {
}))
}
// Set an attribute on an in-construction attribute set, while
// checking against duplicate keys.
/// Set an attribute on an in-construction attribute set, while
/// checking against duplicate keys.
fn set_attr(attrs: &mut NixAttrs, key: NixString, value: Value) -> Result<(), ErrorKind> {
match attrs.0.map_mut().entry(key) {
btree_map::Entry::Occupied(entry) => Err(ErrorKind::DuplicateAttrsKey {
@ -355,12 +358,12 @@ fn set_attr(attrs: &mut NixAttrs, key: NixString, value: Value) -> Result<(), Er
}
}
// Set a nested attribute inside of an attribute set, throwing a
// duplicate key error if a non-hashmap entry already exists on the
// path.
//
// There is some optimisation potential for this simple implementation
// if it becomes a problem.
/// Set a nested attribute inside of an attribute set, throwing a
/// duplicate key error if a non-hashmap entry already exists on the
/// path.
///
/// There is some optimisation potential for this simple implementation
/// if it becomes a problem.
fn set_nested_attr(
attrs: &mut NixAttrs,
key: NixString,

View file

@ -39,7 +39,7 @@ pub struct Builtin {
arity: usize,
func: BuiltinFn,
// Partially applied function arguments.
/// Partially applied function arguments.
partials: Vec<Value>,
}

View file

@ -72,12 +72,12 @@ impl NixString {
}
}
// Return a displayable representation of the string as an
// identifier.
//
// This is used when printing out strings used as e.g. attribute
// set keys, as those are only escaped in the presence of special
// characters.
/// Return a displayable representation of the string as an
/// identifier.
///
/// This is used when printing out strings used as e.g. attribute
/// set keys, as those are only escaped in the presence of special
/// characters.
pub fn ident_str(&self) -> Cow<str> {
let escaped = nix_escape_string(self.as_str());
@ -111,10 +111,10 @@ fn nix_escape_char(ch: char, next: Option<&char>) -> Option<&'static str> {
}
}
// Escape a Nix string for display, as most user-visible representation
// are escaped strings.
//
// Note that this does not add the outer pair of surrounding quotes.
/// Escape a Nix string for display, as most user-visible representation
/// are escaped strings.
///
/// Note that this does not add the outer pair of surrounding quotes.
fn nix_escape_string(input: &str) -> Cow<str> {
let mut iter = input.chars().enumerate().peekable();

View file

@ -30,8 +30,8 @@ pub struct VM<'o> {
frames: Vec<CallFrame>,
stack: Vec<Value>,
// Stack indices of attribute sets from which variables should be
// dynamically resolved (`with`).
/// Stack indices of attribute sets from which variables should be
/// dynamically resolved (`with`).
with_stack: Vec<usize>,
observer: &'o mut dyn Observer,
@ -560,12 +560,12 @@ impl<'o> VM<'o> {
}
}
// Construct runtime representation of an attr path (essentially
// just a list of strings).
//
// The difference to the list construction operation is that this
// forces all elements into strings, as attribute set keys are
// required to be strict in Nix.
/// Construct runtime representation of an attr path (essentially
/// just a list of strings).
///
/// The difference to the list construction operation is that this
/// forces all elements into strings, as attribute set keys are
/// required to be strict in Nix.
fn run_attr_path(&mut self, count: usize) -> EvalResult<()> {
debug_assert!(count > 1, "AttrPath needs at least two fragments");
let mut path = Vec::with_capacity(count);
@ -588,9 +588,9 @@ impl<'o> VM<'o> {
Ok(())
}
// Interpolate string fragments by popping the specified number of
// fragments of the stack, evaluating them to strings, and pushing
// the concatenated result string back on the stack.
/// Interpolate string fragments by popping the specified number of
/// fragments of the stack, evaluating them to strings, and pushing
/// the concatenated result string back on the stack.
fn run_interpolate(&mut self, count: usize) -> EvalResult<()> {
let mut out = String::new();