Skip to content

Make TypeFolder::fold_* return Result #91230

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 28, 2021
Prev Previous commit
Next Next commit
Avoid UB when short-circuiting try_map_id for Vec
  • Loading branch information
eggyal committed Nov 27, 2021
commit 04f1c09f90abebd0c6a7658105dec57099a63caa
15 changes: 11 additions & 4 deletions compiler/rustc_data_structures/src/functor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ impl<T> IdFunctor for Vec<T> {
// FIXME: We don't really care about panics here and leak
// far more than we should, but that should be fine for now.
let len = self.len();
let mut error = Ok(());
unsafe {
self.set_len(0);
let start = self.as_mut_ptr();
Expand All @@ -96,16 +95,24 @@ impl<T> IdFunctor for Vec<T> {
match f(ptr::read(p)) {
Ok(value) => ptr::write(p, value),
Err(err) => {
error = Err(err);
break;
// drop all other elements in self
// (current element was "moved" into the call to f)
for j in (0..i).chain(i + 1..len) {
let p = start.add(j);
ptr::drop_in_place(p);
}

// returning will drop self, releasing the allocation
// (len is 0 so elements will not be re-dropped)
return Err(err);
}
}
}
// Even if we encountered an error, set the len back
// so we don't leak memory.
self.set_len(len);
}
error.map(|()| self)
Ok(self)
}
}

Expand Down