-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Support trait auto import #3120
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
Yeah, this is unfortunate. I feel that we should more actively try to cut a nice API at the |
Maybe |
Had tried, almost works for me, but needs one more tweak, commented the PR. |
d3ef529
to
afc1d18
Compare
No more |
crates/ra_hir/src/source_analyzer.rs
Outdated
match self.resolve_path(db, &path_to_method)? { | ||
PathResolution::Def(ModuleDef::Adt(adt)) => { | ||
let ty = adt.ty(db); | ||
iterate_method_candidates( |
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.
Why do we need to do this here?
I would expect that we reoslve assoc functions during type inferece, and record the result in the appropriate map in InferenceResult
. Perhaps assoc_resolutions
are not properly filled in?
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.
That actually comes from a very confusing (to me) SourceAnalyzer behavior: when constructed for a module (as it had been done before in auto_import assist code: https://github.com/rust-analyzer/rust-analyzer/pull/3120/files#diff-9f55419f762ae3317cf277aab2d8e37aL36), it does not resolve anything related to the functions' types.
If constructed for a very small path under the coursor (as it is done now), it magically starts to resolve those types.
I've removed the module syntax search completely since it was redundant, but did not realize that this code is not needed anymore.
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.
This behavior depends on what the source_binder::find_container
function returns and I find it a bit strange, I would expect to be able to resolve all types, including the function-related ones when the whole module code is given to the analyzer.
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.
Yeah, this aspect of SourceAnalyzer is kind of a mess, you need to use the right source analyzer. We really should do something like lifting all sa methods to sb, such that they just work.
Not sure how to make that ergonomic though, because the caller would have to pass in InFile<ast::Foo>
things instead of just ast::Foo
.
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.
Yeah, this is something that has annoyed me as well. It would be nice if working with InFile<>
s would be more ergonomic in general, and then we could maybe put more API directly on them 🤔
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.
Thanks for the explanation.
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.
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.
Isn't and_then
a monad?
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.
We could at least e.g. add a cast<A: AstNode>(&self: InFile<SyntaxNode>) -> Option<InFile<A>>
...
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.
Oh, right, we do need full monadic power here :-(
And yeah, for full generality we need ReaderT monad transformer ;(
I wish we could do a simple Roslyn style api: https://github.com/dotnet/roslyn/wiki/Getting-Started-C%23-Semantic-Analysis
I checked |
Thanks for checking. Funny, intellij-rust does not provide an import for that function also. |
Lol, the person who wrote this sits in front of me :D I wonder if that 's a problem for us though -- we should handle |
Yeah, we should. I assume we don't do it correctly for libraries? (I.e. we want |
if proposed_imports.is_empty() { | ||
return None; | ||
} | ||
|
||
let mut group = ctx.add_assist_group(format!("Import {}", name_to_import)); | ||
let assist_group_name = if proposed_imports.len() == 1 { |
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.
i wonder if we should just automatically flatten singleton grups at the level of AssistCtx or even the code_actions handler?
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.
We could, we can do all those things on finish()
I think.
I though so as well, but unfortunately the fix is not this simple. We just don't take cfg into account when loweting impls here. We only use cfgs in |
bors r+ |
3120: Support trait auto import r=matklad a=SomeoneToIgnore Unfortunately, for real cases it does not work as spectacular as in the tests. The main reason for that is type inference: * The callee type [here](https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_hir_ty/src/method_resolution.rs#L369) is unknown for many cases * The trait solution [here](https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/ra_hir_ty/src/method_resolution.rs#L399) is also often ambiguous That results in trait candidates being rejected, and some real cases not supported. Example: no imports for `String::from_str("test")` Co-authored-by: Kirill Bulatov <[email protected]>
Build succeeded
|
Unfortunately, for real cases it does not work as spectacular as in the tests.
The main reason for that is type inference:
That results in trait candidates being rejected, and some real cases not supported.
Example: no imports for
String::from_str("test")