From 1345f972021324e63119cc22f77e34b0d88ff8a6 Mon Sep 17 00:00:00 2001 From: pwygab <88221256+merelymyself@users.noreply.github.com> Date: Sat, 25 Jun 2022 05:55:25 +0800 Subject: [PATCH] Errors when `let in`, `let env` and similar commands are passed. (#5866) * throw `let nu/env/nothing/in` error in parsing * add tests and fmt * fix clippy * suggestions * fmt * `lvalue.span` instead of `spans[1]` * clippy * fmt --- crates/nu-command/tests/commands/let_.rs | 15 +++++++++++++++ crates/nu-command/tests/commands/mod.rs | 1 + crates/nu-parser/src/errors.rs | 9 +++++++++ crates/nu-parser/src/parse_keywords.rs | 9 +++++++++ 4 files changed, 34 insertions(+) create mode 100644 crates/nu-command/tests/commands/let_.rs diff --git a/crates/nu-command/tests/commands/let_.rs b/crates/nu-command/tests/commands/let_.rs new file mode 100644 index 0000000000..4ee0614ad5 --- /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 c534b87ba5..e03fc0a64d 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 1ac505945c..221fccc7ee 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 59da17c26c..802b61979d 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();