diff --git a/README.md b/README.md
index eabca00274..1299762c3b 100644
--- a/README.md
+++ b/README.md
@@ -271,6 +271,12 @@ most Windows users.)
just |
nix-env -iA nixpkgs.just |
+
+ Various |
+ PyPI |
+ rust-just |
+ pipx install rust-just |
+
Void Linux |
XBPS |
diff --git a/src/analyzer.rs b/src/analyzer.rs
index 8a6b8eed36..f4f950bb58 100644
--- a/src/analyzer.rs
+++ b/src/analyzer.rs
@@ -323,14 +323,6 @@ impl<'src> Analyzer<'src> {
recipes: &Table<'src, Rc>>,
alias: Alias<'src, Name<'src>>,
) -> CompileResult<'src, Alias<'src>> {
- // Make sure the alias doesn't conflict with any recipe
- if let Some(recipe) = recipes.get(alias.name.lexeme()) {
- return Err(alias.name.token.error(AliasShadowsRecipe {
- alias: alias.name.lexeme(),
- recipe_line: recipe.line_number(),
- }));
- }
-
// Make sure the target recipe exists
match recipes.get(alias.target.lexeme()) {
Some(target) => Ok(alias.resolve(Rc::clone(target))),
diff --git a/src/compile_error.rs b/src/compile_error.rs
index 94df9e24c9..8b4ec8ded6 100644
--- a/src/compile_error.rs
+++ b/src/compile_error.rs
@@ -32,12 +32,6 @@ impl Display for CompileError<'_> {
use CompileErrorKind::*;
match &*self.kind {
- AliasShadowsRecipe { alias, recipe_line } => write!(
- f,
- "Alias `{alias}` defined on line {} shadows recipe `{alias}` defined on line {}",
- self.token.line.ordinal(),
- recipe_line.ordinal(),
- ),
AttributeArgumentCountMismatch {
attribute,
found,
diff --git a/src/compile_error_kind.rs b/src/compile_error_kind.rs
index c99cabac1b..99943fc76b 100644
--- a/src/compile_error_kind.rs
+++ b/src/compile_error_kind.rs
@@ -2,10 +2,6 @@ use super::*;
#[derive(Debug, PartialEq)]
pub(crate) enum CompileErrorKind<'src> {
- AliasShadowsRecipe {
- alias: &'src str,
- recipe_line: usize,
- },
AttributeArgumentCountMismatch {
attribute: &'src str,
found: usize,
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();
+}