Skip to content

function-like procedural macros: no dead_code warning on created code (e.g. "function is never used" warning) #73556

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
sfmunoz opened this issue Jun 20, 2020 · 5 comments
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-proc-macros Area: Procedural macros C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@sfmunoz
Copy link

sfmunoz commented Jun 20, 2020

Problem: I got no "function is never used" warning (dead_code) on code generated by function-like procedural macros

I dare say this is a bug but I'm fairly new to procedural macros and maybe I'm doing something wrong. After quite a lot of searching I was unable to figure out if that was really the case so I decided to open an issue.

Ref: https://doc.rust-lang.org/reference/procedural-macros.html

  • Cargo.toml:
$ cat Cargo.toml
[package]
name = "aux"
version = "0.1.0"
edition = "2018"

[lib]
proc-macro = true
  • src/lib.rs:
$ cat src/lib.rs
use proc_macro::TokenStream;
#[proc_macro]
pub fn make_dummy(_item: TokenStream) -> TokenStream {
    "fn dummy() {}".parse().unwrap()
}
  • src/main.rs:
$ cat src/main.rs
aux::make_dummy!();
fn dummy2() {}
fn main() {
    println!("hello");
}

Expected: with the previous code I expected two function is never used warnings:

  • The first one for the generated fn dummy() {} code
  • The second one for fn dummy2() {} code

Instead: I just got a warning on dummy2() but nothing on dummy():

$ cargo build
   Compiling aux v0.1.0 (/var/tmp/aux)
warning: function is never used: `dummy2`
 --> src/main.rs:2:4
  |
2 | fn dummy2() {}
  |    ^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: 1 warning emitted

    Finished dev [unoptimized + debuginfo] target(s) in 0.23s

Expanded code: both dummy() and dummy2() are there, but there's only a build warning on dummy2():

$ cargo expand --bin aux
    Checking aux v0.1.0 (/var/tmp/aux)
    Finished check [unoptimized + debuginfo] target(s) in 0.06s

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate std;
fn dummy() {}
fn dummy2() {}
fn main() {
    {
        ::std::io::_print(::core::fmt::Arguments::new_v1(
            &["hello\n"],
            &match () {
                () => [],
            },
        ));
    };
}

rustc version: I checked with the following versions of the compiler with same result:

  • rustc 1.44.1:
$ rustc --version --verbose
rustc 1.44.1 (c7087fe00 2020-06-17)
binary: rustc
commit-hash: c7087fe00d2ba919df1d813c040a5d47e43b0fe7
commit-date: 2020-06-17
host: x86_64-unknown-linux-gnu
release: 1.44.1
LLVM version: 9.0
  • rustc 1.46.0-nightly:
$ rustc --version --verbose
rustc 1.46.0-nightly (feb3536eb 2020-06-09)
binary: rustc
commit-hash: feb3536eba10c2e4585d066629598f03d5ddc7c6
commit-date: 2020-06-09
host: x86_64-unknown-linux-gnu
release: 1.46.0-nightly
LLVM version: 10.0
@sfmunoz sfmunoz added the C-bug Category: This is a bug. label Jun 20, 2020
@jonas-schievink
Copy link
Contributor

I believe suppressing lints on procedural macro output is intentional

@jonas-schievink jonas-schievink added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-proc-macros Area: Procedural macros labels Jun 20, 2020
@JohnTitor JohnTitor added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jul 5, 2020
@eminence
Copy link
Contributor

This can also be reproduced with a macro_use -- it doesn't need a proc macro. Is it the same root cause? Should I open a new issue specifically for the macro_use case?

@eminence
Copy link
Contributor

eminence commented Feb 26, 2021

Maybe related to #53209

@eminence
Copy link
Contributor

Related to #53975 and this bit of code:

// If this code originates in a foreign macro, aka something that this crate
// did not itself author, then it's likely that there's nothing this crate
// can do about it. We probably want to skip the lint entirely.
if err.span.primary_spans().iter().any(|s| in_external_macro(sess, *s)) {
// Any suggestions made here are likely to be incorrect, so anything we
// emit shouldn't be automatically fixed by rustfix.
err.allow_suggestions(false);
// If this is a future incompatible that is not an edition fixing lint
// it'll become a hard error, so we have to emit *something*. Also,
// if this lint occurs in the expansion of a macro from an external crate,
// allow individual lints to opt-out from being reported.
let not_future_incompatible =
future_incompatible.map(|f| f.reason.edition().is_some()).unwrap_or(true);
if not_future_incompatible && !lint.report_in_external_macro {
err.cancel();
// Don't continue further, since we don't want to have
// `diag_span_note_once` called for a diagnostic that isn't emitted.
return;
}
}

(I personally would very much like to opt-in to dead_code warnings on generated code)

@persytry
Copy link

persytry commented Apr 5, 2023

Is the Issue resolved?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. A-proc-macros Area: Procedural macros C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants