Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit f2a0588

Browse files
committed
Auto merge of rust-lang#126793 - saethlin:mono-rawvec, r=<try>
Apply "polymorphization at home" to RawVec The idea here is to move all the logic in RawVec into functions with explicit size and alignment parameters. This should eliminate all the fussing about how tweaking RawVec code produces large swings in compile times. This uncovered rust-lang/rust-clippy#12979, so I've modified the relevant test in a way that tries to preserve the spirit of the test without tripping the ICE.
2 parents f8e4ac0 + 7c7067f commit f2a0588

File tree

9 files changed

+443
-294
lines changed

9 files changed

+443
-294
lines changed

library/alloc/src/raw_vec.rs

Lines changed: 343 additions & 202 deletions
Large diffs are not rendered by default.

library/alloc/src/raw_vec/tests.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ fn allocator_param() {
4242

4343
let a = BoundedAlloc { fuel: Cell::new(500) };
4444
let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
45-
assert_eq!(v.alloc.fuel.get(), 450);
45+
assert_eq!(v.inner.alloc.fuel.get(), 450);
4646
v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
47-
assert_eq!(v.alloc.fuel.get(), 250);
47+
assert_eq!(v.inner.alloc.fuel.get(), 250);
4848
}
4949

5050
#[test]
@@ -85,7 +85,7 @@ struct ZST;
8585
fn zst_sanity<T>(v: &RawVec<T>) {
8686
assert_eq!(v.capacity(), usize::MAX);
8787
assert_eq!(v.ptr(), core::ptr::Unique::<T>::dangling().as_ptr());
88-
assert_eq!(v.current_memory(), None);
88+
assert_eq!(v.inner.current_memory(T::LAYOUT), None);
8989
}
9090

9191
#[test]
@@ -105,22 +105,11 @@ fn zst() {
105105
let v: RawVec<ZST> = RawVec::with_capacity_in(100, Global);
106106
zst_sanity(&v);
107107

108-
let v: RawVec<ZST> = RawVec::try_allocate_in(0, AllocInit::Uninitialized, Global).unwrap();
109-
zst_sanity(&v);
110-
111-
let v: RawVec<ZST> = RawVec::try_allocate_in(100, AllocInit::Uninitialized, Global).unwrap();
112-
zst_sanity(&v);
113-
114-
let mut v: RawVec<ZST> =
115-
RawVec::try_allocate_in(usize::MAX, AllocInit::Uninitialized, Global).unwrap();
108+
let mut v: RawVec<ZST> = RawVec::with_capacity_in(usize::MAX, Global);
116109
zst_sanity(&v);
117110

118111
// Check all these operations work as expected with zero-sized elements.
119112

120-
assert!(!v.needs_to_grow(100, usize::MAX - 100));
121-
assert!(v.needs_to_grow(101, usize::MAX - 100));
122-
zst_sanity(&v);
123-
124113
v.reserve(100, usize::MAX - 100);
125114
//v.reserve(101, usize::MAX - 100); // panics, in `zst_reserve_panic` below
126115
zst_sanity(&v);
@@ -137,12 +126,12 @@ fn zst() {
137126
assert_eq!(v.try_reserve_exact(101, usize::MAX - 100), cap_err);
138127
zst_sanity(&v);
139128

140-
assert_eq!(v.grow_amortized(100, usize::MAX - 100), cap_err);
141-
assert_eq!(v.grow_amortized(101, usize::MAX - 100), cap_err);
129+
assert_eq!(v.inner.grow_amortized(100, usize::MAX - 100, ZST::LAYOUT), cap_err);
130+
assert_eq!(v.inner.grow_amortized(101, usize::MAX - 100, ZST::LAYOUT), cap_err);
142131
zst_sanity(&v);
143132

144-
assert_eq!(v.grow_exact(100, usize::MAX - 100), cap_err);
145-
assert_eq!(v.grow_exact(101, usize::MAX - 100), cap_err);
133+
assert_eq!(v.inner.grow_exact(100, usize::MAX - 100, ZST::LAYOUT), cap_err);
134+
assert_eq!(v.inner.grow_exact(101, usize::MAX - 100, ZST::LAYOUT), cap_err);
146135
zst_sanity(&v);
147136
}
148137

library/core/src/mem/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
#![stable(feature = "rust1", since = "1.0.0")]
77

8+
use crate::alloc::Layout;
89
use crate::clone;
910
use crate::cmp;
1011
use crate::fmt;
@@ -1235,6 +1236,10 @@ pub trait SizedTypeProperties: Sized {
12351236
#[doc(hidden)]
12361237
#[unstable(feature = "sized_type_properties", issue = "none")]
12371238
const IS_ZST: bool = size_of::<Self>() == 0;
1239+
1240+
#[doc(hidden)]
1241+
#[unstable(feature = "sized_type_properties", issue = "none")]
1242+
const LAYOUT: Layout = Layout::new::<Self>();
12381243
}
12391244
#[doc(hidden)]
12401245
#[unstable(feature = "sized_type_properties", issue = "none")]

src/etc/gdb_providers.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def __init__(self, valobj):
5656
self._valobj = valobj
5757
vec = valobj["vec"]
5858
self._length = int(vec["len"])
59-
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
59+
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])
6060

6161
def to_string(self):
6262
return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
@@ -74,7 +74,7 @@ def __init__(self, valobj):
7474
vec = buf[ZERO_FIELD] if is_windows else buf
7575

7676
self._length = int(vec["len"])
77-
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["ptr"])
77+
self._data_ptr = unwrap_unique_or_non_null(vec["buf"]["inner"]["ptr"])
7878

7979
def to_string(self):
8080
return self._data_ptr.lazy_string(encoding="utf-8", length=self._length)
@@ -96,6 +96,7 @@ def to_string(self):
9696
def display_hint():
9797
return "string"
9898

99+
99100
def _enumerate_array_elements(element_ptrs):
100101
for (i, element_ptr) in enumerate(element_ptrs):
101102
key = "[{}]".format(i)
@@ -112,6 +113,7 @@ def _enumerate_array_elements(element_ptrs):
112113

113114
yield key, element
114115

116+
115117
class StdSliceProvider(printer_base):
116118
def __init__(self, valobj):
117119
self._valobj = valobj
@@ -130,11 +132,14 @@ def children(self):
130132
def display_hint():
131133
return "array"
132134

135+
133136
class StdVecProvider(printer_base):
134137
def __init__(self, valobj):
135138
self._valobj = valobj
136139
self._length = int(valobj["len"])
137-
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
140+
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
141+
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
142+
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
138143

139144
def to_string(self):
140145
return "Vec(size={})".format(self._length)
@@ -155,11 +160,13 @@ def __init__(self, valobj):
155160
self._head = int(valobj["head"])
156161
self._size = int(valobj["len"])
157162
# BACKCOMPAT: rust 1.75
158-
cap = valobj["buf"]["cap"]
163+
cap = valobj["buf"]["inner"]["cap"]
159164
if cap.type.code != gdb.TYPE_CODE_INT:
160165
cap = cap[ZERO_FIELD]
161166
self._cap = int(cap)
162-
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["ptr"])
167+
self._data_ptr = unwrap_unique_or_non_null(valobj["buf"]["inner"]["ptr"])
168+
ptr_ty = gdb.Type.pointer(valobj.type.template_argument(0))
169+
self._data_ptr = self._data_ptr.reinterpret_cast(ptr_ty)
163170

164171
def to_string(self):
165172
return "VecDeque(size={})".format(self._size)

src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::sync::Once;
1010

1111
const ATOMIC: AtomicUsize = AtomicUsize::new(5);
1212
const CELL: Cell<usize> = Cell::new(6);
13-
const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
13+
const ATOMIC_TUPLE: ([AtomicUsize; 1], Option<Box<AtomicUsize>>, u8) = ([ATOMIC], None, 7);
1414
const INTEGER: u8 = 8;
1515
const STRING: String = String::new();
1616
const STR: &str = "012345";
@@ -74,7 +74,6 @@ fn main() {
7474
let _ = &(&&&&ATOMIC_TUPLE).0; //~ ERROR: interior mutability
7575
let _ = &ATOMIC_TUPLE.0[0]; //~ ERROR: interior mutability
7676
let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst); //~ ERROR: interior mutability
77-
let _ = &*ATOMIC_TUPLE.1;
7877
let _ = &ATOMIC_TUPLE.2;
7978
let _ = (&&&&ATOMIC_TUPLE).0;
8079
let _ = (&&&&ATOMIC_TUPLE).2;

src/tools/clippy/tests/ui/borrow_interior_mutable_const/others.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,23 @@ LL | let _ = ATOMIC_TUPLE.0[0].load(Ordering::SeqCst);
9292
= help: assign this const to a local or static variable, and use the variable here
9393

9494
error: a `const` item with interior mutability should not be borrowed
95-
--> tests/ui/borrow_interior_mutable_const/others.rs:82:13
95+
--> tests/ui/borrow_interior_mutable_const/others.rs:81:13
9696
|
9797
LL | let _ = ATOMIC_TUPLE.0[0];
9898
| ^^^^^^^^^^^^
9999
|
100100
= help: assign this const to a local or static variable, and use the variable here
101101

102102
error: a `const` item with interior mutability should not be borrowed
103-
--> tests/ui/borrow_interior_mutable_const/others.rs:87:5
103+
--> tests/ui/borrow_interior_mutable_const/others.rs:86:5
104104
|
105105
LL | CELL.set(2);
106106
| ^^^^
107107
|
108108
= help: assign this const to a local or static variable, and use the variable here
109109

110110
error: a `const` item with interior mutability should not be borrowed
111-
--> tests/ui/borrow_interior_mutable_const/others.rs:88:16
111+
--> tests/ui/borrow_interior_mutable_const/others.rs:87:16
112112
|
113113
LL | assert_eq!(CELL.get(), 6);
114114
| ^^^^

tests/debuginfo/strings-and-strs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// gdb-command:run
88

99
// gdb-command:print plain_string
10-
// gdbr-check:$1 = alloc::string::String {vec: alloc::vec::Vec<u8, alloc::alloc::Global> {buf: alloc::raw_vec::RawVec<u8, alloc::alloc::Global> {ptr: core::ptr::unique::Unique<u8> {pointer: core::ptr::non_null::NonNull<u8> {pointer: 0x[...]}, _marker: core::marker::PhantomData<u8>}, cap: alloc::raw_vec::Cap (5), alloc: alloc::alloc::Global}, len: 5}}
10+
// gdbr-check:$1 = alloc::string::String {vec: alloc::vec::Vec<u8, alloc::alloc::Global> {buf: alloc::raw_vec::RawVec<u8, alloc::alloc::Global> {inner: alloc::raw_vec::RawVecInner<alloc::alloc::Global> {ptr: core::ptr::unique::Unique<u8> {pointer: core::ptr::non_null::NonNull<u8> {pointer: 0x[...]}, _marker: core::marker::PhantomData<u8>}, cap: alloc::raw_vec::Cap (5), alloc: alloc::alloc::Global}, _marker: core::marker::PhantomData<u8>}, len: 5}}
1111

1212
// gdb-command:print plain_str
1313
// gdbr-check:$2 = "Hello"

tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,65 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
55
let mut _0: &[u8];
66
scope 1 (inlined <Vec<u8> as Deref>::deref) {
77
debug self => _1;
8-
let mut _4: *const u8;
9-
let mut _5: usize;
8+
let mut _6: *const u8;
9+
let mut _7: usize;
1010
scope 2 (inlined Vec::<u8>::as_ptr) {
1111
debug self => _1;
1212
let mut _2: &alloc::raw_vec::RawVec<u8>;
13+
let mut _5: *mut u8;
1314
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
1415
debug self => _2;
15-
let mut _3: std::ptr::NonNull<u8>;
16-
scope 4 (inlined Unique::<u8>::as_ptr) {
17-
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
18-
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
19-
scope 5 (inlined NonNull::<u8>::as_ptr) {
20-
debug self => _3;
21-
}
16+
let mut _3: &alloc::raw_vec::RawVecInner;
17+
scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
18+
debug self => _3;
19+
let mut _4: std::ptr::Unique<u8>;
2220
}
2321
}
2422
}
25-
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
26-
debug data => _4;
27-
debug len => _5;
28-
let _6: *const [u8];
29-
scope 7 (inlined core::ub_checks::check_language_ub) {
30-
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
23+
scope 5 (inlined std::slice::from_raw_parts::<'_, u8>) {
24+
debug data => _6;
25+
debug len => _7;
26+
let _8: *const [u8];
27+
scope 6 (inlined core::ub_checks::check_language_ub) {
28+
scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
3129
}
3230
}
33-
scope 9 (inlined std::mem::size_of::<u8>) {
31+
scope 8 (inlined std::mem::size_of::<u8>) {
3432
}
35-
scope 10 (inlined align_of::<u8>) {
33+
scope 9 (inlined align_of::<u8>) {
3634
}
37-
scope 11 (inlined slice_from_raw_parts::<u8>) {
38-
debug data => _4;
39-
debug len => _5;
40-
scope 12 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
41-
debug data_pointer => _4;
42-
debug metadata => _5;
35+
scope 10 (inlined slice_from_raw_parts::<u8>) {
36+
debug data => _6;
37+
debug len => _7;
38+
scope 11 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
39+
debug data_pointer => _6;
40+
debug metadata => _7;
4341
}
4442
}
4543
}
4644
}
4745

4846
bb0: {
49-
StorageLive(_4);
47+
StorageLive(_5);
48+
StorageLive(_6);
5049
StorageLive(_2);
5150
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
5251
StorageLive(_3);
53-
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
54-
_4 = (_3.0: *const u8);
52+
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
53+
StorageLive(_4);
54+
_4 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>);
55+
_5 = move _4 as *mut u8 (Transmute);
56+
StorageDead(_4);
5557
StorageDead(_3);
58+
_6 = _5 as *const u8 (PtrToPtr);
5659
StorageDead(_2);
57-
StorageLive(_5);
58-
_5 = ((*_1).1: usize);
59-
_6 = *const [u8] from (_4, _5);
60+
StorageLive(_7);
61+
_7 = ((*_1).1: usize);
62+
_8 = *const [u8] from (_6, _7);
63+
StorageDead(_7);
64+
StorageDead(_6);
6065
StorageDead(_5);
61-
StorageDead(_4);
62-
_0 = &(*_6);
66+
_0 = &(*_8);
6367
return;
6468
}
6569
}

tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir

Lines changed: 35 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,65 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
55
let mut _0: &[u8];
66
scope 1 (inlined <Vec<u8> as Deref>::deref) {
77
debug self => _1;
8-
let mut _4: *const u8;
9-
let mut _5: usize;
8+
let mut _6: *const u8;
9+
let mut _7: usize;
1010
scope 2 (inlined Vec::<u8>::as_ptr) {
1111
debug self => _1;
1212
let mut _2: &alloc::raw_vec::RawVec<u8>;
13+
let mut _5: *mut u8;
1314
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
1415
debug self => _2;
15-
let mut _3: std::ptr::NonNull<u8>;
16-
scope 4 (inlined Unique::<u8>::as_ptr) {
17-
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
18-
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
19-
scope 5 (inlined NonNull::<u8>::as_ptr) {
20-
debug self => _3;
21-
}
16+
let mut _3: &alloc::raw_vec::RawVecInner;
17+
scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
18+
debug self => _3;
19+
let mut _4: std::ptr::Unique<u8>;
2220
}
2321
}
2422
}
25-
scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
26-
debug data => _4;
27-
debug len => _5;
28-
let _6: *const [u8];
29-
scope 7 (inlined core::ub_checks::check_language_ub) {
30-
scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
23+
scope 5 (inlined std::slice::from_raw_parts::<'_, u8>) {
24+
debug data => _6;
25+
debug len => _7;
26+
let _8: *const [u8];
27+
scope 6 (inlined core::ub_checks::check_language_ub) {
28+
scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
3129
}
3230
}
33-
scope 9 (inlined std::mem::size_of::<u8>) {
31+
scope 8 (inlined std::mem::size_of::<u8>) {
3432
}
35-
scope 10 (inlined align_of::<u8>) {
33+
scope 9 (inlined align_of::<u8>) {
3634
}
37-
scope 11 (inlined slice_from_raw_parts::<u8>) {
38-
debug data => _4;
39-
debug len => _5;
40-
scope 12 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
41-
debug data_pointer => _4;
42-
debug metadata => _5;
35+
scope 10 (inlined slice_from_raw_parts::<u8>) {
36+
debug data => _6;
37+
debug len => _7;
38+
scope 11 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
39+
debug data_pointer => _6;
40+
debug metadata => _7;
4341
}
4442
}
4543
}
4644
}
4745

4846
bb0: {
49-
StorageLive(_4);
47+
StorageLive(_5);
48+
StorageLive(_6);
5049
StorageLive(_2);
5150
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
5251
StorageLive(_3);
53-
_3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
54-
_4 = (_3.0: *const u8);
52+
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
53+
StorageLive(_4);
54+
_4 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>);
55+
_5 = move _4 as *mut u8 (Transmute);
56+
StorageDead(_4);
5557
StorageDead(_3);
58+
_6 = _5 as *const u8 (PtrToPtr);
5659
StorageDead(_2);
57-
StorageLive(_5);
58-
_5 = ((*_1).1: usize);
59-
_6 = *const [u8] from (_4, _5);
60+
StorageLive(_7);
61+
_7 = ((*_1).1: usize);
62+
_8 = *const [u8] from (_6, _7);
63+
StorageDead(_7);
64+
StorageDead(_6);
6065
StorageDead(_5);
61-
StorageDead(_4);
62-
_0 = &(*_6);
66+
_0 = &(*_8);
6367
return;
6468
}
6569
}

0 commit comments

Comments
 (0)