From fc813af4c889ebe3657d5b95ef37742a07ec8cbc Mon Sep 17 00:00:00 2001 From: Kumar Ujjawal Date: Wed, 4 Jun 2025 13:36:41 +0530 Subject: [PATCH] Better error handling for negative integer exponents in ** operator (#15882) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Title**: Better error handling for negative integer exponents in `**` operator --- ### Bug Fix This PR addresses an issue where attempting to raise an integer to a negative power (e.g. `10 ** -1`) incorrectly triggered an `OperatorOverflow` error. This behavior was misleading since the overflow isn't actually the root problem — it's the unsupported operation of raising integers to negative powers. --- ### Fix Summary * Updated `Value::pow` to: * Check for negative exponents when both operands are integers. * Return a `ShellError::IncorrectValue` with a helpful message guiding users to use floating point values instead. #### Example: ```bash > 10 ** -1 Error: nu::shell::incorrect_value × Incorrect value. ╝─[entry #2:1:4] 1 │ 10 ** -1 · ─┬┬ · │╰── encountered here · ╰── Negative exponent for integer power is unsupported; use floats instead. ``` --- ### Testing Manual testing: * `10 ** -1` → now returns a clear and appropriate `IncorrectValue` error. * `10.0 ** -1`, `10 ** -1.0`, etc. continue to work as expected. --- ### Related Fixes #15860 --------- Co-authored-by: Kumar Ujjawal --- crates/nu-protocol/src/value/mod.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index cfd5adf72f..85b54d9e20 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -3293,8 +3293,16 @@ impl Value { pub fn pow(&self, op: Span, rhs: &Value, span: Span) -> Result { match (self, rhs) { - (Value::Int { val: lhs, .. }, Value::Int { val: rhs, .. }) => { - if let Some(val) = lhs.checked_pow(*rhs as u32) { + (Value::Int { val: lhs, .. }, Value::Int { val: rhsv, .. }) => { + if *rhsv < 0 { + return Err(ShellError::IncorrectValue { + msg: "Negative exponent for integer power is unsupported; use floats instead.".into(), + val_span: rhs.span(), + call_span: op, + }); + } + + if let Some(val) = lhs.checked_pow(*rhsv as u32) { Ok(Value::int(val, span)) } else { Err(ShellError::OperatorOverflow {