diff --git a/src/recipe_resolver.rs b/src/recipe_resolver.rs index c56afeaf3d..936b76edd3 100644 --- a/src/recipe_resolver.rs +++ b/src/recipe_resolver.rs @@ -23,10 +23,10 @@ impl<'src: 'run, 'run> RecipeResolver<'src, 'run> { } for recipe in resolver.resolved_recipes.values() { - for parameter in &recipe.parameters { + for (i, parameter) in recipe.parameters.iter().enumerate() { if let Some(expression) = ¶meter.default { for variable in expression.variables() { - resolver.resolve_variable(&variable, &[])?; + resolver.resolve_variable(&variable, &recipe.parameters[..i])?; } } } @@ -63,11 +63,12 @@ impl<'src: 'run, 'run> RecipeResolver<'src, 'run> { parameters: &[Parameter], ) -> CompileResult<'src> { let name = variable.lexeme(); - let undefined = !self.assignments.contains_key(name) - && !parameters.iter().any(|p| p.name.lexeme() == name) - && !constants().contains_key(name); - if undefined { + let defined = self.assignments.contains_key(name) + || parameters.iter().any(|p| p.name.lexeme() == name) + || constants().contains_key(name); + + if !defined { return Err(variable.error(UndefinedVariable { variable: name })); } diff --git a/tests/lib.rs b/tests/lib.rs index 73f68fb949..681207f3c5 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -82,6 +82,7 @@ mod no_cd; mod no_dependencies; mod no_exit_message; mod os_attributes; +mod parameters; mod parser; mod positional_arguments; mod private; diff --git a/tests/misc.rs b/tests/misc.rs index b4c256370c..590c13cd35 100644 --- a/tests/misc.rs +++ b/tests/misc.rs @@ -1941,26 +1941,6 @@ test! { shell: false, } -test! { - name: parameter_cross_reference_error, - justfile: " - foo: - - bar a b=a: - ", - args: (), - stdout: "", - stderr: " - error: Variable `a` not defined - ——▶ justfile:3:9 - │ - 3 │ bar a b=a: - │ ^ - ", - status: EXIT_FAILURE, - shell: false, -} - #[cfg(windows)] test! { name: pwsh_invocation_directory, diff --git a/tests/parameters.rs b/tests/parameters.rs new file mode 100644 index 0000000000..8cf93ba13d --- /dev/null +++ b/tests/parameters.rs @@ -0,0 +1,38 @@ +use super::*; + +#[test] +fn parameter_default_values_may_use_earlier_parameters() { + Test::new() + .justfile( + " + @foo a b=a: + echo {{ b }} + ", + ) + .args(["foo", "bar"]) + .stdout("bar\n") + .run(); +} + +#[test] +fn parameter_default_values_may_not_use_later_parameters() { + Test::new() + .justfile( + " + @foo a b=c c='': + echo {{ b }} + ", + ) + .args(["foo", "bar"]) + .stderr( + " + error: Variable `c` not defined + ——▶ justfile:1:10 + │ + 1 │ @foo a b=c c='': + │ ^ + ", + ) + .status(EXIT_FAILURE) + .run(); +}