diff --git a/src/ast.rs b/src/ast.rs index f1a84b3f7..3e47cb750 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -64,13 +64,13 @@ trait NodeVisitorMut { fn visit_argument_or_redirection( &mut self, - _node: &mut Box, + _node: &mut ArgumentOrRedirectionVariant, ) -> VisitResult; fn visit_block_statement_header( &mut self, - _node: &mut Box, + _node: &mut BlockStatementHeaderVariant, ) -> VisitResult; - fn visit_statement(&mut self, _node: &mut Box) -> VisitResult; + fn visit_statement(&mut self, _node: &mut StatementVariant) -> VisitResult; fn visit_decorated_statement_decorator( &mut self, @@ -858,10 +858,10 @@ macro_rules! visit_1_field_impl { ( $visit:ident, $field:expr, - (Box<$field_type:ident>), + (variant<$field_type:ident>), $visitor:ident ) => { - visit_union_field!($visit, $field_type, $field, $visitor) + visit_variant_field!($visit, $field_type, $field, $visitor) }; ( $visit:ident, @@ -890,7 +890,7 @@ macro_rules! apply_borrow { }; } -macro_rules! visit_union_field { +macro_rules! visit_variant_field { ( visit, $field_type:ident, @@ -905,11 +905,11 @@ macro_rules! visit_union_field { $field:expr, $visitor:ident ) => { - visit_union_field_mut!($field_type, $visitor, $field) + visit_variant_field_mut!($field_type, $visitor, $field) }; } -macro_rules! visit_union_field_mut { +macro_rules! visit_variant_field_mut { (ArgumentOrRedirectionVariant, $visitor:ident, $field:expr) => { $visitor.visit_argument_or_redirection(&mut $field) }; @@ -978,7 +978,7 @@ macro_rules! set_parent_of_field { ( $self:ident, $field_name:ident, - (Box<$field_type:ident>) + (variant<$field_type:ident>) ) => { set_parent_of_union_field!($self, $field_name, $field_type); }; @@ -1008,10 +1008,7 @@ macro_rules! set_parent_of_union_field { $field_name:ident, ArgumentOrRedirectionVariant ) => { - if matches!( - *$self.$field_name, - ArgumentOrRedirectionVariant::Argument(_) - ) { + if matches!($self.$field_name, ArgumentOrRedirectionVariant::Argument(_)) { $self.$field_name.as_mut_argument().parent = Some($self); $self.$field_name.as_mut_argument().set_parents(); } else { @@ -1024,19 +1021,19 @@ macro_rules! set_parent_of_union_field { $field_name:ident, StatementVariant ) => { - if matches!(*$self.$field_name, StatementVariant::NotStatement(_)) { + if matches!($self.$field_name, StatementVariant::NotStatement(_)) { $self.$field_name.as_mut_not_statement().parent = Some($self); $self.$field_name.as_mut_not_statement().set_parents(); - } else if matches!(*$self.$field_name, StatementVariant::BlockStatement(_)) { + } else if matches!($self.$field_name, StatementVariant::BlockStatement(_)) { $self.$field_name.as_mut_block_statement().parent = Some($self); $self.$field_name.as_mut_block_statement().set_parents(); - } else if matches!(*$self.$field_name, StatementVariant::IfStatement(_)) { + } else if matches!($self.$field_name, StatementVariant::IfStatement(_)) { $self.$field_name.as_mut_if_statement().parent = Some($self); $self.$field_name.as_mut_if_statement().set_parents(); - } else if matches!(*$self.$field_name, StatementVariant::SwitchStatement(_)) { + } else if matches!($self.$field_name, StatementVariant::SwitchStatement(_)) { $self.$field_name.as_mut_switch_statement().parent = Some($self); $self.$field_name.as_mut_switch_statement().set_parents(); - } else if matches!(*$self.$field_name, StatementVariant::DecoratedStatement(_)) { + } else if matches!($self.$field_name, StatementVariant::DecoratedStatement(_)) { $self.$field_name.as_mut_decorated_statement().parent = Some($self); $self.$field_name.as_mut_decorated_statement().set_parents(); } @@ -1046,26 +1043,23 @@ macro_rules! set_parent_of_union_field { $field_name:ident, BlockStatementHeaderVariant ) => { - if matches!( - *$self.$field_name, - BlockStatementHeaderVariant::ForHeader(_) - ) { + if matches!($self.$field_name, BlockStatementHeaderVariant::ForHeader(_)) { $self.$field_name.as_mut_for_header().parent = Some($self); $self.$field_name.as_mut_for_header().set_parents(); } else if matches!( - *$self.$field_name, + $self.$field_name, BlockStatementHeaderVariant::WhileHeader(_) ) { $self.$field_name.as_mut_while_header().parent = Some($self); $self.$field_name.as_mut_while_header().set_parents(); } else if matches!( - *$self.$field_name, + $self.$field_name, BlockStatementHeaderVariant::FunctionHeader(_) ) { $self.$field_name.as_mut_function_header().parent = Some($self); $self.$field_name.as_mut_function_header().set_parents(); } else if matches!( - *$self.$field_name, + $self.$field_name, BlockStatementHeaderVariant::BeginHeader(_) ) { $self.$field_name.as_mut_begin_header().parent = Some($self); @@ -1120,12 +1114,12 @@ fn as_mut_variable_assignment_list(&mut self) -> Option<&mut VariableAssignmentL #[derive(Default, Debug)] pub struct ArgumentOrRedirection { parent: Option<*const dyn Node>, - pub contents: Box, + pub contents: ArgumentOrRedirectionVariant, } implement_node!(ArgumentOrRedirection, branch, argument_or_redirection); implement_acceptor_for_branch!( ArgumentOrRedirection, - (contents: (Box)) + (contents: (variant)) ); impl ConcreteNode for ArgumentOrRedirection { fn as_argument_or_redirection(&self) -> Option<&ArgumentOrRedirection> { @@ -1164,10 +1158,10 @@ fn as_mut_argument_or_redirection_list(&mut self) -> Option<&mut ArgumentOrRedir #[derive(Default, Debug)] pub struct Statement { parent: Option<*const dyn Node>, - pub contents: Box, + pub contents: StatementVariant, } implement_node!(Statement, branch, statement); -implement_acceptor_for_branch!(Statement, (contents: (Box))); +implement_acceptor_for_branch!(Statement, (contents: (variant))); impl ConcreteNode for Statement { fn as_statement(&self) -> Option<&Statement> { Some(self) @@ -1377,7 +1371,7 @@ fn as_mut_begin_header(&mut self) -> Option<&mut BeginHeader> { pub struct BlockStatement { parent: Option<*const dyn Node>, /// A header like for, while, etc. - pub header: Box, + pub header: BlockStatementHeaderVariant, /// List of jobs in this block. pub jobs: JobList, /// The 'end' node. @@ -1388,7 +1382,7 @@ pub struct BlockStatement { implement_node!(BlockStatement, branch, block_statement); implement_acceptor_for_branch!( BlockStatement, - (header: (Box)), + (header: (variant)), (jobs: (JobList)), (end: (KeywordEnd)), (args_or_redirs: (ArgumentOrRedirectionList)), @@ -2105,17 +2099,17 @@ fn as_mut_redirection(&mut self) -> &mut Redirection { impl ArgumentOrRedirection { /// Return whether this represents an argument. pub fn is_argument(&self) -> bool { - matches!(*self.contents, ArgumentOrRedirectionVariant::Argument(_)) + matches!(self.contents, ArgumentOrRedirectionVariant::Argument(_)) } /// Return whether this represents a redirection pub fn is_redirection(&self) -> bool { - matches!(*self.contents, ArgumentOrRedirectionVariant::Redirection(_)) + matches!(self.contents, ArgumentOrRedirectionVariant::Redirection(_)) } /// Return this as an argument, assuming it wraps one. pub fn argument(&self) -> &Argument { - match *self.contents { + match self.contents { ArgumentOrRedirectionVariant::Argument(ref arg) => arg, _ => panic!("Is not an argument"), } @@ -2123,7 +2117,7 @@ pub fn argument(&self) -> &Argument { /// Return this as an argument, assuming it wraps one. pub fn redirection(&self) -> &Redirection { - match *self.contents { + match self.contents { ArgumentOrRedirectionVariant::Redirection(ref arg) => arg, _ => panic!("Is not a redirection"), } @@ -2133,11 +2127,10 @@ pub fn redirection(&self) -> &Redirection { #[derive(Debug)] pub enum StatementVariant { None, - NotStatement(NotStatement), - BlockStatement(BlockStatement), - // IfStatement is much larger than the rest, so we box it. + NotStatement(Box), + BlockStatement(Box), IfStatement(Box), - SwitchStatement(SwitchStatement), + SwitchStatement(Box), DecoratedStatement(DecoratedStatement), } @@ -2214,10 +2207,10 @@ pub fn as_decorated_statement(&self) -> Option<&DecoratedStatement> { fn embedded_node(&self) -> &dyn NodeMut { match self { StatementVariant::None => panic!("cannot visit null statement"), - StatementVariant::NotStatement(node) => node, - StatementVariant::BlockStatement(node) => node, + StatementVariant::NotStatement(node) => &**node, + StatementVariant::BlockStatement(node) => &**node, StatementVariant::IfStatement(node) => &**node, - StatementVariant::SwitchStatement(node) => node, + StatementVariant::SwitchStatement(node) => &**node, StatementVariant::DecoratedStatement(node) => node, } } @@ -2999,12 +2992,12 @@ fn did_visit_fields_of<'a>(&'a mut self, node: &'a dyn NodeMut, flow: VisitResul // Handle them directly. fn visit_argument_or_redirection( &mut self, - node: &mut Box, + node: &mut ArgumentOrRedirectionVariant, ) -> VisitResult { if let Some(arg) = self.try_parse::() { - **node = ArgumentOrRedirectionVariant::Argument(*arg); + *node = ArgumentOrRedirectionVariant::Argument(*arg); } else if let Some(redir) = self.try_parse::() { - **node = ArgumentOrRedirectionVariant::Redirection(*redir); + *node = ArgumentOrRedirectionVariant::Redirection(*redir); } else { internal_error!( self, @@ -3016,12 +3009,12 @@ fn visit_argument_or_redirection( } fn visit_block_statement_header( &mut self, - node: &mut Box, + node: &mut BlockStatementHeaderVariant, ) -> VisitResult { *node = self.allocate_populate_block_header(); VisitResult::Continue(()) } - fn visit_statement(&mut self, node: &mut Box) -> VisitResult { + fn visit_statement(&mut self, node: &mut StatementVariant) -> VisitResult { *node = self.allocate_populate_statement_contents(); VisitResult::Continue(()) } @@ -3537,17 +3530,17 @@ fn populate_list(&mut self, list: &mut ListType, exhaust_stream: /// Allocate and populate a statement contents pointer. /// This must never return null. - fn allocate_populate_statement_contents(&mut self) -> Box { + fn allocate_populate_statement_contents(&mut self) -> StatementVariant { // In case we get a parse error, we still need to return something non-null. Use a // decorated statement; all of its leaf nodes will end up unsourced. - fn got_error(slf: &mut Populator<'_>) -> Box { + fn got_error(slf: &mut Populator<'_>) -> StatementVariant { assert!(slf.unwinding, "Should have produced an error"); new_decorated_statement(slf) } - fn new_decorated_statement(slf: &mut Populator<'_>) -> Box { + fn new_decorated_statement(slf: &mut Populator<'_>) -> StatementVariant { let embedded = slf.allocate_visit::(); - Box::new(StatementVariant::DecoratedStatement(*embedded)) + StatementVariant::DecoratedStatement(*embedded) } if self.peek_token(0).typ == ParseTokenType::terminate && self.allow_incomplete() { @@ -3626,22 +3619,22 @@ fn new_decorated_statement(slf: &mut Populator<'_>) -> Box { match self.peek_token(0).keyword { ParseKeyword::kw_not | ParseKeyword::kw_exclam => { let embedded = self.allocate_visit::(); - Box::new(StatementVariant::NotStatement(*embedded)) + StatementVariant::NotStatement(embedded) } ParseKeyword::kw_for | ParseKeyword::kw_while | ParseKeyword::kw_function | ParseKeyword::kw_begin => { let embedded = self.allocate_visit::(); - Box::new(StatementVariant::BlockStatement(*embedded)) + StatementVariant::BlockStatement(embedded) } ParseKeyword::kw_if => { let embedded = self.allocate_visit::(); - Box::new(StatementVariant::IfStatement(embedded)) + StatementVariant::IfStatement(embedded) } ParseKeyword::kw_switch => { let embedded = self.allocate_visit::(); - Box::new(StatementVariant::SwitchStatement(*embedded)) + StatementVariant::SwitchStatement(embedded) } ParseKeyword::kw_end => { // 'end' is forbidden as a command. @@ -3663,8 +3656,8 @@ fn new_decorated_statement(slf: &mut Populator<'_>) -> Box { /// Allocate and populate a block statement header. /// This must never return null. - fn allocate_populate_block_header(&mut self) -> Box { - Box::new(match self.peek_token(0).keyword { + fn allocate_populate_block_header(&mut self) -> BlockStatementHeaderVariant { + match self.peek_token(0).keyword { ParseKeyword::kw_for => { let embedded = self.allocate_visit::(); BlockStatementHeaderVariant::ForHeader(*embedded) @@ -3688,7 +3681,7 @@ fn allocate_populate_block_header(&mut self) -> Box "should not have descended into block_header" ); } - }) + } } fn try_parse(&mut self) -> Option> { diff --git a/src/highlight/highlight.rs b/src/highlight/highlight.rs index c7196a60c..f6ef4fac5 100644 --- a/src/highlight/highlight.rs +++ b/src/highlight/highlight.rs @@ -1046,7 +1046,7 @@ fn visit_decorated_statement(&mut self, stmt: &DecoratedStatement) { } } fn visit_block_statement(&mut self, block: &BlockStatement) { - match &*block.header { + match &block.header { BlockStatementHeaderVariant::None => panic!(), BlockStatementHeaderVariant::ForHeader(node) => self.visit(node), BlockStatementHeaderVariant::WhileHeader(node) => self.visit(node), diff --git a/src/parse_execution.rs b/src/parse_execution.rs index 28ea79906..aaab62bdb 100644 --- a/src/parse_execution.rs +++ b/src/parse_execution.rs @@ -157,8 +157,7 @@ fn eval_statement( associated_block: Option, ) -> EndExecutionReason { // Note we only expect block-style statements here. No not statements. - let contents = &statement.contents; - match &**contents { + match &statement.contents { StatementVariant::BlockStatement(block) => { self.run_block_statement(ctx, block, associated_block) } @@ -423,7 +422,7 @@ fn infinite_recursive_statement_in_job_list<'b>( // Helper to return if a statement is infinitely recursive in this function. let statement_recurses = |stat: &'b ast::Statement| -> Option<&'b ast::DecoratedStatement> { // Ignore non-decorated statements like `if`, etc. - let StatementVariant::DecoratedStatement(dc) = &*stat.contents else { + let StatementVariant::DecoratedStatement(dc) = &stat.contents else { return None; }; @@ -564,7 +563,7 @@ fn job_is_simple_block(&self, job: &ast::JobPipeline) -> bool { // Check if we're a block statement with redirections. We do it this obnoxious way to preserve // type safety (in case we add more specific statement types). - match &*job.statement.contents { + match &job.statement.contents { StatementVariant::BlockStatement(stmt) => no_redirs(&stmt.args_or_redirs), StatementVariant::SwitchStatement(stmt) => no_redirs(&stmt.args_or_redirs), StatementVariant::IfStatement(stmt) => no_redirs(&stmt.args_or_redirs), @@ -680,7 +679,7 @@ fn populate_job_process( return result; } - match &**specific_statement { + match &specific_statement { StatementVariant::NotStatement(not_statement) => { self.populate_not_process(ctx, job, proc, not_statement) } @@ -874,7 +873,7 @@ fn run_block_statement( ) -> EndExecutionReason { let bh = &statement.header; let contents = &statement.jobs; - match &**bh { + match bh { BlockStatementHeaderVariant::ForHeader(fh) => self.run_for_statement(ctx, fh, contents), BlockStatementHeaderVariant::WhileHeader(wh) => { self.run_while_statement(ctx, wh, contents, associated_block) @@ -1586,7 +1585,7 @@ fn run_1_job( specific_statement )); if result == EndExecutionReason::ok { - result = match &**specific_statement { + result = match &specific_statement { StatementVariant::BlockStatement(block_statement) => { self.run_block_statement(ctx, block_statement, associated_block) } @@ -1942,7 +1941,7 @@ fn profiling_cmd_name_for_redirectable_block( let src_end = match node { StatementVariant::BlockStatement(block_statement) => { let block_header = &block_statement.header; - match &**block_header { + match block_header { BlockStatementHeaderVariant::ForHeader(for_header) => { for_header.semi_nl.source_range().start() } @@ -1993,7 +1992,7 @@ fn job_node_wants_timing(job_node: &ast::JobPipeline) -> bool { // Helper to return true if a node is 'not time ...' or 'not not time...' or... let is_timed_not_statement = |mut stat: &ast::Statement| loop { - match &*stat.contents { + match &stat.contents { StatementVariant::NotStatement(ns) => { if ns.time.is_some() { return true;