feat: rec attrset
This commit is contained in:
@@ -41,7 +41,7 @@ pub trait DowngradeContext {
|
||||
fn with_expr<T>(&self, id: ExprId, f: impl FnOnce(&Hir, &Self) -> T) -> T;
|
||||
|
||||
/// Provides temporary mutable access to an expression.
|
||||
fn with_expr_mut<T>(&mut self, id: &ExprId, f: impl FnOnce(&mut Hir, &mut Self) -> T) -> T;
|
||||
fn with_expr_mut<T>(&mut self, id: ExprId, f: impl FnOnce(&mut Hir, &mut Self) -> T) -> T;
|
||||
}
|
||||
|
||||
// The `ir!` macro generates the `Hir` enum and related structs and traits.
|
||||
@@ -128,7 +128,7 @@ impl Attrs for AttrSet {
|
||||
match attr {
|
||||
Attr::Str(ident) => {
|
||||
// If the next attribute is a static string.
|
||||
if let Some(id) = self.stcs.get(&ident) {
|
||||
if let Some(&id) = self.stcs.get(&ident) {
|
||||
// If a sub-attrset already exists, recurse into it.
|
||||
ctx.with_expr_mut(id, |expr, ctx| {
|
||||
expr.as_mut()
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
//! They are helpers to the main `Downgrade` trait implementations.
|
||||
|
||||
use hashbrown::HashMap;
|
||||
use hashbrown::hash_map::Entry;
|
||||
|
||||
use nixjit_value::format_symbol;
|
||||
use rnix::ast;
|
||||
|
||||
use nixjit_error::{Error, Result};
|
||||
@@ -128,19 +130,22 @@ pub fn downgrade_inherit(
|
||||
// If `from` is None, `inherit foo;` becomes `foo = foo;`.
|
||||
|| Var { sym: ident.clone() }.to_hir(),
|
||||
// If `from` is Some, `inherit (from) foo;` becomes `foo = from.foo;`.
|
||||
|expr| {
|
||||
|&expr| {
|
||||
Select {
|
||||
expr: unsafe { expr.clone() },
|
||||
expr,
|
||||
attrpath: vec![Attr::Str(ident.clone())],
|
||||
default: None,
|
||||
}
|
||||
.to_hir()
|
||||
},
|
||||
);
|
||||
if stcs.insert(ident, ctx.new_expr(expr)).is_some() {
|
||||
// TODO: Handle or error on duplicate attribute definitions.
|
||||
todo!()
|
||||
}
|
||||
match stcs.entry(ident) {
|
||||
Entry::Occupied(occupied) => return Err(Error::EvalError(format!(
|
||||
"attribute '{}' already defined",
|
||||
format_symbol(occupied.key())
|
||||
))),
|
||||
Entry::Vacant(vacant) => vacant.insert(ctx.new_expr(expr))
|
||||
};
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user