Auto merge of #93738 - m-ou-se:rollup-zjyd2et, r=m-ou-se

Rollup of 13 pull requests

Successful merges:

 - #88313 (Make the pre-commit script pre-push instead)
 - #91530 (Suggest 1-tuple parentheses on exprs without existing parens)
 - #92724 (Cleanup c_str.rs)
 - #93208 (Impl {Add,Sub,Mul,Div,Rem,BitXor,BitOr,BitAnd}Assign<$t> for Wrapping<$t> for rust 1.60.0)
 - #93394 (Don't allow {} to refer to implicit captures in format_args.)
 - #93416 (remove `allow_fail` test flag)
 - #93487 (Fix linking stage1 toolchain in `./x.py setup`)
 - #93673 (Linkify sidebar headings for sibling items)
 - #93680 (Drop json::from_reader)
 - #93682 (Update tracking issue for `const_fn_trait_bound`)
 - #93722 (Use shallow clones for submodules managed by rustbuild, not just bootstrap.py)
 - #93723 (Rerun bootstrap's build script when RUSTC changes)
 - #93737 (bootstrap: prefer using '--config' over 'RUST_BOOTSTRAP_CONFIG')

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-02-07 15:32:19 +00:00
commit f52c31840d
55 changed files with 477 additions and 396 deletions

View File

@ -25,6 +25,7 @@ enum ArgumentType {
enum Position {
Exact(usize),
Capture(usize),
Named(Symbol),
}
@ -49,6 +50,8 @@ struct Context<'a, 'b> {
/// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]`
/// * `names` (in JSON): `{"foo": 2}`
args: Vec<P<ast::Expr>>,
/// The number of arguments that were added by implicit capturing.
num_captured_args: usize,
/// Placeholder slot numbers indexed by argument.
arg_types: Vec<Vec<usize>>,
/// Unique format specs seen for each argument.
@ -231,6 +234,11 @@ fn parse_args<'a>(
}
impl<'a, 'b> Context<'a, 'b> {
/// The number of arguments that were explicitly given.
fn num_args(&self) -> usize {
self.args.len() - self.num_captured_args
}
fn resolve_name_inplace(&self, p: &mut parse::Piece<'_>) {
// NOTE: the `unwrap_or` branch is needed in case of invalid format
// arguments, e.g., `format_args!("{foo}")`.
@ -345,7 +353,7 @@ fn verify_count(&mut self, c: parse::Count) {
}
fn describe_num_args(&self) -> Cow<'_, str> {
match self.args.len() {
match self.num_args() {
0 => "no arguments were given".into(),
1 => "there is 1 argument".into(),
x => format!("there are {} arguments", x).into(),
@ -371,7 +379,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
let count = self.pieces.len()
+ self.arg_with_formatting.iter().filter(|fmt| fmt.precision_span.is_some()).count();
if self.names.is_empty() && !numbered_position_args && count != self.args.len() {
if self.names.is_empty() && !numbered_position_args && count != self.num_args() {
e = self.ecx.struct_span_err(
sp,
&format!(
@ -419,7 +427,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
if let Some(span) = fmt.precision_span {
let span = self.fmtsp.from_inner(span);
match fmt.precision {
parse::CountIsParam(pos) if pos > self.args.len() => {
parse::CountIsParam(pos) if pos > self.num_args() => {
e.span_label(
span,
&format!(
@ -462,7 +470,7 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
if let Some(span) = fmt.width_span {
let span = self.fmtsp.from_inner(span);
match fmt.width {
parse::CountIsParam(pos) if pos > self.args.len() => {
parse::CountIsParam(pos) if pos > self.num_args() => {
e.span_label(
span,
&format!(
@ -494,12 +502,15 @@ fn report_invalid_references(&self, numbered_position_args: bool) {
/// Actually verifies and tracks a given format placeholder
/// (a.k.a. argument).
fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
if let Exact(arg) = arg {
if arg >= self.num_args() {
self.invalid_refs.push((arg, self.curpiece));
return;
}
}
match arg {
Exact(arg) => {
if self.args.len() <= arg {
self.invalid_refs.push((arg, self.curpiece));
return;
}
Exact(arg) | Capture(arg) => {
match ty {
Placeholder(_) => {
// record every (position, type) combination only once
@ -526,7 +537,7 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
match self.names.get(&name) {
Some(&idx) => {
// Treat as positional arg.
self.verify_arg_type(Exact(idx), ty)
self.verify_arg_type(Capture(idx), ty)
}
None => {
// For the moment capturing variables from format strings expanded from macros is
@ -541,9 +552,10 @@ fn verify_arg_type(&mut self, arg: Position, ty: ArgumentType) {
} else {
self.fmtsp
};
self.num_captured_args += 1;
self.args.push(self.ecx.expr_ident(span, Ident::new(name, span)));
self.names.insert(name, idx);
self.verify_arg_type(Exact(idx), ty)
self.verify_arg_type(Capture(idx), ty)
} else {
let msg = format!("there is no argument named `{}`", name);
let sp = if self.is_literal {
@ -1051,6 +1063,7 @@ pub fn expand_preparsed_format_args(
let mut cx = Context {
ecx,
args,
num_captured_args: 0,
arg_types,
arg_unique_types,
names,

View File

@ -252,11 +252,6 @@ pub fn expand_test_or_bench(
"ignore",
cx.expr_bool(sp, should_ignore(&cx.sess, &item)),
),
// allow_fail: true | false
field(
"allow_fail",
cx.expr_bool(sp, should_fail(&cx.sess, &item)),
),
// compile_fail: true | false
field("compile_fail", cx.expr_bool(sp, false)),
// no_run: true | false
@ -359,10 +354,6 @@ fn should_ignore(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::ignore)
}
fn should_fail(sess: &Session, i: &ast::Item) -> bool {
sess.contains_name(&i.attrs, sym::allow_fail)
}
fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic {
match cx.sess.find_by_name(&i.attrs, sym::should_panic) {
Some(attr) => {

View File

@ -277,8 +277,6 @@ pub fn set(&self, features: &mut Features, span: Span) {
(incomplete, adt_const_params, "1.56.0", Some(44580), None),
/// Allows defining an `#[alloc_error_handler]`.
(active, alloc_error_handler, "1.29.0", Some(51540), None),
/// Allows a test to fail without failing the whole suite.
(active, allow_fail, "1.19.0", Some(46488), None),
/// Allows explicit discriminants on non-unit enum variants.
(active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None),
/// Allows trait methods with arbitrary self types.
@ -332,7 +330,7 @@ pub fn set(&self, features: &mut Features, span: Span) {
/// Allows using and casting function pointers in a `const fn`.
(active, const_fn_fn_ptr_basics, "1.48.0", Some(57563), None),
/// Allows trait bounds in `const fn`.
(active, const_fn_trait_bound, "1.53.0", Some(57563), None),
(active, const_fn_trait_bound, "1.53.0", Some(93706), None),
/// Allows `for _ in _` loops in const contexts.
(active, const_for, "1.56.0", Some(87575), None),
/// Allows argument and return position `impl Trait` in a `const fn`.

View File

@ -403,7 +403,6 @@ pub struct BuiltinAttribute {
},
// Testing:
gated!(allow_fail, Normal, template!(Word), WarnFollowing, experimental!(allow_fail)),
gated!(
test_runner, CrateLevel, template!(List: "path"), ErrorFollowing, custom_test_frameworks,
"custom test frameworks are an unstable feature",

View File

@ -48,6 +48,8 @@ macro_rules! declare_features {
(removed, advanced_slice_patterns, "1.0.0", Some(62254), None,
Some("merged into `#![feature(slice_patterns)]`")),
(removed, allocator, "1.0.0", None, None, None),
/// Allows a test to fail without failing the whole suite.
(removed, allow_fail, "1.19.0", Some(46488), None, Some("removed due to no clear use cases")),
(removed, await_macro, "1.38.0", Some(50547), None,
Some("subsumed by `.await` syntax")),
/// Allows comparing raw pointers during const eval.

View File

@ -2044,19 +2044,8 @@ pub fn report_and_explain_type_error(
// If a tuple of length one was expected and the found expression has
// parentheses around it, perhaps the user meant to write `(expr,)` to
// build a tuple (issue #86100)
(ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => {
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) {
if let Some(code) =
code.strip_prefix('(').and_then(|s| s.strip_suffix(')'))
{
err.span_suggestion(
span,
"use a trailing comma to create a tuple with one element",
format!("({},)", code),
Applicability::MaybeIncorrect,
);
}
}
(ty::Tuple(_), _) => {
self.emit_tuple_wrap_err(&mut err, span, found, expected)
}
// If a character was expected and the found expression is a string literal
// containing a single character, perhaps the user meant to write `'c'` to
@ -2119,6 +2108,41 @@ pub fn report_and_explain_type_error(
diag
}
fn emit_tuple_wrap_err(
&self,
err: &mut DiagnosticBuilder<'tcx>,
span: Span,
found: Ty<'tcx>,
expected: Ty<'tcx>,
) {
let [expected_tup_elem] = &expected.tuple_fields().collect::<Vec<_>>()[..]
else { return };
if !same_type_modulo_infer(expected_tup_elem, found) {
return;
}
let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
else { return };
let msg = "use a trailing comma to create a tuple with one element";
if code.starts_with('(') && code.ends_with(')') {
let before_close = span.hi() - BytePos::from_u32(1);
err.span_suggestion(
span.with_hi(before_close).shrink_to_hi(),
msg,
",".into(),
Applicability::MachineApplicable,
);
} else {
err.multipart_suggestion(
msg,
vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())],
Applicability::MachineApplicable,
);
}
}
fn values_str(
&self,
values: ValuePairs<'tcx>,

View File

@ -185,8 +185,6 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, HashMap};
use std::io;
use std::io::prelude::*;
use std::mem::swap;
use std::num::FpCategory as Fp;
use std::ops::Index;
@ -250,7 +248,6 @@ pub enum ErrorCode {
pub enum ParserError {
/// msg, line, col
SyntaxError(ErrorCode, usize, usize),
IoError(io::ErrorKind, String),
}
// Builder and Parser have the same errors.
@ -329,10 +326,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
}
fn io_error_to_error(io: io::Error) -> ParserError {
IoError(io.kind(), io.to_string())
}
impl fmt::Display for ParserError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// FIXME this should be a nicer error
@ -2163,21 +2156,6 @@ fn build_object(&mut self) -> Result<Json, BuilderError> {
}
}
/// Decodes a json value from an `&mut io::Read`
pub fn from_reader(rdr: &mut dyn Read) -> Result<Json, BuilderError> {
let mut contents = Vec::new();
match rdr.read_to_end(&mut contents) {
Ok(c) => c,
Err(e) => return Err(io_error_to_error(e)),
};
let s = match str::from_utf8(&contents).ok() {
Some(s) => s,
_ => return Err(SyntaxError(NotUtf8, 0, 0)),
};
let mut builder = Builder::new(s.chars());
builder.build()
}
/// Decodes a json value from a string
pub fn from_str(s: &str) -> Result<Json, BuilderError> {
let mut builder = Builder::new(s.chars());

View File

@ -2148,8 +2148,8 @@ pub fn search(
use std::fs;
fn load_file(path: &Path) -> Result<(Target, TargetWarnings), String> {
let contents = fs::read(path).map_err(|e| e.to_string())?;
let obj = json::from_reader(&mut &contents[..]).map_err(|e| e.to_string())?;
let contents = fs::read_to_string(path).map_err(|e| e.to_string())?;
let obj = json::from_str(&contents).map_err(|e| e.to_string())?;
Target::from_json(obj)
}

View File

@ -239,6 +239,16 @@ fn add_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const AddAssign<$t> for Wrapping<$t> {
#[inline]
fn add_assign(&mut self, other: $t) {
*self = *self + Wrapping(other);
}
}
forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, $t }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Sub for Wrapping<$t> {
@ -262,6 +272,16 @@ fn sub_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const SubAssign<$t> for Wrapping<$t> {
#[inline]
fn sub_assign(&mut self, other: $t) {
*self = *self - Wrapping(other);
}
}
forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, $t }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Mul for Wrapping<$t> {
@ -285,6 +305,16 @@ fn mul_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const MulAssign<$t> for Wrapping<$t> {
#[inline]
fn mul_assign(&mut self, other: $t) {
*self = *self * Wrapping(other);
}
}
forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, $t }
#[stable(feature = "wrapping_div", since = "1.3.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Div for Wrapping<$t> {
@ -308,6 +338,16 @@ fn div_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const DivAssign<$t> for Wrapping<$t> {
#[inline]
fn div_assign(&mut self, other: $t) {
*self = *self / Wrapping(other);
}
}
forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, $t }
#[stable(feature = "wrapping_impls", since = "1.7.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Rem for Wrapping<$t> {
@ -331,6 +371,16 @@ fn rem_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const RemAssign<$t> for Wrapping<$t> {
#[inline]
fn rem_assign(&mut self, other: $t) {
*self = *self % Wrapping(other);
}
}
forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, $t }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Not for Wrapping<$t> {
@ -367,6 +417,16 @@ fn bitxor_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitXorAssign<$t> for Wrapping<$t> {
#[inline]
fn bitxor_assign(&mut self, other: $t) {
*self = *self ^ Wrapping(other);
}
}
forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, $t }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOr for Wrapping<$t> {
@ -390,6 +450,16 @@ fn bitor_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitOrAssign<$t> for Wrapping<$t> {
#[inline]
fn bitor_assign(&mut self, other: $t) {
*self = *self | Wrapping(other);
}
}
forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, $t }
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitAnd for Wrapping<$t> {
@ -413,6 +483,16 @@ fn bitand_assign(&mut self, other: Wrapping<$t>) {
}
forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> }
#[stable(feature = "wrapping_int_assign_impl", since = "1.60.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const BitAndAssign<$t> for Wrapping<$t> {
#[inline]
fn bitand_assign(&mut self, other: $t) {
*self = *self & Wrapping(other);
}
}
forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, $t }
#[stable(feature = "wrapping_neg", since = "1.10.0")]
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
impl const Neg for Wrapping<$t> {

View File

@ -1252,15 +1252,16 @@ pub unsafe fn from_ptr<'a>(ptr: *const c_char) -> &'a CStr {
/// assert!(cstr.is_err());
/// ```
#[stable(feature = "cstr_from_bytes", since = "1.10.0")]
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&CStr, FromBytesWithNulError> {
pub fn from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError> {
let nul_pos = memchr::memchr(0, bytes);
if let Some(nul_pos) = nul_pos {
if nul_pos + 1 != bytes.len() {
return Err(FromBytesWithNulError::interior_nul(nul_pos));
match nul_pos {
Some(nul_pos) if nul_pos + 1 == bytes.len() => {
// SAFETY: We know there is only one nul byte, at the end
// of the byte slice.
Ok(unsafe { Self::from_bytes_with_nul_unchecked(bytes) })
}
Ok(unsafe { CStr::from_bytes_with_nul_unchecked(bytes) })
} else {
Err(FromBytesWithNulError::not_nul_terminated())
Some(nul_pos) => Err(FromBytesWithNulError::interior_nul(nul_pos)),
None => Err(FromBytesWithNulError::not_nul_terminated()),
}
}

View File

@ -47,7 +47,6 @@ pub struct ConsoleTestState {
pub passed: usize,
pub failed: usize,
pub ignored: usize,
pub allowed_fail: usize,
pub filtered_out: usize,
pub measured: usize,
pub exec_time: Option<TestSuiteExecTime>,
@ -71,7 +70,6 @@ pub fn new(opts: &TestOpts) -> io::Result<ConsoleTestState> {
passed: 0,
failed: 0,
ignored: 0,
allowed_fail: 0,
filtered_out: 0,
measured: 0,
exec_time: None,
@ -112,7 +110,6 @@ pub fn write_log_result(
TestResult::TrFailed => "failed".to_owned(),
TestResult::TrFailedMsg(ref msg) => format!("failed: {}", msg),
TestResult::TrIgnored => "ignored".to_owned(),
TestResult::TrAllowedFail => "failed (allowed)".to_owned(),
TestResult::TrBench(ref bs) => fmt_bench_samples(bs),
TestResult::TrTimedFail => "failed (time limit exceeded)".to_owned(),
},
@ -126,7 +123,7 @@ pub fn write_log_result(
}
fn current_test_count(&self) -> usize {
self.passed + self.failed + self.ignored + self.measured + self.allowed_fail
self.passed + self.failed + self.ignored + self.measured
}
}
@ -191,7 +188,6 @@ fn handle_test_result(st: &mut ConsoleTestState, completed_test: CompletedTest)
st.not_failures.push((test, stdout));
}
TestResult::TrIgnored => st.ignored += 1,
TestResult::TrAllowedFail => st.allowed_fail += 1,
TestResult::TrBench(bs) => {
st.metrics.insert_metric(
test.name.as_slice(),

View File

@ -124,15 +124,6 @@ fn write_result(
self.write_event("test", desc.name.as_slice(), "ignored", exec_time, stdout, None)
}
TestResult::TrAllowedFail => self.write_event(
"test",
desc.name.as_slice(),
"allowed_failure",
exec_time,
stdout,
None,
),
TestResult::TrBench(ref bs) => {
let median = bs.ns_iter_summ.median as usize;
let deviation = (bs.ns_iter_summ.max - bs.ns_iter_summ.min) as usize;
@ -172,14 +163,12 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
\"event\": \"{}\", \
\"passed\": {}, \
\"failed\": {}, \
\"allowed_fail\": {}, \
\"ignored\": {}, \
\"measured\": {}, \
\"filtered_out\": {}",
if state.failed == 0 { "ok" } else { "failed" },
state.passed,
state.failed + state.allowed_fail,
state.allowed_fail,
state.failed,
state.ignored,
state.measured,
state.filtered_out,

View File

@ -121,7 +121,7 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
))?;
}
TestResult::TrOk | TestResult::TrAllowedFail => {
TestResult::TrOk => {
self.write_message(&*format!(
"<testcase classname=\"{}\" \
name=\"{}\" time=\"{}\"/>",

View File

@ -49,10 +49,6 @@ pub fn write_ignored(&mut self) -> io::Result<()> {
self.write_short_result("ignored", term::color::YELLOW)
}
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
self.write_short_result("FAILED (allowed)", term::color::YELLOW)
}
pub fn write_time_failed(&mut self) -> io::Result<()> {
self.write_short_result("FAILED (time limit exceeded)", term::color::RED)
}
@ -219,7 +215,6 @@ fn write_result(
TestResult::TrOk => self.write_ok()?,
TestResult::TrFailed | TestResult::TrFailedMsg(_) => self.write_failed()?,
TestResult::TrIgnored => self.write_ignored()?,
TestResult::TrAllowedFail => self.write_allowed_fail()?,
TestResult::TrBench(ref bs) => {
self.write_bench()?;
self.write_plain(&format!(": {}", fmt_bench_samples(bs)))?;
@ -263,22 +258,10 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
self.write_pretty("FAILED", term::color::RED)?;
}
let s = if state.allowed_fail > 0 {
format!(
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
state.passed,
state.failed + state.allowed_fail,
state.allowed_fail,
state.ignored,
state.measured,
state.filtered_out
)
} else {
format!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
)
};
let s = format!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
);
self.write_plain(&s)?;

View File

@ -54,10 +54,6 @@ pub fn write_ignored(&mut self) -> io::Result<()> {
self.write_short_result("i", term::color::YELLOW)
}
pub fn write_allowed_fail(&mut self) -> io::Result<()> {
self.write_short_result("a", term::color::YELLOW)
}
pub fn write_bench(&mut self) -> io::Result<()> {
self.write_pretty("bench", term::color::CYAN)
}
@ -207,7 +203,6 @@ fn write_result(
self.write_failed()
}
TestResult::TrIgnored => self.write_ignored(),
TestResult::TrAllowedFail => self.write_allowed_fail(),
TestResult::TrBench(ref bs) => {
if self.is_multithreaded {
self.write_test_name(desc)?;
@ -244,22 +239,10 @@ fn write_run_finish(&mut self, state: &ConsoleTestState) -> io::Result<bool> {
self.write_pretty("FAILED", term::color::RED)?;
}
let s = if state.allowed_fail > 0 {
format!(
". {} passed; {} failed ({} allowed); {} ignored; {} measured; {} filtered out",
state.passed,
state.failed + state.allowed_fail,
state.allowed_fail,
state.ignored,
state.measured,
state.filtered_out
)
} else {
format!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
)
};
let s = format!(
". {} passed; {} failed; {} ignored; {} measured; {} filtered out",
state.passed, state.failed, state.ignored, state.measured, state.filtered_out
);
self.write_plain(&s)?;

View File

@ -19,7 +19,6 @@ pub enum TestResult {
TrFailed,
TrFailedMsg(String),
TrIgnored,
TrAllowedFail,
TrBench(BenchSamples),
TrTimedFail,
}
@ -42,8 +41,6 @@ pub fn calc_result<'a>(
if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
TestResult::TrOk
} else if desc.allow_fail {
TestResult::TrAllowedFail
} else if let Some(panic_str) = maybe_panic_str {
TestResult::TrFailedMsg(format!(
r#"panic did not contain expected string
@ -64,7 +61,6 @@ pub fn calc_result<'a>(
(&ShouldPanic::Yes, Ok(())) | (&ShouldPanic::YesWithMessage(_), Ok(())) => {
TestResult::TrFailedMsg("test did not panic as expected".to_string())
}
_ if desc.allow_fail => TestResult::TrAllowedFail,
_ => TestResult::TrFailed,
};
@ -90,11 +86,10 @@ pub fn get_result_from_exit_code(
time_opts: &Option<time::TestTimeOptions>,
exec_time: &Option<time::TestExecTime>,
) -> TestResult {
let result = match (desc.allow_fail, code) {
(_, TR_OK) => TestResult::TrOk,
(true, TR_FAILED) => TestResult::TrAllowedFail,
(false, TR_FAILED) => TestResult::TrFailed,
(_, _) => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
let result = match code {
TR_OK => TestResult::TrOk,
TR_FAILED => TestResult::TrFailed,
_ => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
};
// If test is already failed (or allowed to fail), do not change the result.

View File

@ -62,10 +62,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
name: StaticTestName("1"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
@ -74,10 +75,11 @@ fn one_ignored_one_unignored_test() -> Vec<TestDescAndFn> {
name: StaticTestName("2"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
},
@ -94,10 +96,11 @@ fn f() {
name: StaticTestName("whatever"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -115,10 +118,11 @@ fn f() {}
name: StaticTestName("whatever"),
ignore: true,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -140,10 +144,11 @@ fn f() {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::Yes,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -165,10 +170,11 @@ fn f() {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::YesWithMessage("error message"),
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -195,10 +201,11 @@ fn f() {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::YesWithMessage(expected),
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -229,10 +236,11 @@ fn f() {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::YesWithMessage(expected),
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -255,10 +263,11 @@ fn f() {}
name: StaticTestName("whatever"),
ignore: false,
should_panic,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -289,10 +298,11 @@ fn f() {}
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -324,10 +334,11 @@ fn f() {}
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(f)),
};
@ -363,10 +374,11 @@ fn typed_test_desc(test_type: TestType) -> TestDesc {
name: StaticTestName("whatever"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type,
#[cfg(bootstrap)]
allow_fail: false,
}
}
@ -476,10 +488,11 @@ pub fn exclude_should_panic_option() {
name: StaticTestName("3"),
ignore: false,
should_panic: ShouldPanic::Yes,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
});
@ -500,10 +513,11 @@ fn tests() -> Vec<TestDescAndFn> {
name: StaticTestName(name),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(move || {})),
})
@ -589,10 +603,11 @@ fn testfn() {}
name: DynTestName((*name).clone()),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: DynTestFn(Box::new(testfn)),
};
@ -740,10 +755,11 @@ fn f(_: &mut Bencher) {}
name: StaticTestName("f"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
};
crate::bench::benchmark(TestId(0), desc, tx, true, f);
@ -762,10 +778,11 @@ fn f(b: &mut Bencher) {
name: StaticTestName("f"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
};
crate::bench::benchmark(TestId(0), desc, tx, true, f);
@ -778,20 +795,22 @@ fn should_sort_failures_before_printing_them() {
name: StaticTestName("a"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
};
let test_b = TestDesc {
name: StaticTestName("b"),
ignore: false,
should_panic: ShouldPanic::No,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
};
let mut out = PrettyFormatter::new(OutputLocation::Raw(Vec::new()), false, 10, false, None);
@ -802,7 +821,6 @@ fn should_sort_failures_before_printing_them() {
passed: 0,
failed: 0,
ignored: 0,
allowed_fail: 0,
filtered_out: 0,
measured: 0,
exec_time: None,

View File

@ -118,10 +118,11 @@ pub struct TestDesc {
pub name: TestName,
pub ignore: bool,
pub should_panic: options::ShouldPanic,
pub allow_fail: bool,
pub compile_fail: bool,
pub no_run: bool,
pub test_type: TestType,
#[cfg(bootstrap)]
pub allow_fail: bool,
}
impl TestDesc {
@ -150,9 +151,6 @@ pub fn test_mode(&self) -> Option<&'static str> {
}
options::ShouldPanic::No => {}
}
if self.allow_fail {
return Some("allow fail");
}
if self.compile_fail {
return Some("compile fail");
}

View File

@ -30,6 +30,7 @@ fn main() {
println!("{}", suggestion);
}
let pre_commit = config.src.join(".git").join("hooks").join("pre-commit");
Build::new(config).build();
if suggest_setup {
@ -42,6 +43,19 @@ fn main() {
println!("{}", suggestion);
}
// Give a warning if the pre-commit script is in pre-commit and not pre-push.
// HACK: Since the commit script uses hard links, we can't actually tell if it was installed by x.py setup or not.
// We could see if it's identical to src/etc/pre-push.sh, but pre-push may have been modified in the meantime.
// Instead, look for this comment, which is almost certainly not in any custom hook.
if std::fs::read_to_string(pre_commit).map_or(false, |contents| {
contents.contains("https://github.com/rust-lang/rust/issues/77620#issuecomment-705144570")
}) {
println!(
"warning: You have the pre-push script installed to .git/hooks/pre-commit. \
Consider moving it to .git/hooks/pre-push instead, which runs less often."
);
}
if suggest_setup || changelog_suggestion.is_some() {
println!("note: this message was printed twice to make it more likely to be seen");
}

View File

@ -1221,9 +1221,9 @@ def bootstrap(help_triggered):
build.verbose = args.verbose
build.clean = args.clean
# Read from `RUST_BOOTSTRAP_CONFIG`, then `--config`, then fallback to `config.toml` (if it
# Read from `--config`, then `RUST_BOOTSTRAP_CONFIG`, then fallback to `config.toml` (if it
# exists).
toml_path = os.getenv('RUST_BOOTSTRAP_CONFIG') or args.config
toml_path = args.config or os.getenv('RUST_BOOTSTRAP_CONFIG')
if not toml_path and os.path.exists('config.toml'):
toml_path = 'config.toml'

View File

@ -3,6 +3,8 @@
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=RUSTC");
println!("cargo:rerun-if-env-changed=PATH");
println!("cargo:rustc-env=BUILD_TRIPLE={}", env::var("HOST").unwrap());
// This may not be a canonicalized path.

View File

@ -527,7 +527,7 @@ fn dir_is_empty(dir: &Path) -> bool {
// Try passing `--progress` to start, then run git again without if that fails.
let update = |progress: bool| {
let mut git = Command::new("git");
git.args(&["submodule", "update", "--init", "--recursive"]);
git.args(&["submodule", "update", "--init", "--recursive", "--depth=1"]);
if progress {
git.arg("--progress");
}

View File

@ -1,7 +1,9 @@
use crate::TargetSelection;
use crate::{t, VERSION};
use std::env::consts::EXE_SUFFIX;
use std::fmt::Write as _;
use std::path::{Path, PathBuf};
use std::fs::File;
use std::path::{Path, PathBuf, MAIN_SEPARATOR};
use std::process::Command;
use std::str::FromStr;
use std::{
@ -109,7 +111,8 @@ pub fn setup(src_path: &Path, profile: Profile) {
println!("`x.py` will now use the configuration at {}", include_path.display());
let build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
let stage_path = ["build", build.rustc_target_arg(), "stage1"].join("/");
let stage_path =
["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
println!();
@ -171,6 +174,13 @@ fn attempt_toolchain_link(stage_path: &str) {
return;
}
if !ensure_stage1_toolchain_placeholder_exists(stage_path) {
println!(
"Failed to create a template for stage 1 toolchain or confirm that it already exists"
);
return;
}
if try_link_toolchain(&stage_path[..]) {
println!(
"Added `stage1` rustup toolchain; try `cargo +stage1 build` on a separate rust project to run a newly-built toolchain"
@ -219,6 +229,33 @@ fn try_link_toolchain(stage_path: &str) -> bool {
.map_or(false, |output| output.status.success())
}
fn ensure_stage1_toolchain_placeholder_exists(stage_path: &str) -> bool {
let pathbuf = PathBuf::from(stage_path);
if fs::create_dir_all(pathbuf.join("lib")).is_err() {
return false;
};
let pathbuf = pathbuf.join("bin");
if fs::create_dir_all(&pathbuf).is_err() {
return false;
};
let pathbuf = pathbuf.join(format!("rustc{}", EXE_SUFFIX));
if pathbuf.exists() {
return true;
}
// Take care not to overwrite the file
let result = File::options().append(true).create(true).open(&pathbuf);
if result.is_err() {
return false;
}
return true;
}
// Used to get the path for `Subcommand::Setup`
pub fn interactive_path() -> io::Result<Profile> {
fn abbrev_all() -> impl Iterator<Item = ((String, String), Profile)> {
@ -271,9 +308,9 @@ fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
let mut input = String::new();
println!(
"Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` on each commit
to ensure your code is up to par. If you decide later that this behavior is undesirable,
simply delete the `pre-commit` file from .git/hooks."
If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before
pushing your code to ensure your code is up to par. If you decide later that this behavior is
undesirable, simply delete the `pre-push` file from .git/hooks."
);
let should_install = loop {
@ -293,21 +330,21 @@ fn install_git_hook_maybe(src_path: &Path) -> io::Result<()> {
};
if should_install {
let src = src_path.join("src").join("etc").join("pre-commit.sh");
let src = src_path.join("src").join("etc").join("pre-push.sh");
let git = t!(Command::new("git").args(&["rev-parse", "--git-common-dir"]).output().map(
|output| {
assert!(output.status.success(), "failed to run `git`");
PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
}
));
let dst = git.join("hooks").join("pre-commit");
let dst = git.join("hooks").join("pre-push");
match fs::hard_link(src, &dst) {
Err(e) => println!(
"error: could not create hook {}: do you already have the git hook installed?\n{}",
dst.display(),
e
),
Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-commit`"),
Ok(_) => println!("Linked `src/etc/pre-commit.sh` to `.git/hooks/pre-push`"),
};
} else {
println!("Ok, skipping installation!");

View File

@ -16,7 +16,7 @@ if [[ "$OSTYPE" == "msys" || "$OSTYPE" == "win32" ]]; then
COMMAND="python $COMMAND"
fi
echo "Running pre-commit script '$COMMAND'"
echo "Running pre-push script '$COMMAND'"
cd "$ROOT_DIR"

View File

@ -951,10 +951,11 @@ fn add_test(&mut self, test: String, config: LangString, line: usize) {
},
// compiler failures are test failures
should_panic: test::ShouldPanic::No,
allow_fail: config.allow_fail,
compile_fail: config.compile_fail,
no_run,
test_type: test::TestType::DocTest,
#[cfg(bootstrap)]
allow_fail: false,
},
testfn: test::DynTestFn(box move || {
let report_unused_externs = |uext| {

View File

@ -847,7 +847,6 @@ fn error_invalid_codeblock_attr(&self, msg: &str, help: &str) {
crate test_harness: bool,
crate compile_fail: bool,
crate error_codes: Vec<String>,
crate allow_fail: bool,
crate edition: Option<Edition>,
}
@ -869,7 +868,6 @@ fn default() -> Self {
test_harness: false,
compile_fail: false,
error_codes: Vec::new(),
allow_fail: false,
edition: None,
}
}
@ -943,10 +941,6 @@ fn parse(
seen_rust_tags = !seen_other_tags;
}
}
"allow_fail" => {
data.allow_fail = true;
seen_rust_tags = !seen_other_tags;
}
"rust" => {
data.rust = true;
seen_rust_tags = true;
@ -994,12 +988,6 @@ fn parse(
"the code block will either not be tested if not marked as a rust one \
or will be run (which you might not want)",
))
} else if s == "allow-fail" || s == "allow_fail" || s == "allowfail" {
Some((
"allow_fail",
"the code block will either not be tested if not marked as a rust one \
or will be run (which you might not want)",
))
} else if s == "test-harness" || s == "test_harness" || s == "testharness" {
Some((
"test_harness",

View File

@ -70,7 +70,6 @@ fn t(lg: LangString) {
compile_fail: true,
..Default::default()
});
t(LangString { original: "allow_fail".into(), allow_fail: true, ..Default::default() });
t(LangString { original: "no_run,example".into(), no_run: true, ..Default::default() });
t(LangString {
original: "sh,should_panic".into(),

View File

@ -472,6 +472,7 @@ nav.sub {
}
.block ul, .block li {
padding: 0;
margin: 0;
list-style: none;
}
@ -502,8 +503,6 @@ nav.sub {
font-weight: 500;
padding: 0;
margin: 0;
margin-top: 0.5rem;
margin-bottom: 0.25rem;
}
.sidebar-links,

View File

@ -559,7 +559,15 @@ function hideThemeButtonState() {
others.appendChild(div);
}
function block(shortty, longty) {
/**
* Append to the sidebar a "block" of links - a heading along with a list (`<ul>`) of items.
*
* @param {string} shortty - A short type name, like "primitive", "mod", or "macro"
* @param {string} id - The HTML id of the corresponding section on the module page.
* @param {string} longty - A long, capitalized, plural name, like "Primitive Types",
* "Modules", or "Macros".
*/
function block(shortty, id, longty) {
var filtered = items[shortty];
if (!filtered) {
return;
@ -568,7 +576,7 @@ function hideThemeButtonState() {
var div = document.createElement("div");
div.className = "block " + shortty;
var h3 = document.createElement("h3");
h3.textContent = longty;
h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`;
div.appendChild(h3);
var ul = document.createElement("ul");
@ -607,20 +615,20 @@ function hideThemeButtonState() {
var isModule = hasClass(document.body, "mod");
if (!isModule) {
block("primitive", "Primitive Types");
block("mod", "Modules");
block("macro", "Macros");
block("struct", "Structs");
block("enum", "Enums");
block("union", "Unions");
block("constant", "Constants");
block("static", "Statics");
block("trait", "Traits");
block("fn", "Functions");
block("type", "Type Definitions");
block("foreigntype", "Foreign Types");
block("keyword", "Keywords");
block("traitalias", "Trait Aliases");
block("primitive", "primitives", "Primitive Types");
block("mod", "modules", "Modules");
block("macro", "macros", "Macros");
block("struct", "structs", "Structs");
block("enum", "enums", "Enums");
block("union", "unions", "Unions");
block("constant", "constants", "Constants");
block("static", "static", "Statics");
block("trait", "traits", "Traits");
block("fn", "functions", "Functions");
block("type", "types", "Type Definitions");
block("foreigntype", "foreign-types", "Foreign Types");
block("keyword", "keywords", "Keywords");
block("traitalias", "trait-aliases", "Trait Aliases");
}
// `crates{version}.js` should always be loaded before this script, so we can use

View File

@ -7,4 +7,4 @@
{ "type": "test", "name": "c", "event": "ok" }
{ "type": "test", "event": "started", "name": "d" }
{ "type": "test", "name": "d", "event": "ignored" }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }

View File

@ -7,4 +7,4 @@
{ "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" }
{ "type": "test", "event": "started", "name": "d" }
{ "type": "test", "name": "d", "event": "ignored" }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "allowed_fail": 0, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }
{ "type": "suite", "event": "failed", "passed": 2, "failed": 1, "ignored": 1, "measured": 0, "filtered_out": 0, "exec_time": $TIME }

View File

@ -39,4 +39,4 @@ assert-position: ("#method\.must_use", {"y": 45})
// Check that the bottom-most item on the sidebar menu can be scrolled fully into view.
click: ".sidebar-menu-toggle"
scroll-to: ".block.keyword li:nth-child(1)"
assert-position: (".block.keyword li:nth-child(1)", {"y": 542.96875})
assert-position: (".block.keyword li:nth-child(1)", {"y": 542.234375})

View File

@ -78,3 +78,10 @@ assert-text: ("#functions + .item-table .item-left > a", "foo")
// Links to trait implementations in the sidebar should not wrap even if they are long.
goto: file://|DOC_PATH|/lib2/struct.HasALongTraitWithParams.html
assert-property: (".sidebar-links a", {"offsetHeight": 29})
// Test that clicking on of the "In <module>" headings in the sidebar links to the
// appropriate anchor in index.html.
goto: file://|DOC_PATH|/test_docs/struct.Foo.html
click: ".block.mod h3 a"
// PAGE: index.html
assert-css: ("#modules", {"background-color": "rgb(253, 255, 211)"})

View File

@ -23,13 +23,6 @@ pub fn bar() {}
/// ```
pub fn foobar() {}
/// barfoo
///
/// ```allow-fail,allowfail,allOw_fail
/// boo
/// ```
pub fn barfoo() {}
/// b
///
/// ```test-harness,testharness,tesT_harness

View File

@ -111,77 +111,41 @@ error: unknown attribute `nO_run`. Did you mean `no_run`?
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
--> $DIR/check-attr-test.rs:26:1
|
26 | / /// barfoo
27 | | ///
28 | | /// ```allow-fail,allowfail,allOw_fail
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `allowfail`. Did you mean `allow_fail`?
--> $DIR/check-attr-test.rs:26:1
|
26 | / /// barfoo
27 | | ///
28 | | /// ```allow-fail,allowfail,allOw_fail
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `allOw_fail`. Did you mean `allow_fail`?
--> $DIR/check-attr-test.rs:26:1
|
26 | / /// barfoo
27 | | ///
28 | | /// ```allow-fail,allowfail,allOw_fail
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `test-harness`. Did you mean `test_harness`?
--> $DIR/check-attr-test.rs:33:1
--> $DIR/check-attr-test.rs:26:1
|
33 | / /// b
34 | | ///
35 | | /// ```test-harness,testharness,tesT_harness
36 | | /// boo
37 | | /// ```
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: unknown attribute `testharness`. Did you mean `test_harness`?
--> $DIR/check-attr-test.rs:33:1
--> $DIR/check-attr-test.rs:26:1
|
33 | / /// b
34 | | ///
35 | | /// ```test-harness,testharness,tesT_harness
36 | | /// boo
37 | | /// ```
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: unknown attribute `tesT_harness`. Did you mean `test_harness`?
--> $DIR/check-attr-test.rs:33:1
--> $DIR/check-attr-test.rs:26:1
|
33 | / /// b
34 | | ///
35 | | /// ```test-harness,testharness,tesT_harness
36 | | /// boo
37 | | /// ```
26 | / /// b
27 | | ///
28 | | /// ```test-harness,testharness,tesT_harness
29 | | /// boo
30 | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: aborting due to 15 previous errors
error: aborting due to 12 previous errors

View File

@ -30,16 +30,6 @@ pub fn bar() {}
/// ```
pub fn foobar() {}
/// barfoo
//~^ ERROR
//~^^ ERROR
//~^^^ ERROR
///
/// ```allow-fail,allowfail,alLow_fail
/// boo
/// ```
pub fn barfoo() {}
/// b
//~^ ERROR
//~^^ ERROR

View File

@ -129,50 +129,8 @@ LL | | /// ```
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `allow-fail`. Did you mean `allow_fail`?
--> $DIR/check-attr.rs:33:1
|
LL | / /// barfoo
LL | |
LL | |
LL | |
... |
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `allowfail`. Did you mean `allow_fail`?
--> $DIR/check-attr.rs:33:1
|
LL | / /// barfoo
LL | |
LL | |
LL | |
... |
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `alLow_fail`. Did you mean `allow_fail`?
--> $DIR/check-attr.rs:33:1
|
LL | / /// barfoo
LL | |
LL | |
LL | |
... |
LL | | /// boo
LL | | /// ```
| |_______^
|
= help: the code block will either not be tested if not marked as a rust one or will be run (which you might not want)
error: unknown attribute `test-harness`. Did you mean `test_harness`?
--> $DIR/check-attr.rs:43:1
--> $DIR/check-attr.rs:33:1
|
LL | / /// b
LL | |
@ -186,7 +144,7 @@ LL | | /// ```
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: unknown attribute `testharness`. Did you mean `test_harness`?
--> $DIR/check-attr.rs:43:1
--> $DIR/check-attr.rs:33:1
|
LL | / /// b
LL | |
@ -200,7 +158,7 @@ LL | | /// ```
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: unknown attribute `teSt_harness`. Did you mean `test_harness`?
--> $DIR/check-attr.rs:43:1
--> $DIR/check-attr.rs:33:1
|
LL | / /// b
LL | |
@ -213,5 +171,5 @@ LL | | /// ```
|
= help: the code block will either not be tested if not marked as a rust one or the code will be wrapped inside a main function
error: aborting due to 15 previous errors
error: aborting due to 12 previous errors

View File

@ -6,6 +6,10 @@ LL | const TUP: (usize,) = 5usize << 64;
|
= note: expected tuple `(usize,)`
found type `usize`
help: use a trailing comma to create a tuple with one element
|
LL | const TUP: (usize,) = (5usize << 64,);
| + ++
error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
LL | const fn test1<T: std::ops::Add>() {}
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -13,7 +13,7 @@ error[E0658]: trait objects in const fn are unstable
LL | const fn test2(_x: &dyn Send) {}
| ^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -22,7 +22,7 @@ error[E0658]: trait objects in const fn are unstable
LL | const fn test3() -> &'static dyn Send { loop {} }
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to 3 previous errors

View File

@ -136,7 +136,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
LL | const fn foo11<T: std::fmt::Display>(t: T) -> T { t }
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@ -145,7 +145,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
LL | const fn foo11_2<T: Send>(t: T) -> T { t }
| ^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0013]: constant functions cannot refer to statics
@ -218,7 +218,7 @@ LL |
LL | const fn foo(&self) {}
| ------------------- function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@ -230,7 +230,7 @@ LL |
LL | const fn foo2(&self) {}
| -------------------- function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@ -242,7 +242,7 @@ LL |
LL | const fn foo3(&self) {}
| -------------------- function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable
@ -251,7 +251,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
LL | const fn no_apit2(_x: AlanTuring<impl std::fmt::Debug>) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
@ -268,7 +268,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl
LL | const fn no_apit(_x: impl std::fmt::Debug) {}
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0493]: destructors cannot be evaluated at compile-time
@ -285,7 +285,7 @@ error[E0658]: trait objects in const fn are unstable
LL | const fn no_dyn_trait(_x: &dyn std::fmt::Debug) {}
| ^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -294,7 +294,7 @@ error[E0658]: trait objects in const fn are unstable
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -305,7 +305,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
| |
| function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -316,7 +316,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
| |
| function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -327,7 +327,7 @@ LL | const fn really_no_traits_i_mean_it() { (&() as &dyn std::fmt::Debug, ()).1
| |
| function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: function pointers cannot appear in constant functions

View File

@ -6,7 +6,7 @@ LL | const fn no_inner_dyn_trait2(x: Hide) {
LL | x.0.field;
| ^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error[E0658]: trait objects in const fn are unstable
@ -17,7 +17,7 @@ LL | const fn no_inner_dyn_trait_ret() -> Hide { Hide(HasDyn { field: &0 }) }
| |
| function declared as const here
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to 2 previous errors

View File

@ -1,8 +0,0 @@
// check that #[allow_fail] is feature-gated
#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature
fn ok_to_fail() {
assert!(false);
}
fn main() {}

View File

@ -1,12 +0,0 @@
error[E0658]: the `#[allow_fail]` attribute is an experimental feature
--> $DIR/feature-gate-allow_fail.rs:3:1
|
LL | #[allow_fail]
| ^^^^^^^^^^^^^
|
= note: see issue #46488 <https://github.com/rust-lang/rust/issues/46488> for more information
= help: add `#![feature(allow_fail)]` to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View File

@ -0,0 +1,11 @@
fn main() {
let a = "a";
let b = "b";
println!("{a} {b} {} {} {c} {}", c = "c");
//~^ ERROR: invalid reference to positional arguments 1 and 2 (there is 1 argument)
let n = 1;
println!("{a:.n$} {b:.*}");
//~^ ERROR: invalid reference to positional argument 0 (no arguments were given)
}

View File

@ -0,0 +1,22 @@
error: invalid reference to positional arguments 1 and 2 (there is 1 argument)
--> $DIR/format-args-capture-issue-93378.rs:5:26
|
LL | println!("{a} {b} {} {} {c} {}", c = "c");
| ^^ ^^
|
= note: positional arguments are zero-based
error: invalid reference to positional argument 0 (no arguments were given)
--> $DIR/format-args-capture-issue-93378.rs:9:23
|
LL | println!("{a:.n$} {b:.*}");
| ------- ^^^--^
| | |
| | this precision flag adds an extra required argument at position 0, which is why there are 3 arguments expected
| this parameter corresponds to the precision flag
|
= note: positional arguments are zero-based
= note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
error: aborting due to 2 previous errors

View File

@ -5,6 +5,7 @@ fn main() {
named_argument_takes_precedence_to_captured();
formatting_parameters_can_be_captured();
capture_raw_strings_and_idents();
repeated_capture();
#[cfg(panic = "unwind")]
{
@ -80,3 +81,10 @@ fn formatting_parameters_can_be_captured() {
let s = format!("{x:-^width$.precision$}");
assert_eq!(&s, "--7.000--");
}
fn repeated_capture() {
let a = 1;
let b = 2;
let s = format!("{a} {b} {a}");
assert_eq!(&s, "1 2 1");
}

View File

@ -4,7 +4,7 @@ error[E0658]: trait objects in const fn are unstable
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
= note: see issue #93706 <https://github.com/rust-lang/rust/issues/93706> for more information
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
error: aborting due to previous error

View File

@ -10,6 +10,12 @@ fn main() {
let _: Option<(i8,)> = Some();
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
let _: Option<(i32,)> = Some(5_usize);
//~^ ERROR mismatched types
let _: Option<(i32,)> = Some((5_usize));
//~^ ERROR mismatched types
}
fn int_bool(_: (i32, bool)) {

View File

@ -15,7 +15,7 @@ LL | int_bool(1, 2);
| expected 1 argument
|
note: function defined here
--> $DIR/args-instead-of-tuple-errors.rs:15:4
--> $DIR/args-instead-of-tuple-errors.rs:21:4
|
LL | fn int_bool(_: (i32, bool)) {
| ^^^^^^^^ --------------
@ -28,6 +28,25 @@ LL | let _: Option<(i8,)> = Some();
| |
| expected 1 argument
error: aborting due to 3 previous errors
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple-errors.rs:14:34
|
LL | let _: Option<(i32,)> = Some(5_usize);
| ^^^^^^^ expected tuple, found `usize`
|
= note: expected tuple `(i32,)`
found type `usize`
For more information about this error, try `rustc --explain E0061`.
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple-errors.rs:17:34
|
LL | let _: Option<(i32,)> = Some((5_usize));
| ^^^^^^^^^ expected tuple, found `usize`
|
= note: expected tuple `(i32,)`
found type `usize`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0061, E0308.
For more information about an error, try `rustc --explain E0061`.

View File

@ -11,6 +11,12 @@ fn main() {
let _: Option<()> = Some(());
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
let _: Option<(i32,)> = Some((3,));
//~^ ERROR mismatched types
let _: Option<(i32,)> = Some((3,));
//~^ ERROR mismatched types
two_ints((1, 2)); //~ ERROR this function takes 1 argument
with_generic((3, 4)); //~ ERROR this function takes 1 argument

View File

@ -11,6 +11,12 @@ fn main() {
let _: Option<()> = Some();
//~^ ERROR this enum variant takes 1 argument but 0 arguments were supplied
let _: Option<(i32,)> = Some(3);
//~^ ERROR mismatched types
let _: Option<(i32,)> = Some((3));
//~^ ERROR mismatched types
two_ints(1, 2); //~ ERROR this function takes 1 argument
with_generic(3, 4); //~ ERROR this function takes 1 argument

View File

@ -31,14 +31,40 @@ help: expected the unit value `()`; create it with empty parentheses
LL | let _: Option<()> = Some(());
| ++
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple.rs:14:34
|
LL | let _: Option<(i32,)> = Some(3);
| ^ expected tuple, found integer
|
= note: expected tuple `(i32,)`
found type `{integer}`
help: use a trailing comma to create a tuple with one element
|
LL | let _: Option<(i32,)> = Some((3,));
| + ++
error[E0308]: mismatched types
--> $DIR/args-instead-of-tuple.rs:17:34
|
LL | let _: Option<(i32,)> = Some((3));
| ^^^ expected tuple, found integer
|
= note: expected tuple `(i32,)`
found type `{integer}`
help: use a trailing comma to create a tuple with one element
|
LL | let _: Option<(i32,)> = Some((3,));
| +
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:14:5
--> $DIR/args-instead-of-tuple.rs:20:5
|
LL | two_ints(1, 2);
| ^^^^^^^^ - - supplied 2 arguments
|
note: function defined here
--> $DIR/args-instead-of-tuple.rs:19:4
--> $DIR/args-instead-of-tuple.rs:25:4
|
LL | fn two_ints(_: (i32, i32)) {
| ^^^^^^^^ -------------
@ -48,13 +74,13 @@ LL | two_ints((1, 2));
| + +
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:16:5
--> $DIR/args-instead-of-tuple.rs:22:5
|
LL | with_generic(3, 4);
| ^^^^^^^^^^^^ - - supplied 2 arguments
|
note: function defined here
--> $DIR/args-instead-of-tuple.rs:22:4
--> $DIR/args-instead-of-tuple.rs:28:4
|
LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
| ^^^^^^^^^^^^ ----------------
@ -64,13 +90,13 @@ LL | with_generic((3, 4));
| + +
error[E0061]: this function takes 1 argument but 2 arguments were supplied
--> $DIR/args-instead-of-tuple.rs:25:9
--> $DIR/args-instead-of-tuple.rs:31:9
|
LL | with_generic(a, b);
| ^^^^^^^^^^^^ - - supplied 2 arguments
|
note: function defined here
--> $DIR/args-instead-of-tuple.rs:22:4
--> $DIR/args-instead-of-tuple.rs:28:4
|
LL | fn with_generic<T: Copy + Send>((a, b): (i32, T)) {
| ^^^^^^^^^^^^ ----------------
@ -79,6 +105,7 @@ help: use parentheses to construct a tuple
LL | with_generic((a, b));
| + +
error: aborting due to 6 previous errors
error: aborting due to 8 previous errors
For more information about this error, try `rustc --explain E0061`.
Some errors have detailed explanations: E0061, E0308.
For more information about an error, try `rustc --explain E0061`.

View File

@ -11,7 +11,7 @@ LL | let _x: (i32,) = (5);
help: use a trailing comma to create a tuple with one element
|
LL | let _x: (i32,) = (5,);
| ~~~~
| +
error[E0308]: mismatched types
--> $DIR/issue-86100-tuple-paren-comma.rs:13:9
@ -24,7 +24,7 @@ LL | foo((Some(3)));
help: use a trailing comma to create a tuple with one element
|
LL | foo((Some(3),));
| ~~~~~~~~~~
| +
error[E0308]: mismatched types
--> $DIR/issue-86100-tuple-paren-comma.rs:17:22
@ -37,7 +37,7 @@ LL | let _s = S { _s: ("abc".to_string()) };
help: use a trailing comma to create a tuple with one element
|
LL | let _s = S { _s: ("abc".to_string(),) };
| ~~~~~~~~~~~~~~~~~~~~
| +
error[E0308]: mismatched types
--> $DIR/issue-86100-tuple-paren-comma.rs:23:22

View File

@ -1,17 +0,0 @@
// run-pass
// compile-flags: --test
#![feature(allow_fail)]
#![feature(cfg_panic)]
#[test]
#[allow_fail]
fn test1() {
#[cfg(not(panic = "abort"))]
panic!();
}
#[test]
#[allow_fail]
fn test2() {
assert!(true);
}

View File

@ -922,10 +922,11 @@ pub fn make_test_description<R: Read>(
name,
ignore,
should_panic,
allow_fail: false,
compile_fail: false,
no_run: false,
test_type: test::TestType::Unknown,
#[cfg(bootstrap)]
allow_fail: false,
}
}