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

Spurious unreachable_code warning when todo! or unreachable! is used inside html! #379

Open
coreyja opened this issue Apr 26, 2023 · 4 comments
Labels

Comments

@coreyja
Copy link

coreyja commented Apr 26, 2023

Thanks for the awesome Library! I'm using it in a couple of small projects, and really liking it!

One thing I was realizing today is that it doesn't seem like I can use 'panicking' macros like todo! or unreachable! from within the html! macro, without a warning

For example in my blog I have some code to convert a Markdown AST to HTML using Maud. I wanted to use a match like this to get the correct heading element, but the following gives a warning about unreachable_code. Adding allow[unreachable_code] above the macro just leads to a new warning telling that allow is not needed

Since this is a warning its not the end of the world, but since I usually turn warnings into errors I've worked around this in my application by moving the panics out the macro

html! {
  @match self.depth {
    1 => h1 { (self.content) },
    _ => todo!(),
  }
}
@coreyja
Copy link
Author

coreyja commented Apr 26, 2023

Of course about 2 minutes after posting this, and using the rust-analyzer expand macro tool I got a version I'm happy with!
This compiles without warnings for me!

        html! {
            @match self.depth {
                1 => h1 { (content) },
                2 => h2 { (content) },
                3 => h3 { (content) },
                4 => h4 { (content) },
                5 => h5 { (content) },
                6 => h6 { (content) },
                #[allow(unreachable_code)]
                _ => (unreachable!("Invalid heading depth")),
            }
        }

Feel free to close this issue, if you would like! Thanks again for the awesome tool!

@lambda-fairy
Copy link
Owner

Hi @coreyja, thanks for the report. I'm curious why this warning comes up. Would you like to share the output of the expand tool?

@lambda-fairy lambda-fairy changed the title Support panicking macros like todo! and unreachable! inside html! Macro Spurious unreachable_code warning when todo! or unreachable! is used inside html! Jul 30, 2023
@coreyja
Copy link
Author

coreyja commented Jul 31, 2023

This produces the warning

 let output = html! {
    @match self.depth {
    1 => h1 { (content) },
    _ => (unreachable!()),
    }
};

And expands to (I expanded a call to render_to! as well)

let output = {
  extern crate alloc;
  extern crate maud;
  let mut __maud_output = alloc::string::String::with_capacity(70usize);
  match self.depth {
    1 => {
      __maud_output.push_str("<h1>");
      maud::macro_private::render_to!(&content, &mut __maud_output);
      __maud_output.push_str("</h1>");
    }
     _ => {
       {
         use maud::macro_private::*;
         match ChooseRenderOrDisplay(&unreachable!()) {
           x => x
                .implements_render_or_display()
                .render_to(x.0, &mut __maud_output),
         }
       };
      }
    }maud::PreEscaped(__maud_output)
};

I believe this fires the warning because we are using the values of the unreachable to pass into the ChooseRenderOrDisplay struct

Adding the #[allow(unreachable_code)] above that level in the match produces the following and DOES silence the warning:
[Left the render_to! unexpanded this time for brevity]

let output = {
  extern crate alloc;
  extern crate maud;
  let mut __maud_output = alloc::string::String::with_capacity(99usize);
  match self.depth {
    1 => {
      __maud_output.push_str("<h1>");
      maud::macro_private::render_to!(&content, &mut __maud_output);
      __maud_output.push_str("</h1>");
    }
    #[allow(unreachable_code)]
    _ => {
      maud::macro_private::render_to!(&unreachable!(), &mut __maud_output);
    }
  
    }maud::PreEscaped(__maud_output)
};

@lambda-fairy
Copy link
Owner

I wonder why the warning is triggering on generated code. Marking #[allow(unreachable_code)] will fix the immediate issue, but might hide actual unreachable code (however unlikely that might be). I remember the codegen used to be quite sloppy about spans, so perhaps the real fix is in there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants