IR: rasing reasonable error when using subexpression with and operator (#15623)

# Description
Fixes: #15510
I think it's introduced by #14653, which changes `and/or` to `match`
expression.

After looking into `compile_match`, it's important to collect the value
before matching this.
```rust
    // Important to collect it first
    builder.push(Instruction::Collect { src_dst: match_reg }.into_spanned(match_expr.span))?;
```
This pr is going to apply the logic while compiling `and/or` operation.

# User-Facing Changes
The following will raise a reasonable error:
```nushell
> (nu --testbin cococo false) and true
Error: nu:🐚:operator_unsupported_type

  × The 'and' operator does not work on values of type 'string'.
   ╭─[entry #7:1:2]
 1 │ (nu --testbin cococo false) and true
   ·  ─┬                         ─┬─
   ·   │                          ╰── does not support 'string'
   ·   ╰── string
   ╰────
```

# Tests + Formatting
Added 1 test.

# After Submitting
Maybe need to update doc
https://github.com/nushell/nushell.github.io/pull/1876

---------

Co-authored-by: Stefan Holderbach <sholderbach@users.noreply.github.com>
This commit is contained in:
Wind
2025-04-25 22:00:20 +08:00
committed by GitHub
parent 0ca5c2f135
commit 11cdb94699
2 changed files with 10 additions and 0 deletions

View File

@ -70,6 +70,8 @@ pub(crate) fn compile_binary_op(
Boolean::Xor => unreachable!(),
};
// Before match against lhs_reg, it's important to collect it first to get a concrete value if there is a subexpression.
builder.push(Instruction::Collect { src_dst: lhs_reg }.into_spanned(lhs.span))?;
// Short-circuit to return `lhs_reg`. `match` op does not consume `lhs_reg`.
let short_circuit_label = builder.label(None);
builder.r#match(