diff options
author | Vincent Ambo <mail@tazj.in> | 2022-08-24T17·01+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-02T14·13+0000 |
commit | 2023b8e33f0e1700ecbaebf4c6fc37a479e73329 (patch) | |
tree | 3c22ab333c8671d228b47b13a690af8d7c69362c /tvix/eval/src/compiler.rs | |
parent | c3b13416b02d8e0e68330408b107d3aad29e3a3f (diff) |
fix(tvix/eval): consider `let ... inherit ...` in dynamic scopes r/4598
In conditions where no dynamic identifiers exist in a scope, inheriting is usually a no-op - *unless* the identifier is not statically known and the scope has a non-empty `with`-stack. Change-Id: Iff4138d9cd4c56e844bc574203708dacc11c3f73 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6264 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/compiler.rs')
-rw-r--r-- | tvix/eval/src/compiler.rs | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/tvix/eval/src/compiler.rs b/tvix/eval/src/compiler.rs index a2ab6273c102..6eca088ec254 100644 --- a/tvix/eval/src/compiler.rs +++ b/tvix/eval/src/compiler.rs @@ -667,13 +667,34 @@ impl Compiler { for inherit in node.inherits() { match inherit.from() { // Within a `let` binding, inheriting from the outer - // scope is practically a no-op. - None => { + // scope is a no-op *if* the identifier can be + // statically resolved. + None if self.scope().with_stack.is_empty() => { self.emit_warning(inherit.syntax().clone(), WarningKind::UselessInherit); - continue; } + None => { + for ident in inherit.idents() { + // If the identifier resolves statically, it + // has precedence over dynamic bindings, and + // the inherit is useless. + if self + .resolve_local(ident.ident_token().unwrap().text()) + .is_some() + { + self.emit_warning(ident.syntax().clone(), WarningKind::UselessInherit); + continue; + } + + self.compile_ident(ident.clone()); + self.declare_local( + ident.syntax().clone(), + ident.ident_token().unwrap().text(), + ); + } + } + Some(from) => { for ident in inherit.idents() { self.compile(from.expr().unwrap()); |