Skip to content

Commit 902ca44

Browse files
committed
Auto merge of rust-lang#83664 - Dylan-DPC:rollup-wx6idpd, r=Dylan-DPC
Rollup of 7 pull requests Successful merges: - rust-lang#82331 (alloc: Added `as_slice` method to `BinaryHeap` collection) - rust-lang#83130 (escape_ascii take 2) - rust-lang#83374 (unix: Fix feature(unix_socket_ancillary_data) on macos and other BSDs) - rust-lang#83543 (Lint on unknown intra-doc link disambiguators) - rust-lang#83636 (Add a regression test for issue-82792) - rust-lang#83643 (Remove a FIXME resolved by rust-lang#73578) - rust-lang#83644 (:arrow_up: rust-analyzer) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 50489e3 + 6738ee7 commit 902ca44

File tree

19 files changed

+367
-103
lines changed

19 files changed

+367
-103
lines changed

compiler/rustc_middle/src/ty/util.rs

-1
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,6 @@ impl<'tcx> ty::TyS<'tcx> {
699699
/// optimization as well as the rules around static values. Note
700700
/// that the `Freeze` trait is not exposed to end users and is
701701
/// effectively an implementation detail.
702-
// FIXME: use `TyCtxtAt` instead of separate `Span`.
703702
pub fn is_freeze(&'tcx self, tcx_at: TyCtxtAt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> bool {
704703
self.is_trivially_freeze() || tcx_at.is_freeze_raw(param_env.and(self))
705704
}

library/alloc/src/collections/binary_heap.rs

+21
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,27 @@ impl<T> BinaryHeap<T> {
958958
self.data.shrink_to(min_capacity)
959959
}
960960

961+
/// Returns a slice of all values in the underlying vector, in arbitrary
962+
/// order.
963+
///
964+
/// # Examples
965+
///
966+
/// Basic usage:
967+
///
968+
/// ```
969+
/// #![feature(binary_heap_as_slice)]
970+
/// use std::collections::BinaryHeap;
971+
/// use std::io::{self, Write};
972+
///
973+
/// let heap = BinaryHeap::from(vec![1, 2, 3, 4, 5, 6, 7]);
974+
///
975+
/// io::sink().write(heap.as_slice()).unwrap();
976+
/// ```
977+
#[unstable(feature = "binary_heap_as_slice", issue = "83659")]
978+
pub fn as_slice(&self) -> &[T] {
979+
self.data.as_slice()
980+
}
981+
961982
/// Consumes the `BinaryHeap` and returns the underlying vector
962983
/// in arbitrary order.
963984
///

library/alloc/tests/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#![feature(binary_heap_drain_sorted)]
1515
#![feature(slice_ptr_get)]
1616
#![feature(binary_heap_retain)]
17+
#![feature(binary_heap_as_slice)]
1718
#![feature(inplace_iteration)]
1819
#![feature(iter_map_while)]
1920
#![feature(vecdeque_binary_search)]

library/core/src/num/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![stable(feature = "rust1", since = "1.0.0")]
44

5+
use crate::ascii;
56
use crate::intrinsics;
67
use crate::mem;
78
use crate::str::FromStr;
@@ -661,6 +662,31 @@ impl u8 {
661662
pub const fn is_ascii_control(&self) -> bool {
662663
matches!(*self, b'\0'..=b'\x1F' | b'\x7F')
663664
}
665+
666+
/// Returns an iterator that produces an escaped version of a `u8`,
667+
/// treating it as an ASCII character.
668+
///
669+
/// The behavior is identical to [`ascii::escape_default`].
670+
///
671+
/// # Examples
672+
///
673+
/// ```
674+
/// #![feature(inherent_ascii_escape)]
675+
///
676+
/// assert_eq!("0", b'0'.escape_ascii().to_string());
677+
/// assert_eq!("\\t", b'\t'.escape_ascii().to_string());
678+
/// assert_eq!("\\r", b'\r'.escape_ascii().to_string());
679+
/// assert_eq!("\\n", b'\n'.escape_ascii().to_string());
680+
/// assert_eq!("\\'", b'\''.escape_ascii().to_string());
681+
/// assert_eq!("\\\"", b'"'.escape_ascii().to_string());
682+
/// assert_eq!("\\\\", b'\\'.escape_ascii().to_string());
683+
/// assert_eq!("\\x9d", b'\x9d'.escape_ascii().to_string());
684+
/// ```
685+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
686+
#[inline]
687+
pub fn escape_ascii(&self) -> ascii::EscapeDefault {
688+
ascii::escape_default(*self)
689+
}
664690
}
665691

666692
#[lang = "u16"]

library/core/src/slice/ascii.rs

+92
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
//! Operations on ASCII `[u8]`.
22
3+
use crate::ascii;
4+
use crate::fmt::{self, Write};
35
use crate::iter;
46
use crate::mem;
7+
use crate::ops;
58

69
#[lang = "slice_u8"]
710
#[cfg(not(test))]
@@ -56,6 +59,95 @@ impl [u8] {
5659
byte.make_ascii_lowercase();
5760
}
5861
}
62+
63+
/// Returns an iterator that produces an escaped version of this slice,
64+
/// treating it as an ASCII string.
65+
///
66+
/// # Examples
67+
///
68+
/// ```
69+
/// #![feature(inherent_ascii_escape)]
70+
///
71+
/// let s = b"0\t\r\n'\"\\\x9d";
72+
/// let escaped = s.escape_ascii().to_string();
73+
/// assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
74+
/// ```
75+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
76+
pub fn escape_ascii(&self) -> EscapeAscii<'_> {
77+
EscapeAscii { inner: self.iter().flat_map(EscapeByte) }
78+
}
79+
}
80+
81+
impl_fn_for_zst! {
82+
#[derive(Clone)]
83+
struct EscapeByte impl Fn = |byte: &u8| -> ascii::EscapeDefault {
84+
ascii::escape_default(*byte)
85+
};
86+
}
87+
88+
/// An iterator over the escaped version of a byte slice.
89+
///
90+
/// This `struct` is created by the [`slice::escape_ascii`] method. See its
91+
/// documentation for more information.
92+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
93+
#[derive(Clone)]
94+
pub struct EscapeAscii<'a> {
95+
inner: iter::FlatMap<super::Iter<'a, u8>, ascii::EscapeDefault, EscapeByte>,
96+
}
97+
98+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
99+
impl<'a> iter::Iterator for EscapeAscii<'a> {
100+
type Item = u8;
101+
#[inline]
102+
fn next(&mut self) -> Option<u8> {
103+
self.inner.next()
104+
}
105+
#[inline]
106+
fn size_hint(&self) -> (usize, Option<usize>) {
107+
self.inner.size_hint()
108+
}
109+
#[inline]
110+
fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
111+
where
112+
Fold: FnMut(Acc, Self::Item) -> R,
113+
R: ops::Try<Ok = Acc>,
114+
{
115+
self.inner.try_fold(init, fold)
116+
}
117+
#[inline]
118+
fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
119+
where
120+
Fold: FnMut(Acc, Self::Item) -> Acc,
121+
{
122+
self.inner.fold(init, fold)
123+
}
124+
#[inline]
125+
fn last(mut self) -> Option<u8> {
126+
self.next_back()
127+
}
128+
}
129+
130+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
131+
impl<'a> iter::DoubleEndedIterator for EscapeAscii<'a> {
132+
fn next_back(&mut self) -> Option<u8> {
133+
self.inner.next_back()
134+
}
135+
}
136+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
137+
impl<'a> iter::ExactSizeIterator for EscapeAscii<'a> {}
138+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
139+
impl<'a> iter::FusedIterator for EscapeAscii<'a> {}
140+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
141+
impl<'a> fmt::Display for EscapeAscii<'a> {
142+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143+
self.clone().try_for_each(|b| f.write_char(b as char))
144+
}
145+
}
146+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
147+
impl<'a> fmt::Debug for EscapeAscii<'a> {
148+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149+
f.pad("EscapeAscii { .. }")
150+
}
59151
}
60152

61153
/// Returns `true` if any byte in the word `v` is nonascii (>= 128). Snarfed

library/core/src/slice/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ pub use index::SliceIndex;
8181
#[unstable(feature = "slice_range", issue = "76393")]
8282
pub use index::range;
8383

84+
#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
85+
pub use ascii::EscapeAscii;
86+
8487
#[lang = "slice"]
8588
#[cfg(not(test))]
8689
impl<T> [T] {

library/std/src/sys/unix/ext/net/ancillary.rs

+34-23
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ use crate::marker::PhantomData;
55
use crate::mem::{size_of, zeroed};
66
use crate::os::unix::io::RawFd;
77
use crate::path::Path;
8-
#[cfg(target_os = "android")]
9-
use crate::ptr::eq;
10-
use crate::ptr::read_unaligned;
8+
use crate::ptr::{eq, read_unaligned};
119
use crate::slice::from_raw_parts;
1210
use crate::sys::net::Socket;
1311

@@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from(
3028
) -> io::Result<(usize, bool, io::Result<SocketAddr>)> {
3129
unsafe {
3230
let mut msg_name: libc::sockaddr_un = zeroed();
33-
3431
let mut msg: libc::msghdr = zeroed();
3532
msg.msg_name = &mut msg_name as *mut _ as *mut _;
3633
msg.msg_namelen = size_of::<libc::sockaddr_un>() as libc::socklen_t;
3734
msg.msg_iov = bufs.as_mut_ptr().cast();
38-
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
3935
cfg_if::cfg_if! {
4036
if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
4137
msg.msg_iovlen = bufs.len() as libc::size_t;
@@ -45,13 +41,18 @@ pub(super) fn recv_vectored_with_ancillary_from(
4541
target_os = "emscripten",
4642
target_os = "freebsd",
4743
all(target_os = "linux", target_env = "musl",),
44+
target_os = "macos",
4845
target_os = "netbsd",
4946
target_os = "openbsd",
5047
))] {
5148
msg.msg_iovlen = bufs.len() as libc::c_int;
5249
msg.msg_controllen = ancillary.buffer.len() as libc::socklen_t;
5350
}
5451
}
52+
// macos requires that the control pointer is NULL when the len is 0.
53+
if msg.msg_controllen > 0 {
54+
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
55+
}
5556

5657
let count = socket.recv_msg(&mut msg)?;
5758

@@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to(
7980
msg.msg_name = &mut msg_name as *mut _ as *mut _;
8081
msg.msg_namelen = msg_namelen;
8182
msg.msg_iov = bufs.as_ptr() as *mut _;
82-
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
8383
cfg_if::cfg_if! {
8484
if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
8585
msg.msg_iovlen = bufs.len() as libc::size_t;
@@ -89,13 +89,18 @@ pub(super) fn send_vectored_with_ancillary_to(
8989
target_os = "emscripten",
9090
target_os = "freebsd",
9191
all(target_os = "linux", target_env = "musl",),
92+
target_os = "macos",
9293
target_os = "netbsd",
9394
target_os = "openbsd",
9495
))] {
9596
msg.msg_iovlen = bufs.len() as libc::c_int;
9697
msg.msg_controllen = ancillary.length as libc::socklen_t;
9798
}
9899
}
100+
// macos requires that the control pointer is NULL when the len is 0.
101+
if msg.msg_controllen > 0 {
102+
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
103+
}
99104

100105
ancillary.truncated = false;
101106

@@ -147,6 +152,7 @@ fn add_to_ancillary_data<T>(
147152
target_os = "emscripten",
148153
target_os = "freebsd",
149154
all(target_os = "linux", target_env = "musl",),
155+
target_os = "macos",
150156
target_os = "netbsd",
151157
target_os = "openbsd",
152158
))] {
@@ -159,14 +165,12 @@ fn add_to_ancillary_data<T>(
159165
while !cmsg.is_null() {
160166
previous_cmsg = cmsg;
161167
cmsg = libc::CMSG_NXTHDR(&msg, cmsg);
162-
cfg_if::cfg_if! {
163-
// Android return the same pointer if it is the last cmsg.
164-
// Therefore, check it if the previous pointer is the same as the current one.
165-
if #[cfg(target_os = "android")] {
166-
if cmsg == previous_cmsg {
167-
break;
168-
}
169-
}
168+
169+
// Most operating systems, but not Linux or emscripten, return the previous pointer
170+
// when its length is zero. Therefore, check if the previous pointer is the same as
171+
// the current one.
172+
if eq(cmsg, previous_cmsg) {
173+
break;
170174
}
171175
}
172176

@@ -184,6 +188,7 @@ fn add_to_ancillary_data<T>(
184188
target_os = "emscripten",
185189
target_os = "freebsd",
186190
all(target_os = "linux", target_env = "musl",),
191+
target_os = "macos",
187192
target_os = "netbsd",
188193
target_os = "openbsd",
189194
))] {
@@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> {
371376
target_os = "emscripten",
372377
target_os = "freebsd",
373378
all(target_os = "linux", target_env = "musl",),
379+
target_os = "macos",
374380
target_os = "netbsd",
375381
target_os = "openbsd",
376382
))] {
@@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> {
421427
target_os = "emscripten",
422428
target_os = "freebsd",
423429
all(target_os = "linux", target_env = "musl",),
430+
target_os = "macos",
424431
target_os = "netbsd",
425432
target_os = "openbsd",
426433
))] {
@@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> {
435442
};
436443

437444
let cmsg = cmsg.as_ref()?;
438-
cfg_if::cfg_if! {
439-
// Android return the same pointer if it is the last cmsg.
440-
// Therefore, check it if the previous pointer is the same as the current one.
441-
if #[cfg(target_os = "android")] {
442-
if let Some(current) = self.current {
443-
if eq(current, cmsg) {
444-
return None;
445-
}
446-
}
445+
446+
// Most operating systems, but not Linux or emscripten, return the previous pointer
447+
// when its length is zero. Therefore, check if the previous pointer is the same as
448+
// the current one.
449+
if let Some(current) = self.current {
450+
if eq(current, cmsg) {
451+
return None;
447452
}
448453
}
449454

@@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> {
514519
self.buffer.len()
515520
}
516521

522+
/// Returns `true` if the ancillary data is empty.
523+
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
524+
pub fn is_empty(&self) -> bool {
525+
self.length == 0
526+
}
527+
517528
/// Returns the number of used bytes.
518529
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
519530
pub fn len(&self) -> usize {

src/librustdoc/html/markdown.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,7 @@ crate fn plain_text_summary(md: &str) -> String {
11621162
s
11631163
}
11641164

1165+
#[derive(Debug)]
11651166
crate struct MarkdownLink {
11661167
pub kind: LinkType,
11671168
pub link: String,

0 commit comments

Comments
 (0)