Skip to content

Commit ff0da1d

Browse files
lilyballalexcrichton
authored andcommitted
---
yaml --- r: 114175 b: refs/heads/master c: d547de9 h: refs/heads/master i: 114173: 780e3b0 114171: 6143ab4 114167: 66f9617 114159: b14151e 114143: 0400f43 114111: 242db8a 114047: 9c09d6a 113919: 57f1f10 113663: b73fc66 v: v3
1 parent b885aa4 commit ff0da1d

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 4bcc4d76a049a50474764383889e4ede9388da9f
2+
refs/heads/master: d547de998d33e5b688533f4159ea997c940d9431
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: ec0258a381b88b5574e3f8ce72ae553ac3a574b7
55
refs/heads/try: 7c6c492fb2af9a85f21ff952942df3523b22fd17

trunk/src/libstd/vec.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,14 +635,14 @@ impl<T> Vec<T> {
635635
/// ```
636636
pub fn truncate(&mut self, len: uint) {
637637
unsafe {
638-
let mut i = len;
639638
// drop any extra elements
640-
while i < self.len {
641-
ptr::read(self.as_slice().unsafe_ref(i));
642-
i += 1;
639+
while len < self.len {
640+
// decrement len before the read(), so a failure on Drop doesn't
641+
// re-drop the just-failed value.
642+
self.len -= 1;
643+
ptr::read(self.as_slice().unsafe_ref(self.len));
643644
}
644645
}
645-
self.len = len;
646646
}
647647

648648
/// Work with `self` as a mutable slice.
@@ -1862,4 +1862,39 @@ mod tests {
18621862
assert_eq!(b[0].x, 42);
18631863
assert_eq!(b[1].x, 84);
18641864
}
1865+
1866+
#[test]
1867+
fn test_vec_truncate_drop() {
1868+
static mut drops: uint = 0;
1869+
struct Elem(int);
1870+
impl Drop for Elem {
1871+
fn drop(&mut self) {
1872+
unsafe { drops += 1; }
1873+
}
1874+
}
1875+
1876+
let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
1877+
assert_eq!(unsafe { drops }, 0);
1878+
v.truncate(3);
1879+
assert_eq!(unsafe { drops }, 2);
1880+
v.truncate(0);
1881+
assert_eq!(unsafe { drops }, 5);
1882+
}
1883+
1884+
#[test]
1885+
#[should_fail]
1886+
fn test_vec_truncate_fail() {
1887+
struct BadElem(int);
1888+
impl Drop for BadElem {
1889+
fn drop(&mut self) {
1890+
let BadElem(ref mut x) = *self;
1891+
if *x == 0xbadbeef {
1892+
fail!("BadElem failure: 0xbadbeef")
1893+
}
1894+
}
1895+
}
1896+
1897+
let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
1898+
v.truncate(0);
1899+
}
18651900
}

0 commit comments

Comments
 (0)