diff --git a/crates/nu-cli/src/eval_file.rs b/crates/nu-cli/src/eval_file.rs index f6c0226fef..a513ec56c0 100644 --- a/crates/nu-cli/src/eval_file.rs +++ b/crates/nu-cli/src/eval_file.rs @@ -9,7 +9,7 @@ use nu_protocol::report_error; use nu_protocol::{ ast::Call, engine::{EngineState, Stack, StateWorkingSet}, - Config, PipelineData, ShellError, Span, Type, Value, + Config, PipelineData, ShellError, Span, Value, }; use nu_utils::stdout_write_all_and_flush; @@ -102,7 +102,7 @@ pub fn evaluate_file( trace!("parsing file: {}", file_path_str); let _ = parse(&mut working_set, Some(file_path_str), &file, false); - if working_set.find_decl(b"main", &Type::Any).is_some() { + if working_set.find_decl(b"main").is_some() { let args = format!("main {}", args.join(" ")); if !eval_source( diff --git a/crates/nu-engine/src/scope.rs b/crates/nu-engine/src/scope.rs index af887a7a6e..3e6a61a0a2 100644 --- a/crates/nu-engine/src/scope.rs +++ b/crates/nu-engine/src/scope.rs @@ -52,7 +52,7 @@ pub struct ScopeData<'e, 's> { engine_state: &'e EngineState, stack: &'s Stack, vars_map: HashMap<&'e Vec, &'e usize>, - decls_map: HashMap<&'e (Vec, Type), &'e usize>, + decls_map: HashMap<&'e Vec, &'e usize>, modules_map: HashMap<&'e Vec, &'e usize>, visibility: Visibility, } @@ -108,7 +108,7 @@ impl<'e, 's> ScopeData<'e, 's> { pub fn collect_commands(&self, span: Span) -> Vec { let mut commands = vec![]; - for ((command_name, _), decl_id) in &self.decls_map { + for (command_name, decl_id) in &self.decls_map { if self.visibility.is_decl_id_visible(decl_id) && !self.engine_state.get_decl(**decl_id).is_alias() { @@ -488,7 +488,7 @@ impl<'e, 's> ScopeData<'e, 's> { pub fn collect_externs(&self, span: Span) -> Vec { let mut externals = vec![]; - for ((command_name, _), decl_id) in &self.decls_map { + for (command_name, decl_id) in &self.decls_map { let decl = self.engine_state.get_decl(**decl_id); if decl.is_known_external() { diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index afa720f0ee..7e08598f65 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -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(), diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index f9c5864c39..3a4a318624 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -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 { 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; diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index f67f8c04f6..e6647e37d5 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -1590,177 +1590,6 @@ mod input_types { .expect("Error merging delta"); } - #[test] - fn call_types_test() { - let mut engine_state = EngineState::new(); - add_declarations(&mut engine_state); - - let mut working_set = StateWorkingSet::new(&engine_state); - let input = r#"ls | to-custom | group-by name other"#; - - let block = parse(&mut working_set, None, input.as_bytes(), true); - - assert!(working_set.parse_errors.is_empty()); - assert_eq!(block.len(), 1); - - let expressions = &block[0]; - assert_eq!(expressions.len(), 3); - - match &expressions[0] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set - .find_decl(b"ls", &Type::Nothing) - .expect("Error merging delta"); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - - match &expressions[1] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set.find_decl(b"to-custom", &Type::Any).unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - - match &expressions[2] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set - .find_decl(b"group-by", &Type::Custom("custom".into())) - .unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - } - - #[test] - fn storing_variable_test() { - let mut engine_state = EngineState::new(); - add_declarations(&mut engine_state); - - let mut working_set = StateWorkingSet::new(&engine_state); - let input = - r#"let a = (ls | to-custom | group-by name other); let b = (1+3); $a | agg sum"#; - - let block = parse(&mut working_set, None, input.as_bytes(), true); - - assert!(working_set.parse_errors.is_empty()); - assert_eq!(block.len(), 3); - - let expressions = &block[2]; - match &expressions[1] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set - .find_decl(b"agg", &Type::Custom("custom".into())) - .unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - } - - #[test] - fn stored_variable_operation_test() { - let mut engine_state = EngineState::new(); - add_declarations(&mut engine_state); - - let mut working_set = StateWorkingSet::new(&engine_state); - let input = r#"let a = (ls | to-custom | group-by name other); ($a + $a) | agg sum"#; - - let block = parse(&mut working_set, None, input.as_bytes(), true); - - assert!(working_set.parse_errors.is_empty()); - assert_eq!(block.len(), 2); - - let expressions = &block[1]; - match &expressions[1] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set - .find_decl(b"agg", &Type::Custom("custom".into())) - .unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - } - - #[test] - fn multiple_stored_variable_test() { - let mut engine_state = EngineState::new(); - add_declarations(&mut engine_state); - - let mut working_set = StateWorkingSet::new(&engine_state); - let input = r#" - let a = (ls | to-custom | group-by name other); [1 2 3] | to-custom; [1 2 3] | to-custom"#; - - let block = parse(&mut working_set, None, input.as_bytes(), true); - - assert!(working_set.parse_errors.is_empty()); - assert_eq!(block.len(), 3); - - let expressions = &block[1]; - match &expressions[1] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set.find_decl(b"to-custom", &Type::Any).unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - - let expressions = &block[2]; - match &expressions[1] { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let expected_id = working_set.find_decl(b"to-custom", &Type::Any).unwrap(); - assert_eq!(call.decl_id, expected_id) - } - _ => panic!("Expected expression Call not found"), - } - } - #[test] fn call_non_custom_types_test() { let mut engine_state = EngineState::new(); @@ -1785,7 +1614,7 @@ mod input_types { .. }, ) => { - let expected_id = working_set.find_decl(b"ls", &Type::Nothing).unwrap(); + let expected_id = working_set.find_decl(b"ls").unwrap(); assert_eq!(call.decl_id, expected_id) } _ => panic!("Expected expression Call not found"), @@ -1799,7 +1628,7 @@ mod input_types { .. }, ) => { - let expected_id = working_set.find_decl(b"group-by", &Type::Any).unwrap(); + let expected_id = working_set.find_decl(b"group-by").unwrap(); assert_eq!(call.decl_id, expected_id) } _ => panic!("Expected expression Call not found"), @@ -1849,8 +1678,7 @@ mod input_types { }, ) => { let working_set = StateWorkingSet::new(&engine_state); - let expected_id = - working_set.find_decl(b"min", &Type::Any).unwrap(); + let expected_id = working_set.find_decl(b"min").unwrap(); assert_eq!(call.decl_id, expected_id) } _ => panic!("Expected expression Call not found"), @@ -1889,9 +1717,7 @@ mod input_types { .. }, ) => { - let expected_id = working_set - .find_decl(b"with-column", &Type::Custom("custom".into())) - .unwrap(); + let expected_id = working_set.find_decl(b"with-column").unwrap(); assert_eq!(call.decl_id, expected_id) } _ => panic!("Expected expression Call not found"), @@ -1905,9 +1731,7 @@ mod input_types { .. }, ) => { - let expected_id = working_set - .find_decl(b"collect", &Type::Custom("custom".into())) - .unwrap(); + let expected_id = working_set.find_decl(b"collect").unwrap(); assert_eq!(call.decl_id, expected_id) } _ => panic!("Expected expression Call not found"), diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index 5a2ea1ed8a..84240f520c 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -621,7 +621,7 @@ impl EngineState { for overlay_frame in self.active_overlays(removed_overlays).rev() { visibility.append(&overlay_frame.visibility); - if let Some(decl_id) = overlay_frame.get_decl(name, &Type::Any) { + if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { return Some(decl_id); } @@ -638,7 +638,7 @@ impl EngineState { visibility.append(&overlay_frame.visibility); if visibility.is_decl_id_visible(&decl_id) { - for ((name, _), id) in overlay_frame.decls.iter() { + for (name, id) in overlay_frame.decls.iter() { if id == &decl_id { return Some(name); } @@ -714,12 +714,12 @@ impl EngineState { for overlay_frame in self.active_overlays(&[]).rev() { for decl in &overlay_frame.decls { - if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(&decl.0 .0) { + if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(decl.0) { let command = self.get_decl(*decl.1); if ignore_deprecated && command.signature().category == Category::Deprecated { continue; } - output.push((decl.0 .0.clone(), Some(command.usage().to_string()))); + output.push((decl.0.clone(), Some(command.usage().to_string()))); } } } @@ -790,7 +790,7 @@ impl EngineState { } let mut decls: Vec<(Vec, DeclId)> = - decls_map.into_iter().map(|(v, k)| (v.0, k)).collect(); + decls_map.into_iter().map(|(v, k)| (v, k)).collect(); decls.sort_by(|a, b| a.0.cmp(&b.0)); decls.into_iter() @@ -953,7 +953,6 @@ pub struct StateWorkingSet<'a> { pub permanent_state: &'a EngineState, pub delta: StateDelta, pub external_commands: Vec>, - pub type_scope: TypeScope, /// Current working directory relative to the file being parsed right now pub currently_parsed_cwd: Option, /// All previously parsed module files. Used to protect against circular imports. @@ -963,54 +962,6 @@ pub struct StateWorkingSet<'a> { pub parse_errors: Vec, } -/// A temporary placeholder for expression types. It is used to keep track of the input types -/// for each expression in a pipeline -pub struct TypeScope { - /// Layers that map the type inputs that are found in each parsed block - outputs: Vec>, - /// The last know output from a parsed block - last_output: Type, -} - -impl Default for TypeScope { - fn default() -> Self { - Self { - outputs: Vec::new(), - last_output: Type::Any, - } - } -} - -impl TypeScope { - pub fn get_previous(&self) -> &Type { - match self.outputs.last().and_then(|v| v.last()) { - Some(input) => input, - None => &Type::Nothing, - } - } - - pub fn get_last_output(&self) -> Type { - self.last_output.clone() - } - - pub fn add_type(&mut self, input: Type) { - if let Some(v) = self.outputs.last_mut() { - v.push(input) - } else { - self.outputs.push(vec![input]) - } - } - - pub fn enter_scope(&mut self) { - self.outputs.push(Vec::new()) - } - - pub fn exit_scope(&mut self) -> Option> { - self.last_output = self.get_previous().clone(); - self.outputs.pop() - } -} - /// A delta (or change set) between the current global state and a possible future global state. Deltas /// can be applied to the global state to update it to contain both previous state and the state held /// within the delta. @@ -1141,7 +1092,6 @@ impl<'a> StateWorkingSet<'a> { delta: StateDelta::new(permanent_state), permanent_state, external_commands: vec![], - type_scope: TypeScope::default(), currently_parsed_cwd: permanent_state.currently_parsed_cwd.clone(), parsed_module_files: vec![], search_predecls: true, @@ -1197,13 +1147,11 @@ impl<'a> StateWorkingSet<'a> { pub fn add_decl(&mut self, decl: Box) -> DeclId { let name = decl.name().as_bytes().to_vec(); - let input_type = decl.signature().get_input_type(); self.delta.decls.push(decl); let decl_id = self.num_decls() - 1; - self.last_overlay_mut() - .insert_decl(name, input_type, decl_id); + self.last_overlay_mut().insert_decl(name, decl_id); decl_id } @@ -1212,7 +1160,7 @@ impl<'a> StateWorkingSet<'a> { let overlay_frame = self.last_overlay_mut(); for (name, decl_id) in decls { - overlay_frame.insert_decl(name, Type::Any, decl_id); + overlay_frame.insert_decl(name, decl_id); overlay_frame.visibility.use_decl_id(&decl_id); } } @@ -1249,7 +1197,7 @@ impl<'a> StateWorkingSet<'a> { let overlay_frame = self.last_overlay_mut(); if let Some(decl_id) = overlay_frame.predecls.remove(name) { - overlay_frame.insert_decl(name.into(), Type::Any, decl_id); + overlay_frame.insert_decl(name.into(), decl_id); return Some(decl_id); } @@ -1279,7 +1227,7 @@ impl<'a> StateWorkingSet<'a> { visibility.append(&overlay_frame.visibility); - if let Some(decl_id) = overlay_frame.get_decl(name, &Type::Any) { + if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { // Hide decl only if it's not already hidden overlay_frame.visibility.hide_decl_id(&decl_id); @@ -1298,7 +1246,7 @@ impl<'a> StateWorkingSet<'a> { { visibility.append(&overlay_frame.visibility); - if let Some(decl_id) = overlay_frame.get_decl(name, &Type::Any) { + if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { // Hide decl only if it's not already hidden self.last_overlay_mut().visibility.hide_decl_id(&decl_id); @@ -1467,7 +1415,7 @@ impl<'a> StateWorkingSet<'a> { None } - pub fn find_decl(&self, name: &[u8], input: &Type) -> Option { + pub fn find_decl(&self, name: &[u8]) -> Option { let mut removed_overlays = vec![]; let mut visibility: Visibility = Visibility::new(); @@ -1493,7 +1441,7 @@ impl<'a> StateWorkingSet<'a> { } } - if let Some(decl_id) = overlay_frame.get_decl(name, input) { + if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { return Some(decl_id); } @@ -1509,7 +1457,7 @@ impl<'a> StateWorkingSet<'a> { { visibility.append(&overlay_frame.visibility); - if let Some(decl_id) = overlay_frame.get_decl(name, input) { + if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { return Some(decl_id); } @@ -1549,7 +1497,7 @@ impl<'a> StateWorkingSet<'a> { for scope_frame in self.delta.scope.iter().rev() { for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() { for decl in &overlay_frame.decls { - if decl.0 .0.starts_with(name) { + if decl.0.starts_with(name) { return true; } } @@ -1562,7 +1510,7 @@ impl<'a> StateWorkingSet<'a> { .rev() { for decl in &overlay_frame.decls { - if decl.0 .0.starts_with(name) { + if decl.0.starts_with(name) { return true; } } @@ -1768,14 +1716,13 @@ impl<'a> StateWorkingSet<'a> { let overlay_frame = scope_frame.get_overlay(*overlay_id); for decl in &overlay_frame.decls { - if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(&decl.0 .0) - { + if overlay_frame.visibility.is_decl_id_visible(decl.1) && predicate(decl.0) { let command = self.get_decl(*decl.1); if ignore_deprecated && command.signature().category == Category::Deprecated { continue; } - output.push((decl.0 .0.clone(), Some(command.usage().to_string()))); + output.push((decl.0.clone(), Some(command.usage().to_string()))); } } } @@ -1908,7 +1855,7 @@ impl<'a> StateWorkingSet<'a> { let overlay_frame = self.permanent_state.get_overlay(overlay_id); for (decl_key, decl_id) in &overlay_frame.decls { - result.insert(decl_key.0.to_owned(), *decl_id); + result.insert(decl_key.to_owned(), *decl_id); } } @@ -1917,7 +1864,7 @@ impl<'a> StateWorkingSet<'a> { let overlay_frame = scope_frame.get_overlay(overlay_id); for (decl_key, decl_id) in &overlay_frame.decls { - result.insert(decl_key.0.to_owned(), *decl_id); + result.insert(decl_key.to_owned(), *decl_id); } } } diff --git a/crates/nu-protocol/src/engine/overlay.rs b/crates/nu-protocol/src/engine/overlay.rs index 0039cb291e..5134ddc9da 100644 --- a/crates/nu-protocol/src/engine/overlay.rs +++ b/crates/nu-protocol/src/engine/overlay.rs @@ -1,7 +1,5 @@ -use crate::{DeclId, ModuleId, OverlayId, Type, Value, VarId}; -use std::borrow::Borrow; +use crate::{DeclId, ModuleId, OverlayId, Value, VarId}; use std::collections::HashMap; -use std::hash::{Hash, Hasher}; pub static DEFAULT_OVERLAY_NAME: &str = "zero"; @@ -181,7 +179,7 @@ pub struct OverlayFrame { pub vars: HashMap, VarId>, pub constants: HashMap, pub predecls: HashMap, DeclId>, // temporary storage for predeclarations - pub decls: HashMap<(Vec, Type), DeclId>, + pub decls: HashMap, DeclId>, pub modules: HashMap, ModuleId>, pub visibility: Visibility, pub origin: ModuleId, // The original module the overlay was created from @@ -202,82 +200,16 @@ impl OverlayFrame { } } - pub fn insert_decl(&mut self, name: Vec, input: Type, decl_id: DeclId) -> Option { - self.decls.insert((name, input), decl_id) + pub fn insert_decl(&mut self, name: Vec, decl_id: DeclId) -> Option { + self.decls.insert(name, decl_id) } pub fn insert_module(&mut self, name: Vec, module_id: ModuleId) -> Option { self.modules.insert(name, module_id) } - pub fn get_decl(&self, name: &[u8], input: &Type) -> Option { - if let Some(decl) = self.decls.get(&(name, input) as &dyn DeclKey) { - Some(*decl) - } else { - // then fallback to not using the input type - for decl_key in self.decls.keys() { - if decl_key.0 == name { - // FIXME: this fallback may give bad type information - // in the case where no matching type is found. But, at - // least we treat it as a found internal command rather - // than an external command, which would cause further issues - return Some( - *self - .decls - .get(decl_key) - .expect("internal error: found decl not actually found"), - ); - } - } - - None - } - } -} - -trait DeclKey { - fn name(&self) -> &[u8]; - fn input(&self) -> &Type; -} - -impl Hash for dyn DeclKey + '_ { - fn hash(&self, state: &mut H) { - self.name().hash(state); - self.input().hash(state); - } -} - -impl PartialEq for dyn DeclKey + '_ { - fn eq(&self, other: &Self) -> bool { - self.name() == other.name() && self.input() == other.input() - } -} - -impl Eq for dyn DeclKey + '_ {} - -impl<'a> DeclKey for (&'a [u8], &Type) { - fn name(&self) -> &[u8] { - self.0 - } - - fn input(&self) -> &Type { - self.1 - } -} - -impl DeclKey for (Vec, Type) { - fn name(&self) -> &[u8] { - &self.0 - } - - fn input(&self) -> &Type { - &self.1 - } -} - -impl<'a> Borrow for (Vec, Type) { - fn borrow(&self) -> &(dyn DeclKey + 'a) { - self + pub fn get_decl(&self, name: &[u8]) -> Option { + self.decls.get(name).cloned() } }