Skip to content

Tracking issue for mem::unreachable #43751

Description

@tbu-
No description provided.

Activity

  1. added
    B-unstableBlocker: Implemented in the nightly compiler and unstable.
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 8, 2017
  2. scottmcm commented on Aug 9, 2017

    @scottmcm
    Member

    Bikeshed: I find it surprising that safe unreachable!() and unsafe unreachable() do very different things. Also, this seems to have nothing to do with memory, so mem is an odd location for it.

  3. durka commented on Aug 9, 2017

    @durka
    Contributor

    Another possible name/location for discussion: raw::assume_unreachable(). Would require changing the raw module's mandate. We could also leave it under intrinsics, but stabilize it (you can use std::intrinsics::transmute; today).

  4. notriddle commented on Aug 9, 2017

    @notriddle
    Contributor

    This does not belong in mem, and it should not have the same name as the unreachable!() macro.

    Why not just call it std::intrinsics::undefined_behaviour()?

  5. kennytm commented on Aug 9, 2017

    @kennytm
    Member

    There's a suggestion calling it unchecked_unreachable.

  6. durka commented on Aug 9, 2017

    @durka
    Contributor

    I like @notriddle's suggestion. Does what it says on the tin.

  7. added
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    on Aug 10, 2017
  8. diwic commented on Aug 16, 2017

    @diwic
    Contributor

    std::raw::eat_my_laundry()

    (Sorry, couldn't help myself)

  9. notriddle commented on Aug 16, 2017

    @notriddle
    Contributor

    std::raw::eat_my_laundry()

    Except that, in most cases, it won't consume your clothes. Your computer probably doesn't even have the necessary hardware to do anything to your laundry. Undefined behaviour may eat your laundry, because it may do anything; the specification places no constraints on what the result of invoking this intrinsic is. A name like eat_my_laundry fails to express this. Of course, I'm probably taking the suggestion too seriously. 😆

    Unlike eat_my_laundry, though, naming the function undefined_behavior is actually a suggestion; it has the advantage of being one less name that people have to remember. And it's not like invoking this intrinsic may invoke UB; invoking this intrinsic is (at least from a specification and documentation POV) exactly the same as invoking UB any other way. There's no conceptual difference, so I'm not sure why there should be a naming difference.

  10. diwic commented on Aug 17, 2017

    @diwic
    Contributor

    @notriddle Yep, I agree that undefined_behavior is the best suggestion so far. Not sure which module it should fit in though.

    (Context for those who came to this community after Rust 1.0: Before 1.0 there was a disclaimer on Rust's homepage saying something like it wasn't production ready yet, and could in theory do anything, including eating your laundry. I don't remember the exact wording.)

  11. earthengine commented on Aug 18, 2017

    @earthengine

    I would say std itself. Since undefined_behavior is a basic concept, not less common than Box or other common concepts.

  12. kennytm commented on Aug 18, 2017

    @kennytm
    Member

    @earthengine Box is located at std::boxed::Box, not std::Box. std as a module contains no types or functions. (and there's no way this function will enter prelude.)

  13. earthengine commented on Aug 18, 2017

    @earthengine

    Then make it inside std::intrinsics.

  14. nagisa commented on Aug 22, 2017

    @nagisa
    Member

    Consider that another intrinsic, abort, is very similar in behaviour and would probably live in the same place as unreachable.

  15. 54 remaining items

  16. sfackler commented on Apr 18, 2018

    @sfackler
    Member

    We can do literally anything we want when undefined behavior happens so that's not a thing we need to explicitly guarantee.

    #45920 causes a trap to be generated from unreachable anyway, so you're already going to abort if an unreachable_unchecked is reached.

  17. dtolnay commented on Apr 18, 2018

    @dtolnay
    Member

    Then it's just a difference between "unconditionally unchecked is the correct behavior for a function with this name, and if we want a debug checked version later we call it something else or recommend a thirdparty crate" vs "we wish we could check in debug mode but the standard library is not set up to be able to do that -- maybe later." You and Simon seem to have been supporting the former but maybe mark-i-m and I would prefer the latter.

    Is the trap as easily debuggable as a panic with stacktrace?

  18. durka commented on Apr 18, 2018

    @durka
    Contributor
  19. hanna-kruppe commented on Apr 18, 2018

    @hanna-kruppe
    Contributor

    Note that #45920 only kicks in at codegen time, optimizations based on the UB can still cause arbitrarily bad or confusing consequences. You might not even ever hit the unreachable -- if it is conditional, for example, the branch with the "unreachable" in it might be eliminated entirely.

  20. notriddle commented on Apr 18, 2018

    @notriddle
    Contributor

    One reason for not panicking specifically is that it unwinds the stack, and the surrounding unsafe code might not be equipped to handle that.

    What if it immediately aborted and printed a stack trace in debug mode?

  21. mark-i-m commented on Apr 18, 2018

    @mark-i-m
    Contributor

    Is the trap as easily debuggable as a panic with stacktrace?

    It's not quite as nice. A trap will cause the program to be killed on a standard Linux setup. If you are running in GDB, then GDB will pause and you can use bt to get a stacktrace. However, if it just happens when you are running (especially if it is non-deterministic), then you will just get killed by the OS without warning.

    What if it immediately aborted and printed a stack trace in debug mode?

    I think I would be ok with pretty much anything, as long as the program halts and some debugging info is printed.

  22. durka commented on Apr 18, 2018

    @durka
    Contributor
  23. SimonSapin commented on Apr 18, 2018

    @SimonSapin
    Contributor

    I think that I was wrong, and that debug_assertions would do the right thing in libcore since it’s not a function but a macro, so (if I understand things correctly) cfg!(…) in its expansion would be evaluated in the context of the call site.

    However I think that for the past three years the crate also hasn’t been doing what everyone thinks it’s doing, since it uses cfg!(ndebug) which isn’t set by Cargo anymore: rust-lang/cargo#1444

  24. SimonSapin commented on Apr 18, 2018

    @SimonSapin
    Contributor

    I sympathize with this and I struggle to think of reasonable use cases where I would prefer the current unconditionally unchecked unreachable over something like debug_unreachable.

    <[T]>::get_unchecked and every other *_unchecked API are unconditionally unchecked. Why do we have those?

  25. hanna-kruppe commented on Apr 18, 2018

    @hanna-kruppe
    Contributor

    @durka

    Well if it's defined to trap it's not undefined, is it? And those "clever UB optimizations" shouldn't happen in debug mode.

    It's undefined, period, codegen can just be configured is slightly mitigating the impact of any unreachables that make it to codegen. And re: "shouldn't happen in debug mode" -- pretty much all existing runtime checks can be configured independently of optimization level (-Coverflow-checks, debug_assertions) and this should too. Moreover, it appears @sfackler was talking more generally than "just" about debug mode. I just want to be clear about what #45920 does and does not achieve -- it's a mitigation, it doesn't tame any UB nor its consequences.

  26. durka commented on Apr 18, 2018

    @durka
    Contributor

    cfg!(…) in its expansion would be evaluated in the context of the call site.

    Yes but the call site is in libcore, which has already been compiled, so it won't do what you expect. That's why there are ridiculous ingenious hacks to make overflow-checks-in-debug-mode work right.

  27. mark-i-m commented on Apr 18, 2018

    @mark-i-m
    Contributor

    Well if it's defined to trap it's not undefined, is it? And those "clever UB optimizations" shouldn't happen in debug mode.

    Undefined doesn't necessarily have to mean unpredictable. Technically, *(int*)0 is UB, but in practice, most OSes cause it to segfault predictably. UB simply means we don't make any promises. We can still make a best effort, though. On the other hand, it also means we don't have any promises about what happens in debug mode either, just best effort. This makes it seem acceptable to panic in debug mode but not in release mode (assuming we can get it to work).

  28. tbu- commented on Apr 18, 2018

    @tbu-
    ContributorAuthor

    Technically, (int)0 is UB, but in practice, most OSes cause it to segfault predictably.

    This is not true anymore if you factor compilers into the equation. Actual real-world programs don't segfault reliably when the programmer might think that it'd reliably execute the *(int *)0.

  29. added a commit that references this issue on Apr 24, 2018
    f28f5aa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    B-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libs-api[DEPRECATED; DO NOT USE]final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions