miette icon indicating copy to clipboard operation
miette copied to clipboard

Miri complains about miette code

Open ilyvion opened this issue 1 year ago • 3 comments

This might be a false positive (as indicated by miri in its help text), but I figured it's better to report it and have it be a false report than to leave it unreported and have there be a potential source of undefined behavior.

I run miri against all my code bases (because why not?) and I was hit by this today when trying to debug print a Result<(), miette::Report>:

error: Undefined Behavior: trying to reborrow from <5953> for SharedReadOnly permission at alloc1952[0x18], but that tag does not exist in the borrow stack for this location
   --> /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/error.rs:493:5
    |
493 |     &(*(e as *const ErrorImpl<()> as *const ErrorImpl<E>))._object
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
    |     trying to reborrow from <5953> for SharedReadOnly permission at alloc1952[0x18], but that tag does not exist in the borrow stack for this location
    |     this error occurs as part of a reborrow at alloc1952[0x18..0x28]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
    = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <5953> was created by a retag at offsets [0x0..0x18]
   --> src/main.rs:5:5
    |
5   |     println!("{report:?}");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    = note: backtrace:
    = note: inside `miette::eyreish::error::object_ref::<miette::eyreish::into_diagnostic::DiagnosticError>` at /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/error.rs:493:5
    = note: inside `miette::eyreish::error::ErrorImpl::<()>::diagnostic` at /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/error.rs:671:20
    = note: inside closure at /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/fmt.rs:15:42
    = note: inside `std::option::Option::<&std::boxed::Box<dyn miette::ReportHandler>>::map::<std::result::Result<(), std::fmt::Error>, [closure@miette::eyreish::fmt::<impl miette::eyreish::error::ErrorImpl<()>>::debug::{closure#0}]>` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:929:29
    = note: inside `miette::eyreish::fmt::<impl miette::eyreish::error::ErrorImpl<()>>::debug` at /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/fmt.rs:13:9
    = note: inside `miette::eyreish::error::<impl std::fmt::Debug for miette::Report>::fmt` at /home/alex/.cargo/registry/src/github.com-1ecc6299db9ec823/miette-5.1.1/src/eyreish/error.rs:439:9
    = note: inside `<&miette::Report as std::fmt::Debug>::fmt` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:2361:62
    = note: inside closure at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:332:17
    = note: inside `std::result::Result::<(), std::fmt::Error>::and_then::<(), [closure@std::fmt::DebugTuple::field::{closure#0}]>` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:1361:22
    = note: inside `std::fmt::DebugTuple::field` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/builders.rs:319:23
    = note: inside `std::fmt::Formatter::debug_tuple_field1_finish` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:2128:9
    = note: inside `<std::result::Result<(), miette::Report> as std::fmt::Debug>::fmt` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/result.rs:500:48
    = note: inside `std::fmt::write` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/fmt/mod.rs:1198:17
    = note: inside `<std::io::StdoutLock as std::io::Write>::write_fmt` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/mod.rs:1672:15
    = note: inside `<&std::io::Stdout as std::io::Write>::write_fmt` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:711:9
    = note: inside `<std::io::Stdout as std::io::Write>::write_fmt` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:685:9
    = note: inside `std::io::stdio::print_to::<std::io::Stdout>` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:1014:21
    = note: inside `std::io::_print` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/io/stdio.rs:1027:5
note: inside `main` at /home/alex/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/macros.rs:106:9
   --> src/main.rs:5:5
    |
5   |     println!("{report:?}");
    |     ^^^^^^^^^^^^^^^^^^^^^^
    = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)

It's complaining about this bit: https://github.com/zkat/miette/blob/c95f58c87a1335e956be23879754ac312a2b0853/src/eyreish/error.rs#L487-L494

This small program is what triggered the miri error above:

fn main() {
    use miette::IntoDiagnostic;
    let error: Result<(), std::io::Error> = Err(std::io::ErrorKind::Other.into());
    let report: miette::Result<()> = error.into_diagnostic();
    println!("{report:?}");
}

with miette = "5.1.1" as my only dependency.

ilyvion avatar Jul 31 '22 20:07 ilyvion

So this is kinda reaching into the deep dark bits of miette, aka, code I didn't write. This actually comes from eyre, which seems to still have the same code, which in turn comes from anyhow, which seems to have changed it since the eyre fork.

Unfortunately, my unsafe/vtable shenanigans abilities are relatively low and I don't really understand the miri error. I appreciate the report, but I also hope someone finds this and is able to figure out whether it needs a solution (and what that solution might be), because I'm stumped 😅

zkat avatar Jul 31 '22 20:07 zkat

Ah, looks like eyre has a similar report yaahc/eyre#59 to solve the same problem. It was supposedly fixed by yaahc/eyre#81 though, but the issue was re-opened in concert with yaahc/eyre#82 without much explanation.

I don't have it in me to work on this right now, (and I also don't want to make promises about being able to in the future,) but should that change, I could try to investigate more closely what those PRs in eyre are doing to see if it can help miette.

Not that I'm an unsafe/vtable kind of expert either. 😅

ilyvion avatar Aug 01 '22 04:08 ilyvion

https://github.com/dtolnay/anyhow/pull/134 might be of use, it includes explanations for the change, as well as what appears to be a fix for this exact function: https://github.com/dtolnay/anyhow/pull/134/files#diff-97e25e2a0e41c578875856e97b659be2719a65227c104b992e3144efa000c35eL549

vthib avatar Aug 02 '22 18:08 vthib