Skip to content

fix(minifier): preserve RegExp feature detection#24712

Merged
graphite-app[bot] merged 1 commit into
mainfrom
codex/fix-regexp-feature-detection
Jul 21, 2026
Merged

fix(minifier): preserve RegExp feature detection#24712
graphite-app[bot] merged 1 commit into
mainfrom
codex/fix-regexp-feature-detection

Conversation

@Dunqing

@Dunqing Dunqing commented Jul 20, 2026

Copy link
Copy Markdown
Member

PR stack (3 of 3)

  1. refactor(ecmascript)!: gate analysis APIs #24739
  2. refactor(ecmascript): expose engine targets to side effects #24742
  3. fix(minifier): preserve RegExp feature detection #24712 (this PR)

Review #24739 and #24742 first. This PR is based on #24742, so GitHub shows only the RegExp behavior change.

Stacked on #24742, which exposes strict engine-target capabilities to side-effect analysis.

RegExp constructor calls used for engine feature detection were removed by DCE when their pattern was valid according to the current Oxc RegExp parser. A pattern can be valid at build time but still throw a SyntaxError on the configured runtime, so removing the call changes the result of surrounding try/catch checks.

RegExp purity now requires both syntactic validity and support from every configured target. Consumers without concrete targets remain conservative, while an explicit target allows the minifier to remove constructors known to be safe for those engines.

Target-independent flag validation and pattern compatibility checks now live in oxc_regular_expression; side-effect analysis only maps target support to unsupported flags and patterns. String patterns, modern flags, named groups, property escapes, lookbehind, modifiers, invalid flags, and lone-surrogate strings are covered. A RegExp literal with replacement flags is removable only when the target supports both those flags and the dedicated ES2015RegExpConstructorCanAlterFlags compatibility feature. Explicitly targeting esnext opts into current features.

Example

Input:

export function supportsUnicodeRegExp() {
  try {
    new RegExp("\\p{Ll}", "u");
    return true;
  } catch {
    return false;
  }
}

Before:

export function supportsUnicodeRegExp() {
  try {
    return true;
  } catch {
    return false;
  }
}

After:

export function supportsUnicodeRegExp() {
  try {
    new RegExp("\\p{Ll}", "u");
    return true;
  } catch {
    return false;
  }
}

Verified with all oxc_regular_expression, oxc_compat, oxc_ecmascript, and oxc_minifier tests; the no-feature/side_effects/constant_evaluation oxc_ecmascript matrix; affected-crate clippy; formatting; and diff checks.

Fixes rolldown/rolldown#10279.

Implemented with AI assistance (OpenAI Codex and Claude). The contributor remains responsible for reviewing, understanding, and submitting these changes under the repository AI usage policy.

@github-actions github-actions Bot added the A-minifier Area - Minifier label Jul 20, 2026
@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 67 untouched benchmarks
⏩ 9 skipped benchmarks1


Comparing codex/fix-regexp-feature-detection (2273082) with codex/side-effect-engine-targets (4994d9b)

Open in CodSpeed

Footnotes

  1. 9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch 2 times, most recently from e3c3f57 to efb85e2 Compare July 20, 2026 12:26
@Dunqing

Dunqing commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: efb85e2315

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Dunqing Dunqing added the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 20, 2026
@oxc-guard

oxc-guard Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@oxc-guard oxc-guard Bot removed the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 20, 2026
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch 3 times, most recently from 53ced01 to 1a3ef05 Compare July 21, 2026 01:37
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from 1a3ef05 to 91d1240 Compare July 21, 2026 03:16
@github-actions github-actions Bot added the A-linter Area - Linter label Jul 21, 2026
@Dunqing
Dunqing changed the base branch from main to codex/ecmascript-analysis-features July 21, 2026 03:16
@Dunqing
Dunqing force-pushed the codex/ecmascript-analysis-features branch from 0e7b2ae to 602e7f4 Compare July 21, 2026 03:35
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from 91d1240 to 4490b5e Compare July 21, 2026 03:35

Dunqing commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@Dunqing
Dunqing changed the base branch from codex/ecmascript-analysis-features to graphite-base/24712 July 21, 2026 03:51
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from 4490b5e to 32a4d45 Compare July 21, 2026 03:51
@Dunqing
Dunqing changed the base branch from graphite-base/24712 to codex/side-effect-engine-targets July 21, 2026 03:52
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from 03df362 to f51789f Compare July 21, 2026 03:57
@Dunqing
Dunqing force-pushed the codex/side-effect-engine-targets branch 2 times, most recently from 9c04aa6 to 96987da Compare July 21, 2026 05:21
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from f51789f to 3efd4d0 Compare July 21, 2026 05:21
@Dunqing
Dunqing marked this pull request as ready for review July 21, 2026 05:32
@Dunqing
Dunqing requested a review from sapphi-red July 21, 2026 05:45
Comment thread crates/oxc_minifier/src/options.rs Outdated
Comment thread crates/oxc_ecmascript/README.md Outdated
Comment thread crates/oxc_ecmascript/src/side_effects/known_globals.rs
Comment thread crates/oxc_ecmascript/src/side_effects/known_globals.rs Outdated
Comment thread crates/oxc_ecmascript/src/side_effects/known_globals.rs Outdated
Comment thread crates/oxc_ecmascript/src/side_effects/known_globals.rs Outdated
@Dunqing
Dunqing force-pushed the codex/side-effect-engine-targets branch from 96987da to 4994d9b Compare July 21, 2026 08:07
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch 2 times, most recently from 27fd72e to a6ec664 Compare July 21, 2026 08:32
@Dunqing
Dunqing requested a review from leaysgur as a code owner July 21, 2026 08:32
@github-actions github-actions Bot added A-transformer Area - Transformer / Transpiler A-regular-expression Area - Regular Expression labels Jul 21, 2026
@Dunqing
Dunqing requested a review from sapphi-red July 21, 2026 08:48

@sapphi-red sapphi-red left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Comment thread crates/oxc_ecmascript/src/side_effects/known_globals.rs Outdated
@Dunqing
Dunqing force-pushed the codex/fix-regexp-feature-detection branch from a6ec664 to 2273082 Compare July 21, 2026 14:02
@Dunqing Dunqing added the 0-merge Merge with Graphite Merge Queue label Jul 21, 2026

Dunqing commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

Merge activity

> **PR stack (3 of 3)**
> 1. #24739
> 2. #24742
> 3. **#24712 (this PR)**
>
> Review #24739 and #24742 first. This PR is based on #24742, so GitHub shows only the RegExp behavior change.

Stacked on #24742, which exposes strict engine-target capabilities to side-effect analysis.

RegExp constructor calls used for engine feature detection were removed by DCE when their pattern was valid according to the current Oxc RegExp parser. A pattern can be valid at build time but still throw a `SyntaxError` on the configured runtime, so removing the call changes the result of surrounding `try`/`catch` checks.

RegExp purity now requires both syntactic validity and support from every configured target. Consumers without concrete targets remain conservative, while an explicit target allows the minifier to remove constructors known to be safe for those engines.

Target-independent flag validation and pattern compatibility checks now live in `oxc_regular_expression`; side-effect analysis only maps target support to unsupported flags and patterns. String patterns, modern flags, named groups, property escapes, lookbehind, modifiers, invalid flags, and lone-surrogate strings are covered. A RegExp literal with replacement flags is removable only when the target supports both those flags and the dedicated `ES2015RegExpConstructorCanAlterFlags` compatibility feature. Explicitly targeting `esnext` opts into current features.

## Example

Input:

```js
export function supportsUnicodeRegExp() {
  try {
    new RegExp("\\p{Ll}", "u");
    return true;
  } catch {
    return false;
  }
}
```

Before:

```js
export function supportsUnicodeRegExp() {
  try {
    return true;
  } catch {
    return false;
  }
}
```

After:

```js
export function supportsUnicodeRegExp() {
  try {
    new RegExp("\\p{Ll}", "u");
    return true;
  } catch {
    return false;
  }
}
```

Verified with all `oxc_regular_expression`, `oxc_compat`, `oxc_ecmascript`, and `oxc_minifier` tests; the no-feature/`side_effects`/`constant_evaluation` `oxc_ecmascript` matrix; affected-crate clippy; formatting; and diff checks.

Fixes rolldown/rolldown#10279.

Implemented with AI assistance (OpenAI Codex and Claude). The contributor remains responsible for reviewing, understanding, and submitting these changes under the repository AI usage policy.
graphite-app Bot pushed a commit that referenced this pull request Jul 21, 2026
> **PR stack (1 of 3)**
> 1. **#24739 (this PR)**
> 2. #24742
> 3. #24712
>
> Review and merge in this order.

The `oxc_ecmascript` crate currently compiles constant evaluation and side-effect analysis for every consumer, even when a consumer only needs the small shared ECMAScript value primitives. This makes optional analysis code and its dependencies part of unrelated builds.

This introduces two explicit features:

- `side_effects` enables side-effect analysis and its RegExp support.
- `constant_evaluation` enables constant evaluation and implies `side_effects`, because side-effect analysis uses constant folding for several purity decisions.

`ConstantValue`, `ValueType`, and `DetermineValueType` move to feature-independent root modules so `GlobalContext` remains available without either analysis feature. Existing paths through `constant_evaluation` remain re-exported when that feature is enabled.

This is a prerequisite for #24742, which exposes engine targets to side-effect analysis without making compatibility data part of every `oxc_ecmascript` consumer.

This is a breaking Cargo feature change for direct consumers of `oxc_ecmascript`: code using side-effect analysis or constant evaluation must enable the corresponding feature.

Verified locally with the no-feature, `side_effects`, and `constant_evaluation` configurations, crate tests, dependent linter and minifier tests, rustdoc with warnings denied, and `just ready`. The release oxlint binary on this commit is 13,350,096 bytes.

Implemented with AI assistance (OpenAI Codex and Claude). The contributor remains responsible for reviewing, understanding, and maintaining these changes.
graphite-app Bot pushed a commit that referenced this pull request Jul 21, 2026
> **PR stack (2 of 3)**
> 1. #24739
> 2. **#24742 (this PR)**
> 3. #24712
>
> Review #24739 first. This PR is based on its branch, so GitHub shows only the engine-target plumbing.

Stacked on #24739, which introduces the `side_effects` and `constant_evaluation` feature boundary for `oxc_ecmascript`.

Side-effect analysis sometimes needs to know whether runtime syntax is supported by every configured engine. `MayHaveSideEffectsContext` currently has no access to target information, while `EngineTargets::has_feature` is intentionally permissive about missing compatibility data because it answers whether a transformation is needed.

`MayHaveSideEffectsContext::engine_targets()` exposes the configured targets through a general-purpose accessor. Its default is `None`, so consumers without target information remain conservative, while the minifier supplies its existing `CompressOptions::target`.

`EngineTargets::supports_es_feature` provides the corresponding strict capability query. Every configured engine must have compatibility data and meet the required version; empty targets and missing rows are not treated as proof of support. The existing transformation-oriented `has_feature` behavior remains unchanged.

Because `oxc_linter` enables `side_effects`, this also adds `oxc_compat` to the oxlint and language-server build graphs. It does not change side-effect decisions by itself; #24712 consumes the new capability for target-aware RegExp validation.

Verified with all `oxc_compat` tests, the no-feature/`side_effects`/`constant_evaluation` `oxc_ecmascript` matrix, a minifier check, formatting, and Clippy.

Implemented with AI assistance (OpenAI Codex and Claude). The contributor remains responsible for reviewing, understanding, and maintaining these changes.
@graphite-app
graphite-app Bot force-pushed the codex/side-effect-engine-targets branch from 4994d9b to 01c3611 Compare July 21, 2026 14:16
@graphite-app
graphite-app Bot requested a review from camc314 as a code owner July 21, 2026 14:16
@graphite-app
graphite-app Bot force-pushed the codex/fix-regexp-feature-detection branch from 2273082 to 79e6d77 Compare July 21, 2026 14:16
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 21, 2026
Base automatically changed from codex/side-effect-engine-targets to main July 21, 2026 14:21
@graphite-app
graphite-app Bot merged commit 79e6d77 into main Jul 21, 2026
31 checks passed
@graphite-app
graphite-app Bot deleted the codex/fix-regexp-feature-detection branch July 21, 2026 14:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter A-minifier Area - Minifier A-regular-expression Area - Regular Expression A-transformer Area - Transformer / Transpiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Minifier DCE's a side-effecting new RegExp used for engine feature detection

2 participants