Skip to content

Commit 7c46fb2

Browse files
committed
Auto merge of #107625 - matthiaskrgr:rollup-xr9oldy, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #106575 (Suggest `move` in nested closure when appropriate) - #106805 (Suggest `{var:?}` when finding `{?:var}` in inline format strings) - #107500 (Add tests to assert current behavior of large future sizes) - #107598 (Fix benchmarks in library/core with black_box) - #107602 (Parse and recover from type ascription in patterns) - #107608 (Use triple rather than arch for fuchsia test-runner) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 5d32458 + b6e8ebf commit 7c46fb2

21 files changed

+521
-122
lines changed

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+12-16
Original file line numberDiff line numberDiff line change
@@ -583,10 +583,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
583583
let err = FnMutError {
584584
span: *span,
585585
ty_err: match output_ty.kind() {
586-
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
587586
ty::Generator(def, ..) if self.infcx.tcx.generator_is_async(*def) => {
588587
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
589588
}
589+
_ if output_ty.contains_closure() => {
590+
FnMutReturnTypeErr::ReturnClosure { span: *span }
591+
}
590592
_ => FnMutReturnTypeErr::ReturnRef { span: *span },
591593
},
592594
};
@@ -997,7 +999,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
997999
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diagnostic) {
9981000
let map = self.infcx.tcx.hir();
9991001
let body_id = map.body_owned_by(self.mir_def_id());
1000-
let expr = &map.body(body_id).value;
1002+
let expr = &map.body(body_id).value.peel_blocks();
10011003
let mut closure_span = None::<rustc_span::Span>;
10021004
match expr.kind {
10031005
hir::ExprKind::MethodCall(.., args, _) => {
@@ -1012,20 +1014,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
10121014
}
10131015
}
10141016
}
1015-
hir::ExprKind::Block(blk, _) => {
1016-
if let Some(expr) = blk.expr {
1017-
// only when the block is a closure
1018-
if let hir::ExprKind::Closure(hir::Closure {
1019-
capture_clause: hir::CaptureBy::Ref,
1020-
body,
1021-
..
1022-
}) = expr.kind
1023-
{
1024-
let body = map.body(*body);
1025-
if !matches!(body.generator_kind, Some(hir::GeneratorKind::Async(..))) {
1026-
closure_span = Some(expr.span.shrink_to_lo());
1027-
}
1028-
}
1017+
hir::ExprKind::Closure(hir::Closure {
1018+
capture_clause: hir::CaptureBy::Ref,
1019+
body,
1020+
..
1021+
}) => {
1022+
let body = map.body(*body);
1023+
if !matches!(body.generator_kind, Some(hir::GeneratorKind::Async(..))) {
1024+
closure_span = Some(expr.span.shrink_to_lo());
10291025
}
10301026
}
10311027
_ => {}

compiler/rustc_middle/src/ty/sty.rs

+22
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,28 @@ impl<'tcx> Ty<'tcx> {
20432043
cf.is_break()
20442044
}
20452045

2046+
/// Checks whether a type recursively contains any closure
2047+
///
2048+
/// Example: `Option<[[email protected]:4:20]>` returns true
2049+
pub fn contains_closure(self) -> bool {
2050+
struct ContainsClosureVisitor;
2051+
2052+
impl<'tcx> TypeVisitor<'tcx> for ContainsClosureVisitor {
2053+
type BreakTy = ();
2054+
2055+
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
2056+
if let ty::Closure(_, _) = t.kind() {
2057+
ControlFlow::Break(())
2058+
} else {
2059+
t.super_visit_with(self)
2060+
}
2061+
}
2062+
}
2063+
2064+
let cf = self.visit_with(&mut ContainsClosureVisitor);
2065+
cf.is_break()
2066+
}
2067+
20462068
/// Returns the type and mutability of `*ty`.
20472069
///
20482070
/// The parameter `explicit` indicates if this is an *explicit* dereference.

compiler/rustc_parse/src/parser/diagnostics.rs

+39-12
Original file line numberDiff line numberDiff line change
@@ -2405,26 +2405,42 @@ impl<'a> Parser<'a> {
24052405
if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
24062406
|| !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
24072407
{
2408+
let mut snapshot_type = self.create_snapshot_for_diagnostic();
2409+
snapshot_type.bump(); // `:`
2410+
match snapshot_type.parse_ty() {
2411+
Err(inner_err) => {
2412+
inner_err.cancel();
2413+
}
2414+
Ok(ty) => {
2415+
let Err(mut err) = self.expected_one_of_not_found(&[], &[]) else {
2416+
return first_pat;
2417+
};
2418+
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
2419+
self.restore_snapshot(snapshot_type);
2420+
let span = first_pat.span.to(ty.span);
2421+
first_pat = self.mk_pat(span, PatKind::Wild);
2422+
err.emit();
2423+
}
2424+
}
24082425
return first_pat;
24092426
}
24102427
// The pattern looks like it might be a path with a `::` -> `:` typo:
24112428
// `match foo { bar:baz => {} }`
2412-
let span = self.token.span;
2429+
let colon_span = self.token.span;
24132430
// We only emit "unexpected `:`" error here if we can successfully parse the
24142431
// whole pattern correctly in that case.
2415-
let snapshot = self.create_snapshot_for_diagnostic();
2432+
let mut snapshot_pat = self.create_snapshot_for_diagnostic();
2433+
let mut snapshot_type = self.create_snapshot_for_diagnostic();
24162434

24172435
// Create error for "unexpected `:`".
24182436
match self.expected_one_of_not_found(&[], &[]) {
24192437
Err(mut err) => {
2420-
self.bump(); // Skip the `:`.
2421-
match self.parse_pat_no_top_alt(expected) {
2438+
// Skip the `:`.
2439+
snapshot_pat.bump();
2440+
snapshot_type.bump();
2441+
match snapshot_pat.parse_pat_no_top_alt(expected) {
24222442
Err(inner_err) => {
2423-
// Carry on as if we had not done anything, callers will emit a
2424-
// reasonable error.
24252443
inner_err.cancel();
2426-
err.cancel();
2427-
self.restore_snapshot(snapshot);
24282444
}
24292445
Ok(mut pat) => {
24302446
// We've parsed the rest of the pattern.
@@ -2488,22 +2504,33 @@ impl<'a> Parser<'a> {
24882504
_ => {}
24892505
}
24902506
if show_sugg {
2491-
err.span_suggestion(
2492-
span,
2507+
err.span_suggestion_verbose(
2508+
colon_span.until(self.look_ahead(1, |t| t.span)),
24932509
"maybe write a path separator here",
24942510
"::",
24952511
Applicability::MaybeIncorrect,
24962512
);
24972513
} else {
24982514
first_pat = self.mk_pat(new_span, PatKind::Wild);
24992515
}
2500-
err.emit();
2516+
self.restore_snapshot(snapshot_pat);
25012517
}
25022518
}
2519+
match snapshot_type.parse_ty() {
2520+
Err(inner_err) => {
2521+
inner_err.cancel();
2522+
}
2523+
Ok(ty) => {
2524+
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
2525+
self.restore_snapshot(snapshot_type);
2526+
let new_span = first_pat.span.to(ty.span);
2527+
first_pat = self.mk_pat(new_span, PatKind::Wild);
2528+
}
2529+
}
2530+
err.emit();
25032531
}
25042532
_ => {
25052533
// Carry on as if we had not done anything. This should be unreachable.
2506-
self.restore_snapshot(snapshot);
25072534
}
25082535
};
25092536
first_pat

compiler/rustc_parse_format/src/lib.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,13 @@ impl<'a> Iterator for Parser<'a> {
273273
);
274274
}
275275
} else {
276-
self.suggest_positional_arg_instead_of_captured_arg(arg);
276+
if let Some(&(_, maybe)) = self.cur.peek() {
277+
if maybe == '?' {
278+
self.suggest_format();
279+
} else {
280+
self.suggest_positional_arg_instead_of_captured_arg(arg);
281+
}
282+
}
277283
}
278284
Some(NextArgument(Box::new(arg)))
279285
}
@@ -832,6 +838,27 @@ impl<'a> Parser<'a> {
832838
if found { Some(cur) } else { None }
833839
}
834840

841+
fn suggest_format(&mut self) {
842+
if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
843+
let word = self.word();
844+
let _end = self.current_pos();
845+
let pos = self.to_span_index(pos);
846+
self.errors.insert(
847+
0,
848+
ParseError {
849+
description: "expected format parameter to occur after `:`".to_owned(),
850+
note: Some(
851+
format!("`?` comes after `:`, try `{}:{}` instead", word, "?").to_owned(),
852+
),
853+
label: "expected `?` to occur after `:`".to_owned(),
854+
span: pos.to(pos),
855+
secondary_label: None,
856+
should_be_replaced_with_positional_argument: false,
857+
},
858+
);
859+
}
860+
}
861+
835862
fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
836863
if let Some(end) = self.consume_pos('.') {
837864
let byte_pos = self.to_span_index(end);

library/core/benches/char/methods.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
use test::Bencher;
1+
use test::{black_box, Bencher};
22

33
const CHARS: [char; 9] = ['0', 'x', '2', '5', 'A', 'f', '7', '8', '9'];
44
const RADIX: [u32; 5] = [2, 8, 10, 16, 32];
55

66
#[bench]
77
fn bench_to_digit_radix_2(b: &mut Bencher) {
8-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(2)).min())
8+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(2)).min())
99
}
1010

1111
#[bench]
1212
fn bench_to_digit_radix_10(b: &mut Bencher) {
13-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(10)).min())
13+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(10)).min())
1414
}
1515

1616
#[bench]
1717
fn bench_to_digit_radix_16(b: &mut Bencher) {
18-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(16)).min())
18+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(16)).min())
1919
}
2020

2121
#[bench]
2222
fn bench_to_digit_radix_36(b: &mut Bencher) {
23-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(36)).min())
23+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(36)).min())
2424
}
2525

2626
#[bench]
@@ -31,47 +31,59 @@ fn bench_to_digit_radix_var(b: &mut Bencher) {
3131
.cycle()
3232
.zip(RADIX.iter().cycle())
3333
.take(10_000)
34-
.map(|(c, radix)| c.to_digit(*radix))
34+
.map(|(c, radix)| black_box(c).to_digit(*radix))
3535
.min()
3636
})
3737
}
3838

3939
#[bench]
4040
fn bench_to_ascii_uppercase(b: &mut Bencher) {
41-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_ascii_uppercase()).min())
41+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_ascii_uppercase()).min())
4242
}
4343

4444
#[bench]
4545
fn bench_to_ascii_lowercase(b: &mut Bencher) {
46-
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_ascii_lowercase()).min())
46+
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_ascii_lowercase()).min())
4747
}
4848

4949
#[bench]
5050
fn bench_ascii_mix_to_uppercase(b: &mut Bencher) {
51-
b.iter(|| (0..=255).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
51+
b.iter(|| {
52+
(0..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
53+
})
5254
}
5355

5456
#[bench]
5557
fn bench_ascii_mix_to_lowercase(b: &mut Bencher) {
56-
b.iter(|| (0..=255).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
58+
b.iter(|| {
59+
(0..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
60+
})
5761
}
5862

5963
#[bench]
6064
fn bench_ascii_char_to_uppercase(b: &mut Bencher) {
61-
b.iter(|| (0..=127).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
65+
b.iter(|| {
66+
(0..=127).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
67+
})
6268
}
6369

6470
#[bench]
6571
fn bench_ascii_char_to_lowercase(b: &mut Bencher) {
66-
b.iter(|| (0..=127).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
72+
b.iter(|| {
73+
(0..=127).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
74+
})
6775
}
6876

6977
#[bench]
7078
fn bench_non_ascii_char_to_uppercase(b: &mut Bencher) {
71-
b.iter(|| (128..=255).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
79+
b.iter(|| {
80+
(128..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
81+
})
7282
}
7383

7484
#[bench]
7585
fn bench_non_ascii_char_to_lowercase(b: &mut Bencher) {
76-
b.iter(|| (128..=255).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
86+
b.iter(|| {
87+
(128..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
88+
})
7789
}
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
use super::super::*;
22
use core::num::flt2dec::strategy::dragon::*;
33
use std::mem::MaybeUninit;
4-
use test::Bencher;
4+
use test::{black_box, Bencher};
55

66
#[bench]
77
fn bench_small_shortest(b: &mut Bencher) {
88
let decoded = decode_finite(3.141592f64);
99
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
1010
b.iter(|| {
11-
format_shortest(&decoded, &mut buf);
11+
format_shortest(black_box(&decoded), &mut buf);
1212
});
1313
}
1414

@@ -17,7 +17,7 @@ fn bench_big_shortest(b: &mut Bencher) {
1717
let decoded = decode_finite(f64::MAX);
1818
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
1919
b.iter(|| {
20-
format_shortest(&decoded, &mut buf);
20+
format_shortest(black_box(&decoded), &mut buf);
2121
});
2222
}
2323

@@ -26,7 +26,7 @@ fn bench_small_exact_3(b: &mut Bencher) {
2626
let decoded = decode_finite(3.141592f64);
2727
let mut buf = [MaybeUninit::new(0); 3];
2828
b.iter(|| {
29-
format_exact(&decoded, &mut buf, i16::MIN);
29+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
3030
});
3131
}
3232

@@ -35,7 +35,7 @@ fn bench_big_exact_3(b: &mut Bencher) {
3535
let decoded = decode_finite(f64::MAX);
3636
let mut buf = [MaybeUninit::new(0); 3];
3737
b.iter(|| {
38-
format_exact(&decoded, &mut buf, i16::MIN);
38+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
3939
});
4040
}
4141

@@ -44,7 +44,7 @@ fn bench_small_exact_12(b: &mut Bencher) {
4444
let decoded = decode_finite(3.141592f64);
4545
let mut buf = [MaybeUninit::new(0); 12];
4646
b.iter(|| {
47-
format_exact(&decoded, &mut buf, i16::MIN);
47+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
4848
});
4949
}
5050

@@ -53,7 +53,7 @@ fn bench_big_exact_12(b: &mut Bencher) {
5353
let decoded = decode_finite(f64::MAX);
5454
let mut buf = [MaybeUninit::new(0); 12];
5555
b.iter(|| {
56-
format_exact(&decoded, &mut buf, i16::MIN);
56+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
5757
});
5858
}
5959

@@ -62,7 +62,7 @@ fn bench_small_exact_inf(b: &mut Bencher) {
6262
let decoded = decode_finite(3.141592f64);
6363
let mut buf = [MaybeUninit::new(0); 1024];
6464
b.iter(|| {
65-
format_exact(&decoded, &mut buf, i16::MIN);
65+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
6666
});
6767
}
6868

@@ -71,6 +71,6 @@ fn bench_big_exact_inf(b: &mut Bencher) {
7171
let decoded = decode_finite(f64::MAX);
7272
let mut buf = [MaybeUninit::new(0); 1024];
7373
b.iter(|| {
74-
format_exact(&decoded, &mut buf, i16::MIN);
74+
format_exact(black_box(&decoded), &mut buf, i16::MIN);
7575
});
7676
}

0 commit comments

Comments
 (0)