From 03db05bf7345363b5edb0deff3028594d13b0b93 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Mon, 6 Jul 2026 01:01:14 -0700 Subject: [PATCH] Fix variable shadowing --- src/evaluator.rs | 6 +++--- tests/assignment.rs | 52 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/evaluator.rs b/src/evaluator.rs index 343c641687..8e4c3affbb 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -606,15 +606,15 @@ impl<'src, 'run> Evaluator<'src, 'run> { Expression::StringLiteral { string_literal } => Ok(string_literal.cooked.deref().into()), Expression::Variable { name, .. } => { let variable = name.lexeme(); - if let Some(value) = self.scope.value(variable) { - Ok(value.clone()) - } else if self.non_const_assignments.contains_key(name.lexeme()) { + if self.non_const_assignments.contains_key(name.lexeme()) { Err(ConstError::Variable(*name).into()) } else if let Some(assignment) = self .assignments .and_then(|assignments| assignments.get(variable)) { Ok(self.evaluate_assignment(assignment)?.clone()) + } else if let Some(value) = self.scope.value(variable) { + Ok(value.clone()) } else { Err(Error::internal(format!( "attempted to evaluate undefined variable `{variable}`" diff --git a/tests/assignment.rs b/tests/assignment.rs index f1aac188ff..b1db316e78 100644 --- a/tests/assignment.rs +++ b/tests/assignment.rs @@ -61,3 +61,55 @@ fn invalid_attributes_are_an_error() { ) .failure(); } + +#[test] +fn local_variables_can_shadow_constants() { + Test::new() + .justfile( + " + a := HEX + + HEX := 'foo' + ", + ) + .args(["--evaluate", "a"]) + .stdout("foo") + .success(); +} + +#[test] +fn non_const_variables_shadowing_constants_are_an_error_in_const_contexts() { + Test::new() + .justfile( + " + HEX := `echo foo` + + set tempdir := HEX + ", + ) + .stderr( + " + error: cannot access non-const variable `HEX` in const context + ——▶ justfile:3:16 + │ + 3 │ set tempdir := HEX + │ ^^^ + ", + ) + .failure(); +} + +#[test] +fn variables_shadowing_constants_can_be_overridden() { + Test::new() + .justfile( + " + a := HEX + + HEX := 'foo' + ", + ) + .args(["--set", "HEX", "bar", "--evaluate", "a"]) + .stdout("bar") + .success(); +}