about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs26
-rw-r--r--compiler/rustc_parse_format/src/lib.rs16
-rw-r--r--compiler/rustc_parse_format/src/tests.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/on_unimplemented.rs16
-rw-r--r--compiler/rustc_typeck/src/check/check.rs9
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs54
-rw-r--r--compiler/rustc_typeck/src/check/pat.rs56
-rw-r--r--library/alloc/src/collections/btree/map.rs2
-rw-r--r--library/alloc/src/collections/btree/set.rs2
-rw-r--r--library/alloc/src/collections/linked_list.rs2
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs2
-rw-r--r--library/alloc/src/vec/mod.rs9
-rw-r--r--library/core/src/cell.rs3
-rw-r--r--library/core/src/convert/mod.rs5
-rw-r--r--library/core/src/lazy.rs1
-rw-r--r--library/core/src/ptr/non_null.rs6
-rw-r--r--library/core/src/ptr/unique.rs3
-rw-r--r--library/core/src/sync/atomic.rs1
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/std/src/ffi/c_str.rs11
-rw-r--r--library/std/src/ffi/os_str.rs12
-rw-r--r--library/std/src/path.rs6
-rw-r--r--library/std/src/process.rs8
-rw-r--r--library/test/src/cli.rs14
-rw-r--r--library/test/src/formatters/pretty.rs2
-rw-r--r--library/test/src/tests.rs1
-rw-r--r--library/test/src/time.rs5
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile4
-rw-r--r--src/doc/rustc/src/tests/index.md2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/report-time.md7
-rw-r--r--src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr8
-rw-r--r--src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr8
-rw-r--r--src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr8
-rw-r--r--src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr8
-rw-r--r--src/test/ui/binop/issue-28837.stderr16
-rw-r--r--src/test/ui/derives/issue-91550.rs29
-rw-r--r--src/test/ui/derives/issue-91550.stderr84
-rw-r--r--src/test/ui/feature-gates/feature-gate-untagged_unions.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-untagged_unions.stderr10
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-93378.stderr8
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-94010.rs7
-rw-r--r--src/test/ui/fmt/format-args-capture-issue-94010.stderr20
-rw-r--r--src/test/ui/fmt/format-args-capture-missing-variables.stderr24
-rw-r--r--src/test/ui/fmt/ifmt-bad-arg.stderr20
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs22
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr32
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.rs16
-rw-r--r--src/test/ui/functions-closures/fn-help-with-err.stderr24
-rw-r--r--src/test/ui/typeck/issue-91328.fixed10
-rw-r--r--src/test/ui/typeck/issue-91328.rs10
-rw-r--r--src/test/ui/typeck/issue-91328.stderr11
-rw-r--r--src/test/ui/union/issue-41073.rs2
-rw-r--r--src/test/ui/union/issue-41073.stderr5
-rw-r--r--src/test/ui/union/union-custom-drop.rs2
-rw-r--r--src/test/ui/union/union-custom-drop.stderr5
-rw-r--r--src/test/ui/union/union-derive-clone.mirunsafeck.stderr4
-rw-r--r--src/test/ui/union/union-derive-clone.thirunsafeck.stderr4
-rw-r--r--src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr15
-rw-r--r--src/test/ui/union/union-with-drop-fields.rs6
-rw-r--r--src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr15
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs2
62 files changed, 545 insertions, 189 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 1a6e5694791..ac37c4973d8 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -700,11 +700,11 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                                 Some(idx)
                             }
                         }
-                        parse::ArgumentNamed(name) => match args.named_args.get(&name) {
+                        parse::ArgumentNamed(name, span) => match args.named_args.get(&name) {
                             Some(&idx) => Some(idx),
                             None => {
                                 let msg = format!("there is no argument named `{}`", name);
-                                ecx.struct_span_err(span, &msg).emit();
+                                ecx.struct_span_err(template_span.from_inner(span), &msg).emit();
                                 None
                             }
                         },
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 584fbd1b605..6141d00f697 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -11,7 +11,7 @@ use rustc_errors::{pluralize, Applicability, DiagnosticBuilder};
 use rustc_expand::base::{self, *};
 use rustc_parse_format as parse;
 use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::{MultiSpan, Span};
+use rustc_span::{InnerSpan, MultiSpan, Span};
 use smallvec::SmallVec;
 
 use std::borrow::Cow;
@@ -26,7 +26,7 @@ enum ArgumentType {
 enum Position {
     Exact(usize),
     Capture(usize),
-    Named(Symbol),
+    Named(Symbol, InnerSpan),
 }
 
 struct Context<'a, 'b> {
@@ -247,13 +247,13 @@ impl<'a, 'b> Context<'a, 'b> {
         match *p {
             parse::String(_) => {}
             parse::NextArgument(ref mut arg) => {
-                if let parse::ArgumentNamed(s) = arg.position {
+                if let parse::ArgumentNamed(s, _) = arg.position {
                     arg.position = parse::ArgumentIs(lookup(s));
                 }
-                if let parse::CountIsName(s) = arg.format.width {
+                if let parse::CountIsName(s, _) = arg.format.width {
                     arg.format.width = parse::CountIsParam(lookup(s));
                 }
-                if let parse::CountIsName(s) = arg.format.precision {
+                if let parse::CountIsName(s, _) = arg.format.precision {
                     arg.format.precision = parse::CountIsParam(lookup(s));
                 }
             }
@@ -276,7 +276,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 // it's written second, so it should come after width/precision.
                 let pos = match arg.position {
                     parse::ArgumentIs(i) | parse::ArgumentImplicitlyIs(i) => Exact(i),
-                    parse::ArgumentNamed(s) => Named(s),
+                    parse::ArgumentNamed(s, span) => Named(s, span),
                 };
 
                 let ty = Placeholder(match arg.format.ty {
@@ -346,8 +346,8 @@ impl<'a, 'b> Context<'a, 'b> {
             parse::CountIsParam(i) => {
                 self.verify_arg_type(Exact(i), Count);
             }
-            parse::CountIsName(s) => {
-                self.verify_arg_type(Named(s), Count);
+            parse::CountIsName(s, span) => {
+                self.verify_arg_type(Named(s, span), Count);
             }
         }
     }
@@ -533,7 +533,7 @@ impl<'a, 'b> Context<'a, 'b> {
                 }
             }
 
-            Named(name) => {
+            Named(name, span) => {
                 match self.names.get(&name) {
                     Some(&idx) => {
                         // Treat as positional arg.
@@ -548,7 +548,7 @@ impl<'a, 'b> Context<'a, 'b> {
                             self.arg_types.push(Vec::new());
                             self.arg_unique_types.push(Vec::new());
                             let span = if self.is_literal {
-                                *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
+                                self.fmtsp.from_inner(span)
                             } else {
                                 self.fmtsp
                             };
@@ -559,7 +559,7 @@ impl<'a, 'b> Context<'a, 'b> {
                         } else {
                             let msg = format!("there is no argument named `{}`", name);
                             let sp = if self.is_literal {
-                                *self.arg_spans.get(self.curpiece).unwrap_or(&self.fmtsp)
+                                self.fmtsp.from_inner(span)
                             } else {
                                 self.fmtsp
                             };
@@ -629,7 +629,7 @@ impl<'a, 'b> Context<'a, 'b> {
             }
             parse::CountImplied => count(sym::Implied, None),
             // should never be the case, names are already resolved
-            parse::CountIsName(_) => panic!("should never happen"),
+            parse::CountIsName(..) => panic!("should never happen"),
         }
     }
 
@@ -676,7 +676,7 @@ impl<'a, 'b> Context<'a, 'b> {
 
                         // should never be the case, because names are already
                         // resolved.
-                        parse::ArgumentNamed(_) => panic!("should never happen"),
+                        parse::ArgumentNamed(..) => panic!("should never happen"),
                     }
                 };
 
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 9d653de910f..a6a2cbc277c 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -95,7 +95,7 @@ pub enum Position {
     /// The argument is located at a specific index given in the format
     ArgumentIs(usize),
     /// The argument has a name.
-    ArgumentNamed(Symbol),
+    ArgumentNamed(Symbol, InnerSpan),
 }
 
 impl Position {
@@ -147,7 +147,7 @@ pub enum Count {
     /// The count is specified explicitly.
     CountIs(usize),
     /// The count is specified by the argument with the given name.
-    CountIsName(Symbol),
+    CountIsName(Symbol, InnerSpan),
     /// The count is specified by the argument at the given index.
     CountIsParam(usize),
     /// The count is implied and cannot be explicitly specified.
@@ -494,8 +494,11 @@ impl<'a> Parser<'a> {
             Some(ArgumentIs(i))
         } else {
             match self.cur.peek() {
-                Some(&(_, c)) if rustc_lexer::is_id_start(c) => {
-                    Some(ArgumentNamed(Symbol::intern(self.word())))
+                Some(&(start, c)) if rustc_lexer::is_id_start(c) => {
+                    let word = self.word();
+                    let end = start + word.len();
+                    let span = self.to_span_index(start).to(self.to_span_index(end));
+                    Some(ArgumentNamed(Symbol::intern(word), span))
                 }
 
                 // This is an `ArgumentNext`.
@@ -662,8 +665,9 @@ impl<'a> Parser<'a> {
             if word.is_empty() {
                 self.cur = tmp;
                 (CountImplied, None)
-            } else if self.consume('$') {
-                (CountIsName(Symbol::intern(word)), None)
+            } else if let Some(end) = self.consume_pos('$') {
+                let span = self.to_span_index(start + 1).to(self.to_span_index(end));
+                (CountIsName(Symbol::intern(word), span), None)
             } else {
                 self.cur = tmp;
                 (CountImplied, None)
diff --git a/compiler/rustc_parse_format/src/tests.rs b/compiler/rustc_parse_format/src/tests.rs
index b7693a85ad9..6c960fdc72b 100644
--- a/compiler/rustc_parse_format/src/tests.rs
+++ b/compiler/rustc_parse_format/src/tests.rs
@@ -221,8 +221,8 @@ fn format_counts() {
                     fill: None,
                     align: AlignUnknown,
                     flags: 0,
-                    precision: CountIsName(Symbol::intern("b")),
-                    width: CountIsName(Symbol::intern("a")),
+                    precision: CountIsName(Symbol::intern("b"), InnerSpan::new(6, 7)),
+                    width: CountIsName(Symbol::intern("a"), InnerSpan::new(4, 4)),
                     precision_span: None,
                     width_span: None,
                     ty: "?",
diff --git a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
index bdf677a63b6..b05dbbe898a 100644
--- a/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
+++ b/compiler/rustc_trait_selection/src/traits/on_unimplemented.rs
@@ -309,23 +309,23 @@ impl<'tcx> OnUnimplementedFormatString {
                 Piece::String(_) => (), // Normal string, no need to check it
                 Piece::NextArgument(a) => match a.position {
                     // `{Self}` is allowed
-                    Position::ArgumentNamed(s) if s == kw::SelfUpper => (),
+                    Position::ArgumentNamed(s, _) if s == kw::SelfUpper => (),
                     // `{ThisTraitsName}` is allowed
-                    Position::ArgumentNamed(s) if s == name => (),
+                    Position::ArgumentNamed(s, _) if s == name => (),
                     // `{from_method}` is allowed
-                    Position::ArgumentNamed(s) if s == sym::from_method => (),
+                    Position::ArgumentNamed(s, _) if s == sym::from_method => (),
                     // `{from_desugaring}` is allowed
-                    Position::ArgumentNamed(s) if s == sym::from_desugaring => (),
+                    Position::ArgumentNamed(s, _) if s == sym::from_desugaring => (),
                     // `{ItemContext}` is allowed
-                    Position::ArgumentNamed(s) if s == sym::ItemContext => (),
+                    Position::ArgumentNamed(s, _) if s == sym::ItemContext => (),
                     // `{integral}` and `{integer}` and `{float}` are allowed
-                    Position::ArgumentNamed(s)
+                    Position::ArgumentNamed(s, _)
                         if s == sym::integral || s == sym::integer_ || s == sym::float =>
                     {
                         ()
                     }
                     // So is `{A}` if A is a type parameter
-                    Position::ArgumentNamed(s) => {
+                    Position::ArgumentNamed(s, _) => {
                         match generics.params.iter().find(|param| param.name == s) {
                             Some(_) => (),
                             None => {
@@ -392,7 +392,7 @@ impl<'tcx> OnUnimplementedFormatString {
             .map(|p| match p {
                 Piece::String(s) => s,
                 Piece::NextArgument(a) => match a.position {
-                    Position::ArgumentNamed(s) => match generic_map.get(&s) {
+                    Position::ArgumentNamed(s, _) => match generic_map.get(&s) {
                         Some(val) => val,
                         None if s == name => &trait_str,
                         None => {
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 27c8a197835..6dbda1005dd 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -382,10 +382,15 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
                     tcx.sess,
                     field_span,
                     E0740,
-                    "unions may not contain fields that need dropping"
+                    "unions cannot contain fields that may need dropping"
+                )
+                .note(
+                    "a type is guaranteed not to need dropping \
+                    when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type",
                 )
                 .multipart_suggestion_verbose(
-                    "wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped",
+                    "when the type does not implement `Copy`, \
+                    wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped",
                     vec![
                         (ty_span.shrink_to_lo(), format!("std::mem::ManuallyDrop<")),
                         (ty_span.shrink_to_hi(), ">".into()),
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index 81e2b3bc162..a523ba286ec 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -9,8 +9,10 @@ use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{ExprKind, Node, QPath};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::traits::util::supertraits;
 use rustc_middle::ty::fast_reject::{simplify_type, SimplifyParams};
 use rustc_middle::ty::print::with_crate_prefix;
+use rustc_middle::ty::ToPolyTraitRef;
 use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use rustc_span::lev_distance;
 use rustc_span::symbol::{kw, sym, Ident};
@@ -40,7 +42,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     Err(..) => return false,
                 };
 
+                // This conditional prevents us from asking to call errors and unresolved types.
+                // It might seem that we can use `predicate_must_hold_modulo_regions`,
+                // but since a Dummy binder is used to fill in the FnOnce trait's arguments,
+                // type resolution always gives a "maybe" here.
+                if self.autoderef(span, ty).any(|(ty, _)| {
+                    info!("check deref {:?} error", ty);
+                    matches!(ty.kind(), ty::Error(_) | ty::Infer(_))
+                }) {
+                    return false;
+                }
+
                 self.autoderef(span, ty).any(|(ty, _)| {
+                    info!("check deref {:?} impl FnOnce", ty);
                     self.probe(|_| {
                         let fn_once_substs = tcx.mk_substs_trait(
                             ty,
@@ -1196,9 +1210,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Some(adt) if adt.did.is_local() => adt,
                 _ => continue,
             };
-            let can_derive = match self.tcx.get_diagnostic_name(trait_pred.def_id()) {
-                Some(sym::Default) => !adt.is_enum(),
-                Some(
+            if let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) {
+                let can_derive = match diagnostic_name {
+                    sym::Default => !adt.is_enum(),
                     sym::Eq
                     | sym::PartialEq
                     | sym::Ord
@@ -1206,16 +1220,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     | sym::Clone
                     | sym::Copy
                     | sym::Hash
-                    | sym::Debug,
-                ) => true,
-                _ => false,
-            };
-            if can_derive {
-                derives.push((
-                    format!("{}", trait_pred.self_ty()),
-                    self.tcx.def_span(adt.did),
-                    format!("{}", trait_pred.trait_ref.print_only_trait_name()),
-                ));
+                    | sym::Debug => true,
+                    _ => false,
+                };
+                if can_derive {
+                    let self_name = trait_pred.self_ty().to_string();
+                    let self_span = self.tcx.def_span(adt.did);
+                    if let Some(poly_trait_ref) = pred.to_opt_poly_trait_pred() {
+                        for super_trait in supertraits(self.tcx, poly_trait_ref.to_poly_trait_ref())
+                        {
+                            if let Some(parent_diagnostic_name) =
+                                self.tcx.get_diagnostic_name(super_trait.def_id())
+                            {
+                                derives.push((
+                                    self_name.clone(),
+                                    self_span.clone(),
+                                    parent_diagnostic_name.to_string(),
+                                ));
+                            }
+                        }
+                    }
+                    derives.push((self_name, self_span, diagnostic_name.to_string()));
+                } else {
+                    traits.push(self.tcx.def_span(trait_pred.def_id()));
+                }
             } else {
                 traits.push(self.tcx.def_span(trait_pred.def_id()));
             }
diff --git a/compiler/rustc_typeck/src/check/pat.rs b/compiler/rustc_typeck/src/check/pat.rs
index 320f5a97e0a..e034adde1be 100644
--- a/compiler/rustc_typeck/src/check/pat.rs
+++ b/compiler/rustc_typeck/src/check/pat.rs
@@ -2029,34 +2029,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 err.help("the semantics of slice patterns changed recently; see issue #62254");
             }
         } else if Autoderef::new(&self.infcx, self.param_env, self.body_id, span, expected_ty, span)
-            .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..)))
+            .any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
         {
             if let (Some(span), true) = (ti.span, ti.origin_expr) {
                 if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
-                    let applicability = match self.resolve_vars_if_possible(ti.expected).kind() {
-                        ty::Adt(adt_def, _)
-                            if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
-                                || self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
-                        {
-                            // Slicing won't work here, but `.as_deref()` might (issue #91328).
-                            err.span_suggestion(
-                                span,
-                                "consider using `as_deref` here",
-                                format!("{}.as_deref()", snippet),
-                                Applicability::MaybeIncorrect,
-                            );
-                            None
-                        }
-                        // FIXME: instead of checking for Vec only, we could check whether the
-                        // type implements `Deref<Target=X>`; see
-                        // https://github.com/rust-lang/rust/pull/91343#discussion_r761466979
-                        ty::Adt(adt_def, _)
-                            if self.tcx.is_diagnostic_item(sym::Vec, adt_def.did) =>
-                        {
-                            Some(Applicability::MachineApplicable)
+                    let applicability = Autoderef::new(
+                        &self.infcx,
+                        self.param_env,
+                        self.body_id,
+                        span,
+                        self.resolve_vars_if_possible(ti.expected),
+                        span,
+                    )
+                    .find_map(|(ty, _)| {
+                        match ty.kind() {
+                            ty::Adt(adt_def, _)
+                                if self.tcx.is_diagnostic_item(sym::Option, adt_def.did)
+                                    || self.tcx.is_diagnostic_item(sym::Result, adt_def.did) =>
+                            {
+                                // Slicing won't work here, but `.as_deref()` might (issue #91328).
+                                err.span_suggestion(
+                                    span,
+                                    "consider using `as_deref` here",
+                                    format!("{}.as_deref()", snippet),
+                                    Applicability::MaybeIncorrect,
+                                );
+                                Some(None)
+                            }
+
+                            ty::Slice(..) | ty::Array(..) => {
+                                Some(Some(Applicability::MachineApplicable))
+                            }
+
+                            _ => None,
                         }
-                        _ => Some(Applicability::MaybeIncorrect),
-                    };
+                    })
+                    .unwrap_or(Some(Applicability::MaybeIncorrect));
 
                     if let Some(applicability) = applicability {
                         err.span_suggestion(
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index cdb961d4cfb..67f5b386ecd 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -2052,6 +2052,8 @@ where
 
 #[stable(feature = "std_collections_from_array", since = "1.56.0")]
 impl<K: Ord, V, const N: usize> From<[(K, V); N]> for BTreeMap<K, V> {
+    /// Converts a `[(K, V); N]` into a `BTreeMap<(K, V)>`.
+    ///
     /// ```
     /// use std::collections::BTreeMap;
     ///
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 31df4e98ed7..a4315be74e3 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1097,6 +1097,8 @@ impl<T: Ord> FromIterator<T> for BTreeSet<T> {
 
 #[stable(feature = "std_collections_from_array", since = "1.56.0")]
 impl<T: Ord, const N: usize> From<[T; N]> for BTreeSet<T> {
+    /// Converts a `[T; N]` into a `BTreeSet<T>`.
+    ///
     /// ```
     /// use std::collections::BTreeSet;
     ///
diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs
index 4a07d5d4bed..d81f24e7202 100644
--- a/library/alloc/src/collections/linked_list.rs
+++ b/library/alloc/src/collections/linked_list.rs
@@ -1953,6 +1953,8 @@ impl<T: Hash> Hash for LinkedList<T> {
 
 #[stable(feature = "std_collections_from_array", since = "1.56.0")]
 impl<T, const N: usize> From<[T; N]> for LinkedList<T> {
+    /// Converts a `[T; N]` into a `LinkedList<T>`.
+    ///
     /// ```
     /// use std::collections::LinkedList;
     ///
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index db2ad5e8d28..763175fc045 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -3049,6 +3049,8 @@ impl<T, A: Allocator> From<VecDeque<T, A>> for Vec<T, A> {
 
 #[stable(feature = "std_collections_from_array", since = "1.56.0")]
 impl<T, const N: usize> From<[T; N]> for VecDeque<T> {
+    /// Converts a `[T; N]` into a `VecDeque<T>`.
+    ///
     /// ```
     /// use std::collections::VecDeque;
     ///
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index bd3262b51d4..3dc3eee4133 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2906,10 +2906,6 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "vec_from_array", since = "1.44.0")]
 impl<T, const N: usize> From<[T; N]> for Vec<T> {
-    #[cfg(not(test))]
-    fn from(s: [T; N]) -> Vec<T> {
-        <[T]>::into_vec(box s)
-    }
     /// Allocate a `Vec<T>` and move `s`'s items into it.
     ///
     /// # Examples
@@ -2917,6 +2913,11 @@ impl<T, const N: usize> From<[T; N]> for Vec<T> {
     /// ```
     /// assert_eq!(Vec::from([1, 2, 3]), vec![1, 2, 3]);
     /// ```
+    #[cfg(not(test))]
+    fn from(s: [T; N]) -> Vec<T> {
+        <[T]>::into_vec(box s)
+    }
+
     #[cfg(test)]
     fn from(s: [T; N]) -> Vec<T> {
         crate::slice::into_vec(box s)
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index feb94555658..aef7ad77568 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -315,6 +315,7 @@ impl<T: Ord + Copy> Ord for Cell<T> {
 #[stable(feature = "cell_from", since = "1.12.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<T> for Cell<T> {
+    /// Creates a new `Cell<T>` containing the given value.
     fn from(t: T) -> Cell<T> {
         Cell::new(t)
     }
@@ -1244,6 +1245,7 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> {
 #[stable(feature = "cell_from", since = "1.12.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<T> for RefCell<T> {
+    /// Creates a new `RefCell<T>` containing the given value.
     fn from(t: T) -> RefCell<T> {
         RefCell::new(t)
     }
@@ -1979,6 +1981,7 @@ impl<T: Default> Default for UnsafeCell<T> {
 #[stable(feature = "cell_from", since = "1.12.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<T> for UnsafeCell<T> {
+    /// Creates a new `UnsafeCell<T>` containing the given value.
     fn from(t: T) -> UnsafeCell<T> {
         UnsafeCell::new(t)
     }
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index 5566c2ffe87..0ceedf93633 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -538,6 +538,10 @@ impl<T, U> const Into<U> for T
 where
     U: ~const From<T>,
 {
+    /// Calls `U::from(self)`.
+    ///
+    /// That is, this conversion is whatever the implementation of
+    /// <code>[From]&lt;T&gt; for U</code> chooses to do.
     fn into(self) -> U {
         U::from(self)
     }
@@ -547,6 +551,7 @@ where
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<T> for T {
+    /// Returns the argument unchanged.
     fn from(t: T) -> T {
         t
     }
diff --git a/library/core/src/lazy.rs b/library/core/src/lazy.rs
index 788f0cce01b..88826782a3d 100644
--- a/library/core/src/lazy.rs
+++ b/library/core/src/lazy.rs
@@ -75,6 +75,7 @@ impl<T: Eq> Eq for OnceCell<T> {}
 
 #[unstable(feature = "once_cell", issue = "74465")]
 impl<T> const From<T> for OnceCell<T> {
+    /// Creates a new `OnceCell<T>` which already contains the given `value`.
     fn from(value: T) -> Self {
         OnceCell { inner: UnsafeCell::new(Some(value)) }
     }
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 3f5d3f62c96..0aa8e9960a8 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -721,6 +721,9 @@ impl<T: ?Sized> const From<Unique<T>> for NonNull<T> {
 #[stable(feature = "nonnull", since = "1.25.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T: ?Sized> const From<&mut T> for NonNull<T> {
+    /// Converts a `&mut T` to a `NonNull<T>`.
+    ///
+    /// This conversion is safe and infallible since references cannot be null.
     #[inline]
     fn from(reference: &mut T) -> Self {
         // SAFETY: A mutable reference cannot be null.
@@ -731,6 +734,9 @@ impl<T: ?Sized> const From<&mut T> for NonNull<T> {
 #[stable(feature = "nonnull", since = "1.25.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T: ?Sized> const From<&T> for NonNull<T> {
+    /// Converts a `&T` to a `NonNull<T>`.
+    ///
+    /// This conversion is safe and infallible since references cannot be null.
     #[inline]
     fn from(reference: &T) -> Self {
         // SAFETY: A reference cannot be null, so the conditions for
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index f5c624c225f..661d111c99d 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -178,6 +178,9 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
 
 #[unstable(feature = "ptr_internals", issue = "none")]
 impl<T: ?Sized> const From<&mut T> for Unique<T> {
+    /// Converts a `&mut T` to a `Unique<T>`.
+    ///
+    /// This conversion is infallible since references cannot be null.
     #[inline]
     fn from(reference: &mut T) -> Self {
         // SAFETY: A mutable reference cannot be null
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 792016902ae..9ee88dd6014 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -1295,6 +1295,7 @@ impl const From<bool> for AtomicBool {
 #[stable(feature = "atomic_from", since = "1.23.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<*mut T> for AtomicPtr<T> {
+    /// Converts a `*mut T` into an `AtomicPtr<T>`.
     #[inline]
     fn from(p: *mut T) -> Self {
         Self::new(p)
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 72a030617ad..41f0a25dbc3 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -243,7 +243,7 @@ impl<T, E> Poll<Option<Result<T, E>>> {
 #[stable(feature = "futures_api", since = "1.36.0")]
 #[rustc_const_unstable(feature = "const_convert", issue = "88674")]
 impl<T> const From<T> for Poll<T> {
-    /// Convert to a `Ready` variant.
+    /// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
     ///
     /// # Example
     ///
diff --git a/library/std/src/ffi/c_str.rs b/library/std/src/ffi/c_str.rs
index c3f024026ef..6e70d5ca02d 100644
--- a/library/std/src/ffi/c_str.rs
+++ b/library/std/src/ffi/c_str.rs
@@ -871,6 +871,8 @@ impl Borrow<CStr> for CString {
 
 #[stable(feature = "cstring_from_cow_cstr", since = "1.28.0")]
 impl<'a> From<Cow<'a, CStr>> for CString {
+    /// Converts a `Cow<'a, CStr>` into a `CString`, by copying the contents if they are
+    /// borrowed.
     #[inline]
     fn from(s: Cow<'a, CStr>) -> Self {
         s.into_owned()
@@ -879,6 +881,8 @@ impl<'a> From<Cow<'a, CStr>> for CString {
 
 #[stable(feature = "box_from_c_str", since = "1.17.0")]
 impl From<&CStr> for Box<CStr> {
+    /// Converts a `&CStr` into a `Box<CStr>`,
+    /// by copying the contents into a newly allocated [`Box`].
     fn from(s: &CStr) -> Box<CStr> {
         let boxed: Box<[u8]> = Box::from(s.to_bytes_with_nul());
         unsafe { Box::from_raw(Box::into_raw(boxed) as *mut CStr) }
@@ -887,6 +891,8 @@ impl From<&CStr> for Box<CStr> {
 
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl From<Cow<'_, CStr>> for Box<CStr> {
+    /// Converts a `Cow<'a, CStr>` into a `Box<CStr>`,
+    /// by copying the contents if they are borrowed.
     #[inline]
     fn from(cow: Cow<'_, CStr>) -> Box<CStr> {
         match cow {
@@ -984,6 +990,8 @@ impl From<CString> for Arc<CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<&CStr> for Arc<CStr> {
+    /// Converts a `&CStr` into a `Arc<CStr>`,
+    /// by copying the contents into a newly allocated [`Arc`].
     #[inline]
     fn from(s: &CStr) -> Arc<CStr> {
         let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul());
@@ -1004,6 +1012,8 @@ impl From<CString> for Rc<CStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<&CStr> for Rc<CStr> {
+    /// Converts a `&CStr` into a `Rc<CStr>`,
+    /// by copying the contents into a newly allocated [`Rc`].
     #[inline]
     fn from(s: &CStr) -> Rc<CStr> {
         let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul());
@@ -1530,6 +1540,7 @@ impl ToOwned for CStr {
 
 #[stable(feature = "cstring_asref", since = "1.7.0")]
 impl From<&CStr> for CString {
+    /// Copies the contents of the `&CStr` into a newly allocated `CString`.
     fn from(s: &CStr) -> CString {
         s.to_owned()
     }
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 81f72e34d93..9b5e5d6c0cc 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -452,6 +452,8 @@ impl From<String> for OsString {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + AsRef<OsStr>> From<&T> for OsString {
+    /// Copies any value implementing <code>[AsRef]&lt;[OsStr]&gt;</code>
+    /// into a newly allocated [`OsString`].
     fn from(s: &T) -> OsString {
         s.as_ref().to_os_string()
     }
@@ -942,6 +944,7 @@ impl OsStr {
 
 #[stable(feature = "box_from_os_str", since = "1.17.0")]
 impl From<&OsStr> for Box<OsStr> {
+    /// Copies the string into a newly allocated <code>[Box]&lt;[OsStr]&gt;</code>.
     #[inline]
     fn from(s: &OsStr) -> Box<OsStr> {
         let rw = Box::into_raw(s.inner.into_box()) as *mut OsStr;
@@ -951,6 +954,8 @@ impl From<&OsStr> for Box<OsStr> {
 
 #[stable(feature = "box_from_cow", since = "1.45.0")]
 impl From<Cow<'_, OsStr>> for Box<OsStr> {
+    /// Converts a `Cow<'a, OsStr>` into a <code>[Box]&lt;[OsStr]&gt;</code>,
+    /// by copying the contents if they are borrowed.
     #[inline]
     fn from(cow: Cow<'_, OsStr>) -> Box<OsStr> {
         match cow {
@@ -1000,6 +1005,7 @@ impl From<OsString> for Arc<OsStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<&OsStr> for Arc<OsStr> {
+    /// Copies the string into a newly allocated <code>[Arc]&lt;[OsStr]&gt;</code>.
     #[inline]
     fn from(s: &OsStr) -> Arc<OsStr> {
         let arc = s.inner.into_arc();
@@ -1020,6 +1026,7 @@ impl From<OsString> for Rc<OsStr> {
 
 #[stable(feature = "shared_from_slice2", since = "1.24.0")]
 impl From<&OsStr> for Rc<OsStr> {
+    /// Copies the string into a newly allocated <code>[Rc]&lt;[OsStr]&gt;</code>.
     #[inline]
     fn from(s: &OsStr) -> Rc<OsStr> {
         let rc = s.inner.into_rc();
@@ -1029,6 +1036,7 @@ impl From<&OsStr> for Rc<OsStr> {
 
 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
 impl<'a> From<OsString> for Cow<'a, OsStr> {
+    /// Moves the string into a [`Cow::Owned`].
     #[inline]
     fn from(s: OsString) -> Cow<'a, OsStr> {
         Cow::Owned(s)
@@ -1037,6 +1045,7 @@ impl<'a> From<OsString> for Cow<'a, OsStr> {
 
 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
 impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
+    /// Converts the string reference into a [`Cow::Borrowed`].
     #[inline]
     fn from(s: &'a OsStr) -> Cow<'a, OsStr> {
         Cow::Borrowed(s)
@@ -1045,6 +1054,7 @@ impl<'a> From<&'a OsStr> for Cow<'a, OsStr> {
 
 #[stable(feature = "cow_from_osstr", since = "1.28.0")]
 impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
+    /// Converts the string reference into a [`Cow::Borrowed`].
     #[inline]
     fn from(s: &'a OsString) -> Cow<'a, OsStr> {
         Cow::Borrowed(s.as_os_str())
@@ -1053,6 +1063,8 @@ impl<'a> From<&'a OsString> for Cow<'a, OsStr> {
 
 #[stable(feature = "osstring_from_cow_osstr", since = "1.28.0")]
 impl<'a> From<Cow<'a, OsStr>> for OsString {
+    /// Converts a `Cow<'a, OsStr>` into an [`OsString`],
+    /// by copying the contents if they are borrowed.
     #[inline]
     fn from(s: Cow<'a, OsStr>) -> Self {
         s.into_owned()
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 3f7f0f88847..adb8b30ec08 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -1600,7 +1600,7 @@ impl From<Cow<'_, Path>> for Box<Path> {
 
 #[stable(feature = "path_buf_from_box", since = "1.18.0")]
 impl From<Box<Path>> for PathBuf {
-    /// Converts a `Box<Path>` into a `PathBuf`
+    /// Converts a <code>[Box]&lt;[Path]&gt;</code> into a [`PathBuf`].
     ///
     /// This conversion does not allocate or copy memory.
     #[inline]
@@ -1611,7 +1611,7 @@ impl From<Box<Path>> for PathBuf {
 
 #[stable(feature = "box_from_path_buf", since = "1.20.0")]
 impl From<PathBuf> for Box<Path> {
-    /// Converts a `PathBuf` into a `Box<Path>`
+    /// Converts a [`PathBuf`] into a <code>[Box]&lt;[Path]&gt;</code>.
     ///
     /// This conversion currently should not allocate memory,
     /// but this behavior is not guaranteed on all platforms or in all future versions.
@@ -1631,7 +1631,7 @@ impl Clone for Box<Path> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized + AsRef<OsStr>> From<&T> for PathBuf {
-    /// Converts a borrowed `OsStr` to a `PathBuf`.
+    /// Converts a borrowed [`OsStr`] to a [`PathBuf`].
     ///
     /// Allocates a [`PathBuf`] and copies the data into it.
     #[inline]
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 1f048905396..e3fff155e47 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -1277,7 +1277,7 @@ impl fmt::Debug for Stdio {
 
 #[stable(feature = "stdio_from", since = "1.20.0")]
 impl From<ChildStdin> for Stdio {
-    /// Converts a `ChildStdin` into a `Stdio`
+    /// Converts a [`ChildStdin`] into a [`Stdio`].
     ///
     /// # Examples
     ///
@@ -1306,7 +1306,7 @@ impl From<ChildStdin> for Stdio {
 
 #[stable(feature = "stdio_from", since = "1.20.0")]
 impl From<ChildStdout> for Stdio {
-    /// Converts a `ChildStdout` into a `Stdio`
+    /// Converts a [`ChildStdout`] into a [`Stdio`].
     ///
     /// # Examples
     ///
@@ -1335,7 +1335,7 @@ impl From<ChildStdout> for Stdio {
 
 #[stable(feature = "stdio_from", since = "1.20.0")]
 impl From<ChildStderr> for Stdio {
-    /// Converts a `ChildStderr` into a `Stdio`
+    /// Converts a [`ChildStderr`] into a [`Stdio`].
     ///
     /// # Examples
     ///
@@ -1366,7 +1366,7 @@ impl From<ChildStderr> for Stdio {
 
 #[stable(feature = "stdio_from", since = "1.20.0")]
 impl From<fs::File> for Stdio {
-    /// Converts a `File` into a `Stdio`
+    /// Converts a [`File`](fs::File) into a [`Stdio`].
     ///
     /// # Examples
     ///
diff --git a/library/test/src/cli.rs b/library/test/src/cli.rs
index cb40b4e965b..b39701a3d42 100644
--- a/library/test/src/cli.rs
+++ b/library/test/src/cli.rs
@@ -109,12 +109,10 @@ fn optgroups() -> getopts::Options {
             unstable-options = Allow use of experimental features",
             "unstable-options",
         )
-        .optflagopt(
+        .optflag(
             "",
             "report-time",
-            "Show execution time of each test. Available values:
-            plain   = do not colorize the execution time (default);
-            colored = colorize output according to the `color` parameter value;
+            "Show execution time of each test.
 
             Threshold values for colorized output can be configured via
             `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION` and
@@ -125,7 +123,6 @@ fn optgroups() -> getopts::Options {
             is 0.5 seconds, and the critical time is 2 seconds.
 
             Not available for --format=terse",
-            "plain|colored",
         )
         .optflag(
             "",
@@ -319,17 +316,12 @@ fn get_time_options(
     allow_unstable: bool,
 ) -> OptPartRes<Option<TestTimeOptions>> {
     let report_time = unstable_optflag!(matches, allow_unstable, "report-time");
-    let colored_opt_str = matches.opt_str("report-time");
-    let mut report_time_colored = report_time && colored_opt_str == Some("colored".into());
     let ensure_test_time = unstable_optflag!(matches, allow_unstable, "ensure-time");
 
     // If `ensure-test-time` option is provided, time output is enforced,
     // so user won't be confused if any of tests will silently fail.
     let options = if report_time || ensure_test_time {
-        if ensure_test_time && !report_time {
-            report_time_colored = true;
-        }
-        Some(TestTimeOptions::new_from_env(ensure_test_time, report_time_colored))
+        Some(TestTimeOptions::new_from_env(ensure_test_time))
     } else {
         None
     };
diff --git a/library/test/src/formatters/pretty.rs b/library/test/src/formatters/pretty.rs
index 4726ae864df..041df5216d7 100644
--- a/library/test/src/formatters/pretty.rs
+++ b/library/test/src/formatters/pretty.rs
@@ -98,7 +98,7 @@ impl<T: Write> PrettyFormatter<T> {
         if let (Some(opts), Some(time)) = (self.time_options, exec_time) {
             let time_str = format!(" <{}>", time);
 
-            let color = if opts.colored {
+            let color = if self.use_color {
                 if opts.is_critical(desc, time) {
                     Some(term::color::RED)
                 } else if opts.is_warn(desc, time) {
diff --git a/library/test/src/tests.rs b/library/test/src/tests.rs
index 9b9c5205686..d566dbc09f4 100644
--- a/library/test/src/tests.rs
+++ b/library/test/src/tests.rs
@@ -394,7 +394,6 @@ fn test_time_options_threshold() {
 
     let options = TestTimeOptions {
         error_on_excess: false,
-        colored: false,
         unit_threshold: unit.clone(),
         integration_threshold: integration.clone(),
         doctest_threshold: doc.clone(),
diff --git a/library/test/src/time.rs b/library/test/src/time.rs
index e0b6eadffa1..8c64e5d1b73 100644
--- a/library/test/src/time.rs
+++ b/library/test/src/time.rs
@@ -137,14 +137,13 @@ pub struct TestTimeOptions {
     /// Denotes if the test critical execution time limit excess should be considered
     /// a test failure.
     pub error_on_excess: bool,
-    pub colored: bool,
     pub unit_threshold: TimeThreshold,
     pub integration_threshold: TimeThreshold,
     pub doctest_threshold: TimeThreshold,
 }
 
 impl TestTimeOptions {
-    pub fn new_from_env(error_on_excess: bool, colored: bool) -> Self {
+    pub fn new_from_env(error_on_excess: bool) -> Self {
         let unit_threshold = TimeThreshold::from_env_var(time_constants::UNIT_ENV_NAME)
             .unwrap_or_else(Self::default_unit);
 
@@ -155,7 +154,7 @@ impl TestTimeOptions {
         let doctest_threshold = TimeThreshold::from_env_var(time_constants::DOCTEST_ENV_NAME)
             .unwrap_or_else(Self::default_doctest);
 
-        Self { error_on_excess, colored, unit_threshold, integration_threshold, doctest_threshold }
+        Self { error_on_excess, unit_threshold, integration_threshold, doctest_threshold }
     }
 
     pub fn is_warn(&self, test: &TestDesc, exec_time: &TestExecTime) -> bool {
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
index ef49904b53d..51645a81853 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
@@ -1,6 +1,6 @@
-FROM ubuntu:16.04
+FROM ubuntu:20.04
 
-RUN apt-get update && apt-get install -y --no-install-recommends \
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
   g++ \
   make \
   ninja-build \
diff --git a/src/doc/rustc/src/tests/index.md b/src/doc/rustc/src/tests/index.md
index 23a9f31e8e7..0e0eb85db74 100644
--- a/src/doc/rustc/src/tests/index.md
+++ b/src/doc/rustc/src/tests/index.md
@@ -267,7 +267,7 @@ Controls the format of the output. Valid options:
 
 Writes the results of the tests to the given file.
 
-#### `--report-time` _FORMAT_
+#### `--report-time`
 
 ⚠️ 🚧 This option is [unstable](#unstable-options), and requires the `-Z
 unstable-options` flag. See [tracking issue
diff --git a/src/doc/unstable-book/src/compiler-flags/report-time.md b/src/doc/unstable-book/src/compiler-flags/report-time.md
index ac0093f77ae..9e6a1fb0005 100644
--- a/src/doc/unstable-book/src/compiler-flags/report-time.md
+++ b/src/doc/unstable-book/src/compiler-flags/report-time.md
@@ -21,11 +21,8 @@ Sample usage command:
 Available options:
 
 ```sh
---report-time [plain|colored]
-                Show execution time of each test. Available values:
-                plain = do not colorize the execution time (default);
-                colored = colorize output according to the `color`
-                parameter value;
+--report-time
+                Show execution time of each test.
                 Threshold values for colorized output can be
                 configured via
                 `RUST_TEST_TIME_UNIT`, `RUST_TEST_TIME_INTEGRATION`
diff --git a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
index 3b1d922a7f7..11c4e01f418 100644
--- a/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_mirunsafeck.stderr
@@ -23,10 +23,10 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:36:15
+  --> $DIR/bad-template.rs:36:16
    |
 LL |         asm!("{a}");
-   |               ^^^
+   |                ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:38:15
@@ -123,10 +123,10 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:63:14
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
-   |              ^^^
+   |               ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:65:14
diff --git a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
index 3b1d922a7f7..11c4e01f418 100644
--- a/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.aarch64_thirunsafeck.stderr
@@ -23,10 +23,10 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:36:15
+  --> $DIR/bad-template.rs:36:16
    |
 LL |         asm!("{a}");
-   |               ^^^
+   |                ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:38:15
@@ -123,10 +123,10 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:63:14
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
-   |              ^^^
+   |               ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:65:14
diff --git a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
index 3b69186f1e1..c198e0a69dd 100644
--- a/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_mirunsafeck.stderr
@@ -23,10 +23,10 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:36:15
+  --> $DIR/bad-template.rs:36:16
    |
 LL |         asm!("{a}");
-   |               ^^^
+   |                ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:38:15
@@ -123,10 +123,10 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:63:14
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
-   |              ^^^
+   |               ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:65:14
diff --git a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
index 3b69186f1e1..c198e0a69dd 100644
--- a/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
+++ b/src/test/ui/asm/bad-template.x86_64_thirunsafeck.stderr
@@ -23,10 +23,10 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:36:15
+  --> $DIR/bad-template.rs:36:16
    |
 LL |         asm!("{a}");
-   |               ^^^
+   |                ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:38:15
@@ -123,10 +123,10 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:63:14
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
-   |              ^^^
+   |               ^
 
 error: invalid reference to argument at index 0
   --> $DIR/bad-template.rs:65:14
diff --git a/src/test/ui/binop/issue-28837.stderr b/src/test/ui/binop/issue-28837.stderr
index 10f243bab15..1875ea06a06 100644
--- a/src/test/ui/binop/issue-28837.stderr
+++ b/src/test/ui/binop/issue-28837.stderr
@@ -272,9 +272,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
    |
 LL | struct A;
    | ^^^^^^^^^ must implement `PartialOrd<_>`
-help: consider annotating `A` with `#[derive(PartialOrd)]`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
    |
-LL | #[derive(PartialOrd)]
+LL | #[derive(PartialEq, PartialOrd)]
    |
 
 error[E0369]: binary operation `<=` cannot be applied to type `A`
@@ -290,9 +290,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
    |
 LL | struct A;
    | ^^^^^^^^^ must implement `PartialOrd<_>`
-help: consider annotating `A` with `#[derive(PartialOrd)]`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
    |
-LL | #[derive(PartialOrd)]
+LL | #[derive(PartialEq, PartialOrd)]
    |
 
 error[E0369]: binary operation `>` cannot be applied to type `A`
@@ -308,9 +308,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
    |
 LL | struct A;
    | ^^^^^^^^^ must implement `PartialOrd<_>`
-help: consider annotating `A` with `#[derive(PartialOrd)]`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
    |
-LL | #[derive(PartialOrd)]
+LL | #[derive(PartialEq, PartialOrd)]
    |
 
 error[E0369]: binary operation `>=` cannot be applied to type `A`
@@ -326,9 +326,9 @@ note: an implementation of `PartialOrd<_>` might be missing for `A`
    |
 LL | struct A;
    | ^^^^^^^^^ must implement `PartialOrd<_>`
-help: consider annotating `A` with `#[derive(PartialOrd)]`
+help: consider annotating `A` with `#[derive(PartialEq, PartialOrd)]`
    |
-LL | #[derive(PartialOrd)]
+LL | #[derive(PartialEq, PartialOrd)]
    |
 
 error: aborting due to 15 previous errors
diff --git a/src/test/ui/derives/issue-91550.rs b/src/test/ui/derives/issue-91550.rs
new file mode 100644
index 00000000000..56fd5ffa89e
--- /dev/null
+++ b/src/test/ui/derives/issue-91550.rs
@@ -0,0 +1,29 @@
+use std::collections::HashSet;
+
+/// natural case from the issue
+struct Value(u32);
+
+fn main() {
+    let hs = HashSet::<Value>::new();
+    hs.insert(Value(0)); //~ ERROR
+}
+
+/// synthetic cases
+pub struct NoDerives;
+
+struct Object<T>(T);
+impl<T: Eq> Object<T> {
+    fn use_eq(&self) {}
+}
+impl<T: Ord> Object<T> {
+    fn use_ord(&self) {}
+}
+impl<T: Ord + PartialOrd> Object<T> {
+    fn use_ord_and_partial_ord(&self) {}
+}
+
+fn function(foo: Object<NoDerives>) {
+    foo.use_eq(); //~ ERROR
+    foo.use_ord(); //~ ERROR
+    foo.use_ord_and_partial_ord(); //~ ERROR
+}
diff --git a/src/test/ui/derives/issue-91550.stderr b/src/test/ui/derives/issue-91550.stderr
new file mode 100644
index 00000000000..bf4b7c7da0d
--- /dev/null
+++ b/src/test/ui/derives/issue-91550.stderr
@@ -0,0 +1,84 @@
+error[E0599]: the method `insert` exists for struct `HashSet<Value>`, but its trait bounds were not satisfied
+  --> $DIR/issue-91550.rs:8:8
+   |
+LL | struct Value(u32);
+   | ------------------
+   | |
+   | doesn't satisfy `Value: Eq`
+   | doesn't satisfy `Value: Hash`
+...
+LL |     hs.insert(Value(0));
+   |        ^^^^^^ method cannot be called on `HashSet<Value>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `Value: Eq`
+           `Value: Hash`
+help: consider annotating `Value` with `#[derive(Eq, Hash, PartialEq)]`
+   |
+LL | #[derive(Eq, Hash, PartialEq)]
+   |
+
+error[E0599]: the method `use_eq` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied
+  --> $DIR/issue-91550.rs:26:9
+   |
+LL | pub struct NoDerives;
+   | --------------------- doesn't satisfy `NoDerives: Eq`
+LL | 
+LL | struct Object<T>(T);
+   | -------------------- method `use_eq` not found for this
+...
+LL |     foo.use_eq();
+   |         ^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: Eq`
+help: consider annotating `NoDerives` with `#[derive(Eq, PartialEq)]`
+   |
+LL | #[derive(Eq, PartialEq)]
+   |
+
+error[E0599]: the method `use_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied
+  --> $DIR/issue-91550.rs:27:9
+   |
+LL | pub struct NoDerives;
+   | --------------------- doesn't satisfy `NoDerives: Ord`
+LL | 
+LL | struct Object<T>(T);
+   | -------------------- method `use_ord` not found for this
+...
+LL |     foo.use_ord();
+   |         ^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: Ord`
+help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
+   |
+LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
+   |
+
+error[E0599]: the method `use_ord_and_partial_ord` exists for struct `Object<NoDerives>`, but its trait bounds were not satisfied
+  --> $DIR/issue-91550.rs:28:9
+   |
+LL | pub struct NoDerives;
+   | ---------------------
+   | |
+   | doesn't satisfy `NoDerives: Ord`
+   | doesn't satisfy `NoDerives: PartialOrd`
+LL | 
+LL | struct Object<T>(T);
+   | -------------------- method `use_ord_and_partial_ord` not found for this
+...
+LL |     foo.use_ord_and_partial_ord();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `Object<NoDerives>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `NoDerives: Ord`
+           `NoDerives: PartialOrd`
+help: consider annotating `NoDerives` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
+   |
+LL | #[derive(Eq, Ord, PartialEq, PartialOrd)]
+   |
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs b/src/test/ui/feature-gates/feature-gate-untagged_unions.rs
index f5f9631c3bc..af8d8e92b20 100644
--- a/src/test/ui/feature-gates/feature-gate-untagged_unions.rs
+++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.rs
@@ -13,7 +13,7 @@ union U22<T> { // OK
 }
 
 union U3 {
-    a: String, //~ ERROR unions may not contain fields that need dropping
+    a: String, //~ ERROR unions cannot contain fields that may need dropping
 }
 
 union U32 { // field that does not drop but is not `Copy`, either -- this is the real feature gate test!
@@ -21,7 +21,7 @@ union U32 { // field that does not drop but is not `Copy`, either -- this is the
 }
 
 union U4<T> {
-    a: T, //~ ERROR unions may not contain fields that need dropping
+    a: T, //~ ERROR unions cannot contain fields that may need dropping
 }
 
 union U5 { // Having a drop impl is OK
diff --git a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr
index 0967cb7ba8b..9e4a89f80c8 100644
--- a/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr
+++ b/src/test/ui/feature-gates/feature-gate-untagged_unions.stderr
@@ -7,24 +7,26 @@ LL |     a: std::cell::RefCell<i32>,
    = note: see issue #55149 <https://github.com/rust-lang/rust/issues/55149> for more information
    = help: add `#![feature(untagged_unions)]` to the crate attributes to enable
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/feature-gate-untagged_unions.rs:16:5
    |
 LL |     a: String,
    |     ^^^^^^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<String>,
    |        +++++++++++++++++++++++      +
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/feature-gate-untagged_unions.rs:24:5
    |
 LL |     a: T,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<T>,
    |        +++++++++++++++++++++++ +
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 588541044fe..b8e2b2afb38 100644
--- a/src/test/ui/fmt/format-args-capture-issue-93378.stderr
+++ b/src/test/ui/fmt/format-args-capture-issue-93378.stderr
@@ -10,10 +10,10 @@ 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
+   |                   -   ^^^--^
+   |                   |      |
+   |                   |      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
diff --git a/src/test/ui/fmt/format-args-capture-issue-94010.rs b/src/test/ui/fmt/format-args-capture-issue-94010.rs
new file mode 100644
index 00000000000..bd03e9c93ae
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-94010.rs
@@ -0,0 +1,7 @@
+fn main() {
+    const FOO: i32 = 123;
+    println!("{foo:X}");
+    //~^ ERROR: cannot find value `foo` in this scope
+    println!("{:.foo$}", 0);
+    //~^ ERROR: cannot find value `foo` in this scope
+}
diff --git a/src/test/ui/fmt/format-args-capture-issue-94010.stderr b/src/test/ui/fmt/format-args-capture-issue-94010.stderr
new file mode 100644
index 00000000000..ed90dc85536
--- /dev/null
+++ b/src/test/ui/fmt/format-args-capture-issue-94010.stderr
@@ -0,0 +1,20 @@
+error[E0425]: cannot find value `foo` in this scope
+  --> $DIR/format-args-capture-issue-94010.rs:3:16
+   |
+LL |     const FOO: i32 = 123;
+   |     --------------------- similarly named constant `FOO` defined here
+LL |     println!("{foo:X}");
+   |                ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO`
+
+error[E0425]: cannot find value `foo` in this scope
+  --> $DIR/format-args-capture-issue-94010.rs:5:18
+   |
+LL |     const FOO: i32 = 123;
+   |     --------------------- similarly named constant `FOO` defined here
+...
+LL |     println!("{:.foo$}", 0);
+   |                  ^^^ help: a constant with a similar name exists (notice the capitalization): `FOO`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/src/test/ui/fmt/format-args-capture-missing-variables.stderr b/src/test/ui/fmt/format-args-capture-missing-variables.stderr
index d53c206003f..d980e7be273 100644
--- a/src/test/ui/fmt/format-args-capture-missing-variables.stderr
+++ b/src/test/ui/fmt/format-args-capture-missing-variables.stderr
@@ -7,40 +7,40 @@ LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
    |             formatting specifier missing
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:2:17
+  --> $DIR/format-args-capture-missing-variables.rs:2:18
    |
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
-   |                 ^^^^^ not found in this scope
+   |                  ^^^ not found in this scope
 
 error[E0425]: cannot find value `bar` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:2:26
+  --> $DIR/format-args-capture-missing-variables.rs:2:27
    |
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
-   |                          ^^^^^ not found in this scope
+   |                           ^^^ not found in this scope
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:6:14
+  --> $DIR/format-args-capture-missing-variables.rs:6:15
    |
 LL |     format!("{foo}");
-   |              ^^^^^ not found in this scope
+   |               ^^^ not found in this scope
 
 error[E0425]: cannot find value `valueb` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:8:23
+  --> $DIR/format-args-capture-missing-variables.rs:8:24
    |
 LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
-   |                       ^^^^^^^^ not found in this scope
+   |                        ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:14:9
+  --> $DIR/format-args-capture-missing-variables.rs:14:10
    |
 LL |         {foo}
-   |         ^^^^^ not found in this scope
+   |          ^^^ not found in this scope
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/format-args-capture-missing-variables.rs:19:13
+  --> $DIR/format-args-capture-missing-variables.rs:19:14
    |
 LL |     panic!("{foo} {bar}", bar=1);
-   |             ^^^^^ not found in this scope
+   |              ^^^ not found in this scope
 
 error: aborting due to 7 previous errors
 
diff --git a/src/test/ui/fmt/ifmt-bad-arg.stderr b/src/test/ui/fmt/ifmt-bad-arg.stderr
index acc4e95f5bb..3f1f1006713 100644
--- a/src/test/ui/fmt/ifmt-bad-arg.stderr
+++ b/src/test/ui/fmt/ifmt-bad-arg.stderr
@@ -263,34 +263,34 @@ LL |     println!("{:.*}");
    = note: for information about formatting flags, visit https://doc.rust-lang.org/std/fmt/index.html
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/ifmt-bad-arg.rs:27:17
+  --> $DIR/ifmt-bad-arg.rs:27:18
    |
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
-   |                 ^^^^^ not found in this scope
+   |                  ^^^ not found in this scope
 
 error[E0425]: cannot find value `bar` in this scope
-  --> $DIR/ifmt-bad-arg.rs:27:26
+  --> $DIR/ifmt-bad-arg.rs:27:27
    |
 LL |     format!("{} {foo} {} {bar} {}", 1, 2, 3);
-   |                          ^^^^^ not found in this scope
+   |                           ^^^ not found in this scope
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/ifmt-bad-arg.rs:31:14
+  --> $DIR/ifmt-bad-arg.rs:31:15
    |
 LL |     format!("{foo}");
-   |              ^^^^^ not found in this scope
+   |               ^^^ not found in this scope
 
 error[E0425]: cannot find value `valueb` in this scope
-  --> $DIR/ifmt-bad-arg.rs:45:23
+  --> $DIR/ifmt-bad-arg.rs:45:24
    |
 LL |     format!("{valuea} {valueb}", valuea=5, valuec=7);
-   |                       ^^^^^^^^ not found in this scope
+   |                        ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `foo` in this scope
-  --> $DIR/ifmt-bad-arg.rs:60:9
+  --> $DIR/ifmt-bad-arg.rs:60:10
    |
 LL |         {foo}
-   |         ^^^^^ not found in this scope
+   |          ^^^ not found in this scope
 
 error[E0308]: mismatched types
   --> $DIR/ifmt-bad-arg.rs:78:32
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
new file mode 100644
index 00000000000..26deb598762
--- /dev/null
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.rs
@@ -0,0 +1,22 @@
+struct Struct<T>(T);
+impl Struct<T>
+//~^ ERROR cannot find type `T` in this scope
+//~| NOTE not found in this scope
+//~| HELP you might be missing a type parameter
+where
+    T: Copy,
+    //~^ ERROR cannot find type `T` in this scope
+    //~| NOTE not found in this scope
+{
+    // The part where it claims that there is no method named `len` is a bug. Feel free to fix it.
+    // This test is intended to ensure that a different bug, where it claimed
+    // that `v` was a function, does not regress.
+    fn method(v: Vec<u8>) { v.len(); }
+    //~^ ERROR type annotations needed
+    //~| NOTE cannot infer type
+    //~| NOTE type must be known at this point
+    //~| ERROR no method named `len`
+    //~| NOTE private field, not a method
+}
+
+fn main() {}
diff --git a/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
new file mode 100644
index 00000000000..958ce3c25d0
--- /dev/null
+++ b/src/test/ui/functions-closures/fn-help-with-err-generic-is-not-function.stderr
@@ -0,0 +1,32 @@
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/fn-help-with-err-generic-is-not-function.rs:2:13
+   |
+LL | impl Struct<T>
+   |     -       ^ not found in this scope
+   |     |
+   |     help: you might be missing a type parameter: `<T>`
+
+error[E0412]: cannot find type `T` in this scope
+  --> $DIR/fn-help-with-err-generic-is-not-function.rs:7:5
+   |
+LL |     T: Copy,
+   |     ^ not found in this scope
+
+error[E0282]: type annotations needed
+  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
+   |
+LL |     fn method(v: Vec<u8>) { v.len(); }
+   |                               ^^^ cannot infer type
+   |
+   = note: type must be known at this point
+
+error[E0599]: no method named `len` found for struct `Vec<u8>` in the current scope
+  --> $DIR/fn-help-with-err-generic-is-not-function.rs:14:31
+   |
+LL |     fn method(v: Vec<u8>) { v.len(); }
+   |                               ^^^ private field, not a method
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0282, E0412, E0599.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/src/test/ui/functions-closures/fn-help-with-err.rs b/src/test/ui/functions-closures/fn-help-with-err.rs
new file mode 100644
index 00000000000..f8a81af786f
--- /dev/null
+++ b/src/test/ui/functions-closures/fn-help-with-err.rs
@@ -0,0 +1,16 @@
+// This test case checks the behavior of typeck::check::method::suggest::is_fn on Ty::Error.
+fn main() {
+    let arc = std::sync::Arc::new(oops);
+    //~^ ERROR cannot find value `oops` in this scope
+    //~| NOTE not found
+    // The error "note: `arc` is a function, perhaps you wish to call it" MUST NOT appear.
+    arc.blablabla();
+    //~^ ERROR no method named `blablabla`
+    //~| NOTE method not found
+    let arc2 = std::sync::Arc::new(|| 1);
+    // The error "note: `arc2` is a function, perhaps you wish to call it" SHOULD appear
+    arc2.blablabla();
+    //~^ ERROR no method named `blablabla`
+    //~| NOTE method not found
+    //~| NOTE `arc2` is a function, perhaps you wish to call it
+}
diff --git a/src/test/ui/functions-closures/fn-help-with-err.stderr b/src/test/ui/functions-closures/fn-help-with-err.stderr
new file mode 100644
index 00000000000..4d6b3282ad9
--- /dev/null
+++ b/src/test/ui/functions-closures/fn-help-with-err.stderr
@@ -0,0 +1,24 @@
+error[E0425]: cannot find value `oops` in this scope
+  --> $DIR/fn-help-with-err.rs:3:35
+   |
+LL |     let arc = std::sync::Arc::new(oops);
+   |                                   ^^^^ not found in this scope
+
+error[E0599]: no method named `blablabla` found for struct `Arc<_>` in the current scope
+  --> $DIR/fn-help-with-err.rs:7:9
+   |
+LL |     arc.blablabla();
+   |         ^^^^^^^^^ method not found in `Arc<_>`
+
+error[E0599]: no method named `blablabla` found for struct `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>` in the current scope
+  --> $DIR/fn-help-with-err.rs:12:10
+   |
+LL |     arc2.blablabla();
+   |          ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>`
+   |
+   = note: `arc2` is a function, perhaps you wish to call it
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0425, E0599.
+For more information about an error, try `rustc --explain E0425`.
diff --git a/src/test/ui/typeck/issue-91328.fixed b/src/test/ui/typeck/issue-91328.fixed
index 81b6a996072..c0384399a92 100644
--- a/src/test/ui/typeck/issue-91328.fixed
+++ b/src/test/ui/typeck/issue-91328.fixed
@@ -34,4 +34,14 @@ fn baz(v: Vec<i32>) -> i32 {
     }
 }
 
+fn qux(a: &Option<Box<[i32; 2]>>) -> i32 {
+    match a.as_deref() {
+    //~^ HELP: consider using `as_deref` here
+        Some([a, b]) => a + b,
+        //~^ ERROR: expected an array or slice
+        //~| NOTE: pattern cannot match with input type
+        _ => 42,
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/typeck/issue-91328.rs b/src/test/ui/typeck/issue-91328.rs
index e938d8f5c9f..63602d26f97 100644
--- a/src/test/ui/typeck/issue-91328.rs
+++ b/src/test/ui/typeck/issue-91328.rs
@@ -34,4 +34,14 @@ fn baz(v: Vec<i32>) -> i32 {
     }
 }
 
+fn qux(a: &Option<Box<[i32; 2]>>) -> i32 {
+    match a {
+    //~^ HELP: consider using `as_deref` here
+        Some([a, b]) => a + b,
+        //~^ ERROR: expected an array or slice
+        //~| NOTE: pattern cannot match with input type
+        _ => 42,
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/typeck/issue-91328.stderr b/src/test/ui/typeck/issue-91328.stderr
index 96ad00cde4f..f2f407bcaff 100644
--- a/src/test/ui/typeck/issue-91328.stderr
+++ b/src/test/ui/typeck/issue-91328.stderr
@@ -25,6 +25,15 @@ LL |
 LL |         [a, b] => a + b,
    |         ^^^^^^ pattern cannot match with input type `Vec<i32>`
 
-error: aborting due to 3 previous errors
+error[E0529]: expected an array or slice, found `Box<[i32; 2]>`
+  --> $DIR/issue-91328.rs:40:14
+   |
+LL |     match a {
+   |           - help: consider using `as_deref` here: `a.as_deref()`
+LL |
+LL |         Some([a, b]) => a + b,
+   |              ^^^^^^ pattern cannot match with input type `Box<[i32; 2]>`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0529`.
diff --git a/src/test/ui/union/issue-41073.rs b/src/test/ui/union/issue-41073.rs
index 91e9a0d0b65..80474b807e7 100644
--- a/src/test/ui/union/issue-41073.rs
+++ b/src/test/ui/union/issue-41073.rs
@@ -1,7 +1,7 @@
 #![feature(untagged_unions)]
 
 union Test {
-    a: A, //~ ERROR unions may not contain fields that need dropping
+    a: A, //~ ERROR unions cannot contain fields that may need dropping
     b: B
 }
 
diff --git a/src/test/ui/union/issue-41073.stderr b/src/test/ui/union/issue-41073.stderr
index 8edf4db441b..7d4208b10da 100644
--- a/src/test/ui/union/issue-41073.stderr
+++ b/src/test/ui/union/issue-41073.stderr
@@ -1,10 +1,11 @@
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/issue-41073.rs:4:5
    |
 LL |     a: A,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<A>,
    |        +++++++++++++++++++++++ +
diff --git a/src/test/ui/union/union-custom-drop.rs b/src/test/ui/union/union-custom-drop.rs
index 8f816cc1b73..4b333631ec0 100644
--- a/src/test/ui/union/union-custom-drop.rs
+++ b/src/test/ui/union/union-custom-drop.rs
@@ -4,7 +4,7 @@
 #![feature(untagged_unions)]
 
 union Foo {
-    bar: Bar, //~ ERROR unions may not contain fields that need dropping
+    bar: Bar, //~ ERROR unions cannot contain fields that may need dropping
 }
 
 union Bar {
diff --git a/src/test/ui/union/union-custom-drop.stderr b/src/test/ui/union/union-custom-drop.stderr
index 65ca5fd931d..b5579eeef09 100644
--- a/src/test/ui/union/union-custom-drop.stderr
+++ b/src/test/ui/union/union-custom-drop.stderr
@@ -1,10 +1,11 @@
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-custom-drop.rs:7:5
    |
 LL |     bar: Bar,
    |     ^^^^^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     bar: std::mem::ManuallyDrop<Bar>,
    |          +++++++++++++++++++++++   +
diff --git a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr
index 146a627bcde..e8e65fe5d1d 100644
--- a/src/test/ui/union/union-derive-clone.mirunsafeck.stderr
+++ b/src/test/ui/union/union-derive-clone.mirunsafeck.stderr
@@ -16,9 +16,9 @@ LL |     let w = u.clone();
    = note: the following trait bounds were not satisfied:
            `CloneNoCopy: Copy`
            which is required by `U5<CloneNoCopy>: Clone`
-help: consider annotating `CloneNoCopy` with `#[derive(Copy)]`
+help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
    |
-LL | #[derive(Copy)]
+LL | #[derive(Clone, Copy)]
    |
 
 error[E0277]: the trait bound `U1: Copy` is not satisfied
diff --git a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr
index 146a627bcde..e8e65fe5d1d 100644
--- a/src/test/ui/union/union-derive-clone.thirunsafeck.stderr
+++ b/src/test/ui/union/union-derive-clone.thirunsafeck.stderr
@@ -16,9 +16,9 @@ LL |     let w = u.clone();
    = note: the following trait bounds were not satisfied:
            `CloneNoCopy: Copy`
            which is required by `U5<CloneNoCopy>: Clone`
-help: consider annotating `CloneNoCopy` with `#[derive(Copy)]`
+help: consider annotating `CloneNoCopy` with `#[derive(Clone, Copy)]`
    |
-LL | #[derive(Copy)]
+LL | #[derive(Clone, Copy)]
    |
 
 error[E0277]: the trait bound `U1: Copy` is not satisfied
diff --git a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr
index f5e9681735c..93fe996d2a4 100644
--- a/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr
+++ b/src/test/ui/union/union-with-drop-fields.mirunsafeck.stderr
@@ -1,32 +1,35 @@
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:11:5
    |
 LL |     a: String,
    |     ^^^^^^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<String>,
    |        +++++++++++++++++++++++      +
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:19:5
    |
 LL |     a: S,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<S>,
    |        +++++++++++++++++++++++ +
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:24:5
    |
 LL |     a: T,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<T>,
    |        +++++++++++++++++++++++ +
diff --git a/src/test/ui/union/union-with-drop-fields.rs b/src/test/ui/union/union-with-drop-fields.rs
index 96c293418b6..a7a8b69e784 100644
--- a/src/test/ui/union/union-with-drop-fields.rs
+++ b/src/test/ui/union/union-with-drop-fields.rs
@@ -8,7 +8,7 @@ union U {
 }
 
 union W {
-    a: String, //~ ERROR unions may not contain fields that need dropping
+    a: String, //~ ERROR unions cannot contain fields that may need dropping
     b: String, // OK, only one field is reported
 }
 
@@ -16,12 +16,12 @@ struct S(String);
 
 // `S` doesn't implement `Drop` trait, but still has non-trivial destructor
 union Y {
-    a: S, //~ ERROR unions may not contain fields that need dropping
+    a: S, //~ ERROR unions cannot contain fields that may need dropping
 }
 
 // We don't know if `T` is trivially-destructable or not until trans
 union J<T> {
-    a: T, //~ ERROR unions may not contain fields that need dropping
+    a: T, //~ ERROR unions cannot contain fields that may need dropping
 }
 
 union H<T: Copy> {
diff --git a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr
index f5e9681735c..93fe996d2a4 100644
--- a/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr
+++ b/src/test/ui/union/union-with-drop-fields.thirunsafeck.stderr
@@ -1,32 +1,35 @@
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:11:5
    |
 LL |     a: String,
    |     ^^^^^^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<String>,
    |        +++++++++++++++++++++++      +
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:19:5
    |
 LL |     a: S,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<S>,
    |        +++++++++++++++++++++++ +
 
-error[E0740]: unions may not contain fields that need dropping
+error[E0740]: unions cannot contain fields that may need dropping
   --> $DIR/union-with-drop-fields.rs:24:5
    |
 LL |     a: T,
    |     ^^^^
    |
-help: wrap the type with `std::mem::ManuallyDrop` and ensure it is manually dropped
+   = note: a type is guaranteed not to need dropping when it implements `Copy`, or when it is the special `ManuallyDrop<_>` type
+help: when the type does not implement `Copy`, wrap it inside a `ManuallyDrop<_>` and ensure it is manually dropped
    |
 LL |     a: std::mem::ManuallyDrop<T>,
    |        +++++++++++++++++++++++ +
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index b0044695ea8..1fa6301ebd7 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -453,7 +453,7 @@ impl SimpleFormatArgs {
                     }
                 }
             },
-            ArgumentNamed(n) => {
+            ArgumentNamed(n, _) => {
                 if let Some(x) = self.named.iter_mut().find(|x| x.0 == n) {
                     match x.1.as_slice() {
                         // A non-empty format string has been seen already.