perf(structural): flatten chain ellipsis matches in one pass

ober

65d4316d9409df9464db503c4db68fdffc4b2b32

diff --git a/lib/semgrep/match/structural.sls b/lib/semgrep/match/structural.sls
index 9ad400d..e95180a 100644
--- a/lib/semgrep/match/structural.sls
+++ b/lib/semgrep/match/structural.sls
@@ -1154,16 +1154,15 @@
          [(null? pattern-segments)
           (if (null? target-segments) (list bindings) '())]
          [(chain-segment-ellipsis? (car pattern-segments))
-          (let try ([remaining-target target-segments] [acc '()])
+          (let try ([remaining-target target-segments] [groups '()])
             (let ([matched (chain-segments-match
                              language
                              (cdr pattern-segments)
                              remaining-target
                              bindings)])
               (if (null? remaining-target)
-                  (reverse (append (reverse matched) acc))
-                  (try (cdr remaining-target)
-                       (append (reverse matched) acc)))))]
+                  (apply append (reverse (cons matched groups)))
+                  (try (cdr remaining-target) (cons matched groups)))))]
          [(null? target-segments) '()]
          [else
           (sg-append-map
diff --git a/src/.jerbuild-hashes b/src/.jerbuild-hashes
index e244eb4..ab75c7e 100644
--- a/src/.jerbuild-hashes
+++ b/src/.jerbuild-hashes
@@ -5,9 +5,9 @@
    .
    "DBAD99DB5C22F6A1")
  ("src/semgrep/util/literals.ss" . "8A094085551B216E")
- ("src/semgrep/fix.ss" . "3C4F15F61564C5C8")
+ ("src/semgrep/fix.ss" . "938E5D7C01D54494")
  ("src/semgrep/engine/markup-scan.ss" . "40AF9B537485FE0")
- ("src/semgrep/match/structural.ss" . "5BA4F1566448AF3A")
+ ("src/semgrep/match/structural.ss" . "7717D0A0C711BCCA")
  ("src/semgrep/engine/fallback-positive-dispatch.ss"
    .
    "E6D33DDAE59E5B39")
@@ -34,8 +34,8 @@
    .
    "285FDB423AD7E28C")
  ("src/semgrep/result/builders.ss" . "93A64AF4435E6132")
- ("src/semgrep/cli.ss" . "4FE7A57C41C71E97")
- ("src/semgrep/output/sarif.ss" . "740FF3708E6C1BB")
+ ("src/semgrep/cli.ss" . "5C603BD6D4D2BA2E")
+ ("src/semgrep/output/sarif.ss" . "4E9DB313C13368C5")
  ("src/semgrep/engine/js-vardef-scan.ss"
    .
    "BD82BDDFEDD7242D")
@@ -51,12 +51,12 @@
    "221B0D787F146331")
  ("src/semgrep/engine/taint-specs.ss" . "6B0AA195C9B93DFB")
  ("src/semgrep/engine/ts-query-scan.ss" . "51AD5339F6DE47B4")
- ("src/semgrep/rule/parse-rule.ss" . "89CB5B51431A3B2E")
+ ("src/semgrep/rule/parse-rule.ss" . "415BDF8428314C7")
  ("src/semgrep/output/json.ss" . "293881CFA2ADB7BC")
  ("src/semgrep/lang.ss" . "6982E07679D20836")
  ("src/semgrep/parse/parse-target.ss" . "97AA8FFEB12736DA")
  ("src/semgrep/scan.ss" . "E5E3900F4CA79795")
- ("src/semgrep/engine/generic-scan.ss" . "925C9DC8F6C8188F")
+ ("src/semgrep/engine/generic-scan.ss" . "B3B7F0756F1F550D")
  ("src/semgrep/engine/js-constructor-scan.ss"
    .
    "6B226B8D0584A7A")
diff --git a/src/semgrep/match/structural.ss b/src/semgrep/match/structural.ss
index e901cf5..f8e4956 100644
--- a/src/semgrep/match/structural.ss
+++ b/src/semgrep/match/structural.ss
@@ -1185,16 +1185,15 @@
     [(null? pattern-segments)
      (if (null? target-segments) (list bindings) '())]
     [(chain-segment-ellipsis? (car pattern-segments))
-     (let try ([remaining-target target-segments] [acc '()])
+     (let try ([remaining-target target-segments] [groups '()])
        (let ([matched (chain-segments-match
                         language
                         (cdr pattern-segments)
                         remaining-target
                         bindings)])
          (if (null? remaining-target)
-             (reverse (append (reverse matched) acc))
-             (try (cdr remaining-target)
-                  (append (reverse matched) acc)))))]
+             (apply append (reverse (cons matched groups)))
+             (try (cdr remaining-target) (cons matched groups)))))]
     [(null? target-segments) '()]
     [else
      (sg-append-map