Repository navigation
Tracking issue for mem::unreachable #43751
Description
Activity
- addedB-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.T-libs-api[DEPRECATED; DO NOT USE][DEPRECATED; DO NOT USE]
on Aug 8, 2017 Bikeshed: I find it surprising that safe
unreachable!()and unsafeunreachable()do very different things. Also, this seems to have nothing to do with memory, somemis an odd location for it.Reacted by Alex Burka, Martin Carton, quininer, kennytm, Peter Atashian, Nikolai Vazquez, nicole mazzuca, bluss, Kevin Cox, Jon Gjengset and 2 moreAnother possible name/location for discussion:
raw::assume_unreachable(). Would require changing therawmodule's mandate. We could also leave it underintrinsics, but stabilize it (you canuse std::intrinsics::transmute;today).Reacted by bluss, Techcable and Eira FranshamThis does not belong in
mem, and it should not have the same name as theunreachable!()macro.Why not just call it
std::intrinsics::undefined_behaviour()?Reacted by diwic, Gábor Lehel, scottmcm, Peter Atashian, Techcable, Aaron Hill, Kevin Cox, oxalica, mark, Russell Hernandez Ruiz and 2 moreReacted by kennytm and Nikolai VazquezReacted by kennytm, Alex Burka, Lukas H., Others, Crystal Durham, Martin Habovštiak, oxalica, John Charankattu, bb010g, Connie Hilarides and 1 moreThere's a suggestion calling it
unchecked_unreachable.Reacted by Gábor Lehel, Techcable, Sergei Shulepov, bluss, Marco A L Barbosa, Martin Habovštiak, oxalica, mako yass, MSxDOS and John CharankattuI like @notriddle's suggestion. Does what it says on the tin.
Reacted by scottmcm, Techcable, Russell Hernandez Ruiz and Connie HilaridesReacted by kennytmReacted by Michael Howell and Connie Hilarides- addedC-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFC
on Aug 10, 2017 std::raw::eat_my_laundry()(Sorry, couldn't help myself)
Reacted by kennytm, Crystal Durham, Nikolai Vazquez, scottmcm, SHA Miao (沙渺), mark, M Farkas-Dyck, Dylan McKay, John Charankattu, Jonas Platte and 1 morestd::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_laundryfails to express this. Of course, I'm probably taking the suggestion too seriously. 😆Unlike
eat_my_laundry, though, naming the functionundefined_behavioris 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.Reacted by Peter Atashian, Techcable, Eira Fransham and Jonas PlatteReacted by bjorn3 and Jeb Rosen@notriddle Yep, I agree that
undefined_behavioris 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.)
Reacted by earthengine, Peter Atashian, MSxDOS and Dylan McKayI would say
stditself. Sinceundefined_behavioris a basic concept, not less common thanBoxor other common concepts.Reacted by kennytm and Eira Fransham@earthengine
Boxis located atstd::boxed::Box, notstd::Box.stdas a module contains no types or functions. (and there's no way this function will enterprelude.)Then make it inside
std::intrinsics.Consider that another intrinsic,
abort, is very similar in behaviour and would probably live in the same place asunreachable.Reacted by diwic, bluss, Russell Hernandez Ruiz and 1 more54 remaining items
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.
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?
- Abort doesn't print a stack trace but I believe you can catch it in a debugger.…On Wed, Apr 18, 2018 at 4:14 PM, David Tolnay ***@***.***> wrote: 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? — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#43751 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAC3n_tCywRhtTIgSv7qKr2b20Z3_YIAks5tp56RgaJpZM4OxZfV> .
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.
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?
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
btto 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.
- Well if it's defined to trap it's not undefined, is it? And those "clever UB optimizations" shouldn't happen in debug mode.…On Wed, Apr 18, 2018 at 4:25 PM, Robin Kruppe ***@***.***> wrote: Note that #45920 <#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. — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#43751 (comment)>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAC3n89B_KPoilfOw6CqLzu442ctFS97ks5tp6EjgaJpZM4OxZfV> .
I think that I was wrong, and that
debug_assertionswould 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#1444I 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_uncheckedand every other*_uncheckedAPI are unconditionally unchecked. Why do we have those?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.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
ridiculousingenious hacks to make overflow-checks-in-debug-mode work right.Reacted by markWell 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*)0is 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).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.Reacted by Peter Atashian and Connie Hilarides- added a commit that references this issue
on Apr 24, 2018