-
-
Notifications
You must be signed in to change notification settings - Fork 781
fix(inference): improved inference for assignment types #8119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: e0955f4 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
WalkthroughRefactors module graph collector to use binding data, detect writable references, and widen inferred types by unioning RHS assignment types. Adds tests exercising widening from single and multiple assignments and a TypeScript test ensuring no diagnostics for reassigned variables checked in conditions. Adds a public Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Tip 📝 Customizable high-level summaries are now available in beta!You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.
Example instruction:
Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
crates/biome_js_type_info/src/resolver.rs (1)
725-731: union_with helper is fine, but note the “naive” union growthThe implementation matches
optionaland does what the PR describes: it always creates a fresh two‑memberUnionfromcurrent_typeandtyand registers it.That’s perfectly OK for the current “naive” widening, but it does mean repeated widening will keep allocating new union types without flattening or deduplication. If unions ever start to get large or performance becomes an issue, this might be a good place to introduce flattening/reuse.
.changeset/upset-cameras-walk.md (1)
5-5: Tiny wording tweak (optional)Pure style, but this reads a bit smoother without the comma:
-Improved the type inference engine, by resolving types for variables that are assigned to multiple values. +Improved the type inference engine by resolving types for variables that are assigned to multiple values.crates/biome_module_graph/tests/spec_tests.rs (1)
2132-2163: New widening snapshot test is consistent and focusedThis is a clean minimal case for “boolean literal + reassignment” widening; setup mirrors other snapshot tests and the relative
"index.ts"path is used consistently, so behaviour should be stable.If you want to align style with nearby tests, you could optionally write:
let snapshot = ModuleGraphSnapshot::new(module_graph.as_ref(), &fs).with_resolver(resolver.as_ref());but the current
&module_graphform is perfectly fine thanks to deref‑coercion.crates/biome_module_graph/src/js_module_info/collector.rs (1)
609-648: Code duplication in the if-else branches.Lines 613–616 and 643–648 perform identical lookups from
typed_bindings. The else branch is redundant; you can simplify by initialisingtyonce (lines 613–616), applying the writable-reference union conditionally, then returningtyat the end.Apply this refactor to eliminate duplication:
- let ty = if let Some(typed_bindings) = decl + let mut ty = if let Some(typed_bindings) = decl .as_js_variable_declaration() .and_then(|decl| self.variable_declarations.get(decl.syntax())) { - let mut ty = typed_bindings + typed_bindings .iter() .find_map(|(name, ty)| (name == binding_name).then(|| ty.clone())) - .unwrap_or_default(); - + .unwrap_or_default() + } else { + let data = TypeData::from_any_js_declaration(self, scope_id, &decl); + self.reference_to_owned_data(data) + }; + if self.has_writable_reference(&binding) { let references = self.get_writable_references(&binding); for reference in references { let Some(node) = self.binding_node_by_start.get(&reference.range_start) else { continue; }; for ancestor in node.ancestors().skip(1) { if let Some(assignment) = JsAssignmentExpression::cast_ref(&ancestor) && let Ok(right) = assignment.right() { let data = TypeData::from_any_js_expression(self, scope_id, &right); let assigned_type = self.reference_to_owned_data(data); ty = ResolvedTypeId::new( self.level(), self.union_with(ty.clone(), assigned_type).into(), ) .into(); } } } - - ty - } else { - typed_bindings - .iter() - .find_map(|(name, ty)| (name == binding_name).then(|| ty.clone())) - .unwrap_or_default() } - } else { - let data = TypeData::from_any_js_declaration(self, scope_id, &decl); - self.reference_to_owned_data(data) - };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
crates/biome_js_analyze/tests/specs/nursery/noUnnecessaryConditions/validAssignment.ts.snapis excluded by!**/*.snapand included by**crates/biome_module_graph/tests/snapshots/test_widening_via_assignment.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (7)
.changeset/lovely-sloths-chew.md(1 hunks).changeset/upset-cameras-walk.md(1 hunks)crates/biome_js_analyze/tests/specs/nursery/noUnnecessaryConditions/validAssignment.ts(1 hunks)crates/biome_js_type_info/src/resolver.rs(1 hunks)crates/biome_module_graph/src/js_module_info/collector.rs(2 hunks)crates/biome_module_graph/tests/snapshots/test_widening_via_assignment_multiple_values.snap.new(1 hunks)crates/biome_module_graph/tests/spec_tests.rs(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
Applied to files:
crates/biome_js_type_info/src/resolver.rscrates/biome_module_graph/src/js_module_info/collector.rscrates/biome_module_graph/tests/snapshots/test_widening_via_assignment_multiple_values.snap.new
🧬 Code graph analysis (2)
crates/biome_module_graph/tests/spec_tests.rs (3)
crates/biome_fs/src/fs/memory.rs (1)
default(37-49)crates/biome_test_utils/src/lib.rs (1)
get_added_paths(169-190)crates/biome_module_graph/src/js_module_info/module_resolver.rs (1)
for_module(76-91)
crates/biome_module_graph/src/js_module_info/collector.rs (3)
crates/biome_js_type_info/src/type_data.rs (8)
ty(545-550)index(45-47)index(1431-1433)index(1472-1476)reference(343-345)new(39-43)new(1425-1429)new(1460-1470)crates/biome_module_graph/src/js_module_info.rs (1)
binding(264-266)crates/biome_js_type_info/src/local_inference.rs (3)
from_any_js_expression(425-602)from_any_js_expression(2173-2180)from_any_js_expression(2343-2425)
🪛 LanguageTool
.changeset/lovely-sloths-chew.md
[uncategorized] ~5-~5: Possible missing comma found.
Context: ... of the rule noUnnecessaryConditions. Now the rule doesn't isn't triggered for va...
(AI_HYDRA_LEO_MISSING_COMMA)
[grammar] ~5-~5: Two consecutive contractions are very uncommon. Did you maybe just mean “doesn't” or “isn't”?
Context: ...noUnnecessaryConditions. Now the rule doesn't isn't triggered for variables that are mutate...
(DON_T_AREN_T)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: autofix
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Test Node.js API
- GitHub Check: Documentation
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: End-to-end tests
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Check Dependencies
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
🔇 Additional comments (7)
crates/biome_js_analyze/tests/specs/nursery/noUnnecessaryConditions/validAssignment.ts (1)
1-9: Targeted regression fixture looks goodThis neatly captures the “mutated in the same module before the condition” case for
noUnnecessaryConditions. No changes needed from my side.crates/biome_module_graph/tests/spec_tests.rs (1)
2165-2200: Good coverage for multi‑value wideningNice to see a dedicated case where a binding starts as
undefinedand is then assigned both a string and a number in separate functions; that should exercise the “multiple assignments → union” path nicely. Snapshot wiring matches the previous test and looks correct.Nothing I’d change here.
crates/biome_module_graph/tests/snapshots/test_widening_via_assignment_multiple_values.snap.new (1)
1-99: Snapshot looks good!The progressive type widening from
undefined→undefined | string→undefined | string | numbercorrectly reflects the multiple assignment behavior. The structure is clear and validates the new inference logic.crates/biome_module_graph/src/js_module_info/collector.rs (4)
6-9: LGTM!Import changes appropriately include
JsAssignmentExpressionfor the new assignment-tracking logic.
578-578: Clone is acceptable here.Cloning the binding provides access to metadata needed for the improved inference. Since this occurs once per binding during collection, the performance cost is reasonable.
584-598: Helper methods look solid.Clean, focused implementations for detecting and collecting writable references. These support the new type-widening logic nicely.
654-654: Early return is appropriate.Returning after resolving the type from variable declarations prevents unnecessary traversal of further ancestors and maintains the existing control-flow pattern.
CodSpeed Performance ReportMerging #8119 will not alter performanceComparing Summary
Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
crates/biome_module_graph/tests/snapshots/test_widening_via_assignment_multiple_values.snapis excluded by!**/*.snapand included by**
📒 Files selected for processing (2)
.changeset/lovely-sloths-chew.md(1 hunks)crates/biome_module_graph/src/js_module_info/collector.rs(2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
Applied to files:
crates/biome_module_graph/src/js_module_info/collector.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.
Applied to files:
.changeset/lovely-sloths-chew.md
🧬 Code graph analysis (1)
crates/biome_module_graph/src/js_module_info/collector.rs (2)
crates/biome_module_graph/src/js_module_info.rs (1)
binding(264-266)crates/biome_js_type_info/src/local_inference.rs (3)
from_any_js_expression(425-602)from_any_js_expression(2173-2180)from_any_js_expression(2343-2425)
🪛 LanguageTool
.changeset/lovely-sloths-chew.md
[uncategorized] ~5-~5: Possible missing comma found.
Context: ... of the rule noUnnecessaryConditions. Now the rule isn't triggered for variables ...
(AI_HYDRA_LEO_MISSING_COMMA)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: autofix
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_formatter)
🔇 Additional comments (2)
crates/biome_module_graph/src/js_module_info/collector.rs (2)
584-598: Clean helper methods.These helper methods are well-structured and serve their purpose clearly.
618-641: Theunion_withmethod exists and is correctly used; however, scope handling requires architectural clarification.The call to
self.union_with(ty.clone(), assigned_type)on line 635 is valid—the method exists on theTypeResolvertrait thatJsModuleInfoCollectorimplements.However, the scope concern remains: line 631 uses the binding's declaration scope (
scope_id) to infer the assignment's RHS type, even when the assignment occurs in a nested scope (e.g., inside a function). Sincescope_by_rangeis available elsewhere in the collector, consider whether you should look up the assignment's actual scope rather than using the binding's declaration scope. This matters especially for resolving identifiers referenced in complex RHS expressions within different scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
crates/biome_module_graph/src/js_module_info/collector.rs (1)
584-599: Assignment-based type widening: fix scope usage and tidy upNice idea to widen binding types from write references. A few points worth tightening up:
Scope for RHS inference can be wrong (potentially widening to
unknown)In the assignment loop you currently do:
let data = TypeData::from_any_js_expression(self, scope_id, &right); let assigned_type = self.reference_to_owned_data(data); ty = ResolvedTypeId::new( self.level(), self.union_with(ty.clone(), assigned_type), ).into();Here
scope_idis the scope of the declaration (binding.range), not necessarily the scope where the assignment lives. From thefrom_any_js_expressionimplementation inlocal_inference.rs, identifier expressions rely on the providedscope_idto resolve bindings. That means something like:let x = 1; function f(y: string) { x = y; }may fail to see
y(declared in the inner scope) and treat the RHS asunknown, soxgets widened fromnumbertounknowninstead ofnumber | string.You can reuse the already computed expression type from the first pass and avoid the scope mismatch entirely by going through
reference_to_resolved_expression:- if let Some(assignment) = - JsAssignmentExpression::cast_ref(&ancestor) - && let Ok(right) = assignment.right() - { - let data = - TypeData::from_any_js_expression(self, scope_id, &right); - let assigned_type = self.reference_to_owned_data(data); - ty = ResolvedTypeId::new( - self.level(), - self.union_with(ty.clone(), assigned_type), - ) - .into(); - } + if let Some(assignment) = + JsAssignmentExpression::cast_ref(&ancestor) + && let Ok(right) = assignment.right() + { + let assigned_type = + self.reference_to_resolved_expression(scope_id, &right); + ty = ResolvedTypeId::new( + self.level(), + self.union_with(ty.clone(), assigned_type), + ) + .into(); + }This should pick up the RHS type as it was inferred with the correct scope during the initial traversal, and avoids recomputing it. I’d also consider adding a spec that covers a nested-function assignment like the example above to guard this behaviour.
Drop the redundant
elsebranchThe
if self.has_writable_reference(&binding)arm returnstyin both branches:if self.has_writable_reference(&binding) { // ... possibly update ty ... ty } else { ty }You can simply return
tyonce after theifblock and avoid repeating yourself. This is exactly what was mentioned in the previous review, and it’s still an easy cleanup.
Minor tidy-ups
let binding_name = &binding.name.clone();can just belet binding_name = &binding.name;– no need to allocate a freshText.get_writable_referencesallocates aVeconly to iterate over it immediately. You could inline the iterator (for reference in binding.references.iter().filter(|r| r.is_write())) and drop the helper, unless you particularly like the separation.None of these are blockers, but they’ll make this bit of logic a touch leaner and clearer.
Also applies to: 600-645
🧹 Nitpick comments (1)
crates/biome_module_graph/src/js_module_info/collector.rs (1)
573-579: Avoid cloningJsBindingDataandJsSyntaxNodeon the hot path
infer_all_typesonly reads frombindingandnode, so you can pass them by reference and drop theclone()calls if you ever want to trim a bit of overhead here:- let binding = &self.bindings[index]; - if let Some(node) = self.binding_node_by_start.get(&binding.range.start()) { + let binding = &self.bindings[index]; + if let Some(node) = self.binding_node_by_start.get(&binding.range.start()) { let scope_id = scope_id_for_range(scope_by_range, binding.range); - let ty = self.infer_type(&node.clone(), binding.clone(), scope_id); + let ty = self.infer_type(node, binding, scope_id);That would, of course, require
infer_typeto take&JsBindingDatainstead of an owned value.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
crates/biome_module_graph/src/js_module_info/collector.rs(2 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
Applied to files:
crates/biome_module_graph/src/js_module_info/collector.rs
🧬 Code graph analysis (1)
crates/biome_module_graph/src/js_module_info/collector.rs (3)
crates/biome_module_graph/src/js_module_info.rs (1)
binding(264-266)crates/biome_js_formatter/src/utils/assignment_like.rs (1)
right(323-353)crates/biome_js_type_info/src/local_inference.rs (3)
from_any_js_expression(425-602)from_any_js_expression(2173-2180)from_any_js_expression(2343-2425)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: autofix
- GitHub Check: Documentation
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: End-to-end tests
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_module_graph)
🔇 Additional comments (1)
crates/biome_module_graph/src/js_module_info/collector.rs (1)
4-10: New imports look spot onAll the newly imported syntax nodes (
AnyJsImportClause,JsAssignmentExpression, identifiers,inner_string_text, etc.) are used below and match their call‑sites. Nothing to fix here.
arendjr
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice start! I wouldn't consider the requested change to be a blocker personally. Better to be a bit more lenient than too strict, as is currently the case. We can always tighten it again later (although then it might be good to acknowledge this in the changelog).
a34d385 to
b700ad7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
crates/biome_module_graph/src/js_module_info/collector.rs (1)
578-578: Consider performance impact of cloning bindings.Cloning the entire
JsBindingDatastructure (including itsreferencesVec) for every binding during type inference could be expensive for modules with many bindings or heavily-referenced bindings. Consider passing a reference or extracting only the required fields.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/lovely-sloths-chew.md(1 hunks)crates/biome_js_analyze/src/lint/nursery/no_unnecessary_conditions.rs(2 hunks)crates/biome_module_graph/src/js_module_info/collector.rs(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-20T16:24:59.781Z
Learnt from: arendjr
Repo: biomejs/biome PR: 7266
File: crates/biome_js_type_info/src/type.rs:94-102
Timestamp: 2025-08-20T16:24:59.781Z
Learning: In crates/biome_js_type_info/src/type.rs, the flattened_union_variants() method returns TypeReference instances that already have the correct module IDs applied to them. These references should be used directly with resolver.resolve_reference() without applying additional module ID transformations, as variant references may originate from nested unions in different modules.
Applied to files:
crates/biome_module_graph/src/js_module_info/collector.rs
📚 Learning: 2025-08-05T14:43:29.581Z
Learnt from: dyc3
Repo: biomejs/biome PR: 7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.
Applied to files:
.changeset/lovely-sloths-chew.md
🧬 Code graph analysis (2)
crates/biome_js_analyze/src/lint/nursery/no_unnecessary_conditions.rs (1)
crates/biome_analyze/src/rule.rs (2)
sources(617-620)inspired(254-259)
crates/biome_module_graph/src/js_module_info/collector.rs (2)
crates/biome_module_graph/src/js_module_info.rs (1)
binding(264-266)crates/biome_js_type_info/src/local_inference.rs (3)
from_any_js_expression(425-602)from_any_js_expression(2173-2180)from_any_js_expression(2343-2425)
🪛 LanguageTool
.changeset/lovely-sloths-chew.md
[uncategorized] ~5-~5: Possible missing comma found.
Context: ... of the rule noUnnecessaryConditions. Now the rule isn't triggered for variables ...
(AI_HYDRA_LEO_MISSING_COMMA)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: autofix
🔇 Additional comments (7)
.changeset/lovely-sloths-chew.md (1)
5-5: Grammar issue resolved.The previously flagged "doesn't isn't" grammar glitch has been corrected. The sentence now reads smoothly.
crates/biome_js_analyze/src/lint/nursery/no_unnecessary_conditions.rs (2)
47-61: Clear documentation of the rule deviation.The added documentation effectively explains why the rule doesn't trigger for bindings with multiple assignments. The example is illustrative and directly supports the explanation.
90-90: Correct source attribution.Marking the rule as
inspired()appropriately reflects the deviation in behaviour from the source rule, as discussed in previous reviews.crates/biome_module_graph/src/js_module_info/collector.rs (4)
584-598: Clean helper methods for write detection.The helper methods are straightforward and correctly identify writable references using the
is_write()predicate.
609-628: Verify widening scope is intentional.Type widening based on writable references is only applied to variable declarations (lines 609-622), but not to function parameters, type parameters, or for-variable declarations. Is this the intended behaviour, or should widening also apply to reassigned parameters?
668-697: Type widening logic looks sound.The method correctly identifies write references, locates assignment expressions, infers RHS types, and builds union types. The approach of iterating through writable references and unioning assigned types achieves the PR objective of widening types for multiply-assigned bindings.
6-9: Necessary import addition.Adding
JsAssignmentExpressionsupports the new widening logic that inspects assignment expressions.
576b3d6 to
e0955f4
Compare
|
|
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Summary
Part of #6611
This PR improves the inference engine by updating the type of those bindings that are assigned to multiple values.
The implementation is quite naive for now, so if there more than one assignments, we create new types for each one of them. You can see it from the snapshots.
cc @arendjr
Test Plan
Added new tests
Docs