Skip to content

[code-infra] Enable mui/no-floating-cleanup and fix flagged leaks#22872

Open
romgrk wants to merge 3 commits into
mui:masterfrom
romgrk:no-floating-cleanup
Open

[code-infra] Enable mui/no-floating-cleanup and fix flagged leaks#22872
romgrk wants to merge 3 commits into
mui:masterfrom
romgrk:no-floating-cleanup

Conversation

@romgrk

@romgrk romgrk commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Enables the new mui/no-floating-cleanup rule (mui/mui-public#1538) on package sources and resolves everything it flags. The rule reports call statements whose returned cleanup/unsubscribe function is discarded — usually a leaked subscription.

Changes

  • Bump @mui/internal-code-infra to 0.0.4-canary.66 (first version with the rule); enable it on packages/*/src using projectService.
  • Real leaks fixed
    • Return the unsubscribe from effects: MoreEventsPopover, useKeepGroupedColumnsHidden.
    • Register the scheduler stores' dev-assertion subscriptions on their DisposableStack.
    • Migrate the Tree View store to useDisposable — its subscriptions, EventManager, and TimeoutManager are now torn down on unmount. The mount-time side effect (lazy-loading init) moves from the old disposeEffect into a dedicated mountEffect.
  • Intentional non-leak discards annotated with void: d3 scale builder, callback-ref forwarding, markChatLayoutPane (mutates in place and returns the component).
  • Excluded x-codemod (jscodeshift AST transforms, no subscriptions) and the vendored base-ui-copy.
  • Two Data Grid cases the rule surfaced, resolved after analysis (see inline threads):

Notes

  • Full eslint . runs clean with no OOM at the CI 4 GB cap. projectService is ~7% faster than project here; the dominant cost is whole-repo type-checking (see review thread for follow-up speed ideas).

🤖 Generated with Claude Code

Adopt the new `mui/no-floating-cleanup` rule (mui/mui-public#1538), which
flags call statements whose returned cleanup/unsubscribe is discarded, and
resolve everything it reports.

- Bump `@mui/internal-code-infra` to 0.0.4-canary.66 (first version with the
  rule); enable it on `packages/*/src` via `projectService`.
- Real leaks fixed:
  - Return the unsubscribe from effects (`MoreEventsPopover`,
    `useKeepGroupedColumnsHidden`).
  - Register the scheduler stores' dev-assertion subscriptions on their
    `DisposableStack`.
  - Migrate the Tree View store to `useDisposable`; its subscriptions,
    `EventManager` and `TimeoutManager` are now torn down on unmount. The
    mount-time side effect (lazy-loading init) moves from the old
    `disposeEffect` to a dedicated `mountEffect`.
- Intentional non-leak discards annotated with `void` (d3 builder,
  callback-ref forwarding, `markChatLayoutPane` in-place mutation).
- Excluded `x-codemod` (AST transforms) and the vendored `base-ui-copy`.
- Two Data Grid cases left as `void` + `FIXME` pending a behavior decision
  (see inline comments): `useGridRowSelection` no-op effect and
  `useGridRegisterStrategyProcessor` discarded unregister.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
// discards it (previously `runIfRowSelectionIsEnabled(removeOutdatedSelection)`,
// which invoked it). Restoring the call changes selection behavior, so it needs
// a decision; `void` preserves current behavior. See #20668.
void runIf(props.rowSelection, removeOutdatedSelection);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

no-floating-cleanup flagged this. runIf is curried — runIf(props.rowSelection, removeOutdatedSelection) builds a handler and returns it, so as a bare statement the effect is a no-op. It regressed in #20668, which replaced runIfRowSelectionIsEnabled(removeOutdatedSelection) (that one invoked the fn).

Restoring the call (if (props.rowSelection) removeOutdatedSelection()) makes rowSelection.DataGridPro › "should auto select parents when controlling row selection model" expect an extra onRowSelectionModelChange (4 vs 3) — so whether the effect should run is a behavior decision. Left as void to preserve current behavior; needs a maintainer call on whether to restore it (and update the test) or drop the dead effect.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 1d7dba4: deleted the dead effect. Since runIf is curried it has been a no-op since #20668, so removing it is behavior-identical and drops the dead code. removeOutdatedSelection stays wired to the filteredRowsSet event. (If prop-change re-pruning is actually wanted, that is a separate, deliberate fix that also needs to suppress the redundant onRowSelectionModelChange — happy to open an issue.)

@code-infra-dashboard

code-infra-dashboard Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploy preview

https://deploy-preview-22872--material-ui-x.netlify.app/

Bundle size

Bundle Parsed size Gzip size
@mui/x-data-grid ▼-53B(-0.01%) ▼-12B(-0.01%)
@mui/x-data-grid-pro ▼-53B(-0.01%) ▼-10B(-0.01%)
@mui/x-data-grid-premium ▼-55B(-0.01%) ▼-9B(0.00%)
@mui/x-charts 0B(0.00%) 0B(0.00%)
@mui/x-charts-pro 0B(0.00%) 0B(0.00%)
@mui/x-charts-premium 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 🔺+34.7KB(+53.14%) 🔺+12.6KB(+65.11%)
@mui/x-tree-view-pro 🔺+34.7KB(+28.74%) 🔺+12.6KB(+34.39%)
@mui/x-license 0B(0.00%) 0B(0.00%)

Details of bundle changes

Performance

Total duration: 1,878.17 ms -20.65 ms(-1.1%) | Renders: 63 (+0)

No significant changes — details


Check out the code infra dashboard for more information about this PR.

@romgrk romgrk added internal Behind-the-scenes enhancement. Formerly called “core”. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. labels Jun 17, 2026
romgrk and others added 2 commits June 17, 2026 17:13
`pnpm dedupe` converges @mui/utils and @typescript-eslint/parser to single
versions, unblocked by the @mui/internal-code-infra canary.66 bump. Fixes the
`test_static` "`pnpm dedupe` was run?" check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- useGridRowSelection: delete the dead effect. `runIf` is curried, so the
  statement has been a no-op since mui#20668; removing it is behavior-identical
  and drops the confusing dead code. (removeOutdatedSelection is still wired to
  the `filteredRowsSet` event.)
- useGridRegisterStrategyProcessor: keep the discard, reword to a NOTE. The
  unregister fn is intentionally dropped — a strategy processor must outlive
  the registering component (applyStrategyProcessor throws if the active
  strategy's processor is missing) and the cache is reclaimed with the grid
  api, so it is not a leak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Behind-the-scenes enhancement. Formerly called “core”. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant