diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index cd02f28cf..b09a7169f 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -467,6 +467,12 @@ pub fn eval_expression( lhs.upsert_data_at_cell_path(&cell_path.tail, rhs)?; if is_env { + if cell_path.tail.is_empty() { + return Err(ShellError::CannotReplaceEnv( + cell_path.head.span, + )); + } + // The special $env treatment: for something like $env.config.history.max_size = 2000, // get $env.config (or whichever one it is) AFTER the above mutation, and set it // as the "config" environment variable. diff --git a/crates/nu-protocol/src/shell_error.rs b/crates/nu-protocol/src/shell_error.rs index dd88dd3de..65637b674 100644 --- a/crates/nu-protocol/src/shell_error.rs +++ b/crates/nu-protocol/src/shell_error.rs @@ -365,6 +365,20 @@ Either make sure {0} is a string, or add a 'to_string' entry for it in ENV_CONVE )] AutomaticEnvVarSetManually(String, #[label("cannot set '{0}' manually")] Span), + /// It is not possible to replace the entire environment at once + /// + /// ## Resolution + /// + /// Setting the entire environment is not allowed. Change environment variables individually + /// instead. + #[error("Cannot replace environment.")] + #[diagnostic( + code(nu::shell::cannot_replace_env), + url(docsrs), + help(r#"Assigning a value to $env is not allowed."#) + )] + CannotReplaceEnv(#[label("setting $env not allowed")] Span), + /// Division by zero is not a thing. /// /// ## Resolution diff --git a/src/tests/test_engine.rs b/src/tests/test_engine.rs index 8da2be1b2..a8f7da256 100644 --- a/src/tests/test_engine.rs +++ b/src/tests/test_engine.rs @@ -371,3 +371,8 @@ fn range_right_exclusive() -> TestResult { fn assignment_to_in_var_no_panic() -> TestResult { fail_test(r#"$in = 3"#, "needs to be a mutable variable") } + +#[test] +fn assignment_to_env_no_panic() -> TestResult { + fail_test(r#"$env = 3"#, "cannot_replace_env") +}