From 9d664b24f92fbbe22b3243014bb98f6878db30a9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 24 Aug 2021 19:51:53 -0500 Subject: [PATCH 01/23] Make the pre-commit script pre-push instead This should make it substantially less annoying, and hopefully more people will find it useful. In particular, it will no longer run tidy each time you run `git commit --amend` or rebase a branch. This also warns if you have the old script in pre-commit; see the HACK comment for details. --- src/bootstrap/bin/main.rs | 14 ++++++++++++++ src/bootstrap/setup.rs | 12 ++++++------ src/etc/{pre-commit.sh => pre-push.sh} | 2 +- 3 files changed, 21 insertions(+), 7 deletions(-) rename src/etc/{pre-commit.sh => pre-push.sh} (91%) diff --git a/src/bootstrap/bin/main.rs b/src/bootstrap/bin/main.rs index e730a2557e0bf..9c41ab69c8be3 100644 --- a/src/bootstrap/bin/main.rs +++ b/src/bootstrap/bin/main.rs @@ -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"); } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index a5829dfa9d879..6fafd7cf1d575 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -191,9 +191,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 { @@ -213,21 +213,21 @@ simply delete the `pre-commit` file from .git/hooks." }; 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!"); diff --git a/src/etc/pre-commit.sh b/src/etc/pre-push.sh similarity index 91% rename from src/etc/pre-commit.sh rename to src/etc/pre-push.sh index 9045adb54dc1e..a78725f2ab0d1 100755 --- a/src/etc/pre-commit.sh +++ b/src/etc/pre-push.sh @@ -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" From 9648b313cc8896970a12f45b3bb5c0593c3d510f Mon Sep 17 00:00:00 2001 From: Michael Watzko Date: Sat, 22 Jan 2022 17:14:09 +0100 Subject: [PATCH 02/23] Impl {Add,Sub,Mul,Div,Rem,BitXor,BitOr,BitAnd}Assign<$t> for Wrapping<$t> Analog to 1c0dc1810d778bb6fea16aac02cafc5aa2e84b11 #92356 --- library/core/src/num/wrapping.rs | 80 ++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index a0e42c51e4517..64cf7ac347a13 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -239,6 +239,16 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } + #[stable(feature = "wrapping_int_assign_impl", since = "1.61.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> { From 9b8e4c63de9949b0db0977eaa954ee7009485310 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 27 Jan 2022 23:50:46 +0100 Subject: [PATCH 03/23] Don't allow {} to refer to implicit captures in format_args. --- compiler/rustc_builtin_macros/src/format.rs | 35 ++++++++++++++------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 407aaacb88999..154c51b2c7b9e 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -23,6 +23,7 @@ enum ArgumentType { enum Position { Exact(usize), + Capture(usize), Named(Symbol), } @@ -47,6 +48,8 @@ struct Context<'a, 'b> { /// * `arg_unique_types` (in simplified JSON): `[["o", "x"], ["o", "x"], ["o", "x"]]` /// * `names` (in JSON): `{"foo": 2}` args: Vec>, + /// The number of arguments that were added by implicit capturing. + num_captured_args: usize, /// Placeholder slot numbers indexed by argument. arg_types: Vec>, /// Unique format specs seen for each argument. @@ -229,6 +232,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}")`. @@ -343,7 +351,7 @@ impl<'a, 'b> Context<'a, 'b> { } 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(), @@ -369,7 +377,7 @@ impl<'a, 'b> Context<'a, 'b> { 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!( @@ -417,7 +425,7 @@ impl<'a, 'b> Context<'a, 'b> { 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!( @@ -460,7 +468,7 @@ impl<'a, 'b> Context<'a, 'b> { 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!( @@ -492,12 +500,15 @@ impl<'a, 'b> Context<'a, 'b> { /// 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 @@ -524,7 +535,7 @@ impl<'a, 'b> Context<'a, 'b> { 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 @@ -539,9 +550,10 @@ impl<'a, 'b> Context<'a, 'b> { } 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 { @@ -1010,6 +1022,7 @@ pub fn expand_preparsed_format_args( let mut cx = Context { ecx, args, + num_captured_args: 0, arg_types, arg_unique_types, names, From fb2d530dd29e72efa140f6a51f3c2ddf033bc199 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 27 Jan 2022 23:51:11 +0100 Subject: [PATCH 04/23] Add test for format args capture bug. --- src/test/ui/fmt/format-args-capture-issue-93378.rs | 7 +++++++ src/test/ui/fmt/format-args-capture-issue-93378.stderr | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/test/ui/fmt/format-args-capture-issue-93378.rs create mode 100644 src/test/ui/fmt/format-args-capture-issue-93378.stderr diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.rs b/src/test/ui/fmt/format-args-capture-issue-93378.rs new file mode 100644 index 0000000000000..faaa4ca242ce7 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-93378.rs @@ -0,0 +1,7 @@ +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) +} diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.stderr b/src/test/ui/fmt/format-args-capture-issue-93378.stderr new file mode 100644 index 0000000000000..3890e3ca864d7 --- /dev/null +++ b/src/test/ui/fmt/format-args-capture-issue-93378.stderr @@ -0,0 +1,10 @@ +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: aborting due to previous error + From cef9b4758386622c2c52df0920eea978786283a0 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 27 Jan 2022 23:59:34 +0100 Subject: [PATCH 05/23] Extend format-args capture test. --- src/test/ui/fmt/format-args-capture-issue-93378.rs | 4 ++++ .../ui/fmt/format-args-capture-issue-93378.stderr | 14 +++++++++++++- src/test/ui/fmt/format-args-capture.rs | 8 ++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.rs b/src/test/ui/fmt/format-args-capture-issue-93378.rs index faaa4ca242ce7..6744444426472 100644 --- a/src/test/ui/fmt/format-args-capture-issue-93378.rs +++ b/src/test/ui/fmt/format-args-capture-issue-93378.rs @@ -4,4 +4,8 @@ fn main() { 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) } diff --git a/src/test/ui/fmt/format-args-capture-issue-93378.stderr b/src/test/ui/fmt/format-args-capture-issue-93378.stderr index 3890e3ca864d7..588541044fe13 100644 --- a/src/test/ui/fmt/format-args-capture-issue-93378.stderr +++ b/src/test/ui/fmt/format-args-capture-issue-93378.stderr @@ -6,5 +6,17 @@ LL | println!("{a} {b} {} {} {c} {}", c = "c"); | = note: positional arguments are zero-based -error: aborting due to previous error +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 diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index e830a5bc9c5c8..d31d2a6c33657 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/src/test/ui/fmt/format-args-capture.rs @@ -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"); +} From 6562069ebef1097109d315e50cf9929a30e86811 Mon Sep 17 00:00:00 2001 From: "yuhaixin.hx" Date: Fri, 28 Jan 2022 18:31:49 +0800 Subject: [PATCH 06/23] remove allow_fail test flag --- compiler/rustc_builtin_macros/src/test.rs | 9 --- compiler/rustc_feature/src/active.rs | 2 - compiler/rustc_feature/src/builtin_attrs.rs | 1 - compiler/rustc_feature/src/removed.rs | 2 + library/test/src/console.rs | 6 +- library/test/src/formatters/json.rs | 13 +--- library/test/src/formatters/junit.rs | 2 +- library/test/src/formatters/pretty.rs | 25 ++------ library/test/src/formatters/terse.rs | 25 ++------ library/test/src/test_result.rs | 13 ++-- library/test/src/tests.rs | 20 ------- library/test/src/types.rs | 4 -- src/librustdoc/doctest.rs | 1 - src/librustdoc/html/markdown.rs | 12 ---- src/librustdoc/html/markdown/tests.rs | 1 - .../libtest-json/output-default.json | 2 +- .../libtest-json/output-stdout-success.json | 2 +- src/test/rustdoc-ui/check-attr-test.rs | 7 --- src/test/rustdoc-ui/check-attr-test.stderr | 60 ++++--------------- src/test/rustdoc-ui/check-attr.rs | 10 ---- src/test/rustdoc-ui/check-attr.stderr | 50 ++-------------- .../feature-gates/feature-gate-allow_fail.rs | 8 --- .../feature-gate-allow_fail.stderr | 12 ---- .../ui/test-attrs/test-allow-fail-attr.rs | 17 ------ src/tools/compiletest/src/header.rs | 1 - 25 files changed, 35 insertions(+), 270 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-allow_fail.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-allow_fail.stderr delete mode 100644 src/test/ui/test-attrs/test-allow-fail-attr.rs diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index c08b141b557ca..9459bb7047f5c 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -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) => { diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 0b65a5ff3ecc3..d7e88ae53c12b 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -274,8 +274,6 @@ declare_features! ( (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. diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index fc7f01f041d34..810b58c316475 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -403,7 +403,6 @@ pub const BUILTIN_ATTRIBUTES: &[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", diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs index b9f3b5ad1b1fc..f5f944db5e90b 100644 --- a/compiler/rustc_feature/src/removed.rs +++ b/compiler/rustc_feature/src/removed.rs @@ -48,6 +48,8 @@ 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. diff --git a/library/test/src/console.rs b/library/test/src/console.rs index 9c261e8cc8eff..920f55ad251a6 100644 --- a/library/test/src/console.rs +++ b/library/test/src/console.rs @@ -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, @@ -71,7 +70,6 @@ impl ConsoleTestState { passed: 0, failed: 0, ignored: 0, - allowed_fail: 0, filtered_out: 0, measured: 0, exec_time: None, @@ -112,7 +110,6 @@ impl ConsoleTestState { 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 @@ impl ConsoleTestState { } 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(), diff --git a/library/test/src/formatters/json.rs b/library/test/src/formatters/json.rs index 424d3ef7b4106..c089bfc4791b5 100644 --- a/library/test/src/formatters/json.rs +++ b/library/test/src/formatters/json.rs @@ -124,15 +124,6 @@ impl OutputFormatter for JsonFormatter { 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 @@ impl OutputFormatter for JsonFormatter { \"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, diff --git a/library/test/src/formatters/junit.rs b/library/test/src/formatters/junit.rs index fa23cf2689671..6fc24fefa842b 100644 --- a/library/test/src/formatters/junit.rs +++ b/library/test/src/formatters/junit.rs @@ -122,7 +122,7 @@ impl OutputFormatter for JunitFormatter { ))?; } - TestResult::TrOk | TestResult::TrAllowedFail => { + TestResult::TrOk => { self.write_message(&*format!( "", diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs index 4a03b4b914760..4726ae864df77 100644 --- a/library/test/src/formatters/pretty.rs +++ b/library/test/src/formatters/pretty.rs @@ -49,10 +49,6 @@ impl PrettyFormatter { 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 @@ impl OutputFormatter for PrettyFormatter { 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 @@ impl OutputFormatter for PrettyFormatter { 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)?; diff --git a/library/test/src/formatters/terse.rs b/library/test/src/formatters/terse.rs index 1f2c410cd96f3..12aca7cd9a42d 100644 --- a/library/test/src/formatters/terse.rs +++ b/library/test/src/formatters/terse.rs @@ -54,10 +54,6 @@ impl TerseFormatter { 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 @@ impl OutputFormatter for TerseFormatter { 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 @@ impl OutputFormatter for TerseFormatter { 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)?; diff --git a/library/test/src/test_result.rs b/library/test/src/test_result.rs index c5c56ca9c7ff9..8c216a1e0e70e 100644 --- a/library/test/src/test_result.rs +++ b/library/test/src/test_result.rs @@ -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, exec_time: &Option, ) -> 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. diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 7f0b6193d09ac..8aba486bbf48f 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -62,7 +62,6 @@ fn one_ignored_one_unignored_test() -> Vec { name: StaticTestName("1"), ignore: true, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -74,7 +73,6 @@ fn one_ignored_one_unignored_test() -> Vec { name: StaticTestName("2"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -94,7 +92,6 @@ pub fn do_not_run_ignored_tests() { name: StaticTestName("whatever"), ignore: true, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -115,7 +112,6 @@ pub fn ignored_tests_result_in_ignored() { name: StaticTestName("whatever"), ignore: true, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -140,7 +136,6 @@ fn test_should_panic() { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::Yes, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -165,7 +160,6 @@ fn test_should_panic_good_message() { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::YesWithMessage("error message"), - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -195,7 +189,6 @@ fn test_should_panic_bad_message() { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::YesWithMessage(expected), - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -229,7 +222,6 @@ fn test_should_panic_non_string_message_type() { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::YesWithMessage(expected), - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -255,7 +247,6 @@ fn test_should_panic_but_succeeds() { name: StaticTestName("whatever"), ignore: false, should_panic, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -289,7 +280,6 @@ fn report_time_test_template(report_time: bool) -> Option { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -324,7 +314,6 @@ fn time_test_failure_template(test_type: TestType) -> TestResult { name: StaticTestName("whatever"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type, @@ -363,7 +352,6 @@ 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, @@ -476,7 +464,6 @@ 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, @@ -500,7 +487,6 @@ pub fn exact_filter_match() { name: StaticTestName(name), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -589,7 +575,6 @@ fn sample_tests() -> Vec { name: DynTestName((*name).clone()), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -740,7 +725,6 @@ pub fn test_bench_no_iter() { name: StaticTestName("f"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -762,7 +746,6 @@ pub fn test_bench_iter() { name: StaticTestName("f"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -778,7 +761,6 @@ 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, @@ -788,7 +770,6 @@ fn should_sort_failures_before_printing_them() { name: StaticTestName("b"), ignore: false, should_panic: ShouldPanic::No, - allow_fail: false, compile_fail: false, no_run: false, test_type: TestType::Unknown, @@ -802,7 +783,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, diff --git a/library/test/src/types.rs b/library/test/src/types.rs index 37bb38fb0df4e..90aa5e8b4f966 100644 --- a/library/test/src/types.rs +++ b/library/test/src/types.rs @@ -118,7 +118,6 @@ 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, @@ -150,9 +149,6 @@ impl TestDesc { } options::ShouldPanic::No => {} } - if self.allow_fail { - return Some("allow fail"); - } if self.compile_fail { return Some("compile fail"); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 024fe6345d295..f34580c107f7c 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -951,7 +951,6 @@ impl Tester for Collector { }, // 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, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index a9a3a0af276b1..a40181352f6c0 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -847,7 +847,6 @@ crate struct LangString { crate test_harness: bool, crate compile_fail: bool, crate error_codes: Vec, - crate allow_fail: bool, crate edition: Option, } @@ -869,7 +868,6 @@ impl Default for LangString { test_harness: false, compile_fail: false, error_codes: Vec::new(), - allow_fail: false, edition: None, } } @@ -943,10 +941,6 @@ impl LangString { 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 @@ impl LangString { "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", diff --git a/src/librustdoc/html/markdown/tests.rs b/src/librustdoc/html/markdown/tests.rs index d4af3663b624a..ea6575d179d86 100644 --- a/src/librustdoc/html/markdown/tests.rs +++ b/src/librustdoc/html/markdown/tests.rs @@ -70,7 +70,6 @@ fn test_lang_string_parse() { 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(), diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json index 099b65a23cad6..e2c778aa86509 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-default.json +++ b/src/test/run-make-fulldeps/libtest-json/output-default.json @@ -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 } diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json index fd676799a7664..68eb00c297ea7 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json +++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json @@ -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 } diff --git a/src/test/rustdoc-ui/check-attr-test.rs b/src/test/rustdoc-ui/check-attr-test.rs index 023d620bea222..e955470148a16 100644 --- a/src/test/rustdoc-ui/check-attr-test.rs +++ b/src/test/rustdoc-ui/check-attr-test.rs @@ -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 diff --git a/src/test/rustdoc-ui/check-attr-test.stderr b/src/test/rustdoc-ui/check-attr-test.stderr index affd0372a1f5e..b1fa9edf0e4cb 100644 --- a/src/test/rustdoc-ui/check-attr-test.stderr +++ b/src/test/rustdoc-ui/check-attr-test.stderr @@ -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`? +error: unknown attribute `test-harness`. Did you mean `test_harness`? --> $DIR/check-attr-test.rs:26:1 | -26 | / /// barfoo +26 | / /// b 27 | | /// -28 | | /// ```allow-fail,allowfail,allOw_fail +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 will be run (which you might not want) + = 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 `allowfail`. Did you mean `allow_fail`? +error: unknown attribute `testharness`. Did you mean `test_harness`? --> $DIR/check-attr-test.rs:26:1 | -26 | / /// barfoo +26 | / /// b 27 | | /// -28 | | /// ```allow-fail,allowfail,allOw_fail +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 will be run (which you might not want) + = 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 `allOw_fail`. Did you mean `allow_fail`? +error: unknown attribute `tesT_harness`. Did you mean `test_harness`? --> $DIR/check-attr-test.rs:26:1 | -26 | / /// barfoo +26 | / /// b 27 | | /// -28 | | /// ```allow-fail,allowfail,allOw_fail +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 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 - | -33 | / /// b -34 | | /// -35 | | /// ```test-harness,testharness,tesT_harness -36 | | /// boo -37 | | /// ``` - | |_______^ - | - = 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 - | -33 | / /// b -34 | | /// -35 | | /// ```test-harness,testharness,tesT_harness -36 | | /// boo -37 | | /// ``` - | |_______^ - | - = 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 - | -33 | / /// b -34 | | /// -35 | | /// ```test-harness,testharness,tesT_harness -36 | | /// boo -37 | | /// ``` | |_______^ | = 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 diff --git a/src/test/rustdoc-ui/check-attr.rs b/src/test/rustdoc-ui/check-attr.rs index 763bc4c6cddb9..0b3f7bedda5cf 100644 --- a/src/test/rustdoc-ui/check-attr.rs +++ b/src/test/rustdoc-ui/check-attr.rs @@ -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 diff --git a/src/test/rustdoc-ui/check-attr.stderr b/src/test/rustdoc-ui/check-attr.stderr index 9312cfb76f35f..370b804c56c64 100644 --- a/src/test/rustdoc-ui/check-attr.stderr +++ b/src/test/rustdoc-ui/check-attr.stderr @@ -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 diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.rs b/src/test/ui/feature-gates/feature-gate-allow_fail.rs deleted file mode 100644 index 287d4ccf18010..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-allow_fail.rs +++ /dev/null @@ -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() {} diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr deleted file mode 100644 index 76115fb969833..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr +++ /dev/null @@ -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 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`. diff --git a/src/test/ui/test-attrs/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs deleted file mode 100644 index 29ce9f7c2e94f..0000000000000 --- a/src/test/ui/test-attrs/test-allow-fail-attr.rs +++ /dev/null @@ -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); -} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 27d59bc01f22a..603b0b68a42b0 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -922,7 +922,6 @@ pub fn make_test_description( name, ignore, should_panic, - allow_fail: false, compile_fail: false, no_run: false, test_type: test::TestType::Unknown, From 0b8c9fbf0bd5e7e9917e7c26e9216d41ddcd2ef7 Mon Sep 17 00:00:00 2001 From: "yuhaixin.hx" Date: Fri, 28 Jan 2022 19:07:00 +0800 Subject: [PATCH 07/23] add allow_fail field in TestDesc to pass check --- library/test/src/tests.rs | 38 +++++++++++++++++++++++++++++ library/test/src/types.rs | 2 ++ src/librustdoc/doctest.rs | 2 ++ src/tools/compiletest/src/header.rs | 2 ++ 4 files changed, 44 insertions(+) diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs index 8aba486bbf48f..9b9c520568662 100644 --- a/library/test/src/tests.rs +++ b/library/test/src/tests.rs @@ -65,6 +65,8 @@ fn one_ignored_one_unignored_test() -> Vec { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(move || {})), }, @@ -76,6 +78,8 @@ fn one_ignored_one_unignored_test() -> Vec { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(move || {})), }, @@ -95,6 +99,8 @@ pub fn do_not_run_ignored_tests() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -115,6 +121,8 @@ pub fn ignored_tests_result_in_ignored() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -139,6 +147,8 @@ fn test_should_panic() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -163,6 +173,8 @@ fn test_should_panic_good_message() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -192,6 +204,8 @@ fn test_should_panic_bad_message() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -225,6 +239,8 @@ fn test_should_panic_non_string_message_type() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -250,6 +266,8 @@ fn test_should_panic_but_succeeds() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -283,6 +301,8 @@ fn report_time_test_template(report_time: bool) -> Option { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -317,6 +337,8 @@ fn time_test_failure_template(test_type: TestType) -> TestResult { compile_fail: false, no_run: false, test_type, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(f)), }; @@ -355,6 +377,8 @@ fn typed_test_desc(test_type: TestType) -> TestDesc { compile_fail: false, no_run: false, test_type, + #[cfg(bootstrap)] + allow_fail: false, } } @@ -467,6 +491,8 @@ pub fn exclude_should_panic_option() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(move || {})), }); @@ -490,6 +516,8 @@ pub fn exact_filter_match() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(move || {})), }) @@ -578,6 +606,8 @@ fn sample_tests() -> Vec { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }, testfn: DynTestFn(Box::new(testfn)), }; @@ -728,6 +758,8 @@ pub fn test_bench_no_iter() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }; crate::bench::benchmark(TestId(0), desc, tx, true, f); @@ -749,6 +781,8 @@ pub fn test_bench_iter() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }; crate::bench::benchmark(TestId(0), desc, tx, true, f); @@ -764,6 +798,8 @@ fn should_sort_failures_before_printing_them() { compile_fail: false, no_run: false, test_type: TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, }; let test_b = TestDesc { @@ -773,6 +809,8 @@ fn should_sort_failures_before_printing_them() { 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); diff --git a/library/test/src/types.rs b/library/test/src/types.rs index 90aa5e8b4f966..43e5a10ebbe95 100644 --- a/library/test/src/types.rs +++ b/library/test/src/types.rs @@ -121,6 +121,8 @@ pub struct TestDesc { pub compile_fail: bool, pub no_run: bool, pub test_type: TestType, + #[cfg(bootstrap)] + pub allow_fail: bool, } impl TestDesc { diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index f34580c107f7c..b9432b204eee9 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -954,6 +954,8 @@ impl Tester for Collector { 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| { diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 603b0b68a42b0..da7a19139c65b 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -925,6 +925,8 @@ pub fn make_test_description( compile_fail: false, no_run: false, test_type: test::TestType::Unknown, + #[cfg(bootstrap)] + allow_fail: false, } } From 4738ce463e29da3bb96d14d15e77519bf21bcd49 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 4 Dec 2021 17:33:59 +0000 Subject: [PATCH 08/23] Suggest 1-tuple parentheses, without existing parens --- .../src/infer/error_reporting/mod.rs | 20 +++++++++---------- .../ui/consts/const-tup-index-span.stderr | 4 ++++ src/test/ui/typeck/issue-84768.stderr | 4 ++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 1eb8190bd7d2f..486dec50d9ef5 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2046,16 +2046,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // 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, - ); - } + let code_stripped = code + .strip_prefix('(') + .and_then(|s| s.strip_suffix(')')) + .unwrap_or(&code); + err.span_suggestion( + span, + "use a trailing comma to create a tuple with one element", + format!("({},)", code_stripped), + Applicability::MaybeIncorrect, + ); } } // If a character was expected and the found expression is a string literal diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index 6724984d8d7ac..392d83a6f345b 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -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 diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr index 0a79d539ea962..f99d389f940d4 100644 --- a/src/test/ui/typeck/issue-84768.stderr +++ b/src/test/ui/typeck/issue-84768.stderr @@ -12,6 +12,10 @@ LL | ::call_once(f, 1) | = note: expected tuple `(&mut u8,)` found type `{integer}` +help: use a trailing comma to create a tuple with one element + | +LL | ::call_once(f, (1,)) + | ~~~~ error: aborting due to 2 previous errors From c734c32776e26861c89e261b8757522e46031978 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 4 Dec 2021 22:22:23 +0000 Subject: [PATCH 09/23] Replace span suggestion with multipart --- .../src/infer/error_reporting/mod.rs | 20 ++++++++----------- .../ui/consts/const-tup-index-span.stderr | 2 +- src/test/ui/typeck/issue-84768.stderr | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 486dec50d9ef5..e169e9a843197 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2045,18 +2045,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // 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) { - let code_stripped = code - .strip_prefix('(') - .and_then(|s| s.strip_suffix(')')) - .unwrap_or(&code); - err.span_suggestion( - span, - "use a trailing comma to create a tuple with one element", - format!("({},)", code_stripped), - Applicability::MaybeIncorrect, - ); - } + err.multipart_suggestion( + "use a trailing comma to create a tuple with one element", + vec![ + (span.shrink_to_lo(), "(".into()), + (span.shrink_to_hi(), ",)".into()), + ], + Applicability::MaybeIncorrect, + ); } // 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 diff --git a/src/test/ui/consts/const-tup-index-span.stderr b/src/test/ui/consts/const-tup-index-span.stderr index 392d83a6f345b..d301f8c4054c2 100644 --- a/src/test/ui/consts/const-tup-index-span.stderr +++ b/src/test/ui/consts/const-tup-index-span.stderr @@ -9,7 +9,7 @@ LL | const TUP: (usize,) = 5usize << 64; help: use a trailing comma to create a tuple with one element | LL | const TUP: (usize,) = (5usize << 64,); - | ~~~~~~~~~~~~~~~ + | + ++ error: aborting due to previous error diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr index f99d389f940d4..331aa25c7a3d4 100644 --- a/src/test/ui/typeck/issue-84768.stderr +++ b/src/test/ui/typeck/issue-84768.stderr @@ -15,7 +15,7 @@ LL | ::call_once(f, 1) help: use a trailing comma to create a tuple with one element | LL | ::call_once(f, (1,)) - | ~~~~ + | + ++ error: aborting due to 2 previous errors From 18cea90d4a01cbb3a1285f633b1058fd39931956 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Fri, 28 Jan 2022 22:32:16 +0000 Subject: [PATCH 10/23] Handle existing parentheses when suggesting trailing-tuple-comma --- .../src/infer/error_reporting/mod.rs | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index e169e9a843197..71a81d12839dc 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2045,14 +2045,27 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // parentheses around it, perhaps the user meant to write `(expr,)` to // build a tuple (issue #86100) (ty::Tuple(_), _) if expected.tuple_fields().count() == 1 => { - err.multipart_suggestion( - "use a trailing comma to create a tuple with one element", - vec![ - (span.shrink_to_lo(), "(".into()), - (span.shrink_to_hi(), ",)".into()), - ], - Applicability::MaybeIncorrect, - ); + if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span) { + 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(), + "use a trailing comma to create a tuple with one element", + ",".into(), + Applicability::MaybeIncorrect, + ); + } else { + err.multipart_suggestion( + "use a trailing comma to create a tuple with one element", + vec![ + (span.shrink_to_lo(), "(".into()), + (span.shrink_to_hi(), ",)".into()), + ], + Applicability::MaybeIncorrect, + ); + } + } } // 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 From 91a43f04237dc9fe839fe8466d459e4f215d02fc Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Fri, 28 Jan 2022 23:17:47 +0000 Subject: [PATCH 11/23] Only suggest 1-tuple if expected and found types match --- .../src/infer/error_reporting/mod.rs | 48 +++++++++++-------- src/test/ui/typeck/issue-84768.stderr | 4 -- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 71a81d12839dc..c16181aab04fb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2044,26 +2044,34 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // 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 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(), - "use a trailing comma to create a tuple with one element", - ",".into(), - Applicability::MaybeIncorrect, - ); - } else { - err.multipart_suggestion( - "use a trailing comma to create a tuple with one element", - vec![ - (span.shrink_to_lo(), "(".into()), - (span.shrink_to_hi(), ",)".into()), - ], - Applicability::MaybeIncorrect, - ); + (ty::Tuple(_), _) => { + if let [expected_tup_elem] = + expected.tuple_fields().collect::>()[..] + { + if same_type_modulo_infer(expected_tup_elem, found) { + if let Ok(code) = + self.tcx.sess().source_map().span_to_snippet(span) + { + 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(), + "use a trailing comma to create a tuple with one element", + ",".into(), + Applicability::MaybeIncorrect, + ); + } else { + err.multipart_suggestion( + "use a trailing comma to create a tuple with one element", + vec![ + (span.shrink_to_lo(), "(".into()), + (span.shrink_to_hi(), ",)".into()), + ], + Applicability::MaybeIncorrect, + ); + } + } } } } diff --git a/src/test/ui/typeck/issue-84768.stderr b/src/test/ui/typeck/issue-84768.stderr index 331aa25c7a3d4..0a79d539ea962 100644 --- a/src/test/ui/typeck/issue-84768.stderr +++ b/src/test/ui/typeck/issue-84768.stderr @@ -12,10 +12,6 @@ LL | ::call_once(f, 1) | = note: expected tuple `(&mut u8,)` found type `{integer}` -help: use a trailing comma to create a tuple with one element - | -LL | ::call_once(f, (1,)) - | + ++ error: aborting due to 2 previous errors From 72d3b45af055276b07e73611278268282848a139 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Fri, 28 Jan 2022 23:27:01 +0000 Subject: [PATCH 12/23] Test 1-tuple parentheses wrapping --- .../args-instead-of-tuple-errors.rs | 6 +++ .../args-instead-of-tuple-errors.stderr | 25 +++++++++-- .../suggestions/args-instead-of-tuple.fixed | 6 +++ .../ui/suggestions/args-instead-of-tuple.rs | 6 +++ .../suggestions/args-instead-of-tuple.stderr | 43 +++++++++++++++---- .../issue-86100-tuple-paren-comma.stderr | 6 +-- 6 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs index 2c3ee5fcb8039..5403b8d6d2871 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple-errors.rs +++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.rs @@ -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)) { diff --git a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr index a2ad602dbd47a..ddcdfb1c3b344 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr +++ b/src/test/ui/suggestions/args-instead-of-tuple-errors.stderr @@ -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` + +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 -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`. diff --git a/src/test/ui/suggestions/args-instead-of-tuple.fixed b/src/test/ui/suggestions/args-instead-of-tuple.fixed index c9b8a41d469b9..66e53f9ce2c80 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple.fixed +++ b/src/test/ui/suggestions/args-instead-of-tuple.fixed @@ -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 diff --git a/src/test/ui/suggestions/args-instead-of-tuple.rs b/src/test/ui/suggestions/args-instead-of-tuple.rs index d4cc3024dd0d2..a15bff07ebfe6 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple.rs +++ b/src/test/ui/suggestions/args-instead-of-tuple.rs @@ -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 diff --git a/src/test/ui/suggestions/args-instead-of-tuple.stderr b/src/test/ui/suggestions/args-instead-of-tuple.stderr index 172db7ee3df38..6a7602c9d0f45 100644 --- a/src/test/ui/suggestions/args-instead-of-tuple.stderr +++ b/src/test/ui/suggestions/args-instead-of-tuple.stderr @@ -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((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((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`. diff --git a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr index 9c8356a528470..0016f19284250 100644 --- a/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr +++ b/src/test/ui/suggestions/issue-86100-tuple-paren-comma.stderr @@ -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 From 0fb2b7a2da00fb323f43f2e503b79086135b5906 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 5 Feb 2022 14:50:46 -0500 Subject: [PATCH 13/23] Drop json::from_reader Performing UTF-8 decode outside the JSON module makes more sense in almost all cases. --- compiler/rustc_serialize/src/json.rs | 22 ---------------------- compiler/rustc_target/src/spec/mod.rs | 4 ++-- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_serialize/src/json.rs b/compiler/rustc_serialize/src/json.rs index 044de8e4e2483..6a39854924122 100644 --- a/compiler/rustc_serialize/src/json.rs +++ b/compiler/rustc_serialize/src/json.rs @@ -185,8 +185,6 @@ use self::ParserState::*; 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 @@ impl fmt::Display for ErrorCode { } } -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 @@ impl> Builder { } } -/// Decodes a json value from an `&mut io::Read` -pub fn from_reader(rdr: &mut dyn Read) -> Result { - 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 { let mut builder = Builder::new(s.chars()); diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 4effb8bacf6d6..51ab32a79adc5 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -2145,8 +2145,8 @@ impl Target { 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) } From 2f236246d03852e3d86bb04b1b1da263efd64425 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 5 Feb 2022 20:11:50 -0500 Subject: [PATCH 14/23] Drop time dependency from bootstrap This was only used for the inclusion of 'current' dates into our manpages, but it is not clear that this is practically necessary. The manpage is essentially never updated, and so we can likely afford to keep a manual date in these files. It also seems possible to just omit it, but that may cause other tools trouble, so avoid doing that for now. --- Cargo.lock | 1 - src/bootstrap/Cargo.toml | 1 - src/bootstrap/dist.rs | 25 +++---------------------- src/bootstrap/lib.rs | 20 +------------------- src/doc/man/rustc.1 | 2 +- src/doc/man/rustdoc.1 | 2 +- 6 files changed, 6 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 208ce841759b9..81f34c457a187 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -236,7 +236,6 @@ dependencies = [ "pretty_assertions", "serde", "serde_json", - "time", "toml", "winapi", ] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index b68b2163f873a..bf8dc31667c2d 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -44,7 +44,6 @@ libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" toml = "0.5" -time = "0.1" ignore = "0.4.10" opener = "0.5" once_cell = "1.7.2" diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 66b63cd1278c5..472ee3fb01474 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -24,7 +24,6 @@ use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, timeit}; use crate::{Compiler, DependencyType, Mode, LLVM_TOOLS}; -use time::{self, Timespec}; pub fn pkgname(builder: &Builder<'_>, component: &str) -> String { format!("{}-{}", component, builder.rust_package_vers()) @@ -422,33 +421,15 @@ impl Step for Rustc { let man_src = builder.src.join("src/doc/man"); let man_dst = image.join("share/man/man1"); - // Reproducible builds: If SOURCE_DATE_EPOCH is set, use that as the time. - let time = env::var("SOURCE_DATE_EPOCH") - .map(|timestamp| { - let epoch = timestamp - .parse() - .map_err(|err| format!("could not parse SOURCE_DATE_EPOCH: {}", err)) - .unwrap(); - - time::at(Timespec::new(epoch, 0)) - }) - .unwrap_or_else(|_| time::now()); - - let month_year = t!(time::strftime("%B %Y", &time)); // don't use our `bootstrap::util::{copy, cp_r}`, because those try // to hardlink, and we don't want to edit the source templates for file_entry in builder.read_dir(&man_src) { let page_src = file_entry.path(); let page_dst = man_dst.join(file_entry.file_name()); + let src_text = t!(std::fs::read_to_string(&page_src)); + let new_text = src_text.replace("", &builder.version); + t!(std::fs::write(&page_dst, &new_text)); t!(fs::copy(&page_src, &page_dst)); - // template in month/year and version number - builder.replace_in_file( - &page_dst, - &[ - ("", &month_year), - ("", &builder.version), - ], - ); } // Debugger scripts diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e5f84d417bf0b..b2ae57438efc4 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -106,8 +106,7 @@ use std::cell::{Cell, RefCell}; use std::collections::{HashMap, HashSet}; use std::env; -use std::fs::{self, File, OpenOptions}; -use std::io::{Read, Seek, SeekFrom, Write}; +use std::fs::{self, File}; use std::path::{Path, PathBuf}; use std::process::{self, Command}; use std::str; @@ -1335,23 +1334,6 @@ impl Build { } } - /// Search-and-replaces within a file. (Not maximally efficiently: allocates a - /// new string for each replacement.) - pub fn replace_in_file(&self, path: &Path, replacements: &[(&str, &str)]) { - if self.config.dry_run { - return; - } - let mut contents = String::new(); - let mut file = t!(OpenOptions::new().read(true).write(true).open(path)); - t!(file.read_to_string(&mut contents)); - for &(target, replacement) in replacements { - contents = contents.replace(target, replacement); - } - t!(file.seek(SeekFrom::Start(0))); - t!(file.set_len(0)); - t!(file.write_all(contents.as_bytes())); - } - /// Copies the `src` directory recursively to `dst`. Both are assumed to exist /// when this function is called. pub fn cp_r(&self, src: &Path, dst: &Path) { diff --git a/src/doc/man/rustc.1 b/src/doc/man/rustc.1 index 3788e3c864e82..4e7170806d47b 100644 --- a/src/doc/man/rustc.1 +++ b/src/doc/man/rustc.1 @@ -1,4 +1,4 @@ -.TH RUSTC "1" "" "rustc " "User Commands" +.TH RUSTC "1" "April 2019" "rustc " "User Commands" .SH NAME rustc \- The Rust compiler .SH SYNOPSIS diff --git a/src/doc/man/rustdoc.1 b/src/doc/man/rustdoc.1 index d7f78e8f6f4de..e618534797282 100644 --- a/src/doc/man/rustdoc.1 +++ b/src/doc/man/rustdoc.1 @@ -1,4 +1,4 @@ -.TH RUSTDOC "1" "" "rustdoc " "User Commands" +.TH RUSTDOC "1" "July 2018" "rustdoc " "User Commands" .SH NAME rustdoc \- generate documentation from Rust source code .SH SYNOPSIS From a4112dc7b5c8240f4e9163c1f696426e3899a26d Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Sat, 5 Feb 2022 19:57:02 -0800 Subject: [PATCH 15/23] fix linking stage1 toolchain in setup --- src/bootstrap/setup.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 5bc0a505bf695..a28815d09761b 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -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 { fn abbrev_all() -> impl Iterator { From e27ebb5dff38aad9fbaa3d957820a1bd3c8d3bbf Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Thu, 3 Feb 2022 22:50:32 -0800 Subject: [PATCH 16/23] Linkify sidebar headings for sibling items Also adjust CSS so this doesn't produce excess padding/margin. --- src/librustdoc/html/static/css/rustdoc.css | 3 +- src/librustdoc/html/static/js/main.js | 40 +++++++++++++--------- src/test/rustdoc-gui/sidebar-mobile.goml | 2 +- src/test/rustdoc-gui/sidebar.goml | 7 ++++ 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a431bb63f63e0..b28c8766f8a8c 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -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, diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index cab3c28342dab..8e1919f75d671 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -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 (`
    `) 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 = `${longty}`; 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 diff --git a/src/test/rustdoc-gui/sidebar-mobile.goml b/src/test/rustdoc-gui/sidebar-mobile.goml index 60bcffe120bec..ef588a69f1d5f 100644 --- a/src/test/rustdoc-gui/sidebar-mobile.goml +++ b/src/test/rustdoc-gui/sidebar-mobile.goml @@ -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}) diff --git a/src/test/rustdoc-gui/sidebar.goml b/src/test/rustdoc-gui/sidebar.goml index ef3a92ad7a6ce..9505e00512f4c 100644 --- a/src/test/rustdoc-gui/sidebar.goml +++ b/src/test/rustdoc-gui/sidebar.goml @@ -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 " 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)"}) From 57b102ff73504d45318a66e0df852b74aacd5ca4 Mon Sep 17 00:00:00 2001 From: Ruby Lazuli Date: Sat, 5 Feb 2022 15:02:00 -0600 Subject: [PATCH 17/23] Fix tracking issue for `const_fn_trait_bound` It previously pointed to #57563, the conglomerate issue for `const fn` (presumably under the feature gate `const_fn`). `const_fn_trait_bounds` weren't mentioned here, so this commit changes its tracking issue to a new one. --- compiler/rustc_feature/src/active.rs | 2 +- .../consts/const_fn_trait_bound.stock.stderr | 6 ++--- .../consts/min_const_fn/min_const_fn.stderr | 24 +++++++++---------- .../min_const_fn/min_const_fn_dyn.stderr | 4 ++-- src/test/ui/nll/issue-55825-const-fn.stderr | 2 +- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index bfe2459dc8dc1..aed6ad3f8eca4 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -332,7 +332,7 @@ declare_features! ( /// 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`. diff --git a/src/test/ui/consts/const_fn_trait_bound.stock.stderr b/src/test/ui/consts/const_fn_trait_bound.stock.stderr index d652b5268a8bf..7d9e18cb341f3 100644 --- a/src/test/ui/consts/const_fn_trait_bound.stock.stderr +++ b/src/test/ui/consts/const_fn_trait_bound.stock.stderr @@ -4,7 +4,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl LL | const fn test1() {} | ^ | - = note: see issue #57563 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #93706 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/min_const_fn/min_const_fn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn.stderr index fd1ab6f64bf56..67cb604b6a7be 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn.stderr @@ -136,7 +136,7 @@ error[E0658]: trait bounds other than `Sized` on const fn parameters are unstabl LL | const fn foo11(t: T) -> T { t } | ^ | - = note: see issue #57563 for more information + = note: see issue #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: T) -> T { t } | ^ | - = note: see issue #57563 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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) {} | ^^^^^^^^^^^^^^^^^^^^ | - = note: see issue #57563 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 for more information + = note: see issue #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 diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr index 6eec1df5aeca7..4c2199101d302 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_dyn.stderr @@ -6,7 +6,7 @@ LL | const fn no_inner_dyn_trait2(x: Hide) { LL | x.0.field; | ^^^^^^^^^ | - = note: see issue #57563 for more information + = note: see issue #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 for more information + = note: see issue #93706 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/issue-55825-const-fn.stderr b/src/test/ui/nll/issue-55825-const-fn.stderr index 9af5180343bf2..c834f8bd9c4f5 100644 --- a/src/test/ui/nll/issue-55825-const-fn.stderr +++ b/src/test/ui/nll/issue-55825-const-fn.stderr @@ -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 for more information + = note: see issue #93706 for more information = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable error: aborting due to previous error From afb7a502f6e4e564d034ebf9601f4a4a13551f15 Mon Sep 17 00:00:00 2001 From: Inteon <42113979+inteon@users.noreply.github.com> Date: Sun, 6 Feb 2022 20:07:03 +0100 Subject: [PATCH 18/23] rewrite from_bytes_with_nul to match code style in from_vec_with_nul Signed-off-by: Inteon <42113979+inteon@users.noreply.github.com> --- library/std/src/ffi/c_str.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs index 66fee2fe54837..e10c6a5daf13e 100644 --- a/library/std/src/ffi/c_str.rs +++ b/library/std/src/ffi/c_str.rs @@ -1252,15 +1252,16 @@ impl 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()), } } From 344ea6e0e5d5fca3fbfb065a9fd03eff55f76471 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 2 Feb 2022 22:18:36 +0000 Subject: [PATCH 19/23] Factor out emit_tuple_wrap_err, improve Applicability --- .../src/infer/error_reporting/mod.rs | 68 +++++++++++-------- 1 file changed, 39 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index c16181aab04fb..3b7e861e44efa 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2045,35 +2045,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // parentheses around it, perhaps the user meant to write `(expr,)` to // build a tuple (issue #86100) (ty::Tuple(_), _) => { - if let [expected_tup_elem] = - expected.tuple_fields().collect::>()[..] - { - if same_type_modulo_infer(expected_tup_elem, found) { - if let Ok(code) = - self.tcx.sess().source_map().span_to_snippet(span) - { - 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(), - "use a trailing comma to create a tuple with one element", - ",".into(), - Applicability::MaybeIncorrect, - ); - } else { - err.multipart_suggestion( - "use a trailing comma to create a tuple with one element", - vec![ - (span.shrink_to_lo(), "(".into()), - (span.shrink_to_hi(), ",)".into()), - ], - Applicability::MaybeIncorrect, - ); - } - } - } - } + 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 @@ -2136,6 +2108,44 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { 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::>()[..] + 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 }; + + 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(), + "use a trailing comma to create a tuple with one element", + ",".into(), + Applicability::MachineApplicable, + ); + } else { + err.multipart_suggestion( + "use a trailing comma to create a tuple with one element", + vec![ + (span.shrink_to_lo(), "(".into()), + (span.shrink_to_hi(), ",)".into()), + ], + Applicability::MachineApplicable, + ); + } + } + fn values_str( &self, values: ValuePairs<'tcx>, From 82a012299dcf6fefc107cbb7036465fe94ec1e2d Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 2 Feb 2022 22:22:13 +0000 Subject: [PATCH 20/23] Merge duplicate suggestion string --- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 3b7e861e44efa..c5da9977db782 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2125,22 +2125,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { 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(), - "use a trailing comma to create a tuple with one element", + msg, ",".into(), Applicability::MachineApplicable, ); } else { err.multipart_suggestion( - "use a trailing comma to create a tuple with one element", - vec![ - (span.shrink_to_lo(), "(".into()), - (span.shrink_to_hi(), ",)".into()), - ], + msg, + vec![(span.shrink_to_lo(), "(".into()), (span.shrink_to_hi(), ",)".into())], Applicability::MachineApplicable, ); } From 1870db6e4176732275b8be728863f018561b533b Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 6 Feb 2022 19:37:35 -0600 Subject: [PATCH 21/23] Use shallow clones for submodules managed by rustbuild, not just bootstrap.py I missed this in https://github.com/rust-lang/rust/pull/89757; it made `x.py test src/bootstrap` very slow. --- src/bootstrap/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index e5f84d417bf0b..1a42d25c352d3 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -527,7 +527,7 @@ impl Build { // 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"); } From b5b21507c1a9ce2aa94a5cce6789d2b3281e62b8 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 6 Feb 2022 19:54:35 -0600 Subject: [PATCH 22/23] Rerun bootstrap's build script when RUSTC changes Previously, rustbuild would give strange errors if you tried to reuse the same build directory under two names: ``` $ mkdir tmp && cd tmp $ ../x.py check Building rustbuild Finished dev [unoptimized] target(s) in 35.27s Checking stage0 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu) ^C $ cd .. $ mv tmp/build build $ ./x.py check Building rustbuild Compiling bootstrap v0.0.0 (/home/jnelson/rust-lang/rust/src/bootstrap) Finished dev [unoptimized] target(s) in 11.18s failed to execute command: "/home/jnelson/rust-lang/rust/tmp/build/x86_64-unknown-linux-gnu/stage0/bin/rustc" "--target" "x86_64-unknown-linux-gnu" "--print" "target-libdir" error: No such file or directory (os error 2) ``` This fixes the error. Reusing the same build directory is useful if you want to test path-things in bootstrap itself, without having to recompile it each time. For good measure, this also reruns the build script when PATH changes. --- src/bootstrap/build.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/build.rs b/src/bootstrap/build.rs index d40b924e0ff5f..6e39ea00f808c 100644 --- a/src/bootstrap/build.rs +++ b/src/bootstrap/build.rs @@ -3,6 +3,8 @@ use std::path::PathBuf; 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. From 14ff58cd862e3dff8d87e445932d37116924aeb2 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 7 Feb 2022 11:45:12 +0100 Subject: [PATCH 23/23] Stabilize wrapping_int_assign_impl in 1.60.0. --- library/core/src/num/wrapping.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/library/core/src/num/wrapping.rs b/library/core/src/num/wrapping.rs index 64cf7ac347a13..5353d900e7662 100644 --- a/library/core/src/num/wrapping.rs +++ b/library/core/src/num/wrapping.rs @@ -239,7 +239,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const AddAssign, add_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -272,7 +272,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const SubAssign, sub_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -305,7 +305,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const MulAssign, mul_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -338,7 +338,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const DivAssign, div_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -371,7 +371,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const RemAssign, rem_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -417,7 +417,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitXorAssign, bitxor_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -450,7 +450,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitOrAssign, bitor_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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] @@ -483,7 +483,7 @@ macro_rules! wrapping_impl { } forward_ref_op_assign! { impl const BitAndAssign, bitand_assign for Wrapping<$t>, Wrapping<$t> } - #[stable(feature = "wrapping_int_assign_impl", since = "1.61.0")] + #[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]