@@ -645,29 +645,31 @@ impl<'a> PeepholeOptimizations {
645645 }
646646
647647 fn fold_object_spread ( & self , e : & mut ObjectExpression < ' a > , ctx : & mut Ctx < ' a , ' _ > ) {
648+ fn should_fold_spread_element < ' a > ( e : & Expression < ' a > , ctx : & mut Ctx < ' a , ' _ > ) -> bool {
649+ match e {
650+ Expression :: ArrayExpression ( o) if o. elements . is_empty ( ) => true ,
651+ Expression :: ArrowFunctionExpression ( _) | Expression :: FunctionExpression ( _) => true ,
652+ e if e. is_literal ( ) && !e. is_string_literal ( ) => true ,
653+ e if e. evaluate_value ( ctx) . is_some_and ( |v| !v. is_string ( ) )
654+ && !e. may_have_side_effects ( ctx) =>
655+ {
656+ true
657+ }
658+ _ => false ,
659+ }
660+ }
648661 let ( new_size, should_fold) =
649662 e. properties . iter ( ) . fold ( ( 0 , false ) , |( new_size, should_fold) , p| {
650663 let ObjectPropertyKind :: SpreadProperty ( spread_element) = p else {
651664 return ( new_size + 1 , should_fold) ;
652665 } ;
653- let e = & spread_element. argument ;
654- if ctx. is_expression_undefined ( e) {
655- return ( new_size, true ) ;
656- }
657- match e {
658- Expression :: BooleanLiteral ( _)
659- | Expression :: NullLiteral ( _)
660- | Expression :: NumericLiteral ( _)
661- | Expression :: BigIntLiteral ( _)
662- | Expression :: RegExpLiteral ( _)
663- | Expression :: ArrowFunctionExpression ( _)
664- | Expression :: FunctionExpression ( _) => ( new_size, true ) ,
666+ match & spread_element. argument {
665667 Expression :: ObjectExpression ( o)
666668 if Self :: is_spread_inlineable_object_literal ( o, ctx) =>
667669 {
668670 ( new_size + o. properties . len ( ) , true )
669671 }
670- Expression :: ArrayExpression ( o ) if o . elements . is_empty ( ) => ( new_size, true ) ,
672+ e if should_fold_spread_element ( e , ctx ) => ( new_size, true ) ,
671673 _ => ( new_size + 1 , should_fold) ,
672674 }
673675 } ) ;
@@ -683,15 +685,6 @@ impl<'a> PeepholeOptimizations {
683685 continue ;
684686 }
685687 match e {
686- Expression :: BooleanLiteral ( _)
687- | Expression :: NullLiteral ( _)
688- | Expression :: NumericLiteral ( _)
689- | Expression :: BigIntLiteral ( _)
690- | Expression :: RegExpLiteral ( _)
691- | Expression :: ArrowFunctionExpression ( _)
692- | Expression :: FunctionExpression ( _) => {
693- // skip
694- }
695688 Expression :: ObjectExpression ( o)
696689 if Self :: is_spread_inlineable_object_literal ( o, ctx) =>
697690 {
@@ -707,8 +700,8 @@ impl<'a> PeepholeOptimizations {
707700 }
708701 } ) ) ;
709702 }
710- Expression :: ArrayExpression ( o ) if o . elements . is_empty ( ) => {
711- // skip empty array
703+ e if should_fold_spread_element ( e , ctx ) => {
704+ // skip
712705 }
713706 _ => {
714707 new_properties. push ( ObjectPropertyKind :: SpreadProperty ( spread_element) ) ;
@@ -2123,6 +2116,8 @@ mod test {
21232116 fold ( "({ z, ...void 0 })" , result) ;
21242117 fold ( "({ z, ...null })" , result) ;
21252118 fold ( "({ z, ...true })" , result) ;
2119+ fold ( "({ z, ...!0 })" , result) ;
2120+ fold ( "({ z, ...!1 })" , result) ;
21262121 fold ( "({ z, ...1 })" , result) ;
21272122 fold ( "({ z, ...1n })" , result) ;
21282123 fold ( "({ z, .../asdf/ })" , result) ;
0 commit comments