See first comment for an even smaller example of the issue. Thanks @mgattozzi for the insight that led to that!
I was integrating NonZeroU8 into some code when I ran into an illegal instruction error that looks like this:
thread panicked while panicking. aborting.
error: process didn't exit successfully: `/path/to/my/project/target/debug/deps/xxxx-b71130afded4f9e4` (signal: 4, SIGILL: illegal instruction)
I spent a really long time trying to narrow this down and I got down to the following contrived example: (Rust Playground)
use std::{
fmt,
num::NonZeroU8,
};
pub struct Foo;
impl fmt::Display for Foo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", NonZeroU8::new(0).unwrap())
}
}
#[test]
fn something() {
panic!("{}", Foo);
}
This probably looks like super weird code that no one would ever write, but this started from some real code I promise. :laughing:
The key part of this code is:
NonZeroU8::new(0).unwrap()
The illegal instruction error occurs whenever that 0 is any value less than or equal to zero. You may be asking yourself "How do you make a u8 literal less than zero?" Well you don't. Rust protects you from that. The thing that Rust doesn't protect you from is this: (Rust Playground)
let y = 3;
let x = 2 - y;
write!(f, "{}", NonZeroU8::new(x).unwrap())
The variable x will be -1 and the code will produce the same illegal instruction error.
Some weird things to note about this:
cargo run. The failure is on cargo test.Display. Inlining does NOT produce the error:// No illegal instructions for this code!
use std::num::NonZeroU8;
#[test]
fn something() {
panic!("{}", NonZeroU8::new(0).unwrap());
}
The real MVP @mgattozzi realized what the problem was in a second. The display impl panics within the panic in the test and that's what causes the problem. Here's an even more minimal reproduction:
use std::fmt;
pub struct Foo;
impl fmt::Display for Foo {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
panic!()
}
}
#[test]
fn something() {
panic!("{}", Foo);
}
thread panicked while panicking. aborting.
error: process didn't exit successfully: `/playground/target/debug/deps/playground-b71130afded4f9e4` (signal: 4, SIGILL: illegal instruction)
I guess you could say I did a good job writing this issue given that someone was able to take a cursory look at it and figure out so much. Sorry I didn't catch it myself! :laughing:
I'm going to close this issue because I think this is expected behaviour.
I totally misunderstood the bug and thought it was happening during compilation. Sorry about that folks! :fearful:
Looks like it's time for me to go to bed. :sleeping:
Most helpful comment
The real MVP @mgattozzi realized what the problem was in a second. The display impl panics within the panic in the test and that's what causes the problem. Here's an even more minimal reproduction:
I guess you could say I did a good job writing this issue given that someone was able to take a cursory look at it and figure out so much. Sorry I didn't catch it myself! :laughing: