Skip to content

Commit 13f8a57

Browse files
committed
Auto merge of #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 41dd149 + 28a8301 commit 13f8a57

File tree

15 files changed

+559
-312
lines changed

15 files changed

+559
-312
lines changed

Diff for: library/alloc/src/raw_vec.rs

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

Diff for: 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

Diff for: 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")]

Diff for: 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)

Diff for: src/etc/lldb_providers.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -389,11 +389,11 @@ def get_child_at_index(self, index):
389389
def update(self):
390390
# type: () -> None
391391
self.length = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
392-
self.buf = self.valobj.GetChildMemberWithName("buf")
392+
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName("inner")
393393

394394
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
395395

396-
self.element_type = self.data_ptr.GetType().GetPointeeType()
396+
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
397397
self.element_type_size = self.element_type.GetByteSize()
398398

399399
def has_children(self):
@@ -474,15 +474,15 @@ def update(self):
474474
# type: () -> None
475475
self.head = self.valobj.GetChildMemberWithName("head").GetValueAsUnsigned()
476476
self.size = self.valobj.GetChildMemberWithName("len").GetValueAsUnsigned()
477-
self.buf = self.valobj.GetChildMemberWithName("buf")
477+
self.buf = self.valobj.GetChildMemberWithName("buf").GetChildMemberWithName("inner")
478478
cap = self.buf.GetChildMemberWithName("cap")
479479
if cap.GetType().num_fields == 1:
480480
cap = cap.GetChildAtIndex(0)
481481
self.cap = cap.GetValueAsUnsigned()
482482

483483
self.data_ptr = unwrap_unique_or_non_null(self.buf.GetChildMemberWithName("ptr"))
484484

485-
self.element_type = self.data_ptr.GetType().GetPointeeType()
485+
self.element_type = self.valobj.GetType().GetTemplateArgumentType(0)
486486
self.element_type_size = self.element_type.GetByteSize()
487487

488488
def has_children(self):

Diff for: src/etc/natvis/liballoc.natvis

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,26 @@
44
<DisplayString>{{ len={len} }}</DisplayString>
55
<Expand>
66
<Item Name="[len]" ExcludeView="simple">len</Item>
7-
<Item Name="[capacity]" ExcludeView="simple">buf.cap.__0</Item>
7+
<Item Name="[capacity]" ExcludeView="simple">buf.inner.cap.__0</Item>
88
<ArrayItems>
99
<Size>len</Size>
10-
<ValuePointer>buf.ptr.pointer.pointer</ValuePointer>
10+
<ValuePointer>($T1*)buf.inner.ptr.pointer.pointer</ValuePointer>
1111
</ArrayItems>
1212
</Expand>
1313
</Type>
1414
<Type Name="alloc::collections::vec_deque::VecDeque&lt;*&gt;">
1515
<DisplayString>{{ len={len} }}</DisplayString>
1616
<Expand>
1717
<Item Name="[len]" ExcludeView="simple">len</Item>
18-
<Item Name="[capacity]" ExcludeView="simple">buf.cap.__0</Item>
18+
<Item Name="[capacity]" ExcludeView="simple">buf.inner.cap.__0</Item>
1919
<CustomListItems>
2020
<Variable Name="i" InitialValue="0" />
2121
<Size>len</Size>
2222
<Loop>
2323
<If Condition="i == len">
2424
<Break/>
2525
</If>
26-
<Item>buf.ptr.pointer.pointer[(i + head) % buf.cap.__0]</Item>
26+
<Item>(($T1*)buf.inner.ptr.pointer.pointer)[(i + head) % buf.inner.cap.__0]</Item>
2727
<Exec>i = i + 1</Exec>
2828
</Loop>
2929
</CustomListItems>
@@ -41,17 +41,17 @@
4141
</Expand>
4242
</Type>
4343
<Type Name="alloc::string::String">
44-
<DisplayString>{(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
45-
<StringView>(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8</StringView>
44+
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
45+
<StringView>(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8</StringView>
4646
<Expand>
4747
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
48-
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap.__0</Item>
48+
<Item Name="[capacity]" ExcludeView="simple">vec.buf.inner.cap.__0</Item>
4949
<Synthetic Name="[chars]">
50-
<DisplayString>{(char*)vec.buf.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
50+
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
5151
<Expand>
5252
<ArrayItems>
5353
<Size>vec.len</Size>
54-
<ValuePointer>(char*)vec.buf.ptr.pointer.pointer</ValuePointer>
54+
<ValuePointer>(char*)vec.buf.inner.ptr.pointer.pointer</ValuePointer>
5555
</ArrayItems>
5656
</Expand>
5757
</Synthetic>

Diff for: src/etc/natvis/libstd.natvis

+3-3
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,14 @@
104104
</Type>
105105

106106
<Type Name="std::ffi::os_str::OsString">
107-
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
107+
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
108108
<Expand>
109109
<Synthetic Name="[chars]">
110-
<DisplayString>{(char*)inner.inner.bytes.buf.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
110+
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
111111
<Expand>
112112
<ArrayItems>
113113
<Size>inner.inner.bytes.len</Size>
114-
<ValuePointer>(char*)inner.inner.bytes.buf.ptr.pointer.pointer</ValuePointer>
114+
<ValuePointer>(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer</ValuePointer>
115115
</ArrayItems>
116116
</Expand>
117117
</Synthetic>

Diff for: 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;

Diff for: 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
| ^^^^

Diff for: 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

Diff for: 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
──────────────────────────────────────────────────

Diff for: tests/debuginfo/pretty-std.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@
8181
// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64,alloc::alloc::Global>]
8282
// cdb-check: [len] : 4 [Type: [...]]
8383
// cdb-check: [capacity] : [...] [Type: [...]]
84-
// cdb-check: [0] : 4 [Type: unsigned __int64]
85-
// cdb-check: [1] : 5 [Type: unsigned __int64]
86-
// cdb-check: [2] : 6 [Type: unsigned __int64]
87-
// cdb-check: [3] : 7 [Type: unsigned __int64]
84+
// cdb-check: [0] : 4 [Type: u64]
85+
// cdb-check: [1] : 5 [Type: u64]
86+
// cdb-check: [2] : 6 [Type: u64]
87+
// cdb-check: [3] : 7 [Type: u64]
8888

8989
// cdb-command: dx str_slice
9090
// cdb-check:str_slice : "IAMA string slice!" [Type: ref$<str$>]
@@ -141,8 +141,8 @@
141141
// cdb-check: [<Raw View>] [Type: alloc::collections::vec_deque::VecDeque<i32,alloc::alloc::Global>]
142142
// cdb-check: [len] : 0x2 [Type: unsigned [...]]
143143
// cdb-check: [capacity] : 0x8 [Type: unsigned [...]]
144-
// cdb-check: [0x0] : 90 [Type: int]
145-
// cdb-check: [0x1] : 20 [Type: int]
144+
// cdb-check: [0x0] : 90 [Type: i32]
145+
// cdb-check: [0x1] : 20 [Type: i32]
146146

147147
#![allow(unused_variables)]
148148
use std::collections::{LinkedList, VecDeque};

Diff for: 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"

0 commit comments

Comments
 (0)