Conversation
🦋 Changeset detectedLatest commit: dd78724 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 |
Merging this PR will not alter performance
Comparing Footnotes
|
80290f8 to
ad4e684
Compare
This comment was marked as resolved.
This comment was marked as resolved.
WalkthroughAdds a new nursery lint rule Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs`:
- Around line 435-446: The current has_shadowed_binding function walks the
entire syntax tree and treats any identifier named `name` as shadowing even when
it lives in a different scope; restrict the lookup to the lexical scope that
contains the call instead. Change has_shadowed_binding to find the nearest
enclosing scope node for the call (e.g., the nearest function, method, block,
module/Script node) and only search descendants of that scope node for
AnyJsIdentifierBinding with the same name, still ignoring the binding that has
the same range as the call; this prevents nested/outer unrelated bindings
(parameters or locals) from silencing a top-level String(...) diagnostic and
avoids a full-tree walk per candidate.
- Around line 282-290: The code only handles identifier assignments (using
AnyJsAssignmentPattern::AnyJsAssignment and as_js_identifier_assignment) so
member/element targets like obj.name += "" or arr[i] += "" are skipped; extend
the match to also handle member/element assignment variants (the
AnyJsAssignmentPattern branch that yields a member/element assignment — e.g.,
use the pattern that exposes as_js_member_assignment / as_js_element_assignment
or similar on the same assign value), extract the target expression from that
member/element assignment and query its static type the same way you do for
identifiers (call the appropriate ctx type-check helper, e.g., reuse
ctx.type_of_named_value or call the corresponding ctx.type_of_member_value), and
return None only if you cannot resolve the type; keep node.range() as the
location passed into the type query.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: d562b57b-5f95-47cf-9309-641afeef6105
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (6)
.changeset/upset-women-open.mdcrates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.tscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.tscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_useless_type_conversion.rs
| let left = node.left().ok()?; | ||
| let ty = match left { | ||
| AnyJsAssignmentPattern::AnyJsAssignment(assign) => { | ||
| let identifier = assign.as_js_identifier_assignment()?; | ||
| let name = identifier.name_token().ok()?; | ||
| ctx.type_of_named_value(node.range(), name.text_trimmed()) | ||
| } | ||
| _ => return None, | ||
| }; |
There was a problem hiding this comment.
Handle member targets for += "" too.
This currently stops at JsIdentifierAssignment, so obj.name += "" or arr[i] += "" quietly escape even when the left-hand side is statically string. A tiny invalid snapshot for a typed member access would keep this branch honest.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs`
around lines 282 - 290, The code only handles identifier assignments (using
AnyJsAssignmentPattern::AnyJsAssignment and as_js_identifier_assignment) so
member/element targets like obj.name += "" or arr[i] += "" are skipped; extend
the match to also handle member/element assignment variants (the
AnyJsAssignmentPattern branch that yields a member/element assignment — e.g.,
use the pattern that exposes as_js_member_assignment / as_js_element_assignment
or similar on the same assign value), extract the target expression from that
member/element assignment and query its static type the same way you do for
identifiers (call the appropriate ctx type-check helper, e.g., reuse
ctx.type_of_named_value or call the corresponding ctx.type_of_member_value), and
return None only if you cannot resolve the type; keep node.range() as the
location passed into the type query.
There was a problem hiding this comment.
turns out our APIs don't make this easy to do, so I'm going to leave this alone for now
There was a problem hiding this comment.
Maybe it's worth adding issue_number to the metadata of the rule at this point, so we know things are still missing, but planned
ad4e684 to
d46083f
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs (2)
435-446:⚠️ Potential issue | 🟠 MajorMake the shadowing lookup lexical-scope aware.
This scan treats any nested
String/Number/Boolean/BigIntbinding as shadowing, so real top-level diagnostics can disappear even when that binding is out of scope. It also walks the whole file per candidate call, which is a strong suspect for the slowdown mentioned on the PR.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs` around lines 435 - 446, The current has_shadowed_binding function scans from the file root and treats any identifier anywhere as shadowing; change it to find the nearest enclosing lexical scope for the JsCallExpression (e.g., nearest function, block, module/Script node) instead of using call.syntax().ancestors().last(), then restrict the search to descendants of that scope only and ensure bindings are actually in-scope (e.g., declared in the same scope or an inner scope that would shadow the call), keeping the existing checks on AnyJsIdentifierBinding, binding.name_token(), and binding.range() != call.range() to avoid self-matches; this both makes shadow detection lexically correct and avoids walking the whole file for each call.
282-290:⚠️ Potential issue | 🟡 Minor
+= ""still misses member and element targets.This path only handles
JsIdentifierAssignment, so cases likeobj.name += ""andarr[i] += ""still slip past the rule even when the target is staticallystring.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs` around lines 282 - 290, The current match only handles JsIdentifierAssignment via AnyJsAssignmentPattern -> AnyJsAssignment -> as_js_identifier_assignment, so member (obj.name += "") and element (arr[i] += "") targets are skipped; update the match for left (from node.left()) to, after trying as_js_identifier_assignment, also detect member and element assignment targets (e.g., as member/element variants on the AnyJsAssignment) and extract the target expression, then call the appropriate type check (use ctx.type_of_expression(node.range(), target_expr) or the existing helper that computes a target's type) instead of only ctx.type_of_named_value, ensuring member and element targets return their static type so the rule catches += "" on those as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs`:
- Around line 435-446: The current has_shadowed_binding function scans from the
file root and treats any identifier anywhere as shadowing; change it to find the
nearest enclosing lexical scope for the JsCallExpression (e.g., nearest
function, block, module/Script node) instead of using
call.syntax().ancestors().last(), then restrict the search to descendants of
that scope only and ensure bindings are actually in-scope (e.g., declared in the
same scope or an inner scope that would shadow the call), keeping the existing
checks on AnyJsIdentifierBinding, binding.name_token(), and binding.range() !=
call.range() to avoid self-matches; this both makes shadow detection lexically
correct and avoids walking the whole file for each call.
- Around line 282-290: The current match only handles JsIdentifierAssignment via
AnyJsAssignmentPattern -> AnyJsAssignment -> as_js_identifier_assignment, so
member (obj.name += "") and element (arr[i] += "") targets are skipped; update
the match for left (from node.left()) to, after trying
as_js_identifier_assignment, also detect member and element assignment targets
(e.g., as member/element variants on the AnyJsAssignment) and extract the target
expression, then call the appropriate type check (use
ctx.type_of_expression(node.range(), target_expr) or the existing helper that
computes a target's type) instead of only ctx.type_of_named_value, ensuring
member and element targets return their static type so the rule catches += "" on
those as well.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 33e9ca98-5f4e-47c4-8187-9da06bb7563d
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (6)
.changeset/upset-women-open.mdcrates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.tscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.tscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_useless_type_conversion.rs
✅ Files skipped from review due to trivial changes (4)
- .changeset/upset-women-open.md
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts
- crates/biome_rule_options/src/no_useless_type_conversion.rs
ematipico
left a comment
There was a problem hiding this comment.
Please make sure that all these internal functions have proper docstrings that explain their business logic
2b25728 to
0fc7465
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs (1)
434-436: Preferis_empty()overlen() == 0.Minor idiomatic nit.
Suggested change
AnyJsExpression::JsTemplateExpression(template_expression) => { - template_expression.elements().len() == 0 + template_expression.elements().is_empty() }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs` around lines 434 - 436, Replace the idiomatic check using len() == 0 with is_empty(): in the match arm for AnyJsExpression::JsTemplateExpression, change the conditional that calls template_expression.elements().len() == 0 to use template_expression.elements().is_empty() instead; update the expression in that match arm to call is_empty() on elements() to make the code idiomatic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs`:
- Around line 434-436: Replace the idiomatic check using len() == 0 with
is_empty(): in the match arm for AnyJsExpression::JsTemplateExpression, change
the conditional that calls template_expression.elements().len() == 0 to use
template_expression.elements().is_empty() instead; update the expression in that
match arm to call is_empty() on elements() to make the code idiomatic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 9d5f6734-40d4-42ff-af41-a176ddb89fe9
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (6)
.changeset/upset-women-open.mdcrates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.tscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.tscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_useless_type_conversion.rs
✅ Files skipped from review due to trivial changes (4)
- .changeset/upset-women-open.md
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts
- crates/biome_rule_options/src/no_useless_type_conversion.rs
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- crates/biome_rule_options/src/lib.rs
ematipico
left a comment
There was a problem hiding this comment.
- Docs need some rewording
- We should avoid recursions
- I believe we should add more targeted tests
975e8ad to
a3cac04
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts`:
- Around line 50-51: The double bitwise-not operator usage on the BigInt union
variable threeOrFourBigInt will throw; replace the `~~threeOrFourBigInt` usage
with a BigInt-safe alternative such as converting to a Number
(Number(threeOrFourBigInt)) if you need numeric coercion, or remove the `~~`
entirely and use an explicit check/operation that supports BigInt (e.g., compare
against 3n/4n or use BigInt arithmetic) to avoid the TypeError.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: f1679837-64f0-4e01-a9b1-5c0156373efc
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (7)
.changeset/upset-women-open.mdcrates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rscrates/biome_js_analyze/src/services/typed.rscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.tscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.tscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_useless_type_conversion.rs
✅ Files skipped from review due to trivial changes (4)
- crates/biome_rule_options/src/lib.rs
- .changeset/upset-women-open.md
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts
- crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs
🚧 Files skipped from review as they are similar to previous changes (2)
- crates/biome_js_analyze/src/services/typed.rs
- crates/biome_rule_options/src/no_useless_type_conversion.rs
| let left = node.left().ok()?; | ||
| let ty = match left { | ||
| AnyJsAssignmentPattern::AnyJsAssignment(assign) => { | ||
| let identifier = assign.as_js_identifier_assignment()?; | ||
| let name = identifier.name_token().ok()?; | ||
| ctx.type_of_named_value(node.range(), name.text_trimmed()) | ||
| } | ||
| _ => return None, | ||
| }; |
There was a problem hiding this comment.
Maybe it's worth adding issue_number to the metadata of the rule at this point, so we know things are still missing, but planned
a3cac04 to
dd78724
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/biome_js_analyze/src/services/typed.rs`:
- Around line 22-23: has_binding currently treats a missing SemanticModel (the
struct field model: Option<SemanticModel>) the same as "no binding", which hides
unavailability of semantic data; change has_binding to fail fast when model is
None instead of returning false (e.g., make has_binding return a Result<bool,
Error> or explicitly propagate an error/early return when model.is_none(), or
unwrap with a clear context if the phase guarantees availability), update all
callers of has_binding to handle the Result/propagated error (the call sites
noted around the other checks that rely on has_binding), and ensure any logic
that checks for global bindings uses SemanticModel directly so shadowed locals
aren’t misclassified as unbound.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 40df50f9-b521-49d3-8bf1-449e8a8c0a54
⛔ Files ignored due to path filters (9)
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rsis excluded by!**/migrate/eslint_any_rule_to_biome.rsand included by**crates/biome_configuration/src/analyzer/linter/rules.rsis excluded by!**/rules.rsand included by**crates/biome_configuration/src/generated/domain_selector.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_configuration/src/generated/linter_options_check.rsis excluded by!**/generated/**,!**/generated/**and included by**crates/biome_diagnostics_categories/src/categories.rsis excluded by!**/categories.rsand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts.snapis excluded by!**/*.snapand included by**crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts.snapis excluded by!**/*.snapand included by**packages/@biomejs/backend-jsonrpc/src/workspace.tsis excluded by!**/backend-jsonrpc/src/workspace.tsand included by**packages/@biomejs/biome/configuration_schema.jsonis excluded by!**/configuration_schema.jsonand included by**
📒 Files selected for processing (7)
.changeset/upset-women-open.mdcrates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rscrates/biome_js_analyze/src/services/typed.rscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.tscrates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.tscrates/biome_rule_options/src/lib.rscrates/biome_rule_options/src/no_useless_type_conversion.rs
✅ Files skipped from review due to trivial changes (3)
- .changeset/upset-women-open.md
- crates/biome_rule_options/src/no_useless_type_conversion.rs
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/valid.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- crates/biome_rule_options/src/lib.rs
- crates/biome_js_analyze/tests/specs/nursery/noUselessTypeConversion/invalid.ts
- crates/biome_js_analyze/src/lint/nursery/no_useless_type_conversion.rs
| model: Option<SemanticModel>, | ||
| } |
There was a problem hiding this comment.
Don’t treat “missing semantic model” as “no binding”.
Right now has_binding returns false both when a reference is truly unbound and when SemanticModel is absent. That can leak false positives for shadowed globals. Since this service runs in Phases::Semantic, it should fail fast if SemanticModel is unavailable.
Suggested fix
pub struct TypedService {
resolver: Option<Arc<ModuleResolver>>,
- model: Option<SemanticModel>,
+ model: SemanticModel,
}
@@
pub fn has_binding(&self, reference: &JsReferenceIdentifier) -> bool {
- self.model
- .as_ref()
- .is_some_and(|model| model.binding(reference).is_some())
+ self.model.binding(reference).is_some()
}
@@
- let model = services.get_service::<SemanticModel>().cloned();
- Ok(Self { resolver, model })
+ let model = services
+ .get_service::<SemanticModel>()
+ .cloned()
+ .ok_or_else(|| ServicesDiagnostic::new(rule_key.rule_name(), &["SemanticModel"]))?;
+ Ok(Self { resolver, model })
}Based on learnings: "Check if a variable is global using the semantic model before reporting rules that ban certain functions or variables to avoid false positives on locally redeclared variables."
Also applies to: 72-76, 97-98
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/biome_js_analyze/src/services/typed.rs` around lines 22 - 23,
has_binding currently treats a missing SemanticModel (the struct field model:
Option<SemanticModel>) the same as "no binding", which hides unavailability of
semantic data; change has_binding to fail fast when model is None instead of
returning false (e.g., make has_binding return a Result<bool, Error> or
explicitly propagate an error/early return when model.is_none(), or unwrap with
a clear context if the phase guarantees availability), update all callers of
has_binding to handle the Result/propagated error (the call sites noted around
the other checks that rely on has_binding), and ensure any logic that checks for
global bindings uses SemanticModel directly so shadowed locals aren’t
misclassified as unbound.
Summary
This adds
noUselessTypeConversion, a port of https://typescript-eslint.io/rules/no-unnecessary-type-conversiongenerated by gpt 5.4
Test Plan
snapshots
Docs