Repository: swc-project/swc (rust)

Issue:
Panic when compiling expression `[1, 2].slice(1, undefined)`
### Describe the bug

When compiling the expression `[1, 2].slice(1, undefined)`, which is taken from Ext.js, SWC panics with the following output:
```
Panic: PanicInfo { payload: Any { .. }, message: Some(slice index starts at 1 but ends at 0), location: Location { file: "/rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/alloc/src/vec/mod.rs", line: 1993, col: 36 }, can_unwind: true }
Backtrace:    0: <unknown>
   1: <unknown>
   2: _napi_register_module_v1
   3: _napi_register_module_v1
   4: _napi_register_module_v1
   5: _napi_register_module_v1
   6: _wasmer_vm_imported_memory32_atomic_notify
   7: _wasmer_vm_imported_memory32_atomic_notify
   8: _napi_register_module_v1
   9: _napi_register_module_v1
  10: _napi_register_module_v1
  11: _napi_register_module_v1
  12: _napi_register_module_v1
  13: _napi_register_module_v1
  14: _napi_register_module_v1
  15: _napi_register_module_v1
  16: _napi_register_module_v1
  17: <unknown>
  18: __ZN6v8impl12_GLOBAL__N_123FunctionCallbackWrapper6InvokeERKN2v820FunctionCallbackInfoINS2_5ValueEEE
  19: __ZN2v88internal25FunctionCallbackArguments4CallENS0_15CallHandlerInfoE
  20: __ZN2v88internal12_GLOBAL__N_119HandleApiCallHelperILb0EEENS0_11MaybeHandleINS0_6ObjectEEEPNS0_7IsolateENS0_6HandleINS0_10HeapObjectEEENS8_INS0_20FunctionTemplateInfoEEENS8_IS4_EEPmi
  21: __ZN2v88internal21Builtin_HandleApiCallEiPmPNS0_7IsolateE

failed to handle: slice index starts at 1 but ends at 0
Error: Failed to compile 1 file with swc.
    at Object.assertCompilationResult (/SwcBug/node_modules/@swc/cli/lib/swc/util.js:149:15)
    at files (/SwcBug/node_modules/@swc/cli/lib/swc/file.js:201:19)
    at async _default (/SwcBug/node_modules/@swc/cli/lib/swc/file.js:220:9)
```

Unfortunately, that stack trace is not very helpful... However, I was able to get a much more useful one by running `RUST_BACKTRACE=1 cargo run es minifier ensure-size panic.js` from the SWC repo:
```
thread 'main' panicked at 'slice index starts at 1 but ends at 0', /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/alloc/src/vec/mod.rs:1993:36
stack backtrace:
   0: rust_begin_unwind
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/std/src/panicking.rs:593:5
   1: core::panicking::panic_fmt
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/panicking.rs:67:14
   2: core::slice::index::slice_index_order_fail_rt
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/slice/index.rs:98:5
   3: core::slice::index::slice_index_order_fail
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/slice/index.rs:91:14
   4: core::slice::index::range
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/slice/index.rs:720:9
   5: alloc::vec::Vec<T,A>::drain
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/alloc/src/vec/mod.rs:1993:36
   6: swc_ecma_minifier::compress::pure::evaluate::<impl swc_ecma_minifier::compress::pure::Pure>::eval_array_method_call
             at ./crates/swc_ecma_minifier/src/compress/pure/evaluate.rs:122:45
   7: <swc_ecma_minifier::compress::pure::Pure as swc_ecma_visit::VisitMut>::visit_mut_expr
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:491:9
   8: swc_ecma_visit::visit_mut_expr_stmt
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
   9: <swc_ecma_ast::stmt::ExprStmt as swc_ecma_visit::VisitMutWith<V>>::visit_mut_children_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  10: <swc_ecma_minifier::compress::pure::Pure as swc_ecma_visit::VisitMut>::visit_mut_expr_stmt
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:564:9
  11: swc_ecma_visit::visit_mut_stmt
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  12: <swc_ecma_ast::stmt::Stmt as swc_ecma_visit::VisitMutWith<V>>::visit_mut_children_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  13: <swc_ecma_minifier::compress::pure::Pure as swc_ecma_visit::VisitMut>::visit_mut_stmt
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:869:13
  14: swc_ecma_visit::visit_mut_module_item
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  15: swc_ecma_visit::VisitMut::visit_mut_module_item
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  16: <swc_ecma_ast::module::ModuleItem as swc_ecma_visit::VisitMutWith<V>>::visit_mut_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  17: swc_ecma_minifier::compress::pure::Pure::visit_par::{{closure}}
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:244:21
  18: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/ops/function.rs:305:13
  19: core::option::Option<T>::map
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/option.rs:1075:29
  20: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/iter/adapters/map.rs:103:26
  21: core::iter::traits::iterator::Iterator::reduce
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/iter/traits/iterator.rs:2517:21
  22: swc_ecma_minifier::compress::pure::Pure::visit_par
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:232:23
  23: <swc_ecma_minifier::compress::pure::Pure as swc_ecma_visit::VisitMut>::visit_mut_module_items
             at ./crates/swc_ecma_minifier/src/compress/pure/mod.rs:692:9
  24: swc_ecma_visit::visit_mut_module
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  25: swc_ecma_visit::VisitMut::visit_mut_module
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  26: <swc_ecma_ast::module::Module as swc_ecma_visit::VisitMutWith<V>>::visit_mut_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  27: <swc_ecma_ast::module::Module as swc_ecma_minifier::util::unit::CompileUnit>::apply
             at ./crates/swc_ecma_minifier/src/util/unit.rs:70:9
  28: swc_ecma_minifier::compress::Compressor::optimize_unit
             at ./crates/swc_ecma_minifier/src/compress/mod.rs:244:13
  29: swc_ecma_minifier::compress::Compressor::optimize_unit_repeatedly
             at ./crates/swc_ecma_minifier/src/compress/mod.rs:120:13
  30: <swc_ecma_minifier::compress::Compressor as swc_ecma_visit::VisitMut>::visit_mut_module
             at ./crates/swc_ecma_minifier/src/compress/mod.rs:332:9
  31: swc_ecma_visit::visit_mut_program
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  32: swc_ecma_visit::VisitMut::visit_mut_program
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  33: <swc_ecma_ast::module::Program as swc_ecma_visit::VisitMutWith<V>>::visit_mut_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  34: <swc_ecma_visit::Folder<V> as swc_ecma_visit::VisitMut>::visit_mut_program
             at ./crates/swc_ecma_visit/src/lib.rs:257:13
  35: <swc_visit::AndThen<A,B> as swc_ecma_visit::VisitMut>::visit_mut_program
             at ./crates/swc_ecma_visit/src/lib.rs:48:9
  36: <swc_ecma_ast::module::Program as swc_ecma_visit::VisitMutWith<V>>::visit_mut_with
             at ./crates/swc_ecma_visit/src/lib.rs:537:1
  37: swc_ecma_minifier::optimize
             at ./crates/swc_ecma_minifier/src/lib.rs:223:13
  38: dbg_swc::util::minifier::get_minified
             at ./crates/dbg-swc/src/util/minifier.rs:27:9
  39: dbg_swc::es::minifier::ensure_size::EnsureSize::check_file::{{closure}}::{{closure}}
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:158:44
  40: scoped_tls::ScopedKey<T>::set
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  41: better_scoped_tls::ScopedKey<T>::set
             at ./crates/better_scoped_tls/src/lib.rs:55:9
  42: dbg_swc::es::minifier::ensure_size::EnsureSize::check_file::{{closure}}
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:156:13
  43: dbg_swc::util::wrap_task
             at ./crates/dbg-swc/src/util/mod.rs:24:5
  44: dbg_swc::es::minifier::ensure_size::EnsureSize::check_file
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:150:9
  45: dbg_swc::es::minifier::ensure_size::EnsureSize::run::{{closure}}::{{closure}}::{{closure}}
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:46:56
  46: scoped_tls::ScopedKey<T>::set
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  47: better_scoped_tls::ScopedKey<T>::set
             at ./crates/better_scoped_tls/src/lib.rs:55:9
  48: dbg_swc::es::minifier::ensure_size::EnsureSize::run::{{closure}}::{{closure}}
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:46:32
  49: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/ops/function.rs:272:13
  50: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/ops/function.rs:305:13
  51: core::option::Option<T>::map
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/option.rs:1075:29
  52: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/iter/adapters/map.rs:103:26
  53: rayon::iter::plumbing::Folder::consume_iter
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:178:21
  54: <rayon::iter::map::MapFolder<C,F> as rayon::iter::plumbing::Folder<T>>::consume_iter
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/map.rs:248:21
  55: rayon::iter::plumbing::Producer::fold_with
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:110:9
  56: rayon::iter::plumbing::bridge_producer_consumer::helper
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:438:13
  57: rayon::iter::plumbing::bridge_producer_consumer
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:397:12
  58: <rayon::iter::plumbing::bridge::Callback<C> as rayon::iter::plumbing::ProducerCallback<I>>::callback
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:373:13
  59: <rayon::slice::Iter<T> as rayon::iter::IndexedParallelIterator>::with_producer
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/slice/mod.rs:732:9
  60: rayon::iter::plumbing::bridge
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/plumbing/mod.rs:357:12
  61: <rayon::slice::Iter<T> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/slice/mod.rs:708:9
  62: <rayon::iter::map::Map<I,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/map.rs:49:9
  63: <rayon::iter::filter_map::FilterMap<I,P> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/filter_map.rs:46:9
  64: <rayon::iter::map::Map<I,F> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/map.rs:49:9
  65: <rayon::iter::while_some::WhileSome<I> as rayon::iter::ParallelIterator>::drive_unindexed
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/while_some.rs:44:9
  66: rayon::iter::extend::<impl rayon::iter::ParallelExtend<T> for alloc::vec::Vec<T>>::par_extend
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/extend.rs:576:28
  67: rayon::iter::from_par_iter::collect_extended
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/from_par_iter.rs:17:5
  68: rayon::iter::from_par_iter::<impl rayon::iter::FromParallelIterator<T> for alloc::vec::Vec<T>>::from_par_iter
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/from_par_iter.rs:30:9
  69: rayon::iter::ParallelIterator::collect
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/mod.rs:2056:9
  70: rayon::result::<impl rayon::iter::FromParallelIterator<core::result::Result<T,E>> for core::result::Result<C,E>>::from_par_iter
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/result.rs:121:26
  71: rayon::iter::ParallelIterator::collect
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rayon-1.7.0/src/iter/mod.rs:2056:9
  72: dbg_swc::es::minifier::ensure_size::EnsureSize::run::{{closure}}
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:44:13
  73: scoped_tls::ScopedKey<T>::with
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:171:13
  74: better_scoped_tls::ScopedKey<T>::with
             at ./crates/better_scoped_tls/src/lib.rs:73:9
  75: dbg_swc::es::minifier::ensure_size::EnsureSize::run
             at ./crates/dbg-swc/src/es/minifier/ensure_size.rs:43:27
  76: dbg_swc::es::minifier::MinifierCommand::run
             at ./crates/dbg-swc/src/es/minifier/mod.rs:31:49
  77: dbg_swc::es::EsCommand::run
             at ./crates/dbg-swc/src/es/mod.rs:24:36
  78: dbg_swc::main::{{closure}}::{{closure}}::{{closure}}
             at ./crates/dbg-swc/src/main.rs:121:37
  79: scoped_tls::ScopedKey<T>::set
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  80: better_scoped_tls::ScopedKey<T>::set
             at ./crates/better_scoped_tls/src/lib.rs:55:9
  81: dbg_swc::main::{{closure}}::{{closure}}
             at ./crates/dbg-swc/src/main.rs:120:17
  82: scoped_tls::ScopedKey<T>::set
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  83: better_scoped_tls::ScopedKey<T>::set
             at ./crates/better_scoped_tls/src/lib.rs:55:9
  84: dbg_swc::main::{{closure}}
             at ./crates/dbg-swc/src/main.rs:119:13
  85: swc_error_reporters::handler::try_with_handler::{{closure}}
             at ./crates/swc_error_reporters/src/handler.rs:105:40
  86: scoped_tls::ScopedKey<T>::set
             at /Users/jflr/.cargo/registry/src/index.crates.io-6f17d22bba15001f/scoped-tls-1.0.1/src/lib.rs:137:9
  87: better_scoped_tls::ScopedKey<T>::set
             at ./crates/better_scoped_tls/src/lib.rs:55:9
  88: swc_error_reporters::handler::try_with_handler
             at ./crates/swc_error_reporters/src/handler.rs:105:15
  89: dbg_swc::main
             at ./crates/dbg-swc/src/main.rs:112:5
  90: core::ops::function::FnOnce::call_once
             at /rustc/839e9a6e1210934fd24b15548b811a97c77138fc/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

### Input code

```typescript
console.log([1, 2].slice(1, undefined));
```


### Config

```json
{
  "minify": true,
  "jsc": {
    "minify": {
      "compress": true
    }
  }
}
```


### Playground link

https://play.swc.rs/?version=1.3.73&code=H4sIAAAAAAAAA0vOzyvOz0nVy8lP14g21FEwitUrzslMTtUAskvzUlLTMvNSUzQ1rbkABC6U%2BykAAAA%3D&config=H4sIAAAAAAAAA32US5LjMAiG932KlNe9nVnMAXo3Z1ApEnKUloVLoHRcXbn74FeS6WDvbD5%2BkADx%2FXY4NGdyzZ%2FDt3zKT28LQbn%2Fi4WGzPYqlgZcZ8mV2HPzvtIzjSjYRDCZbjNp2JYWeFLRr8W9SYgEq%2Fti62KOYXhO6LDrCxA92cQq8WoHmel%2F%2FcIKfo2AS322HxET2LxDjCUTM0MLRQvsMCXbE5iLLUqU8aS2REItxQgrgzd9wV7l2UeOmCXnK%2FVgvXHoQUGxgON4AU0muUSWSa6n3GfCHo61bacm%2F1DDxaZqWckJ16klclol6gkjsQk1ayWc4UYNZrgU96cyBlOAa8mvujPGvNGTTwCpQLJE2XagxZ08gszTljrsKmMOMrI8KFzmW7tlhlaKamIMSmXHykDhqHWzgK8Oxso67TgL3igfRQ8GQpBZUULTV2R30pLy0AMGBUh%2FbdCmagbm%2Fgo3%2BPggdvCH3JL1AVs8OsunbUpDd8S0k6ADPqHfcZBWMG7jIlvi2m%2Fzmj3IaIBXXSpN4HUJyANgNGlali%2BzIc9DIpo24fGxJhaH230Jdza3j%2Fc%2B7%2BG3xaHp0NcJLht%2B7O%2B8l383D6d1C68naCL9XYVz1Ns%2FLRqxri0GAAA%3D

### Expected behavior

SWC should be able to compile that expression.

### Actual behavior

_No response_

### Version

1.3.73

### Additional context

_No response_

Pull request:
fix(es/minifier): Abort on `Array.slice` with `start >= end`
**Description:**


**Related issue:**

 - Closes #7742.


Patch:
diff --git a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs
index 6ab5273da5..61dae47052 100644
--- a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs
+++ b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs
@@ -103,14 +103,18 @@ impl Pure<'_> {
 
                             if let Value::Known(end) = end {
                                 let end = end.floor() as usize;
+                                let end = end.min(arr.elems.len());
+
+                                if start >= end {
+                                    return;
+                                }
+
                                 self.changed = true;
                                 report_change!(
                                     "evaluate: Reducing array.slice({}, {}) call",
                                     start,
                                     end
                                 );
-                                let end = end.min(arr.elems.len());
-
                                 if start >= arr.elems.len() {
                                     *e = Expr::Array(ArrayLit {
                                         span: *span,


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/input.js
new file mode 100644
index 0000000000..9e17c2f74a
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/input.js
@@ -0,0 +1,1 @@
+console.log([1, 2].slice(1, undefined));
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/output.js
new file mode 100644
index 0000000000..b853e0666d
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/7742/1/output.js
@@ -0,0 +1,4 @@
+console.log([
+    1,
+    2
+].slice(1, void 0));