Skip to content

Rollup of 11 pull requests #70202

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

Closed
wants to merge 52 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
57b1e7a
Remove the call that makes miri fail
DutchGhost Mar 16, 2020
dcc2321
The const_forget_box was unused, and doesns't add anything to test by…
DutchGhost Mar 16, 2020
0760803
rather than removing const_forget_box, stick an attribute on it and e…
DutchGhost Mar 16, 2020
a5206f9
add `Option::{zip,zip_with}` methods under "option_zip" gate
WaffleLapkin Mar 13, 2020
d36d3fa
fixes to `Option::{zip,zip_with}`
WaffleLapkin Mar 18, 2020
4c363e3
Move the const-forget test into ui tests
DutchGhost Mar 18, 2020
6c37252
permit negative impls for non-auto traits
nikomatsakis Jan 8, 2020
f1b86fc
make a custom error for overlap with negative impls
nikomatsakis Jan 8, 2020
a781991
introduce `negative_impls` feature gate and document
nikomatsakis Jan 9, 2020
9312607
create a tracking issue and link to it
nikomatsakis Jan 17, 2020
c5b01fd
bump negative impls version to 1.44.0
nikomatsakis Mar 13, 2020
eb3bcf8
convert to doc comments
nikomatsakis Mar 13, 2020
30e73e6
move feature-gate-negative-impls test to traits/negative-impls
nikomatsakis Mar 13, 2020
1868640
comment the `typeck-negative-impls-builtin` test
nikomatsakis Mar 13, 2020
09f1e6a
give the negative-impls-builtin test a more sensible name
nikomatsakis Mar 13, 2020
377835e
move stderr file too
nikomatsakis Mar 13, 2020
d3866a4
add test for negative specializes negative
nikomatsakis Mar 13, 2020
e6db481
use slice pattern instead of calling `is_empty()` and `[0]`
nikomatsakis Mar 19, 2020
62d46f8
pacify the merciless x.py fmt
nikomatsakis Mar 19, 2020
121bffc
make "other" in docs of `Option::{zip,zip_with}` monofont
WaffleLapkin Mar 19, 2020
bd6deaa
Derive PartialEq, Eq and Hash for RangeInclusive
Mar 19, 2020
6570e27
Removed unused `Hasher` import.
Mar 19, 2020
fd0e15b
Make std::sync::Arc compatible with ThreadSanitizer
tmiasko Mar 20, 2020
d6f3a43
Update const_forget.rs
DutchGhost Mar 20, 2020
3f6236e
Fix oudated comment for NamedRegionMap
bjorn3 Mar 20, 2020
e61f126
Replace shared root with optional root
Mark-Simulacrum Mar 18, 2020
1c44f85
Remove shared root code and assertions from BTree nodes
Mark-Simulacrum Mar 18, 2020
3c04fda
Make functions dependent only on shared root avoidance safe
Mark-Simulacrum Mar 18, 2020
54b7c38
Drop NodeHeader type from BTree code
Mark-Simulacrum Mar 18, 2020
13f6d77
Simplify ensure_root_is_owned callers
Mark-Simulacrum Mar 18, 2020
4d85314
Update test commentary for shared root removal
Mark-Simulacrum Mar 20, 2020
bce7f6f
Fix debugger pretty printing of BTrees
Mark-Simulacrum Mar 18, 2020
32670dd
Clean up E0439 explanation
GuillaumeGomez Mar 20, 2020
0296d49
fix layout_test visitor name
RalfJung Mar 10, 2020
55c2cf2
add debug option to #[rustc_layout]
RalfJung Mar 10, 2020
d9f60bc
add a test for rustc_layout(debug)
RalfJung Mar 10, 2020
0d018a5
expand_include: set `.directory` to dir of included file.
Centril Mar 20, 2020
c62e36b
make rustc_layout also work for type definitions
RalfJung Mar 20, 2020
951a366
remove redundant import (clippy::single_component_path_imports)
matthiaskrgr Mar 19, 2020
ad00e91
remove redundant returns (clippy::needless_return)
matthiaskrgr Mar 20, 2020
7b49678
fmt
RalfJung Mar 20, 2020
111301d
Rollup merge of #65097 - tmiasko:arc, r=Amanieu
Dylan-DPC Mar 21, 2020
16338b1
Rollup merge of #68004 - nikomatsakis:negative-impls, r=varkor
Dylan-DPC Mar 21, 2020
c31cd0f
Rollup merge of #69901 - RalfJung:rustc_layout, r=eddyb
Dylan-DPC Mar 21, 2020
63ceb8e
Rollup merge of #69997 - WaffleLapkin:option_zip, r=LukasKalbertodt
Dylan-DPC Mar 21, 2020
0751e6a
Rollup merge of #70038 - DutchGhost:const-forget-tests, r=RalfJung
Dylan-DPC Mar 21, 2020
1bdc860
Rollup merge of #70111 - Mark-Simulacrum:btree-no-shared, r=cuviper
Dylan-DPC Mar 21, 2020
be6e983
Rollup merge of #70166 - CDirkx:range-inclusive-derives, r=cramertj
Dylan-DPC Mar 21, 2020
8ce4c1c
Rollup merge of #70177 - bjorn3:patch-2, r=Dylan-DPC
Dylan-DPC Mar 21, 2020
c4494c8
Rollup merge of #70184 - Centril:include-mod-relativism, r=petrochenkov
Dylan-DPC Mar 21, 2020
b20db78
Rollup merge of #70187 - matthiaskrgr:cl2ppy, r=Mark-Simulacrum
Dylan-DPC Mar 21, 2020
cb62d67
Rollup merge of #70188 - GuillaumeGomez:cleanup-e0439, r=Dylan-DPC
Dylan-DPC Mar 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove shared root code and assertions from BTree nodes
  • Loading branch information
Mark-Simulacrum committed Mar 20, 2020
commit 1c44f852df205ae6d363cc9a2b12f8093b3ed342
53 changes: 2 additions & 51 deletions src/liballoc/collections/btree/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,21 +111,6 @@ impl<K, V> LeafNode<K, V> {
}
}

impl<K, V> NodeHeader<K, V> {
fn is_shared_root(&self) -> bool {
ptr::eq(self, &EMPTY_ROOT_NODE as *const _ as *const _)
}
}

// We need to implement Sync here in order to make a static instance.
unsafe impl Sync for NodeHeader<(), ()> {}

// An empty node used as a placeholder for the root node, to avoid allocations.
// We use just a header in order to save space, since no operation on an empty tree will
// ever take a pointer past the first key.
static EMPTY_ROOT_NODE: NodeHeader<(), ()> =
NodeHeader { parent: ptr::null(), parent_idx: MaybeUninit::uninit(), len: 0 };

/// The underlying representation of internal nodes. As with `LeafNode`s, these should be hidden
/// behind `BoxedNode`s to prevent dropping uninitialized keys and values. Any pointer to an
/// `InternalNode` can be directly casted to a pointer to the underlying `LeafNode` portion of the
Expand Down Expand Up @@ -154,8 +139,8 @@ impl<K, V> InternalNode<K, V> {
}

/// A managed, non-null pointer to a node. This is either an owned pointer to
/// `LeafNode<K, V>`, an owned pointer to `InternalNode<K, V>`, or a (not owned)
/// pointer to `NodeHeader<(), ()` (more specifically, the pointer to EMPTY_ROOT_NODE).
/// `LeafNode<K, V>` or an owned pointer to `InternalNode<K, V>`.
///
/// All of these types have a `NodeHeader<K, V>` prefix, meaning that they have at
/// least the same size as `NodeHeader<K, V>` and store the same kinds of data at the same
/// offsets; and they have a pointer alignment at least as large as `NodeHeader<K, V>`'s.
Expand Down Expand Up @@ -196,20 +181,6 @@ unsafe impl<K: Sync, V: Sync> Sync for Root<K, V> {}
unsafe impl<K: Send, V: Send> Send for Root<K, V> {}

impl<K, V> Root<K, V> {
/// Whether the instance of `Root` wraps a shared, empty root node. If not,
/// the entire tree is uniquely owned by the owner of the `Root` instance.
pub fn is_shared_root(&self) -> bool {
self.as_ref().is_shared_root()
}

/// Returns a shared tree, wrapping a shared root node that is eternally empty.
pub fn shared_empty_root() -> Self {
Root {
node: unsafe { BoxedNode::from_ptr(NonNull::from(&EMPTY_ROOT_NODE).cast()) },
height: 0,
}
}

/// Returns a new owned tree, with its own root node that is initially empty.
pub fn new_leaf() -> Self {
Root { node: BoxedNode::from_leaf(Box::new(unsafe { LeafNode::new() })), height: 0 }
Expand Down Expand Up @@ -245,7 +216,6 @@ impl<K, V> Root<K, V> {
/// Adds a new internal node with a single edge, pointing to the previous root, and make that
/// new node the root. This increases the height by 1 and is the opposite of `pop_level`.
pub fn push_level(&mut self) -> NodeRef<marker::Mut<'_>, K, V, marker::Internal> {
debug_assert!(!self.is_shared_root());
let mut new_node = Box::new(unsafe { InternalNode::new() });
new_node.edges[0].write(unsafe { BoxedNode::from_ptr(self.node.as_ptr()) });

Expand Down Expand Up @@ -381,19 +351,13 @@ impl<BorrowType, K, V, Type> NodeRef<BorrowType, K, V, Type> {
/// Unsafe because the node must not be the shared root. For more information,
/// see the `NodeRef` comments.
unsafe fn as_leaf(&self) -> &LeafNode<K, V> {
debug_assert!(!self.is_shared_root());
self.node.as_ref()
}

fn as_header(&self) -> &NodeHeader<K, V> {
unsafe { &*(self.node.as_ptr() as *const NodeHeader<K, V>) }
}

/// Returns whether the node is the shared, empty root.
pub fn is_shared_root(&self) -> bool {
self.as_header().is_shared_root()
}

/// Borrows a view into the keys stored in the node.
/// Unsafe because the caller must ensure that the node is not the shared root.
pub unsafe fn keys(&self) -> &[K] {
Expand Down Expand Up @@ -464,7 +428,6 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
pub unsafe fn deallocate_and_ascend(
self,
) -> Option<Handle<NodeRef<marker::Owned, K, V, marker::Internal>, marker::Edge>> {
assert!(!self.is_shared_root());
let height = self.height;
let node = self.node;
let ret = self.ascend().ok();
Expand Down Expand Up @@ -527,14 +490,12 @@ impl<'a, K, V, Type> NodeRef<marker::Mut<'a>, K, V, Type> {
impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Immut<'a>, K, V, Type> {
/// Unsafe because the caller must ensure that the node is not the shared root.
unsafe fn into_key_slice(self) -> &'a [K] {
debug_assert!(!self.is_shared_root());
// We cannot be the shared root, so `as_leaf` is okay.
slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().keys), self.len())
}

/// Unsafe because the caller must ensure that the node is not the shared root.
unsafe fn into_val_slice(self) -> &'a [V] {
debug_assert!(!self.is_shared_root());
// We cannot be the shared root, so `as_leaf` is okay.
slice::from_raw_parts(MaybeUninit::first_ptr(&self.as_leaf().vals), self.len())
}
Expand All @@ -555,7 +516,6 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

/// Unsafe because the caller must ensure that the node is not the shared root.
unsafe fn into_key_slice_mut(mut self) -> &'a mut [K] {
debug_assert!(!self.is_shared_root());
// We cannot be the shared root, so `as_leaf_mut` is okay.
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).keys),
Expand All @@ -565,7 +525,6 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

/// Unsafe because the caller must ensure that the node is not the shared root.
unsafe fn into_val_slice_mut(mut self) -> &'a mut [V] {
debug_assert!(!self.is_shared_root());
slice::from_raw_parts_mut(
MaybeUninit::first_ptr_mut(&mut (*self.as_leaf_mut()).vals),
self.len(),
Expand All @@ -574,7 +533,6 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef<marker::Mut<'a>, K, V, Type> {

/// Unsafe because the caller must ensure that the node is not the shared root.
unsafe fn into_slices_mut(mut self) -> (&'a mut [K], &'a mut [V]) {
debug_assert!(!self.is_shared_root());
// We cannot use the getters here, because calling the second one
// invalidates the reference returned by the first.
// More precisely, it is the call to `len` that is the culprit,
Expand All @@ -592,7 +550,6 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
/// Adds a key/value pair the end of the node.
pub fn push(&mut self, key: K, val: V) {
assert!(self.len() < CAPACITY);
debug_assert!(!self.is_shared_root());

let idx = self.len();

Expand All @@ -607,7 +564,6 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Leaf> {
/// Adds a key/value pair to the beginning of the node.
pub fn push_front(&mut self, key: K, val: V) {
assert!(self.len() < CAPACITY);
debug_assert!(!self.is_shared_root());

unsafe {
slice_insert(self.keys_mut(), 0, key);
Expand All @@ -624,7 +580,6 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
pub fn push(&mut self, key: K, val: V, edge: Root<K, V>) {
assert!(edge.height == self.height - 1);
assert!(self.len() < CAPACITY);
debug_assert!(!self.is_shared_root());

let idx = self.len();

Expand Down Expand Up @@ -658,7 +613,6 @@ impl<'a, K, V> NodeRef<marker::Mut<'a>, K, V, marker::Internal> {
pub fn push_front(&mut self, key: K, val: V, edge: Root<K, V>) {
assert!(edge.height == self.height - 1);
assert!(self.len() < CAPACITY);
debug_assert!(!self.is_shared_root());

unsafe {
slice_insert(self.keys_mut(), 0, key);
Expand Down Expand Up @@ -904,7 +858,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge
fn insert_fit(&mut self, key: K, val: V) -> *mut V {
// Necessary for correctness, but in a private module
debug_assert!(self.node.len() < CAPACITY);
debug_assert!(!self.node.is_shared_root());

unsafe {
slice_insert(self.node.keys_mut(), self.idx, key);
Expand Down Expand Up @@ -1081,7 +1034,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
/// - All the key/value pairs to the right of this handle are put into a newly
/// allocated node.
pub fn split(mut self) -> (NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, K, V, Root<K, V>) {
assert!(!self.node.is_shared_root());
unsafe {
let mut new_node = Box::new(LeafNode::new());

Expand Down Expand Up @@ -1113,7 +1065,6 @@ impl<'a, K, V> Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::KV>
pub fn remove(
mut self,
) -> (Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>, K, V) {
assert!(!self.node.is_shared_root());
unsafe {
let k = slice_remove(self.node.keys_mut(), self.idx);
let v = slice_remove(self.node.vals_mut(), self.idx);
Expand Down
14 changes: 6 additions & 8 deletions src/liballoc/collections/btree/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,12 @@ where
// Using `keys()` is fine here even if BorrowType is mutable, as all we return
// is an index -- not a reference.
let len = node.len();
if len > 0 {
let keys = unsafe { node.keys() }; // safe because a non-empty node cannot be the shared root
for (i, k) in keys.iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Ordering::Equal => return (i, true),
Ordering::Less => return (i, false),
}
let keys = unsafe { node.keys() }; // safe because a non-empty node cannot be the shared root
for (i, k) in keys.iter().enumerate() {
match key.cmp(k.borrow()) {
Ordering::Greater => {}
Ordering::Equal => return (i, true),
Ordering::Less => return (i, false),
}
}
(len, false)
Expand Down