rust-lang / miri

An interpreter for Rust's mid-level intermediate representation
Apache License 2.0
4.16k stars 318 forks source link

MIRI_NO_STD can lead to very confusing errors #3529

Closed RalfJung closed 2 months ago

RalfJung commented 2 months ago

To reproduce, consider the following crate:

[package]
name = "embeddedMiri"
version = "0.1.0"
edition = "2021"

[profile.dev]
panic ='abort'

[profile.release]
panic ='abort'

[dependencies]
panic-semihosting = "0.6.0"

with main.rs being

#![no_std]
#![feature(start)]

use panic_semihosting as _;

#[start]
fn main(_argc: isize, _argv: *const *const u8) ->isize{
    panic!("hello")
}

It turns out panic_semihosting actually needs std on targets that do not satisfy all(target_arch = "arm", target_os = "none").

When running this with a truly no-std target such as x86_64-unknown-none, this is very clear from the error:

error[E0463]: can't find crate for `std`
  |
  = note: the `x86_64-unknown-none` target may not support the standard library
  = note: `std` is required by `panic_semihosting` because it does not declare `#![no_std]`
  = help: consider building the standard library from source with `cargo build -Zbuild-std`

However, when one does MIRI_NO_STD=1 cargo miri run to run this without std on a target that has std, the error is pretty bad:

error[E0463]: can't find crate for `panic_semihosting`
 --> src/main.rs:4:5
  |
4 | use panic_semihosting as _;
  |     ^^^^^^^^^^^^^^^^^ can't find crate

error[E0463]: can't find crate for `panic_semihosting`
 --> src/main.rs:4:5
  |
4 | use panic_semihosting as _;
  |     ^^^^^^^^^^^^^^^^^ can't find crate
  |
  = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`

error: `#[panic_handler]` function required, but not found

error: aborting due to 3 previous errors

I don't know exactly why that is. But my current inclination is to just remove the MIRI_NO_STD env var; it shouldn't be needd as -none targets get built without std automatically...

RalfJung commented 2 months ago

Amusingly, MIRI_NO_STD=1 cargo miri run --target i686-unknown-linux-gnu actually gives a nice error. It is only MIRI_NO_STD=1 with the host target that produces a bad error.

RalfJung commented 2 months ago

Somehow https://github.com/rust-lang/rust/pull/124582 did not help, this still prints the same bad error. I don't know why things behave different for the host target vs anther target.

RalfJung commented 2 months ago

Ah, the issue arises when first doing cargo miri run and then later MIRI_NO_STD=1 cargo miri run. There's stuff cached in the target dir that seems to confuse rustc. cargo miri clean fixes this.

I think that's good enough for now; though if MIRI_NO_STD keeps confusing people maybe we should entirely remove it.