rust-lang / rfcs

RFCs for changes to Rust
https://rust-lang.github.io/rfcs/
Apache License 2.0
5.89k stars 1.56k forks source link

deactivate all panics (obviously optional) #3280

Closed WormPatch closed 2 years ago

WormPatch commented 2 years ago

unreachable_unchecked is a way to tell the compiler: "this will never happend", example:

fn index(array:&[u8], x:usize) {
    if x < array.len() {
        return array[x]; //return is more readable
    } else {
        panic!("out of bounds");
    }
}

if we replace panic!() with unreachable_unchecked(), this function converts into:

fn index(array:&[u8], x:usize) { array[x] }

what happened here?, we "despanicked" a function.

panic = 'unreachable_unchecked' in Cargo.toml. will despanic all functions in project. disabling all checks

ChayimFriedman2 commented 2 years ago

This is very bad. It just makes Rust into an unsafe language.

WormPatch commented 2 years ago

This is very bad. It just makes Rust into an unsafe language.

i know most cases its bad, but its just optional. sometimes its needed

edit: literally there are many libs that makes unpanic versions of his functions, do it automatically, it can even be an automatic unpanicking feature

ChayimFriedman2 commented 2 years ago

i know most cases its bad, but its just optional. sometimes its needed

I'm yet to meet a case where it should be applied globally. And you can always patch std.

literally there are many libs that makes unpanic versions of his functions, do it automatically, it can even be an automatic unpanicking feature

Those non-panicking functions are either fallible and don't invoke UB, in this case a feature like that won't help, or they are marked unsafe and usually have other name (X_unchecked).

shepmaster commented 2 years ago

literally there are many libs that makes unpanic versions of his functions,

please link to some examples

WormPatch commented 2 years ago

Those non-panicking functions are either fallible and don't invoke UB, in this case a feature like that won't help, or they are marked unsafe and usually have other name (X_unchecked).

replacing panic with unchecked_unreachable cant break the code when its correct

WormPatch commented 2 years ago

literally there are many libs that makes unpanic versions of his functions,

please link to some examples

I was wrong, "unchecked" distinguished between "Some()" and "Err()", not with panics. but that would happend with Err() sometimes because LLVM can optimize it since unwrap doesnt checks in unpanic

ChayimFriedman2 commented 2 years ago

replacing panic with unchecked_unreachable cant break the code when its correct

This is true, but a meaningless property: introducing any UB can't break correct code, since if it invokes the UB it is by definition incorrect. The very reason for the existence of Rust is to protect us from incorrect code.

but that would happend with Err() sometimes because LLVM can optimize it since unwrap doesnt checks in unpanic

unwrap() definitely panics on Err. LLVM may be able to optimize that based on context, but not just because of this panic alone.

WormPatch commented 2 years ago

replacing panic with unchecked_unreachable cant break the code when its correct

This is true, but a meaningless property: introducing any UB can't break correct code, since if it invokes the UB it is by definition incorrect. The very reason for the existence of Rust is to protect us from incorrect code.

but that would happend with Err() sometimes because LLVM can optimize it since unwrap doesnt checks in unpanic

unwrap() definitely panics on Err. LLVM may be able to optimize that based on context, but not just because of this panic alone.

even with this its not that unsafe as C++, maybe using this in drivers or specified software

ChayimFriedman2 commented 2 years ago

even with this its not that unsafe as C++, maybe using this in drivers or specified software

Not as bad - but even one UB is too much. We don't make Rust in order to "win" C++, and therefore we should not stop if our "victory" is guaranteed.

If you have a specific use case where it is required (I'd like to see it, by the way), you can fork Rust and patch std. Standardizing a very dangerous process that is useless for 99% of the people 99% of the time is the wrong thing to do.

chorman0773 commented 2 years ago

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}
WormPatch commented 2 years ago

even with this its not that unsafe as C++, maybe using this in drivers or specified software

Not as bad - but even one UB is too much. We don't make Rust in order to "win" C++, and therefore we should not stop if our "victory" is guaranteed.

If you have a specific use case where it is required (I'd like to see it, by the way), you can fork Rust and patch std. Standardizing a very dangerous process that is useless for 99% of the people 99% of the time is the wrong thing to do.

i dont mean winning to C++ it was only a comparison

WormPatch commented 2 years ago

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}

i dont know if that works but i think my idea is a little bit easier to use

chorman0773 commented 2 years ago

That will replace all panics with UB.

On Thu, Jun 16, 2022 at 18:12 Worm Patch @.***> wrote:

Or if you really really want, you can do this:

[panic_handler]pub fn onpanic(: &PanicInfo) -> !{

unsafe{core::hint::unreachable_unchecked()}

}

i dont know if that works but i think my idea is a little bit easier to use

— Reply to this email directly, view it on GitHub https://github.com/rust-lang/rfcs/issues/3280#issuecomment-1158183608, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD22JHJGZ64Z56CBQOPDVPORGDANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.***>

ChayimFriedman2 commented 2 years ago

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}

Technically it does replace all panics with UB, but LLVM does not optimize them out, probably because panic is #[cold].

Also, this rules out std.

i dont mean winning to C++ it was only a comparison

And my point was that if we can do better, we should do better.

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}

i dont know if that works but i think my idea is a little bit easier to use

This does not need to be easy, especially when as I said this is irrelevant for 99% of the people 99% of the time, and the proposed solution is just some characters longer (if it would work). Optimizing for the easiness of this is a wrong judgement of risks and benefits.

WormPatch commented 2 years ago

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}

Technically it does replace all panics with UB, but LLVM does not optimize them out, probably because panic is #[cold].

Also, this rules out std.

i dont mean winning to C++ it was only a comparison

And my point was that if we can do better, we should do better.

Or if you really really want, you can do this:

#[panic_handler]
pub fn on_panic(_: &PanicInfo) -> !{
    unsafe{core::hint::unreachable_unchecked()}
}

i dont know if that works but i think my idea is a little bit easier to use

This does not need to be easy, especially when as I said this is irrelevant for 99% of the people 99% of the time, and the proposed solution is just some characters longer (if it would work). Optimizing for the easiness of this is a wrong judgement of risks and benefits.

i understand in that context, we have good computers, that is pretty nothing even to an 1990 computer, but how would you do it in small embedding, you dont wanna drop and quit. now i remember why i feel uncomfortable with this, i have an usb wifi micro (dont wanna code in C, because i need some features). image this has really small size pointer, drop and quit is not enough,

Lokathor commented 2 years ago

Embedded or not, if the code has a bug and would panic, using unreachable_unchecked() instead of a panic doesn't fix a single thing. Now you just have a completely different kind of problem when you hit the bug.

WormPatch commented 2 years ago

Embedded or not, if the code has a bug and would panic, using unreachable_unchecked() instead of a panic doesn't fix a single thing. Now you just have a completely different kind of problem when you hit the bug.

of course i would/will not use this when i have'nt tested my code

SOF3 commented 2 years ago

I still don't understand what you're trying to achieve. Nothing stops you from using vec.get_unchecked() or result.unwrap_unchecked(). Why does this need to be a compiler option?'

WormPatch commented 2 years ago

I still don't understand what you're trying to achieve. Nothing stops you from using vec.get_unchecked() or result.unwrap_unchecked(). Why does this need to be a compiler option?'

thats a lot more painful, we cant assume all functions has his unchecked versions, this compiler option is easy to implement, it only replaces panic!() just like 'abort' and 'unwind'

ChayimFriedman2 commented 2 years ago

thats a lot more painful, we cant assume all functions has his unchecked versions, this compiler option is easy to implement, it only replaces panic!() just like 'abort' and 'unwind'

I'm sure not all your panics need to be unchecked. Some can be optimized out anyway, some actually can hit the invalid case. So you're arguing to remove a lot of safety for ease of use. This is the wrong thing to do. I, and some others, even think that unsafe Rust needs to be harder deliberately (on some cases at least) so people won't use it unless they must.

WormPatch commented 2 years ago

thats a lot more painful, we cant assume all functions has his unchecked versions, this compiler option is easy to implement, it only replaces panic!() just like 'abort' and 'unwind'

I'm sure not all your panics need to be unchecked. Some can be optimized out anyway, some actually can hit the invalid case. So you're arguing to remove a lot of safety for ease of use. This is the wrong thing to do. I, and some others, even think that unsafe Rust needs to be harder deliberately (on some cases at least) so people won't use it unless they must.

Yes, I also thought about that but I didn't want to say it so as not to complicate it more, maybe panic = 'unsafe_unreachable_unchecked', it has unsafe in it and it seems painful.

and no, not all functions will be dispanicked by default by the compiler.

Lokathor commented 2 years ago

I, and some others, even think that unsafe Rust needs to be harder deliberately (on some cases at least) so people won't use it unless they must.

Naw. Nope. Not even once.

ChayimFriedman2 commented 2 years ago

I, and some others, even think that unsafe Rust needs to be harder deliberately (on some cases at least) so people won't use it unless they must.

Naw. Nope. Not even once.

Well let's not discuss it here.

Kixiron commented 2 years ago

I feel like what you actually want is to use panic = "abort", it has the same effect (making panics as small as possible, not bringing in formatting code, no unwinding, etc) while not being heinously unsound and impossible to use correctly. Honestly I'm pretty comfortable saying that the proposal as-is will never be accepted as part of rust, so this issue can probably be closed

WormPatch commented 2 years ago

Honestly I'm pretty comfortable saying that the proposal as-is will never be accepted as part of rust, so this issue can probably be closed

I'm trying to give my reasons, there is not reason to close it yet. i know most of the times its better to leave panics, but what about the cases when not?, well the cases when not, maybe ask to be added

Kixiron commented 2 years ago

The cases where panics can be soundly elided are nicely handled by manual usages of unreachable_unchecked() and .unwrap_unchecked(). Applying UB as a blanket measure is incredibly unsound and completely bypasses any ability of the unsafety to be manually verified. No one's going to sift through thousands upon thousands of panics to vet them all and even if they did they would either take an inordinate amount of time to do so or wouldn't be properly validating each site.

WormPatch commented 2 years ago

is really unreachable_unchecked() that hard to compile? i dont think so. and yes doing it manually makes the language harder, i want to debug it with panics and release without panics that is the point

thomcc commented 2 years ago

i want to debug it with panics and release without panics that is the point

Doing this goes against several of Rust's design goals around safety. I don't think it's very likely that your line of argument here will be successful.

That said, if you want this, Zig is a modern low level language that offers it.

Lokathor commented 2 years ago

The difficulty of compiling unreachable_unchecked() is not the issue.

If the code would ever get to unreachable_unchecked() it's undefined behavior. That's very bad. You could even say that the entire point of the Rust language is to eliminate undefined behavior as much as possible. Allowing an easy to use compilation option that would introduce UB at hundreds or possibly thousands of locations throughout a program is completely unacceptable. No amount of explanation of the problem or intent will make it an acceptable addition to the compiler.

WormPatch commented 2 years ago

i want to debug it with panics and release without panics that is the point

Doing this goes against several of Rust's design goals around safety. I don't think it's very likely that your line of argument here will be successful.

That said, if you want this, Zig is a modern low level language that offers it.

i like zig but i want to do this in Rust

WormPatch commented 2 years ago

The difficulty of compiling unreachable_unchecked() is not the issue.

If the code would ever get to unreachable_unchecked() it's undefined behavior. That's very bad. You could even say that the entire point of the Rust language is to eliminate undefined behavior as much as possible. Allowing an easy to use compilation option that would introduce UB at hundreds or possibly thousands of locations throughout a program is completely unacceptable. No amount of explanation of the problem or intent will make it an acceptable addition to the compiler.

yes, thats is the point of rust, but rust also lets you do whatever you want when programming, example: unsafe{}, sometimes you need unsafe keyword, unsafe keyword is there and it's useful. rust is secure but let you do whatever you want at the same time, and that is good, i know this is unsafe

Lokathor commented 2 years ago

The difference is that every time an unsafe{} block is used the programmer has (or should have) verified that all necessary pre-conditions of the unsafe operation are true. And you should do this for every single unsafe block, through the whole program.

Your suggestion turns safe code into unverified unsafe code.

WormPatch commented 2 years ago

The difference is that every time an unsafe{} block is used the programmer has (or should have) verified that all necessary pre-conditions of the unsafe operation are true. And you should do this for every single unsafe block, through the whole program.

Your suggestion turns safe code into unverified unsafe code.

well, i think people is supposed to test the code before using a theorical panic = 'unsafe_unreachable_unchecked'. thats for sure

Kixiron commented 2 years ago

Testing is not verification, "works on my machine" is not a justification for UB

WormPatch commented 2 years ago

Testing is not verification, "works on my machine" is not a justification for UB

if it works in embed its ok. this should not be used in projects like data bases that are target specific but they are big enough to worth it

Lokathor commented 2 years ago

Speaking as someone who programs rust for the GBA: even embedded developers should not use unreachable_unchecked() that often.

WormPatch commented 2 years ago

Speaking as someone who programs rust for the GBA: even embedded developers should not use unreachable_unchecked() that often.

GBA is a little big because its made to play games

edit: STOP THE SAD FACES

BurntSushi commented 2 years ago

@WormPatch I'm not on the relevant teams that would decide something like this, but I'm nearly certain that your request will likely never be granted. For example, with this option enabled, it fundamentally changes the definition of soundness as it currently exists in Rust. Namely, routines that are safe to call today only because of an assert that is guaranteed to run would become unsafe to call for some set of inputs, despite being marked safe. Notably, this would include things like sub-slicing and RefCell::borrow. It's an option that changes the character of Rust and alters its core value proposition.

On a different note, in this thread, I think you have thrown around the word "need" carelessly. I don't see a single concrete and precise technical argument for why you actually need this. If such an argument does indeed exist, then I suspect Rust is not something you can use, no matter how much you want to. With that said, I'm quite skeptical that any such argument exists.

WormPatch commented 2 years ago

I think I realized that they will not accept it, however they could at least add a way to modify the panic code in Cargo.toml. so that it affects all the files when release, who knows maybe someone wants the panics to be shown in a window or being registered in a DB, so if someone wants it to be deleted just make it "unrechable_unexpected();"

Lokathor commented 2 years ago

You can already define your own #[panic_handler] in no_std code, and you can set a custom panic hook in code using the standard library.

WormPatch commented 2 years ago

You can already define your own #[panic_handler] in no_std code, and you can set a custom panic hook in code using the standard library.

no thanks i like std. do panic hooks makes my own panic or it replace them all?

Lokathor commented 2 years ago

I'm very curious what possible device you could be programming for that's less powerful than a GBA and still supports the full standard library.

But regardless of that, the panic hook is called by all code that panics.

WormPatch commented 2 years ago

I'm very curious what possible device you could be programming for that's less powerful than a GBA and still supports the full standard library.

But regardless of that, the panic hook is called by all code that panics.

i havent tryed it yet, but i think rust only compiles whatever you use

edit: i sent a photo of the devise, i dont know which model it is

edit 2: panic hook is called by all code that panics or its replaced?

Lokathor commented 2 years ago

the panic hook is called by a panic if std is compiled into the project

you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html

WormPatch commented 2 years ago

the panic hook is called by a panic if std is compiled into the project

you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html

it doesnt work, i tried with index out of bounds and it says "illegal instruction", but i think its in my OS (debian) because its in spanish, or maybe its ud2

chorman0773 commented 2 years ago

rust uses ud2 to abort the process. LLVM will also typically generate ud2 in branches that definately contain undefined behaviour (trap unreachable).

On Fri, 17 Jun 2022 at 16:26, Worm Patch @.***> wrote:

the panic hook is called by a panic if std is compiled into the project

you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html

it doesnt work, i tried with index out of bounds and it says "illegal instruction", but i think its in my OS (debian) because its in spanish, or maybe its ud2

— Reply to this email directly, view it on GitHub https://github.com/rust-lang/rfcs/issues/3280#issuecomment-1159205599, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.***>

WormPatch commented 2 years ago

rust uses ud2 to abort the process. LLVM will also typically generate ud2 in branches that definately contain undefined behaviour (trap unreachable). On Fri, 17 Jun 2022 at 16:26, Worm Patch @.> wrote: the panic hook is called by a panic if std is compiled into the project you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html it doesnt work, i tried with index out of bounds and it says "illegal instruction", but i think its in my OS (debian) because its in spanish, or maybe its ud2 — Reply to this email directly, view it on GitHub <#3280 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.>

when i put "unreachable_unexpected()" directly it doesnt happends

chorman0773 commented 2 years ago

Well, yeah. In that case it just deletes the branch.

On Fri, 17 Jun 2022 at 17:09, Worm Patch @.***> wrote:

rust uses ud2 to abort the process. LLVM will also typically generate ud2 in branches that definately contain undefined behaviour (trap unreachable). … <#m1650203930501164910> On Fri, 17 Jun 2022 at 16:26, Worm Patch @.> wrote: the panic hook is called by a panic if std is compiled into the project you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html https://doc.rust-lang.org/nightly/rustc/platform-support.html it doesnt work, i tried with index out of bounds and it says "illegal instruction", but i think its in my OS (debian) because its in spanish, or maybe its ud2 — Reply to this email directly, view it on GitHub <#3280 (comment) https://github.com/rust-lang/rfcs/issues/3280#issuecomment-1159205599>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.>

when i put "unreachable_unexpected()" directly it doesnt happends

— Reply to this email directly, view it on GitHub https://github.com/rust-lang/rfcs/issues/3280#issuecomment-1159228199, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD26KNK4CAAPPBDAITEDVPTSR3ANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.***>

WormPatch commented 2 years ago

Well, yeah. In that case it just deletes the branch. On Fri, 17 Jun 2022 at 17:09, Worm Patch @.> wrote: rust uses ud2 to abort the process. LLVM will also typically generate ud2 in branches that definately contain undefined behaviour (trap unreachable). … <#m1650203930501164910> On Fri, 17 Jun 2022 at 16:26, Worm Patch @.> wrote: the panic hook is called by a panic if std is compiled into the project you can find out which compilation targets support std or not on the platform support page: https://doc.rust-lang.org/nightly/rustc/platform-support.html https://doc.rust-lang.org/nightly/rustc/platform-support.html it doesnt work, i tried with index out of bounds and it says "illegal instruction", but i think its in my OS (debian) because its in spanish, or maybe its ud2 — Reply to this email directly, view it on GitHub <#3280 (comment) <#3280 (comment)>>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ https://github.com/notifications/unsubscribe-auth/ABGLD27YDXVRWNVF5GSOLMDVPTNQPANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.> when i put "unreachable_unexpected()" directly it doesnt happends — Reply to this email directly, view it on GitHub <#3280 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABGLD26KNK4CAAPPBDAITEDVPTSR3ANCNFSM5Y5Q2TTQ . You are receiving this because you commented.Message ID: @.>

i dont understand

WormPatch commented 2 years ago

i dont understand what is wrong with this is totally optional and its sane in correct code