diff --git a/crates/nu-command/tests/commands/alias.rs b/crates/nu-command/tests/commands/alias.rs index 91fb26993..7d9817238 100644 --- a/crates/nu-command/tests/commands/alias.rs +++ b/crates/nu-command/tests/commands/alias.rs @@ -90,3 +90,23 @@ fn cant_alias_keyword() { )); assert!(actual.err.contains("cant_alias_keyword")); } + +#[test] +fn alias_wont_recurse() { + let actual = nu!( + cwd: ".", pipeline( + r#" + module myspamsymbol { + export def myfoosymbol [prefix: string, msg: string] { + $prefix + $msg + } + }; + use myspamsymbol myfoosymbol; + alias myfoosymbol = myfoosymbol 'hello'; + myfoosymbol ' world' + "# + )); + + assert_eq!(actual.out, "hello world"); + assert!(actual.err.is_empty()); +} diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index fd29da114..62b0e3d42 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -804,6 +804,13 @@ pub fn parse_alias( let replacement_spans = &spans[(split_id + 2)..]; + // Temporarily hide the alias itself to prevent recursion + let predecl_id = working_set + .delta + .last_scope_frame_mut() + .predecls + .remove(&alias_name); + let (expr, err) = parse_call( working_set, replacement_spans, @@ -812,6 +819,14 @@ pub fn parse_alias( false, // TODO: Should this be set properly??? ); + if let Some(id) = predecl_id { + working_set + .delta + .last_scope_frame_mut() + .predecls + .insert(alias_name.to_vec(), id); + } + if let Some(e) = err { if let ParseError::MissingPositional(..) = e { // ignore missing required positional