prevent parser from parsing variables as units (#12378)

# Description

Resolves #11274.

```
~/CodingProjects/nushell> let day = 2; echo 0..<$day
╭───┬───╮
│ 0 │ 0 │
│ 1 │ 1 │
╰───┴───╯
~/CodingProjects/nushell> let kb = "jan"; echo 0..$kb 
Error: nu:🐚:type_mismatch

  × Type mismatch during operation.
   ╭─[entry #1:1:22]
 1 │ let kb = "jan"; echo 0..$kb
   ·                      ┬─┬─┬─
   ·                      │ │ ╰── string
   ·                      │ ╰── type mismatch for operator
   ·                      ╰── int
   ╰────
```


# Tests + Formatting

Relevant test added 🆙 

---------

Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
pwygab 2024-04-04 15:55:14 +08:00 committed by GitHub
parent cd00a489af
commit f0a073b397
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 15 additions and 0 deletions

View File

@ -2323,6 +2323,11 @@ pub fn parse_unit_value<'res>(
let lhs = strip_underscores(value[..lhs_len].as_bytes()); let lhs = strip_underscores(value[..lhs_len].as_bytes());
let lhs_span = Span::new(span.start, span.start + lhs_len); let lhs_span = Span::new(span.start, span.start + lhs_len);
let unit_span = Span::new(span.start + lhs_len, span.end); let unit_span = Span::new(span.start + lhs_len, span.end);
if lhs.ends_with('$') {
// If `parse_unit_value` has higher precedence over `parse_range`,
// a variable with the name of a unit could otherwise not be used as the end of a range.
return None;
}
let (decimal_part, number_part) = modf(match lhs.parse::<f64>() { let (decimal_part, number_part) = modf(match lhs.parse::<f64>() {
Ok(it) => it, Ok(it) => it,

View File

@ -1191,6 +1191,16 @@ mod range {
assert!(!working_set.parse_errors.is_empty()); assert!(!working_set.parse_errors.is_empty());
} }
#[test]
fn vars_not_read_as_units() {
let engine_state = EngineState::new();
let mut working_set = StateWorkingSet::new(&engine_state);
let _ = parse(&mut working_set, None, b"0..<$day", true);
assert!(working_set.parse_errors.is_empty());
}
} }
#[cfg(test)] #[cfg(test)]