Skip to content

Commit e250777

Browse files
committed
Auto merge of rust-lang#91691 - matthiaskrgr:rollup-wfommdr, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - rust-lang#91042 (Use Vec extend instead of repeated pushes on several places) - rust-lang#91476 (Improve 'cannot contain emoji' error.) - rust-lang#91568 (Pretty print break and continue without redundant space) - rust-lang#91645 (Implement `core::future::join!`) - rust-lang#91666 (update Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 3c857f4 + 229aa1b commit e250777

File tree

19 files changed

+291
-39
lines changed

19 files changed

+291
-39
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -2135,22 +2135,20 @@ impl<'a> State<'a> {
21352135
ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true),
21362136
ast::ExprKind::Break(opt_label, ref opt_expr) => {
21372137
self.word("break");
2138-
self.space();
21392138
if let Some(label) = opt_label {
2140-
self.print_ident(label.ident);
21412139
self.space();
2140+
self.print_ident(label.ident);
21422141
}
21432142
if let Some(ref expr) = *opt_expr {
2144-
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
21452143
self.space();
2144+
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
21462145
}
21472146
}
21482147
ast::ExprKind::Continue(opt_label) => {
21492148
self.word("continue");
2150-
self.space();
21512149
if let Some(label) = opt_label {
2150+
self.space();
21522151
self.print_ident(label.ident);
2153-
self.space()
21542152
}
21552153
}
21562154
ast::ExprKind::Ret(ref result) => {

compiler/rustc_hir_pretty/src/lib.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1543,22 +1543,20 @@ impl<'a> State<'a> {
15431543
hir::ExprKind::Path(ref qpath) => self.print_qpath(qpath, true),
15441544
hir::ExprKind::Break(destination, ref opt_expr) => {
15451545
self.word("break");
1546-
self.space();
15471546
if let Some(label) = destination.label {
1548-
self.print_ident(label.ident);
15491547
self.space();
1548+
self.print_ident(label.ident);
15501549
}
15511550
if let Some(ref expr) = *opt_expr {
1552-
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
15531551
self.space();
1552+
self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
15541553
}
15551554
}
15561555
hir::ExprKind::Continue(destination) => {
15571556
self.word("continue");
1558-
self.space();
15591557
if let Some(label) = destination.label {
1558+
self.space();
15601559
self.print_ident(label.ident);
1561-
self.space()
15621560
}
15631561
}
15641562
hir::ExprKind::Ret(ref result) => {

compiler/rustc_interface/src/passes.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_codegen_ssa::traits::CodegenBackend;
1010
use rustc_data_structures::parallel;
1111
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
1212
use rustc_data_structures::temp_dir::MaybeTempDir;
13-
use rustc_errors::{ErrorReported, PResult};
13+
use rustc_errors::{Applicability, ErrorReported, PResult};
1414
use rustc_expand::base::ExtCtxt;
1515
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
1616
use rustc_hir::Crate;
@@ -456,10 +456,26 @@ pub fn configure_and_expand(
456456
identifiers.sort_by_key(|&(key, _)| key);
457457
for (ident, mut spans) in identifiers.into_iter() {
458458
spans.sort();
459-
sess.diagnostic().span_err(
460-
MultiSpan::from(spans),
461-
&format!("identifiers cannot contain emoji: `{}`", ident),
462-
);
459+
if ident == sym::ferris {
460+
let first_span = spans[0];
461+
sess.diagnostic()
462+
.struct_span_err(
463+
MultiSpan::from(spans),
464+
"Ferris cannot be used as an identifier",
465+
)
466+
.span_suggestion(
467+
first_span,
468+
"try using their name instead",
469+
"ferris".to_string(),
470+
Applicability::MaybeIncorrect,
471+
)
472+
.emit();
473+
} else {
474+
sess.diagnostic().span_err(
475+
MultiSpan::from(spans),
476+
&format!("identifiers cannot contain emoji: `{}`", ident),
477+
);
478+
}
463479
}
464480
});
465481

compiler/rustc_mir_transform/src/coverage/spans.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,7 @@ impl<'a, 'tcx> CoverageSpans<'a, 'tcx> {
329329
fn mir_to_initial_sorted_coverage_spans(&self) -> Vec<CoverageSpan> {
330330
let mut initial_spans = Vec::<CoverageSpan>::with_capacity(self.mir_body.num_nodes() * 2);
331331
for (bcb, bcb_data) in self.basic_coverage_blocks.iter_enumerated() {
332-
for coverage_span in self.bcb_to_initial_coverage_spans(bcb, bcb_data) {
333-
initial_spans.push(coverage_span);
334-
}
332+
initial_spans.extend(self.bcb_to_initial_coverage_spans(bcb, bcb_data));
335333
}
336334

337335
if initial_spans.is_empty() {

compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ symbols! {
630630
fdiv_fast,
631631
feature,
632632
fence,
633+
ferris: "🦀",
633634
fetch_update,
634635
ffi,
635636
ffi_const,

compiler/rustc_trait_selection/src/traits/coherence.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,7 @@ fn orphan_check_trait_ref<'tcx>(
498498
return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type));
499499
}
500500

501-
for input_ty in non_local_tys {
502-
non_local_spans.push((input_ty, i == 0));
503-
}
501+
non_local_spans.extend(non_local_tys.into_iter().map(|input_ty| (input_ty, i == 0)));
504502
}
505503
// If we exit above loop, never found a local type.
506504
debug!("orphan_check_trait_ref: no local type");

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -362,9 +362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
362362
.infcx
363363
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
364364

365-
for predicate_index in result {
366-
candidates.vec.push(ProjectionCandidate(predicate_index));
367-
}
365+
candidates.vec.extend(result.into_iter().map(ProjectionCandidate));
368366
}
369367

370368
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller

compiler/rustc_typeck/src/check/mod.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -686,9 +686,8 @@ fn bounds_from_generic_predicates<'tcx>(
686686
};
687687
let mut where_clauses = vec![];
688688
for (ty, bounds) in types {
689-
for bound in &bounds {
690-
where_clauses.push(format!("{}: {}", ty, tcx.def_path_str(*bound)));
691-
}
689+
where_clauses
690+
.extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))));
692691
}
693692
for projection in &projections {
694693
let p = projection.skip_binder();

compiler/rustc_typeck/src/check/upvar.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -904,10 +904,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
904904
) -> MigrationWarningReason {
905905
let mut reasons = MigrationWarningReason::default();
906906

907-
for auto_trait in auto_trait_reasons {
908-
reasons.auto_traits.push(auto_trait);
909-
}
910-
907+
reasons.auto_traits.extend(auto_trait_reasons);
911908
reasons.drop_order = drop_order;
912909

913910
reasons

library/core/src/future/join.rs

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
#![allow(unused_imports)] // items are used by the macro
2+
3+
use crate::cell::UnsafeCell;
4+
use crate::future::{poll_fn, Future};
5+
use crate::mem;
6+
use crate::pin::Pin;
7+
use crate::task::{Context, Poll};
8+
9+
/// Polls multiple futures simultaneously, returning a tuple
10+
/// of all results once complete.
11+
///
12+
/// While `join!(a, b)` is similar to `(a.await, b.await)`,
13+
/// `join!` polls both futures concurrently and is therefore more efficient.
14+
///
15+
/// # Examples
16+
///
17+
/// ```
18+
/// #![feature(future_join, future_poll_fn)]
19+
///
20+
/// use std::future::join;
21+
///
22+
/// async fn one() -> usize { 1 }
23+
/// async fn two() -> usize { 2 }
24+
///
25+
/// # let _ = async {
26+
/// let x = join!(one(), two()).await;
27+
/// assert_eq!(x, (1, 2));
28+
/// # };
29+
/// ```
30+
///
31+
/// `join!` is variadic, so you can pass any number of futures:
32+
///
33+
/// ```
34+
/// #![feature(future_join, future_poll_fn)]
35+
///
36+
/// use std::future::join;
37+
///
38+
/// async fn one() -> usize { 1 }
39+
/// async fn two() -> usize { 2 }
40+
/// async fn three() -> usize { 3 }
41+
///
42+
/// # let _ = async {
43+
/// let x = join!(one(), two(), three()).await;
44+
/// assert_eq!(x, (1, 2, 3));
45+
/// # };
46+
/// ```
47+
#[unstable(feature = "future_join", issue = "91642")]
48+
pub macro join {
49+
( $($fut:expr),* $(,)?) => {
50+
join! { @count: (), @futures: {}, @rest: ($($fut,)*) }
51+
},
52+
// Recurse until we have the position of each future in the tuple
53+
(
54+
// A token for each future that has been expanded: "_ _ _"
55+
@count: ($($count:tt)*),
56+
// Futures and their positions in the tuple: "{ a => (_), b => (_ _)) }"
57+
@futures: { $($fut:tt)* },
58+
// Take a future from @rest to expand
59+
@rest: ($current:expr, $($rest:tt)*)
60+
) => {
61+
join! {
62+
@count: ($($count)* _),
63+
@futures: { $($fut)* $current => ($($count)*), },
64+
@rest: ($($rest)*)
65+
}
66+
},
67+
// Now generate the output future
68+
(
69+
@count: ($($count:tt)*),
70+
@futures: {
71+
$( $(@$f:tt)? $fut:expr => ( $($pos:tt)* ), )*
72+
},
73+
@rest: ()
74+
) => {
75+
async move {
76+
let mut futures = ( $( MaybeDone::Future($fut), )* );
77+
78+
poll_fn(move |cx| {
79+
let mut done = true;
80+
81+
$(
82+
let ( $($pos,)* fut, .. ) = &mut futures;
83+
84+
// SAFETY: The futures are never moved
85+
done &= unsafe { Pin::new_unchecked(fut).poll(cx).is_ready() };
86+
)*
87+
88+
if done {
89+
// Extract all the outputs
90+
Poll::Ready(($({
91+
let ( $($pos,)* fut, .. ) = &mut futures;
92+
93+
fut.take_output().unwrap()
94+
}),*))
95+
} else {
96+
Poll::Pending
97+
}
98+
}).await
99+
}
100+
}
101+
}
102+
103+
/// Future used by `join!` that stores it's output to
104+
/// be later taken and doesn't panic when polled after ready.
105+
///
106+
/// This type is public in a private module for use by the macro.
107+
#[allow(missing_debug_implementations)]
108+
#[unstable(feature = "future_join", issue = "91642")]
109+
pub enum MaybeDone<F: Future> {
110+
Future(F),
111+
Done(F::Output),
112+
Took,
113+
}
114+
115+
#[unstable(feature = "future_join", issue = "91642")]
116+
impl<F: Future> MaybeDone<F> {
117+
pub fn take_output(&mut self) -> Option<F::Output> {
118+
match &*self {
119+
MaybeDone::Done(_) => match mem::replace(self, Self::Took) {
120+
MaybeDone::Done(val) => Some(val),
121+
_ => unreachable!(),
122+
},
123+
_ => None,
124+
}
125+
}
126+
}
127+
128+
#[unstable(feature = "future_join", issue = "91642")]
129+
impl<F: Future> Future for MaybeDone<F> {
130+
type Output = ();
131+
132+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
133+
// SAFETY: pinning in structural for `f`
134+
unsafe {
135+
match self.as_mut().get_unchecked_mut() {
136+
MaybeDone::Future(f) => match Pin::new_unchecked(f).poll(cx) {
137+
Poll::Ready(val) => self.set(Self::Done(val)),
138+
Poll::Pending => return Poll::Pending,
139+
},
140+
MaybeDone::Done(_) => {}
141+
MaybeDone::Took => unreachable!(),
142+
}
143+
}
144+
145+
Poll::Ready(())
146+
}
147+
}

library/core/src/future/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@ use crate::{
1111

1212
mod future;
1313
mod into_future;
14+
mod join;
1415
mod pending;
1516
mod poll_fn;
1617
mod ready;
1718

1819
#[stable(feature = "futures_api", since = "1.36.0")]
1920
pub use self::future::Future;
2021

22+
#[unstable(feature = "future_join", issue = "91642")]
23+
pub use self::join::join;
24+
2125
#[unstable(feature = "into_future", issue = "67644")]
2226
pub use into_future::IntoFuture;
2327

0 commit comments

Comments
 (0)