Skip to content
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

Feature request: Expand macro single step #11888

Open
CAD97 opened this issue Apr 3, 2022 · 7 comments
Open

Feature request: Expand macro single step #11888

CAD97 opened this issue Apr 3, 2022 · 7 comments
Labels
A-ide general IDE features A-macro macro expansion C-feature Category: feature request E-unknown It's unclear if the issue is E-hard or E-easy without digging in fun A technically challenging issue with high impact

Comments

@CAD97
Copy link
Contributor

CAD97 commented Apr 3, 2022

We already have the "Expand macro recursively" action, which is useful for seeing what a macro eventually expands to if it successfully expands. However, for debugging e.g. tt muncher macros, it can be very useful to expand a single step in macro expansion, to track how the macro processes along the way.

A key feature is that it can't just show the first level of expansion, it also has to be possible to choose any macros in the output and expand those (a single step).

@Veykril Veykril added fun A technically challenging issue with high impact E-unknown It's unclear if the issue is E-hard or E-easy without digging in A-macro macro expansion C-feature Category: feature request A-ide general IDE features labels Apr 3, 2022
@Veykril
Copy link
Member

Veykril commented Apr 3, 2022

Easily going back up into the previous expansion would also be very nice to have (basically full expansion tree traversal)

cc #5949, #10548

@tfpk
Copy link
Contributor

tfpk commented Dec 20, 2022

Howdy -- I'm currently taking a look at this (particularly because it'd work really well with my macrokata project).

My plan is the following: create an action very similar to expandMacro, but rather than popping open a new window, do an in-place replacement. This will mean that going in and out of depth is very easy (going backwards is just an undo, going forwards is a repetition of the expandSingleMacro command).

Some questions that I'd like to raise as I'm working on this:

  • This is not a "safe" operation (in that it can produce correct but different code) -- is it worth wrapping expansions in unsafe? Or are we happy that anyone using this operation should know it's not perfect?
  • Is it more important to expand $crate (which is more likely to lead to working code), or should we leave it un-expanded so it's a literal expansion of the macro?

Would appreciate your perspective! Thanks :)

@Veykril
Copy link
Member

Veykril commented Dec 20, 2022

What you want to do sounds more like #13598

This is not a "safe" operation (in that it can produce correct but different code) -- is it worth wrapping expansions in unsafe? Or are we happy that anyone using this operation should know it's not perfect?

unsafe has a completely different meaning, so that's not a good idea, its fine if the action isnt perfect, a lot of r-a's assists are still imperfect

Is it more important to expand $crate (which is more likely to lead to working code), or should we leave it un-expanded so it's a literal expansion of the macro?

Ideally we'd replace that with the proper crate identifier, but that is somewhat tricky to do since the crate name changes depending on the crate we are inlining the expansion into.

But ye, any discussions regarding your idea would be better suited in the linked issue I think.

bors added a commit that referenced this issue Jan 9, 2023
Add action to expand a declarative macro once, inline. Fixes #13598

This commit adds a new r-a method, `expandMacroInline`, which expands the macro that's currently selected. See  #13598 for the most applicable issue; though I suspect it'll resolve part of #5949 and make #11888 significantly easier).

The macro works like this:

![rust-analyser-feature](https://user-images.githubusercontent.com/10906982/208813167-3123e379-8fd5-4206-a4f4-5af1129565f9.gif)

I have 2 questions before this PR can be merged:

1. **Should we rustfmt the output?** The advantage of doing this is neater code. The disadvantages are we'd have to format the whole expr/stmt/block (since there's no point just formatting one part, especially over multiple lines), and maybe it moves the code around more in weird ways. My suggestion here is to start off by not doing any formatting; and if it appears useful we can decide to do formatting in a later release.
2.   **Is it worth solving the `$crate` hygiene issue now?** -- I think this PR is usable as of right now for some use-cases; but it is annoying that many common macros (i.e. `println!()`, `format!()`) can't be expanded further unless the user guesses the correct `$crate` value. The trouble with solving that issue is that I think it's complicated and imperfect. If we do solve it; we'd also need to either change the existing `expandMacro`/`expandMacroInline` commands; provide some option to allow/disallow `$crate` expanding; or come to some other compromise.
@crazymerlyn
Copy link

Should this be marked fixed with #13810 or is there anything still left to be done?

@Veykril
Copy link
Member

Veykril commented Jan 14, 2024

That one is a different thing. What the issue talks about here is merely viewing a single macro expansion step (and then potentially step further).

@crazymerlyn
Copy link

I'm not sure I understand. From what I can see, the current "Inline macro" code action only expands one level of macro.

For example, when using "Inline macro" on

macro_rules! calculate {
    ($e:expr) => {{ $e }};
    ($e:expr, $($es:expr),+) => {{
        $e +
        calculate! { $($es),+ }
    }};
}

fn main() {
    let _a = calculate! {1,2,3};
}

I get:

macro_rules! calculate {
    ($e:expr) => {{ $e }};
    ($e:expr, $($es:expr),+) => {{
        $e +
        calculate! { $($es),+ }
    }};
}

fn main() {
    let _a = {
  1+calculate!{
    2,3
  }
};
}

Do you mean something else when you say "one step"?

@CAD97
Copy link
Contributor Author

CAD97 commented Jan 14, 2024

The "expand macro recursively" intent shows the macro expansion in a fresh window without editing the source. "Expand macro inline" does work to satisfy the underlying desire, but a full realization of the feature request is more like an interactive macro debugger, able to step through expansion to determine what's being done without modifying the original source. (But "expand macro inline" is the functionality which would power the visualization (almost, because hygiene).)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ide general IDE features A-macro macro expansion C-feature Category: feature request E-unknown It's unclear if the issue is E-hard or E-easy without digging in fun A technically challenging issue with high impact
Projects
None yet
Development

No branches or pull requests

4 participants