Hi, I am interested in tackling https://github.com/rust-analyzer/rust-analyzer/issues/5265. Would someone who is familiar with the current state of proc macro support be willing to give some tips on what needs to change and where to get started? Thank you! :)
It seems to me that something like that would only be possible if the proc macro "cooperates" and propagates the input identifiers instead of creating new ones. That way we can at least theoretically map between input and output tokens via
I don't know if this actually works correctly with proc macros though.
do we expand fn-like proc macros? I'm confused what the actual problem is now, is it expanding them or making IDE features work inside of them? If it's the latter, and we're expanding them already, Jonas is right. But the macros should already be doing that, if they want correct error spans in rustc, right? In that case the question does become whether we're tracking that correctly all the way through
Yeah we should be expanding them now (not correctly, mind you, but simple cases should work)
(renamed the issue to clarify what is being requested)
I have to admit I don't really know in detail how span tracking works in proc macros, don't they nowadays usually stringify and re-parse their input? :thinking:
or is that not the case anymore
I'm not sure either, syn might consume the tokens from the
@Jonas Schievink @Florian Diebold Using the
quote crates it is straightforward to propagate the input identifiers, and blocks wrapped in curly braces are passed through verbatim.
I am already observing some rudimentary support for fn-like proc macros in rust analyzer: the type of the return value is available on hover, even when there is no type annotation nearby that could be hinting it.
yeah, that's what you'd expect when we can expand the macro, but not track the tokens through the expansion
for IDE features to work inside the macro call, we need to know the connection between the tokens written in the source code, and the tokens in the expanded code. And that probably doesn't work right now
that makes sense
I am observing that the rust compiler is keeping track of that correctly. Red squiggles end up in the right places when there are errors.
that's good in the sense that it should at least be possible to do, then ;)
can you provide any guidance on where in the rust analyzer I could start digging to add this support?
we also already do it for macro_rules macros, so the infrastructure exists already. So the missing piece should "just" be to keep track in the proc-macro specific parts
One thing that isn't going to work is IDE support in incomplete proc macro input. The macro has to expand successfully or we don't get any output from it.
ah, that's true :(
ya, but at least getting it working for when the macro expands successfully would be a big step.
what if the macro was designed to be fault-tolerant, i.e. it expanded to produce partial rust code?
then it should work, but it's doubtful that many proc macros are.
syn would have to be able to parse incomplete code too
Thanks, I'm going to start looking into this and will let you know how it goes.
I can't tell you exactly what to do, but I'd start around here. This function gets a
Subtree and returns an expanded
Subtree. The tokens in this subtree have
TokenIds, and those need to be preserved. @Jonas Schievink am I missing something, or do fn-like proc macros also expand through
yes, it's a gross hack :D
you can use custom derives as
!-macros and vice-versa
@Jonas Schievink it seems that the changes you made in the last few days to proc-macros have to some extent implemented this feature!
uh, yeah, this seems to work wayyyy better than expected
I wonder if it was the token remapping fix that did this
They now basically work as well as MBE macros, at least in the cases I've tested
thanks! :) I am testing now and so far a lot is working.
I am seeing a lot of "proc macro server crashed" errors, I will try to get something small and reproducible and file an issue.
Is there a way of rebooting the proc macro server without restarting RA?
Not currently, no
But it prints the panic message to stderr
So it should show up in the output panel
I think we could send a
window/showMessageRequest to the client and prompt a restart if someone wanted to implement that
Yes, that would be good