mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Deny the unsafe_op_in_unsafe_fn
lint in
`rustc_arena`.
This commit is contained in:
parent
7a96158b53
commit
47fb8e6c70
@ -20,6 +20,7 @@
|
|||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![cfg_attr(test, feature(test))]
|
#![cfg_attr(test, feature(test))]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
#![deny(rustc::untranslatable_diagnostic)]
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
#![deny(rustc::diagnostic_outside_of_impl)]
|
#![deny(rustc::diagnostic_outside_of_impl)]
|
||||||
#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
|
#![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
|
||||||
@ -74,21 +75,29 @@ impl<T> ArenaChunk<T> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
|
unsafe fn new(capacity: usize) -> ArenaChunk<T> {
|
||||||
ArenaChunk {
|
ArenaChunk {
|
||||||
storage: NonNull::new_unchecked(Box::into_raw(Box::new_uninit_slice(capacity))),
|
storage: NonNull::from(Box::leak(Box::new_uninit_slice(capacity))),
|
||||||
entries: 0,
|
entries: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destroys this arena chunk.
|
/// Destroys this arena chunk.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that `len` elements of this chunk have been initialized.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn destroy(&mut self, len: usize) {
|
unsafe fn destroy(&mut self, len: usize) {
|
||||||
// The branch on needs_drop() is an -O1 performance optimization.
|
// The branch on needs_drop() is an -O1 performance optimization.
|
||||||
// Without the branch, dropping TypedArena<u8> takes linear time.
|
// Without the branch, dropping TypedArena<T> takes linear time.
|
||||||
if mem::needs_drop::<T>() {
|
if mem::needs_drop::<T>() {
|
||||||
|
// SAFETY: The caller must ensure that `len` elements of this chunk have
|
||||||
|
// been initialized.
|
||||||
|
unsafe {
|
||||||
let slice = self.storage.as_mut();
|
let slice = self.storage.as_mut();
|
||||||
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(&mut slice[..len]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Returns a pointer to the first allocated object.
|
// Returns a pointer to the first allocated object.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -255,7 +264,9 @@ impl<T> TypedArena<T> {
|
|||||||
self.ensure_capacity(len);
|
self.ensure_capacity(len);
|
||||||
|
|
||||||
let start_ptr = self.ptr.get();
|
let start_ptr = self.ptr.get();
|
||||||
self.ptr.set(start_ptr.add(len));
|
// SAFETY: `self.ensure_capacity` makes sure that there is enough space
|
||||||
|
// for `len` elements.
|
||||||
|
unsafe { self.ptr.set(start_ptr.add(len)) };
|
||||||
start_ptr
|
start_ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,6 +494,10 @@ impl DroplessArena {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The caller must ensure that `mem` is valid for writes up to
|
||||||
|
/// `size_of::<T>() * len`.
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
|
unsafe fn write_from_iter<T, I: Iterator<Item = T>>(
|
||||||
&self,
|
&self,
|
||||||
@ -494,13 +509,18 @@ impl DroplessArena {
|
|||||||
// Use a manual loop since LLVM manages to optimize it better for
|
// Use a manual loop since LLVM manages to optimize it better for
|
||||||
// slice iterators
|
// slice iterators
|
||||||
loop {
|
loop {
|
||||||
let value = iter.next();
|
// SAFETY: The caller must ensure that `mem` is valid for writes up to
|
||||||
if i >= len || value.is_none() {
|
// `size_of::<T>() * len`.
|
||||||
|
unsafe {
|
||||||
|
match iter.next() {
|
||||||
|
Some(value) if i < len => mem.add(i).write(value),
|
||||||
|
Some(_) | None => {
|
||||||
// We only return as many items as the iterator gave us, even
|
// We only return as many items as the iterator gave us, even
|
||||||
// though it was supposed to give us `len`
|
// though it was supposed to give us `len`
|
||||||
return slice::from_raw_parts_mut(mem, i);
|
return slice::from_raw_parts_mut(mem, i);
|
||||||
}
|
}
|
||||||
ptr::write(mem.add(i), value.unwrap());
|
}
|
||||||
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user