mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 00:03:43 +00:00
Auto merge of #81889 - m-ou-se:rollup-k63log3, r=m-ou-se
Rollup of 9 pull requests Successful merges: - #71531 (Move treat err as bug tests to ui) - #81356 (libtest: allow multiple filters) - #81735 (faster few span methods) - #81779 (improve error message for disallowed ptr-to-int casts in const eval) - #81817 (Add option to emit compiler stderr per bitwidth.) - #81828 (parse_format: treat r" as a literal) - #81840 (fix formatting of std::iter::Map) - #81861 (Show MIR bytes separately in -Zmeta-stats output) - #81865 (Clean up weird Option mapping) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
0fc6756b42
@ -572,10 +572,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
|
||||
let tcx = self.tcx;
|
||||
|
||||
// Encode MIR.
|
||||
i = self.position();
|
||||
self.encode_mir();
|
||||
let mir_bytes = self.position() - i;
|
||||
|
||||
// Encode the items.
|
||||
i = self.position();
|
||||
self.encode_def_ids();
|
||||
self.encode_mir();
|
||||
self.encode_info_for_items();
|
||||
let item_bytes = self.position() - i;
|
||||
|
||||
@ -700,6 +704,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
|
||||
println!(" def-path table bytes: {}", def_path_table_bytes);
|
||||
println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
|
||||
println!(" mir bytes: {}", mir_bytes);
|
||||
println!(" item bytes: {}", item_bytes);
|
||||
println!(" table bytes: {}", tables_bytes);
|
||||
println!(" hygiene bytes: {}", hygiene_bytes);
|
||||
|
@ -16,6 +16,7 @@ use crate::interpret::{
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ConstEvalErrKind {
|
||||
NeedsRfc(String),
|
||||
PtrToIntCast,
|
||||
ConstAccessesStatic,
|
||||
ModifiedGlobal,
|
||||
AssertFailure(AssertKind<ConstInt>),
|
||||
@ -39,6 +40,12 @@ impl fmt::Display for ConstEvalErrKind {
|
||||
NeedsRfc(ref msg) => {
|
||||
write!(f, "\"{}\" needs an rfc before being allowed inside constants", msg)
|
||||
}
|
||||
PtrToIntCast => {
|
||||
write!(
|
||||
f,
|
||||
"cannot cast pointer to integer because it was not created by cast from integer"
|
||||
)
|
||||
}
|
||||
ConstAccessesStatic => write!(f, "constant accesses static"),
|
||||
ModifiedGlobal => {
|
||||
write!(f, "modifying a static's initial value from another static's initializer")
|
||||
|
@ -352,7 +352,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||
}
|
||||
|
||||
fn ptr_to_int(_mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer) -> InterpResult<'tcx, u64> {
|
||||
Err(ConstEvalErrKind::NeedsRfc("pointer-to-integer cast".to_string()).into())
|
||||
Err(ConstEvalErrKind::PtrToIntCast.into())
|
||||
}
|
||||
|
||||
fn binary_ptr_op(
|
||||
|
@ -730,7 +730,7 @@ fn find_skips_from_snippet(
|
||||
str_style: Option<usize>,
|
||||
) -> (Vec<usize>, bool) {
|
||||
let snippet = match snippet {
|
||||
Some(ref s) if s.starts_with('"') || s.starts_with("r#") => s,
|
||||
Some(ref s) if s.starts_with('"') || s.starts_with("r\"") || s.starts_with("r#") => s,
|
||||
_ => return (vec![], false),
|
||||
};
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#![feature(nll)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(option_expect_none)]
|
||||
#![feature(str_split_once)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
@ -539,7 +539,7 @@ impl SourceMap {
|
||||
|
||||
pub fn is_line_before_span_empty(&self, sp: Span) -> bool {
|
||||
match self.span_to_prev_source(sp) {
|
||||
Ok(s) => s.split('\n').last().map_or(false, |l| l.trim_start().is_empty()),
|
||||
Ok(s) => s.rsplit_once('\n').unwrap_or(("", &s)).1.trim_start().is_empty(),
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
@ -632,10 +632,11 @@ impl SourceMap {
|
||||
pub fn span_to_margin(&self, sp: Span) -> Option<usize> {
|
||||
match self.span_to_prev_source(sp) {
|
||||
Err(_) => None,
|
||||
Ok(source) => source
|
||||
.split('\n')
|
||||
.last()
|
||||
.map(|last_line| last_line.len() - last_line.trim_start().len()),
|
||||
Ok(source) => {
|
||||
let last_line = source.rsplit_once('\n').unwrap_or(("", &source)).1;
|
||||
|
||||
Some(last_line.len() - last_line.trim_start().len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -651,7 +652,7 @@ impl SourceMap {
|
||||
pub fn span_extend_to_prev_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
|
||||
if let Ok(prev_source) = self.span_to_prev_source(sp) {
|
||||
let prev_source = prev_source.rsplit(c).next().unwrap_or("");
|
||||
if !prev_source.is_empty() && (!prev_source.contains('\n') || accept_newlines) {
|
||||
if !prev_source.is_empty() && (accept_newlines || !prev_source.contains('\n')) {
|
||||
return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
|
||||
}
|
||||
}
|
||||
@ -673,7 +674,7 @@ impl SourceMap {
|
||||
let prev_source = prev_source.rsplit(&pat).next().unwrap_or("").trim_start();
|
||||
if prev_source.is_empty() && sp.lo().0 != 0 {
|
||||
return sp.with_lo(BytePos(sp.lo().0 - 1));
|
||||
} else if !prev_source.contains('\n') || accept_newlines {
|
||||
} else if accept_newlines || !prev_source.contains('\n') {
|
||||
return sp.with_lo(BytePos(sp.lo().0 - prev_source.len() as u32));
|
||||
}
|
||||
}
|
||||
@ -693,7 +694,7 @@ impl SourceMap {
|
||||
pub fn span_extend_to_next_char(&self, sp: Span, c: char, accept_newlines: bool) -> Span {
|
||||
if let Ok(next_source) = self.span_to_next_source(sp) {
|
||||
let next_source = next_source.split(c).next().unwrap_or("");
|
||||
if !next_source.is_empty() && (!next_source.contains('\n') || accept_newlines) {
|
||||
if !next_source.is_empty() && (accept_newlines || !next_source.contains('\n')) {
|
||||
return sp.with_hi(BytePos(sp.hi().0 + next_source.len() as u32));
|
||||
}
|
||||
}
|
||||
|
@ -285,13 +285,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
self.check_expr_eq_type(&e, ty);
|
||||
ty
|
||||
}
|
||||
ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => self.check_then_else(
|
||||
&cond,
|
||||
then_expr,
|
||||
opt_else_expr.as_ref().map(|e| &**e),
|
||||
expr.span,
|
||||
expected,
|
||||
),
|
||||
ExprKind::If(cond, then_expr, opt_else_expr) => {
|
||||
self.check_then_else(cond, then_expr, opt_else_expr, expr.span, expected)
|
||||
}
|
||||
ExprKind::DropTemps(ref e) => self.check_expr_with_expectation(e, expected),
|
||||
ExprKind::Array(ref args) => self.check_expr_array(args, expected, expr),
|
||||
ExprKind::ConstBlock(ref anon_const) => self.to_const(anon_const).ty,
|
||||
|
@ -60,6 +60,7 @@ pub struct Map<I, F> {
|
||||
iter: I,
|
||||
f: F,
|
||||
}
|
||||
|
||||
impl<I, F> Map<I, F> {
|
||||
pub(in crate::iter) fn new(iter: I, f: F) -> Map<I, F> {
|
||||
Map { iter, f }
|
||||
|
@ -10,7 +10,7 @@ use super::time::TestTimeOptions;
|
||||
#[derive(Debug)]
|
||||
pub struct TestOpts {
|
||||
pub list: bool,
|
||||
pub filter: Option<String>,
|
||||
pub filters: Vec<String>,
|
||||
pub filter_exact: bool,
|
||||
pub force_run_in_process: bool,
|
||||
pub exclude_should_panic: bool,
|
||||
@ -148,12 +148,13 @@ fn optgroups() -> getopts::Options {
|
||||
}
|
||||
|
||||
fn usage(binary: &str, options: &getopts::Options) {
|
||||
let message = format!("Usage: {} [OPTIONS] [FILTER]", binary);
|
||||
let message = format!("Usage: {} [OPTIONS] [FILTERS...]", binary);
|
||||
println!(
|
||||
r#"{usage}
|
||||
|
||||
The FILTER string is tested against the name of all tests, and only those
|
||||
tests whose names contain the filter are run.
|
||||
tests whose names contain the filter are run. Multiple filter strings may
|
||||
be passed, which will run all tests matching any of the filters.
|
||||
|
||||
By default, all tests are run in parallel. This can be altered with the
|
||||
--test-threads flag or the RUST_TEST_THREADS environment variable when running
|
||||
@ -243,7 +244,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
|
||||
|
||||
let logfile = get_log_file(&matches)?;
|
||||
let run_ignored = get_run_ignored(&matches, include_ignored)?;
|
||||
let filter = get_filter(&matches)?;
|
||||
let filters = matches.free.clone();
|
||||
let nocapture = get_nocapture(&matches)?;
|
||||
let test_threads = get_test_threads(&matches)?;
|
||||
let color = get_color_config(&matches)?;
|
||||
@ -253,7 +254,7 @@ fn parse_opts_impl(matches: getopts::Matches) -> OptRes {
|
||||
|
||||
let test_opts = TestOpts {
|
||||
list,
|
||||
filter,
|
||||
filters,
|
||||
filter_exact: exact,
|
||||
force_run_in_process,
|
||||
exclude_should_panic,
|
||||
@ -397,12 +398,6 @@ fn get_run_ignored(matches: &getopts::Matches, include_ignored: bool) -> OptPart
|
||||
Ok(run_ignored)
|
||||
}
|
||||
|
||||
fn get_filter(matches: &getopts::Matches) -> OptPartRes<Option<String>> {
|
||||
let filter = if !matches.free.is_empty() { Some(matches.free[0].clone()) } else { None };
|
||||
|
||||
Ok(filter)
|
||||
}
|
||||
|
||||
fn get_allow_unstable(matches: &getopts::Matches) -> OptPartRes<bool> {
|
||||
let mut allow_unstable = false;
|
||||
|
||||
|
@ -396,8 +396,8 @@ pub fn filter_tests(opts: &TestOpts, tests: Vec<TestDescAndFn>) -> Vec<TestDescA
|
||||
};
|
||||
|
||||
// Remove tests that don't match the test filter
|
||||
if let Some(ref filter) = opts.filter {
|
||||
filtered.retain(|test| matches_filter(test, filter));
|
||||
if !opts.filters.is_empty() {
|
||||
filtered.retain(|test| opts.filters.iter().any(|filter| matches_filter(test, filter)));
|
||||
}
|
||||
|
||||
// Skip tests that match any of the skip filters
|
||||
|
@ -34,7 +34,7 @@ impl TestOpts {
|
||||
fn new() -> TestOpts {
|
||||
TestOpts {
|
||||
list: false,
|
||||
filter: None,
|
||||
filters: vec![],
|
||||
filter_exact: false,
|
||||
force_run_in_process: false,
|
||||
exclude_should_panic: false,
|
||||
@ -473,43 +473,60 @@ pub fn exact_filter_match() {
|
||||
}
|
||||
|
||||
let substr =
|
||||
filter_tests(&TestOpts { filter: Some("base".into()), ..TestOpts::new() }, tests());
|
||||
assert_eq!(substr.len(), 4);
|
||||
|
||||
let substr = filter_tests(&TestOpts { filter: Some("bas".into()), ..TestOpts::new() }, tests());
|
||||
filter_tests(&TestOpts { filters: vec!["base".into()], ..TestOpts::new() }, tests());
|
||||
assert_eq!(substr.len(), 4);
|
||||
|
||||
let substr =
|
||||
filter_tests(&TestOpts { filter: Some("::test".into()), ..TestOpts::new() }, tests());
|
||||
filter_tests(&TestOpts { filters: vec!["bas".into()], ..TestOpts::new() }, tests());
|
||||
assert_eq!(substr.len(), 4);
|
||||
|
||||
let substr =
|
||||
filter_tests(&TestOpts { filters: vec!["::test".into()], ..TestOpts::new() }, tests());
|
||||
assert_eq!(substr.len(), 3);
|
||||
|
||||
let substr =
|
||||
filter_tests(&TestOpts { filter: Some("base::test".into()), ..TestOpts::new() }, tests());
|
||||
filter_tests(&TestOpts { filters: vec!["base::test".into()], ..TestOpts::new() }, tests());
|
||||
assert_eq!(substr.len(), 3);
|
||||
|
||||
let substr = filter_tests(
|
||||
&TestOpts { filters: vec!["test1".into(), "test2".into()], ..TestOpts::new() },
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(substr.len(), 2);
|
||||
|
||||
let exact = filter_tests(
|
||||
&TestOpts { filter: Some("base".into()), filter_exact: true, ..TestOpts::new() },
|
||||
&TestOpts { filters: vec!["base".into()], filter_exact: true, ..TestOpts::new() },
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(exact.len(), 1);
|
||||
|
||||
let exact = filter_tests(
|
||||
&TestOpts { filter: Some("bas".into()), filter_exact: true, ..TestOpts::new() },
|
||||
&TestOpts { filters: vec!["bas".into()], filter_exact: true, ..TestOpts::new() },
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(exact.len(), 0);
|
||||
|
||||
let exact = filter_tests(
|
||||
&TestOpts { filter: Some("::test".into()), filter_exact: true, ..TestOpts::new() },
|
||||
&TestOpts { filters: vec!["::test".into()], filter_exact: true, ..TestOpts::new() },
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(exact.len(), 0);
|
||||
|
||||
let exact = filter_tests(
|
||||
&TestOpts { filter: Some("base::test".into()), filter_exact: true, ..TestOpts::new() },
|
||||
&TestOpts { filters: vec!["base::test".into()], filter_exact: true, ..TestOpts::new() },
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(exact.len(), 1);
|
||||
|
||||
let exact = filter_tests(
|
||||
&TestOpts {
|
||||
filters: vec!["base".into(), "base::test".into()],
|
||||
filter_exact: true,
|
||||
..TestOpts::new()
|
||||
},
|
||||
tests(),
|
||||
);
|
||||
assert_eq!(exact.len(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -1,7 +0,0 @@
|
||||
-include ../tools.mk
|
||||
|
||||
all:
|
||||
$(RUSTC) err.rs -Z treat-err-as-bug 2>&1 \
|
||||
| $(CGREP) "panicked at 'aborting due to \`-Z treat-err-as-bug=1\`'"
|
||||
$(RUSTC) delay_span_bug.rs -Z treat-err-as-bug 2>&1 \
|
||||
| $(CGREP) "panicked at 'aborting due to \`-Z treat-err-as-bug=1\`'"
|
@ -1,4 +0,0 @@
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_error(delay_span_bug_from_inside_query)]
|
||||
fn main() {}
|
@ -1,3 +0,0 @@
|
||||
#![crate_type="rlib"]
|
||||
|
||||
pub static C: u32 = 0-1;
|
13
src/test/ui/const-ptr/ptr_to_usize_cast.rs
Normal file
13
src/test/ui/const-ptr/ptr_to_usize_cast.rs
Normal file
@ -0,0 +1,13 @@
|
||||
#![feature(const_raw_ptr_to_usize_cast)]
|
||||
|
||||
fn main() {
|
||||
const OK: usize = unsafe { 0 as *const i32 as usize };
|
||||
|
||||
const _ERROR: usize = unsafe { &0 as *const i32 as usize };
|
||||
//~^ ERROR [const_err]
|
||||
//~| NOTE cannot cast pointer to integer because it was not created by cast from integer
|
||||
//~| NOTE
|
||||
//~| NOTE `#[deny(const_err)]` on by default
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
//~| NOTE see issue #71800
|
||||
}
|
14
src/test/ui/const-ptr/ptr_to_usize_cast.stderr
Normal file
14
src/test/ui/const-ptr/ptr_to_usize_cast.stderr
Normal file
@ -0,0 +1,14 @@
|
||||
error: any use of this value will cause an error
|
||||
--> $DIR/ptr_to_usize_cast.rs:6:36
|
||||
|
|
||||
LL | const _ERROR: usize = unsafe { &0 as *const i32 as usize };
|
||||
| -------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -4,7 +4,7 @@ error: any use of this value will cause an error
|
||||
LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 };
|
||||
| ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^-------
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
@ -4,7 +4,7 @@ error: any use of this value will cause an error
|
||||
LL | pub const FOO: usize = unsafe { BAR as usize };
|
||||
| --------------------------------^^^^^^^^^^^^---
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
|
||||
= note: `#[deny(const_err)]` on by default
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
|
@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/issue-52432.rs:7:10
|
||||
|
|
||||
LL | [(); &(static || {}) as *const _ as usize];
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -15,7 +15,7 @@ static INT_PTR_ARITH: () = unsafe {
|
||||
let x: usize = std::mem::transmute(&0);
|
||||
let _v = x + 0;
|
||||
//~^ ERROR could not evaluate static initializer
|
||||
//~| NOTE pointer-to-integer cast
|
||||
//~| NOTE cannot cast pointer to integer
|
||||
};
|
||||
|
||||
fn main() {}
|
||||
|
@ -8,7 +8,7 @@ error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ptr_arith.rs:16:14
|
||||
|
|
||||
LL | let _v = x + 0;
|
||||
| ^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| ^^^^^ cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
||||
warning: skipping const checks
|
||||
|
|
||||
|
@ -71,14 +71,14 @@ const _: *const u8 =
|
||||
|
||||
const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||
//~^ ERROR any use of this value will cause an error
|
||||
//~| NOTE "pointer-to-integer cast" needs an rfc
|
||||
//~| NOTE cannot cast pointer to integer
|
||||
//~| NOTE
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
//~| NOTE
|
||||
|
||||
const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
||||
//~^ ERROR any use of this value will cause an error
|
||||
//~| NOTE "pointer-to-integer cast" needs an rfc
|
||||
//~| NOTE cannot cast pointer to integer
|
||||
//~| NOTE
|
||||
//~| WARN this was previously accepted by the compiler but is being phased out
|
||||
//~| NOTE
|
||||
|
@ -36,7 +36,7 @@ error: any use of this value will cause an error
|
||||
LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
|
||||
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
@ -47,7 +47,7 @@ error: any use of this value will cause an error
|
||||
LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
|
||||
| --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---
|
||||
| |
|
||||
| "pointer-to-integer cast" needs an rfc before being allowed inside constants
|
||||
| cannot cast pointer to integer because it was not created by cast from integer
|
||||
|
|
||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
||||
|
@ -5,6 +5,7 @@
|
||||
fn main() {
|
||||
named_argument_takes_precedence_to_captured();
|
||||
formatting_parameters_can_be_captured();
|
||||
capture_raw_strings_and_idents();
|
||||
|
||||
#[cfg(panic = "unwind")]
|
||||
{
|
||||
@ -25,6 +26,16 @@ fn named_argument_takes_precedence_to_captured() {
|
||||
assert_eq!(&s, "positional-named-captured");
|
||||
}
|
||||
|
||||
fn capture_raw_strings_and_idents() {
|
||||
let r#type = "apple";
|
||||
let s = format!(r#"The fruit is an {type}"#);
|
||||
assert_eq!(&s, "The fruit is an apple");
|
||||
|
||||
let r#type = "orange";
|
||||
let s = format!(r"The fruit is an {type}");
|
||||
assert_eq!(&s, "The fruit is an orange");
|
||||
}
|
||||
|
||||
#[cfg(panic = "unwind")]
|
||||
fn panic_with_single_argument_does_not_get_formatted() {
|
||||
// panic! with a single argument does not perform string formatting.
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: invalid reference to positional arguments 1 and 2 (there is 1 argument)
|
||||
--> $DIR/issue-75307.rs:2:13
|
||||
--> $DIR/issue-75307.rs:2:17
|
||||
|
|
||||
LL | format!(r"{}{}{}", named_arg=1);
|
||||
| ^^^^^^^^^
|
||||
| ^^^^
|
||||
|
|
||||
= note: positional arguments are zero-based
|
||||
|
||||
|
17
src/test/ui/test-attrs/test-filter-multiple.rs
Normal file
17
src/test/ui/test-attrs/test-filter-multiple.rs
Normal file
@ -0,0 +1,17 @@
|
||||
// run-pass
|
||||
// compile-flags: --test
|
||||
// run-flags: --test-threads=1 test1 test2
|
||||
// check-run-results
|
||||
// normalize-stdout-test "finished in \d+\.\d+s" -> "finished in $$TIME"
|
||||
// ignore-emscripten no threads support
|
||||
|
||||
#[test]
|
||||
fn test1() {}
|
||||
|
||||
#[test]
|
||||
fn test2() {}
|
||||
|
||||
#[test]
|
||||
fn test3() {
|
||||
panic!("this should not run");
|
||||
}
|
7
src/test/ui/test-attrs/test-filter-multiple.run.stdout
Normal file
7
src/test/ui/test-attrs/test-filter-multiple.run.stdout
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
running 2 tests
|
||||
test test1 ... ok
|
||||
test test2 ... ok
|
||||
|
||||
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in $TIME
|
||||
|
11
src/test/ui/treat-err-as-bug/delay_span_bug.rs
Normal file
11
src/test/ui/treat-err-as-bug/delay_span_bug.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// compile-flags: -Ztreat-err-as-bug
|
||||
// failure-status: 101
|
||||
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
||||
// error-pattern: [trigger_delay_span_bug] trigger a delay span bug
|
||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_error(delay_span_bug_from_inside_query)]
|
||||
fn main() {}
|
11
src/test/ui/treat-err-as-bug/delay_span_bug.stderr
Normal file
11
src/test/ui/treat-err-as-bug/delay_span_bug.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error: internal compiler error: delayed span bug triggered by #[rustc_error(delay_span_bug_from_inside_query)]
|
||||
--> $DIR/delay_span_bug.rs:11:1
|
||||
|
|
||||
LL | fn main() {}
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: internal compiler error: unexpected panic
|
||||
|
||||
query stack during panic:
|
||||
#0 [trigger_delay_span_bug] trigger a delay span bug
|
||||
end of query stack
|
11
src/test/ui/treat-err-as-bug/err.rs
Normal file
11
src/test/ui/treat-err-as-bug/err.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// compile-flags: -Ztreat-err-as-bug
|
||||
// failure-status: 101
|
||||
// error-pattern: aborting due to `-Z treat-err-as-bug=1`
|
||||
// error-pattern: [eval_to_allocation_raw] const-evaluating + checking `C`
|
||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
pub static C: u32 = 0 - 1;
|
||||
//~^ ERROR could not evaluate static initializer
|
12
src/test/ui/treat-err-as-bug/err.stderr
Normal file
12
src/test/ui/treat-err-as-bug/err.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/err.rs:10:21
|
||||
|
|
||||
LL | pub static C: u32 = 0 - 1;
|
||||
| ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
|
||||
|
||||
error: internal compiler error: unexpected panic
|
||||
|
||||
query stack during panic:
|
||||
#0 [eval_to_allocation_raw] const-evaluating + checking `C`
|
||||
#1 [eval_to_allocation_raw] const-evaluating + checking `C`
|
||||
end of query stack
|
@ -240,8 +240,8 @@ pub struct Config {
|
||||
/// Run ignored tests
|
||||
pub run_ignored: bool,
|
||||
|
||||
/// Only run tests that match this filter
|
||||
pub filter: Option<String>,
|
||||
/// Only run tests that match these filters
|
||||
pub filters: Vec<String>,
|
||||
|
||||
/// Exactly match the filter, rather than a substring
|
||||
pub filter_exact: bool,
|
||||
|
@ -333,6 +333,8 @@ pub struct TestProps {
|
||||
pub assembly_output: Option<String>,
|
||||
// If true, the test is expected to ICE
|
||||
pub should_ice: bool,
|
||||
// If true, the stderr is expected to be different across bit-widths.
|
||||
pub stderr_per_bitwidth: bool,
|
||||
}
|
||||
|
||||
impl TestProps {
|
||||
@ -372,6 +374,7 @@ impl TestProps {
|
||||
rustfix_only_machine_applicable: false,
|
||||
assembly_output: None,
|
||||
should_ice: false,
|
||||
stderr_per_bitwidth: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,6 +541,10 @@ impl TestProps {
|
||||
if self.assembly_output.is_none() {
|
||||
self.assembly_output = config.parse_assembly_output(ln);
|
||||
}
|
||||
|
||||
if !self.stderr_per_bitwidth {
|
||||
self.stderr_per_bitwidth = config.parse_stderr_per_bitwidth(ln);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -774,6 +781,10 @@ impl Config {
|
||||
self.parse_name_directive(line, "ignore-pass")
|
||||
}
|
||||
|
||||
fn parse_stderr_per_bitwidth(&self, line: &str) -> bool {
|
||||
self.parse_name_directive(line, "stderr-per-bitwidth")
|
||||
}
|
||||
|
||||
fn parse_assembly_output(&self, line: &str) -> Option<String> {
|
||||
self.parse_name_value_directive(line, "assembly-output").map(|r| r.trim().to_string())
|
||||
}
|
||||
|
@ -221,7 +221,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
|
||||
suite: matches.opt_str("suite").unwrap(),
|
||||
debugger: None,
|
||||
run_ignored,
|
||||
filter: matches.free.first().cloned(),
|
||||
filters: matches.free.clone(),
|
||||
filter_exact: matches.opt_present("exact"),
|
||||
force_pass_mode: matches.opt_str("pass").map(|mode| {
|
||||
mode.parse::<PassMode>()
|
||||
@ -280,7 +280,7 @@ pub fn log_config(config: &Config) {
|
||||
logv(c, format!("stage_id: {}", config.stage_id));
|
||||
logv(c, format!("mode: {}", config.mode));
|
||||
logv(c, format!("run_ignored: {}", config.run_ignored));
|
||||
logv(c, format!("filter: {}", opt_str(&config.filter)));
|
||||
logv(c, format!("filters: {:?}", config.filters));
|
||||
logv(c, format!("filter_exact: {}", config.filter_exact));
|
||||
logv(
|
||||
c,
|
||||
@ -465,7 +465,7 @@ fn configure_lldb(config: &Config) -> Option<Config> {
|
||||
pub fn test_opts(config: &Config) -> test::TestOpts {
|
||||
test::TestOpts {
|
||||
exclude_should_panic: false,
|
||||
filter: config.filter.clone(),
|
||||
filters: config.filters.clone(),
|
||||
filter_exact: config.filter_exact,
|
||||
run_ignored: if config.run_ignored { test::RunIgnored::Yes } else { test::RunIgnored::No },
|
||||
format: if config.quiet { test::OutputFormat::Terse } else { test::OutputFormat::Pretty },
|
||||
|
@ -3124,7 +3124,12 @@ impl<'test> TestCx<'test> {
|
||||
errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
|
||||
}
|
||||
if !self.props.dont_check_compiler_stderr {
|
||||
errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
|
||||
let kind = if self.props.stderr_per_bitwidth {
|
||||
format!("{}bit.stderr", get_pointer_width(&self.config.target))
|
||||
} else {
|
||||
String::from("stderr")
|
||||
};
|
||||
errors += self.compare_output(&kind, &normalized_stderr, &expected_stderr);
|
||||
}
|
||||
}
|
||||
TestOutput::Run => {
|
||||
|
Loading…
Reference in New Issue
Block a user