Skip to content

Commit 3f50dea

Browse files
committed
Auto merge of rust-lang#78033 - Dylan-DPC:rollup-ds2cfsf, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#76199 (Permit uninhabited enums to cast into ints) - rust-lang#77751 (liballoc: VecDeque: Add binary search functions) - rust-lang#77785 (Remove compiler-synthesized reexports when documenting) - rust-lang#77932 (BTreeMap: improve gdb introspection of BTreeMap with ZST keys or values) - rust-lang#77961 (Set .llvmbc and .llvmcmd sections as allocatable) - rust-lang#77985 (llvm: backport SystemZ fix for AGR clobbers) Failed merges: r? `@ghost`
2 parents f1b97ee + b9c45d1 commit 3f50dea

File tree

14 files changed

+238
-38
lines changed

14 files changed

+238
-38
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -936,8 +936,8 @@ unsafe fn embed_bitcode(
936936
llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
937937
} else {
938938
let asm = "
939-
.section .llvmbc,\"e\"
940-
.section .llvmcmd,\"e\"
939+
.section .llvmbc,\"a\"
940+
.section .llvmcmd,\"a\"
941941
";
942942
llvm::LLVMRustAppendModuleInlineAsm(llmod, asm.as_ptr().cast(), asm.len());
943943
}

compiler/rustc_middle/src/ty/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,10 @@ impl<'tcx> AdtDef {
24362436
self.variants.iter().flat_map(|v| v.fields.iter())
24372437
}
24382438

2439+
/// Whether the ADT lacks fields. Note that this includes uninhabited enums,
2440+
/// e.g., `enum Void {}` is considered payload free as well.
24392441
pub fn is_payloadfree(&self) -> bool {
2440-
!self.variants.is_empty() && self.variants.iter().all(|v| v.fields.is_empty())
2442+
self.variants.iter().all(|v| v.fields.is_empty())
24412443
}
24422444

24432445
/// Return a `VariantDef` given a variant id.

compiler/rustc_mir/src/interpret/cast.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,14 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
139139

140140
// # First handle non-scalar source values.
141141

142-
// Handle cast from a univariant (ZST) enum.
142+
// Handle cast from a ZST enum (0 or 1 variants).
143143
match src.layout.variants {
144144
Variants::Single { index } => {
145+
if src.layout.abi.is_uninhabited() {
146+
// This is dead code, because an uninhabited enum is UB to
147+
// instantiate.
148+
throw_ub!(Unreachable);
149+
}
145150
if let Some(discr) = src.layout.ty.discriminant_for_variant(*self.tcx, index) {
146151
assert!(src.layout.is_zst());
147152
let discr_layout = self.layout_of(discr.ty)?;

library/alloc/src/collections/btree/node.rs

-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ impl<K, V> LeafNode<K, V> {
8787
#[repr(C)]
8888
// gdb_providers.py uses this type name for introspection.
8989
struct InternalNode<K, V> {
90-
// gdb_providers.py uses this field name for introspection.
9190
data: LeafNode<K, V>,
9291

9392
/// The pointers to the children of this node. `len + 1` of these are considered

library/alloc/src/collections/vec_deque.rs

+138-1
Original file line numberDiff line numberDiff line change
@@ -2181,7 +2181,7 @@ impl<T> VecDeque<T> {
21812181
///
21822182
/// This method does not allocate and does not change the order of the
21832183
/// inserted elements. As it returns a mutable slice, this can be used to
2184-
/// sort or binary search a deque.
2184+
/// sort a deque.
21852185
///
21862186
/// Once the internal storage is contiguous, the [`as_slices`] and
21872187
/// [`as_mut_slices`] methods will return the entire contents of the
@@ -2430,6 +2430,143 @@ impl<T> VecDeque<T> {
24302430
self.wrap_copy(self.tail, self.head, k);
24312431
}
24322432
}
2433+
2434+
/// Binary searches this sorted `VecDeque` for a given element.
2435+
///
2436+
/// If the value is found then [`Result::Ok`] is returned, containing the
2437+
/// index of the matching element. If there are multiple matches, then any
2438+
/// one of the matches could be returned. If the value is not found then
2439+
/// [`Result::Err`] is returned, containing the index where a matching
2440+
/// element could be inserted while maintaining sorted order.
2441+
///
2442+
/// # Examples
2443+
///
2444+
/// Looks up a series of four elements. The first is found, with a
2445+
/// uniquely determined position; the second and third are not
2446+
/// found; the fourth could match any position in `[1, 4]`.
2447+
///
2448+
/// ```
2449+
/// #![feature(vecdeque_binary_search)]
2450+
/// use std::collections::VecDeque;
2451+
///
2452+
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
2453+
///
2454+
/// assert_eq!(deque.binary_search(&13), Ok(9));
2455+
/// assert_eq!(deque.binary_search(&4), Err(7));
2456+
/// assert_eq!(deque.binary_search(&100), Err(13));
2457+
/// let r = deque.binary_search(&1);
2458+
/// assert!(matches!(r, Ok(1..=4)));
2459+
/// ```
2460+
///
2461+
/// If you want to insert an item to a sorted `VecDeque`, while maintaining
2462+
/// sort order:
2463+
///
2464+
/// ```
2465+
/// #![feature(vecdeque_binary_search)]
2466+
/// use std::collections::VecDeque;
2467+
///
2468+
/// let mut deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
2469+
/// let num = 42;
2470+
/// let idx = deque.binary_search(&num).unwrap_or_else(|x| x);
2471+
/// deque.insert(idx, num);
2472+
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
2473+
/// ```
2474+
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
2475+
#[inline]
2476+
pub fn binary_search(&self, x: &T) -> Result<usize, usize>
2477+
where
2478+
T: Ord,
2479+
{
2480+
self.binary_search_by(|e| e.cmp(x))
2481+
}
2482+
2483+
/// Binary searches this sorted `VecDeque` with a comparator function.
2484+
///
2485+
/// The comparator function should implement an order consistent
2486+
/// with the sort order of the underlying `VecDeque`, returning an
2487+
/// order code that indicates whether its argument is `Less`,
2488+
/// `Equal` or `Greater` than the desired target.
2489+
///
2490+
/// If the value is found then [`Result::Ok`] is returned, containing the
2491+
/// index of the matching element. If there are multiple matches, then any
2492+
/// one of the matches could be returned. If the value is not found then
2493+
/// [`Result::Err`] is returned, containing the index where a matching
2494+
/// element could be inserted while maintaining sorted order.
2495+
///
2496+
/// # Examples
2497+
///
2498+
/// Looks up a series of four elements. The first is found, with a
2499+
/// uniquely determined position; the second and third are not
2500+
/// found; the fourth could match any position in `[1, 4]`.
2501+
///
2502+
/// ```
2503+
/// #![feature(vecdeque_binary_search)]
2504+
/// use std::collections::VecDeque;
2505+
///
2506+
/// let deque: VecDeque<_> = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
2507+
///
2508+
/// assert_eq!(deque.binary_search_by(|x| x.cmp(&13)), Ok(9));
2509+
/// assert_eq!(deque.binary_search_by(|x| x.cmp(&4)), Err(7));
2510+
/// assert_eq!(deque.binary_search_by(|x| x.cmp(&100)), Err(13));
2511+
/// let r = deque.binary_search_by(|x| x.cmp(&1));
2512+
/// assert!(matches!(r, Ok(1..=4)));
2513+
/// ```
2514+
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
2515+
pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
2516+
where
2517+
F: FnMut(&'a T) -> Ordering,
2518+
{
2519+
let (front, back) = self.as_slices();
2520+
2521+
if let Some(Ordering::Less | Ordering::Equal) = back.first().map(|elem| f(elem)) {
2522+
back.binary_search_by(f).map(|idx| idx + front.len()).map_err(|idx| idx + front.len())
2523+
} else {
2524+
front.binary_search_by(f)
2525+
}
2526+
}
2527+
2528+
/// Binary searches this sorted `VecDeque` with a key extraction function.
2529+
///
2530+
/// Assumes that the `VecDeque` is sorted by the key, for instance with
2531+
/// [`make_contiguous().sort_by_key()`](#method.make_contiguous) using the same
2532+
/// key extraction function.
2533+
///
2534+
/// If the value is found then [`Result::Ok`] is returned, containing the
2535+
/// index of the matching element. If there are multiple matches, then any
2536+
/// one of the matches could be returned. If the value is not found then
2537+
/// [`Result::Err`] is returned, containing the index where a matching
2538+
/// element could be inserted while maintaining sorted order.
2539+
///
2540+
/// # Examples
2541+
///
2542+
/// Looks up a series of four elements in a slice of pairs sorted by
2543+
/// their second elements. The first is found, with a uniquely
2544+
/// determined position; the second and third are not found; the
2545+
/// fourth could match any position in `[1, 4]`.
2546+
///
2547+
/// ```
2548+
/// #![feature(vecdeque_binary_search)]
2549+
/// use std::collections::VecDeque;
2550+
///
2551+
/// let deque: VecDeque<_> = vec![(0, 0), (2, 1), (4, 1), (5, 1),
2552+
/// (3, 1), (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
2553+
/// (1, 21), (2, 34), (4, 55)].into();
2554+
///
2555+
/// assert_eq!(deque.binary_search_by_key(&13, |&(a,b)| b), Ok(9));
2556+
/// assert_eq!(deque.binary_search_by_key(&4, |&(a,b)| b), Err(7));
2557+
/// assert_eq!(deque.binary_search_by_key(&100, |&(a,b)| b), Err(13));
2558+
/// let r = deque.binary_search_by_key(&1, |&(a,b)| b);
2559+
/// assert!(matches!(r, Ok(1..=4)));
2560+
/// ```
2561+
#[unstable(feature = "vecdeque_binary_search", issue = "78021")]
2562+
#[inline]
2563+
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
2564+
where
2565+
F: FnMut(&'a T) -> B,
2566+
B: Ord,
2567+
{
2568+
self.binary_search_by(|k| f(k).cmp(b))
2569+
}
24332570
}
24342571

24352572
impl<T: Clone> VecDeque<T> {

library/alloc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(inplace_iteration)]
2121
#![feature(iter_map_while)]
2222
#![feature(int_bits_const)]
23+
#![feature(vecdeque_binary_search)]
2324

2425
use std::collections::hash_map::DefaultHasher;
2526
use std::hash::{Hash, Hasher};

library/alloc/tests/vec_deque.rs

+39
Original file line numberDiff line numberDiff line change
@@ -1659,3 +1659,42 @@ fn test_drain_leak() {
16591659
drop(v);
16601660
assert_eq!(unsafe { DROPS }, 7);
16611661
}
1662+
1663+
#[test]
1664+
fn test_binary_search() {
1665+
// Contiguous (front only) search:
1666+
let deque: VecDeque<_> = vec![1, 2, 3, 5, 6].into();
1667+
assert!(deque.as_slices().1.is_empty());
1668+
assert_eq!(deque.binary_search(&3), Ok(2));
1669+
assert_eq!(deque.binary_search(&4), Err(3));
1670+
1671+
// Split search (both front & back non-empty):
1672+
let mut deque: VecDeque<_> = vec![5, 6].into();
1673+
deque.push_front(3);
1674+
deque.push_front(2);
1675+
deque.push_front(1);
1676+
deque.push_back(10);
1677+
assert!(!deque.as_slices().0.is_empty());
1678+
assert!(!deque.as_slices().1.is_empty());
1679+
assert_eq!(deque.binary_search(&0), Err(0));
1680+
assert_eq!(deque.binary_search(&1), Ok(0));
1681+
assert_eq!(deque.binary_search(&5), Ok(3));
1682+
assert_eq!(deque.binary_search(&7), Err(5));
1683+
assert_eq!(deque.binary_search(&20), Err(6));
1684+
}
1685+
1686+
#[test]
1687+
fn test_binary_search_by() {
1688+
let deque: VecDeque<_> = vec![(1,), (2,), (3,), (5,), (6,)].into();
1689+
1690+
assert_eq!(deque.binary_search_by(|&(v,)| v.cmp(&3)), Ok(2));
1691+
assert_eq!(deque.binary_search_by(|&(v,)| v.cmp(&4)), Err(3));
1692+
}
1693+
1694+
#[test]
1695+
fn test_binary_search_by_key() {
1696+
let deque: VecDeque<_> = vec![(1,), (2,), (3,), (5,), (6,)].into();
1697+
1698+
assert_eq!(deque.binary_search_by_key(&3, |&(v,)| v), Ok(2));
1699+
assert_eq!(deque.binary_search_by_key(&4, |&(v,)| v), Err(3));
1700+
}

src/etc/gdb_providers.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,8 @@ def cast_to_internal(node):
229229
yield child
230230
if i < length:
231231
# Avoid "Cannot perform pointer math on incomplete type" on zero-sized arrays.
232-
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else None
233-
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else None
232+
key = keys[i]["value"]["value"] if keys.type.sizeof > 0 else "()"
233+
val = vals[i]["value"]["value"] if vals.type.sizeof > 0 else "()"
234234
yield key, val
235235

236236

@@ -242,11 +242,8 @@ def children_of_map(map):
242242
root = root.cast(gdb.lookup_type(root.type.name[21:-1]))
243243
boxed_root_node = root["node"]
244244
height = root["height"]
245-
for i, (key, val) in enumerate(children_of_node(boxed_root_node, height)):
246-
if key is not None:
247-
yield "key{}".format(i), key
248-
if val is not None:
249-
yield "val{}".format(i), val
245+
for child in children_of_node(boxed_root_node, height):
246+
yield child
250247

251248

252249
class StdBTreeSetProvider:
@@ -258,8 +255,8 @@ def to_string(self):
258255

259256
def children(self):
260257
inner_map = self.valobj["map"]
261-
for child in children_of_map(inner_map):
262-
yield child
258+
for i, (child, _) in enumerate(children_of_map(inner_map)):
259+
yield "[{}]".format(i), child
263260

264261
@staticmethod
265262
def display_hint():
@@ -274,8 +271,9 @@ def to_string(self):
274271
return "BTreeMap(size={})".format(self.valobj["length"])
275272

276273
def children(self):
277-
for child in children_of_map(self.valobj):
278-
yield child
274+
for i, (key, val) in enumerate(children_of_map(self.valobj)):
275+
yield "key{}".format(i), key
276+
yield "val{}".format(i), val
279277

280278
@staticmethod
281279
def display_hint():

src/librustdoc/clean/mod.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ use rustc_middle::ty::fold::TypeFolder;
2323
use rustc_middle::ty::subst::{InternalSubsts, Subst};
2424
use rustc_middle::ty::{self, AdtKind, Lift, Ty, TyCtxt};
2525
use rustc_mir::const_eval::{is_const_fn, is_min_const_fn, is_unstable_const_fn};
26-
use rustc_span::hygiene::MacroKind;
26+
use rustc_span::hygiene::{AstPass, MacroKind};
2727
use rustc_span::symbol::{kw, sym, Ident, Symbol};
28-
use rustc_span::{self, Pos};
28+
use rustc_span::{self, ExpnKind, Pos};
2929
use rustc_typeck::hir_ty_to_ty;
3030

3131
use std::collections::hash_map::Entry;
@@ -2231,6 +2231,13 @@ impl Clean<Vec<Item>> for doctree::ExternCrate<'_> {
22312231

22322232
impl Clean<Vec<Item>> for doctree::Import<'_> {
22332233
fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
2234+
// We need this comparison because some imports (for std types for example)
2235+
// are "inserted" as well but directly by the compiler and they should not be
2236+
// taken into account.
2237+
if self.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::StdImports) {
2238+
return Vec::new();
2239+
}
2240+
22342241
// We consider inlining the documentation of `pub use` statements, but we
22352242
// forcefully don't inline if this is not public or if the
22362243
// #[doc(no_inline)] attribute is present.

src/test/debuginfo/pretty-std-collections.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -34,20 +34,26 @@
3434
// gdb-check:$6 = BTreeMap(size=15) = {[0] = pretty_std_collections::MyLeafNode (0), [...]}
3535
// (abbreviated because it's boring but we need enough elements to include internal nodes)
3636

37-
// gdb-command: print zst_btree_map
38-
// gdb-check:$7 = BTreeMap(size=1)
37+
// gdb-command: print zst_key_btree_map
38+
// gdb-check:$7 = BTreeMap(size=1) = {[()] = 1}
39+
40+
// gdb-command: print zst_val_btree_map
41+
// gdb-check:$8 = BTreeMap(size=1) = {[1] = ()}
42+
43+
// gdb-command: print zst_key_val_btree_map
44+
// gdb-check:$9 = BTreeMap(size=1) = {[()] = ()}
3945

4046
// gdb-command: print vec_deque
41-
// gdb-check:$8 = VecDeque(size=3) = {5, 3, 7}
47+
// gdb-check:$10 = VecDeque(size=3) = {5, 3, 7}
4248

4349
// gdb-command: print vec_deque2
44-
// gdb-check:$9 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
50+
// gdb-check:$11 = VecDeque(size=7) = {2, 3, 4, 5, 6, 7, 8}
4551

4652
// gdb-command: print hash_map
47-
// gdb-check:$10 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
53+
// gdb-check:$12 = HashMap(size=4) = {[1] = 10, [2] = 20, [3] = 30, [4] = 40}
4854

4955
// gdb-command: print hash_set
50-
// gdb-check:$11 = HashSet(size=4) = {1, 2, 3, 4}
56+
// gdb-check:$13 = HashSet(size=4) = {1, 2, 3, 4}
5157

5258
// === LLDB TESTS ==================================================================================
5359

@@ -114,8 +120,14 @@ fn main() {
114120
nasty_btree_map.insert(i, MyLeafNode(i));
115121
}
116122

117-
let mut zst_btree_map: BTreeMap<(), ()> = BTreeMap::new();
118-
zst_btree_map.insert((), ());
123+
let mut zst_key_btree_map: BTreeMap<(), i32> = BTreeMap::new();
124+
zst_key_btree_map.insert((), 1);
125+
126+
let mut zst_val_btree_map: BTreeMap<i32, ()> = BTreeMap::new();
127+
zst_val_btree_map.insert(1, ());
128+
129+
let mut zst_key_val_btree_map: BTreeMap<(), ()> = BTreeMap::new();
130+
zst_key_val_btree_map.insert((), ());
119131

120132
// VecDeque
121133
let mut vec_deque = VecDeque::new();
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// compile-flags: --no-defaults
2+
3+
#![crate_name = "foo"]
4+
5+
// @has 'foo/index.html' '//code' 'extern crate std;'
6+
// @!has 'foo/index.html' '//code' 'use std::prelude::v1::*;'
7+
pub struct Foo;
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
// check-pass
2+
13
enum E {}
24

35
fn f(e: E) {
4-
println!("{}", (e as isize).to_string()); //~ ERROR non-primitive cast
6+
println!("{}", (e as isize).to_string());
57
}
68

79
fn main() {}

0 commit comments

Comments
 (0)