chore(eval): upgrade to 2024 edition

Part of #114
There were a lot of warnings about drop order change. They are triggered
by NixString's custom drop, but the drop doesn't have side effects so
they can be ignored.

Change-Id: I19071de0fd39b8f0d19abc917d1d89d1cf26de40
Reviewed-on: https://cl.snix.dev/c/snix/+/30592
Reviewed-by: Florian Klink <flokli@flokli.de>
Autosubmit: Bence Nemes <nemes.bence1@gmail.com>
Reviewed-by: Domen Kožar <domen@cachix.org>
Tested-by: besadii
This commit is contained in:
Starnick4444 2025-07-01 06:18:30 +02:00 committed by clbot
parent beca8c8a4c
commit 40ab29c05a
31 changed files with 130 additions and 115 deletions

View file

@ -4031,7 +4031,7 @@ rec {
"snix-eval" = rec { "snix-eval" = rec {
crateName = "snix-eval"; crateName = "snix-eval";
version = "0.1.0"; version = "0.1.0";
edition = "2021"; edition = "2024";
src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval; }; src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval; };
libName = "snix_eval"; libName = "snix_eval";
dependencies = [ dependencies = [
@ -4166,7 +4166,7 @@ rec {
"snix-eval-builtin-macros" = rec { "snix-eval-builtin-macros" = rec {
crateName = "snix-eval-builtin-macros"; crateName = "snix-eval-builtin-macros";
version = "0.0.1"; version = "0.0.1";
edition = "2021"; edition = "2024";
src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval/builtin-macros; }; src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval/builtin-macros; };
procMacro = true; procMacro = true;
libName = "snix_eval_builtin_macros"; libName = "snix_eval_builtin_macros";

View file

@ -14138,7 +14138,7 @@ rec {
"snix-eval" = rec { "snix-eval" = rec {
crateName = "snix-eval"; crateName = "snix-eval";
version = "0.1.0"; version = "0.1.0";
edition = "2021"; edition = "2024";
src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval; }; src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval; };
libName = "snix_eval"; libName = "snix_eval";
dependencies = [ dependencies = [
@ -14307,7 +14307,7 @@ rec {
"snix-eval-builtin-macros" = rec { "snix-eval-builtin-macros" = rec {
crateName = "snix-eval-builtin-macros"; crateName = "snix-eval-builtin-macros";
version = "0.0.1"; version = "0.0.1";
edition = "2021"; edition = "2024";
src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval/builtin-macros; }; src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval/builtin-macros; };
procMacro = true; procMacro = true;
libName = "snix_eval_builtin_macros"; libName = "snix_eval_builtin_macros";

View file

@ -1,7 +1,7 @@
[package] [package]
name = "snix-eval" name = "snix-eval"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2024"
[lib] [lib]
name = "snix_eval" name = "snix_eval"

View file

@ -1,4 +1,4 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion}; use criterion::{Criterion, black_box, criterion_group, criterion_main};
use itertools::Itertools; use itertools::Itertools;
use mimalloc::MiMalloc; use mimalloc::MiMalloc;

View file

@ -2,7 +2,7 @@
name = "snix-eval-builtin-macros" name = "snix-eval-builtin-macros"
version = "0.0.1" version = "0.0.1"
authors = ["Griffin Smith <root@gws.fyi>"] authors = ["Griffin Smith <root@gws.fyi>"]
edition = "2021" edition = "2024"
[dependencies] [dependencies]
syn = { version = "1.0.109", features = [ syn = { version = "1.0.109", features = [

View file

@ -0,0 +1,2 @@
# FUTUREWORK: move to .. once all crates are migrated (#114)
edition = "2024"

View file

@ -2,12 +2,12 @@ extern crate proc_macro;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::Span; use proc_macro2::Span;
use quote::{quote, quote_spanned, ToTokens}; use quote::{ToTokens, quote, quote_spanned};
use syn::parse::Parse; use syn::parse::Parse;
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{ use syn::{
parse2, parse_macro_input, parse_quote, parse_quote_spanned, Attribute, FnArg, Ident, Item, Attribute, FnArg, Ident, Item, ItemMod, LitStr, Meta, Pat, PatIdent, PatType, Token, Type,
ItemMod, LitStr, Meta, Pat, PatIdent, PatType, Token, Type, parse_macro_input, parse_quote, parse_quote_spanned, parse2,
}; };
/// Description of a single argument passed to a builtin /// Description of a single argument passed to a builtin
@ -188,7 +188,9 @@ pub fn builtins(args: TokenStream, item: TokenStream) -> TokenStream {
if let Pat::Ident(PatIdent { ident, .. }) = pat.as_ref() { if let Pat::Ident(PatIdent { ident, .. }) = pat.as_ref() {
if *ident == "state" { if *ident == "state" {
if state_type.is_none() { if state_type.is_none() {
panic!("builtin captures a `state` argument, but no state type was defined"); panic!(
"builtin captures a `state` argument, but no state type was defined"
);
} }
captures_state = true; captures_state = true;

2
snix/eval/rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
# FUTUREWORK: move to .. once all crates are migrated (#114)
edition = "2024"

View file

@ -2,7 +2,7 @@ use bstr::ByteSlice;
use data_encoding::HEXLOWER; use data_encoding::HEXLOWER;
use md5::Md5; use md5::Md5;
use sha1::Sha1; use sha1::Sha1;
use sha2::{digest::Output, Digest, Sha256, Sha512}; use sha2::{Digest, Sha256, Sha512, digest::Output};
use crate::ErrorKind; use crate::ErrorKind;

View file

@ -4,11 +4,10 @@ use genawaiter::rc::Gen;
use std::time::{SystemTime, UNIX_EPOCH}; use std::time::{SystemTime, UNIX_EPOCH};
use crate::{ use crate::{
self as snix_eval, self as snix_eval, NixString, Value,
errors::ErrorKind, errors::ErrorKind,
value::NixAttrs, value::NixAttrs,
vm::generators::{self, GenCo}, vm::generators::{self, GenCo},
NixString, Value,
}; };
#[builtins] #[builtins]

View file

@ -101,12 +101,12 @@ fn cached_regex(pattern: &str) -> Result<Regex, regex::Error> {
mod pure_builtins { mod pure_builtins {
use std::ffi::OsString; use std::ffi::OsString;
use bstr::{BString, ByteSlice, B}; use bstr::{B, BString, ByteSlice};
use itertools::Itertools; use itertools::Itertools;
use os_str_bytes::OsStringBytes; use os_str_bytes::OsStringBytes;
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
use crate::{value::PointerEquality, AddContext, NixContext, NixContextElement}; use crate::{AddContext, NixContext, NixContextElement, value::PointerEquality};
use super::*; use super::*;
@ -355,11 +355,7 @@ mod pure_builtins {
.rfind_char('/') .rfind_char('/')
.map(|last_slash| { .map(|last_slash| {
let x = &str[..last_slash]; let x = &str[..last_slash];
if x.is_empty() { if x.is_empty() { B("/") } else { x }
B("/")
} else {
x
}
}) })
.unwrap_or(b"."); .unwrap_or(b".");
if is_path { if is_path {

View file

@ -85,7 +85,7 @@ fn value_variant_to_xml<W: Write>(w: &mut XmlEmitter<W>, value: &Value) -> Resul
if formals.ellipsis { if formals.ellipsis {
attrs.push(("ellipsis", "1")); attrs.push(("ellipsis", "1"));
} }
if let Some(ref name) = &formals.name { if let Some(name) = &formals.name {
attrs.push(("name", name.as_str())); attrs.push(("name", name.as_str()));
} }
@ -126,7 +126,7 @@ fn value_variant_to_xml<W: Write>(w: &mut XmlEmitter<W>, value: &Value) -> Resul
return Err(ErrorKind::SnixBug { return Err(ErrorKind::SnixBug {
msg: "internal value variant encountered in builtins.toXML", msg: "internal value variant encountered in builtins.toXML",
metadata: Some(Rc::new(value.clone())), metadata: Some(Rc::new(value.clone())),
}) });
} }
Value::Catchable(_) => { Value::Catchable(_) => {

View file

@ -1,8 +1,8 @@
use std::cmp::Ordering; use std::cmp::Ordering;
use std::iter::{once, Chain, Once}; use std::iter::{Chain, Once, once};
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use bstr::{BStr, ByteSlice, B}; use bstr::{B, BStr, ByteSlice};
/// Version strings can be broken up into Parts. /// Version strings can be broken up into Parts.
/// One Part represents either a string of digits or characters. /// One Part represents either a string of digits or characters.
@ -97,10 +97,10 @@ impl<'a> Iterator for VersionPartsIter<'a> {
match cached_part { match cached_part {
InternalPart::Break => return None, InternalPart::Break => return None,
InternalPart::Number { range } => { InternalPart::Number { range } => {
return Some(VersionPart::Number(&self.version[range])) return Some(VersionPart::Number(&self.version[range]));
} }
InternalPart::Word { range } => { InternalPart::Word { range } => {
return Some(VersionPart::Word(&self.version[range])) return Some(VersionPart::Word(&self.version[range]));
} }
} }
} }

View file

@ -114,7 +114,7 @@ impl Binding {
value: ast::Expr, value: ast::Expr,
) { ) {
match self { match self {
Binding::InheritFrom { name, ref span, .. } => { Binding::InheritFrom { name, span, .. } => {
c.emit_error(span, ErrorKind::UnmergeableInherit { name: name.clone() }) c.emit_error(span, ErrorKind::UnmergeableInherit { name: name.clone() })
} }

View file

@ -10,12 +10,12 @@ use genawaiter::rc::Gen;
use std::rc::Weak; use std::rc::Weak;
use crate::{ use crate::{
ErrorKind, SourceCode, Value,
builtins::coerce_value_to_path, builtins::coerce_value_to_path,
generators::pin_generator, generators::pin_generator,
observer::NoOpObserver, observer::NoOpObserver,
value::{Builtin, Thunk}, value::{Builtin, Thunk},
vm::generators::{self, GenCo}, vm::generators::{self, GenCo},
ErrorKind, SourceCode, Value,
}; };
async fn import_impl( async fn import_impl(

View file

@ -26,6 +26,8 @@ use std::collections::BTreeMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::{Rc, Weak}; use std::rc::{Rc, Weak};
use crate::CoercionKind;
use crate::SourceCode;
use crate::chunk::Chunk; use crate::chunk::Chunk;
use crate::errors::{CatchableErrorKind, Error, ErrorKind, EvalResult}; use crate::errors::{CatchableErrorKind, Error, ErrorKind, EvalResult};
use crate::observer::CompilerObserver; use crate::observer::CompilerObserver;
@ -33,8 +35,6 @@ use crate::opcode::{CodeIdx, Op, Position, UpvalueIdx};
use crate::spans::ToSpan; use crate::spans::ToSpan;
use crate::value::{Closure, Formals, Lambda, NixAttrs, Thunk, Value}; use crate::value::{Closure, Formals, Lambda, NixAttrs, Thunk, Value};
use crate::warnings::{EvalWarning, WarningKind}; use crate::warnings::{EvalWarning, WarningKind};
use crate::CoercionKind;
use crate::SourceCode;
use self::scope::{LocalIdx, LocalPosition, Scope, Upvalue, UpvalueKind}; use self::scope::{LocalIdx, LocalPosition, Scope, Upvalue, UpvalueKind};
@ -1141,16 +1141,20 @@ impl Compiler<'_, '_> {
if self.scope()[tracked_formal.local_idx()].needs_finaliser { if self.scope()[tracked_formal.local_idx()].needs_finaliser {
let stack_idx = self.scope().stack_index(tracked_formal.local_idx()); let stack_idx = self.scope().stack_index(tracked_formal.local_idx());
match tracked_formal { match tracked_formal {
TrackedFormal::NoDefault { .. } => TrackedFormal::NoDefault { .. } => panic!(
panic!("Snix bug: local for pattern formal needs finaliser, but has no default expr"), "Snix bug: local for pattern formal needs finaliser, but has no default expr"
TrackedFormal::WithDefault { finalise_request_idx, .. } => { ),
let finalise_request_stack_idx = self.scope().stack_index(*finalise_request_idx); TrackedFormal::WithDefault {
finalise_request_idx,
..
} => {
let finalise_request_stack_idx =
self.scope().stack_index(*finalise_request_idx);
// TODO(sterni): better spans // TODO(sterni): better spans
self.push_op(Op::GetLocal, pattern); self.push_op(Op::GetLocal, pattern);
self.push_uvarint(finalise_request_stack_idx.0 as u64); self.push_uvarint(finalise_request_stack_idx.0 as u64);
let jump_over_finalise = let jump_over_finalise = self.push_op(Op::JumpIfNoFinaliseRequest, pattern);
self.push_op(Op::JumpIfNoFinaliseRequest, pattern);
self.push_u16(0); self.push_u16(0);
self.push_op(Op::Finalise, pattern); self.push_op(Op::Finalise, pattern);
self.push_uvarint(stack_idx.0 as u64); self.push_uvarint(stack_idx.0 as u64);
@ -1502,7 +1506,7 @@ fn expr_static_attr_str(node: &ast::Attr) -> Option<SmolStr> {
// about the dynamic wrapper when determining whether the node // about the dynamic wrapper when determining whether the node
// itself is dynamic, it depends solely on the expression inside // itself is dynamic, it depends solely on the expression inside
// (i.e. `let ${"a"} = 1; in a` is valid). // (i.e. `let ${"a"} = 1; in a` is valid).
ast::Attr::Dynamic(ref dynamic) => match dynamic.expr().unwrap() { ast::Attr::Dynamic(dynamic) => match dynamic.expr().unwrap() {
ast::Expr::Str(s) => expr_static_str(&s), ast::Expr::Str(s) => expr_static_str(&s),
_ => None, _ => None,
}, },

View file

@ -47,13 +47,13 @@ use crate::value::Lambda;
use crate::vm::run_lambda; use crate::vm::run_lambda;
// Re-export the public interface used by other crates. // Re-export the public interface used by other crates.
pub use crate::compiler::{compile, prepare_globals, CompilationOutput, GlobalsMap}; pub use crate::compiler::{CompilationOutput, GlobalsMap, compile, prepare_globals};
pub use crate::errors::{AddContext, CatchableErrorKind, Error, ErrorKind, EvalResult}; pub use crate::errors::{AddContext, CatchableErrorKind, Error, ErrorKind, EvalResult};
pub use crate::io::{DummyIO, EvalIO, FileType}; pub use crate::io::{DummyIO, EvalIO, FileType};
pub use crate::pretty_ast::pretty_print_expr; pub use crate::pretty_ast::pretty_print_expr;
pub use crate::source::SourceCode; pub use crate::source::SourceCode;
pub use crate::value::{NixContext, NixContextElement}; pub use crate::value::{NixContext, NixContextElement};
pub use crate::vm::{generators, EvalMode}; pub use crate::vm::{EvalMode, generators};
pub use crate::warnings::{EvalWarning, WarningKind}; pub use crate::warnings::{EvalWarning, WarningKind};
pub use builtin_macros; pub use builtin_macros;
use smol_str::SmolStr; use smol_str::SmolStr;

View file

@ -3,8 +3,8 @@ use std::convert::Infallible;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use crate::errors::{CatchableErrorKind, ErrorKind};
use crate::EvalIO; use crate::EvalIO;
use crate::errors::{CatchableErrorKind, ErrorKind};
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
enum NixSearchPathEntry { enum NixSearchPathEntry {

View file

@ -11,12 +11,12 @@ use std::rc::Rc;
use std::time::Instant; use std::time::Instant;
use tabwriter::TabWriter; use tabwriter::TabWriter;
use crate::SourceCode;
use crate::Value;
use crate::chunk::Chunk; use crate::chunk::Chunk;
use crate::generators::VMRequest; use crate::generators::VMRequest;
use crate::opcode::{CodeIdx, Op}; use crate::opcode::{CodeIdx, Op};
use crate::value::Lambda; use crate::value::Lambda;
use crate::SourceCode;
use crate::Value;
/// Implemented by types that wish to observe internal happenings of /// Implemented by types that wish to observe internal happenings of
/// the Snix compiler. /// the Snix compiler.

View file

@ -4,7 +4,7 @@
//! printed in either minimised or well-formatted style. //! printed in either minimised or well-formatted style.
use rnix::ast::{self, AstToken, HasEntry}; use rnix::ast::{self, AstToken, HasEntry};
use serde::{ser::SerializeMap, Serialize, Serializer}; use serde::{Serialize, Serializer, ser::SerializeMap};
pub fn pretty_print_expr(expr: &ast::Expr) -> String { pub fn pretty_print_expr(expr: &ast::Expr) -> String {
serde_json::ser::to_string_pretty(&SerializeAST(expr)) serde_json::ser::to_string_pretty(&SerializeAST(expr))

View file

@ -1,4 +1,4 @@
use crate::{value::Value, EvalIO, FileType}; use crate::{EvalIO, FileType, value::Value};
use builtin_macros::builtins; use builtin_macros::builtins;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest; use rstest::rstest;
@ -91,7 +91,7 @@ where
#[cfg(feature = "impure")] #[cfg(feature = "impure")]
fn eval_test(code_path: PathBuf, expect_success: bool) { fn eval_test(code_path: PathBuf, expect_success: bool) {
use crate::{vm::EvalMode, StdIO}; use crate::{StdIO, vm::EvalMode};
eprintln!("path: {}", code_path.display()); eprintln!("path: {}", code_path.display());
assert_eq!( assert_eq!(
@ -180,7 +180,7 @@ fn eval_test(code_path: PathBuf, expect_success: bool) {
#[cfg(feature = "impure")] #[cfg(feature = "impure")]
#[rstest] #[rstest]
fn identity(#[files("src/tests/snix_tests/identity-*.nix")] code_path: PathBuf) { fn identity(#[files("src/tests/snix_tests/identity-*.nix")] code_path: PathBuf) {
use crate::{vm::EvalMode, EvalIO}; use crate::{EvalIO, vm::EvalMode};
let code = std::fs::read_to_string(code_path).expect("should be able to read test code"); let code = std::fs::read_to_string(code_path).expect("should be able to read test code");

View file

@ -9,7 +9,7 @@
use std::ops::Index; use std::ops::Index;
use crate::{opcode::UpvalueIdx, Value}; use crate::{Value, opcode::UpvalueIdx};
/// Structure for carrying upvalues of an UpvalueCarrier. The /// Structure for carrying upvalues of an UpvalueCarrier. The
/// implementation of this struct encapsulates the logic for /// implementation of this struct encapsulates the logic for

View file

@ -4,7 +4,7 @@ use proptest::collection::{btree_map, vec};
use proptest::{prelude::*, strategy::BoxedStrategy}; use proptest::{prelude::*, strategy::BoxedStrategy};
use std::ffi::OsString; use std::ffi::OsString;
use super::{attrs::AttrsRep, NixAttrs, NixList, NixString, Value}; use super::{NixAttrs, NixList, NixString, Value, attrs::AttrsRep};
#[derive(Clone)] #[derive(Clone)]
pub enum Parameters { pub enum Parameters {

View file

@ -6,7 +6,7 @@
//! Due to this, construction and management of attribute sets has //! Due to this, construction and management of attribute sets has
//! some peculiarities that are encapsulated within this module. //! some peculiarities that are encapsulated within this module.
use std::borrow::Borrow; use std::borrow::Borrow;
use std::collections::{hash_map, BTreeMap}; use std::collections::{BTreeMap, hash_map};
use std::iter::FromIterator; use std::iter::FromIterator;
use std::rc::Rc; use std::rc::Rc;
use std::sync::LazyLock; use std::sync::LazyLock;
@ -14,15 +14,15 @@ use std::sync::LazyLock;
use bstr::BStr; use bstr::BStr;
use itertools::Itertools as _; use itertools::Itertools as _;
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use serde::de::{Deserializer, Error, Visitor};
use serde::Deserialize; use serde::Deserialize;
use serde::de::{Deserializer, Error, Visitor};
use super::string::NixString;
use super::thunk::ThunkSet;
use super::TotalDisplay; use super::TotalDisplay;
use super::Value; use super::Value;
use crate::errors::ErrorKind; use super::string::NixString;
use super::thunk::ThunkSet;
use crate::CatchableErrorKind; use crate::CatchableErrorKind;
use crate::errors::ErrorKind;
static NAME: LazyLock<NixString> = LazyLock::new(|| "name".into()); static NAME: LazyLock<NixString> = LazyLock::new(|| "name".into());
static VALUE: LazyLock<NixString> = LazyLock::new(|| "value".into()); static VALUE: LazyLock<NixString> = LazyLock::new(|| "value".into());
@ -300,10 +300,7 @@ impl NixAttrs {
AttrsRep::Map(map) => KeyValue::Map(map.iter()), AttrsRep::Map(map) => KeyValue::Map(map.iter()),
AttrsRep::Empty => KeyValue::Empty, AttrsRep::Empty => KeyValue::Empty,
AttrsRep::KV { AttrsRep::KV { name, value } => KeyValue::KV {
ref name,
ref value,
} => KeyValue::KV {
name, name,
value, value,
at: IterKV::default(), at: IterKV::default(),
@ -320,10 +317,7 @@ impl NixAttrs {
let sorted = map.iter().sorted_by_key(|x| x.0); let sorted = map.iter().sorted_by_key(|x| x.0);
KeyValue::Sorted(sorted) KeyValue::Sorted(sorted)
} }
AttrsRep::KV { AttrsRep::KV { name, value } => KeyValue::KV {
ref name,
ref value,
} => KeyValue::KV {
name, name,
value, value,
at: IterKV::default(), at: IterKV::default(),

View file

@ -4,13 +4,13 @@
/// as there is internal Nix logic that must happen within the /// as there is internal Nix logic that must happen within the
/// serialisation methods. /// serialisation methods.
use super::{CoercionKind, Value}; use super::{CoercionKind, Value};
use crate::NixContext;
use crate::errors::ErrorKind; use crate::errors::ErrorKind;
use crate::generators::{self, GenCo}; use crate::generators::{self, GenCo};
use crate::NixContext;
use bstr::ByteSlice; use bstr::ByteSlice;
use serde_json::value::to_value;
use serde_json::Value as Json; // name clash with *our* `Value` use serde_json::Value as Json; // name clash with *our* `Value`
use serde_json::value::to_value;
use serde_json::{Map, Number}; use serde_json::{Map, Number};
impl Value { impl Value {
@ -110,7 +110,7 @@ impl Value {
| val @ Value::DeferredUpvalue(_) | val @ Value::DeferredUpvalue(_)
| val @ Value::UnresolvedPath(_) | val @ Value::UnresolvedPath(_)
| val @ Value::FinaliseRequest(_) => { | val @ Value::FinaliseRequest(_) => {
return Err(ErrorKind::NotSerialisableToJson(val.type_of())) return Err(ErrorKind::NotSerialisableToJson(val.type_of()));
} }
}; };
Ok((value, context)) Ok((value, context))

View file

@ -4,9 +4,9 @@ use std::rc::Rc;
use serde::Deserialize; use serde::Deserialize;
use super::thunk::ThunkSet;
use super::TotalDisplay; use super::TotalDisplay;
use super::Value; use super::Value;
use super::thunk::ThunkSet;
#[repr(transparent)] #[repr(transparent)]
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]

View file

@ -23,10 +23,10 @@ mod path;
mod string; mod string;
mod thunk; mod thunk;
use crate::AddContext;
use crate::errors::{CatchableErrorKind, ErrorKind}; use crate::errors::{CatchableErrorKind, ErrorKind};
use crate::opcode::StackIdx; use crate::opcode::StackIdx;
use crate::vm::generators::{self, GenCo}; use crate::vm::generators::{self, GenCo};
use crate::AddContext;
pub use attrs::NixAttrs; pub use attrs::NixAttrs;
pub use builtin::{Builtin, BuiltinResult}; pub use builtin::{Builtin, BuiltinResult};
pub(crate) use function::Formals; pub(crate) use function::Formals;
@ -810,7 +810,7 @@ impl Value {
return Err(ErrorKind::Incomparable { return Err(ErrorKind::Incomparable {
lhs: lhs.type_of(), lhs: lhs.type_of(),
rhs: rhs.type_of(), rhs: rhs.type_of(),
}) });
} }
}; };
if result != Ordering::Equal { if result != Ordering::Equal {

View file

@ -9,7 +9,7 @@ use rnix::ast;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
use rustc_hash::FxHasher; use rustc_hash::FxHasher;
use std::alloc::dealloc; use std::alloc::dealloc;
use std::alloc::{alloc, handle_alloc_error, Layout}; use std::alloc::{Layout, alloc, handle_alloc_error};
use std::borrow::{Borrow, Cow}; use std::borrow::{Borrow, Cow};
use std::cell::RefCell; use std::cell::RefCell;
use std::ffi::c_void; use std::ffi::c_void;
@ -19,8 +19,8 @@ use std::ops::Deref;
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use std::slice; use std::slice;
use serde::de::{Deserializer, Visitor};
use serde::Deserialize; use serde::Deserialize;
use serde::de::{Deserializer, Visitor};
mod context; mod context;
@ -75,12 +75,14 @@ impl NixStringInner {
/// This function must only be called on a pointer that has been properly initialized with /// This function must only be called on a pointer that has been properly initialized with
/// [`Self::alloc`]. The data buffer may not necessarily be initialized /// [`Self::alloc`]. The data buffer may not necessarily be initialized
unsafe fn layout_of(this: NonNull<c_void>) -> (Layout, usize, usize) { unsafe fn layout_of(this: NonNull<c_void>) -> (Layout, usize, usize) {
let layout = Layout::new::<Option<Box<NixContext>>>(); unsafe {
let (_, len_offset) = layout.extend(Layout::new::<usize>()).unwrap(); let layout = Layout::new::<Option<Box<NixContext>>>();
// SAFETY: Layouts are linear, so even though we haven't involved data at all yet, we know let (_, len_offset) = layout.extend(Layout::new::<usize>()).unwrap();
// the len_offset is a valid offset into the second field of the allocation // SAFETY: Layouts are linear, so even though we haven't involved data at all yet, we know
let len = *(this.as_ptr().add(len_offset) as *const usize); // the len_offset is a valid offset into the second field of the allocation
Self::layout(len) let len = *(this.as_ptr().add(len_offset) as *const usize);
Self::layout(len)
}
} }
/// Allocate an *uninitialized* nix string with the given length. Writes the length to the /// Allocate an *uninitialized* nix string with the given length. Writes the length to the
@ -121,9 +123,11 @@ impl NixStringInner {
/// This function must only be called with a pointer that has been properly initialized with /// This function must only be called with a pointer that has been properly initialized with
/// [`Self::alloc`] /// [`Self::alloc`]
unsafe fn dealloc(this: NonNull<c_void>) { unsafe fn dealloc(this: NonNull<c_void>) {
let (layout, _, _) = Self::layout_of(this); unsafe {
// SAFETY: okay because of the safety guarantees of this method let (layout, _, _) = Self::layout_of(this);
dealloc(this.as_ptr() as *mut u8, layout) // SAFETY: okay because of the safety guarantees of this method
dealloc(this.as_ptr() as *mut u8, layout)
}
} }
/// Return the length of the Nix string at the given pointer /// Return the length of the Nix string at the given pointer
@ -133,11 +137,13 @@ impl NixStringInner {
/// This function must only be called with a pointer that has been properly initialized with /// This function must only be called with a pointer that has been properly initialized with
/// [`Self::alloc`] /// [`Self::alloc`]
unsafe fn len(this: NonNull<c_void>) -> usize { unsafe fn len(this: NonNull<c_void>) -> usize {
let (_, len_offset, _) = Self::layout_of(this); unsafe {
// SAFETY: As long as the safety guarantees of this method are upheld, we've allocated with let (_, len_offset, _) = Self::layout_of(this);
// a layout that causes the len_offset to be in-bounds and writeable, and if the allocation // SAFETY: As long as the safety guarantees of this method are upheld, we've allocated with
// succeeded it won't wrap // a layout that causes the len_offset to be in-bounds and writeable, and if the allocation
*(this.as_ptr().add(len_offset) as *const usize) // succeeded it won't wrap
*(this.as_ptr().add(len_offset) as *const usize)
}
} }
/// Return a pointer to the context value within the given Nix string pointer /// Return a pointer to the context value within the given Nix string pointer
@ -162,7 +168,7 @@ impl NixStringInner {
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See /// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
/// [`NonNull::as_ref`] for more. /// [`NonNull::as_ref`] for more.
unsafe fn context_ref<'a>(this: NonNull<c_void>) -> &'a Option<Box<NixContext>> { unsafe fn context_ref<'a>(this: NonNull<c_void>) -> &'a Option<Box<NixContext>> {
Self::context_ptr(this).as_ref().unwrap() unsafe { Self::context_ptr(this).as_ref().unwrap() }
} }
/// Construct a mutable reference to the context value within the given Nix string pointer /// Construct a mutable reference to the context value within the given Nix string pointer
@ -176,7 +182,7 @@ impl NixStringInner {
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See /// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
/// [`NonNull::as_mut`] for more. /// [`NonNull::as_mut`] for more.
unsafe fn context_mut<'a>(this: NonNull<c_void>) -> &'a mut Option<Box<NixContext>> { unsafe fn context_mut<'a>(this: NonNull<c_void>) -> &'a mut Option<Box<NixContext>> {
Self::context_ptr(this).as_mut().unwrap() unsafe { Self::context_ptr(this).as_mut().unwrap() }
} }
/// Return a pointer to the data array within the given Nix string pointer /// Return a pointer to the data array within the given Nix string pointer
@ -186,9 +192,11 @@ impl NixStringInner {
/// This function must only be called with a pointer that has been properly initialized with /// This function must only be called with a pointer that has been properly initialized with
/// [`Self::alloc`] /// [`Self::alloc`]
unsafe fn data_ptr(this: NonNull<c_void>) -> *mut u8 { unsafe fn data_ptr(this: NonNull<c_void>) -> *mut u8 {
let (_, _, data_offset) = Self::layout_of(this); unsafe {
// SAFETY: data is the third field in the layout of the allocation let (_, _, data_offset) = Self::layout_of(this);
this.as_ptr().add(data_offset) as *mut u8 // SAFETY: data is the third field in the layout of the allocation
this.as_ptr().add(data_offset) as *mut u8
}
} }
/// Construct a shared reference to the data slice within the given Nix string pointer /// Construct a shared reference to the data slice within the given Nix string pointer
@ -202,9 +210,11 @@ impl NixStringInner {
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See /// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
/// [`slice::from_raw_parts`] for more. /// [`slice::from_raw_parts`] for more.
unsafe fn data_slice<'a>(this: NonNull<c_void>) -> &'a [u8] { unsafe fn data_slice<'a>(this: NonNull<c_void>) -> &'a [u8] {
let len = Self::len(this); unsafe {
let data = Self::data_ptr(this); let len = Self::len(this);
slice::from_raw_parts(data, len) let data = Self::data_ptr(this);
slice::from_raw_parts(data, len)
}
} }
/// Construct a mutable reference to the data slice within the given Nix string pointer /// Construct a mutable reference to the data slice within the given Nix string pointer
@ -219,9 +229,11 @@ impl NixStringInner {
/// [`slice::from_raw_parts_mut`] for more. /// [`slice::from_raw_parts_mut`] for more.
#[allow(dead_code)] #[allow(dead_code)]
unsafe fn data_slice_mut<'a>(this: NonNull<c_void>) -> &'a mut [u8] { unsafe fn data_slice_mut<'a>(this: NonNull<c_void>) -> &'a mut [u8] {
let len = Self::len(this); unsafe {
let data = Self::data_ptr(this); let len = Self::len(this);
slice::from_raw_parts_mut(data, len) let data = Self::data_ptr(this);
slice::from_raw_parts_mut(data, len)
}
} }
/// Clone the Nix string pointed to by this pointer, and return a pointer to a new Nix string /// Clone the Nix string pointed to by this pointer, and return a pointer to a new Nix string
@ -234,14 +246,16 @@ impl NixStringInner {
/// pointer returned from [`Self::context_ptr`]), and the data array has been properly /// pointer returned from [`Self::context_ptr`]), and the data array has been properly
/// initialized (by writing to the pointer returned from [`Self::data_ptr`]). /// initialized (by writing to the pointer returned from [`Self::data_ptr`]).
unsafe fn clone(this: NonNull<c_void>) -> NonNull<c_void> { unsafe fn clone(this: NonNull<c_void>) -> NonNull<c_void> {
let (layout, _, _) = Self::layout_of(this); unsafe {
let ptr = alloc(layout); let (layout, _, _) = Self::layout_of(this);
if let Some(new) = NonNull::new(ptr as *mut _) { let ptr = alloc(layout);
ptr::copy_nonoverlapping(this.as_ptr(), new.as_ptr(), layout.size()); if let Some(new) = NonNull::new(ptr as *mut _) {
Self::context_ptr(new).write(Self::context_ref(this).clone()); ptr::copy_nonoverlapping(this.as_ptr(), new.as_ptr(), layout.size());
new Self::context_ptr(new).write(Self::context_ref(this).clone());
} else { new
handle_alloc_error(layout); } else {
handle_alloc_error(layout);
}
} }
} }
} }
@ -543,7 +557,7 @@ impl Deref for NixString {
#[cfg(feature = "arbitrary")] #[cfg(feature = "arbitrary")]
mod arbitrary { mod arbitrary {
use super::*; use super::*;
use proptest::prelude::{any_with, Arbitrary}; use proptest::prelude::{Arbitrary, any_with};
use proptest::strategy::{BoxedStrategy, Strategy}; use proptest::strategy::{BoxedStrategy, Strategy};
impl Arbitrary for NixString { impl Arbitrary for NixString {

View file

@ -26,12 +26,12 @@ use std::{
}; };
use crate::{ use crate::{
Value,
errors::ErrorKind, errors::ErrorKind,
opcode::Op, opcode::Op,
upvalues::Upvalues, upvalues::Upvalues,
value::Closure, value::Closure,
vm::generators::{self, GenCo}, vm::generators::{self, GenCo},
Value,
}; };
use super::{Lambda, TotalDisplay}; use super::{Lambda, TotalDisplay};
@ -240,7 +240,7 @@ impl Thunk {
first_force: forced_at, first_force: forced_at,
suspended_at, suspended_at,
content_span, content_span,
}) });
} }
// If there is a native function stored in the thunk, evaluate it // If there is a native function stored in the thunk, evaluate it

View file

@ -14,10 +14,10 @@ use std::ffi::OsString;
use std::fmt::Display; use std::fmt::Display;
use std::future::Future; use std::future::Future;
use crate::value::PointerEquality;
use crate::warnings::{EvalWarning, WarningKind};
use crate::FileType; use crate::FileType;
use crate::NixString; use crate::NixString;
use crate::value::PointerEquality;
use crate::warnings::{EvalWarning, WarningKind};
use super::*; use super::*;
@ -254,7 +254,7 @@ where
} }
/// Helper function to enqueue a new generator. /// Helper function to enqueue a new generator.
pub(super) fn enqueue_generator<F, G>(&mut self, name: &'static str, span: Span, gen: G) pub(super) fn enqueue_generator<F, G>(&mut self, name: &'static str, span: Span, r#gen: G)
where where
F: Future<Output = Result<Value, ErrorKind>> + 'static, F: Future<Output = Result<Value, ErrorKind>> + 'static,
G: FnOnce(GenCo) -> F, G: FnOnce(GenCo) -> F,
@ -263,7 +263,7 @@ where
name, name,
span, span,
state: GeneratorState::Running, state: GeneratorState::Running,
generator: Gen::new(|co| pin_generator(gen(co))), generator: Gen::new(|co| pin_generator(r#gen(co))),
}); });
} }

View file

@ -19,7 +19,7 @@ use serde_json::json;
use std::{cmp::Ordering, ops::DerefMut, path::PathBuf, rc::Rc}; use std::{cmp::Ordering, ops::DerefMut, path::PathBuf, rc::Rc};
use crate::{ use crate::{
arithmetic_op, NixString, SourceCode, arithmetic_op,
chunk::Chunk, chunk::Chunk,
cmp_op, cmp_op,
compiler::GlobalsMap, compiler::GlobalsMap,
@ -36,10 +36,9 @@ use crate::{
}, },
vm::generators::GenCo, vm::generators::GenCo,
warnings::{EvalWarning, WarningKind}, warnings::{EvalWarning, WarningKind},
NixString, SourceCode,
}; };
use generators::{call_functor, Generator, GeneratorState}; use generators::{Generator, GeneratorState, call_functor};
use self::generators::{VMRequest, VMResponse}; use self::generators::{VMRequest, VMResponse};
@ -641,8 +640,11 @@ where
if !finalise { if !finalise {
frame.ip += offset; frame.ip += offset;
} }
}, }
val => panic!("Snix bug: OpJumIfNoFinaliseRequest: expected FinaliseRequest, but got {}", val.type_of()), val => panic!(
"Snix bug: OpJumIfNoFinaliseRequest: expected FinaliseRequest, but got {}",
val.type_of()
),
} }
} }