Skip to content

Commit 04f1c09

Browse files
committed
Avoid UB when short-circuiting try_map_id for Vec
1 parent 51e15ac commit 04f1c09

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

compiler/rustc_data_structures/src/functor.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ impl<T> IdFunctor for Vec<T> {
8787
// FIXME: We don't really care about panics here and leak
8888
// far more than we should, but that should be fine for now.
8989
let len = self.len();
90-
let mut error = Ok(());
9190
unsafe {
9291
self.set_len(0);
9392
let start = self.as_mut_ptr();
@@ -96,16 +95,24 @@ impl<T> IdFunctor for Vec<T> {
9695
match f(ptr::read(p)) {
9796
Ok(value) => ptr::write(p, value),
9897
Err(err) => {
99-
error = Err(err);
100-
break;
98+
// drop all other elements in self
99+
// (current element was "moved" into the call to f)
100+
for j in (0..i).chain(i + 1..len) {
101+
let p = start.add(j);
102+
ptr::drop_in_place(p);
103+
}
104+
105+
// returning will drop self, releasing the allocation
106+
// (len is 0 so elements will not be re-dropped)
107+
return Err(err);
101108
}
102109
}
103110
}
104111
// Even if we encountered an error, set the len back
105112
// so we don't leak memory.
106113
self.set_len(len);
107114
}
108-
error.map(|()| self)
115+
Ok(self)
109116
}
110117
}
111118

0 commit comments

Comments
 (0)