Skip to content

edition idioms lints: unused_extern_crate false positives #53964

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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