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
This commit is contained in:
commit
7c46fb2111
@ -583,10 +583,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
let err = FnMutError {
|
||||
span: *span,
|
||||
ty_err: match output_ty.kind() {
|
||||
ty::Closure(_, _) => FnMutReturnTypeErr::ReturnClosure { span: *span },
|
||||
ty::Generator(def, ..) if self.infcx.tcx.generator_is_async(*def) => {
|
||||
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
|
||||
}
|
||||
_ if output_ty.contains_closure() => {
|
||||
FnMutReturnTypeErr::ReturnClosure { span: *span }
|
||||
}
|
||||
_ => FnMutReturnTypeErr::ReturnRef { span: *span },
|
||||
},
|
||||
};
|
||||
@ -997,7 +999,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diagnostic) {
|
||||
let map = self.infcx.tcx.hir();
|
||||
let body_id = map.body_owned_by(self.mir_def_id());
|
||||
let expr = &map.body(body_id).value;
|
||||
let expr = &map.body(body_id).value.peel_blocks();
|
||||
let mut closure_span = None::<rustc_span::Span>;
|
||||
match expr.kind {
|
||||
hir::ExprKind::MethodCall(.., args, _) => {
|
||||
@ -1012,20 +1014,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Block(blk, _) => {
|
||||
if let Some(expr) = blk.expr {
|
||||
// only when the block is a closure
|
||||
if let hir::ExprKind::Closure(hir::Closure {
|
||||
capture_clause: hir::CaptureBy::Ref,
|
||||
body,
|
||||
..
|
||||
}) = expr.kind
|
||||
{
|
||||
let body = map.body(*body);
|
||||
if !matches!(body.generator_kind, Some(hir::GeneratorKind::Async(..))) {
|
||||
closure_span = Some(expr.span.shrink_to_lo());
|
||||
}
|
||||
}
|
||||
hir::ExprKind::Closure(hir::Closure {
|
||||
capture_clause: hir::CaptureBy::Ref,
|
||||
body,
|
||||
..
|
||||
}) => {
|
||||
let body = map.body(*body);
|
||||
if !matches!(body.generator_kind, Some(hir::GeneratorKind::Async(..))) {
|
||||
closure_span = Some(expr.span.shrink_to_lo());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -2043,6 +2043,28 @@ impl<'tcx> Ty<'tcx> {
|
||||
cf.is_break()
|
||||
}
|
||||
|
||||
/// Checks whether a type recursively contains any closure
|
||||
///
|
||||
/// Example: `Option<[closure@file.rs:4:20]>` returns true
|
||||
pub fn contains_closure(self) -> bool {
|
||||
struct ContainsClosureVisitor;
|
||||
|
||||
impl<'tcx> TypeVisitor<'tcx> for ContainsClosureVisitor {
|
||||
type BreakTy = ();
|
||||
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
if let ty::Closure(_, _) = t.kind() {
|
||||
ControlFlow::Break(())
|
||||
} else {
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let cf = self.visit_with(&mut ContainsClosureVisitor);
|
||||
cf.is_break()
|
||||
}
|
||||
|
||||
/// Returns the type and mutability of `*ty`.
|
||||
///
|
||||
/// The parameter `explicit` indicates if this is an *explicit* dereference.
|
||||
|
@ -2405,26 +2405,42 @@ impl<'a> Parser<'a> {
|
||||
if !matches!(first_pat.kind, PatKind::Ident(_, _, None) | PatKind::Path(..))
|
||||
|| !self.look_ahead(1, |token| token.is_ident() && !token.is_reserved_ident())
|
||||
{
|
||||
let mut snapshot_type = self.create_snapshot_for_diagnostic();
|
||||
snapshot_type.bump(); // `:`
|
||||
match snapshot_type.parse_ty() {
|
||||
Err(inner_err) => {
|
||||
inner_err.cancel();
|
||||
}
|
||||
Ok(ty) => {
|
||||
let Err(mut err) = self.expected_one_of_not_found(&[], &[]) else {
|
||||
return first_pat;
|
||||
};
|
||||
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
|
||||
self.restore_snapshot(snapshot_type);
|
||||
let span = first_pat.span.to(ty.span);
|
||||
first_pat = self.mk_pat(span, PatKind::Wild);
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
return first_pat;
|
||||
}
|
||||
// The pattern looks like it might be a path with a `::` -> `:` typo:
|
||||
// `match foo { bar:baz => {} }`
|
||||
let span = self.token.span;
|
||||
let colon_span = self.token.span;
|
||||
// We only emit "unexpected `:`" error here if we can successfully parse the
|
||||
// whole pattern correctly in that case.
|
||||
let snapshot = self.create_snapshot_for_diagnostic();
|
||||
let mut snapshot_pat = self.create_snapshot_for_diagnostic();
|
||||
let mut snapshot_type = self.create_snapshot_for_diagnostic();
|
||||
|
||||
// Create error for "unexpected `:`".
|
||||
match self.expected_one_of_not_found(&[], &[]) {
|
||||
Err(mut err) => {
|
||||
self.bump(); // Skip the `:`.
|
||||
match self.parse_pat_no_top_alt(expected) {
|
||||
// Skip the `:`.
|
||||
snapshot_pat.bump();
|
||||
snapshot_type.bump();
|
||||
match snapshot_pat.parse_pat_no_top_alt(expected) {
|
||||
Err(inner_err) => {
|
||||
// Carry on as if we had not done anything, callers will emit a
|
||||
// reasonable error.
|
||||
inner_err.cancel();
|
||||
err.cancel();
|
||||
self.restore_snapshot(snapshot);
|
||||
}
|
||||
Ok(mut pat) => {
|
||||
// We've parsed the rest of the pattern.
|
||||
@ -2488,8 +2504,8 @@ impl<'a> Parser<'a> {
|
||||
_ => {}
|
||||
}
|
||||
if show_sugg {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
err.span_suggestion_verbose(
|
||||
colon_span.until(self.look_ahead(1, |t| t.span)),
|
||||
"maybe write a path separator here",
|
||||
"::",
|
||||
Applicability::MaybeIncorrect,
|
||||
@ -2497,13 +2513,24 @@ impl<'a> Parser<'a> {
|
||||
} else {
|
||||
first_pat = self.mk_pat(new_span, PatKind::Wild);
|
||||
}
|
||||
err.emit();
|
||||
self.restore_snapshot(snapshot_pat);
|
||||
}
|
||||
}
|
||||
match snapshot_type.parse_ty() {
|
||||
Err(inner_err) => {
|
||||
inner_err.cancel();
|
||||
}
|
||||
Ok(ty) => {
|
||||
err.span_label(ty.span, "specifying the type of a pattern isn't supported");
|
||||
self.restore_snapshot(snapshot_type);
|
||||
let new_span = first_pat.span.to(ty.span);
|
||||
first_pat = self.mk_pat(new_span, PatKind::Wild);
|
||||
}
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
_ => {
|
||||
// Carry on as if we had not done anything. This should be unreachable.
|
||||
self.restore_snapshot(snapshot);
|
||||
}
|
||||
};
|
||||
first_pat
|
||||
|
@ -273,7 +273,13 @@ impl<'a> Iterator for Parser<'a> {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
self.suggest_positional_arg_instead_of_captured_arg(arg);
|
||||
if let Some(&(_, maybe)) = self.cur.peek() {
|
||||
if maybe == '?' {
|
||||
self.suggest_format();
|
||||
} else {
|
||||
self.suggest_positional_arg_instead_of_captured_arg(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(NextArgument(Box::new(arg)))
|
||||
}
|
||||
@ -832,6 +838,27 @@ impl<'a> Parser<'a> {
|
||||
if found { Some(cur) } else { None }
|
||||
}
|
||||
|
||||
fn suggest_format(&mut self) {
|
||||
if let (Some(pos), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
|
||||
let word = self.word();
|
||||
let _end = self.current_pos();
|
||||
let pos = self.to_span_index(pos);
|
||||
self.errors.insert(
|
||||
0,
|
||||
ParseError {
|
||||
description: "expected format parameter to occur after `:`".to_owned(),
|
||||
note: Some(
|
||||
format!("`?` comes after `:`, try `{}:{}` instead", word, "?").to_owned(),
|
||||
),
|
||||
label: "expected `?` to occur after `:`".to_owned(),
|
||||
span: pos.to(pos),
|
||||
secondary_label: None,
|
||||
should_be_replaced_with_positional_argument: false,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: Argument<'a>) {
|
||||
if let Some(end) = self.consume_pos('.') {
|
||||
let byte_pos = self.to_span_index(end);
|
||||
|
@ -1,26 +1,26 @@
|
||||
use test::Bencher;
|
||||
use test::{black_box, Bencher};
|
||||
|
||||
const CHARS: [char; 9] = ['0', 'x', '2', '5', 'A', 'f', '7', '8', '9'];
|
||||
const RADIX: [u32; 5] = [2, 8, 10, 16, 32];
|
||||
|
||||
#[bench]
|
||||
fn bench_to_digit_radix_2(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(2)).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(2)).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_to_digit_radix_10(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(10)).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(10)).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_to_digit_radix_16(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(16)).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(16)).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_to_digit_radix_36(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_digit(36)).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_digit(36)).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@ -31,47 +31,59 @@ fn bench_to_digit_radix_var(b: &mut Bencher) {
|
||||
.cycle()
|
||||
.zip(RADIX.iter().cycle())
|
||||
.take(10_000)
|
||||
.map(|(c, radix)| c.to_digit(*radix))
|
||||
.map(|(c, radix)| black_box(c).to_digit(*radix))
|
||||
.min()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_to_ascii_uppercase(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_ascii_uppercase()).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_ascii_uppercase()).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_to_ascii_lowercase(b: &mut Bencher) {
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| c.to_ascii_lowercase()).min())
|
||||
b.iter(|| CHARS.iter().cycle().take(10_000).map(|c| black_box(c).to_ascii_lowercase()).min())
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_ascii_mix_to_uppercase(b: &mut Bencher) {
|
||||
b.iter(|| (0..=255).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
|
||||
b.iter(|| {
|
||||
(0..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_ascii_mix_to_lowercase(b: &mut Bencher) {
|
||||
b.iter(|| (0..=255).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
|
||||
b.iter(|| {
|
||||
(0..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_ascii_char_to_uppercase(b: &mut Bencher) {
|
||||
b.iter(|| (0..=127).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
|
||||
b.iter(|| {
|
||||
(0..=127).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_ascii_char_to_lowercase(b: &mut Bencher) {
|
||||
b.iter(|| (0..=127).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
|
||||
b.iter(|| {
|
||||
(0..=127).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_non_ascii_char_to_uppercase(b: &mut Bencher) {
|
||||
b.iter(|| (128..=255).cycle().take(10_000).map(|b| char::from(b).to_uppercase()).count())
|
||||
b.iter(|| {
|
||||
(128..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_uppercase()).count()
|
||||
})
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn bench_non_ascii_char_to_lowercase(b: &mut Bencher) {
|
||||
b.iter(|| (128..=255).cycle().take(10_000).map(|b| char::from(b).to_lowercase()).count())
|
||||
b.iter(|| {
|
||||
(128..=255).cycle().take(10_000).map(|b| black_box(char::from(b)).to_lowercase()).count()
|
||||
})
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
use super::super::*;
|
||||
use core::num::flt2dec::strategy::dragon::*;
|
||||
use std::mem::MaybeUninit;
|
||||
use test::Bencher;
|
||||
use test::{black_box, Bencher};
|
||||
|
||||
#[bench]
|
||||
fn bench_small_shortest(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
|
||||
b.iter(|| {
|
||||
format_shortest(&decoded, &mut buf);
|
||||
format_shortest(black_box(&decoded), &mut buf);
|
||||
});
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ fn bench_big_shortest(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
|
||||
b.iter(|| {
|
||||
format_shortest(&decoded, &mut buf);
|
||||
format_shortest(black_box(&decoded), &mut buf);
|
||||
});
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ fn bench_small_exact_3(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 3];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ fn bench_big_exact_3(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 3];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ fn bench_small_exact_12(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 12];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ fn bench_big_exact_12(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 12];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ fn bench_small_exact_inf(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 1024];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -71,6 +71,6 @@ fn bench_big_exact_inf(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 1024];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::super::*;
|
||||
use core::num::flt2dec::strategy::grisu::*;
|
||||
use std::mem::MaybeUninit;
|
||||
use test::Bencher;
|
||||
use test::{black_box, Bencher};
|
||||
|
||||
pub fn decode_finite<T: DecodableFloat>(v: T) -> Decoded {
|
||||
match decode(v).1 {
|
||||
@ -15,7 +15,7 @@ fn bench_small_shortest(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
|
||||
b.iter(|| {
|
||||
format_shortest(&decoded, &mut buf);
|
||||
format_shortest(black_box(&decoded), &mut buf);
|
||||
});
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ fn bench_big_shortest(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); MAX_SIG_DIGITS];
|
||||
b.iter(|| {
|
||||
format_shortest(&decoded, &mut buf);
|
||||
format_shortest(black_box(&decoded), &mut buf);
|
||||
});
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ fn bench_small_exact_3(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 3];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ fn bench_big_exact_3(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 3];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ fn bench_small_exact_12(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 12];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ fn bench_big_exact_12(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 12];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ fn bench_small_exact_inf(b: &mut Bencher) {
|
||||
let decoded = decode_finite(3.141592f64);
|
||||
let mut buf = [MaybeUninit::new(0); 1024];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
||||
@ -78,6 +78,6 @@ fn bench_big_exact_inf(b: &mut Bencher) {
|
||||
let decoded = decode_finite(f64::MAX);
|
||||
let mut buf = [MaybeUninit::new(0); 1024];
|
||||
b.iter(|| {
|
||||
format_exact(&decoded, &mut buf, i16::MIN);
|
||||
format_exact(black_box(&decoded), &mut buf, i16::MIN);
|
||||
});
|
||||
}
|
||||
|
@ -19,18 +19,18 @@ import shutil
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import ClassVar, List
|
||||
from typing import ClassVar, List, Optional
|
||||
|
||||
|
||||
@dataclass
|
||||
class TestEnvironment:
|
||||
rust_dir: str
|
||||
sdk_dir: str
|
||||
target_arch: str
|
||||
package_server_pid: int = None
|
||||
emu_addr: str = None
|
||||
libstd_name: str = None
|
||||
libtest_name: str = None
|
||||
target: str
|
||||
package_server_pid: Optional[int] = None
|
||||
emu_addr: Optional[str] = None
|
||||
libstd_name: Optional[str] = None
|
||||
libtest_name: Optional[str] = None
|
||||
verbose: bool = False
|
||||
|
||||
@staticmethod
|
||||
@ -40,6 +40,15 @@ class TestEnvironment:
|
||||
return os.path.abspath(tmp_dir)
|
||||
return os.path.join(os.path.dirname(__file__), "tmp~")
|
||||
|
||||
@staticmethod
|
||||
def triple_to_arch(triple):
|
||||
if "x86_64" in triple:
|
||||
return "x64"
|
||||
elif "aarch64" in triple:
|
||||
return "arm64"
|
||||
else:
|
||||
raise Exception(f"Unrecognized target triple {triple}")
|
||||
|
||||
@classmethod
|
||||
def env_file_path(cls):
|
||||
return os.path.join(cls.tmp_dir(), "test_env.json")
|
||||
@ -49,7 +58,7 @@ class TestEnvironment:
|
||||
return cls(
|
||||
os.path.abspath(args.rust),
|
||||
os.path.abspath(args.sdk),
|
||||
args.target_arch,
|
||||
args.target,
|
||||
verbose=args.verbose,
|
||||
)
|
||||
|
||||
@ -60,7 +69,7 @@ class TestEnvironment:
|
||||
return cls(
|
||||
test_env["rust_dir"],
|
||||
test_env["sdk_dir"],
|
||||
test_env["target_arch"],
|
||||
test_env["target"],
|
||||
libstd_name=test_env["libstd_name"],
|
||||
libtest_name=test_env["libtest_name"],
|
||||
emu_addr=test_env["emu_addr"],
|
||||
@ -68,13 +77,6 @@ class TestEnvironment:
|
||||
verbose=test_env["verbose"],
|
||||
)
|
||||
|
||||
def image_name(self):
|
||||
if self.target_arch == "x64":
|
||||
return "qemu-x64"
|
||||
if self.target_arch == "arm64":
|
||||
return "qemu-arm64"
|
||||
raise Exception(f"Unrecognized target architecture {self.target_arch}")
|
||||
|
||||
def write_to_file(self):
|
||||
with open(self.env_file_path(), "w", encoding="utf-8") as f:
|
||||
f.write(json.dumps(self.__dict__))
|
||||
@ -108,13 +110,6 @@ class TestEnvironment:
|
||||
def repo_dir(self):
|
||||
return os.path.join(self.tmp_dir(), self.TEST_REPO_NAME)
|
||||
|
||||
def rustlib_dir(self):
|
||||
if self.target_arch == "x64":
|
||||
return "x86_64-unknown-fuchsia"
|
||||
if self.target_arch == "arm64":
|
||||
return "aarch64-unknown-fuchsia"
|
||||
raise Exception(f"Unrecognized target architecture {self.target_arch}")
|
||||
|
||||
def libs_dir(self):
|
||||
return os.path.join(
|
||||
self.rust_dir,
|
||||
@ -125,7 +120,7 @@ class TestEnvironment:
|
||||
return os.path.join(
|
||||
self.libs_dir(),
|
||||
"rustlib",
|
||||
self.rustlib_dir(),
|
||||
self.target,
|
||||
"lib",
|
||||
)
|
||||
|
||||
@ -384,7 +379,7 @@ class TestEnvironment:
|
||||
"--emulator-log",
|
||||
self.emulator_log_path(),
|
||||
"--image-name",
|
||||
self.image_name(),
|
||||
"qemu-" + self.triple_to_arch(self.target),
|
||||
],
|
||||
stdout=self.subprocess_output(),
|
||||
stderr=self.subprocess_output(),
|
||||
@ -642,11 +637,11 @@ class TestEnvironment:
|
||||
package_dir=package_dir,
|
||||
package_name=package_name,
|
||||
rust_dir=self.rust_dir,
|
||||
rustlib_dir=self.rustlib_dir(),
|
||||
rustlib_dir=self.target,
|
||||
sdk_dir=self.sdk_dir,
|
||||
libstd_name=self.libstd_name,
|
||||
libtest_name=self.libtest_name,
|
||||
target_arch=self.target_arch,
|
||||
target_arch=self.triple_to_arch(self.target),
|
||||
)
|
||||
)
|
||||
for shared_lib in shared_libs:
|
||||
@ -969,8 +964,8 @@ def main():
|
||||
action="store_true",
|
||||
)
|
||||
start_parser.add_argument(
|
||||
"--target-arch",
|
||||
help="the architecture of the image to test",
|
||||
"--target",
|
||||
help="the target platform to test",
|
||||
required=True,
|
||||
)
|
||||
start_parser.set_defaults(func=start)
|
||||
|
@ -697,7 +697,7 @@ test environment with:
|
||||
src/ci/docker/scripts/fuchsia-test-runner.py start
|
||||
--rust ${RUST_SRC_PATH}/install
|
||||
--sdk ${SDK_PATH}
|
||||
--target-arch {x64,arm64}
|
||||
--target-triple {x86_64-unknown-fuchsia|aarch64-unknown-fuchsia}
|
||||
```
|
||||
|
||||
Where `${RUST_SRC_PATH}/install` is the `prefix` set in `config.toml` and
|
||||
|
16
tests/ui/async-await/future-sizes/future-as-arg.rs
Normal file
16
tests/ui/async-await/future-sizes/future-as-arg.rs
Normal file
@ -0,0 +1,16 @@
|
||||
// edition: 2021
|
||||
// run-pass
|
||||
|
||||
async fn test(_arg: [u8; 16]) {}
|
||||
|
||||
async fn use_future(fut: impl std::future::Future<Output = ()>) {
|
||||
fut.await
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let actual = std::mem::size_of_val(
|
||||
&use_future(use_future(use_future(use_future(use_future(test([0; 16])))))));
|
||||
// Not using an exact number in case it slightly changes over different commits
|
||||
let expected = 550;
|
||||
assert!(actual > expected, "expected: >{expected}, actual: {actual}");
|
||||
}
|
18
tests/ui/async-await/future-sizes/large-arg.rs
Normal file
18
tests/ui/async-await/future-sizes/large-arg.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// compile-flags: -Z print-type-sizes --crate-type=lib
|
||||
// edition: 2021
|
||||
// build-pass
|
||||
// ignore-pass
|
||||
|
||||
pub async fn test() {
|
||||
let _ = a([0u8; 1024]).await;
|
||||
}
|
||||
|
||||
pub async fn a<T>(t: T) -> T {
|
||||
b(t).await
|
||||
}
|
||||
async fn b<T>(t: T) -> T {
|
||||
c(t).await
|
||||
}
|
||||
async fn c<T>(t: T) -> T {
|
||||
t
|
||||
}
|
60
tests/ui/async-await/future-sizes/large-arg.stdout
Normal file
60
tests/ui/async-await/future-sizes/large-arg.stdout
Normal file
@ -0,0 +1,60 @@
|
||||
print-type-size type: `[async fn body@$DIR/large-arg.rs:6:21: 8:2]`: 3076 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Suspend0`: 3075 bytes
|
||||
print-type-size local `.__awaitee`: 3075 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Unresumed`: 0 bytes
|
||||
print-type-size variant `Returned`: 0 bytes
|
||||
print-type-size variant `Panicked`: 0 bytes
|
||||
print-type-size type: `[async fn body@$DIR/large-arg.rs:10:30: 12:2]`: 3075 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Suspend0`: 3074 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size local `.__awaitee`: 2050 bytes
|
||||
print-type-size variant `Unresumed`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Returned`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Panicked`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/large-arg.rs:10:30: 12:2]>`: 3075 bytes, alignment: 1 bytes
|
||||
print-type-size field `.value`: 3075 bytes
|
||||
print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/large-arg.rs:10:30: 12:2]>`: 3075 bytes, alignment: 1 bytes
|
||||
print-type-size variant `MaybeUninit`: 3075 bytes
|
||||
print-type-size field `.uninit`: 0 bytes
|
||||
print-type-size field `.value`: 3075 bytes
|
||||
print-type-size type: `[async fn body@$DIR/large-arg.rs:13:26: 15:2]`: 2050 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Suspend0`: 2049 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size local `.__awaitee`: 1025 bytes
|
||||
print-type-size variant `Unresumed`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Returned`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Panicked`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/large-arg.rs:13:26: 15:2]>`: 2050 bytes, alignment: 1 bytes
|
||||
print-type-size field `.value`: 2050 bytes
|
||||
print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/large-arg.rs:13:26: 15:2]>`: 2050 bytes, alignment: 1 bytes
|
||||
print-type-size variant `MaybeUninit`: 2050 bytes
|
||||
print-type-size field `.uninit`: 0 bytes
|
||||
print-type-size field `.value`: 2050 bytes
|
||||
print-type-size type: `[async fn body@$DIR/large-arg.rs:16:26: 18:2]`: 1025 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Unresumed`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Returned`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size variant `Panicked`: 1024 bytes
|
||||
print-type-size upvar `.t`: 1024 bytes, offset: 0 bytes, alignment: 1 bytes
|
||||
print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/large-arg.rs:16:26: 18:2]>`: 1025 bytes, alignment: 1 bytes
|
||||
print-type-size field `.value`: 1025 bytes
|
||||
print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/large-arg.rs:16:26: 18:2]>`: 1025 bytes, alignment: 1 bytes
|
||||
print-type-size variant `MaybeUninit`: 1025 bytes
|
||||
print-type-size field `.uninit`: 0 bytes
|
||||
print-type-size field `.value`: 1025 bytes
|
||||
print-type-size type: `std::task::Poll<[u8; 1024]>`: 1025 bytes, alignment: 1 bytes
|
||||
print-type-size discriminant: 1 bytes
|
||||
print-type-size variant `Ready`: 1024 bytes
|
||||
print-type-size field `.0`: 1024 bytes
|
||||
print-type-size variant `Pending`: 0 bytes
|
@ -0,0 +1,26 @@
|
||||
// run-rustfix
|
||||
#![allow(dead_code, path_statements)]
|
||||
fn foo1(s: &str) -> impl Iterator<Item = String> + '_ {
|
||||
None.into_iter()
|
||||
.flat_map(move |()| s.chars().map(move |c| format!("{}{}", c, s)))
|
||||
//~^ ERROR captured variable cannot escape `FnMut` closure body
|
||||
//~| HELP consider adding 'move' keyword before the nested closure
|
||||
}
|
||||
|
||||
fn foo2(s: &str) -> impl Sized + '_ {
|
||||
move |()| s.chars().map(move |c| format!("{}{}", c, s))
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
//~| HELP consider adding 'move' keyword before the nested closure
|
||||
}
|
||||
|
||||
pub struct X;
|
||||
pub fn foo3<'a>(
|
||||
bar: &'a X,
|
||||
) -> impl Iterator<Item = ()> + 'a {
|
||||
Some(()).iter().flat_map(move |()| {
|
||||
Some(()).iter().map(move |()| { bar; }) //~ ERROR captured variable cannot escape
|
||||
//~^ HELP consider adding 'move' keyword before the nested closure
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,3 +1,5 @@
|
||||
// run-rustfix
|
||||
#![allow(dead_code, path_statements)]
|
||||
fn foo1(s: &str) -> impl Iterator<Item = String> + '_ {
|
||||
None.into_iter()
|
||||
.flat_map(move |()| s.chars().map(|c| format!("{}{}", c, s)))
|
||||
@ -11,4 +13,14 @@ fn foo2(s: &str) -> impl Sized + '_ {
|
||||
//~| HELP consider adding 'move' keyword before the nested closure
|
||||
}
|
||||
|
||||
pub struct X;
|
||||
pub fn foo3<'a>(
|
||||
bar: &'a X,
|
||||
) -> impl Iterator<Item = ()> + 'a {
|
||||
Some(()).iter().flat_map(move |()| {
|
||||
Some(()).iter().map(|()| { bar; }) //~ ERROR captured variable cannot escape
|
||||
//~^ HELP consider adding 'move' keyword before the nested closure
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: captured variable cannot escape `FnMut` closure body
|
||||
--> $DIR/issue-95079-missing-move-in-nested-closure.rs:3:29
|
||||
--> $DIR/issue-95079-missing-move-in-nested-closure.rs:5:29
|
||||
|
|
||||
LL | fn foo1(s: &str) -> impl Iterator<Item = String> + '_ {
|
||||
| - variable defined here
|
||||
@ -7,7 +7,7 @@ LL | None.into_iter()
|
||||
LL | .flat_map(move |()| s.chars().map(|c| format!("{}{}", c, s)))
|
||||
| - -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| | |
|
||||
| | returns a reference to a captured variable which escapes the closure body
|
||||
| | returns a closure that contains a reference to a captured variable, which then escapes the closure body
|
||||
| | variable captured here
|
||||
| inferred to be a `FnMut` closure
|
||||
|
|
||||
@ -19,12 +19,12 @@ LL | .flat_map(move |()| s.chars().map(move |c| format!("{}{}", c, s)))
|
||||
| ++++
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/issue-95079-missing-move-in-nested-closure.rs:9:15
|
||||
--> $DIR/issue-95079-missing-move-in-nested-closure.rs:11:15
|
||||
|
|
||||
LL | move |()| s.chars().map(|c| format!("{}{}", c, s))
|
||||
| --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
|
||||
| | |
|
||||
| | return type of closure `Map<Chars<'_>, [closure@$DIR/issue-95079-missing-move-in-nested-closure.rs:9:29: 9:32]>` contains a lifetime `'2`
|
||||
| | return type of closure `Map<Chars<'_>, [closure@$DIR/issue-95079-missing-move-in-nested-closure.rs:11:29: 11:32]>` contains a lifetime `'2`
|
||||
| lifetime `'1` represents this closure's body
|
||||
|
|
||||
= note: closure implements `Fn`, so references to captured variables can't escape the closure
|
||||
@ -33,5 +33,26 @@ help: consider adding 'move' keyword before the nested closure
|
||||
LL | move |()| s.chars().map(move |c| format!("{}{}", c, s))
|
||||
| ++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: captured variable cannot escape `FnMut` closure body
|
||||
--> $DIR/issue-95079-missing-move-in-nested-closure.rs:21:9
|
||||
|
|
||||
LL | bar: &'a X,
|
||||
| --- variable defined here
|
||||
LL | ) -> impl Iterator<Item = ()> + 'a {
|
||||
LL | Some(()).iter().flat_map(move |()| {
|
||||
| - inferred to be a `FnMut` closure
|
||||
LL | Some(()).iter().map(|()| { bar; })
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^
|
||||
| | |
|
||||
| | variable captured here
|
||||
| returns a closure that contains a reference to a captured variable, which then escapes the closure body
|
||||
|
|
||||
= note: `FnMut` closures only have access to their captured variables while they are executing...
|
||||
= note: ...therefore, they cannot allow references to captured variables to escape
|
||||
help: consider adding 'move' keyword before the nested closure
|
||||
|
|
||||
LL | Some(()).iter().map(move |()| { bar; })
|
||||
| ++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
15
tests/ui/fmt/format-string-wrong-order.rs
Normal file
15
tests/ui/fmt/format-string-wrong-order.rs
Normal file
@ -0,0 +1,15 @@
|
||||
fn main() {
|
||||
let bar = 3;
|
||||
format!("{?:}", bar);
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
format!("{?:bar}");
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
format!("{?:?}", bar);
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
format!("{??}", bar);
|
||||
//~^ ERROR invalid format string: expected `'}'`, found `'?'`
|
||||
format!("{?;bar}");
|
||||
//~^ ERROR invalid format string: expected `'}'`, found `'?'`
|
||||
format!("{?:#?}", bar);
|
||||
//~^ ERROR invalid format string: expected format parameter to occur after `:`
|
||||
}
|
54
tests/ui/fmt/format-string-wrong-order.stderr
Normal file
54
tests/ui/fmt/format-string-wrong-order.stderr
Normal file
@ -0,0 +1,54 @@
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
--> $DIR/format-string-wrong-order.rs:3:15
|
||||
|
|
||||
LL | format!("{?:}", bar);
|
||||
| ^ expected `?` to occur after `:` in format string
|
||||
|
|
||||
= note: `?` comes after `:`, try `:?` instead
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
--> $DIR/format-string-wrong-order.rs:5:15
|
||||
|
|
||||
LL | format!("{?:bar}");
|
||||
| ^ expected `?` to occur after `:` in format string
|
||||
|
|
||||
= note: `?` comes after `:`, try `bar:?` instead
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
--> $DIR/format-string-wrong-order.rs:7:15
|
||||
|
|
||||
LL | format!("{?:?}", bar);
|
||||
| ^ expected `?` to occur after `:` in format string
|
||||
|
|
||||
= note: `?` comes after `:`, try `:?` instead
|
||||
|
||||
error: invalid format string: expected `'}'`, found `'?'`
|
||||
--> $DIR/format-string-wrong-order.rs:9:15
|
||||
|
|
||||
LL | format!("{??}", bar);
|
||||
| -^ expected `}` in format string
|
||||
| |
|
||||
| because of this opening brace
|
||||
|
|
||||
= note: if you intended to print `{`, you can escape it using `{{`
|
||||
|
||||
error: invalid format string: expected `'}'`, found `'?'`
|
||||
--> $DIR/format-string-wrong-order.rs:11:15
|
||||
|
|
||||
LL | format!("{?;bar}");
|
||||
| -^ expected `}` in format string
|
||||
| |
|
||||
| because of this opening brace
|
||||
|
|
||||
= note: if you intended to print `{`, you can escape it using `{{`
|
||||
|
||||
error: invalid format string: expected format parameter to occur after `:`
|
||||
--> $DIR/format-string-wrong-order.rs:13:15
|
||||
|
|
||||
LL | format!("{?:#?}", bar);
|
||||
| ^ expected `?` to occur after `:` in format string
|
||||
|
|
||||
= note: `?` comes after `:`, try `:?` instead
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
@ -68,7 +68,6 @@ fn main() {
|
||||
Foo:Bar::Baz => {}
|
||||
//~^ ERROR: expected one of
|
||||
//~| HELP: maybe write a path separator here
|
||||
//~| ERROR: failed to resolve: `Bar` is a variant, not a module
|
||||
}
|
||||
match myfoo {
|
||||
Foo::Bar => {}
|
||||
|
@ -2,89 +2,118 @@ error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:17:12
|
||||
|
|
||||
LL | Foo:Bar => {}
|
||||
| ^
|
||||
| ^--- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | Foo::Bar => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `{`, or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:23:17
|
||||
|
|
||||
LL | qux::Foo:Bar => {}
|
||||
| ^
|
||||
| ^--- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of 8 possible tokens
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | qux::Foo::Bar => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:29:12
|
||||
|
|
||||
LL | qux:Foo::Baz => {}
|
||||
| ^
|
||||
| ^-------- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | qux::Foo::Baz => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:35:12
|
||||
|
|
||||
LL | qux: Foo::Baz if true => {}
|
||||
| ^
|
||||
| ^ -------- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | qux::Foo::Baz if true => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:40:15
|
||||
|
|
||||
LL | if let Foo:Bar = f() {
|
||||
| ^
|
||||
| ^--- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | if let Foo::Bar = f() {
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:48:16
|
||||
|
|
||||
LL | ref qux: Foo::Baz => {}
|
||||
| ^
|
||||
| ^ -------- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | ref qux::Foo::Baz => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:57:16
|
||||
|
|
||||
LL | mut qux: Foo::Baz => {}
|
||||
| ^
|
||||
| ^ -------- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | mut qux::Foo::Baz => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:68:12
|
||||
|
|
||||
LL | Foo:Bar::Baz => {}
|
||||
| ^
|
||||
| ^-------- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | Foo::Bar::Baz => {}
|
||||
| ~~
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:75:12
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:74:12
|
||||
|
|
||||
LL | Foo:Bar => {}
|
||||
| ^
|
||||
| ^--- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
| help: maybe write a path separator here: `::`
|
||||
|
||||
error[E0433]: failed to resolve: `Bar` is a variant, not a module
|
||||
--> $DIR/issue-87086-colon-path-sep.rs:68:13
|
||||
|
|
||||
LL | Foo:Bar::Baz => {}
|
||||
| ^^^ `Bar` is a variant, not a module
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | Foo::Bar => {}
|
||||
| ~~
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0433`.
|
||||
|
16
tests/ui/parser/type-ascription-in-pattern.rs
Normal file
16
tests/ui/parser/type-ascription-in-pattern.rs
Normal file
@ -0,0 +1,16 @@
|
||||
fn foo(x: bool) -> i32 {
|
||||
match x {
|
||||
x: i32 => x, //~ ERROR expected
|
||||
//~^ ERROR mismatched types
|
||||
true => 42.,
|
||||
false => 0.333,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
match foo(true) {
|
||||
42: i32 => (), //~ ERROR expected
|
||||
_: f64 => (), //~ ERROR expected
|
||||
x: i32 => (), //~ ERROR expected
|
||||
}
|
||||
}
|
54
tests/ui/parser/type-ascription-in-pattern.stderr
Normal file
54
tests/ui/parser/type-ascription-in-pattern.stderr
Normal file
@ -0,0 +1,54 @@
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/type-ascription-in-pattern.rs:3:10
|
||||
|
|
||||
LL | x: i32 => x,
|
||||
| ^ --- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | x::i32 => x,
|
||||
| ~~
|
||||
|
||||
error: expected one of `...`, `..=`, `..`, or `|`, found `:`
|
||||
--> $DIR/type-ascription-in-pattern.rs:12:11
|
||||
|
|
||||
LL | 42: i32 => (),
|
||||
| ^ --- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `...`, `..=`, `..`, or `|`
|
||||
|
||||
error: expected `|`, found `:`
|
||||
--> $DIR/type-ascription-in-pattern.rs:13:10
|
||||
|
|
||||
LL | _: f64 => (),
|
||||
| ^ --- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected `|`
|
||||
|
||||
error: expected one of `@` or `|`, found `:`
|
||||
--> $DIR/type-ascription-in-pattern.rs:14:10
|
||||
|
|
||||
LL | x: i32 => (),
|
||||
| ^ --- specifying the type of a pattern isn't supported
|
||||
| |
|
||||
| expected one of `@` or `|`
|
||||
|
|
||||
help: maybe write a path separator here
|
||||
|
|
||||
LL | x::i32 => (),
|
||||
| ~~
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/type-ascription-in-pattern.rs:3:19
|
||||
|
|
||||
LL | fn foo(x: bool) -> i32 {
|
||||
| --- expected `i32` because of return type
|
||||
LL | match x {
|
||||
LL | x: i32 => x,
|
||||
| ^ expected `i32`, found `bool`
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
x
Reference in New Issue
Block a user