Earlier quoted context omitted.
The issue here isn't new features at all. `if let` is more or less syntax sugar for `match`. And match behaves like that, too and has been in rust since 1.0. That match did behaves like that is due to some old, you could say legacy, reasons and had been criticized even in the early rust 1.x days. But changing a behavior which subtle change when locks are released is not something you can easily fix with a rust editio…
> `if let` is more or less syntax sugar for `match`. Which are new features for systems languages that otherwise rely on RAII for locking. So it's in the class of "original sin." > so we are pretty much stuck with it. You could refuse to compile it under some set of flags. Isn't that the basic value premise of the language here?
Rust's Sneaky Deadlock With `if let` Blocks
21–30 of 85 posts
Re: Rust's Sneaky Deadlock With `if let` Blocks
#22This is why pthread_mutex_lock() and pthread_mutex_unlock() will always be kings - it is clear when things are locked and when they are unlocked. Nobody needs to write articles warning you about pthread_mutex being taken randomly by syntactic sugar and not released till a magic later time due to the same sugar. Ditto for RWlock/XYZloc/ABClock/etc...
Re: Rust's Sneaky Deadlock With `if let` Blocks
#23Happy to be corrected, but from what I gathered RWLock should mostly be avoided in favour of a simple Mutex unless you have a very read-heavy usecase and even then the performances are subpar compared to mutex.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#24This is why pthread_mutex_lock() and pthread_mutex_unlock() will always be kings - it is clear when things are locked and when they are unlocked. Nobody needs to write articles warning you about pthread_mutex being taken randomly by syntactic sugar and not released till a magic later time due to the same sugar. Ditto for RWlock/XYZloc/ABClock/etc...
This really reads like satire but feels like the author is actually being sincere. I’ve seen so many deadlocks happening due to pthread mutexes. Certainly way more than this syntactic corner case. It’s so common in fact that I saw a codebase that made their mutexes recursive to avoid having to think about it.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#25This is why pthread_mutex_lock() and pthread_mutex_unlock() will always be kings - it is clear when things are locked and when they are unlocked. Nobody needs to write articles warning you about pthread_mutex being taken randomly by syntactic sugar and not released till a magic later time due to the same sugar. Ditto for RWlock/XYZloc/ABClock/etc...
Plus you're working in a memory unsafe, concurrency unsafe language.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#26Earlier quoted context omitted.
I see it as a consequence of Rust being too liberal with additions to the language. It's hard to maintain some of these guarantees in the presence of certain syntactic forms. This happens in all languages. It is a little hilarious to see a rustaceon write: > and you can sus out if a program is going to cause a deadlock by just making sure you aren't acquiring multiple simultaneous locks. Ah.. not a problem! You just…
The issue here isn't new features at all. `if let` is more or less syntax sugar for `match`. And match behaves like that, too and has been in rust since 1.0. That match did behaves like that is due to some old, you could say legacy, reasons and had been criticized even in the early rust 1.x days. But changing a behavior which subtle change when locks are released is not something you can easily fix with a rust editio…
1) temporaries being added "alongside" the item they appear in. This makes a tone of thing much much simpler, but comes back to bites us here.
2) "alongside" for match statement meaning alongside the whole statement (but for `if {` it's alongside the condition)
3) things being always dropped at the very end of the scope if not moved out from it earlier, which again makes things easier to understand in most cases.
both had been discussed a bunch around 1.0/early 1.x days and both are things which in most situations make it easier to write rust code (and for beginners potentially much easier)
but both have also drawbacks
like the not-that-common example in this blog
or e.g. in async where rust has to keep any values which impl Drop around across async await calls as it can't know if there is a side effect in Drop
In the past I personally had been a contender of allowing the compiler to drop value anywhere between the last time they have been referenced and the end of the scopes without any rules or stability about where exactly (i.e. if you need a guard to be kept around you need to be explicit about it).
But working more together with people of very varying skill levels in the last 5/6 years made me change my mind and agree that that would have been a terrible idea.
And having rules about guaranteed drops as early as possible seem initially easy but aren't due to things like conditional moves, partial moves etc. I.e. it would still be quite a bit more complicated to teach it.
Furthermore in both alternatives to 3) you likely still wouldn't (guaranteed) drop the guard temporary in the other match branch before you requesting the new guard as guaranteeing compiler behavior like that means having a lot of additional edges in many partial move scenarios and potentially even a bunch of additional branch. In both cases it would likely increase code size and mess with the branch predictor and I-caches and be generally just not good (but it would help with async await boundaries).
Re: Rust's Sneaky Deadlock With `if let` Blocks
#27Re: Rust's Sneaky Deadlock With `if let` Blocks
#28Earlier quoted context omitted.
The issue here isn't new features at all. `if let` is more or less syntax sugar for `match`. And match behaves like that, too and has been in rust since 1.0. That match did behaves like that is due to some old, you could say legacy, reasons and had been criticized even in the early rust 1.x days. But changing a behavior which subtle change when locks are released is not something you can easily fix with a rust editio…
Funny you say that: https://github.com/rust-lang/rust/issues/131154 Looks like this is getting fixed in Rust 2024 :)
Through making if-let less syntax sugar for changing a implicit behavior people most likely didn't rely on but have problems with seems like a very good idea
My comment about this being hard to change was mainly about match. Not considering the option of making if-let less syntax sugary.
And in difference to if-let, for match people do (or at least did years ago in production code) rely on it.
Re: Rust's Sneaky Deadlock With `if let` Blocks
#29Earlier quoted context omitted.
This really reads like satire but feels like the author is actually being sincere. I’ve seen so many deadlocks happening due to pthread mutexes. Certainly way more than this syntactic corner case. It’s so common in fact that I saw a codebase that made their mutexes recursive to avoid having to think about it.
[flagged]
Re: Rust's Sneaky Deadlock With `if let` Blocks
#30Is there any explicit reason as to why RWLock can’t simply try to upgrade the read-lock to write-lock given they’re both being held by the same thread?
let lock = RwLock::new(Box::new(111));
let r: &i32 = &**lock.read().unwrap(); // points to 111
*lock.write().unwrap() = Box::new(222); // allocates a new Box and deallocates 111
println!("{}", *r); // use after free