feat: debug thunk location
This commit is contained in:
@@ -40,6 +40,7 @@ pub(crate) trait CodegenContext {
|
|||||||
fn get_current_dir(&self) -> &Path;
|
fn get_current_dir(&self) -> &Path;
|
||||||
fn get_store_dir(&self) -> &str;
|
fn get_store_dir(&self) -> &str;
|
||||||
fn get_current_source_id(&self) -> usize;
|
fn get_current_source_id(&self) -> usize;
|
||||||
|
fn get_current_source(&self) -> crate::error::Source;
|
||||||
}
|
}
|
||||||
|
|
||||||
trait EscapeQuote {
|
trait EscapeQuote {
|
||||||
@@ -117,9 +118,19 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
|
|||||||
Ir::Arg(x) => format!("arg{}", x.inner.0),
|
Ir::Arg(x) => format!("arg{}", x.inner.0),
|
||||||
Ir::Let(x) => x.compile(ctx),
|
Ir::Let(x) => x.compile(ctx),
|
||||||
Ir::Select(x) => x.compile(ctx),
|
Ir::Select(x) => x.compile(ctx),
|
||||||
&Ir::Thunk(Thunk { inner: expr_id, .. }) => {
|
&Ir::Thunk(Thunk {
|
||||||
|
inner: expr_id,
|
||||||
|
span,
|
||||||
|
}) => {
|
||||||
let inner = ctx.get_ir(expr_id).compile(ctx);
|
let inner = ctx.get_ir(expr_id).compile(ctx);
|
||||||
format!("Nix.createThunk(()=>({}),\"expr{}\")", inner, expr_id.0)
|
format!(
|
||||||
|
"Nix.createThunk(()=>({}),\"expr{} {}:{}:{}\")",
|
||||||
|
inner,
|
||||||
|
expr_id.0,
|
||||||
|
ctx.get_current_source().get_name(),
|
||||||
|
usize::from(span.start()),
|
||||||
|
usize::from(span.end())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
&Ir::ExprRef(ExprRef { inner: expr_id, .. }) => {
|
&Ir::ExprRef(ExprRef { inner: expr_id, .. }) => {
|
||||||
format!("expr{}", expr_id.0)
|
format!("expr{}", expr_id.0)
|
||||||
|
|||||||
@@ -230,6 +230,9 @@ impl CodegenContext for Ctx {
|
|||||||
.checked_sub(1)
|
.checked_sub(1)
|
||||||
.expect("current_source not set")
|
.expect("current_source not set")
|
||||||
}
|
}
|
||||||
|
fn get_current_source(&self) -> crate::error::Source {
|
||||||
|
self.sources.last().expect("current_source not set").clone()
|
||||||
|
}
|
||||||
fn get_store_dir(&self) -> &str {
|
fn get_store_dir(&self) -> &str {
|
||||||
self.store.as_store().get_store_dir()
|
self.store.as_store().get_store_dir()
|
||||||
}
|
}
|
||||||
@@ -322,8 +325,8 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
|||||||
ExprId(self.ctx.irs.len() + self.irs.len() - 1)
|
ExprId(self.ctx.irs.len() + self.irs.len() - 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_thunk(&mut self, id: ExprId) -> ExprId {
|
fn get_ir(&self, id: ExprId) -> &Ir {
|
||||||
let ir = if id.0 < self.ctx.irs.len() {
|
if id.0 < self.ctx.irs.len() {
|
||||||
self.ctx.irs.get(id.0).expect("unreachable")
|
self.ctx.irs.get(id.0).expect("unreachable")
|
||||||
} else {
|
} else {
|
||||||
self.irs
|
self.irs
|
||||||
@@ -331,7 +334,11 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
|||||||
.expect("ExprId out of bounds")
|
.expect("ExprId out of bounds")
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("maybe_thunk called on an extracted expr")
|
.expect("maybe_thunk called on an extracted expr")
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn maybe_thunk(&mut self, id: ExprId) -> ExprId {
|
||||||
|
let ir = self.get_ir(id);
|
||||||
match ir {
|
match ir {
|
||||||
Ir::Builtin(_)
|
Ir::Builtin(_)
|
||||||
| Ir::Builtins(_)
|
| Ir::Builtins(_)
|
||||||
@@ -449,7 +456,7 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_expr(&mut self, id: ExprId) -> Ir {
|
fn extract_ir(&mut self, id: ExprId) -> Ir {
|
||||||
let local_id = id.0 - self.ctx.irs.len();
|
let local_id = id.0 - self.ctx.irs.len();
|
||||||
self.irs
|
self.irs
|
||||||
.get_mut(local_id)
|
.get_mut(local_id)
|
||||||
@@ -458,7 +465,7 @@ impl DowngradeContext for DowngradeCtx<'_> {
|
|||||||
.expect("extract_expr called on an already extracted expr")
|
.expect("extract_expr called on an already extracted expr")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_expr(&mut self, id: ExprId, expr: Ir) {
|
fn replace_ir(&mut self, id: ExprId, expr: Ir) {
|
||||||
let local_id = id.0 - self.ctx.irs.len();
|
let local_id = id.0 - self.ctx.irs.len();
|
||||||
let _ = self
|
let _ = self
|
||||||
.irs
|
.irs
|
||||||
|
|||||||
@@ -35,11 +35,7 @@ impl TryFrom<&str> for Source {
|
|||||||
|
|
||||||
impl From<Source> for NamedSource<Arc<str>> {
|
impl From<Source> for NamedSource<Arc<str>> {
|
||||||
fn from(value: Source) -> Self {
|
fn from(value: Source) -> Self {
|
||||||
let name = match value.ty {
|
let name = value.get_name();
|
||||||
SourceType::Eval(_) => "«eval»".into(),
|
|
||||||
SourceType::Repl(_) => "«repl»".into(),
|
|
||||||
SourceType::File(path) => path.as_os_str().to_string_lossy().to_string(),
|
|
||||||
};
|
|
||||||
NamedSource::new(name, value.src.clone())
|
NamedSource::new(name, value.src.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -75,6 +71,14 @@ impl Source {
|
|||||||
.expect("source file must have a parent dir"),
|
.expect("source file must have a parent dir"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_name(&self) -> String {
|
||||||
|
match &self.ty {
|
||||||
|
SourceType::Eval(_) => "«eval»".into(),
|
||||||
|
SourceType::Repl(_) => "«repl»".into(),
|
||||||
|
SourceType::File(path) => path.as_os_str().to_string_lossy().to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug, Diagnostic)]
|
#[derive(Error, Debug, Diagnostic)]
|
||||||
|
|||||||
@@ -28,8 +28,9 @@ pub trait DowngradeContext {
|
|||||||
fn get_sym(&self, id: SymId) -> &str;
|
fn get_sym(&self, id: SymId) -> &str;
|
||||||
fn lookup(&mut self, sym: SymId, span: TextRange) -> Result<ExprId>;
|
fn lookup(&mut self, sym: SymId, span: TextRange) -> Result<ExprId>;
|
||||||
|
|
||||||
fn extract_expr(&mut self, id: ExprId) -> Ir;
|
fn get_ir(&self, id: ExprId) -> &Ir;
|
||||||
fn replace_expr(&mut self, id: ExprId, expr: Ir);
|
fn extract_ir(&mut self, id: ExprId) -> Ir;
|
||||||
|
fn replace_ir(&mut self, id: ExprId, expr: Ir);
|
||||||
fn reserve_slots(&mut self, slots: usize) -> impl Iterator<Item = ExprId> + Clone + use<Self>;
|
fn reserve_slots(&mut self, slots: usize) -> impl Iterator<Item = ExprId> + Clone + use<Self>;
|
||||||
fn get_current_source(&self) -> Source;
|
fn get_current_source(&self) -> Source;
|
||||||
|
|
||||||
@@ -124,7 +125,7 @@ impl AttrSet {
|
|||||||
// If the next attribute is a static string.
|
// 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.
|
// If a sub-attrset already exists, recurse into it.
|
||||||
let mut ir = ctx.extract_expr(id);
|
let mut ir = ctx.extract_ir(id);
|
||||||
let result = ir
|
let result = ir
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.try_unwrap_attr_set()
|
.try_unwrap_attr_set()
|
||||||
@@ -139,7 +140,7 @@ impl AttrSet {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|attrs| attrs._insert(path, name, value, ctx));
|
.and_then(|attrs| attrs._insert(path, name, value, ctx));
|
||||||
ctx.replace_expr(id, ir);
|
ctx.replace_ir(id, ir);
|
||||||
result?;
|
result?;
|
||||||
} else {
|
} else {
|
||||||
// Create a new sub-attrset because this path doesn't exist yet.
|
// Create a new sub-attrset because this path doesn't exist yet.
|
||||||
|
|||||||
@@ -405,21 +405,17 @@ where
|
|||||||
|
|
||||||
for (sym, slot) in binding_keys.iter().copied().zip(slots.iter()) {
|
for (sym, slot) in binding_keys.iter().copied().zip(slots.iter()) {
|
||||||
if let Some(&expr) = bindings.get(&sym) {
|
if let Some(&expr) = bindings.get(&sym) {
|
||||||
ctx.replace_expr(
|
ctx.replace_ir(
|
||||||
*slot,
|
*slot,
|
||||||
Thunk {
|
Thunk {
|
||||||
inner: expr,
|
inner: expr,
|
||||||
// span: ctx.get_span(expr),
|
span: ctx.get_ir(expr).span(),
|
||||||
// FIXME: span
|
|
||||||
span: synthetic_span(),
|
|
||||||
}
|
}
|
||||||
.to_ir(),
|
.to_ir(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Err(Error::downgrade_error(
|
return Err(Error::internal(
|
||||||
format!("binding '{}' not found", format_symbol(ctx.get_sym(sym))),
|
format!("binding '{}' not found", format_symbol(ctx.get_sym(sym))),
|
||||||
ctx.get_current_source(),
|
|
||||||
synthetic_span(),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user