Diference between #[allowed(unused_variables)] and _

Hello everyone,
I’m writing some code where, when I call a function from the genpdf crate called set_header, it generates a variable representing the pages, but I don’t need to use it.
There are two ways I know of to tell the compiler that I don’t need to use it. My question is: what is the difference between using #[allowed(unused_variables)] and _<variable_name>?

fn decorator_pdf(file_decorator: &mut Document) {
    let mut decorator = SimplePageDecorator::new();
    decorator.set_margins(10);

    #[allow(unused_variables)]
    decorator.set_header(|page_number| {
        let mut layout = LinearLayout::vertical();
        let bre = elements::Break::new(2);

        layout.push(
            elements::Paragraph::new("Github user activity")
                .styled(style::Style::new().bold().with_font_size(18)),
        );

        layout.push(bre);
        layout
    });

    file_decorator.set_page_decorator(decorator);
}
fn decorator_pdf(file_decorator: &mut Document) {
    let mut decorator = SimplePageDecorator::new();
    decorator.set_margins(10);

   
    decorator.set_header(|_page_number| {
        let mut layout = LinearLayout::vertical();
        let bre = elements::Break::new(2);

        layout.push(
            elements::Paragraph::new("Github user activity")
                .styled(style::Style::new().bold().with_font_size(18)),
        );

        layout.push(bre);
        layout
    });

    file_decorator.set_page_decorator(decorator);
}

Thank you very much for clarifying that

The former allows all unused variables in the corresponding expression (that is, it suppresses the warning if you accidentally leave something else unused inside the callback). The latter influences that one variable only.

@Cerber-Ursi Thank you very much for its explain,helping me to understand concept and you use.

In addition to cerber-ursi's comment, which is very important:

I use them to meant different things to "future me":

  • let _ = do_task()? for something that returns a value I am never going to care about. [Rare case]
  • let _checksum = update(&buf, Val)? so I know what it is that I'm choosing to ignore [Sometimes]
  • #[expect(unused_something, reason="handling foo not yet implemented"] for work in progress. I mentally forbid "allow" - with "expect" I get a like in future to remove it, "allow" has a nasty habit of becoming a zombie
  • #[allow(unused_variables, reason="foo only used in tests/windows/feature-x")] the one case for allow, where the code is sometimes used, depending on cfg

So in your case, I would personally go with let _pages = set_header(...)

that is not completely correct.
let _ = x does not bind x, whereas let _unused = x does.

let x : String = "x".to_owned();
let _ = x;
println!("{x} is still here !"); // compiles because x has not been dropped

because x is not bound, if it is a value expression then it will be dropped, because it's not bound to anything.
but if it is a place like the example i just showed, it will not be moved out and thus not dropped.

here is an example of all the cases i could think of

@Morgane55440 @MusicalNinjaDad @giocri Many thanks to everyone who replied to my post and helped me understand a new concept.