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

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

Open
sfmunoz opened this issue Jun 20, 2020 · 5 comments
Labels
A-lint 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-lint 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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lint 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