Skip to content

Commit 2ed65da

Browse files
committed
Auto merge of #104629 - JohnTitor:rollup-vp3m98i, r=JohnTitor
Rollup of 6 pull requests Successful merges: - #103901 (Add tracking issue for `const_arguments_as_str`) - #104112 (rustdoc: Add copy to the description of repeat) - #104435 (`VecDeque::resize` should re-use the buffer in the passed-in element) - #104467 (Fix substraction with overflow in `wrong_number_of_generic_args.rs`) - #104608 (Cleanup macro matching recovery) - #104626 (Fix doctest errors related to rustc_middle) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 7477c1f + d553811 commit 2ed65da

File tree

19 files changed

+377
-14
lines changed

19 files changed

+377
-14
lines changed

compiler/rustc_expand/src/mbe/macro_rules.rs

-1
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,6 @@ fn try_match_macro<'matcher, T: Tracker<'matcher>>(
495495
// hacky, but speeds up the `html5ever` benchmark significantly. (Issue
496496
// 68836 suggests a more comprehensive but more complex change to deal with
497497
// this situation.)
498-
// FIXME(Nilstrieb): Stop recovery from happening on this parser and retry later with recovery if the macro failed to match.
499498
let parser = parser_from_cx(sess, arg.clone(), T::recovery());
500499
// Try each arm's matchers.
501500
let mut tt_parser = TtParser::new(name);

compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
728728
&& let Some(trait_path_segment) = path.segments.get(0) {
729729
let num_generic_args_supplied_to_trait = trait_path_segment.args().num_generic_params();
730730

731-
if num_assoc_fn_excess_args == num_trait_generics_except_self - num_generic_args_supplied_to_trait {
731+
if num_generic_args_supplied_to_trait + num_assoc_fn_excess_args == num_trait_generics_except_self
732+
{
732733
if let Some(span) = self.gen_args.span_ext()
733734
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
734735
let sugg = vec![

compiler/rustc_middle/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ version = "0.0.0"
44
edition = "2021"
55

66
[lib]
7-
doctest = false
87

98
[dependencies]
109
bitflags = "1.2.1"

compiler/rustc_middle/src/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1648,6 +1648,8 @@ rustc_queries! {
16481648
/// a generic type parameter will panic if you call this method on it:
16491649
///
16501650
/// ```
1651+
/// use std::fmt::Debug;
1652+
///
16511653
/// pub trait Foo<T: Debug> {}
16521654
/// ```
16531655
///

compiler/rustc_middle/src/ty/inhabitedness/mod.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//!
66
//! # Example
77
//! ```rust
8-
//! enum Void {}
8+
//! #![feature(never_type)]
99
//! mod a {
1010
//! pub mod b {
1111
//! pub struct SecretlyUninhabited {
@@ -15,6 +15,7 @@
1515
//! }
1616
//!
1717
//! mod c {
18+
//! enum Void {}
1819
//! pub struct AlsoSecretlyUninhabited {
1920
//! _priv: Void,
2021
//! }
@@ -35,7 +36,7 @@
3536
//! `Foo`.
3637
//!
3738
//! # Example
38-
//! ```rust
39+
//! ```ignore(illustrative)
3940
//! let foo_result: Result<T, Foo> = ... ;
4041
//! let Ok(t) = foo_result;
4142
//! ```

compiler/rustc_parse/src/parser/expr.rs

-5
Original file line numberDiff line numberDiff line change
@@ -2078,12 +2078,7 @@ impl<'a> Parser<'a> {
20782078

20792079
if self.token.kind == TokenKind::Semi
20802080
&& matches!(self.token_cursor.frame.delim_sp, Some((Delimiter::Parenthesis, _)))
2081-
// HACK: This is needed so we can detect whether we're inside a macro,
2082-
// where regular assumptions about what tokens can follow other tokens
2083-
// don't necessarily apply.
20842081
&& self.may_recover()
2085-
// FIXME(Nilstrieb): Remove this check once `may_recover` actually stops recovery
2086-
&& self.subparser_name.is_none()
20872082
{
20882083
// It is likely that the closure body is a block but where the
20892084
// braces have been removed. We will recover and eat the next

library/alloc/src/collections/vec_deque/mod.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use core::cmp::{self, Ordering};
1111
use core::fmt;
1212
use core::hash::{Hash, Hasher};
13-
use core::iter::{repeat_with, FromIterator};
13+
use core::iter::{repeat_n, repeat_with, FromIterator};
1414
use core::marker::PhantomData;
1515
use core::mem::{ManuallyDrop, MaybeUninit, SizedTypeProperties};
1616
use core::ops::{Index, IndexMut, Range, RangeBounds};
@@ -2833,7 +2833,12 @@ impl<T: Clone, A: Allocator> VecDeque<T, A> {
28332833
/// ```
28342834
#[stable(feature = "deque_extras", since = "1.16.0")]
28352835
pub fn resize(&mut self, new_len: usize, value: T) {
2836-
self.resize_with(new_len, || value.clone());
2836+
if new_len > self.len() {
2837+
let extra = new_len - self.len();
2838+
self.extend(repeat_n(value, extra))
2839+
} else {
2840+
self.truncate(new_len);
2841+
}
28372842
}
28382843
}
28392844

library/alloc/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@
124124
#![feature(inplace_iteration)]
125125
#![feature(iter_advance_by)]
126126
#![feature(iter_next_chunk)]
127+
#![feature(iter_repeat_n)]
127128
#![feature(layout_for_ptr)]
128129
#![feature(maybe_uninit_slice)]
129130
#![feature(maybe_uninit_uninit_array)]

library/alloc/src/slice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ impl<T> [T] {
458458
hack::into_vec(self)
459459
}
460460

461-
/// Creates a vector by repeating a slice `n` times.
461+
/// Creates a vector by copying a slice `n` times.
462462
///
463463
/// # Panics
464464
///

library/alloc/tests/vec_deque.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1727,3 +1727,11 @@ fn test_from_zero_sized_vec() {
17271727
let queue = VecDeque::from(v);
17281728
assert_eq!(queue.len(), 100);
17291729
}
1730+
1731+
#[test]
1732+
fn test_resize_keeps_reserved_space_from_item() {
1733+
let v = Vec::<i32>::with_capacity(1234);
1734+
let mut d = VecDeque::new();
1735+
d.resize(1, v);
1736+
assert_eq!(d[0].capacity(), 1234);
1737+
}

library/core/src/fmt/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ impl<'a> Arguments<'a> {
510510
/// assert_eq!(format_args!("{}", 1).as_str(), None);
511511
/// ```
512512
#[stable(feature = "fmt_as_str", since = "1.52.0")]
513-
#[rustc_const_unstable(feature = "const_arguments_as_str", issue = "none")]
513+
#[rustc_const_unstable(feature = "const_arguments_as_str", issue = "103900")]
514514
#[must_use]
515515
#[inline]
516516
pub const fn as_str(&self) -> Option<&'static str> {

library/core/src/iter/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ pub use self::sources::{once, Once};
401401
pub use self::sources::{once_with, OnceWith};
402402
#[stable(feature = "rust1", since = "1.0.0")]
403403
pub use self::sources::{repeat, Repeat};
404+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
405+
pub use self::sources::{repeat_n, RepeatN};
404406
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
405407
pub use self::sources::{repeat_with, RepeatWith};
406408
#[stable(feature = "iter_successors", since = "1.34.0")]

library/core/src/iter/sources.rs

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod from_generator;
44
mod once;
55
mod once_with;
66
mod repeat;
7+
mod repeat_n;
78
mod repeat_with;
89
mod successors;
910

@@ -16,6 +17,9 @@ pub use self::empty::{empty, Empty};
1617
#[stable(feature = "iter_once", since = "1.2.0")]
1718
pub use self::once::{once, Once};
1819

20+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
21+
pub use self::repeat_n::{repeat_n, RepeatN};
22+
1923
#[stable(feature = "iterator_repeat_with", since = "1.28.0")]
2024
pub use self::repeat_with::{repeat_with, RepeatWith};
2125

+195
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
use crate::iter::{FusedIterator, TrustedLen};
2+
use crate::mem::ManuallyDrop;
3+
4+
/// Creates a new iterator that repeats a single element a given number of times.
5+
///
6+
/// The `repeat_n()` function repeats a single value exactly `n` times.
7+
///
8+
/// This is very similar to using [`repeat()`] with [`Iterator::take()`],
9+
/// but there are two differences:
10+
/// - `repeat_n()` can return the original value, rather than always cloning.
11+
/// - `repeat_n()` produces an [`ExactSizeIterator`].
12+
///
13+
/// [`repeat()`]: crate::iter::repeat
14+
///
15+
/// # Examples
16+
///
17+
/// Basic usage:
18+
///
19+
/// ```
20+
/// #![feature(iter_repeat_n)]
21+
/// use std::iter;
22+
///
23+
/// // four of the the number four:
24+
/// let mut four_fours = iter::repeat_n(4, 4);
25+
///
26+
/// assert_eq!(Some(4), four_fours.next());
27+
/// assert_eq!(Some(4), four_fours.next());
28+
/// assert_eq!(Some(4), four_fours.next());
29+
/// assert_eq!(Some(4), four_fours.next());
30+
///
31+
/// // no more fours
32+
/// assert_eq!(None, four_fours.next());
33+
/// ```
34+
///
35+
/// For non-`Copy` types,
36+
///
37+
/// ```
38+
/// #![feature(iter_repeat_n)]
39+
/// use std::iter;
40+
///
41+
/// let v: Vec<i32> = Vec::with_capacity(123);
42+
/// let mut it = iter::repeat_n(v, 5);
43+
///
44+
/// for i in 0..4 {
45+
/// // It starts by cloning things
46+
/// let cloned = it.next().unwrap();
47+
/// assert_eq!(cloned.len(), 0);
48+
/// assert_eq!(cloned.capacity(), 0);
49+
/// }
50+
///
51+
/// // ... but the last item is the original one
52+
/// let last = it.next().unwrap();
53+
/// assert_eq!(last.len(), 0);
54+
/// assert_eq!(last.capacity(), 123);
55+
///
56+
/// // ... and now we're done
57+
/// assert_eq!(None, it.next());
58+
/// ```
59+
#[inline]
60+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
61+
#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
62+
pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
63+
let mut element = ManuallyDrop::new(element);
64+
65+
if count == 0 {
66+
// SAFETY: we definitely haven't dropped it yet, since we only just got
67+
// passed it in, and because the count is zero the instance we're about
68+
// to create won't drop it, so to avoid leaking we need to now.
69+
unsafe { ManuallyDrop::drop(&mut element) };
70+
}
71+
72+
RepeatN { element, count }
73+
}
74+
75+
/// An iterator that repeats an element an exact number of times.
76+
///
77+
/// This `struct` is created by the [`repeat_n()`] function.
78+
/// See its documentation for more.
79+
#[derive(Clone, Debug)]
80+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
81+
#[doc(hidden)] // waiting on ACP#120 to decide whether to expose publicly
82+
pub struct RepeatN<A> {
83+
count: usize,
84+
// Invariant: has been dropped iff count == 0.
85+
element: ManuallyDrop<A>,
86+
}
87+
88+
impl<A> RepeatN<A> {
89+
/// If we haven't already dropped the element, return it in an option.
90+
///
91+
/// Clears the count so it won't be dropped again later.
92+
#[inline]
93+
fn take_element(&mut self) -> Option<A> {
94+
if self.count > 0 {
95+
self.count = 0;
96+
// SAFETY: We just set count to zero so it won't be dropped again,
97+
// and it used to be non-zero so it hasn't already been dropped.
98+
unsafe { Some(ManuallyDrop::take(&mut self.element)) }
99+
} else {
100+
None
101+
}
102+
}
103+
}
104+
105+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
106+
impl<A> Drop for RepeatN<A> {
107+
fn drop(&mut self) {
108+
self.take_element();
109+
}
110+
}
111+
112+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
113+
impl<A: Clone> Iterator for RepeatN<A> {
114+
type Item = A;
115+
116+
#[inline]
117+
fn next(&mut self) -> Option<A> {
118+
if self.count == 0 {
119+
return None;
120+
}
121+
122+
self.count -= 1;
123+
Some(if self.count == 0 {
124+
// SAFETY: the check above ensured that the count used to be non-zero,
125+
// so element hasn't been dropped yet, and we just lowered the count to
126+
// zero so it won't be dropped later, and thus it's okay to take it here.
127+
unsafe { ManuallyDrop::take(&mut self.element) }
128+
} else {
129+
A::clone(&mut self.element)
130+
})
131+
}
132+
133+
#[inline]
134+
fn size_hint(&self) -> (usize, Option<usize>) {
135+
let len = self.len();
136+
(len, Some(len))
137+
}
138+
139+
#[inline]
140+
fn advance_by(&mut self, skip: usize) -> Result<(), usize> {
141+
let len = self.count;
142+
143+
if skip >= len {
144+
self.take_element();
145+
}
146+
147+
if skip > len {
148+
Err(len)
149+
} else {
150+
self.count = len - skip;
151+
Ok(())
152+
}
153+
}
154+
155+
#[inline]
156+
fn last(mut self) -> Option<A> {
157+
self.take_element()
158+
}
159+
160+
#[inline]
161+
fn count(self) -> usize {
162+
self.len()
163+
}
164+
}
165+
166+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
167+
impl<A: Clone> ExactSizeIterator for RepeatN<A> {
168+
fn len(&self) -> usize {
169+
self.count
170+
}
171+
}
172+
173+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
174+
impl<A: Clone> DoubleEndedIterator for RepeatN<A> {
175+
#[inline]
176+
fn next_back(&mut self) -> Option<A> {
177+
self.next()
178+
}
179+
180+
#[inline]
181+
fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
182+
self.advance_by(n)
183+
}
184+
185+
#[inline]
186+
fn nth_back(&mut self, n: usize) -> Option<A> {
187+
self.nth(n)
188+
}
189+
}
190+
191+
#[unstable(feature = "iter_repeat_n", issue = "104434")]
192+
impl<A: Clone> FusedIterator for RepeatN<A> {}
193+
194+
#[unstable(feature = "trusted_len", issue = "37572")]
195+
unsafe impl<A: Clone> TrustedLen for RepeatN<A> {}

0 commit comments

Comments
 (0)