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

Compiler marks import as unnecessary when it isn't (panic_handler) #127852

Open
mysteriouslyseeing opened this issue Jul 17, 2024 · 6 comments
Open
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. L-unused_imports Lint: unused_imports T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@mysteriouslyseeing
Copy link

I tried this code:

lib.rs:

#![no_std]

#[cfg_attr(not(test), panic_handler)]
pub fn panic_handler(_info: &core::panic::PanicInfo<'_>) -> ! {
    loop {}
}

main.rs:

#![no_std]
#![no_main]

use playground;

Cargo.toml:

[package]
name = "playground"
version = "0.0.1"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

[profile.dev]
panic = "abort"

Upon running cargo check it gives this output:

warning: unused import: `playground`
 --> src/main.rs:4:5
  |
4 | use playground;
  |     ^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `playground` (bin "playground") generated 1 warning (run `cargo fix --bin "playground"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s

This is incorrect, as the import provides panic_handler for main, even though it is not directly imported.

To get a minimal reproduction you can run:
git clone --branch panic_handler_import_bug https://github.com/mysteriouslyseeing/playground.git

Note that cargo build will fail at linkage with that minimal reproduction due to the #![no_main] present. An alternate entry point would have to be specified based on the binaries' target to allow cargo build to work.

Meta

rustc --version --verbose: (stable)

rustc 1.79.0 (129f3b996 2024-06-10)
binary: rustc
commit-hash: 129f3b9964af4d4a709d1383930ade12dfe7c081
commit-date: 2024-06-10
host: x86_64-unknown-linux-gnu
release: 1.79.0
LLVM version: 18.1.7

rustc --version --verbose: (nightly)

rustc 1.81.0-nightly (032be6f7b 2024-07-16)
binary: rustc
commit-hash: 032be6f7bbe091c7dfa29f115e94b9cc9bae1758
commit-date: 2024-07-16
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7

cargo fix:

    Checking playground v0.0.1 (/home/wschroeder/Projects/playground)
warning: failed to automatically apply fixes suggested by rustc to crate `playground`
This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag

The following errors were reported:
error: `#[panic_handler]` function required, but not found

error: aborting due to 1 previous error

Original diagnostics will follow.

warning: unused import: `playground`
 --> src/main.rs:4:5
  |
4 | use playground;
  |     ^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `playground` (bin "playground") generated 1 warning (run `cargo fix --bin "playground"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06s

@mysteriouslyseeing mysteriouslyseeing added the C-bug Category: This is a bug. label Jul 17, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 17, 2024
@mysteriouslyseeing mysteriouslyseeing changed the title Compiler marks import as unnecessary if it only imports Compiler marks import as unnecessary when it isn't (panic_handler) Jul 17, 2024
@bjorn3
Copy link
Member

bjorn3 commented Jul 17, 2024

You can use use playground as _; to suppress this lint.

@mysteriouslyseeing
Copy link
Author

You can use use playground as _; to suppress this lint.

I don't actually need to suppress the lint, I noticed it while I was refactoring and realised that the resulting fix would break the program.

@jieyouxu jieyouxu added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. L-unused_imports Lint: unused_imports needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jul 17, 2024
@saethlin saethlin removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jul 17, 2024
@ChayimFriedman2
Copy link
Contributor

Alternatively use extern crate playground which is commonly used to link the crate.

@mysteriouslyseeing
Copy link
Author

Alternatively use extern crate playground which is commonly used to link the crate.

Or #[allow(unused_imports)]. I'm not looking for a solution for an annoying lint, I'm reporting a compiler bug.

@zachs18
Copy link
Contributor

zachs18 commented Aug 9, 2024

Similar example:

// lib.rs
#![no_std]
use num_traits;
pub fn f(x: f64) -> f64 {
    x.powf(3.14)
}
# Cargo.toml
[package]
name = "num-traits-std-powf"
version = "0.1.0"
edition = "2021"

[dependencies]
num-traits = { version = "0.2.19" }

This gives an unused_import warning for use_num_traits;, even though that causes std to be pulled in (through num_traits's default std feature), and removing it causes f64::powf to not exist and compilation to fail.

(Should this be a separate issue? It seemed related)

@mysteriouslyseeing
Copy link
Author

I checked and this also happens with using a custom allocator:
lib.rs:

#![no_std]

use core::alloc::GlobalAlloc;
extern crate alloc;

pub struct Allocator;

unsafe impl GlobalAlloc for Allocator {
    unsafe fn alloc(&self, _layout: core::alloc::Layout) -> *mut u8 {
        unimplemented!()
    }
    unsafe fn dealloc(&self, _ptr: *mut u8, _layout: core::alloc::Layout) {
        unimplemented!()
    }
}

#[global_allocator]
pub static ALLOCATOR: Allocator = Allocator;

main.rs:

#![no_std]
#![no_main]

extern crate alloc;

use core::panic::PanicInfo;

use playground;

#[cfg_attr(not(test), panic_handler)]
fn panic_handler(_info: &PanicInfo) -> ! {
    loop {}
}

cargo check:

warning: unused import: `playground`
 --> src/main.rs:6:5
  |
6 | use playground;
  |     ^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `playground` (bin "playground") generated 1 warning (run `cargo fix --bin "playground"` to apply 1 suggestion)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.00s

cargo check after removing import:

    Checking playground v0.0.1 (/home/wschroeder/Projects/playground)
error: no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait

error: could not compile `playground` (bin "playground") due to 1 previous error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. L-unused_imports Lint: unused_imports 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

7 participants