Skip to content

Commit 191a318

Browse files
committed
Auto merge of rust-lang#126793 - saethlin:mono-rawvec, r=scottmcm
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 fac7753 + 295001d commit 191a318

File tree

11 files changed

+537
-290
lines changed

11 files changed

+537
-290
lines changed

library/alloc/src/raw_vec.rs

+376-193
Large diffs are not rendered by default.

library/alloc/src/raw_vec/tests.rs

+8-19
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ fn allocator_param() {
4343

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

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

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

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

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

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

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

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

library/core/src/mem/mod.rs

+5
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::marker::DiscriminantKind;
910
use crate::{clone, cmp, fmt, hash, intrinsics, ptr};
1011

@@ -1238,6 +1239,10 @@ pub trait SizedTypeProperties: Sized {
12381239
#[doc(hidden)]
12391240
#[unstable(feature = "sized_type_properties", issue = "none")]
12401241
const IS_ZST: bool = size_of::<Self>() == 0;
1242+
1243+
#[doc(hidden)]
1244+
#[unstable(feature = "sized_type_properties", issue = "none")]
1245+
const LAYOUT: Layout = Layout::new::<Self>();
12411246
}
12421247
#[doc(hidden)]
12431248
#[unstable(feature = "sized_type_properties", issue = "none")]

src/etc/gdb_providers.py

+12-5
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

+1-2
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

+3-3
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
| ^^^^

src/tools/miri/tests/pass/tree_borrows/vec_unique.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// FIXME: This test is broken since https://github.com/rust-lang/rust/pull/126793,
2+
// possibly related to the additional struct between Vec and Unique.
13
//@revisions: default uniq
24
// We disable the GC for this test because it would change what is printed.
35
//@compile-flags: -Zmiri-tree-borrows -Zmiri-provenance-gc=0

src/tools/miri/tests/pass/tree_borrows/vec_unique.uniq.stderr

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
Warning: this tree is indicative only. Some tags may have been hidden.
33
0.. 2
44
| Act | └─┬──<TAG=root of the allocation>
5-
|-----| └─┬──<TAG=base.as_ptr(), base.as_ptr()>
6-
|-----| └─┬──<TAG=raw_parts.0>
7-
|-----| └────<TAG=reconstructed.as_ptr(), reconstructed.as_ptr()>
5+
|-----| ├────<TAG=base.as_ptr()>
6+
|-----| ├────<TAG=base.as_ptr()>
7+
|-----| └─┬──<TAG=raw_parts.0>
8+
|-----| ├────<TAG=reconstructed.as_ptr()>
9+
|-----| └────<TAG=reconstructed.as_ptr()>
810
──────────────────────────────────────────────────

tests/debuginfo/strings-and-strs.rs

+1-1
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

+62-32
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,93 @@ 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 _7: usize;
109
scope 2 (inlined Vec::<u8>::as_ptr) {
1110
debug self => _1;
1211
let mut _2: &alloc::raw_vec::RawVec<u8>;
1312
scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
1413
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) {
14+
let mut _3: &alloc::raw_vec::RawVecInner;
15+
scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
16+
debug self => _3;
17+
let mut _6: std::ptr::NonNull<u8>;
18+
scope 5 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
2019
debug self => _3;
20+
let mut _4: std::ptr::NonNull<u8>;
21+
scope 6 (inlined Unique::<u8>::cast::<u8>) {
22+
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
23+
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
24+
scope 7 (inlined NonNull::<u8>::cast::<u8>) {
25+
debug self => _4;
26+
scope 8 (inlined NonNull::<u8>::as_ptr) {
27+
debug self => _4;
28+
let mut _5: *const u8;
29+
}
30+
}
31+
}
32+
scope 9 (inlined #[track_caller] <Unique<u8> as Into<NonNull<u8>>>::into) {
33+
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
34+
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
35+
scope 10 (inlined <NonNull<u8> as From<Unique<u8>>>::from) {
36+
debug ((unique: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
37+
debug ((unique: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
38+
scope 11 (inlined Unique::<u8>::as_non_null_ptr) {
39+
debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
40+
debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
41+
}
42+
}
43+
}
44+
}
45+
scope 12 (inlined NonNull::<u8>::as_ptr) {
46+
debug self => _6;
2147
}
2248
}
2349
}
2450
}
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) {
51+
scope 13 (inlined std::slice::from_raw_parts::<'_, u8>) {
52+
debug data => _5;
53+
debug len => _7;
54+
let _8: *const [u8];
55+
scope 14 (inlined core::ub_checks::check_language_ub) {
56+
scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
3157
}
3258
}
33-
scope 9 (inlined std::mem::size_of::<u8>) {
59+
scope 16 (inlined std::mem::size_of::<u8>) {
3460
}
35-
scope 10 (inlined align_of::<u8>) {
61+
scope 17 (inlined align_of::<u8>) {
3662
}
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;
63+
scope 18 (inlined slice_from_raw_parts::<u8>) {
64+
debug data => _5;
65+
debug len => _7;
66+
scope 19 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
67+
debug data_pointer => _5;
68+
debug metadata => _7;
4369
}
4470
}
4571
}
4672
}
4773

4874
bb0: {
49-
StorageLive(_4);
5075
StorageLive(_2);
5176
_2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
5277
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);
55-
StorageDead(_3);
56-
StorageDead(_2);
57-
StorageLive(_5);
58-
_5 = ((*_1).1: usize);
78+
_3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
5979
StorageLive(_6);
60-
_6 = *const [u8] from (_4, _5);
61-
_0 = &(*_6);
62-
StorageDead(_6);
63-
StorageDead(_5);
80+
StorageLive(_4);
81+
_4 = (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
82+
_5 = (_4.0: *const u8);
83+
_6 = NonNull::<u8> { pointer: _5 };
6484
StorageDead(_4);
85+
StorageDead(_6);
86+
StorageDead(_3);
87+
StorageDead(_2);
88+
StorageLive(_7);
89+
_7 = ((*_1).1: usize);
90+
StorageLive(_8);
91+
_8 = *const [u8] from (_5, _7);
92+
_0 = &(*_8);
93+
StorageDead(_8);
94+
StorageDead(_7);
6595
return;
6696
}
6797
}

0 commit comments

Comments
 (0)