intellij-rust: error_chain's Result support

When using the error_chain crate it’s common to define the errors in a “errors.rs” mod and import them where needed with use errors::*.

This overrides the default Result<T,E> enum with a Result<T>, and intellij-rust reports all the functions using it as errors (Wrong number of arguments: expected 2, found 1 [E0243]).

I know it’s hard to parse macros (see #955), but I was wondering if there is a way to use annotations to declare the definition of enums, structs or functions (like // @defines Result<T> or similar) to use in the mod defining them, so that the parser recognizes them.

P.S.: sorry for the empty bug report earlier, I don’t know what I pressed to post it while writing… 😃

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 19
  • Comments: 17 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Make E0243 an inspection instead of annotation, so it could be opted out.

Yeah, we definitely should do this with perhaps most of the errors: combination of macros and shadowing leads to false positives 😦

Special casing error_chain! would be a nice addition!

I’ve been using this as a workaround, if anyone else is interested:

https://github.com/FauxFaux/error-chain-for-dumb-ides#error-chain-for-dumb-ides

@matklad this might be worth talking about on #964. RLS can expand both macros and procedcural macros.

I was recently at the error-chain meeting, and they were discussing moving to procedural macros, so I would definitely not recommend any sort of error-chain specific hacks.

Are there examples of such macro expansions in the plugin? I saw special cases for several macros, but they seem to only handle macro calls correctly, not to expand them.

No, there are no such examples yet. The general idea would be to create an RsFile with macro expanded code (the same way RsPsiFactory creates files), find the relevant nodes in this file and attach them via getContext mechanism to the macro call. We now handle name resolution of strings like foo::bar::baz in the similar way (the place to look at is RsCodeFragmentFactory).

So in the end you’ll have a MacroCall node, which has an .expansion property which holds a PSI node in an in-memory file. During resolve of a name, when you encounter a MacroCall, you process .expansion. And when you are resolving a name inside the expansion, everything should just work because resolve uses .getContext and not .getParent.

And there should be macro hygene somewhere in here, but we can definitely punt on it for the start 😃

Does this make any sense?