diff --git a/crates/nu-command/tests/commands/let_.rs b/crates/nu-command/tests/commands/let_.rs new file mode 100644 index 000000000..4ee0614ad --- /dev/null +++ b/crates/nu-command/tests/commands/let_.rs @@ -0,0 +1,15 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn let_parse_error() { + let actual = nu!( + cwd: ".", pipeline( + r#" + let in = 3 + "# + )); + + assert!(actual + .err + .contains("'in' is the name of a builtin Nushell variable")); +} diff --git a/crates/nu-command/tests/commands/mod.rs b/crates/nu-command/tests/commands/mod.rs index c534b87ba..e03fc0a64 100644 --- a/crates/nu-command/tests/commands/mod.rs +++ b/crates/nu-command/tests/commands/mod.rs @@ -30,6 +30,7 @@ mod into_filesize; mod into_int; mod last; mod length; +mod let_; mod lines; mod ls; mod math; diff --git a/crates/nu-parser/src/errors.rs b/crates/nu-parser/src/errors.rs index 1ac505945..221fccc7e 100644 --- a/crates/nu-parser/src/errors.rs +++ b/crates/nu-parser/src/errors.rs @@ -88,6 +88,14 @@ pub enum ParseError { )] LetInPipeline(String, String, #[label("let in pipeline")] Span), + #[error("Let used with builtin variable name.")] + #[diagnostic( + code(nu::parser::let_builtin_var), + url(docsrs), + help("'{0}' is the name of a builtin Nushell variable. `let` cannot assign to it.") + )] + LetBuiltinVar(String, #[label("already a builtin variable")] Span), + #[error("Incorrect value")] #[diagnostic(code(nu::parser::incorrect_value), url(docsrs), help("{2}"))] IncorrectValue(String, #[label("unexpected {0}")] Span, String), @@ -311,6 +319,7 @@ impl ParseError { ParseError::UnexpectedKeyword(_, s) => *s, ParseError::BuiltinCommandInPipeline(_, s) => *s, ParseError::LetInPipeline(_, _, s) => *s, + ParseError::LetBuiltinVar(_, s) => *s, ParseError::IncorrectValue(_, s, _) => *s, ParseError::MultipleRestParams(s) => *s, ParseError::VariableNotFound(s) => *s, diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index 59da17c26..802b61979 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -2286,6 +2286,15 @@ pub fn parse_let( parse_var_with_opt_type(working_set, &spans[1..(span.0)], &mut idx); error = error.or(err); + let var_name = + String::from_utf8_lossy(working_set.get_span_contents(lvalue.span)) + .to_string(); + + if ["in", "nu", "env", "nothing"].contains(&var_name.as_str()) { + error = + error.or(Some(ParseError::LetBuiltinVar(var_name, lvalue.span))); + } + let var_id = lvalue.as_var(); let rhs_type = rvalue.ty.clone();