Skip to content

fix(core): partition duplicate-export groups by common-importer before value/type suppression#858

Closed
BartWaardenburg wants to merge 3 commits into
mainfrom
fix/issue-848-duplicate-export-partition
Closed

fix(core): partition duplicate-export groups by common-importer before value/type suppression#858
BartWaardenburg wants to merge 3 commits into
mainfrom
fix/issue-848-duplicate-export-partition

Conversation

@BartWaardenburg
Copy link
Copy Markdown
Collaborator

Replaced the whole-group has_common_importer boolean with partition_by_common_importer (union-find). Independent entries for a name-group are now split into connected components by shared importer before the value+type self-suppression check runs. A cross-package member sharing no importer with the rest (e.g. a backend class Label) is isolated into a singleton component and dropped, so it cannot inflate value_modules and defeat the suppression that should apply to the connected frontend value+type pair. Two focused regression tests were added: one for the false-positive scenario from #848 and a companion test confirming genuine duplicates among connected modules still surface.

Review

Verdict: SHIP

  • Behavior is now stricter than the old whole-group boolean: value/type self-suppression and singleton-dropping run per importer-connected component, so a multi-cluster finding is narrowed to only the connected members (verified by the second test asserting 3 locations -> 2). This is the intended conservative/precision direction (fewer false positives) and the original SvelteKit unrelated-leaf protection test still passes, but it is a genuine behavior change worth noting in the changelog.
  • Minor: the per-component value/type counts use entry counts (value_count/type_count) rather than distinct-module counts as the old global check did (value_modules/type_modules). Only diverges if a single module contributes 2+ value entries of the same name, which is pathological (TS overload dedup merges these earlier); no real-world regression. The direct-import union uses entries.iter().position (first match by file_id), so a second same-file entry is only joined transitively via shared importers; incompleteness is in the singleton-drop (conservative) direction, not a false-positive risk.
  • Verified independently: both new tests FAIL on original code (panic / left:3 right:2 assertion) and PASS with the fix applied; fallow-core lib tests (62) and integration tests (563) pass; clippy and fmt clean. FxHashMap/FxHashSet used throughout (no std collections); test module already carries #[expect(deprecated)] covering the find_duplicate_exports calls; no #[cfg_attr(miri, ignore)] needed since the tests build an in-memory ModuleGraph with no tempdir/fs IO, matching sibling duplicate-export tests. Diff is single-file and minimal.

Closes #848

…e value/type suppression

Before this fix, has_common_importer was a whole-group boolean. A
cross-package member sharing no importer with the rest of the name-group
(e.g. a backend `class Label` that no frontend module imports) stayed in
the group, inflating value_modules so the value+type self-suppression
check was defeated, manufacturing a false duplicate-export finding.

The fix replaces the whole-group has_common_importer call with
partition_by_common_importer, a union-find that splits the independent
entries into connected components by shared importer. Value+type
self-suppression now applies per component, so an isolated backend class
does not inflate the frontend component's value count.

Two regression tests added:
- duplicate_exports_cross_package_backend_does_not_defeat_value_type_suppression:
  backend `class Label` (no shared importer with frontend) must not
  prevent the frontend value+type pair from self-suppressing.
- duplicate_exports_genuine_value_duplicate_still_flagged_despite_unrelated_backend:
  two frontend values sharing a common importer must still report as a
  genuine duplicate even when an unrelated backend module also exports
  the same name.

Fixes #848
@BartWaardenburg BartWaardenburg force-pushed the fix/issue-848-duplicate-export-partition branch from f9cf622 to 4aec65d Compare June 1, 2026 21:55
@BartWaardenburg
Copy link
Copy Markdown
Collaborator Author

Landed on main via maintainer direct-to-main flow, squashed into e8175df. The linked issue is fixed on main; closing this PR as redundant.

@BartWaardenburg BartWaardenburg deleted the fix/issue-848-duplicate-export-partition branch June 2, 2026 09:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

duplicate-export: cross-package member with no common importer defeats value/type self-suppression

1 participant