I always wondered what the actuator in the exhaust air valve for my apartment ventilation was - now I'm pretty sure it's a wax motor! You can use a switch to increase the airflow, but it takes a few seconds to react and opens/closes very slowly and quietly.
Some of them are a sort of hydraulic one that uses a spring and some fluid to make the spring release slowly. No idea which you would have lol.
The slow closing prevents water hammer, at least in water systems. In air systems it might just prevent a blast of back pressure blowing all the dust out of your vents onto your carpet.
It's just the opposite side of the same mountain, used as a case study for modeling GLOF risk. In fact, they prominently cite "Potentially dangerous glacial lakes across the Tibetan Plateau" [1], which includes Gyirong Port and the downstream valley as a high risk of GLOFs and notes that many buildings there are exposed to potential flash flooding. Take a look at Fig. 5 [2] - the upper left cluster of dangerous lakes and exposed buildings is the site of the disaster. They also name Jilong, Nyalam, Dingri and Kangding as the Tibetan counties with the highest lake danger; the glacier collapse happened at the border of Jilong county.
Yes, editions are a great mechanism. It still has its limits, especially if you want easy edition migrations. All existing Rust code assumes it can drop any type whenever it wants, and that is not something you can just change across editions. You have to be very careful with defaults if you don't want conflicts when crossing edition boundaries.
The naïve idea would be to just say that all generic parameters have an implicit `where T: Move` bound, and you have to explicitly opt out of it with `where T: ?Move`, just like with `?Sized`.
In fact, that's exactly how I would expect it to work, but there may be non-obvious drawbacks.
The compat issue has always been associated types on std traits.
For example, should Iterator::Item be Move or ?Move
If you leave it as Move, you can't create any iterators over !Move types. If you change it to ?Move, then functions using generic iterators can't assume that the elements of an Iterator are always moveable. Which is a breaking change compared to now.
The most critical trait is probably Deref. Using !Move types without `Deref::Target: ?Move` is painful, because calling any method on boxed types relies on Deref.
The people working on this are aware that it poses backcompat problems that don't have obvious solutions. They are looking into non-obvious solutions. https://lcnr.de/blog/2025/11/28/implicit-auto-traits-assoc-t... is the most up-to-date one I'm currently aware of.
Niko Matsakis (T-Lang) has since also published a post on only-bounds: https://smallcultfollowing.com/babysteps/blog/2026/06/09/onl.... Sized hierarchy, Move, and Forget/Leak all share the same fundamental compat issues, so we're all pretty motivated to solve the underlying problems in a way that enables all the other features to be built on top.
I had read that post, but IIUC it doesn't address the kind of backcompat issues that I meant to be referring to (the ones that would apply even if there was only ever going to be one new question-mark trait).
I'm very probably missing something, but as a user I would definitely expect `Iterator::Item: Move`, but then also that `&{mut} T: Move where T: ?Move`.
But yeah I can see how these bounds are somewhat viral. Thanks!
Imagine if MyTrait comes from core/std. Adding an opt-out bound like ?Sized (or ?Move) is a breaking change for any generic code that relies on Sized/Move. But you want some traits from std to be open for !Move types.
Yes, destructuring is typically the only allowed way to get rid of linear/indestructible values. If the type has private fields, this is only possible in the same module, so commit(txn) and rollback(txn) would have to be implemented in the same module as the Transaction type.
> # How does this relate to the "pin ergonomics" initiative?
> This work is an alternative to Project Goal 2025H2: Continue Experimentation with Pin Ergonomics, which includes the following extensions:
> A new item family pin in lvalues, e.g. &pin x, &pin mut x, &pin const x.
> A one-off overload of Rust's Drop trait, e.g. fn drop(&pin mut self).
> A new item kind pin in patterns, e.g. &pin .
> Notably, this work does not solve pin's duplicate definition problem, meaning that even with these extentions we still end up with Trait and PinnedTrait variants of existing traits. The Drop trait being the exception to this, since the initiative is proposing to special-case it using a one-off overload.
You could also detect when the elevator call button gets pressed again right after the elevator has left a floor. That means someone wasn't able to get on the elevator (and is now waiting for the next one).