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:
parent
beca8c8a4c
commit
40ab29c05a
31 changed files with 130 additions and 115 deletions
|
|
@ -4031,7 +4031,7 @@ rec {
|
|||
"snix-eval" = rec {
|
||||
crateName = "snix-eval";
|
||||
version = "0.1.0";
|
||||
edition = "2021";
|
||||
edition = "2024";
|
||||
src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval; };
|
||||
libName = "snix_eval";
|
||||
dependencies = [
|
||||
|
|
@ -4166,7 +4166,7 @@ rec {
|
|||
"snix-eval-builtin-macros" = rec {
|
||||
crateName = "snix-eval-builtin-macros";
|
||||
version = "0.0.1";
|
||||
edition = "2021";
|
||||
edition = "2024";
|
||||
src = lib.cleanSourceWith { filter = sourceFilter; src = ../../snix/eval/builtin-macros; };
|
||||
procMacro = true;
|
||||
libName = "snix_eval_builtin_macros";
|
||||
|
|
|
|||
|
|
@ -14138,7 +14138,7 @@ rec {
|
|||
"snix-eval" = rec {
|
||||
crateName = "snix-eval";
|
||||
version = "0.1.0";
|
||||
edition = "2021";
|
||||
edition = "2024";
|
||||
src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval; };
|
||||
libName = "snix_eval";
|
||||
dependencies = [
|
||||
|
|
@ -14307,7 +14307,7 @@ rec {
|
|||
"snix-eval-builtin-macros" = rec {
|
||||
crateName = "snix-eval-builtin-macros";
|
||||
version = "0.0.1";
|
||||
edition = "2021";
|
||||
edition = "2024";
|
||||
src = lib.cleanSourceWith { filter = sourceFilter; src = ./eval/builtin-macros; };
|
||||
procMacro = true;
|
||||
libName = "snix_eval_builtin_macros";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[package]
|
||||
name = "snix-eval"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
name = "snix_eval"
|
||||
|
|
|
|||
|
|
@ -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 mimalloc::MiMalloc;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
name = "snix-eval-builtin-macros"
|
||||
version = "0.0.1"
|
||||
authors = ["Griffin Smith <root@gws.fyi>"]
|
||||
edition = "2021"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "1.0.109", features = [
|
||||
|
|
|
|||
2
snix/eval/builtin-macros/rustfmt.toml
Normal file
2
snix/eval/builtin-macros/rustfmt.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# FUTUREWORK: move to .. once all crates are migrated (#114)
|
||||
edition = "2024"
|
||||
|
|
@ -2,12 +2,12 @@ extern crate proc_macro;
|
|||
|
||||
use proc_macro::TokenStream;
|
||||
use proc_macro2::Span;
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
use quote::{ToTokens, quote, quote_spanned};
|
||||
use syn::parse::Parse;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parse2, parse_macro_input, parse_quote, parse_quote_spanned, Attribute, FnArg, Ident, Item,
|
||||
ItemMod, LitStr, Meta, Pat, PatIdent, PatType, Token, Type,
|
||||
Attribute, FnArg, Ident, Item, 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
|
||||
|
|
@ -188,7 +188,9 @@ pub fn builtins(args: TokenStream, item: TokenStream) -> TokenStream {
|
|||
if let Pat::Ident(PatIdent { ident, .. }) = pat.as_ref() {
|
||||
if *ident == "state" {
|
||||
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;
|
||||
|
|
|
|||
2
snix/eval/rustfmt.toml
Normal file
2
snix/eval/rustfmt.toml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# FUTUREWORK: move to .. once all crates are migrated (#114)
|
||||
edition = "2024"
|
||||
|
|
@ -2,7 +2,7 @@ use bstr::ByteSlice;
|
|||
use data_encoding::HEXLOWER;
|
||||
use md5::Md5;
|
||||
use sha1::Sha1;
|
||||
use sha2::{digest::Output, Digest, Sha256, Sha512};
|
||||
use sha2::{Digest, Sha256, Sha512, digest::Output};
|
||||
|
||||
use crate::ErrorKind;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,11 +4,10 @@ use genawaiter::rc::Gen;
|
|||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use crate::{
|
||||
self as snix_eval,
|
||||
self as snix_eval, NixString, Value,
|
||||
errors::ErrorKind,
|
||||
value::NixAttrs,
|
||||
vm::generators::{self, GenCo},
|
||||
NixString, Value,
|
||||
};
|
||||
|
||||
#[builtins]
|
||||
|
|
|
|||
|
|
@ -101,12 +101,12 @@ fn cached_regex(pattern: &str) -> Result<Regex, regex::Error> {
|
|||
mod pure_builtins {
|
||||
use std::ffi::OsString;
|
||||
|
||||
use bstr::{BString, ByteSlice, B};
|
||||
use bstr::{B, BString, ByteSlice};
|
||||
use itertools::Itertools;
|
||||
use os_str_bytes::OsStringBytes;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
use crate::{value::PointerEquality, AddContext, NixContext, NixContextElement};
|
||||
use crate::{AddContext, NixContext, NixContextElement, value::PointerEquality};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -355,11 +355,7 @@ mod pure_builtins {
|
|||
.rfind_char('/')
|
||||
.map(|last_slash| {
|
||||
let x = &str[..last_slash];
|
||||
if x.is_empty() {
|
||||
B("/")
|
||||
} else {
|
||||
x
|
||||
}
|
||||
if x.is_empty() { B("/") } else { x }
|
||||
})
|
||||
.unwrap_or(b".");
|
||||
if is_path {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ fn value_variant_to_xml<W: Write>(w: &mut XmlEmitter<W>, value: &Value) -> Resul
|
|||
if formals.ellipsis {
|
||||
attrs.push(("ellipsis", "1"));
|
||||
}
|
||||
if let Some(ref name) = &formals.name {
|
||||
if let Some(name) = &formals.name {
|
||||
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 {
|
||||
msg: "internal value variant encountered in builtins.toXML",
|
||||
metadata: Some(Rc::new(value.clone())),
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
Value::Catchable(_) => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::cmp::Ordering;
|
||||
use std::iter::{once, Chain, Once};
|
||||
use std::iter::{Chain, Once, once};
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use bstr::{BStr, ByteSlice, B};
|
||||
use bstr::{B, BStr, ByteSlice};
|
||||
|
||||
/// Version strings can be broken up into Parts.
|
||||
/// One Part represents either a string of digits or characters.
|
||||
|
|
@ -97,10 +97,10 @@ impl<'a> Iterator for VersionPartsIter<'a> {
|
|||
match cached_part {
|
||||
InternalPart::Break => return None,
|
||||
InternalPart::Number { range } => {
|
||||
return Some(VersionPart::Number(&self.version[range]))
|
||||
return Some(VersionPart::Number(&self.version[range]));
|
||||
}
|
||||
InternalPart::Word { range } => {
|
||||
return Some(VersionPart::Word(&self.version[range]))
|
||||
return Some(VersionPart::Word(&self.version[range]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ impl Binding {
|
|||
value: ast::Expr,
|
||||
) {
|
||||
match self {
|
||||
Binding::InheritFrom { name, ref span, .. } => {
|
||||
Binding::InheritFrom { name, span, .. } => {
|
||||
c.emit_error(span, ErrorKind::UnmergeableInherit { name: name.clone() })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ use genawaiter::rc::Gen;
|
|||
use std::rc::Weak;
|
||||
|
||||
use crate::{
|
||||
ErrorKind, SourceCode, Value,
|
||||
builtins::coerce_value_to_path,
|
||||
generators::pin_generator,
|
||||
observer::NoOpObserver,
|
||||
value::{Builtin, Thunk},
|
||||
vm::generators::{self, GenCo},
|
||||
ErrorKind, SourceCode, Value,
|
||||
};
|
||||
|
||||
async fn import_impl(
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ use std::collections::BTreeMap;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::rc::{Rc, Weak};
|
||||
|
||||
use crate::CoercionKind;
|
||||
use crate::SourceCode;
|
||||
use crate::chunk::Chunk;
|
||||
use crate::errors::{CatchableErrorKind, Error, ErrorKind, EvalResult};
|
||||
use crate::observer::CompilerObserver;
|
||||
|
|
@ -33,8 +35,6 @@ use crate::opcode::{CodeIdx, Op, Position, UpvalueIdx};
|
|||
use crate::spans::ToSpan;
|
||||
use crate::value::{Closure, Formals, Lambda, NixAttrs, Thunk, Value};
|
||||
use crate::warnings::{EvalWarning, WarningKind};
|
||||
use crate::CoercionKind;
|
||||
use crate::SourceCode;
|
||||
|
||||
use self::scope::{LocalIdx, LocalPosition, Scope, Upvalue, UpvalueKind};
|
||||
|
||||
|
|
@ -1141,16 +1141,20 @@ impl Compiler<'_, '_> {
|
|||
if self.scope()[tracked_formal.local_idx()].needs_finaliser {
|
||||
let stack_idx = self.scope().stack_index(tracked_formal.local_idx());
|
||||
match tracked_formal {
|
||||
TrackedFormal::NoDefault { .. } =>
|
||||
panic!("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::NoDefault { .. } => panic!(
|
||||
"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);
|
||||
|
||||
// TODO(sterni): better spans
|
||||
self.push_op(Op::GetLocal, pattern);
|
||||
self.push_uvarint(finalise_request_stack_idx.0 as u64);
|
||||
let jump_over_finalise =
|
||||
self.push_op(Op::JumpIfNoFinaliseRequest, pattern);
|
||||
let jump_over_finalise = self.push_op(Op::JumpIfNoFinaliseRequest, pattern);
|
||||
self.push_u16(0);
|
||||
self.push_op(Op::Finalise, pattern);
|
||||
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
|
||||
// itself is dynamic, it depends solely on the expression inside
|
||||
// (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),
|
||||
_ => None,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -47,13 +47,13 @@ use crate::value::Lambda;
|
|||
use crate::vm::run_lambda;
|
||||
|
||||
// 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::io::{DummyIO, EvalIO, FileType};
|
||||
pub use crate::pretty_ast::pretty_print_expr;
|
||||
pub use crate::source::SourceCode;
|
||||
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 builtin_macros;
|
||||
use smol_str::SmolStr;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::convert::Infallible;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::errors::{CatchableErrorKind, ErrorKind};
|
||||
use crate::EvalIO;
|
||||
use crate::errors::{CatchableErrorKind, ErrorKind};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum NixSearchPathEntry {
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ use std::rc::Rc;
|
|||
use std::time::Instant;
|
||||
use tabwriter::TabWriter;
|
||||
|
||||
use crate::SourceCode;
|
||||
use crate::Value;
|
||||
use crate::chunk::Chunk;
|
||||
use crate::generators::VMRequest;
|
||||
use crate::opcode::{CodeIdx, Op};
|
||||
use crate::value::Lambda;
|
||||
use crate::SourceCode;
|
||||
use crate::Value;
|
||||
|
||||
/// Implemented by types that wish to observe internal happenings of
|
||||
/// the Snix compiler.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
//! printed in either minimised or well-formatted style.
|
||||
|
||||
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 {
|
||||
serde_json::ser::to_string_pretty(&SerializeAST(expr))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{value::Value, EvalIO, FileType};
|
||||
use crate::{EvalIO, FileType, value::Value};
|
||||
use builtin_macros::builtins;
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
|
|
@ -91,7 +91,7 @@ where
|
|||
|
||||
#[cfg(feature = "impure")]
|
||||
fn eval_test(code_path: PathBuf, expect_success: bool) {
|
||||
use crate::{vm::EvalMode, StdIO};
|
||||
use crate::{StdIO, vm::EvalMode};
|
||||
|
||||
eprintln!("path: {}", code_path.display());
|
||||
assert_eq!(
|
||||
|
|
@ -180,7 +180,7 @@ fn eval_test(code_path: PathBuf, expect_success: bool) {
|
|||
#[cfg(feature = "impure")]
|
||||
#[rstest]
|
||||
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");
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
use std::ops::Index;
|
||||
|
||||
use crate::{opcode::UpvalueIdx, Value};
|
||||
use crate::{Value, opcode::UpvalueIdx};
|
||||
|
||||
/// Structure for carrying upvalues of an UpvalueCarrier. The
|
||||
/// implementation of this struct encapsulates the logic for
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use proptest::collection::{btree_map, vec};
|
|||
use proptest::{prelude::*, strategy::BoxedStrategy};
|
||||
use std::ffi::OsString;
|
||||
|
||||
use super::{attrs::AttrsRep, NixAttrs, NixList, NixString, Value};
|
||||
use super::{NixAttrs, NixList, NixString, Value, attrs::AttrsRep};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Parameters {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
//! Due to this, construction and management of attribute sets has
|
||||
//! some peculiarities that are encapsulated within this module.
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::{hash_map, BTreeMap};
|
||||
use std::collections::{BTreeMap, hash_map};
|
||||
use std::iter::FromIterator;
|
||||
use std::rc::Rc;
|
||||
use std::sync::LazyLock;
|
||||
|
|
@ -14,15 +14,15 @@ use std::sync::LazyLock;
|
|||
use bstr::BStr;
|
||||
use itertools::Itertools as _;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::de::{Deserializer, Error, Visitor};
|
||||
use serde::Deserialize;
|
||||
use serde::de::{Deserializer, Error, Visitor};
|
||||
|
||||
use super::string::NixString;
|
||||
use super::thunk::ThunkSet;
|
||||
use super::TotalDisplay;
|
||||
use super::Value;
|
||||
use crate::errors::ErrorKind;
|
||||
use super::string::NixString;
|
||||
use super::thunk::ThunkSet;
|
||||
use crate::CatchableErrorKind;
|
||||
use crate::errors::ErrorKind;
|
||||
|
||||
static NAME: LazyLock<NixString> = LazyLock::new(|| "name".into());
|
||||
static VALUE: LazyLock<NixString> = LazyLock::new(|| "value".into());
|
||||
|
|
@ -300,10 +300,7 @@ impl NixAttrs {
|
|||
AttrsRep::Map(map) => KeyValue::Map(map.iter()),
|
||||
AttrsRep::Empty => KeyValue::Empty,
|
||||
|
||||
AttrsRep::KV {
|
||||
ref name,
|
||||
ref value,
|
||||
} => KeyValue::KV {
|
||||
AttrsRep::KV { name, value } => KeyValue::KV {
|
||||
name,
|
||||
value,
|
||||
at: IterKV::default(),
|
||||
|
|
@ -320,10 +317,7 @@ impl NixAttrs {
|
|||
let sorted = map.iter().sorted_by_key(|x| x.0);
|
||||
KeyValue::Sorted(sorted)
|
||||
}
|
||||
AttrsRep::KV {
|
||||
ref name,
|
||||
ref value,
|
||||
} => KeyValue::KV {
|
||||
AttrsRep::KV { name, value } => KeyValue::KV {
|
||||
name,
|
||||
value,
|
||||
at: IterKV::default(),
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@
|
|||
/// as there is internal Nix logic that must happen within the
|
||||
/// serialisation methods.
|
||||
use super::{CoercionKind, Value};
|
||||
use crate::NixContext;
|
||||
use crate::errors::ErrorKind;
|
||||
use crate::generators::{self, GenCo};
|
||||
use crate::NixContext;
|
||||
|
||||
use bstr::ByteSlice;
|
||||
use serde_json::value::to_value;
|
||||
use serde_json::Value as Json; // name clash with *our* `Value`
|
||||
use serde_json::value::to_value;
|
||||
use serde_json::{Map, Number};
|
||||
|
||||
impl Value {
|
||||
|
|
@ -110,7 +110,7 @@ impl Value {
|
|||
| val @ Value::DeferredUpvalue(_)
|
||||
| val @ Value::UnresolvedPath(_)
|
||||
| val @ Value::FinaliseRequest(_) => {
|
||||
return Err(ErrorKind::NotSerialisableToJson(val.type_of()))
|
||||
return Err(ErrorKind::NotSerialisableToJson(val.type_of()));
|
||||
}
|
||||
};
|
||||
Ok((value, context))
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ use std::rc::Rc;
|
|||
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::thunk::ThunkSet;
|
||||
use super::TotalDisplay;
|
||||
use super::Value;
|
||||
use super::thunk::ThunkSet;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ mod path;
|
|||
mod string;
|
||||
mod thunk;
|
||||
|
||||
use crate::AddContext;
|
||||
use crate::errors::{CatchableErrorKind, ErrorKind};
|
||||
use crate::opcode::StackIdx;
|
||||
use crate::vm::generators::{self, GenCo};
|
||||
use crate::AddContext;
|
||||
pub use attrs::NixAttrs;
|
||||
pub use builtin::{Builtin, BuiltinResult};
|
||||
pub(crate) use function::Formals;
|
||||
|
|
@ -810,7 +810,7 @@ impl Value {
|
|||
return Err(ErrorKind::Incomparable {
|
||||
lhs: lhs.type_of(),
|
||||
rhs: rhs.type_of(),
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
if result != Ordering::Equal {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use rnix::ast;
|
|||
use rustc_hash::FxHashSet;
|
||||
use rustc_hash::FxHasher;
|
||||
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::cell::RefCell;
|
||||
use std::ffi::c_void;
|
||||
|
|
@ -19,8 +19,8 @@ use std::ops::Deref;
|
|||
use std::ptr::{self, NonNull};
|
||||
use std::slice;
|
||||
|
||||
use serde::de::{Deserializer, Visitor};
|
||||
use serde::Deserialize;
|
||||
use serde::de::{Deserializer, Visitor};
|
||||
|
||||
mod context;
|
||||
|
||||
|
|
@ -75,12 +75,14 @@ impl NixStringInner {
|
|||
/// 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
|
||||
unsafe fn layout_of(this: NonNull<c_void>) -> (Layout, usize, usize) {
|
||||
let layout = Layout::new::<Option<Box<NixContext>>>();
|
||||
let (_, len_offset) = layout.extend(Layout::new::<usize>()).unwrap();
|
||||
// SAFETY: Layouts are linear, so even though we haven't involved data at all yet, we know
|
||||
// the len_offset is a valid offset into the second field of the allocation
|
||||
let len = *(this.as_ptr().add(len_offset) as *const usize);
|
||||
Self::layout(len)
|
||||
unsafe {
|
||||
let layout = Layout::new::<Option<Box<NixContext>>>();
|
||||
let (_, len_offset) = layout.extend(Layout::new::<usize>()).unwrap();
|
||||
// SAFETY: Layouts are linear, so even though we haven't involved data at all yet, we know
|
||||
// the len_offset is a valid offset into the second field of the allocation
|
||||
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
|
||||
|
|
@ -121,9 +123,11 @@ impl NixStringInner {
|
|||
/// This function must only be called with a pointer that has been properly initialized with
|
||||
/// [`Self::alloc`]
|
||||
unsafe fn dealloc(this: NonNull<c_void>) {
|
||||
let (layout, _, _) = Self::layout_of(this);
|
||||
// SAFETY: okay because of the safety guarantees of this method
|
||||
dealloc(this.as_ptr() as *mut u8, layout)
|
||||
unsafe {
|
||||
let (layout, _, _) = Self::layout_of(this);
|
||||
// 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
|
||||
|
|
@ -133,11 +137,13 @@ impl NixStringInner {
|
|||
/// This function must only be called with a pointer that has been properly initialized with
|
||||
/// [`Self::alloc`]
|
||||
unsafe fn len(this: NonNull<c_void>) -> usize {
|
||||
let (_, len_offset, _) = Self::layout_of(this);
|
||||
// SAFETY: As long as the safety guarantees of this method are upheld, we've allocated with
|
||||
// a layout that causes the len_offset to be in-bounds and writeable, and if the allocation
|
||||
// succeeded it won't wrap
|
||||
*(this.as_ptr().add(len_offset) as *const usize)
|
||||
unsafe {
|
||||
let (_, len_offset, _) = Self::layout_of(this);
|
||||
// SAFETY: As long as the safety guarantees of this method are upheld, we've allocated with
|
||||
// a layout that causes the len_offset to be in-bounds and writeable, and if the allocation
|
||||
// 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
|
||||
|
|
@ -162,7 +168,7 @@ impl NixStringInner {
|
|||
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
|
||||
/// [`NonNull::as_ref`] for more.
|
||||
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
|
||||
|
|
@ -176,7 +182,7 @@ impl NixStringInner {
|
|||
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
|
||||
/// [`NonNull::as_mut`] for more.
|
||||
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
|
||||
|
|
@ -186,9 +192,11 @@ impl NixStringInner {
|
|||
/// This function must only be called with a pointer that has been properly initialized with
|
||||
/// [`Self::alloc`]
|
||||
unsafe fn data_ptr(this: NonNull<c_void>) -> *mut u8 {
|
||||
let (_, _, data_offset) = Self::layout_of(this);
|
||||
// SAFETY: data is the third field in the layout of the allocation
|
||||
this.as_ptr().add(data_offset) as *mut u8
|
||||
unsafe {
|
||||
let (_, _, data_offset) = Self::layout_of(this);
|
||||
// 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
|
||||
|
|
@ -202,9 +210,11 @@ impl NixStringInner {
|
|||
/// Also, all the normal Rust rules about pointer-to-reference conversion apply. See
|
||||
/// [`slice::from_raw_parts`] for more.
|
||||
unsafe fn data_slice<'a>(this: NonNull<c_void>) -> &'a [u8] {
|
||||
let len = Self::len(this);
|
||||
let data = Self::data_ptr(this);
|
||||
slice::from_raw_parts(data, len)
|
||||
unsafe {
|
||||
let len = Self::len(this);
|
||||
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
|
||||
|
|
@ -219,9 +229,11 @@ impl NixStringInner {
|
|||
/// [`slice::from_raw_parts_mut`] for more.
|
||||
#[allow(dead_code)]
|
||||
unsafe fn data_slice_mut<'a>(this: NonNull<c_void>) -> &'a mut [u8] {
|
||||
let len = Self::len(this);
|
||||
let data = Self::data_ptr(this);
|
||||
slice::from_raw_parts_mut(data, len)
|
||||
unsafe {
|
||||
let len = Self::len(this);
|
||||
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
|
||||
|
|
@ -234,14 +246,16 @@ impl NixStringInner {
|
|||
/// pointer returned from [`Self::context_ptr`]), and the data array has been properly
|
||||
/// initialized (by writing to the pointer returned from [`Self::data_ptr`]).
|
||||
unsafe fn clone(this: NonNull<c_void>) -> NonNull<c_void> {
|
||||
let (layout, _, _) = Self::layout_of(this);
|
||||
let ptr = alloc(layout);
|
||||
if let Some(new) = NonNull::new(ptr as *mut _) {
|
||||
ptr::copy_nonoverlapping(this.as_ptr(), new.as_ptr(), layout.size());
|
||||
Self::context_ptr(new).write(Self::context_ref(this).clone());
|
||||
new
|
||||
} else {
|
||||
handle_alloc_error(layout);
|
||||
unsafe {
|
||||
let (layout, _, _) = Self::layout_of(this);
|
||||
let ptr = alloc(layout);
|
||||
if let Some(new) = NonNull::new(ptr as *mut _) {
|
||||
ptr::copy_nonoverlapping(this.as_ptr(), new.as_ptr(), layout.size());
|
||||
Self::context_ptr(new).write(Self::context_ref(this).clone());
|
||||
new
|
||||
} else {
|
||||
handle_alloc_error(layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -543,7 +557,7 @@ impl Deref for NixString {
|
|||
#[cfg(feature = "arbitrary")]
|
||||
mod arbitrary {
|
||||
use super::*;
|
||||
use proptest::prelude::{any_with, Arbitrary};
|
||||
use proptest::prelude::{Arbitrary, any_with};
|
||||
use proptest::strategy::{BoxedStrategy, Strategy};
|
||||
|
||||
impl Arbitrary for NixString {
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ use std::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
Value,
|
||||
errors::ErrorKind,
|
||||
opcode::Op,
|
||||
upvalues::Upvalues,
|
||||
value::Closure,
|
||||
vm::generators::{self, GenCo},
|
||||
Value,
|
||||
};
|
||||
|
||||
use super::{Lambda, TotalDisplay};
|
||||
|
|
@ -240,7 +240,7 @@ impl Thunk {
|
|||
first_force: forced_at,
|
||||
suspended_at,
|
||||
content_span,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// If there is a native function stored in the thunk, evaluate it
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ use std::ffi::OsString;
|
|||
use std::fmt::Display;
|
||||
use std::future::Future;
|
||||
|
||||
use crate::value::PointerEquality;
|
||||
use crate::warnings::{EvalWarning, WarningKind};
|
||||
use crate::FileType;
|
||||
use crate::NixString;
|
||||
use crate::value::PointerEquality;
|
||||
use crate::warnings::{EvalWarning, WarningKind};
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
@ -254,7 +254,7 @@ where
|
|||
}
|
||||
|
||||
/// 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
|
||||
F: Future<Output = Result<Value, ErrorKind>> + 'static,
|
||||
G: FnOnce(GenCo) -> F,
|
||||
|
|
@ -263,7 +263,7 @@ where
|
|||
name,
|
||||
span,
|
||||
state: GeneratorState::Running,
|
||||
generator: Gen::new(|co| pin_generator(gen(co))),
|
||||
generator: Gen::new(|co| pin_generator(r#gen(co))),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use serde_json::json;
|
|||
use std::{cmp::Ordering, ops::DerefMut, path::PathBuf, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
arithmetic_op,
|
||||
NixString, SourceCode, arithmetic_op,
|
||||
chunk::Chunk,
|
||||
cmp_op,
|
||||
compiler::GlobalsMap,
|
||||
|
|
@ -36,10 +36,9 @@ use crate::{
|
|||
},
|
||||
vm::generators::GenCo,
|
||||
warnings::{EvalWarning, WarningKind},
|
||||
NixString, SourceCode,
|
||||
};
|
||||
|
||||
use generators::{call_functor, Generator, GeneratorState};
|
||||
use generators::{Generator, GeneratorState, call_functor};
|
||||
|
||||
use self::generators::{VMRequest, VMResponse};
|
||||
|
||||
|
|
@ -641,8 +640,11 @@ where
|
|||
if !finalise {
|
||||
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()
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue