forked from extern/nushell
Remove broken compile-time overload system (#9677)
# Description This PR removes the compile-time overload system. Unfortunately, this system never worked correctly because in a gradual type system where types can be `Any`, you don't have enough information to correctly resolve function calls with overloads. These resolutions must be done at runtime, if they're supported. That said, there's a bit of work that needs to go into resolving input/output types (here overloads do not execute separate commands, but the same command and each overload explains how each output type corresponds to input types). This PR also removes the type scope, which would give incorrect answers in cases where multiple subexpressions were used in a pipeline. # User-Facing Changes Finishes removing compile-time overloads. These were only used in a few places in the code base, but it's possible it may impact user code. I'll mark this as breaking change so we can review. # Tests + Formatting <!-- Don't forget to add tests that cover your changes. Make sure you've run and fixed any issues with these commands: - `cargo fmt --all -- --check` to check standard code formatting (`cargo fmt --all` applies these changes) - `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used -A clippy::needless_collect -A clippy::result_large_err` to check that you're using the standard code style - `cargo test --workspace` to check that all tests pass - `cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"` to run the tests for the standard library > **Note** > from `nushell` you can also use the `toolkit` as follows > ```bash > use toolkit.nu # or use an `env_change` hook to activate it automatically > toolkit check pr > ``` --> # After Submitting <!-- If your PR had any user-facing changes, update [the documentation](https://github.com/nushell/nushell.github.io) after the PR is merged, if necessary. This will help us keep the docs up to date. -->
This commit is contained in:
@ -235,7 +235,7 @@ pub fn parse_for(working_set: &mut StateWorkingSet, spans: &[Span]) -> Expressio
|
||||
// Parsing the spans and checking that they match the register signature
|
||||
// Using a parsed call makes more sense than checking for how many spans are in the call
|
||||
// Also, by creating a call, it can be checked if it matches the declaration signature
|
||||
let (call, call_span) = match working_set.find_decl(b"for", &Type::Nothing) {
|
||||
let (call, call_span) = match working_set.find_decl(b"for") {
|
||||
None => {
|
||||
working_set.error(ParseError::UnknownState(
|
||||
"internal error: for declaration not found".into(),
|
||||
@ -359,7 +359,7 @@ pub fn parse_def(
|
||||
// Parsing the spans and checking that they match the register signature
|
||||
// Using a parsed call makes more sense than checking for how many spans are in the call
|
||||
// Also, by creating a call, it can be checked if it matches the declaration signature
|
||||
let (call, call_span) = match working_set.find_decl(&def_call, &Type::Nothing) {
|
||||
let (call, call_span) = match working_set.find_decl(&def_call) {
|
||||
None => {
|
||||
working_set.error(ParseError::UnknownState(
|
||||
"internal error: def declaration not found".into(),
|
||||
@ -548,7 +548,7 @@ pub fn parse_extern(
|
||||
// Parsing the spans and checking that they match the register signature
|
||||
// Using a parsed call makes more sense than checking for how many spans are in the call
|
||||
// Also, by creating a call, it can be checked if it matches the declaration signature
|
||||
let (call, call_span) = match working_set.find_decl(&extern_call, &Type::Nothing) {
|
||||
let (call, call_span) = match working_set.find_decl(&extern_call) {
|
||||
None => {
|
||||
working_set.error(ParseError::UnknownState(
|
||||
"internal error: def declaration not found".into(),
|
||||
@ -739,7 +739,7 @@ pub fn parse_alias(
|
||||
return Pipeline::from_vec(vec![garbage(*span)]);
|
||||
}
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"alias", &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(b"alias") {
|
||||
let (command_spans, rest_spans) = spans.split_at(split_id);
|
||||
|
||||
let original_starting_error_count = working_set.parse_errors.len();
|
||||
@ -941,7 +941,7 @@ pub fn parse_export_in_block(
|
||||
b"export".to_vec()
|
||||
};
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(&full_name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(&full_name) {
|
||||
let ParsedInternalCall { call, output, .. } = parse_internal_call(
|
||||
working_set,
|
||||
if full_name == b"export" {
|
||||
@ -1035,7 +1035,7 @@ pub fn parse_export_in_module(
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
let export_decl_id = if let Some(id) = working_set.find_decl(b"export", &Type::Nothing) {
|
||||
let export_decl_id = if let Some(id) = working_set.find_decl(b"export") {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
@ -1064,16 +1064,15 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let pipeline = parse_def(working_set, &lite_command, Some(module_name));
|
||||
|
||||
let export_def_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export def", &Type::Nothing) {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export def' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
let export_def_decl_id = if let Some(id) = working_set.find_decl(b"export def") {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export def' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
// Trying to warp the 'def' call into the 'export def' in a very clumsy way
|
||||
if let Some(PipelineElement::Expression(
|
||||
@ -1101,7 +1100,7 @@ pub fn parse_export_in_module(
|
||||
let decl_name = working_set.get_span_contents(*decl_name_span);
|
||||
let decl_name = trim_quotes(decl_name);
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name) {
|
||||
result.push(Exportable::Decl {
|
||||
name: decl_name.to_vec(),
|
||||
id: decl_id,
|
||||
@ -1123,16 +1122,16 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let pipeline = parse_def(working_set, &lite_command, Some(module_name));
|
||||
|
||||
let export_def_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export def-env", &Type::Nothing) {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export def-env' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
let export_def_decl_id = if let Some(id) = working_set.find_decl(b"export def-env")
|
||||
{
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export def-env' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
// Trying to warp the 'def' call into the 'export def' in a very clumsy way
|
||||
if let Some(PipelineElement::Expression(
|
||||
@ -1162,7 +1161,7 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let decl_name = trim_quotes(decl_name);
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name) {
|
||||
result.push(Exportable::Decl {
|
||||
name: decl_name.to_vec(),
|
||||
id: decl_id,
|
||||
@ -1183,16 +1182,15 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let pipeline = parse_extern(working_set, &lite_command, Some(module_name));
|
||||
|
||||
let export_def_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export extern", &Type::Nothing) {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export extern' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
let export_def_decl_id = if let Some(id) = working_set.find_decl(b"export extern") {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export extern' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
// Trying to warp the 'def' call into the 'export def' in a very clumsy way
|
||||
if let Some(PipelineElement::Expression(
|
||||
@ -1222,7 +1220,7 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let decl_name = trim_quotes(decl_name);
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(decl_name) {
|
||||
result.push(Exportable::Decl {
|
||||
name: decl_name.to_vec(),
|
||||
id: decl_id,
|
||||
@ -1243,16 +1241,16 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let pipeline = parse_alias(working_set, &lite_command, Some(module_name));
|
||||
|
||||
let export_alias_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export alias", &Type::Nothing) {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export alias' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
let export_alias_decl_id = if let Some(id) = working_set.find_decl(b"export alias")
|
||||
{
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export alias' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
// Trying to warp the 'alias' call into the 'export alias' in a very clumsy way
|
||||
if let Some(PipelineElement::Expression(
|
||||
@ -1282,7 +1280,7 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let alias_name = trim_quotes(alias_name);
|
||||
|
||||
if let Some(alias_id) = working_set.find_decl(alias_name, &Type::Nothing) {
|
||||
if let Some(alias_id) = working_set.find_decl(alias_name) {
|
||||
result.push(Exportable::Decl {
|
||||
name: alias_name.to_vec(),
|
||||
id: alias_id,
|
||||
@ -1303,16 +1301,15 @@ pub fn parse_export_in_module(
|
||||
};
|
||||
let (pipeline, exportables) = parse_use(working_set, &lite_command.parts);
|
||||
|
||||
let export_use_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export use", &Type::Nothing) {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export use' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
let export_use_decl_id = if let Some(id) = working_set.find_decl(b"export use") {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
"missing 'export use' command".into(),
|
||||
export_span,
|
||||
));
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
};
|
||||
|
||||
// Trying to warp the 'use' call into the 'export use' in a very clumsy way
|
||||
if let Some(PipelineElement::Expression(
|
||||
@ -1341,7 +1338,7 @@ pub fn parse_export_in_module(
|
||||
parse_module(working_set, lite_command, Some(module_name));
|
||||
|
||||
let export_module_decl_id =
|
||||
if let Some(id) = working_set.find_decl(b"export module", &Type::Nothing) {
|
||||
if let Some(id) = working_set.find_decl(b"export module") {
|
||||
id
|
||||
} else {
|
||||
working_set.error(ParseError::InternalError(
|
||||
@ -1446,7 +1443,7 @@ pub fn parse_export_env(
|
||||
return (garbage_pipeline(spans), None);
|
||||
}
|
||||
|
||||
let call = match working_set.find_decl(b"export-env", &Type::Nothing) {
|
||||
let call = match working_set.find_decl(b"export-env") {
|
||||
Some(decl_id) => {
|
||||
let ParsedInternalCall { call, output } =
|
||||
parse_internal_call(working_set, spans[0], &[spans[1]], decl_id);
|
||||
@ -1958,7 +1955,7 @@ pub fn parse_module(
|
||||
1
|
||||
};
|
||||
|
||||
let (call, call_span) = match working_set.find_decl(b"module", &Type::Nothing) {
|
||||
let (call, call_span) = match working_set.find_decl(b"module") {
|
||||
Some(decl_id) => {
|
||||
let (command_spans, rest_spans) = spans.split_at(split_id);
|
||||
|
||||
@ -2099,7 +2096,7 @@ pub fn parse_module(
|
||||
};
|
||||
|
||||
let module_decl_id = working_set
|
||||
.find_decl(b"module", &Type::Nothing)
|
||||
.find_decl(b"module")
|
||||
.expect("internal error: missing module command");
|
||||
|
||||
let call = Box::new(Call {
|
||||
@ -2150,7 +2147,7 @@ pub fn parse_use(working_set: &mut StateWorkingSet, spans: &[Span]) -> (Pipeline
|
||||
return (garbage_pipeline(spans), vec![]);
|
||||
}
|
||||
|
||||
let (call, call_span, args_spans) = match working_set.find_decl(b"use", &Type::Nothing) {
|
||||
let (call, call_span, args_spans) = match working_set.find_decl(b"use") {
|
||||
Some(decl_id) => {
|
||||
let (command_spans, rest_spans) = spans.split_at(split_id);
|
||||
|
||||
@ -2306,7 +2303,7 @@ pub fn parse_hide(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeline
|
||||
return garbage_pipeline(spans);
|
||||
}
|
||||
|
||||
let (call, args_spans) = match working_set.find_decl(b"hide", &Type::Nothing) {
|
||||
let (call, args_spans) = match working_set.find_decl(b"hide") {
|
||||
Some(decl_id) => {
|
||||
let ParsedInternalCall { call, output } =
|
||||
parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
@ -2365,7 +2362,7 @@ pub fn parse_hide(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeline
|
||||
(true, working_set.get_module(module_id).clone())
|
||||
} else if import_pattern.members.is_empty() {
|
||||
// The pattern head can be:
|
||||
if let Some(id) = working_set.find_decl(&import_pattern.head.name, &Type::Nothing) {
|
||||
if let Some(id) = working_set.find_decl(&import_pattern.head.name) {
|
||||
// a custom command,
|
||||
let mut module = Module::new(b"tmp".to_vec());
|
||||
module.add_decl(import_pattern.head.name.clone(), id);
|
||||
@ -2803,7 +2800,7 @@ pub fn parse_let(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeline
|
||||
// return Pipeline::from_vec(vec![garbage(*span)]);
|
||||
// }
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"let", &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(b"let") {
|
||||
if spans.len() >= 4 {
|
||||
// This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
|
||||
// so that the var-id created by the variable isn't visible in the expression that init it
|
||||
@ -2919,7 +2916,7 @@ pub fn parse_const(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipelin
|
||||
// return Pipeline::from_vec(vec![garbage(*span)]);
|
||||
// }
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"const", &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(b"const") {
|
||||
let cmd = working_set.get_decl(decl_id);
|
||||
let call_signature = cmd.signature().call_signature();
|
||||
|
||||
@ -3041,7 +3038,7 @@ pub fn parse_mut(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeline
|
||||
// return Pipeline::from_vec(vec![garbage(*span)]);
|
||||
// }
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"mut", &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(b"mut") {
|
||||
if spans.len() >= 4 {
|
||||
// This is a bit of by-hand parsing to get around the issue where we want to parse in the reverse order
|
||||
// so that the var-id created by the variable isn't visible in the expression that init it
|
||||
@ -3155,7 +3152,7 @@ pub fn parse_source(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipeli
|
||||
if name == b"source" || name == b"source-env" {
|
||||
let scoped = name == b"source-env";
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(name) {
|
||||
let cwd = working_set.get_cwd();
|
||||
|
||||
// Is this the right call to be using here?
|
||||
@ -3286,7 +3283,7 @@ pub fn parse_where_expr(working_set: &mut StateWorkingSet, spans: &[Span]) -> Ex
|
||||
return garbage(span(spans));
|
||||
}
|
||||
|
||||
let call = match working_set.find_decl(b"where", &Type::List(Box::new(Type::Any))) {
|
||||
let call = match working_set.find_decl(b"where") {
|
||||
Some(decl_id) => {
|
||||
let ParsedInternalCall { call, output } =
|
||||
parse_internal_call(working_set, spans[0], &spans[1..], decl_id);
|
||||
@ -3349,7 +3346,7 @@ pub fn parse_register(working_set: &mut StateWorkingSet, spans: &[Span]) -> Pipe
|
||||
// Parsing the spans and checking that they match the register signature
|
||||
// Using a parsed call makes more sense than checking for how many spans are in the call
|
||||
// Also, by creating a call, it can be checked if it matches the declaration signature
|
||||
let (call, call_span) = match working_set.find_decl(b"register", &Type::Nothing) {
|
||||
let (call, call_span) = match working_set.find_decl(b"register") {
|
||||
None => {
|
||||
working_set.error(ParseError::UnknownState(
|
||||
"internal error: Register declaration not found".into(),
|
||||
|
@ -815,8 +815,6 @@ pub fn parse_internal_call(
|
||||
}
|
||||
}
|
||||
|
||||
working_set.type_scope.add_type(output.clone());
|
||||
|
||||
if signature.creates_scope {
|
||||
working_set.enter_scope();
|
||||
}
|
||||
@ -1052,8 +1050,7 @@ pub fn parse_call(
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
let input = working_set.type_scope.get_previous();
|
||||
let mut maybe_decl_id = working_set.find_decl(&name, input);
|
||||
let mut maybe_decl_id = working_set.find_decl(&name);
|
||||
|
||||
while maybe_decl_id.is_none() {
|
||||
// Find the longest command match
|
||||
@ -1075,7 +1072,7 @@ pub fn parse_call(
|
||||
name.extend(name_part);
|
||||
}
|
||||
}
|
||||
maybe_decl_id = working_set.find_decl(&name, input);
|
||||
maybe_decl_id = working_set.find_decl(&name);
|
||||
}
|
||||
|
||||
if let Some(decl_id) = maybe_decl_id {
|
||||
@ -1096,7 +1093,7 @@ pub fn parse_call(
|
||||
}
|
||||
|
||||
// TODO: Try to remove the clone
|
||||
let decl = working_set.get_decl(decl_id).clone();
|
||||
let decl = working_set.get_decl(decl_id);
|
||||
|
||||
let parsed_call = if let Some(alias) = decl.as_alias() {
|
||||
if let Expression {
|
||||
@ -1104,7 +1101,7 @@ pub fn parse_call(
|
||||
span: _,
|
||||
ty,
|
||||
custom_completion,
|
||||
} = &alias.wrapped_call
|
||||
} = &alias.clone().wrapped_call
|
||||
{
|
||||
trace!("parsing: alias of external call");
|
||||
|
||||
@ -2004,9 +2001,6 @@ pub fn parse_full_cell_path(
|
||||
// Creating a Type scope to parse the new block. This will keep track of
|
||||
// the previous input type found in that block
|
||||
let output = parse_block(working_set, &output, span, true, true);
|
||||
working_set
|
||||
.type_scope
|
||||
.add_type(working_set.type_scope.get_last_output());
|
||||
|
||||
let ty = output.output_type();
|
||||
|
||||
@ -2742,7 +2736,7 @@ pub fn parse_shape_name(
|
||||
return SyntaxShape::Any;
|
||||
}
|
||||
|
||||
let decl_id = working_set.find_decl(command_name, &Type::Any);
|
||||
let decl_id = working_set.find_decl(command_name);
|
||||
|
||||
if let Some(decl_id) = decl_id {
|
||||
return SyntaxShape::Custom(Box::new(shape), decl_id);
|
||||
@ -5088,7 +5082,7 @@ pub fn parse_expression(
|
||||
}
|
||||
};
|
||||
|
||||
let with_env = working_set.find_decl(b"with-env", &Type::Any);
|
||||
let with_env = working_set.find_decl(b"with-env");
|
||||
|
||||
if !shorthand.is_empty() {
|
||||
if let Some(decl_id) = with_env {
|
||||
@ -5146,14 +5140,7 @@ pub fn parse_variable(working_set: &mut StateWorkingSet, span: Span) -> Option<V
|
||||
let bytes = working_set.get_span_contents(span);
|
||||
|
||||
if is_variable(bytes) {
|
||||
if let Some(var_id) = working_set.find_variable(bytes) {
|
||||
let input = working_set.get_variable(var_id).ty.clone();
|
||||
working_set.type_scope.add_type(input);
|
||||
|
||||
Some(var_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
working_set.find_variable(bytes)
|
||||
} else {
|
||||
working_set.error(ParseError::Expected("valid variable name", span));
|
||||
|
||||
@ -5172,7 +5159,7 @@ pub fn parse_builtin_commands(
|
||||
{
|
||||
trace!("parsing: not math expression or unaliasable parser keyword");
|
||||
let name = working_set.get_span_contents(lite_command.parts[0]);
|
||||
if let Some(decl_id) = working_set.find_decl(name, &Type::Nothing) {
|
||||
if let Some(decl_id) = working_set.find_decl(name) {
|
||||
let cmd = working_set.get_decl(decl_id);
|
||||
if cmd.is_alias() {
|
||||
// Parse keywords that can be aliased. Note that we check for "unaliasable" keywords
|
||||
@ -5350,8 +5337,8 @@ pub fn parse_pipeline(
|
||||
parse_builtin_commands(working_set, &new_command, is_subexpression);
|
||||
|
||||
if pipeline_index == 0 {
|
||||
let let_decl_id = working_set.find_decl(b"let", &Type::Nothing);
|
||||
let mut_decl_id = working_set.find_decl(b"mut", &Type::Nothing);
|
||||
let let_decl_id = working_set.find_decl(b"let");
|
||||
let mut_decl_id = working_set.find_decl(b"mut");
|
||||
for element in pipeline.elements.iter_mut() {
|
||||
if let PipelineElement::Expression(
|
||||
_,
|
||||
@ -5416,7 +5403,6 @@ pub fn parse_pipeline(
|
||||
LiteElement::Command(span, command) => {
|
||||
trace!("parsing: pipeline element: command");
|
||||
let expr = parse_expression(working_set, &command.parts, is_subexpression);
|
||||
working_set.type_scope.add_type(expr.ty.clone());
|
||||
|
||||
PipelineElement::Expression(*span, expr)
|
||||
}
|
||||
@ -5424,8 +5410,6 @@ pub fn parse_pipeline(
|
||||
trace!("parsing: pipeline element: redirection");
|
||||
let expr = parse_string(working_set, command.parts[0]);
|
||||
|
||||
working_set.type_scope.add_type(expr.ty.clone());
|
||||
|
||||
PipelineElement::Redirection(*span, redirection.clone(), expr)
|
||||
}
|
||||
LiteElement::SeparateRedirection {
|
||||
@ -5435,12 +5419,8 @@ pub fn parse_pipeline(
|
||||
trace!("parsing: pipeline element: separate redirection");
|
||||
let out_expr = parse_string(working_set, out_command.parts[0]);
|
||||
|
||||
working_set.type_scope.add_type(out_expr.ty.clone());
|
||||
|
||||
let err_expr = parse_string(working_set, err_command.parts[0]);
|
||||
|
||||
working_set.type_scope.add_type(err_expr.ty.clone());
|
||||
|
||||
PipelineElement::SeparateRedirection {
|
||||
out: (*out_span, out_expr),
|
||||
err: (*err_span, err_expr),
|
||||
@ -5452,9 +5432,7 @@ pub fn parse_pipeline(
|
||||
} => {
|
||||
trace!("parsing: pipeline element: same target redirection");
|
||||
let expr = parse_expression(working_set, &command.parts, is_subexpression);
|
||||
working_set.type_scope.add_type(expr.ty.clone());
|
||||
let redirect_expr = parse_string(working_set, redirect_command.parts[0]);
|
||||
working_set.type_scope.add_type(redirect_expr.ty.clone());
|
||||
PipelineElement::SameTargetRedirection {
|
||||
cmd: (*cmd_span, expr),
|
||||
redirection: (*redirect_span, redirect_expr),
|
||||
@ -5487,8 +5465,8 @@ pub fn parse_pipeline(
|
||||
} => {
|
||||
let mut pipeline = parse_builtin_commands(working_set, command, is_subexpression);
|
||||
|
||||
let let_decl_id = working_set.find_decl(b"let", &Type::Nothing);
|
||||
let mut_decl_id = working_set.find_decl(b"mut", &Type::Nothing);
|
||||
let let_decl_id = working_set.find_decl(b"let");
|
||||
let mut_decl_id = working_set.find_decl(b"mut");
|
||||
|
||||
if pipeline_index == 0 {
|
||||
for element in pipeline.elements.iter_mut() {
|
||||
@ -5542,12 +5520,9 @@ pub fn parse_pipeline(
|
||||
} => {
|
||||
trace!("parsing: pipeline element: same target redirection");
|
||||
let expr = parse_expression(working_set, &command.parts, is_subexpression);
|
||||
working_set.type_scope.add_type(expr.ty.clone());
|
||||
|
||||
let redirect_expr = parse_string(working_set, redirect_cmd.parts[0]);
|
||||
|
||||
working_set.type_scope.add_type(redirect_expr.ty.clone());
|
||||
|
||||
Pipeline {
|
||||
elements: vec![PipelineElement::SameTargetRedirection {
|
||||
cmd: (*span, expr),
|
||||
@ -5576,7 +5551,6 @@ pub fn parse_block(
|
||||
if scoped {
|
||||
working_set.enter_scope();
|
||||
}
|
||||
working_set.type_scope.enter_scope();
|
||||
|
||||
// Pre-declare any definition so that definitions
|
||||
// that share the same block can see each other
|
||||
@ -5605,7 +5579,6 @@ pub fn parse_block(
|
||||
if scoped {
|
||||
working_set.exit_scope();
|
||||
}
|
||||
working_set.type_scope.exit_scope();
|
||||
|
||||
block.span = Some(span);
|
||||
|
||||
@ -6008,7 +5981,7 @@ fn wrap_element_with_collect(
|
||||
fn wrap_expr_with_collect(working_set: &mut StateWorkingSet, expr: &Expression) -> Expression {
|
||||
let span = expr.span;
|
||||
|
||||
if let Some(decl_id) = working_set.find_decl(b"collect", &Type::List(Box::new(Type::Any))) {
|
||||
if let Some(decl_id) = working_set.find_decl(b"collect") {
|
||||
let mut output = vec![];
|
||||
|
||||
let var_id = IN_VARIABLE_ID;
|
||||
|
Reference in New Issue
Block a user