Skip to content

Unwinding intrinsics use non-unwinding ABI #104451

Closed

Description

@tmiasko

There are intrinsics like assert_inhabited, which can unwind, but use rust-intrinsic ABI that never unwinds:

| RustIntrinsic
| PlatformIntrinsic
| Unadjusted => false,

An example demonstrating the issue. The argument passed to function f is never dropped, when assert_inhabited unwinds:

#![feature(core_intrinsics)]
#![feature(never_type)]

struct NoisyDrop(&'static str);

impl Drop for NoisyDrop {
    fn drop(&mut self) {
        println!("{}", self.0);
    }
}

pub fn f<A, B>(_: A) {
    core::intrinsics::assert_inhabited::<B>()
}

fn main() {
    let _a = NoisyDrop("1");
    f::<NoisyDrop, !>(NoisyDrop("2"));
}

$ rustc a.rs && ./a
thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', a.rs:13:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
1

Activity

  1. nbdd0121 commented on Nov 15, 2022

    @nbdd0121
    Member

    I'll work on this after #102906 is merged.

    @rustbot claim

  2. RalfJung commented on Nov 15, 2022

    @RalfJung
    Member

    Are these intrinsics the only ones that unwind? Maybe we should just make them abort instead by calling the (fairly recent) panic_str_nounwind.

    However, AFAIK try is also an intrinsic and that can unwind?

  3. nbdd0121 commented on Nov 15, 2022

    @nbdd0121
    Member

    try catches unwind and it does not itself unwind.

  4. nbdd0121 commented on Nov 15, 2022

    @nbdd0121
    Member

    My current idea is to change assert_inhabited to is_inhabited intrinsic, and then have a wrapper that checks the value and panic if true. But making them abort sounds like an easier alternative.

  5. RalfJung commented on Nov 15, 2022

    @RalfJung
    Member

    It should be a nice abort via panic_str_nounwind though.

    I am honestly not sure why the intrinsics are panicking rather than returning a boolean... I think I tried that and it didn't work? But yeah bool-returning intrinsics sound better (less magic) ayway.

  6. RalfJung commented on Nov 15, 2022

    @RalfJung
    Member

    One possible reason is that in CTFE and Miri, these intrinsics will actually abort instead of panic. Getting the if ... { panic_str_nounwind } to work in CTFE will be a bit of work (extending the existing hacks that make regular panicking work in CTFE, or using const_eval_select) and the backtrace will be slightly worse in Miri.

    So given that we want something different implementations for Miri, CTFE, and runtime, maybe going with 'call panic_str_nounwind instead' is the better option. (An immediate-abort-panic just didn't exist when I added these intrinsics, otherwise this is probably what I would have done from the start.)

  7. added
    A-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows
    on Mar 11, 2023
  8. RalfJung commented on Apr 12, 2023

    @RalfJung
    Member

    With #105997, I think assert_inhabited and friends do now indeed never unwind.

    But as determined in rust-lang/miri#2839, we still have const_eval_select, which very much can unwind.

  9. nbdd0121 commented on Apr 12, 2023

    @nbdd0121
    Member

    Yeah, I originally thought that we can remove all unwinding intrinsics, but unfortunately that's not true. I am working on a PR to change the ABI to be unwindable and stick #[rustc_nounwind] to most intrinsics.

  10. RalfJung commented on Apr 12, 2023

    @RalfJung
    Member

    That sounds like the cleanest approach, thanks!

  11. added
    I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
    on Apr 12, 2023
  12. added
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Apr 12, 2023
  13. removed
    I-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
    on Apr 12, 2023
  14. added a commit that references this issue on Apr 13, 2023
    e85ecbb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-intrinsicsArea: IntrinsicsA-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflowsC-bugCategory: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions