Most Rust static analysis tools hook into the compiler and get this for free.
Racer has that problem because racer implements a rudimentary minicompiler that's much faster than Rust. When you want autocompletion, it needs to be fast. Running a full type check is a non-starter here. So you implement your own "type searcher" which is able to perform some level of inference and search for items. Being deliberately incomplete, it doesn't handle some cases; looks like macros are one of them. Since racer uses syntex handling macros would not be much harder (just run the macro visitor first; three lines of code!), but I assume it doesn't for performance reasons or something.
(disclaimer: I only have a rough idea of racer's architecture; ICBW)
> But my real concern is how to write refactoring tools when macros are implied
This is a problem with refactoring whether or not you're using tools. And like you mention there's exactly the same problem with generated code. If anything, Rust macros being hygenic are nicer here, since you can trace back where the generated code comes from and _attempt_ to refactor the source.
And macros like try do not affect refactoring tools at all; being self-contained. Its user-defined macros that mess things up.
I didn't know that. Understood. Thank you for the explanation.
> And macros like try do not affect refactoring tools at all; being self-contained. Its user-defined macros that mess things up.
What do you mean by "self-contained"? How is it different from user-defined macros?
It doesn't introduce any new identifiers or anything. As far as refactoring is concerned, it's just another block with nothing interesting inside it. This is sort of highlighted by the fact that we can and do plan to add syntax sugar for try!() -- if it was a language feature it wouldn't cause refactoring issues, so why is that the case here?
User defined macros (there may be some exported library macros that do this too, but try is not one of them) may define functions or implement traits or something, which might need to be modified by your refactor, which might need fiddly modification of the macro internals.
(Also, note that due to Rust's macro hygiene, all variables defined within a macro are inaccessible in the call region, unless the identifier was passed in at the call region. This helps too)