Skip to content

Use inferred type in “extract type as type alias” assist #20125

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

nicolas-guichard
Copy link
Contributor

@nicolas-guichard nicolas-guichard commented Jun 30, 2025

This records the inferred type for type references in InferenceResult then uses that information in extract_type_alias to extract the inferred type.

Fixes #20108

This adds a type_of_type arena to InferenceResult to record which type
a given type reference gets inferred to.
This uses the new InferenceResult content to turn type references into
completely resolved types instead of just returning the lexical type.
When met with types with placeholders, this ensures this assist
extracts the inferred type instead of the type with placeholders.

For instance, when met with this code:
```
fn main() {
    let vec: Vec<_> = vec![4];
}
```
selecting Vec<_> and extracting an alias will now yield `Vec<i32>`
instead of `Vec<_>`.
@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 30, 2025
@flodiebold
Copy link
Member

I think that could be a lot of types to store, and we'd like to avoid making the InferenceResult bigger. I wonder if we could just store the inferred types of _ types. Or alternatively we could even determine them from the inferred variable types with a bit of unification. It does make this quite a bit more complicated though, admittedly.

@nicolas-guichard
Copy link
Contributor Author

alternatively we could even determine them from the inferred variable types with a bit of unification

I don't think that's doable in the general case. In the case of LetStmt maybe, but as you say that would be a lot of work to map the selected part of the type to the correct part of the pattern. For other cases such as func::<Vec<_>>(arg0, arg1); I don't think this would work.

I'll rework this to only store the inferred _ types. Ideally this can be re-used to implement #11722 too.

@flodiebold
Copy link
Member

For other cases such as func::<Vec<_>>(arg0, arg1); I don't think this would work.

We have the recorded type of func::<Vec<_>>, so it would just be a matter of unifying that type with the lowered type where there's a variable in place of _.

Maybe before reworking it, take a look at how the memory usage changes for rust-analyzer analysis-stats with and without the patch. It could very well be not that much memory.

@ChayimFriedman2
Copy link
Contributor

@flodiebold This regressed analysis-stats only by 3mb, so I think it's acceptable.

@ChayimFriedman2
Copy link
Contributor

Unfortunately this approach isn't enough, as all the intermediate types created during lowering won't appear in the InferenceResult. For example, if there is Vec<_>, the whole Vec<_> will appear but not the _. Furthermore, solving this will be difficult as the TyLoweringContext has no knowledge of the InferenceContext (we should change that, but that needs to wait on the trait solver migration). Also, doing it properly may indeed increase memory usage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extract type as type alias assist does not fill infer vars
4 participants