@@ -23,10 +23,10 @@ impl<'a, 'b> PeepholeOptimizations {
23
23
stmts : & mut Vec < ' a , Statement < ' a > > ,
24
24
ctx : Ctx < ' a , ' _ > ,
25
25
) {
26
+ self . dead_code_elimination ( stmts, ctx) ;
26
27
if stmts. iter ( ) . any ( |stmt| matches ! ( stmt, Statement :: EmptyStatement ( _) ) ) {
27
28
stmts. retain ( |stmt| !matches ! ( stmt, Statement :: EmptyStatement ( _) ) ) ;
28
29
}
29
- self . dead_code_elimination ( stmts, ctx) ;
30
30
}
31
31
32
32
pub fn remove_dead_code_exit_statement ( & mut self , stmt : & mut Statement < ' a > , ctx : Ctx < ' a , ' _ > ) {
@@ -68,20 +68,19 @@ impl<'a, 'b> PeepholeOptimizations {
68
68
}
69
69
}
70
70
71
- /// Removes dead code thats comes after `return` statements after inlining `if ` statements
71
+ /// Removes dead code thats comes after `return`, `throw`, `continue` and `break ` statements.
72
72
fn dead_code_elimination ( & mut self , stmts : & mut Vec < ' a , Statement < ' a > > , ctx : Ctx < ' a , ' b > ) {
73
73
// Remove code after `return` and `throw` statements
74
74
let mut index = None ;
75
75
' outer: for ( i, stmt) in stmts. iter ( ) . enumerate ( ) {
76
- if matches ! ( stmt , Statement :: ReturnStatement ( _ ) | Statement :: ThrowStatement ( _ ) ) {
76
+ if Self :: is_unreachable_statement ( stmt ) {
77
77
index. replace ( i) ;
78
78
break ;
79
79
}
80
80
// Double check block statements folded by if statements above
81
81
if let Statement :: BlockStatement ( block_stmt) = stmt {
82
82
for stmt in & block_stmt. body {
83
- if matches ! ( stmt, Statement :: ReturnStatement ( _) | Statement :: ThrowStatement ( _) )
84
- {
83
+ if Self :: is_unreachable_statement ( stmt) {
85
84
index. replace ( i) ;
86
85
break ' outer;
87
86
}
@@ -129,6 +128,16 @@ impl<'a, 'b> PeepholeOptimizations {
129
128
}
130
129
}
131
130
131
+ fn is_unreachable_statement ( stmt : & Statement < ' a > ) -> bool {
132
+ matches ! (
133
+ stmt,
134
+ Statement :: ReturnStatement ( _)
135
+ | Statement :: ThrowStatement ( _)
136
+ | Statement :: BreakStatement ( _)
137
+ | Statement :: ContinueStatement ( _)
138
+ )
139
+ }
140
+
132
141
/// Remove block from single line blocks
133
142
/// `{ block } -> block`
134
143
fn try_optimize_block (
@@ -915,4 +924,12 @@ mod test {
915
924
test ( "foo(...[])" , "foo()" ) ;
916
925
test ( "new Foo(...[])" , "new Foo()" ) ;
917
926
}
927
+
928
+ #[ test]
929
+ fn remove_unreachable ( ) {
930
+ test ( "while(true) { break a; unreachable;}" , "for(;;) break a" ) ;
931
+ test ( "while(true) { continue a; unreachable;}" , "for(;;) continue a" ) ;
932
+ test ( "while(true) { throw a; unreachable;}" , "for(;;) throw a" ) ;
933
+ test ( "while(true) { return a; unreachable;}" , "for(;;) return a" ) ;
934
+ }
918
935
}
0 commit comments