Stream: t-compiler/rust-analyzer

Topic: monomorphised go to definition


Daniel Mcnab (Apr 06 2021 at 11:50, on Zulip):

Please hold: Got hit by enter to submit

Daniel Mcnab (Apr 06 2021 at 11:57, on Zulip):

I often find myself trying to work out what code gets called in a specific instantiation of a generic function, e.g. in

trait Flob {
              fn flobulate(self){...} //<-E
}
impl Flob for u32 {
              fn flobulate(self){...} //<- D
}
fn exec<T: Flob>(val: T) { // <-B
    val.flobulate(); // <-C
}
fn main(){
     exec(10u32); <-A
}

I would click go to definition on exec at A, which would take me to B. I'd then click go to definition of flobulate at C, which I would want to take me to D, but instead takes me to E, which doesn't actually show me the code which is run. This means that I have to drop what I'm trying to find out, and manually track which types are used in the instantiation I am interest with, trace them though (following associated types manually, for example) and then track down the specific trait implementation which is actually used.
This is not fun, and feels like something rust-analyzer could help with.

Daniel Mcnab (Apr 06 2021 at 12:00, on Zulip):

I mostly want to confirm that this is an issue that other people are having and think solutions could exist for. I suppose really rust-analyzer#4558 would be a necessary prerequisite.

Daniel Mcnab (Apr 06 2021 at 12:05, on Zulip):

My proposed user experience would be that when you follow a go to definition on a generic function, if specific type information is available (either from this procedure or because the call does not use the current context's generics), the generics the function is used with are pushed onto a stack somewhere. Ideally, going back using mouse 4 or alt-left would pop this stack. These generics would then be used to get the specific type information for the first step as far as possible. These types could also be displayed as inlay hints next to the generics, i.e.

fn exec<T: Flob{inlay hint: =u32}>(val: T) { // <-B
    val.flobulate(); // <-C
}

in my example

Daniel Mcnab (Apr 06 2021 at 12:07, on Zulip):

Oh, I think this is exactly <https://github.com/rust-analyzer/rust-analyzer/issues/2541#issuecomment-565199436>, so it's already on the radar.

matklad (Apr 06 2021 at 12:08, on Zulip):

Yes, I'd love to see this. E-hard + E-fun though.

matklad (Apr 06 2021 at 12:08, on Zulip):

@Daniel Mcnab could you post this as an issue? The existing issue is all other the place, we need something more specific here.

matklad (Apr 06 2021 at 12:09, on Zulip):

Should also link to the issue about goto definition going to an impl (one of the most voted for)

Daniel Mcnab (Apr 06 2021 at 12:11, on Zulip):

E-herculean

Daniel Mcnab (Apr 06 2021 at 12:30, on Zulip):

@matklad in your example in https://github.com/rust-analyzer/rust-analyzer/issues/2541#issuecomment-565199436, where would you press go to definition the second time? On the {} in the format string?

matklad (Apr 06 2021 at 12:34, on Zulip):

uh, indeed that's a bad example, as it doesn't literarly call fmt

Daniel Mcnab (Apr 06 2021 at 12:34, on Zulip):

Added a comment to #3419

Daniel Mcnab (Apr 06 2021 at 12:36, on Zulip):

Right, made rust-analyzer#8373

Florian Diebold (Apr 06 2021 at 15:07, on Zulip):

doing this properly will require LSP support, right? at least so the substitution stack can be pushed/popped in the right moments

matklad (Apr 06 2021 at 15:15, on Zulip):

Maybe? If we add some special short-cut here, like "goto def with subst", then we need support. If we somehow piggy back that on top of usual goto def, then we don't need extra support

Daniel Mcnab (Apr 06 2021 at 15:35, on Zulip):

Pushing the stack should be easy enough to track, although we do have to think about the unbounded memory use it implies (since ideally you'd be able to have an infinite sidetrack somewhere else without losing your place, although that might be unreasonable.
Popping would be more difficult, we'd have to intercept workbench.action.navigateBack, which might not be possible in vscode; then make a custom protocol for it.

rpjohnst (Apr 07 2021 at 18:47, on Zulip):

another possibility ux-wise comes from vs, which lets you pick the type arguments from a dropdown based on find-all-references: https://devblogs.microsoft.com/cppblog/visual-studio-c-template-intellisense-populates-based-on-instantiations-in-your-code/

rpjohnst (Apr 07 2021 at 18:47, on Zulip):

no idea if that kind of extra ui is possible with lsp though

Jonas Schievink [he/him] (Apr 07 2021 at 18:50, on Zulip):

that looks sick! but also not possible without extra client support

Daniel Mcnab (Apr 07 2021 at 19:47, on Zulip):

That seems like kind of the reverse - I almost commented that kind of idea, but I hadn't seen the Visual studio implementation of it

Jeremy Kolb (Apr 07 2021 at 21:47, on Zulip):

Maybe you could get around it with a code action or custom command but I think this is worth an issue on https://github.com/microsoft/language-server-protocol/ for the protocol support for goto def UI changes

Last update: Jul 24 2021 at 21:15UTC