diff --git a/crates/nu-engine/src/compile/operator.rs b/crates/nu-engine/src/compile/operator.rs index 6e127c8d5b..2a913f8836 100644 --- a/crates/nu-engine/src/compile/operator.rs +++ b/crates/nu-engine/src/compile/operator.rs @@ -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( diff --git a/tests/shell/pipeline/commands/external.rs b/tests/shell/pipeline/commands/external.rs index e5c6915565..c0cf8e1adb 100644 --- a/tests/shell/pipeline/commands/external.rs +++ b/tests/shell/pipeline/commands/external.rs @@ -717,3 +717,11 @@ fn external_error_with_backtrace() { assert_eq!(chained_error_cnt.len(), 0); }); } + +#[test] +fn sub_external_expression_with_and_op_should_raise_proper_error() { + let actual = nu!("(nu --testbin cococo false) and true"); + assert!(actual + .err + .contains("The 'and' operator does not work on values of type 'string'")) +}