From 3533204e999cf70378131c63e1abbfe812109792 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 26 Dec 2020 15:59:02 +0100 Subject: [PATCH 01/13] clarify wrapping ptr arithmetic docs --- library/core/src/ptr/const_ptr.rs | 87 ++++++++++++++++++------------- library/core/src/ptr/mut_ptr.rs | 87 ++++++++++++++++++------------- 2 files changed, 102 insertions(+), 72 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 8fd9ff768c4f4..6638033566f29 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -232,23 +232,26 @@ impl *const T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `x.wrapping_offset((y as usize).wrapping_sub(x as usize) / size_of::())` - /// is *not* the same as `y`, and dereferencing it is undefined behavior - /// unless `x` and `y` point into the same allocated object. + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// Compared to [`offset`], this method basically delays the requirement of staying - /// within the same allocated object: [`offset`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// Compared to [`offset`], this method basically delays the requirement of staying within the + /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] + /// can be optimized better and is thus preferable in performance-sensitive code. + /// + /// `x.wrapping_offset(o).wrapping_offset(-o)` is always the same as `x` (if `-o` does not + /// overflow). In other words, leaving the allocated object and then re-entering it later is + /// permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -571,19 +574,25 @@ impl *const T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. + /// + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// Compared to [`add`], this method basically delays the requirement of staying within the + /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] + /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// Compared to [`add`], this method basically delays the requirement of staying - /// within the same allocated object: [`add`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_add` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the + /// allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -628,19 +637,25 @@ impl *const T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. + /// + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// Compared to [`sub`], this method basically delays the requirement of staying within the + /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] + /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// Compared to [`sub`], this method basically delays the requirement of staying - /// within the same allocated object: [`sub`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the + /// allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 5f94c2393aef3..a0edb036c251d 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -238,23 +238,26 @@ impl *mut T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `x.wrapping_offset((y as usize).wrapping_sub(x as usize) / size_of::())` - /// is *not* the same as `y`, and dereferencing it is undefined behavior - /// unless `x` and `y` point into the same allocated object. + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// Compared to [`offset`], this method basically delays the requirement of staying - /// within the same allocated object: [`offset`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_offset` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`offset`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// Compared to [`offset`], this method basically delays the requirement of staying within the + /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_offset` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] + /// can be optimized better and is thus preferable in performance-sensitive code. + /// + /// `x.wrapping_offset(o).wrapping_offset(-o)` is always the same as `x` (if `-o` does not + /// overflow). In other words, leaving the allocated object and then re-entering it later is + /// permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -678,19 +681,25 @@ impl *mut T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. + /// + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// Compared to [`add`], this method basically delays the requirement of staying within the + /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_add` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] + /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// Compared to [`add`], this method basically delays the requirement of staying - /// within the same allocated object: [`add`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_add` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`add`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the + /// allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -735,19 +744,25 @@ impl *mut T { /// /// # Safety /// - /// The resulting pointer does not need to be in bounds, but it is - /// potentially hazardous to dereference (which requires `unsafe`). + /// This operation itself is always safe, but using the resulting pointer is not. + /// + /// The resulting pointer remains attached to the same allocated object that `self` points to. + /// It may *not* be used to access a different allocated object. Note that in Rust, every + /// (stack-allocated) variable is considered a separate allocated object. + /// + /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / + /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is + /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the + /// same allocated object. /// - /// In particular, the resulting pointer remains attached to the same allocated - /// object that `self` points to. It may *not* be used to access a - /// different allocated object. Note that in Rust, - /// every (stack-allocated) variable is considered a separate allocated object. + /// Compared to [`sub`], this method basically delays the requirement of staying within the + /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object + /// boundaries; `wrapping_sub` produces a pointer but still leads to Undefined Behavior if a + /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] + /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// Compared to [`sub`], this method basically delays the requirement of staying - /// within the same allocated object: [`sub`] is immediate Undefined Behavior when - /// crossing object boundaries; `wrapping_sub` produces a pointer but still leads - /// to Undefined Behavior if that pointer is dereferenced. [`sub`] can be optimized - /// better and is thus preferable in performance-sensitive code. + /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the + /// allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. From 8543388beb52785897b87e3f0a5ffd3c8560f956 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 26 Dec 2020 18:07:52 +0100 Subject: [PATCH 02/13] address review feedback --- library/core/src/ptr/const_ptr.rs | 35 ++++++++++++++++++------------- library/core/src/ptr/mut_ptr.rs | 35 ++++++++++++++++++------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 6638033566f29..38519f759ae05 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -238,10 +238,10 @@ impl *const T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`offset`], this method basically delays the requirement of staying within the /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object @@ -249,9 +249,10 @@ impl *const T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// `x.wrapping_offset(o).wrapping_offset(-o)` is always the same as `x` (if `-o` does not - /// overflow). In other words, leaving the allocated object and then re-entering it later is - /// permitted. + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, + /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other + /// words, leaving the allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -580,10 +581,10 @@ impl *const T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`add`], this method basically delays the requirement of staying within the /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object @@ -591,6 +592,8 @@ impl *const T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] /// can be optimized better and is thus preferable in performance-sensitive code. /// + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// @@ -643,10 +646,10 @@ impl *const T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`sub`], this method basically delays the requirement of staying within the /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object @@ -654,6 +657,8 @@ impl *const T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] /// can be optimized better and is thus preferable in performance-sensitive code. /// + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index a0edb036c251d..92f4e431de499 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -244,10 +244,10 @@ impl *mut T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_offset((y as isize) - (x as isize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`offset`], this method basically delays the requirement of staying within the /// same allocated object: [`offset`] is immediate Undefined Behavior when crossing object @@ -255,9 +255,10 @@ impl *mut T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`offset`] /// can be optimized better and is thus preferable in performance-sensitive code. /// - /// `x.wrapping_offset(o).wrapping_offset(-o)` is always the same as `x` (if `-o` does not - /// overflow). In other words, leaving the allocated object and then re-entering it later is - /// permitted. + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, + /// `x.wrapping_offset(o).wrapping_offset(o.wrapping_neg())` is always the same as `x`. In other + /// words, leaving the allocated object and then re-entering it later is permitted. /// /// If you need to cross object boundaries, cast the pointer to an integer and /// do the arithmetic there. @@ -687,10 +688,10 @@ impl *mut T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_add((y as usize) - (x as usize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`add`], this method basically delays the requirement of staying within the /// same allocated object: [`add`] is immediate Undefined Behavior when crossing object @@ -698,6 +699,8 @@ impl *mut T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`add`] /// can be optimized better and is thus preferable in performance-sensitive code. /// + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// @@ -750,10 +753,10 @@ impl *mut T { /// It may *not* be used to access a different allocated object. Note that in Rust, every /// (stack-allocated) variable is considered a separate allocated object. /// - /// In other words, `let z = x.wrapping_add((y as usize).wrapping_sub(x as usize) / - /// size_of::())` does *not* make `z` the same as `y`: `z` is still attached to the object `x` is - /// attached to, and dereferencing it is Undefined Behavior unless `x` and `y` point into the - /// same allocated object. + /// In other words, `let z = x.wrapping_sub((x as usize) - (y as usize))` does *not* make `z` + /// the same as `y` even if we assume `T` has size `1` and there is no overflow: `z` is still + /// attached to the object `x` is attached to, and dereferencing it is Undefined Behavior unless + /// `x` and `y` point into the same allocated object. /// /// Compared to [`sub`], this method basically delays the requirement of staying within the /// same allocated object: [`sub`] is immediate Undefined Behavior when crossing object @@ -761,6 +764,8 @@ impl *mut T { /// pointer is dereferenced when it is out-of-bounds of the object it is attached to. [`sub`] /// can be optimized better and is thus preferable in performance-sensitive code. /// + /// The delayed check only considers the value of the pointer that was dereferenced, not the + /// intermediate values used during the computation of the final result. For example, /// `x.wrapping_add(o).wrapping_sub(o)` is always the same as `x`. In other words, leaving the /// allocated object and then re-entering it later is permitted. /// From be3a5a1beccaebdae7deb46870eb4e711464c738 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Thu, 17 Dec 2020 20:58:25 +0100 Subject: [PATCH 03/13] BTreeMap: rename the area access methods --- library/alloc/src/collections/btree/node.rs | 98 ++++++++++----------- 1 file changed, 48 insertions(+), 50 deletions(-) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 16b4b1091eff7..b3641a7a0c697 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -489,7 +489,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// /// # Safety /// `index` is in bounds of 0..CAPACITY - unsafe fn key_area_mut_at(&mut self, index: I) -> &mut Output + unsafe fn key_area_mut(&mut self, index: I) -> &mut Output where I: SliceIndex<[MaybeUninit], Output = Output>, { @@ -503,7 +503,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// /// # Safety /// `index` is in bounds of 0..CAPACITY - unsafe fn val_area_mut_at(&mut self, index: I) -> &mut Output + unsafe fn val_area_mut(&mut self, index: I) -> &mut Output where I: SliceIndex<[MaybeUninit], Output = Output>, { @@ -519,7 +519,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { /// /// # Safety /// `index` is in bounds of 0..CAPACITY + 1 - unsafe fn edge_area_mut_at(&mut self, index: I) -> &mut Output + unsafe fn edge_area_mut(&mut self, index: I) -> &mut Output where I: SliceIndex<[MaybeUninit>], Output = Output>, { @@ -583,8 +583,8 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { assert!(idx < CAPACITY); *len += 1; unsafe { - self.key_area_mut_at(idx).write(key); - self.val_area_mut_at(idx).write(val); + self.key_area_mut(idx).write(key); + self.val_area_mut(idx).write(val); } } @@ -593,8 +593,8 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { let new_len = self.len() + 1; assert!(new_len <= CAPACITY); unsafe { - slice_insert(self.key_area_mut_at(..new_len), 0, key); - slice_insert(self.val_area_mut_at(..new_len), 0, val); + slice_insert(self.key_area_mut(..new_len), 0, key); + slice_insert(self.val_area_mut(..new_len), 0, val); *self.len_mut() = new_len as u16; } } @@ -627,9 +627,9 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { assert!(idx < CAPACITY); *len += 1; unsafe { - self.key_area_mut_at(idx).write(key); - self.val_area_mut_at(idx).write(val); - self.edge_area_mut_at(idx + 1).write(edge.node); + self.key_area_mut(idx).write(key); + self.val_area_mut(idx).write(val); + self.edge_area_mut(idx + 1).write(edge.node); Handle::new_edge(self.reborrow_mut(), idx + 1).correct_parent_link(); } } @@ -642,9 +642,9 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { assert!(new_len <= CAPACITY); unsafe { - slice_insert(self.key_area_mut_at(..new_len), 0, key); - slice_insert(self.val_area_mut_at(..new_len), 0, val); - slice_insert(self.edge_area_mut_at(..new_len + 1), 0, edge.node); + slice_insert(self.key_area_mut(..new_len), 0, key); + slice_insert(self.val_area_mut(..new_len), 0, val); + slice_insert(self.edge_area_mut(..new_len + 1), 0, edge.node); *self.len_mut() = new_len as u16; } @@ -662,12 +662,12 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { let idx = self.len() - 1; unsafe { - let key = self.key_area_mut_at(idx).assume_init_read(); - let val = self.val_area_mut_at(idx).assume_init_read(); + let key = self.key_area_mut(idx).assume_init_read(); + let val = self.val_area_mut(idx).assume_init_read(); let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(mut internal) => { - let node = internal.edge_area_mut_at(idx + 1).assume_init_read(); + let node = internal.edge_area_mut(idx + 1).assume_init_read(); let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData }; // Currently, clearing the parent link is superfluous, because we will // insert the node elsewhere and set its parent link again. @@ -690,12 +690,12 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { let old_len = self.len(); unsafe { - let key = slice_remove(self.key_area_mut_at(..old_len), 0); - let val = slice_remove(self.val_area_mut_at(..old_len), 0); + let key = slice_remove(self.key_area_mut(..old_len), 0); + let val = slice_remove(self.val_area_mut(..old_len), 0); let edge = match self.reborrow_mut().force() { ForceResult::Leaf(_) => None, ForceResult::Internal(mut internal) => { - let node = slice_remove(internal.edge_area_mut_at(..old_len + 1), 0); + let node = slice_remove(internal.edge_area_mut(..old_len + 1), 0); let mut edge = Root { node, height: internal.height - 1, _marker: PhantomData }; // Currently, clearing the parent link is superfluous, because we will // insert the node elsewhere and set its parent link again. @@ -919,11 +919,11 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark let new_len = self.node.len() + 1; unsafe { - slice_insert(self.node.key_area_mut_at(..new_len), self.idx, key); - slice_insert(self.node.val_area_mut_at(..new_len), self.idx, val); + slice_insert(self.node.key_area_mut(..new_len), self.idx, key); + slice_insert(self.node.val_area_mut(..new_len), self.idx, val); *self.node.len_mut() = new_len as u16; - self.node.val_area_mut_at(self.idx).assume_init_mut() + self.node.val_area_mut(self.idx).assume_init_mut() } } } @@ -978,9 +978,9 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, let new_len = self.node.len() + 1; unsafe { - slice_insert(self.node.key_area_mut_at(..new_len), self.idx, key); - slice_insert(self.node.val_area_mut_at(..new_len), self.idx, val); - slice_insert(self.node.edge_area_mut_at(..new_len + 1), self.idx + 1, edge.node); + slice_insert(self.node.key_area_mut(..new_len), self.idx, key); + slice_insert(self.node.val_area_mut(..new_len), self.idx, val); + slice_insert(self.node.edge_area_mut(..new_len + 1), self.idx + 1, edge.node); *self.node.len_mut() = new_len as u16; self.node.correct_childrens_parent_links(self.idx + 1..new_len + 1); @@ -1085,7 +1085,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeTyp impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType>, marker::KV> { pub fn key_mut(&mut self) -> &mut K { - unsafe { self.node.key_area_mut_at(self.idx).assume_init_mut() } + unsafe { self.node.key_area_mut(self.idx).assume_init_mut() } } pub fn into_val_mut(self) -> &'a mut V { @@ -1127,16 +1127,16 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> let new_len = self.node.len() - self.idx - 1; new_node.len = new_len as u16; unsafe { - let k = self.node.key_area_mut_at(self.idx).assume_init_read(); - let v = self.node.val_area_mut_at(self.idx).assume_init_read(); + let k = self.node.key_area_mut(self.idx).assume_init_read(); + let v = self.node.val_area_mut(self.idx).assume_init_read(); ptr::copy_nonoverlapping( - self.node.key_area_mut_at(self.idx + 1..).as_ptr(), + self.node.key_area_mut(self.idx + 1..).as_ptr(), new_node.keys.as_mut_ptr(), new_len, ); ptr::copy_nonoverlapping( - self.node.val_area_mut_at(self.idx + 1..).as_ptr(), + self.node.val_area_mut(self.idx + 1..).as_ptr(), new_node.vals.as_mut_ptr(), new_len, ); @@ -1173,8 +1173,8 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { let old_len = self.node.len(); unsafe { - let k = slice_remove(self.node.key_area_mut_at(..old_len), self.idx); - let v = slice_remove(self.node.val_area_mut_at(..old_len), self.idx); + let k = slice_remove(self.node.key_area_mut(..old_len), self.idx); + let v = slice_remove(self.node.val_area_mut(..old_len), self.idx); *self.node.len_mut() = (old_len - 1) as u16; ((k, v), self.left_edge()) } @@ -1195,7 +1195,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, let kv = self.split_leaf_data(&mut new_node.data); let new_len = usize::from(new_node.data.len); ptr::copy_nonoverlapping( - self.node.edge_area_mut_at(self.idx + 1..).as_ptr(), + self.node.edge_area_mut(self.idx + 1..).as_ptr(), new_node.edges.as_mut_ptr(), new_len + 1, ); @@ -1321,25 +1321,23 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { unsafe { *left_node.len_mut() = new_left_len as u16; - let parent_key = - slice_remove(parent_node.key_area_mut_at(..old_parent_len), parent_idx); - left_node.key_area_mut_at(old_left_len).write(parent_key); + let parent_key = slice_remove(parent_node.key_area_mut(..old_parent_len), parent_idx); + left_node.key_area_mut(old_left_len).write(parent_key); ptr::copy_nonoverlapping( - right_node.key_area_mut_at(..).as_ptr(), - left_node.key_area_mut_at(old_left_len + 1..).as_mut_ptr(), + right_node.key_area_mut(..).as_ptr(), + left_node.key_area_mut(old_left_len + 1..).as_mut_ptr(), right_len, ); - let parent_val = - slice_remove(parent_node.val_area_mut_at(..old_parent_len), parent_idx); - left_node.val_area_mut_at(old_left_len).write(parent_val); + let parent_val = slice_remove(parent_node.val_area_mut(..old_parent_len), parent_idx); + left_node.val_area_mut(old_left_len).write(parent_val); ptr::copy_nonoverlapping( - right_node.val_area_mut_at(..).as_ptr(), - left_node.val_area_mut_at(old_left_len + 1..).as_mut_ptr(), + right_node.val_area_mut(..).as_ptr(), + left_node.val_area_mut(old_left_len + 1..).as_mut_ptr(), right_len, ); - slice_remove(&mut parent_node.edge_area_mut_at(..old_parent_len + 1), parent_idx + 1); + slice_remove(&mut parent_node.edge_area_mut(..old_parent_len + 1), parent_idx + 1); parent_node.correct_childrens_parent_links(parent_idx + 1..old_parent_len); *parent_node.len_mut() -= 1; @@ -1349,8 +1347,8 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { let mut left_node = left_node.reborrow_mut().cast_to_internal_unchecked(); let mut right_node = right_node.cast_to_internal_unchecked(); ptr::copy_nonoverlapping( - right_node.edge_area_mut_at(..).as_ptr(), - left_node.edge_area_mut_at(old_left_len + 1..).as_mut_ptr(), + right_node.edge_area_mut(..).as_ptr(), + left_node.edge_area_mut(old_left_len + 1..).as_mut_ptr(), right_len + 1, ); @@ -1458,7 +1456,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { match (left_node.reborrow_mut().force(), right_node.reborrow_mut().force()) { (ForceResult::Internal(left), ForceResult::Internal(mut right)) => { // Make room for stolen edges. - let right_edges = right.edge_area_mut_at(..).as_mut_ptr(); + let right_edges = right.edge_area_mut(..).as_mut_ptr(); ptr::copy(right_edges, right_edges.add(count), old_right_len + 1); right.correct_childrens_parent_links(count..new_right_len + 1); @@ -1518,7 +1516,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { move_edges(right.reborrow_mut(), 0, left, old_left_len + 1, count); // Fill gap where stolen edges used to be. - let right_edges = right.edge_area_mut_at(..).as_mut_ptr(); + let right_edges = right.edge_area_mut(..).as_mut_ptr(); ptr::copy(right_edges.add(count), right_edges, new_right_len + 1); right.correct_childrens_parent_links(0..=new_right_len); } @@ -1551,8 +1549,8 @@ unsafe fn move_edges<'a, K: 'a, V: 'a>( count: usize, ) { unsafe { - let source_ptr = source.edge_area_mut_at(..).as_ptr(); - let dest_ptr = dest.edge_area_mut_at(dest_offset..).as_mut_ptr(); + let source_ptr = source.edge_area_mut(..).as_ptr(); + let dest_ptr = dest.edge_area_mut(dest_offset..).as_mut_ptr(); ptr::copy_nonoverlapping(source_ptr.add(source_offset), dest_ptr, count); dest.correct_childrens_parent_links(dest_offset..dest_offset + count); } From 142764f79e847fe5d6cc1fdb4b3dce9949648db4 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Sat, 26 Dec 2020 13:22:33 -0800 Subject: [PATCH 04/13] Add links to the source for the rustc and rustdoc books. --- src/doc/rustc/book.toml | 3 +++ src/doc/rustdoc/book.toml | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/doc/rustc/book.toml b/src/doc/rustc/book.toml index 8adc05c513720..21d127c39c904 100644 --- a/src/doc/rustc/book.toml +++ b/src/doc/rustc/book.toml @@ -3,3 +3,6 @@ authors = ["The Rust Project Developers"] multilingual = false src = "src" title = "The rustc book" + +[output.html] +git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustc" diff --git a/src/doc/rustdoc/book.toml b/src/doc/rustdoc/book.toml index ba30c107667ed..c2e7ff589066b 100644 --- a/src/doc/rustdoc/book.toml +++ b/src/doc/rustdoc/book.toml @@ -2,3 +2,6 @@ authors = ["The Rust Project Developers"] src = "src" title = "The rustdoc book" + +[output.html] +git-repository-url = "https://github.com/rust-lang/rust/tree/master/src/doc/rustdoc" From eeed3118d0a10807503346406004aa3e01ae7755 Mon Sep 17 00:00:00 2001 From: CAD97 Date: Sat, 26 Dec 2020 18:16:44 -0500 Subject: [PATCH 05/13] Use raw version of align_of in rc data_offset This was missed in #73845 when switching to use the raw operators. Fixes #80365 --- library/alloc/src/sync.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 9d478a302e96c..38db47cdafbf1 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -14,7 +14,7 @@ use core::hint; use core::intrinsics::abort; use core::iter; use core::marker::{PhantomData, Unpin, Unsize}; -use core::mem::{self, align_of_val, size_of_val}; +use core::mem::{self, align_of_val_raw, size_of_val}; use core::ops::{CoerceUnsized, Deref, DispatchFromDyn, Receiver}; use core::pin::Pin; use core::ptr::{self, NonNull}; @@ -2364,7 +2364,7 @@ unsafe fn data_offset(ptr: *const T) -> isize { // Because it is `?Sized`, it will always be the last field in memory. // Note: This is a detail of the current implementation of the compiler, // and is not a guaranteed language detail. Do not rely on it outside of std. - unsafe { data_offset_align(align_of_val(&*ptr)) } + unsafe { data_offset_align(align_of_val_raw(ptr)) } } #[inline] From 6aea014fbfc1b9bdba22bc3dcd03ab64d9785b63 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sat, 26 Dec 2020 17:55:39 -0800 Subject: [PATCH 06/13] Document `InferTy` & co. --- compiler/rustc_middle/src/ty/sty.rs | 33 ++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 4ce76409c6f19..0631f2c53784e 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1424,28 +1424,33 @@ pub struct EarlyBoundRegion { pub name: Symbol, } +/// A **ty**pe **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] pub struct TyVid { pub index: u32, } +/// A **`const`** **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] pub struct ConstVid<'tcx> { pub index: u32, pub phantom: PhantomData<&'tcx ()>, } +/// An **int**egral (`u32`, `i32`, `usize`, etc.) type **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] pub struct IntVid { pub index: u32, } +/// An **float**ing-point (`f32` or `f64`) type **v**ariable **ID**. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] pub struct FloatVid { pub index: u32, } rustc_index::newtype_index! { + /// A **region** (lifetime) **v**ariable **ID**. pub struct RegionVid { DEBUG_FORMAT = custom, } @@ -1457,18 +1462,40 @@ impl Atom for RegionVid { } } +/// A placeholder for a type that hasn't been inferred yet. +/// +/// E.g., if we have an empty array (`[]`), then we create a fresh +/// type variable for the element type since we won't know until it's +/// used what the element type is supposed to be. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)] #[derive(HashStable)] pub enum InferTy { + /// A type variable. TyVar(TyVid), + /// An integral type variable. + /// + /// These are created when the compiler sees an integer literal like + /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.). + /// We don't know until it's used what type it's supposed to be, so + /// we create a fresh type variable. IntVar(IntVid), + /// A floating-point type variable. + /// + /// These are created when the compiler sees an float literal like + /// `1.0` that could be either an `f32` or an `f64`. + /// We don't know until it's used what type it's supposed to be, so + /// we create a fresh type variable. FloatVar(FloatVid), - /// A `FreshTy` is one that is generated as a replacement for an - /// unbound type variable. This is convenient for caching etc. See - /// `infer::freshen` for more details. + /// A [`FreshTy`][Self::FreshTy] is one that is generated as a replacement + /// for an unbound type variable. This is convenient for caching etc. See + /// `rustc_infer::infer::freshen` for more details. + /// + /// Compare with [`TyVar`][Self::TyVar]. FreshTy(u32), + /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`IntVar`][Self::IntVar]. FreshIntTy(u32), + /// Like [`FreshTy`][Self::FreshTy], but as a replacement for [`FloatVar`][Self::FloatVar]. FreshFloatTy(u32), } From cb177852c1e3521ef203386a67aad2c73e7543ea Mon Sep 17 00:00:00 2001 From: 0xflotus <0xflotus@gmail.com> Date: Sun, 27 Dec 2020 03:22:23 +0100 Subject: [PATCH 07/13] fix: small typo error in chalk/mod.rs --- compiler/rustc_traits/src/chalk/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index f3a55fec9e462..bd2f87f70a2f1 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -98,7 +98,7 @@ crate fn evaluate_goal<'tcx>( let mut solver = chalk_engine::solve::SLGSolver::new(32, None); let db = ChalkRustIrDatabase { interner, reempty_placeholder }; let solution = solver.solve(&db, &lowered_goal); - debug!(?obligation, ?solution, "evaluatate goal"); + debug!(?obligation, ?solution, "evaluate goal"); // Ideally, the code to convert *back* to rustc types would live close to // the code to convert *from* rustc types. Right now though, we don't From f57152f64048754640926a95e6b76b18f28574b1 Mon Sep 17 00:00:00 2001 From: Marco Ieni <11428655+MarcoIeni@users.noreply.github.com> Date: Sun, 27 Dec 2020 14:10:00 +0100 Subject: [PATCH 08/13] rustdoc book: fix example --- src/doc/rustdoc/src/what-is-rustdoc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md index 1f6dced180b96..32dc1e02bb3db 100644 --- a/src/doc/rustdoc/src/what-is-rustdoc.md +++ b/src/doc/rustdoc/src/what-is-rustdoc.md @@ -10,7 +10,7 @@ CSS, and JavaScript. Let's give it a try! Create a new project with Cargo: ```bash -$ cargo new docs +$ cargo new docs --lib $ cd docs ``` From fcc88fab6c1b71a81386046135069203dc553f69 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Sun, 27 Dec 2020 19:28:09 +0100 Subject: [PATCH 09/13] Add regression test for #80375 --- src/test/ui/const-generics/issues/issue-80375.rs | 4 ++++ src/test/ui/const-generics/issues/issue-80375.stderr | 11 +++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/const-generics/issues/issue-80375.rs create mode 100644 src/test/ui/const-generics/issues/issue-80375.stderr diff --git a/src/test/ui/const-generics/issues/issue-80375.rs b/src/test/ui/const-generics/issues/issue-80375.rs new file mode 100644 index 0000000000000..c906bb2c4d9b4 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-80375.rs @@ -0,0 +1,4 @@ +struct MyArray([u8; COUNT + 1]); +//~^ ERROR generic parameters may not be used in const operations + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-80375.stderr b/src/test/ui/const-generics/issues/issue-80375.stderr new file mode 100644 index 0000000000000..9765a639a48d0 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-80375.stderr @@ -0,0 +1,11 @@ +error: generic parameters may not be used in const operations + --> $DIR/issue-80375.rs:1:41 + | +LL | struct MyArray([u8; COUNT + 1]); + | ^^^^^ cannot perform const operation using `COUNT` + | + = help: const parameters may only be used as standalone arguments, i.e. `COUNT` + = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions + +error: aborting due to previous error + From cdad0c80ef93dc64dd9ab8ec2410ec08f60b4120 Mon Sep 17 00:00:00 2001 From: Camelid Date: Sun, 27 Dec 2020 11:05:40 -0800 Subject: [PATCH 10/13] Also show the displayed version of IntVar and FloatVar Co-authored-by: Joshua Nelson --- compiler/rustc_middle/src/ty/sty.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 0631f2c53784e..744c7a541a53c 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1472,14 +1472,14 @@ impl Atom for RegionVid { pub enum InferTy { /// A type variable. TyVar(TyVid), - /// An integral type variable. + /// An integral type variable (`{integer}`). /// /// These are created when the compiler sees an integer literal like /// `1` that could be several different types (`u8`, `i32`, `u32`, etc.). /// We don't know until it's used what type it's supposed to be, so /// we create a fresh type variable. IntVar(IntVid), - /// A floating-point type variable. + /// A floating-point type variable (`{float}`). /// /// These are created when the compiler sees an float literal like /// `1.0` that could be either an `f32` or an `f64`. From 9e779986aa2aaa6d28b48020f9da8f37b95959ee Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 28 Dec 2020 09:13:46 +0100 Subject: [PATCH 11/13] Add "length" as doc alias to len methods --- library/alloc/src/collections/binary_heap.rs | 1 + library/alloc/src/collections/btree/map.rs | 1 + library/alloc/src/collections/btree/set.rs | 1 + library/alloc/src/collections/linked_list.rs | 1 + library/alloc/src/collections/vec_deque/mod.rs | 1 + library/alloc/src/string.rs | 1 + library/alloc/src/vec.rs | 1 + library/core/src/iter/traits/exact_size.rs | 1 + library/core/src/slice/mod.rs | 1 + library/core/src/str/mod.rs | 1 + library/std/src/collections/hash/map.rs | 1 + library/std/src/collections/hash/set.rs | 1 + library/std/src/ffi/os_str.rs | 1 + 13 files changed, 13 insertions(+) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index 97ebc12175f73..76051d9e1dffd 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -915,6 +915,7 @@ impl BinaryHeap { /// /// assert_eq!(heap.len(), 2); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { self.data.len() diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 735213363f60d..944e0e65cf7c1 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2132,6 +2132,7 @@ impl BTreeMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")] pub const fn len(&self) -> usize { diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index f63c3dd580408..c72e305a1f947 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -975,6 +975,7 @@ impl BTreeSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_btree_new", issue = "71835")] pub const fn len(&self) -> usize { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index 4707f12940171..397e774f1a03d 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -593,6 +593,7 @@ impl LinkedList { /// dl.push_back(3); /// assert_eq!(dl.len(), 3); /// ``` + #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 7cf4041f2920f..42a1a08c6fcbc 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1038,6 +1038,7 @@ impl VecDeque { /// v.push_back(1); /// assert_eq!(v.len(), 1); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { count(self.tail, self.head, self.cap()) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 27b32b6950267..9198892859317 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -1388,6 +1388,7 @@ impl String { /// assert_eq!(fancy_f.len(), 4); /// assert_eq!(fancy_f.chars().count(), 3); /// ``` + #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs index 2b08f1f3629b3..c9fa41138cd41 100644 --- a/library/alloc/src/vec.rs +++ b/library/alloc/src/vec.rs @@ -1559,6 +1559,7 @@ impl Vec { /// let a = vec![1, 2, 3]; /// assert_eq!(a.len(), 3); /// ``` + #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/core/src/iter/traits/exact_size.rs b/library/core/src/iter/traits/exact_size.rs index eadbdf45c7c6f..996d62e2b4a42 100644 --- a/library/core/src/iter/traits/exact_size.rs +++ b/library/core/src/iter/traits/exact_size.rs @@ -91,6 +91,7 @@ pub trait ExactSizeIterator: Iterator { /// /// assert_eq!(5, five.len()); /// ``` + #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] fn len(&self) -> usize { diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index f5af48e0dd277..bb1014332a1cf 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -84,6 +84,7 @@ impl [T] { /// let a = [1, 2, 3]; /// assert_eq!(a.len(), 3); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")] #[inline] diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 83cf47c8c8f61..ba495a1a9fbe4 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -138,6 +138,7 @@ impl str { /// assert_eq!("ƒoo".len(), 4); // fancy f! /// assert_eq!("ƒoo".chars().count(), 3); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_str_len", since = "1.32.0")] #[inline] diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 4f24a8bb75a0e..0680b1fc32975 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -448,6 +448,7 @@ impl HashMap { /// a.insert(1, "a"); /// assert_eq!(a.len(), 1); /// ``` + #[doc(alias = "length")] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { self.base.len() diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index 27093c1a077b0..f49e5801c3535 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -199,6 +199,7 @@ impl HashSet { /// v.insert(1); /// assert_eq!(v.len(), 1); /// ``` + #[doc(alias = "length")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn len(&self) -> usize { diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 5d93016cadb37..2eef4d58507c0 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -653,6 +653,7 @@ impl OsStr { /// let os_str = OsStr::new("foo"); /// assert_eq!(os_str.len(), 3); /// ``` + #[doc(alias = "length")] #[stable(feature = "osstring_simple_functions", since = "1.9.0")] pub fn len(&self) -> usize { self.inner.inner.len() From b3be9e10926f75740f0a5d126e8c8532d2c76ed2 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Mon, 28 Dec 2020 09:29:42 +0100 Subject: [PATCH 12/13] Add "chr" as doc alias to char::from_u32 --- library/core/src/char/convert.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index 394db5b5917f0..de05a8c82e8f6 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -47,6 +47,7 @@ use super::MAX; /// /// assert_eq!(None, c); /// ``` +#[doc(alias = "chr")] #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn from_u32(i: u32) -> Option { From 10d6ff71e83e370d345ef43f6aaef8196727f22f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 28 Dec 2020 20:04:27 +0100 Subject: [PATCH 13/13] Fix stabilization version of deque_range feature. --- library/alloc/src/collections/vec_deque/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 7cf4041f2920f..c27ac498472f9 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -1091,7 +1091,7 @@ impl VecDeque { /// assert_eq!(all.len(), 3); /// ``` #[inline] - #[stable(feature = "deque_range", since = "1.50.0")] + #[stable(feature = "deque_range", since = "1.51.0")] pub fn range(&self, range: R) -> Iter<'_, T> where R: RangeBounds, @@ -1130,7 +1130,7 @@ impl VecDeque { /// assert_eq!(v, vec![2, 4, 12]); /// ``` #[inline] - #[stable(feature = "deque_range", since = "1.50.0")] + #[stable(feature = "deque_range", since = "1.51.0")] pub fn range_mut(&mut self, range: R) -> IterMut<'_, T> where R: RangeBounds,