Skip to content

edition idioms lints: unused_extern_crate false positives #53964

Open
@japaric

Description

@japaric

STR

  1. Crates that provide lang items
$ cargo new --bin foo && cd $_

$ cargo add panic-abort # or any other crate only provides a `panic_handler` function

$ cat >src/main.rs <<'EOF'
#![no_main]
#![no_std]

extern crate panic_abort;
EOF

$ # ignore linking; it's not important for this example
$ # also set panic to abort to simplify things
$ mkdir .cargo
$ cat >.cargo/config <<'EOF'
[build]
rustflags = ["-C", "panic=abort", "-C", "linker=true"]
EOF

$ cargo build && echo OK
OK

$ cargo rustc -- -D rust_2018_idioms
   Compiling foo v0.1.0 (file:///home/japaric/tmp/foo)
error: unused extern crate
 --> src/main.rs:4:1
  |
4 | extern crate panic_abort;
  | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it
  |
  = note: `-D unused-extern-crates` implied by `-D rust-2018-idioms`

error: aborting due to previous error

Removing the extern crate as per the suggestion breaks compilation:

$ cat src/main.rs
#![no_main]
#![no_std]

// extern crate panic_abort;
$ cargo build
   Compiling foo v0.1.0 (file:///home/japaric/tmp/foo)
error: `#[panic_handler]` function required, but not found

error: aborting due to previous error
  1. Crates that inject symbols dependencies
$ git clone https://github.com/rust-embedded/embedonomicon --branch edition-lint-false-positive-do-not-delete

$ cd embedonomicon/ci/main/app

$ cat src/main.rs
#![feature(panic_handler)]
#![no_std]
#![no_main]

extern crate rt;

use core::panic::PanicInfo;

#[no_mangle]
pub fn main() -> ! {
    let _x = 42;

    loop {}
}

#[panic_handler]
fn panic(_panic: &PanicInfo<'_>) -> ! {
    loop {}
}
$ rustup target add thumbv7m-none-eabi
$ cargo build && echo OK
OK

$ cargo rustc -- -D rust_2018_idioms
cargo rustc -- -D rust_2018_idioms
   Compiling app v0.1.0 (file:///home/japaric/tmp/embedonomicon/ci/main/app)
error: unused extern crate
 --> src/main.rs:4:1
  |
4 | extern crate rt;
  | ^^^^^^^^^^^^^^^^ help: remove it
  |
  = note: `-D unused-extern-crates` implied by `-D rust-2018-idioms`

error: aborting due to previous error

Removing the extern crate as suggested breaks linking.

$ sed -i '/extern crate/d' src/main.rs
$ cargo build
error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "gnu" (..)
  = note: rust-lld: error: malformed / incomplete vector table

The error above is a custom assertion that checks that the binary has the right memory layout. Removing extern crate rt produces an invalid (empty) binary.

Metadata

$ rustc -V
rustc 1.30.0-nightly (1c2e17f4e 2018-09-04)

(2) seems unfixable, or at least very hard to properly fix, to me since it requires knowing the dependencies between symbols and symbol information is only complete / exact after optimization, plus linker scripts can make some symbols required. A good enough fix could be to not warn about crates that expose public, reachable #[no_mangle] / #[export_name] symbols. In any case, I expect that in practice not many people will encounter this warning.

(1) should be fixable and should be fixed. The compiler should be able to determine if a crate contains lang items. This scenario I expect to be much more common since some of us, embedded devs, like to pack panic_handlers in crates as that makes it easy to switch between them.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-edition-2018Area: The 2018 editionA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions