Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #64432 - gnzlbg:simplify_truncate, r=alexcrichton
Make the semantics of Vec::truncate(N) consistent with slices. This commit simplifies the implementation of `Vec::truncate(N)` and makes its semantics identical to dropping the `[vec.len() - N..]` sub-slice tail of the vector, which is the same behavior as dropping a vector containing the same sub-slice. This changes two unspecified aspects of `Vec::truncate` behavior: * the drop order, from back-to-front to front-to-back, * the behavior of `Vec::truncate` on panics: if dropping one element of the tail panics, currently, `Vec::truncate` panics, but with this PR all other elements are still dropped, and if dropping a second element of the tail panics, with this PR, the program aborts. Programs can trivially observe both changes. For example ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7bef575b83b06e82b3e3529e4edbcac7)): ```rust fn main() { struct Bomb(usize); impl Drop for Bomb { fn drop(&mut self) { panic!(format!("{}", self.0)); } } let mut v = vec![Bomb(0), Bomb(1)]; std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { v.truncate(0); })); assert_eq!(v.len(), 1); std::mem::forget(v); } ``` panics printing `1` today and succeeds. With this change, it panics printing `0` first (due to the drop order change), and then aborts with a double-panic printing `1`, just like dropping the `[Bomb(0), Bomb(1)]` slice does, or dropping `vec![Bomb(0), Bomb(1)]` does. This needs to go through a crater run. r? @SimonSapin
- Loading branch information