about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/param-attrs.md27
-rw-r--r--src/liballoc/alloc.rs2
-rw-r--r--src/libcore/panicking.rs2
-rw-r--r--src/librustc/error_codes.rs34
-rw-r--r--src/librustc/lint/builtin.rs4
-rw-r--r--src/librustc/middle/resolve_lifetime.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs4
-rw-r--r--src/librustc/ty/error.rs2
-rw-r--r--src/librustc_lint/types.rs4
-rw-r--r--src/librustc_lint/unused.rs22
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs3
-rw-r--r--src/librustc_resolve/check_unused.rs4
-rw-r--r--src/librustc_resolve/late/diagnostics.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs4
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/expr.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/librustc_typeck/check/pat.rs14
-rw-r--r--src/libstd/sys/vxworks/fs.rs2
-rw-r--r--src/libstd/sys/vxworks/os.rs23
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs5
-rw-r--r--src/libsyntax/feature_gate/accepted.rs2
-rw-r--r--src/libsyntax/feature_gate/active.rs3
-rw-r--r--src/libsyntax/feature_gate/check.rs1
-rw-r--r--src/libsyntax/parse/attr.rs7
-rw-r--r--src/libsyntax/parse/diagnostics.rs8
-rw-r--r--src/libsyntax/parse/mod.rs2
-rw-r--r--src/libsyntax/parse/parser.rs4
-rw-r--r--src/libsyntax/parse/parser/expr.rs9
-rw-r--r--src/libsyntax/parse/parser/path.rs7
-rw-r--r--src/libsyntax/parse/parser/ty.rs6
-rw-r--r--src/libsyntax_ext/format.rs3
-rw-r--r--src/test/ui/issues/issue-10291.stderr1
-rw-r--r--src/test/ui/issues/issue-52533.stderr1
-rw-r--r--src/test/ui/issues/issue-64559.rs6
-rw-r--r--src/test/ui/issues/issue-64559.stderr18
-rw-r--r--src/test/ui/issues/issue-64593.rs12
-rw-r--r--src/test/ui/lint/lint-unused-mut-variables.rs2
-rw-r--r--src/test/ui/lint/lint-unused-variables.rs2
-rw-r--r--src/test/ui/lub-if.stderr1
-rw-r--r--src/test/ui/lub-match.stderr1
-rw-r--r--src/test/ui/nll/issue-52742.stderr1
-rw-r--r--src/test/ui/nll/issue-55401.stderr1
-rw-r--r--src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr1
-rw-r--r--src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr1
-rw-r--r--src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr1
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.rs4
-rw-r--r--src/test/ui/parser/fn-arg-doc-comment.stderr33
-rw-r--r--src/test/ui/regions/regions-early-bound-error-method.stderr1
-rw-r--r--src/test/ui/regions/regions-early-bound-error.stderr1
-rw-r--r--src/test/ui/regions/regions-nested-fns.stderr1
-rw-r--r--src/test/ui/regions/regions-static-bound.migrate.stderr3
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs1
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr104
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs2
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs16
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr27
-rw-r--r--src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs1
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs1
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr50
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr1
-rw-r--r--src/test/ui/wf/wf-static-method.stderr3
66 files changed, 252 insertions, 280 deletions
diff --git a/src/doc/unstable-book/src/language-features/param-attrs.md b/src/doc/unstable-book/src/language-features/param-attrs.md
deleted file mode 100644
index 4b83c204ba1..00000000000
--- a/src/doc/unstable-book/src/language-features/param-attrs.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# `param_attrs`
-
-The tracking issue for this feature is: [#60406]
-
-[#60406]: https://github.com/rust-lang/rust/issues/60406
-
-Allow attributes in formal function parameter position so external tools and compiler internals can
-take advantage of the additional information that the parameters provide.
-
-Enables finer conditional compilation with `#[cfg(..)]` and linting control of variables. Moreover,
-opens the path to richer DSLs created by users.
-
-------------------------
-
-Example:
-
-```rust
-#![feature(param_attrs)]
-
-fn len(
-  #[cfg(windows)] slice: &[u16],
-  #[cfg(not(windows))] slice: &[u8],
-) -> usize
-{
-  slice.len()
-}
-```
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index dc7fd1adc29..a39fcd5ad4c 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -240,7 +240,7 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
 #[stable(feature = "global_alloc", since = "1.28.0")]
 #[rustc_allocator_nounwind]
 pub fn handle_alloc_error(layout: Layout) -> ! {
-    #[allow(improper_ctypes)]
+    #[cfg_attr(bootstrap, allow(improper_ctypes))]
     extern "Rust" {
         #[lang = "oom"]
         fn oom_impl(layout: Layout) -> !;
diff --git a/src/libcore/panicking.rs b/src/libcore/panicking.rs
index 15b7d69c58d..3d2bc24bf24 100644
--- a/src/libcore/panicking.rs
+++ b/src/libcore/panicking.rs
@@ -71,7 +71,7 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3
     }
 
     // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
-    #[allow(improper_ctypes)] // PanicInfo contains a trait object which is not FFI safe
+    #[cfg_attr(boostrap_stdarch_ignore_this, allow(improper_ctypes))]
     extern "Rust" {
         #[lang = "panic_impl"]
         fn panic_impl(pi: &PanicInfo<'_>) -> !;
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index eee33846139..f6564f1fcd4 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -1347,6 +1347,39 @@ struct Foo<T: 'static> {
 ```
 "##,
 
+E0312: r##"
+Reference's lifetime of borrowed content doesn't match the expected lifetime.
+
+Erroneous code example:
+
+```compile_fail,E0312
+pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'static str {
+    if maybestr.is_none() {
+        "(none)"
+    } else {
+        let s: &'a str = maybestr.as_ref().unwrap();
+        s  // Invalid lifetime!
+    }
+}
+```
+
+To fix this error, either lessen the expected lifetime or find a way to not have
+to use this reference outside of its current scope (by running the code directly
+in the same block for example?):
+
+```
+// In this case, we can fix the issue by switching from "static" lifetime to 'a
+pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'a str {
+    if maybestr.is_none() {
+        "(none)"
+    } else {
+        let s: &'a str = maybestr.as_ref().unwrap();
+        s  // Ok!
+    }
+}
+```
+"##,
+
 E0317: r##"
 This error occurs when an `if` expression without an `else` block is used in a
 context where a type other than `()` is expected, for example a `let`
@@ -2202,7 +2235,6 @@ static X: u32 = 42;
 //  E0304, // expected signed integer constant
 //  E0305, // expected constant
     E0311, // thing may not live long enough
-    E0312, // lifetime of reference outlives lifetime of borrowed content
     E0313, // lifetime of borrowed pointer outlives lifetime of captured
            // variable
     E0314, // closure outlives stack frame
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index dd290572d7b..5906a6388a8 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -7,7 +7,7 @@
 use crate::lint::{LintPass, LateLintPass, LintArray};
 use crate::middle::stability;
 use crate::session::Session;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use syntax::ast;
 use syntax::source_map::Span;
 use syntax::symbol::Symbol;
@@ -524,7 +524,7 @@ pub(crate) fn add_elided_lifetime_in_path_suggestion(
     };
     db.span_suggestion(
         replace_span,
-        &format!("indicate the anonymous lifetime{}", if n >= 2 { "s" } else { "" }),
+        &format!("indicate the anonymous lifetime{}", pluralise!(n)),
         suggestion,
         Applicability::MachineApplicable
     );
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 8836a632a7c..d833a34385b 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -17,7 +17,7 @@ use crate::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
 use crate::rustc::lint;
 use crate::session::Session;
 use crate::util::nodemap::{DefIdMap, FxHashMap, FxHashSet, HirIdMap, HirIdSet};
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc_macros::HashStable;
 use std::borrow::Cow;
 use std::cell::Cell;
@@ -3047,7 +3047,7 @@ pub fn report_missing_lifetime_specifiers(
         span,
         E0106,
         "missing lifetime specifier{}",
-        if count > 1 { "s" } else { "" }
+        pluralise!(count)
     )
 }
 
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 1d87484ef09..c9018f1c290 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -33,7 +33,7 @@ use crate::ty::subst::Subst;
 use crate::ty::SubtypePredicate;
 use crate::util::nodemap::{FxHashMap, FxHashSet};
 
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use std::fmt;
 use syntax::ast;
 use syntax::symbol::{sym, kw};
@@ -1214,7 +1214,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 _ => format!("{} {}argument{}",
                              arg_length,
                              if distinct && arg_length > 1 { "distinct " } else { "" },
-                             if arg_length == 1 { "" } else { "s" }),
+                             pluralise!(arg_length))
             }
         };
 
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index 62910ec3204..5409cbc4129 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -196,7 +196,7 @@ impl<'tcx> ty::TyS<'tcx> {
                 let n = tcx.lift_to_global(&n).unwrap();
                 match n.try_eval_usize(tcx, ty::ParamEnv::empty()) {
                     Some(n) => {
-                        format!("array of {} element{}", n, if n != 1 { "s" } else { "" }).into()
+                        format!("array of {} element{}", n, pluralise!(n)).into()
                     }
                     None => "array".into(),
                 }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 3b8c06ba154..40261f6d137 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -975,7 +975,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
     fn check_foreign_item(&mut self, cx: &LateContext<'_, '_>, it: &hir::ForeignItem) {
         let mut vis = ImproperCTypesVisitor { cx };
         let abi = cx.tcx.hir().get_foreign_abi(it.hir_id);
-        if abi != Abi::RustIntrinsic && abi != Abi::PlatformIntrinsic {
+        if let Abi::Rust | Abi::RustCall | Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+            // Don't worry about types in internal ABIs.
+        } else {
             match it.node {
                 hir::ForeignItemKind::Fn(ref decl, _, _) => {
                     vis.check_foreign_fn(it.hir_id, decl);
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index c3975098351..2d4af2f606a 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -9,7 +9,7 @@ use lint::{LintPass, EarlyLintPass, LateLintPass};
 
 use syntax::ast;
 use syntax::attr;
-use syntax::errors::Applicability;
+use syntax::errors::{Applicability, pluralise};
 use syntax::feature_gate::{AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
 use syntax::print::pprust;
 use syntax::symbol::{kw, sym};
@@ -48,7 +48,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
         }
 
         let ty = cx.tables.expr_ty(&expr);
-        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", false);
+        let type_permits_lack_of_use = check_must_use_ty(cx, ty, &expr, s.span, "", "", 1);
 
         let mut fn_warned = false;
         let mut op_warned = false;
@@ -135,7 +135,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
             span: Span,
             descr_pre: &str,
             descr_post: &str,
-            plural: bool,
+            plural_len: usize,
         ) -> bool {
             if ty.is_unit() || cx.tcx.is_ty_uninhabited_from(
                 cx.tcx.hir().get_module_parent(expr.hir_id), ty)
@@ -143,13 +143,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                 return true;
             }
 
-            let plural_suffix = if plural { "s" } else { "" };
+            let plural_suffix = pluralise!(plural_len);
 
             match ty.sty {
                 ty::Adt(..) if ty.is_box() => {
                     let boxed_ty = ty.boxed_ty();
                     let descr_pre = &format!("{}boxed ", descr_pre);
-                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural)
+                    check_must_use_ty(cx, boxed_ty, expr, span, descr_pre, descr_post, plural_len)
                 }
                 ty::Adt(def, _) => {
                     check_must_use_def(cx, def.did, span, descr_pre, descr_post)
@@ -202,7 +202,15 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                     for (i, ty) in tys.iter().map(|k| k.expect_ty()).enumerate() {
                         let descr_post = &format!(" in tuple element {}", i);
                         let span = *spans.get(i).unwrap_or(&span);
-                        if check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, plural) {
+                        if check_must_use_ty(
+                            cx,
+                            ty,
+                            expr,
+                            span,
+                            descr_pre,
+                            descr_post,
+                            plural_len
+                        ) {
                             has_emitted = true;
                         }
                     }
@@ -216,7 +224,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnusedResults {
                             descr_pre,
                             plural_suffix,
                         );
-                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, true)
+                        check_must_use_ty(cx, ty, expr, span, descr_pre, descr_post, n as usize + 1)
                     }
                     // Otherwise, we don't lint, to avoid false positives.
                     _ => false,
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index 81359c6a46e..599a0ad0d0c 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -180,7 +180,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     );
                 }
                 if Some(DesugaringKind::ForLoop) == move_span.desugaring_kind() {
-                    if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
+                    let sess = self.infcx.tcx.sess;
+                    if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
                         err.span_suggestion(
                             move_span,
                             "consider borrowing to avoid moving into the for loop",
diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs
index 96d44b4b4c0..0d85be83e12 100644
--- a/src/librustc_resolve/check_unused.rs
+++ b/src/librustc_resolve/check_unused.rs
@@ -26,6 +26,8 @@
 use crate::Resolver;
 use crate::resolve_imports::ImportDirectiveSubclass;
 
+use errors::pluralise;
+
 use rustc::util::nodemap::NodeMap;
 use rustc::{lint, ty};
 use rustc_data_structures::fx::FxHashSet;
@@ -295,7 +297,7 @@ impl Resolver<'_> {
                 }).collect::<Vec<String>>();
             span_snippets.sort();
             let msg = format!("unused import{}{}",
-                            if len > 1 { "s" } else { "" },
+                            pluralise!(len),
                             if !span_snippets.is_empty() {
                                 format!(": {}", span_snippets.join(", "))
                             } else {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 0c86d8494fd..df8bd3fa75e 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -424,7 +424,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                 } else {
                     err.note("did you mean to use one of the enum's variants?");
                 }
-            },
+            }
             (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
                 if let Some((ctor_def, ctor_vis))
                         = self.r.struct_constructors.get(&def_id).cloned() {
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e77e8290f1f..360343169bc 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -11,7 +11,7 @@ use crate::{Resolver, ResolutionError, Segment, ModuleKind};
 use crate::{names_to_string, module_to_string};
 use crate::diagnostics::Suggestion;
 
-use errors::Applicability;
+use errors::{Applicability, pluralise};
 
 use rustc_data_structures::ptr_key::PtrKey;
 use rustc::ty;
@@ -728,7 +728,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
 
             let msg = format!(
                 "unresolved import{} {}",
-                if paths.len() > 1 { "s" } else { "" },
+                pluralise!(paths.len()),
                 paths.join(", "),
             );
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 09e6b769003..718d12484f7 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1346,7 +1346,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 span,
                 E0191,
                 "the value of the associated type{} {} must be specified",
-                if associated_types.len() == 1 { "" } else { "s" },
+                pluralise!(associated_types.len()),
                 names,
             );
             let (suggest, potential_assoc_types_spans) =
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 049f2eb16bb..1ae50b8cb28 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -17,7 +17,7 @@ use crate::util::common::ErrorReported;
 use crate::util::nodemap::FxHashMap;
 use crate::astconv::AstConv as _;
 
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use syntax::ast;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax::source_map::Span;
@@ -1178,7 +1178,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             struct_span_err!(tcx.sess, span, E0063,
                              "missing field{} {}{} in initializer of `{}`",
-                             if remaining_fields.len() == 1 { "" } else { "s" },
+                             pluralise!(remaining_fields.len()),
                              remaining_fields_names,
                              truncated_fields_error,
                              adt_ty)
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 3e45b1e98d4..74e4f28255b 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -5,7 +5,7 @@ use crate::check::FnCtxt;
 use crate::middle::lang_items::FnOnceTraitLangItem;
 use crate::namespace::Namespace;
 use crate::util::nodemap::FxHashSet;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc::hir::{self, ExprKind, Node, QPath};
 use rustc::hir::def::{Res, DefKind};
 use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId};
@@ -560,7 +560,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let help = format!("{an}other candidate{s} {were} found in the following \
                                         trait{s}, perhaps add a `use` for {one_of_them}:",
                                     an = if candidates.len() == 1 {"an" } else { "" },
-                                    s = if candidates.len() == 1 { "" } else { "s" },
+                                    s = pluralise!(candidates.len()),
                                     were = if candidates.len() == 1 { "was" } else { "were" },
                                     one_of_them = if candidates.len() == 1 {
                                         "it"
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0eeeee01c82..7ff8f9c95c8 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -88,7 +88,7 @@ pub mod intrinsic;
 mod op;
 
 use crate::astconv::{AstConv, PathSeg};
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
 use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath};
 use rustc::hir::def::{CtorOf, Res, DefKind};
 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -4935,5 +4935,5 @@ fn fatally_break_rust(sess: &Session) {
 }
 
 fn potentially_plural_count(count: usize, word: &str) -> String {
-    format!("{} {}{}", count, word, if count == 1 { "" } else { "s" })
+    format!("{} {}{}", count, word, pluralise!(count))
 }
diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs
index 8502b89de14..d93a4052cd3 100644
--- a/src/librustc_typeck/check/pat.rs
+++ b/src/librustc_typeck/check/pat.rs
@@ -1,6 +1,6 @@
 use crate::check::FnCtxt;
 use crate::util::nodemap::FxHashMap;
-use errors::{Applicability, DiagnosticBuilder};
+use errors::{Applicability, DiagnosticBuilder, pluralise};
 use rustc::hir::{self, PatKind, Pat, HirId};
 use rustc::hir::def::{Res, DefKind, CtorKind};
 use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -684,8 +684,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     fn e0023(&self, pat_span: Span, res: Res, subpats: &'tcx [P<Pat>], fields: &[ty::FieldDef]) {
-        let subpats_ending = if subpats.len() == 1 { "" } else { "s" };
-        let fields_ending = if fields.len() == 1 { "" } else { "s" };
+        let subpats_ending = pluralise!(subpats.len());
+        let fields_ending = pluralise!(fields.len());
         let res_span = self.tcx.def_span(res.def_id());
         struct_span_err!(
             self.tcx.sess,
@@ -1103,10 +1103,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0527,
             "pattern requires {} element{} but array has {}",
             min_len,
-            if min_len != 1 { "s" } else { "" },
+            pluralise!(min_len),
             size,
         )
-        .span_label(span, format!("expected {} element{}", size, if size != 1 { "s" } else { "" }))
+        .span_label(span, format!("expected {} element{}", size, pluralise!(size)))
         .emit();
     }
 
@@ -1117,14 +1117,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             E0528,
             "pattern requires at least {} element{} but array has {}",
             min_len,
-            if min_len != 1 { "s" } else { "" },
+            pluralise!(min_len),
             size,
         ).span_label(
             span,
             format!(
                 "pattern cannot match array of {} element{}",
                 size,
-                if size != 1 { "s" } else { "" },
+                pluralise!(size),
             ),
         ).emit();
     }
diff --git a/src/libstd/sys/vxworks/fs.rs b/src/libstd/sys/vxworks/fs.rs
index d537d2258fd..51fdb1c0e55 100644
--- a/src/libstd/sys/vxworks/fs.rs
+++ b/src/libstd/sys/vxworks/fs.rs
@@ -529,7 +529,7 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
     let p = cstr(p)?;
     let mut stat: stat64 = unsafe { mem::zeroed() };
     cvt(unsafe {
-        libc::lstat(p.as_ptr(), &mut stat as *mut _ as *mut _)
+        libc::stat(p.as_ptr(), &mut stat as *mut _ as *mut _)
     })?;
     Ok(FileAttr { stat })
 }
diff --git a/src/libstd/sys/vxworks/os.rs b/src/libstd/sys/vxworks/os.rs
index 5dc35a6176b..f4798da1876 100644
--- a/src/libstd/sys/vxworks/os.rs
+++ b/src/libstd/sys/vxworks/os.rs
@@ -287,28 +287,7 @@ pub fn temp_dir() -> PathBuf {
 }
 
 pub fn home_dir() -> Option<PathBuf> {
-    return crate::env::var_os("HOME").or_else(|| unsafe {
-        fallback()
-    }).map(PathBuf::from);
-
-    unsafe fn fallback() -> Option<OsString> {
-        let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
-            n if n < 0 => 512 as usize,
-            n => n as usize,
-        };
-        let mut buf = Vec::with_capacity(amt);
-        let mut passwd: libc::passwd = mem::zeroed();
-        let mut result = ptr::null_mut();
-        match libc::getpwuid_r(libc::getuid(), &mut passwd, buf.as_mut_ptr(),
-                                buf.capacity(), &mut result) {
-            0 if !result.is_null() => {
-                let ptr = passwd.pw_dir as *const _;
-                let bytes = CStr::from_ptr(ptr).to_bytes().to_vec();
-                Some(OsStringExt::from_vec(bytes))
-            },
-            _ => None,
-        }
-    }
+    None
 }
 
 pub fn exit(code: i32) -> ! {
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 23735727fe8..f9c07e3a2e4 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -8,6 +8,7 @@ use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint};
 
 use smallvec::{smallvec, SmallVec};
 
+use errors::pluralise;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
 use syntax_pos::hygiene::{ExpnId, Transparency};
@@ -348,10 +349,10 @@ impl LockstepIterSize {
                         "meta-variable `{}` repeats {} time{}, but `{}` repeats {} time{}",
                         l_id,
                         l_len,
-                        if l_len != 1 { "s" } else { "" },
+                        pluralise!(l_len),
                         r_id,
                         r_len,
-                        if r_len != 1 { "s" } else { "" },
+                        pluralise!(r_len),
                     );
                     LockstepIterSize::Contradiction(msg)
                 }
diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs
index eff9f90a861..5538daf388e 100644
--- a/src/libsyntax/feature_gate/accepted.rs
+++ b/src/libsyntax/feature_gate/accepted.rs
@@ -243,6 +243,8 @@ declare_features! (
     (accepted, async_await, "1.39.0", Some(50547), None),
     /// Allows mixing bind-by-move in patterns and references to those identifiers in guards.
     (accepted, bind_by_move_pattern_guards, "1.39.0", Some(15287), None),
+    /// Allows attributes in formal function parameters.
+    (accepted, param_attrs, "1.39.0", Some(60406), None),
 
     // -------------------------------------------------------------------------
     // feature-group-end: accepted features
diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs
index dd78777b569..38c16dbac6a 100644
--- a/src/libsyntax/feature_gate/active.rs
+++ b/src/libsyntax/feature_gate/active.rs
@@ -489,9 +489,6 @@ declare_features! (
     /// Allows the user of associated type bounds.
     (active, associated_type_bounds, "1.34.0", Some(52662), None),
 
-    /// Attributes on formal function params.
-    (active, param_attrs, "1.36.0", Some(60406), None),
-
     /// Allows calling constructor functions in `const fn`.
     (active, const_constructor, "1.37.0", Some(61456), None),
 
diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs
index b4491a87f06..b50ca1ad1cf 100644
--- a/src/libsyntax/feature_gate/check.rs
+++ b/src/libsyntax/feature_gate/check.rs
@@ -812,7 +812,6 @@ pub fn check_crate(krate: &ast::Crate,
         }
     }
 
-    gate_all!(param_attrs, "attributes on function parameters are unstable");
     gate_all!(let_chains, "`let` expressions in this position are experimental");
     gate_all!(async_closure, "async closures are unstable");
     gate_all!(yields, generators, "yield syntax is experimental");
diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs
index 9aa1ec0b14f..bba70973631 100644
--- a/src/libsyntax/parse/attr.rs
+++ b/src/libsyntax/parse/attr.rs
@@ -19,13 +19,6 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \
                                                      permitted in this context";
 
 impl<'a> Parser<'a> {
-    crate fn parse_param_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
-        let attrs = self.parse_outer_attributes()?;
-        self.sess.gated_spans.param_attrs.borrow_mut()
-            .extend(attrs.iter().map(|a| a.span));
-        Ok(attrs)
-    }
-
     /// Parses attributes that appear before an item.
     crate fn parse_outer_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> {
         let mut attrs: Vec<ast::Attribute> = Vec::new();
diff --git a/src/libsyntax/parse/diagnostics.rs b/src/libsyntax/parse/diagnostics.rs
index b74f2492c35..2d7f4f71ca4 100644
--- a/src/libsyntax/parse/diagnostics.rs
+++ b/src/libsyntax/parse/diagnostics.rs
@@ -11,7 +11,7 @@ use crate::ptr::P;
 use crate::symbol::{kw, sym};
 use crate::ThinVec;
 use crate::util::parser::AssocOp;
-use errors::{Applicability, DiagnosticBuilder, DiagnosticId};
+use errors::{Applicability, DiagnosticBuilder, DiagnosticId, pluralise};
 use rustc_data_structures::fx::FxHashSet;
 use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
 use log::{debug, trace};
@@ -532,15 +532,15 @@ impl<'a> Parser<'a> {
             self.eat_to_tokens(&[&end]);
             let span = lo.until(self.token.span);
 
-            let plural = number_of_gt > 1 || number_of_shr >= 1;
+            let total_num_of_gt = number_of_gt + number_of_shr * 2;
             self.diagnostic()
                 .struct_span_err(
                     span,
-                    &format!("unmatched angle bracket{}", if plural { "s" } else { "" }),
+                    &format!("unmatched angle bracket{}", pluralise!(total_num_of_gt)),
                 )
                 .span_suggestion(
                     span,
-                    &format!("remove extra angle bracket{}", if plural { "s" } else { "" }),
+                    &format!("remove extra angle bracket{}", pluralise!(total_num_of_gt)),
                     String::new(),
                     Applicability::MachineApplicable,
                 )
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 2441a027f99..f7b87d154fe 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -49,8 +49,6 @@ static_assert_size!(PResult<'_, bool>, 16);
 /// used and should be feature gated accordingly in `check_crate`.
 #[derive(Default)]
 pub struct GatedSpans {
-    /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`.
-    pub param_attrs: Lock<Vec<Span>>,
     /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`.
     pub let_chains: Lock<Vec<Span>>,
     /// Spans collected for gating `async_closure`, e.g. `async || ..`.
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fcebfa29962..b2b6504919e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -979,7 +979,7 @@ impl<'a> Parser<'a> {
         is_name_required: impl Fn(&token::Token) -> bool,
     ) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         if let Some(mut param) = self.parse_self_param()? {
             param.attrs = attrs.into();
             return self.recover_bad_self_param(param, is_trait_item);
@@ -1362,7 +1362,7 @@ impl<'a> Parser<'a> {
     /// Returns the parsed optional self parameter with attributes and whether a self
     /// shortcut was used.
     fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option<Param>> {
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         let param_opt = self.parse_self_param()?;
         Ok(param_opt.map(|mut param| {
             param.attrs = attrs.into();
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 31b28443abb..41c3747b950 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -66,6 +66,10 @@ pub(super) enum LhsExpr {
 }
 
 impl From<Option<ThinVec<Attribute>>> for LhsExpr {
+    /// Converts `Some(attrs)` into `LhsExpr::AttributesParsed(attrs)`
+    /// and `None` into `LhsExpr::NotYetParsed`.
+    ///
+    /// This conversion does not allocate.
     fn from(o: Option<ThinVec<Attribute>>) -> Self {
         if let Some(attrs) = o {
             LhsExpr::AttributesParsed(attrs)
@@ -76,6 +80,9 @@ impl From<Option<ThinVec<Attribute>>> for LhsExpr {
 }
 
 impl From<P<Expr>> for LhsExpr {
+    /// Converts the `expr: P<Expr>` into `LhsExpr::AlreadyParsed(expr)`.
+    ///
+    /// This conversion does not allocate.
     fn from(expr: P<Expr>) -> Self {
         LhsExpr::AlreadyParsed(expr)
     }
@@ -1176,7 +1183,7 @@ impl<'a> Parser<'a> {
     /// Parses a parameter in a closure header (e.g., `|arg, arg|`).
     fn parse_fn_block_param(&mut self) -> PResult<'a, Param> {
         let lo = self.token.span;
-        let attrs = self.parse_param_attributes()?;
+        let attrs = self.parse_outer_attributes()?;
         let pat = self.parse_pat(PARAM_EXPECTED)?;
         let t = if self.eat(&token::Colon) {
             self.parse_ty()?
diff --git a/src/libsyntax/parse/parser/path.rs b/src/libsyntax/parse/parser/path.rs
index d4b13cc2e01..dcd3c648017 100644
--- a/src/libsyntax/parse/parser/path.rs
+++ b/src/libsyntax/parse/parser/path.rs
@@ -9,7 +9,7 @@ use crate::symbol::kw;
 
 use std::mem;
 use log::debug;
-use errors::{Applicability};
+use errors::{Applicability, pluralise};
 
 /// Specifies how to parse a path.
 #[derive(Copy, Clone, PartialEq)]
@@ -347,20 +347,19 @@ impl<'a> Parser<'a> {
                 let span = lo.with_hi(
                     lo.lo() + BytePos(snapshot.unmatched_angle_bracket_count)
                 );
-                let plural = snapshot.unmatched_angle_bracket_count > 1;
                 self.diagnostic()
                     .struct_span_err(
                         span,
                         &format!(
                             "unmatched angle bracket{}",
-                            if plural { "s" } else { "" }
+                            pluralise!(snapshot.unmatched_angle_bracket_count)
                         ),
                     )
                     .span_suggestion(
                         span,
                         &format!(
                             "remove extra angle bracket{}",
-                            if plural { "s" } else { "" }
+                            pluralise!(snapshot.unmatched_angle_bracket_count)
                         ),
                         String::new(),
                         Applicability::MachineApplicable,
diff --git a/src/libsyntax/parse/parser/ty.rs b/src/libsyntax/parse/parser/ty.rs
index 465e31ac57e..5697edd8e48 100644
--- a/src/libsyntax/parse/parser/ty.rs
+++ b/src/libsyntax/parse/parser/ty.rs
@@ -11,7 +11,7 @@ use crate::symbol::{kw};
 
 use rustc_target::spec::abi::Abi;
 
-use errors::{Applicability};
+use errors::{Applicability, pluralise};
 
 /// Returns `true` if `IDENT t` can start a type -- `IDENT::a::b`, `IDENT<u8, u8>`,
 /// `IDENT<<u8 as Trait>::AssocTy>`.
@@ -397,7 +397,7 @@ impl<'a> Parser<'a> {
         }
 
         if !negative_bounds.is_empty() || was_negative {
-            let plural = negative_bounds.len() > 1;
+            let negative_bounds_len = negative_bounds.len();
             let last_span = negative_bounds.last().map(|sp| *sp);
             let mut err = self.struct_span_err(
                 negative_bounds,
@@ -420,7 +420,7 @@ impl<'a> Parser<'a> {
                 }
                 err.span_suggestion_hidden(
                     bound_list,
-                    &format!("remove the trait bound{}", if plural { "s" } else { "" }),
+                    &format!("remove the trait bound{}", pluralise!(negative_bounds_len)),
                     new_bound_list,
                     Applicability::MachineApplicable,
                 );
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 46c7cbb83de..26455df17b8 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -5,6 +5,7 @@ use fmt_macros as parse;
 
 use errors::DiagnosticBuilder;
 use errors::Applicability;
+use errors::pluralise;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
@@ -299,7 +300,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 &format!(
                     "{} positional argument{} in format string, but {}",
                     count,
-                    if count != 1 { "s" } else { "" },
+                    pluralise!(count),
                     self.describe_num_args(),
                 ),
             );
diff --git a/src/test/ui/issues/issue-10291.stderr b/src/test/ui/issues/issue-10291.stderr
index 5e63469da59..a836593e0da 100644
--- a/src/test/ui/issues/issue-10291.stderr
+++ b/src/test/ui/issues/issue-10291.stderr
@@ -20,3 +20,4 @@ LL | fn test<'x>(x: &'x isize) {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/issues/issue-52533.stderr b/src/test/ui/issues/issue-52533.stderr
index 1ed740c421e..58654800207 100644
--- a/src/test/ui/issues/issue-52533.stderr
+++ b/src/test/ui/issues/issue-52533.stderr
@@ -17,3 +17,4 @@ LL |     foo(|a, b| b)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/issues/issue-64559.rs b/src/test/ui/issues/issue-64559.rs
new file mode 100644
index 00000000000..71e054b5d98
--- /dev/null
+++ b/src/test/ui/issues/issue-64559.rs
@@ -0,0 +1,6 @@
+fn main() {
+    let orig = vec![true];
+    for _val in orig {}
+    let _closure = || orig;
+    //~^ ERROR use of moved value: `orig`
+}
diff --git a/src/test/ui/issues/issue-64559.stderr b/src/test/ui/issues/issue-64559.stderr
new file mode 100644
index 00000000000..3c685dc8d08
--- /dev/null
+++ b/src/test/ui/issues/issue-64559.stderr
@@ -0,0 +1,18 @@
+error[E0382]: use of moved value: `orig`
+  --> $DIR/issue-64559.rs:4:20
+   |
+LL |     let orig = vec![true];
+   |         ---- move occurs because `orig` has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
+LL |     for _val in orig {}
+   |                 ----
+   |                 |
+   |                 value moved here
+   |                 help: consider borrowing to avoid moving into the for loop: `&orig`
+LL |     let _closure = || orig;
+   |                    ^^ ---- use occurs due to use in closure
+   |                    |
+   |                    value used here after move
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/src/test/ui/issues/issue-64593.rs b/src/test/ui/issues/issue-64593.rs
new file mode 100644
index 00000000000..9e787f638a9
--- /dev/null
+++ b/src/test/ui/issues/issue-64593.rs
@@ -0,0 +1,12 @@
+// check-pass
+#![deny(improper_ctypes)]
+
+pub struct Error(std::num::NonZeroU32);
+
+extern "Rust" {
+    fn foo(dest: &mut [u8]) -> Result<(), Error>;
+}
+
+fn main() {
+    let _ = unsafe { foo(&mut []) };
+}
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs
index f140546b048..1af44ecf362 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/lint-unused-mut-variables.rs
@@ -3,7 +3,7 @@
 // Exercise the unused_mut attribute in some positive and negative cases
 
 #![deny(unused_mut)]
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 
 async fn baz_async(
     mut a: i32,
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
index 06b818636f9..1a6b5183f0f 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 #![deny(unused_variables)]
 
 async fn foo_async(
diff --git a/src/test/ui/lub-if.stderr b/src/test/ui/lub-if.stderr
index bb772d4c6c6..26f756c9183 100644
--- a/src/test/ui/lub-if.stderr
+++ b/src/test/ui/lub-if.stderr
@@ -26,3 +26,4 @@ LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/lub-match.stderr b/src/test/ui/lub-match.stderr
index 090af251436..0cb0a23c6f2 100644
--- a/src/test/ui/lub-match.stderr
+++ b/src/test/ui/lub-match.stderr
@@ -26,3 +26,4 @@ LL | pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/issue-52742.stderr b/src/test/ui/nll/issue-52742.stderr
index b9829158002..90a35177f4c 100644
--- a/src/test/ui/nll/issue-52742.stderr
+++ b/src/test/ui/nll/issue-52742.stderr
@@ -20,3 +20,4 @@ LL | |     }
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/issue-55401.stderr b/src/test/ui/nll/issue-55401.stderr
index 50debc6386f..4ec16ba055a 100644
--- a/src/test/ui/nll/issue-55401.stderr
+++ b/src/test/ui/nll/issue-55401.stderr
@@ -13,3 +13,4 @@ LL | fn static_to_a_to_static_through_ref_in_tuple<'a>(x: &'a u32) -> &'static u
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
index f49d68458be..0a8ad4221c9 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-normalize.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
index 451bcf41e42..d596aaf098f 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-1.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a>(_: &'a u32) -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
index d129e55e1e6..80ff9a043d4 100644
--- a/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
+++ b/src/test/ui/nll/user-annotations/constant-in-expr-trait-item-2.stderr
@@ -13,3 +13,4 @@ LL | fn foo<'a, T: Foo<'a>>() -> &'static u32 {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/parser/fn-arg-doc-comment.rs b/src/test/ui/parser/fn-arg-doc-comment.rs
index 4a4f959e213..995eb62d0bb 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.rs
+++ b/src/test/ui/parser/fn-arg-doc-comment.rs
@@ -2,14 +2,10 @@ pub fn f(
     /// Comment
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
     id: u8,
     /// Other
     //~^ ERROR documentation comments cannot be applied to function parameters
     //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
     a: u8,
 ) {}
 
diff --git a/src/test/ui/parser/fn-arg-doc-comment.stderr b/src/test/ui/parser/fn-arg-doc-comment.stderr
index d8884de1fe8..669785af45f 100644
--- a/src/test/ui/parser/fn-arg-doc-comment.stderr
+++ b/src/test/ui/parser/fn-arg-doc-comment.stderr
@@ -1,5 +1,5 @@
 error: attributes cannot be applied to a function parameter's type
-  --> $DIR/fn-arg-doc-comment.rs:16:12
+  --> $DIR/fn-arg-doc-comment.rs:12:12
    |
 LL | fn bar(id: #[allow(dead_code)] i32) {}
    |            ^^^^^^^^^^^^^^^^^^^ attributes are not allowed here
@@ -11,31 +11,13 @@ LL |     /// Comment
    |     ^^^^^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/fn-arg-doc-comment.rs:8:5
+  --> $DIR/fn-arg-doc-comment.rs:6:5
    |
 LL |     /// Other
    |     ^^^^^^^^^ doc comments are not allowed here
 
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/fn-arg-doc-comment.rs:2:5
-   |
-LL |     /// Comment
-   |     ^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/fn-arg-doc-comment.rs:8:5
-   |
-LL |     /// Other
-   |     ^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:22:7
+  --> $DIR/fn-arg-doc-comment.rs:18:7
    |
 LL |     f("", "");
    |       ^^ expected u8, found reference
@@ -44,7 +26,7 @@ LL |     f("", "");
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:22:11
+  --> $DIR/fn-arg-doc-comment.rs:18:11
    |
 LL |     f("", "");
    |           ^^ expected u8, found reference
@@ -53,7 +35,7 @@ LL |     f("", "");
               found type `&'static str`
 
 error[E0308]: mismatched types
-  --> $DIR/fn-arg-doc-comment.rs:29:9
+  --> $DIR/fn-arg-doc-comment.rs:25:9
    |
 LL |     bar("");
    |         ^^ expected i32, found reference
@@ -61,7 +43,6 @@ LL |     bar("");
    = note: expected type `i32`
               found type `&'static str`
 
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0308, E0658.
-For more information about an error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/regions/regions-early-bound-error-method.stderr b/src/test/ui/regions/regions-early-bound-error-method.stderr
index 2e5f55f8742..7b9f2c9503b 100644
--- a/src/test/ui/regions/regions-early-bound-error-method.stderr
+++ b/src/test/ui/regions/regions-early-bound-error-method.stderr
@@ -17,3 +17,4 @@ LL |     fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-early-bound-error.stderr b/src/test/ui/regions/regions-early-bound-error.stderr
index bc52f4bef7e..a68355b78f5 100644
--- a/src/test/ui/regions/regions-early-bound-error.stderr
+++ b/src/test/ui/regions/regions-early-bound-error.stderr
@@ -17,3 +17,4 @@ LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.stderr
index 15c9c9ca4dd..904dee6998c 100644
--- a/src/test/ui/regions/regions-nested-fns.stderr
+++ b/src/test/ui/regions/regions-nested-fns.stderr
@@ -57,3 +57,4 @@ LL | fn nested<'x>(x: &'x isize) {
 
 error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/regions/regions-static-bound.migrate.stderr b/src/test/ui/regions/regions-static-bound.migrate.stderr
index fc8cca929d3..21ead8b768f 100644
--- a/src/test/ui/regions/regions-static-bound.migrate.stderr
+++ b/src/test/ui/regions/regions-static-bound.migrate.stderr
@@ -30,4 +30,5 @@ LL |     static_id_indirect(&v);
 
 error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0621`.
+Some errors have detailed explanations: E0312, E0621.
+For more information about an error, try `rustc --explain E0312`.
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
index d71711336b0..a6f693bd5b5 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.rs
@@ -1,7 +1,5 @@
 // edition:2018
 
-#![feature(param_attrs)]
-
 trait Trait2015 { fn foo(#[allow(C)] i32); }
 //~^ ERROR expected one of `:`, `@`, or `|`, found `)`
 
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
index 26b414e4268..9860e9805b2 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-2018.stderr
@@ -1,5 +1,5 @@
 error: expected one of `:`, `@`, or `|`, found `)`
-  --> $DIR/param-attrs-2018.rs:5:41
+  --> $DIR/param-attrs-2018.rs:3:41
    |
 LL | trait Trait2015 { fn foo(#[allow(C)] i32); }
    |                                         ^ expected one of `:`, `@`, or `|` here
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
index 5eeda66173d..1217f89cb31 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-allowed.rs
@@ -2,7 +2,6 @@
 // compile-flags: --cfg something
 
 #![deny(unused_mut)]
-#![feature(param_attrs)]
 
 extern "C" {
     fn ffi(
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
index a8fe5d6c1f6..c4684a3fa82 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
@@ -1,5 +1,3 @@
-#![feature(param_attrs)]
-
 extern "C" {
     fn ffi(
         /// Foo
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
index 8ab3fc39a0c..0fc6ca2f7f3 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
@@ -1,311 +1,311 @@
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:7:9
+  --> $DIR/param-attrs-builtin-attrs.rs:5:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:23:5
+  --> $DIR/param-attrs-builtin-attrs.rs:21:5
    |
 LL |     #[test] a: u32,
    |     ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:38:5
+  --> $DIR/param-attrs-builtin-attrs.rs:36:5
    |
 LL |     #[test] a: u32,
    |     ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:58:9
+  --> $DIR/param-attrs-builtin-attrs.rs:56:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:79:9
+  --> $DIR/param-attrs-builtin-attrs.rs:77:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:98:9
+  --> $DIR/param-attrs-builtin-attrs.rs:96:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:117:9
+  --> $DIR/param-attrs-builtin-attrs.rs:115:9
    |
 LL |         #[test] a: i32,
    |         ^^^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/param-attrs-builtin-attrs.rs:134:9
+  --> $DIR/param-attrs-builtin-attrs.rs:132:9
    |
 LL |         #[test] a: u32,
    |         ^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:5:9
+  --> $DIR/param-attrs-builtin-attrs.rs:3:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:9:9
+  --> $DIR/param-attrs-builtin-attrs.rs:7:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:11:9
+  --> $DIR/param-attrs-builtin-attrs.rs:9:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:13:9
+  --> $DIR/param-attrs-builtin-attrs.rs:11:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:15:9
+  --> $DIR/param-attrs-builtin-attrs.rs:13:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:21:5
+  --> $DIR/param-attrs-builtin-attrs.rs:19:5
    |
 LL |     /// Foo
    |     ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:25:5
+  --> $DIR/param-attrs-builtin-attrs.rs:23:5
    |
 LL |     /// Bar
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:27:5
+  --> $DIR/param-attrs-builtin-attrs.rs:25:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:29:5
+  --> $DIR/param-attrs-builtin-attrs.rs:27:5
    |
 LL |     /// Baz
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:31:5
+  --> $DIR/param-attrs-builtin-attrs.rs:29:5
    |
 LL |     #[no_mangle] b: i32,
    |     ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:36:5
+  --> $DIR/param-attrs-builtin-attrs.rs:34:5
    |
 LL |     /// Foo
    |     ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:40:5
+  --> $DIR/param-attrs-builtin-attrs.rs:38:5
    |
 LL |     /// Bar
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:42:5
+  --> $DIR/param-attrs-builtin-attrs.rs:40:5
    |
 LL |     #[must_use]
    |     ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:44:5
+  --> $DIR/param-attrs-builtin-attrs.rs:42:5
    |
 LL |     /// Baz
    |     ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:46:5
+  --> $DIR/param-attrs-builtin-attrs.rs:44:5
    |
 LL |     #[no_mangle] b: i32,
    |     ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:53:9
+  --> $DIR/param-attrs-builtin-attrs.rs:51:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:56:9
+  --> $DIR/param-attrs-builtin-attrs.rs:54:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:60:9
+  --> $DIR/param-attrs-builtin-attrs.rs:58:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:62:9
+  --> $DIR/param-attrs-builtin-attrs.rs:60:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:64:9
+  --> $DIR/param-attrs-builtin-attrs.rs:62:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:66:9
+  --> $DIR/param-attrs-builtin-attrs.rs:64:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:74:9
+  --> $DIR/param-attrs-builtin-attrs.rs:72:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:77:9
+  --> $DIR/param-attrs-builtin-attrs.rs:75:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:81:9
+  --> $DIR/param-attrs-builtin-attrs.rs:79:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:83:9
+  --> $DIR/param-attrs-builtin-attrs.rs:81:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:85:9
+  --> $DIR/param-attrs-builtin-attrs.rs:83:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:87:9
+  --> $DIR/param-attrs-builtin-attrs.rs:85:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:93:9
+  --> $DIR/param-attrs-builtin-attrs.rs:91:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:96:9
+  --> $DIR/param-attrs-builtin-attrs.rs:94:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:100:9
+  --> $DIR/param-attrs-builtin-attrs.rs:98:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:102:9
+  --> $DIR/param-attrs-builtin-attrs.rs:100:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:104:9
+  --> $DIR/param-attrs-builtin-attrs.rs:102:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:106:9
+  --> $DIR/param-attrs-builtin-attrs.rs:104:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:112:9
+  --> $DIR/param-attrs-builtin-attrs.rs:110:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:115:9
+  --> $DIR/param-attrs-builtin-attrs.rs:113:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:119:9
+  --> $DIR/param-attrs-builtin-attrs.rs:117:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:121:9
+  --> $DIR/param-attrs-builtin-attrs.rs:119:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:123:9
+  --> $DIR/param-attrs-builtin-attrs.rs:121:9
    |
 LL |         /// Qux
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:125:9
+  --> $DIR/param-attrs-builtin-attrs.rs:123:9
    |
 LL |         #[no_mangle] b: i32,
    |         ^^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:132:9
+  --> $DIR/param-attrs-builtin-attrs.rs:130:9
    |
 LL |         /// Foo
    |         ^^^^^^^ doc comments are not allowed here
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:136:9
+  --> $DIR/param-attrs-builtin-attrs.rs:134:9
    |
 LL |         /// Bar
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:138:9
+  --> $DIR/param-attrs-builtin-attrs.rs:136:9
    |
 LL |         #[must_use]
    |         ^^^^^^^^^^^
 
 error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:140:9
+  --> $DIR/param-attrs-builtin-attrs.rs:138:9
    |
 LL |         /// Baz
    |         ^^^^^^^ doc comments are not allowed here
 
 error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
-  --> $DIR/param-attrs-builtin-attrs.rs:142:9
+  --> $DIR/param-attrs-builtin-attrs.rs:140:9
    |
 LL |         #[no_mangle] b: i32
    |         ^^^^^^^^^^^^
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index 5ad6e23cf2a..d44ff14e992 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -1,7 +1,7 @@
 // compile-flags: --cfg something
 // edition:2018
 
-#![feature(async_closure, param_attrs)]
+#![feature(async_closure)]
 #![deny(unused_variables)]
 
 extern "C" {
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
deleted file mode 100644
index a7f4855915b..00000000000
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-// gate-test-param_attrs
-
-#![deny(unused_variables)]
-
-fn foo(
-    /// Foo
-    //~^ ERROR documentation comments cannot be applied to function parameters
-    //~| NOTE doc comments are not allowed here
-    //~| ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
-    #[allow(unused_variables)] a: u8
-    //~^ ERROR attributes on function parameters are unstable
-    //~| NOTE https://github.com/rust-lang/rust/issues/60406
-) {}
-
-fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
deleted file mode 100644
index 0bb9d05dca0..00000000000
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-feature-gate.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: documentation comments cannot be applied to function parameters
-  --> $DIR/param-attrs-feature-gate.rs:6:5
-   |
-LL |     /// Foo
-   |     ^^^^^^^ doc comments are not allowed here
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:6:5
-   |
-LL |     /// Foo
-   |     ^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error[E0658]: attributes on function parameters are unstable
-  --> $DIR/param-attrs-feature-gate.rs:11:5
-   |
-LL |     #[allow(unused_variables)] a: u8
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: for more information, see https://github.com/rust-lang/rust/issues/60406
-   = help: add `#![feature(param_attrs)]` to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
index 1a7e9481745..fb86020d992 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
@@ -2,7 +2,6 @@
 
 // check-pass
 
-#![feature(param_attrs)]
 #![feature(c_variadic)]
 
 extern crate param_attrs;
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index 7f003089254..9f4e2710dc4 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -1,6 +1,5 @@
 // aux-build:ident-mac.rs
 
-#![feature(param_attrs)]
 #![feature(c_variadic)]
 
 extern crate ident_mac;
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index 3b72e8ab4bd..b4946fa7494 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -1,149 +1,149 @@
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:11:21
+  --> $DIR/proc-macro-cannot-be-used.rs:10:21
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                     ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:11:38
+  --> $DIR/proc-macro-cannot-be-used.rs:10:38
    |
 LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:15:38
+  --> $DIR/proc-macro-cannot-be-used.rs:14:38
    |
 LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:18:28
+  --> $DIR/proc-macro-cannot-be-used.rs:17:28
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:18:38
+  --> $DIR/proc-macro-cannot-be-used.rs:17:38
    |
 LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
    |                                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:22:9
+  --> $DIR/proc-macro-cannot-be-used.rs:21:9
    |
 LL | fn free(#[id] arg1: u8) {
    |         ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:24:16
+  --> $DIR/proc-macro-cannot-be-used.rs:23:16
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:24:28
+  --> $DIR/proc-macro-cannot-be-used.rs:23:28
    |
 LL |     let lam = |#[id] W(x), #[id] y| ();
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:30:18
+  --> $DIR/proc-macro-cannot-be-used.rs:29:18
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                  ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:30:30
+  --> $DIR/proc-macro-cannot-be-used.rs:29:30
    |
 LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
    |                              ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:33:18
+  --> $DIR/proc-macro-cannot-be-used.rs:32:18
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                  ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:33:31
+  --> $DIR/proc-macro-cannot-be-used.rs:32:31
    |
 LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
    |                               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:36:22
+  --> $DIR/proc-macro-cannot-be-used.rs:35:22
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:36:42
+  --> $DIR/proc-macro-cannot-be-used.rs:35:42
    |
 LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
    |                                          ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:39:22
+  --> $DIR/proc-macro-cannot-be-used.rs:38:22
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                      ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:39:45
+  --> $DIR/proc-macro-cannot-be-used.rs:38:45
    |
 LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
    |                                             ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:45:15
+  --> $DIR/proc-macro-cannot-be-used.rs:44:15
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:45:27
+  --> $DIR/proc-macro-cannot-be-used.rs:44:27
    |
 LL |     fn trait1(#[id] self, #[id] arg1: u8);
    |                           ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:48:15
+  --> $DIR/proc-macro-cannot-be-used.rs:47:15
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |               ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:48:28
+  --> $DIR/proc-macro-cannot-be-used.rs:47:28
    |
 LL |     fn trait2(#[id] &self, #[id] arg1: u8);
    |                            ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:51:19
+  --> $DIR/proc-macro-cannot-be-used.rs:50:19
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                   ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:51:39
+  --> $DIR/proc-macro-cannot-be-used.rs:50:39
    |
 LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
    |                                       ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:19
+  --> $DIR/proc-macro-cannot-be-used.rs:53:19
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                   ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:42
+  --> $DIR/proc-macro-cannot-be-used.rs:53:42
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                          ^^^^^
 
 error: expected an inert attribute, found an attribute macro
-  --> $DIR/proc-macro-cannot-be-used.rs:54:58
+  --> $DIR/proc-macro-cannot-be-used.rs:53:58
    |
 LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
    |                                                          ^^^^^
diff --git a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
index 728efadf419..526055ba04b 100644
--- a/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closures-infer-argument-types-two-region-pointers.stderr
@@ -23,3 +23,4 @@ LL | |     });
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/wf/wf-static-method.stderr b/src/test/ui/wf/wf-static-method.stderr
index f82526aa88e..3ec90f00448 100644
--- a/src/test/ui/wf/wf-static-method.stderr
+++ b/src/test/ui/wf/wf-static-method.stderr
@@ -105,4 +105,5 @@ LL |     <IndirectEvil>::static_evil(b)
 
 error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0478`.
+Some errors have detailed explanations: E0312, E0478.
+For more information about an error, try `rustc --explain E0312`.