fix let: glob cast from string

This commit is contained in:
Devyn Cairns 2024-07-08 19:54:40 -07:00
parent ea3849da17
commit 4878d7250f
3 changed files with 24 additions and 4 deletions

View File

@ -2,7 +2,7 @@ use nu_protocol::{
ast::{Block, Call, Expr, Expression},
engine::StateWorkingSet,
ir::Instruction,
IntoSpanned, RegId, VarId,
IntoSpanned, RegId, Type, VarId,
};
use super::{compile_block, compile_expression, BlockBuilder, CompileError, RedirectModes};
@ -302,6 +302,8 @@ pub(crate) fn compile_let(
let block_id = block_arg.as_block().ok_or_else(invalid)?;
let block = working_set.get_block(block_id);
let variable = working_set.get_variable(var_id);
compile_block(
working_set,
builder,
@ -311,6 +313,17 @@ pub(crate) fn compile_let(
io_reg,
)?;
// If the variable is a glob type variable, we should cast it with GlobFrom
if variable.ty == Type::Glob {
builder.push(
Instruction::GlobFrom {
src_dst: io_reg,
no_expand: true,
}
.into_spanned(call.head),
)?;
}
builder.push(
Instruction::StoreVariable {
var_id,

View File

@ -503,8 +503,14 @@ fn eval_instruction<D: DebugContext>(
}
Instruction::GlobFrom { src_dst, no_expand } => {
let string_value = ctx.collect_reg(*src_dst, *span)?;
let string = string_value.into_string()?;
let glob_value = Value::glob(string, *no_expand, *span);
let glob_value = if matches!(string_value, Value::Glob { .. }) {
// It already is a glob, so don't touch it.
string_value
} else {
// Treat it as a string, then cast
let string = string_value.into_string()?;
Value::glob(string, *no_expand, *span)
};
ctx.put_reg(*src_dst, glob_value.into_pipeline_data());
Ok(Continue)
}

View File

@ -169,7 +169,8 @@ pub enum Instruction {
/// Append a value onto the end of a string. Uses `to_expanded_string(", ", ...)` on the value.
/// Used for string interpolation literals. Not the same thing as the `++` operator.
StringAppend { src_dst: RegId, val: RegId },
/// Convert a string into a glob. Used for glob interpolation.
/// Convert a string into a glob. Used for glob interpolation and setting glob variables. If the
/// value is already a glob, it won't be modified (`no_expand` will have no effect).
GlobFrom { src_dst: RegId, no_expand: bool },
/// Push a value onto the end of a list. Used to construct list literals.
ListPush { src_dst: RegId, item: RegId },