-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Methods that can fail (panic) should be marked as unsafe #340
Comments
These can't cause memory unsafety, there's no reason for these to be unsafe. Partiality isn't a bad thing, necessarily. |
Agree with @cmr. |
In wider meaning 'unsafe' indicate any operation that can emergently stop current task. For single-task programs it's also will stop whole proccess. I'm sure, in most of cases, such behaviour will be unexpected and undesireable. But if rust have so strict meaning for Anyway we definitely need good solution to prevent rust code (especially libraries) from being highly error-prone. At present, very sensitive parts of standard library predisposed to errors. For example trait pub trait Index<Index, Result> {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Result;
}
fn index<'a>(&'a self, index: &uint) -> &'a T {
self.get(*index)
}
pub fn get<'a>(&'a self, index: uint) -> &'a T {
&self.as_slice()[index]
} Expression if index < 0 || index >= vector.len() { return false; }
let value = vector[index]; Except for it's excess work for a programmer and ugly. I forced to make redundant operation to prevent task crush. But rust supposed to be fast. Isn't it? I seeing such situation totally wrong. Moreover actually it is inconsistancy with other vector methods. For example fn last(&'a self) -> Option<&'a T>;
/// Returns a reference to the last element of a vector, or None if it is empty
fn last_mut(&'a mut self) -> Option<&'a mut T>;
/// Returns a mutable reference to the last element of a vector, or None if it is empty
fn swap_remove(&mut self, index: uint) -> Option<T>
/// Removes an element from anywhere in the vector and return it, replacing it with the last element.
/// This does not preserve ordering, but is O(1).
/// Returns None if index is out of bounds. In contrast to described above, those methods really safe and do not force to make excess checks. Furthermore programmer must deside that to do in case of Therefore pub trait Index<Index, Result> {
/// The method for the indexing (`Foo[Bar]`) operation
fn index<'a>(&'a self, index: &Index) -> &'a Option<Result>;
} But this example just subcase of big problem with unexpected So my proposition is following:
I'm sure we must do it before version 1.0. Otherwise we have a risk of Rust will be not exceptional (fast and reliable), but just another ordinary programming language. |
@sergey-kucher I think you misunderstand some of the fundamental design goals and criteria for Rust. Some of the things you describe are already underway, in terms of trying to revise the standard API's to encourage use of But the simple truth is that If we required |
Task panics are for when the program has entered an inconsistent state. There is no correct way for the program to proceed, so it simply panics and takes out the whole task (whether that's enough is a different issue). They are for asserting that the program is correct, and as such provide greater safety than the same method without the panic. Usage of panic!/assert! should be encouraged whenever a programmer is making an assumption that they can't fully justify at the time of writing, or to guard against inappropriate usage (particularly, on internal methods to guard against refactoring errors). If need be, they can use debug_assert! to remove any production expense. Of course, as @pnkfelix notes, most APIs that fail on simply bad user input should yield an option/result, or have an alternative that yields an option/result (which is the case with indexing, but we're in the middle of some major refactoring there, so the way to do that might not be intuitive). For the record to get from a Vec in a non-failing way, you have to do |
@pnkfelix @gankro Thanks for your response.
I'm glad to hear this. Because I'm really was worried about API. Now I can calm a little bit. I agree But I'm still sure But maybe this is not so big proglem than it seems. |
@sergey-kucher you can probably write a lint that detects whether some code locally expands into a call to Since the compiler supports dynamically loaded lints via plugins, I would suggest you go down that route, rather than try to convince the team that this is a necessary addition to the rust compiler as distributed. |
I'll think about it. Thanks |
Yeah, I think that abusing |
FWIW: an effect similar to the opposite of this one is called |
May be use |
Resolve a race in the implementation of Shared
Deprecate Ember.merge
Some of core methods using
fail!
macros. Likeexpect
andunwrap
ofcore::option::Option
andcore::result::Result
.I found two primary things about this:
Seems like some of fail (panic) methods will be preserved (like
expect
for aOption<V>
). But using of such methods is highly error-prone.To prevent mass usage of them I suggest to mark such methods as
unsafe
.For example:
Or maybe generate some special type of warning on compile.
The text was updated successfully, but these errors were encountered: