Skip to content

Conversation

@Gankra
Copy link
Contributor

@Gankra Gankra commented Nov 27, 2025

Summary

This is the final goto-targets with missing goto-definition/declaration implementations!
You can now theoretically click on all the user-defined names in all the syntax. 🎉

This adds:

  • goto definition/declaration on patterns/typevars
  • find-references/rename on patterns/typevars
  • fixes syntax highlighting of *rest patterns

This notably does not add:

  • goto-type for patterns/typevars
  • hover for patterns/typevars (because that's just goto-type for names)

Also I realized we were at the precipice of one of the great GotoTarget sins being resolved, and so I made import aliases also resolve to a ResolvedDefinition. This removes a ton of cruft and prevents further backsliding.

Note however that import aliases are, in general, completely jacked up when it comes to find-references/renames (both before and after this PR). Previously you could try to rename an import alias and it just wouldn't do anything. With this change we instead refuse to even let you try to rename it.

Sorting out why import aliases are jacked up is an ongoing thing I hope to handle in a followup.

Test Plan

You'll surely not regret checking in 86 snapshot tests

@Gankra Gankra changed the title [ty] Implement goto-definition/declaration for all syntax [ty] Implement patterns/typevars in the LSP Nov 27, 2025
@astral-sh-bot
Copy link

astral-sh-bot bot commented Nov 27, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@Gankra Gankra changed the title [ty] Implement patterns/typevars in the LSP [ty] Implement patterns and typevars in the LSP Nov 27, 2025
@Gankra Gankra added server Related to the LSP server ty Multi-file analysis & type inference labels Nov 27, 2025
@astral-sh-bot
Copy link

astral-sh-bot bot commented Nov 27, 2025

mypy_primer results

Changes were detected when running on open source projects
beartype (https://github.com/beartype/beartype)
- beartype/claw/_package/clawpkgtrie.py:66:29: warning[unsupported-base] Unsupported class base with type `<class 'dict[str, PackagesTrieBlacklist]'> | <class 'dict[str, Divergent]'>`
- beartype/claw/_package/clawpkgtrie.py:247:29: warning[unsupported-base] Unsupported class base with type `<class 'dict[str, PackagesTrieWhitelist]'> | <class 'dict[str, Divergent]'>`
- Found 500 diagnostics
+ Found 498 diagnostics

No memory usage changes detected ✅

Comment on lines 1478 to 1482
let (symbol_name, is_reexported) = if let Some(asname) = &alias.asname {
self.scopes_by_expression
.record_expression(asname, self.current_scope());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This one is actually useless I think (I added it while thrashing and trying to get imports rename/reference working... it did not work).

Copy link
Member

Choose a reason for hiding this comment

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

Should we remove it then? Seems easy enough to add once we know why we need it

Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Nice, this actually streamlines things :)

) -> Option<DefinitionsOrTargets<'db>> {
use crate::NavigationTarget;
) -> Option<Definitions<'db>> {
match self {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: You could reduce the boilerplate here, I think, by doing something like:

let definitions = match self {
    GotoTarget::Expression(expression) => {
        definitions_for_expression(model, *expression)
    },
    GotoTarget::FunctionDef(function) => {
        Some(vec![ResolvedDefinition::Definition(
            function.definition(model),
        )])
    },
    ...
};

definitions.map(Definitions)

Comment on lines +1067 to +1068
self.scopes_by_expression
.record_expression(name, self.current_scope());
Copy link
Member

Choose a reason for hiding this comment

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

Should we add a record_name method or at least rename the struct (or update its documentation) to explain that, yes, it's mostly expressions but sometimes it's names too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is probably a good idea, I'll integrate it into some followup work I have planned that will involve more reckoning about ""expressions""

Comment on lines 1478 to 1482
let (symbol_name, is_reexported) = if let Some(asname) = &alias.asname {
self.scopes_by_expression
.record_expression(asname, self.current_scope());
Copy link
Member

Choose a reason for hiding this comment

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

Should we remove it then? Seems easy enough to add once we know why we need it

@Gankra Gankra enabled auto-merge (squash) November 28, 2025 13:38
@Gankra Gankra merged commit c534bfa into main Nov 28, 2025
40 checks passed
@Gankra Gankra deleted the gankra/stmtz branch November 28, 2025 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants