diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 3ec16433..137d5214 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -469,7 +469,10 @@ impl fmt::Debug for Expr { Self::Dot(_, _, _) => "Dot", Self::And(_, _) => "And", Self::Or(_, _) => "Or", - _ => unreachable!(), + expr => unreachable!( + "Self::Dot or Self::And or Self::Or expected but gets {:?}", + expr + ), }; display_pos = *pos; diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index c90d405e..cda7bad5 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -480,7 +480,11 @@ impl Stmt { match self { Self::Var(_, _, _, _) => true, - Self::FnCall(x, _) if x.name == KEYWORD_EVAL => true, + Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_block_dependent), + + Self::FnCall(x, _) | Self::Expr(Expr::FnCall(x, _)) => { + x.namespace.is_none() && x.name == KEYWORD_EVAL + } #[cfg(not(feature = "no_module"))] Self::Import(_, _, _) | Self::Export(_, _) => true, @@ -500,6 +504,8 @@ impl Stmt { match self { Self::Var(expr, _, _, _) => expr.is_pure(), + Self::Expr(Expr::Stmt(s)) => s.iter().all(Stmt::is_internally_pure), + #[cfg(not(feature = "no_module"))] Self::Import(expr, _, _) => expr.is_pure(), #[cfg(not(feature = "no_module"))] diff --git a/src/engine.rs b/src/engine.rs index 4a8424f4..fd4104f8 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -129,7 +129,7 @@ impl ChainArgument { Self::MethodCallArgs(Some(mut values), pos) => { (values.iter_mut().map(std::mem::take).collect(), pos) } - _ => unreachable!("`MethodCallArgs` expected"), + x => unreachable!("ChainArgument::MethodCallArgs expected but gets {:?}", x), } } /// Return the [position][Position]. @@ -174,7 +174,7 @@ fn match_chaining_type(expr: &Expr) -> ChainType { Expr::Index(_, _, _) => ChainType::Indexing, #[cfg(not(feature = "no_object"))] Expr::Dot(_, _, _) => ChainType::Dotting, - _ => unreachable!("`expr` should only be `Index` or `Dot`, but got {:?}", expr), + expr => unreachable!("Expr::Index or Expr::Dot expected but gets {:?}", expr), } } @@ -1226,7 +1226,7 @@ impl Engine { #[cfg(feature = "no_module")] (_, Some((_, _)), _) => unreachable!("qualified access under no_module"), }, - _ => unreachable!("Expr::Variable expected, but gets {:?}", expr), + _ => unreachable!("Expr::Variable expected but gets {:?}", expr), } } @@ -1258,7 +1258,7 @@ impl Engine { _ if state.always_search_scope => (0, expr.position()), Expr::Variable(Some(i), pos, _) => (i.get() as usize, *pos), Expr::Variable(None, pos, v) => (v.0.map(NonZeroUsize::get).unwrap_or(0), *pos), - _ => unreachable!("Expr::Variable expected, but gets {:?}", expr), + _ => unreachable!("Expr::Variable expected but gets {:?}", expr), }; // Check the variable resolver, if any @@ -1774,7 +1774,7 @@ impl Engine { Expr::Index(x, term, pos) => (x.as_ref(), ChainType::Indexing, *term, *pos), #[cfg(not(feature = "no_object"))] Expr::Dot(x, term, pos) => (x.as_ref(), ChainType::Dotting, *term, *pos), - _ => unreachable!("index or dot chain expected, but gets {:?}", expr), + expr => unreachable!("Expr::Index or Expr::Dot expected but gets {:?}", expr), }; let idx_values = &mut StaticVec::new_const(); @@ -2123,7 +2123,7 @@ impl Engine { ) } } else { - unreachable!("`Range` or `RangeInclusive`"); + unreachable!("Range or RangeInclusive expected but gets {:?}", idx); }; let field_value = (*value & mask) >> shift; @@ -2655,7 +2655,7 @@ impl Engine { match lhs_expr { // name op= rhs (handled above) Expr::Variable(_, _, _) => { - unreachable!("Expr::Variable case should already been handled") + unreachable!("Expr::Variable case is already handled") } // idx_lhs[idx_expr] op= rhs #[cfg(not(feature = "no_index"))] diff --git a/src/module/mod.rs b/src/module/mod.rs index a182574e..0662e483 100644 --- a/src/module/mod.rs +++ b/src/module/mod.rs @@ -1334,7 +1334,7 @@ impl Module { self.all_type_iterators.clear(); self.indexed = false; self.contains_indexed_global_functions = false; - self.interner.merge(&other.interner); + self.interner += &other.interner; self } @@ -1384,7 +1384,7 @@ impl Module { self.all_type_iterators.clear(); self.indexed = false; self.contains_indexed_global_functions = false; - self.interner.merge(&other.interner); + self.interner += &other.interner; self } diff --git a/src/optimizer.rs b/src/optimizer.rs index fb3c7cd4..64d3037d 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -199,7 +199,7 @@ fn optimize_stmt_block( let stmt = mem::take(&mut second[0]); let mut stmts = match stmt { Stmt::Block(block, _) => block, - _ => unreachable!("Stmt::Block expected but gets {:?}", stmt), + stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), }; statements = first .iter_mut() diff --git a/src/packages/array_basic.rs b/src/packages/array_basic.rs index 7e61dce8..6c07f94d 100644 --- a/src/packages/array_basic.rs +++ b/src/packages/array_basic.rs @@ -771,7 +771,7 @@ pub mod array_functions { v if v > 0 => Ordering::Greater, v if v < 0 => Ordering::Less, 0 => Ordering::Equal, - _ => unreachable!(), + _ => unreachable!("v is {}", v), }) .unwrap_or_else(|| x.type_id().cmp(&y.type_id())) }); diff --git a/src/parser.rs b/src/parser.rs index 46d1a742..627a750c 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -349,7 +349,7 @@ fn eat_token(input: &mut TokenStream, expected_token: Token) -> Position { if t != expected_token { unreachable!( - "expecting {} (found {}) at {}", + "{} expected but gets {} at {}", expected_token.syntax(), t.syntax(), pos @@ -1098,7 +1098,7 @@ fn parse_switch( None } (None, None) => Some(stmt.into()), - _ => unreachable!("both hash and range in `switch` statement case"), + _ => unreachable!("both hash and range in switch statement case"), }; match input.peek().expect(NEVER_ENDS) { @@ -1163,7 +1163,7 @@ fn parse_primary( } Token::True => Expr::BoolConstant(true, settings.pos), Token::False => Expr::BoolConstant(false, settings.pos), - _ => unreachable!(), + token => unreachable!("token is {:?}", token), }, #[cfg(not(feature = "no_float"))] Token::FloatConstant(x) => { @@ -1182,7 +1182,7 @@ fn parse_primary( Token::LeftBrace if settings.allow_stmt_expr => { match parse_block(input, state, lib, settings.level_up())? { block @ Stmt::Block(_, _) => Expr::Stmt(Box::new(block.into())), - stmt => unreachable!("expecting Stmt::Block, but gets {:?}", stmt), + stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), } } // ( - grouped expression @@ -1253,16 +1253,17 @@ fn parse_primary( Token::InterpolatedString(_) => { let mut segments = StaticVec::::new(); - if let (Token::InterpolatedString(s), pos) = input.next().expect(NEVER_ENDS) { - segments.push(Expr::StringConstant(s.into(), pos)); - } else { - unreachable!(); + match input.next().expect(NEVER_ENDS) { + (Token::InterpolatedString(s), pos) => { + segments.push(Expr::StringConstant(s.into(), pos)); + } + token => unreachable!("Token::InterpolatedString expected but gets {:?}", token), } loop { let expr = match parse_block(input, state, lib, settings.level_up())? { block @ Stmt::Block(_, _) => Expr::Stmt(Box::new(block.into())), - stmt => unreachable!("expecting Stmt::Block, but gets {:?}", stmt), + stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), }; segments.push(expr); @@ -1288,7 +1289,7 @@ fn parse_primary( return Err(err.into_err(pos)) } (token, _) => unreachable!( - "expected a string within an interpolated string literal, but gets {:?}", + "string within an interpolated string literal expected but gets {:?}", token ), } @@ -1324,7 +1325,7 @@ fn parse_primary( Token::Identifier(_) => { let s = match input.next().expect(NEVER_ENDS) { (Token::Identifier(s), _) => s, - _ => unreachable!(), + token => unreachable!("Token::Identifier expected but gets {:?}", token), }; match input.peek().expect(NEVER_ENDS).0 { @@ -1383,7 +1384,7 @@ fn parse_primary( Token::Reserved(_) => { let s = match input.next().expect(NEVER_ENDS) { (Token::Reserved(s), _) => s, - _ => unreachable!(), + token => unreachable!("Token::Reserved expected but gets {:?}", token), }; match input.peek().expect(NEVER_ENDS).0 { @@ -1411,7 +1412,7 @@ fn parse_primary( Token::LexError(_) => match input.next().expect(NEVER_ENDS) { (Token::LexError(err), _) => return Err(err.into_err(settings.pos)), - _ => unreachable!(), + token => unreachable!("Token::LexError expected but gets {:?}", token), }, _ => { @@ -1694,12 +1695,12 @@ fn make_assignment_stmt( ref e => Some(e.position()), }, Expr::Index(x, term, _) | Expr::Dot(x, term, _) => match x.lhs { - Expr::Property(_) => unreachable!("unexpected `Expr::Property` in indexing"), + Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"), _ if !term => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))), _ => None, }, Expr::Property(_) if parent_is_dot => None, - Expr::Property(_) => unreachable!("unexpected `Expr::Property` in indexing"), + Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"), e if parent_is_dot => Some(e.position()), _ => None, } @@ -1838,7 +1839,7 @@ fn make_dot_expr( let (x, term, pos, is_dot) = match rhs { Expr::Dot(x, term, pos) => (x, term, pos, true), Expr::Index(x, term, pos) => (x, term, pos, false), - _ => unreachable!(), + expr => unreachable!("Expr::Dot or Expr::Index expected but gets {:?}", expr), }; match x.lhs { @@ -1877,7 +1878,7 @@ fn make_dot_expr( }; Ok(Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos)) } - _ => unreachable!("invalid dot expression: {:?}", x.lhs), + expr => unreachable!("invalid dot expression: {:?}", expr), } } // lhs.nnn::func(...) @@ -2162,7 +2163,7 @@ fn parse_custom_syntax( segments.push(keyword.clone().into()); tokens.push(keyword); } - stmt => unreachable!("expecting Stmt::Block, but gets {:?}", stmt), + stmt => unreachable!("Stmt::Block expected but gets {:?}", stmt), }, CUSTOM_SYNTAX_MARKER_BOOL => match input.next().expect(NEVER_ENDS) { (b @ Token::True, pos) | (b @ Token::False, pos) => { @@ -2338,7 +2339,7 @@ fn parse_while_loop( (expr, pos) } (Token::Loop, pos) => (Expr::Unit(Position::NONE), pos), - _ => unreachable!(), + token => unreachable!("Token::While or Token::Loop expected but gets {:?}", token), }; settings.pos = token_pos; settings.is_breakable = true; @@ -2789,7 +2790,7 @@ fn parse_stmt( } if !crate::tokenizer::is_doc_comment(comment) { - unreachable!("expecting doc-comment, but gets {:?}", comment); + unreachable!("doc-comment expected but gets {:?}", comment); } if !settings.is_global { @@ -2806,7 +2807,7 @@ fn parse_stmt( _ => return Err(PERR::WrongDocComment.into_err(comments_pos)), } } - _ => unreachable!(), + token => unreachable!("Token::Comment expected but gets {:?}", token), } } @@ -2933,14 +2934,15 @@ fn parse_stmt( let (return_type, token_pos) = input .next() .map(|(token, pos)| { - ( - match token { - Token::Return => AST_OPTION_NONE, - Token::Throw => AST_OPTION_BREAK_OUT, - _ => unreachable!(), - }, - pos, - ) + let flags = match token { + Token::Return => AST_OPTION_NONE, + Token::Throw => AST_OPTION_BREAK_OUT, + token => unreachable!( + "Token::Return or Token::Throw expected but gets {:?}", + token + ), + }; + (flags, pos) }) .expect(NEVER_ENDS); diff --git a/src/tokenizer.rs b/src/tokenizer.rs index 2a6d301f..9387bbee 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -250,7 +250,7 @@ impl fmt::Display for Position { #[cfg(not(feature = "no_position"))] write!(f, "line {}, position {}", self.line, self.pos)?; #[cfg(feature = "no_position")] - unreachable!(); + unreachable!("no position"); } Ok(()) @@ -285,7 +285,7 @@ impl Add for Position { }, }; #[cfg(feature = "no_position")] - unreachable!(); + unreachable!("no position"); } } } @@ -1159,7 +1159,7 @@ pub fn parse_string_literal( 'x' => 2, 'u' => 4, 'U' => 8, - _ => unreachable!(), + c => unreachable!("x or u or U expected but gets '{}'", c), }; for _ in 0..len { @@ -1506,14 +1506,14 @@ fn get_next_token_inner( 'x' | 'X' => is_hex_digit, 'o' | 'O' => is_numeric_digit, 'b' | 'B' => is_numeric_digit, - _ => unreachable!(), + c => unreachable!("x/X or o/O or b/B expected but gets '{}'", c), }; radix_base = Some(match ch { 'x' | 'X' => 16, 'o' | 'O' => 8, 'b' | 'B' => 2, - _ => unreachable!(), + c => unreachable!("x/X or o/O or b/B expected but gets '{}'", c), }); } @@ -2238,7 +2238,7 @@ impl<'a> Iterator for TokenIterator<'a> { (Token::Custom(token.syntax().into()), pos) } else { // Active standard keyword - should never be a custom keyword! - unreachable!("`{:?}` is an active keyword", token) + unreachable!("{:?} is an active keyword", token) } } // Disabled symbol diff --git a/src/types/dynamic.rs b/src/types/dynamic.rs index 09d24950..140903a8 100644 --- a/src/types/dynamic.rs +++ b/src/types/dynamic.rs @@ -9,6 +9,7 @@ use std::{ any::{type_name, Any, TypeId}, fmt, hash::{Hash, Hasher}, + mem, ops::{Deref, DerefMut}, str::FromStr, }; @@ -472,7 +473,7 @@ impl Hash for Dynamic { /// /// Panics if the [`Dynamic`] value contains an unrecognized trait object. fn hash(&self, state: &mut H) { - std::mem::discriminant(&self.0).hash(state); + mem::discriminant(&self.0).hash(state); match self.0 { Union::Unit(_, _, _) => ().hash(state), @@ -1614,21 +1615,19 @@ impl Dynamic { pub(crate) fn flatten_in_place(&mut self) -> &mut Self { match self.0 { #[cfg(not(feature = "no_closure"))] - Union::Shared(_, _, _) => match std::mem::take(self).0 { - Union::Shared(cell, _, _) => { - *self = crate::func::native::shared_try_take(cell).map_or_else( - #[cfg(not(feature = "sync"))] - |cell| cell.borrow().clone(), - #[cfg(feature = "sync")] - |cell| cell.read().unwrap().clone(), - #[cfg(not(feature = "sync"))] - |value| value.into_inner(), - #[cfg(feature = "sync")] - |value| value.into_inner().unwrap(), - ); - } - _ => unreachable!(), - }, + Union::Shared(ref mut cell, _, _) => { + let cell = mem::take(cell); + *self = crate::func::native::shared_try_take(cell).map_or_else( + #[cfg(not(feature = "sync"))] + |cell| cell.borrow().clone(), + #[cfg(feature = "sync")] + |cell| cell.read().unwrap().clone(), + #[cfg(not(feature = "sync"))] + |value| value.into_inner(), + #[cfg(feature = "sync")] + |value| value.into_inner().unwrap(), + ); + } _ => (), } self