Remove the Value::Block case (#12582)

# Description
`Value` describes the types of first-class values that users and scripts
can create, manipulate, pass around, and store. However, `Block`s are
not first-class values in the language, so this PR removes it from
`Value`. This removes some unnecessary code, and this change should be
invisible to the user except for the change to `scope modules` described
below.

# User-Facing Changes
Breaking change: the output of `scope modules` was changed so that
`env_block` is now `has_env_block` which is a boolean value instead of a
`Block`.

# After Submitting
Update the language guide possibly.
This commit is contained in:
Ian Manske
2024-04-21 05:03:33 +00:00
committed by GitHub
parent 5fd34320e9
commit 3b1d405b96
32 changed files with 171 additions and 352 deletions

View File

@ -1,8 +1,5 @@
use nu_engine::command_prelude::*;
use nu_protocol::{
engine::{Closure, StateWorkingSet},
PipelineMetadata,
};
use nu_protocol::{engine::StateWorkingSet, PipelineMetadata};
#[derive(Clone)]
pub struct Describe;
@ -336,16 +333,12 @@ fn describe_value(
),
head,
),
Value::Block { val, .. }
| Value::Closure {
val: Closure { block_id: val, .. },
..
} => {
let block = engine_state.map(|engine_state| engine_state.get_block(val));
Value::Closure { val, .. } => {
let block = engine_state.map(|engine_state| engine_state.get_block(val.block_id));
if let Some(block) = block {
let mut record = Record::new();
record.push("type", Value::string(value.get_type().to_string(), head));
record.push("type", Value::string("closure", head));
record.push(
"signature",
Value::record(

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
use nu_protocol::{engine::Block, ListStream};
use nu_protocol::ListStream;
#[derive(Clone)]
pub struct For;
@ -66,18 +66,22 @@ impl Command for For {
.as_keyword()
.expect("internal error: missing keyword");
let block_id = call
.positional_nth(2)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let eval_expression = get_eval_expression(engine_state);
let eval_block = get_eval_block(engine_state);
let value = eval_expression(engine_state, stack, keyword_expr)?;
let block: Block = call.req(engine_state, stack, 2)?;
let numbered = call.has_flag(engine_state, stack, "numbered")?;
let ctrlc = engine_state.ctrlc.clone();
let engine_state = engine_state.clone();
let block = engine_state.get_block(block.block_id).clone();
let block = engine_state.get_block(block_id);
let stack = &mut stack.push_redirection(None, None);
@ -104,7 +108,7 @@ impl Command for For {
},
);
match eval_block(&engine_state, stack, &block, PipelineData::empty()) {
match eval_block(&engine_state, stack, block, PipelineData::empty()) {
Err(ShellError::Break { .. }) => {
break;
}
@ -142,7 +146,7 @@ impl Command for For {
},
);
match eval_block(&engine_state, stack, &block, PipelineData::empty()) {
match eval_block(&engine_state, stack, block, PipelineData::empty()) {
Err(ShellError::Break { .. }) => {
break;
}
@ -166,7 +170,7 @@ impl Command for For {
x => {
stack.add_var(var_id, x);
eval_block(&engine_state, stack, &block, PipelineData::empty())?.into_value(head);
eval_block(&engine_state, stack, block, PipelineData::empty())?.into_value(head);
}
}
Ok(PipelineData::empty())

View File

@ -2,7 +2,7 @@ use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::{
engine::{Block, StateWorkingSet},
engine::StateWorkingSet,
eval_const::{eval_const_subexpression, eval_constant, eval_constant_with_input},
};
@ -52,14 +52,18 @@ impl Command for If {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let cond = call.positional_nth(0).expect("checked through parser");
let then_block: Block = call.req_const(working_set, 1)?;
let then_block = call
.positional_nth(1)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let else_case = call.positional_nth(2);
let result = eval_constant(working_set, cond)?;
match &result {
Value::Bool { val, .. } => {
if *val {
let block = working_set.get_block(then_block.block_id);
let block = working_set.get_block(then_block);
eval_const_subexpression(
working_set,
block,
@ -103,8 +107,13 @@ impl Command for If {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let cond = call.positional_nth(0).expect("checked through parser");
let then_block: Block = call.req(engine_state, stack, 1)?;
let then_block = call
.positional_nth(1)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let else_case = call.positional_nth(2);
let eval_expression = get_eval_expression(engine_state);
let eval_expression_with_input = get_eval_expression_with_input(engine_state);
let eval_block = get_eval_block(engine_state);
@ -113,7 +122,7 @@ impl Command for If {
match &result {
Value::Bool { val, .. } => {
if *val {
let block = engine_state.get_block(then_block.block_id);
let block = engine_state.get_block(then_block);
eval_block(engine_state, stack, block, input)
} else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() {

View File

@ -1,5 +1,4 @@
use nu_engine::{command_prelude::*, get_eval_block};
use nu_protocol::engine::Block;
#[derive(Clone)]
pub struct Loop;
@ -28,7 +27,13 @@ impl Command for Loop {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let block: Block = call.req(engine_state, stack, 0)?;
let block_id = call
.positional_nth(0)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let block = engine_state.get_block(block_id);
let eval_block = get_eval_block(engine_state);
let stack = &mut stack.push_redirection(None, None);
@ -38,8 +43,6 @@ impl Command for Loop {
break;
}
let block = engine_state.get_block(block.block_id);
match eval_block(engine_state, stack, block, PipelineData::empty()) {
Err(ShellError::Break { .. }) => {
break;

View File

@ -1,5 +1,5 @@
use nu_engine::{command_prelude::*, get_eval_block, EvalBlockFn};
use nu_protocol::engine::{Block, Closure};
use nu_protocol::engine::Closure;
#[derive(Clone)]
pub struct Try;
@ -38,10 +38,15 @@ impl Command for Try {
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let try_block: Block = call.req(engine_state, stack, 0)?;
let try_block = call
.positional_nth(0)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let catch_block: Option<Closure> = call.opt(engine_state, stack, 1)?;
let try_block = engine_state.get_block(try_block.block_id);
let try_block = engine_state.get_block(try_block);
let eval_block = get_eval_block(engine_state);
let result = eval_block(engine_state, stack, try_block, input);

View File

@ -1,5 +1,4 @@
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
use nu_protocol::engine::Block;
#[derive(Clone)]
pub struct While;
@ -38,7 +37,11 @@ impl Command for While {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let cond = call.positional_nth(0).expect("checked through parser");
let block: Block = call.req(engine_state, stack, 1)?;
let block_id = call
.positional_nth(1)
.expect("checked through parser")
.as_block()
.expect("internal error: missing block");
let eval_expression = get_eval_expression(engine_state);
let eval_block = get_eval_block(engine_state);
@ -55,7 +58,7 @@ impl Command for While {
match &result {
Value::Bool { val, .. } => {
if *val {
let block = engine_state.get_block(block.block_id);
let block = engine_state.get_block(block_id);
match eval_block(engine_state, stack, block, PipelineData::empty()) {
Err(ShellError::Break { .. }) => {

View File

@ -288,9 +288,6 @@ impl<'a> std::fmt::Debug for DebuggableValue<'a> {
}
write!(f, "]")
}
Value::Block { val, .. } => {
write!(f, "Block({:?})", val)
}
Value::Closure { val, .. } => {
write!(f, "Closure({:?})", val)
}