Skip to content
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

🐛 correctness/noUnusedVariables inferring in unions reports unused variables #565

Closed
1 task done
netner-d opened this issue Oct 20, 2023 · 6 comments · Fixed by #657
Closed
1 task done

🐛 correctness/noUnusedVariables inferring in unions reports unused variables #565

netner-d opened this issue Oct 20, 2023 · 6 comments · Fixed by #657
Assignees
Labels
A-Linter Area: linter L-JavaScript Language: JavaScript and super languages S-Bug-confirmed Status: report has been confirmed as a valid bug

Comments

@netner-d
Copy link

Environment information

CLI:
  Version:                      1.3.0
  Color support:                true

Platform:
  CPU Architecture:             aarch64
  OS:                           macos

Environment:
  BIOME_LOG_DIR:                unset
  NO_COLOR:                     unset
  TERM:                         "xterm-256color"
  JS_RUNTIME_VERSION:           "v18.18.2"
  JS_RUNTIME_NAME:              "node"
  NODE_PACKAGE_MANAGER:         "yarn/1.22.19"

Biome Configuration:
  Status:                       Loaded successfully
  Formatter disabled:           false
  Linter disabled:              false
  Organize imports disabled:    false
  VCS disabled:                 true

Workspace:
  Open Documents:               0

What happened?

Infering in unions reports unused variables on leading infered type variables.

// Nonesense type, just so you get the idea
type TestUnionType<T> = T extends (infer B)[] | infer B ? B : never;
//                                       ^
//                                       "This variable is unused"

type Value = TestUnionType<"">; // ""
type Value2 = TestUnionType<["", "okok"]>; // "" | "okok"

Expected result

noUnusedVariables shouldn't be reported

Code of Conduct

  • I agree to follow Biome's Code of Conduct
@netner-d netner-d changed the title 🐛 correctness/noUnusedVariables 🐛 correctness/noUnusedVariables inferring in unions reports unused variables Oct 20, 2023
@Conaclos Conaclos added A-Linter Area: linter L-JavaScript Language: JavaScript and super languages S-Bug-confirmed Status: report has been confirmed as a valid bug labels Oct 20, 2023
@Conaclos Conaclos self-assigned this Oct 20, 2023
@Conaclos
Copy link
Member

Conaclos commented Oct 20, 2023

This is a tricky case. TypeScript has so many exceptions...

Our name resolver has the assumption that a binding is bound to a single declaration. Here B is declared at different places. I am unsure how to fix the issue. We could ignore extra declarations or turn them into reads, however this conflicts with another assumption: every binding identifier has an associated semantic binding.

@denbezrukov @ematipico any thoughts?

Maybe emit different bindings and duplicate the read for every binding?

@Conaclos Conaclos removed their assignment Oct 20, 2023
@ematipico
Copy link
Member

ematipico commented Oct 20, 2023

I might not know few things, so I might get things wrong.

Given this code

T extends (infer B)[] | infer B ? B : never

Isn't B declared twice in two different scopes? On scope in (infer B)[] and the second scope in infer B ? B : never?

@Conaclos
Copy link
Member

Conaclos commented Oct 20, 2023

Unfortunately not, it is the same declaration :/

If you hover and click on the B reference in TypeScript Playground, you notice that the reference is bound to these two declarations.

@Conaclos
Copy link
Member

Conaclos commented Oct 20, 2023

On reflection, we could bind multiple binding identifiers to the same semantic binding. This could solve our problem without destroying all our assumptions. This will require a refactoring of how we identify a semantic binding (for now we identify it using the binding identifier's scope). I am not 100% happy about this because it prevents some optimizations I was planning to do. However, this seems like the best compromise to me.

EDIT: we still have an issue by adopting this approach: several syntax nodes are associated to the same semantic binding. This seems really wrong to make more complex the API just for infer bindings...

@Conaclos
Copy link
Member

Conaclos commented Nov 2, 2023

Instead of introducing exceptions in the semantic model, we could just ignore infer T that precedes another infer T.

@ematipico
Copy link
Member

Yeah, we could try this approach

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Linter Area: linter L-JavaScript Language: JavaScript and super languages S-Bug-confirmed Status: report has been confirmed as a valid bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants