@@ -65,7 +65,7 @@ use serde::Deserialize;
6565
6666use oxc_allocator:: { TakeIn , Vec as ArenaVec } ;
6767use oxc_ast:: { AstBuilder , NONE , ast:: * } ;
68- use oxc_data_structures:: inline_string:: InlineString ;
68+ use oxc_data_structures:: { assert_unchecked , inline_string:: InlineString } ;
6969use oxc_semantic:: SymbolId ;
7070use oxc_span:: SPAN ;
7171use oxc_traverse:: { Ancestor , Traverse } ;
@@ -1093,11 +1093,26 @@ fn minify_template_literal<'a>(lit: &mut TemplateLiteral<'a>, ast: AstBuilder<'a
10931093 let output_str = unsafe { std:: str:: from_utf8_unchecked ( & output) } ;
10941094 quasis. last_mut ( ) . unwrap ( ) . value . raw = ast. atom ( output_str) ;
10951095
1096- // Remove quasis that are marked for removal, and the expressions following them
1096+ // Remove quasis that are marked for removal, and the expressions following them.
1097+ // TODO: Remove scopes, symbols, and references for removed `Expression`s.
10971098 if delete_some {
1099+ // We assert the lengths of `quasis` and `expressions` here so that we can safely remove
1100+ // the bounds check in the `retain` loop.
1101+ // It should always be true that `quasis.len() == expressions.len() + 1`
1102+ // but `quasis.len() >= expressions.len()` is all we need to ensure safety of `assert_unchecked!`
1103+ // below, and it's a cheaper check.
1104+ assert ! ( quasis. len( ) >= expressions. len( ) ) ;
1105+
10981106 let mut quasis_iter = quasis. iter ( ) ;
1099- // TODO: Remove scopes, symbols, and references for removed `Expression`.
1100- expressions. retain ( |_| quasis_iter. next ( ) . unwrap ( ) . span != REMOVE_SENTINEL ) ;
1107+ expressions. retain ( |_| {
1108+ // This unchecked assertion removes bounds check in `unwrap`.
1109+ // SAFETY: We asserted above that there are at least as many quasis as expressions,
1110+ // so `quasis_iter` cannot be exhausted in this loop.
1111+ unsafe { assert_unchecked ! ( !quasis_iter. as_slice( ) . is_empty( ) ) } ;
1112+ let quasi = quasis_iter. next ( ) . unwrap ( ) ;
1113+ quasi. span != REMOVE_SENTINEL
1114+ } ) ;
1115+
11011116 quasis. retain ( |quasi| quasi. span != REMOVE_SENTINEL ) ;
11021117 }
11031118}
0 commit comments