about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml2
-rw-r--r--compiler/rustc_ast/src/util/literal.rs24
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs23
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs10
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs24
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs14
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs26
-rw-r--r--compiler/rustc_feature/src/active.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir/src/intravisit.rs1
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs3
-rw-r--r--compiler/rustc_lexer/src/unescape.rs34
-rw-r--r--compiler/rustc_lexer/src/unescape/tests.rs19
-rw-r--r--compiler/rustc_lint/src/unused.rs10
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs2
-rw-r--r--compiler/rustc_llvm/build.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs112
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs23
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs69
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs14
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs6
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs14
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs2
-rw-r--r--compiler/rustc_save_analysis/src/dump_visitor.rs1
-rw-r--r--compiler/rustc_session/src/parse.rs20
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs15
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs22
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs54
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs3
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs20
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs104
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs2
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs67
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs21
-rw-r--r--compiler/rustc_typeck/src/collect.rs7
-rw-r--r--library/alloc/src/vec/mod.rs2
-rw-r--r--library/core/src/array/mod.rs22
-rw-r--r--library/core/src/ptr/non_null.rs88
-rw-r--r--library/core/src/slice/iter/macros.rs15
-rw-r--r--library/core/tests/slice.rs42
-rw-r--r--library/std/src/macros.rs2
-rw-r--r--src/ci/github-actions/ci.yml2
-rw-r--r--src/doc/rustdoc/src/command-line-arguments.md2
-rw-r--r--src/librustdoc/clean/mod.rs9
m---------src/llvm-project0
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-block-error.stderr4
-rw-r--r--src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-62097.nll.stderr2
-rw-r--r--src/test/ui/async-await/issues/issue-78938-async-block.stderr4
-rw-r--r--src/test/ui/block-result/issue-5500.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr2
-rw-r--r--src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr2
-rw-r--r--src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr2
-rw-r--r--src/test/ui/const-generics/const-argument-if-length.full.stderr9
-rw-r--r--src/test/ui/const-generics/const-argument-if-length.min.stderr4
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-3.stderr3
-rw-r--r--src/test/ui/const-generics/occurs-check/unused-substs-5.stderr3
-rw-r--r--src/test/ui/deref-suggestion.stderr65
-rw-r--r--src/test/ui/diverging-tuple-parts-39485.stderr2
-rw-r--r--src/test/ui/dst/dst-object-from-unsized-type.stderr8
-rw-r--r--src/test/ui/estr-subtyping.stderr3
-rw-r--r--src/test/ui/expr/if/if-no-match-bindings.stderr80
-rw-r--r--src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs4
-rw-r--r--src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs4
-rw-r--r--src/test/ui/feature-gates/feature-gate-trait_upcasting.rs13
-rw-r--r--src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr12
-rw-r--r--src/test/ui/hygiene/auxiliary/intercrate.rs2
-rw-r--r--src/test/ui/hygiene/hygienic-label-1.rs2
-rw-r--r--src/test/ui/hygiene/hygienic-label-1.stderr4
-rw-r--r--src/test/ui/hygiene/hygienic-label-3.rs2
-rw-r--r--src/test/ui/hygiene/hygienic-label-3.stderr4
-rw-r--r--src/test/ui/impl-trait/does-not-live-long-enough.stderr2
-rw-r--r--src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr72
-rw-r--r--src/test/ui/infinite/infinite-autoderef.stderr10
-rw-r--r--src/test/ui/issues/issue-11515.rs4
-rw-r--r--src/test/ui/issues/issue-11515.stderr10
-rw-r--r--src/test/ui/issues/issue-22644.stderr72
-rw-r--r--src/test/ui/issues/issue-32122-1.stderr10
-rw-r--r--src/test/ui/issues/issue-32122-2.stderr10
-rw-r--r--src/test/ui/issues/issue-42954.stderr11
-rw-r--r--src/test/ui/issues/issue-50687-ice-on-borrow.stderr10
-rw-r--r--src/test/ui/issues/issue-71676-1.stderr40
-rw-r--r--src/test/ui/issues/issue-71676-2.stderr10
-rw-r--r--src/test/ui/issues/issue-77218.stderr8
-rw-r--r--src/test/ui/json-bom-plus-crlf-multifile.stderr6
-rw-r--r--src/test/ui/json-bom-plus-crlf.stderr6
-rw-r--r--src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr2
-rw-r--r--src/test/ui/lint/fn_must_use.stderr14
-rw-r--r--src/test/ui/lint/must-use-ops.stderr134
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs15
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs4
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs9
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs16
-rw-r--r--src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr16
-rw-r--r--src/test/ui/lint/unused-borrows.stderr41
-rw-r--r--src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs (renamed from src/test/ui/lint/auxiliary/lint_unused_extern_crate.rs)0
-rw-r--r--src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs (renamed from src/test/ui/lint/auxiliary/lint_unused_extern_crate2.rs)0
-rw-r--r--src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs (renamed from src/test/ui/lint/auxiliary/lint_unused_extern_crate3.rs)0
-rw-r--r--src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs (renamed from src/test/ui/lint/auxiliary/lint_unused_extern_crate4.rs)0
-rw-r--r--src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs (renamed from src/test/ui/lint/auxiliary/lint_unused_extern_crate5.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-30730.rs (renamed from src/test/ui/unused/issue-30730.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-30730.stderr (renamed from src/test/ui/unused/issue-30730.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-46576.rs (renamed from src/test/ui/unused/issue-46576.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-46576.stderr (renamed from src/test/ui/unused/issue-46576.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs (renamed from src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr (renamed from src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed (renamed from src/test/ui/lint/issue-54180-unused-ref-field.fixed)0
-rw-r--r--src/test/ui/lint/unused/issue-54180-unused-ref-field.rs (renamed from src/test/ui/lint/issue-54180-unused-ref-field.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr (renamed from src/test/ui/lint/issue-54180-unused-ref-field.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed (renamed from src/test/ui/lint/issue-54538-unused-parens-lint.fixed)0
-rw-r--r--src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs (renamed from src/test/ui/lint/issue-54538-unused-parens-lint.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr (renamed from src/test/ui/lint/issue-54538-unused-parens-lint.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-59896.rs (renamed from src/test/ui/unused/issue-59896.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-59896.stderr (renamed from src/test/ui/unused/issue-59896.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs (renamed from src/test/ui/lint/issue-67691-unused-field-in-or-pattern.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr (renamed from src/test/ui/lint/issue-67691-unused-field-in-or-pattern.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-70041.rs (renamed from src/test/ui/unused/issue-70041.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-70041.stderr (renamed from src/test/ui/unused/issue-70041.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs (renamed from src/test/ui/lint/issue-71290-unused-paren-binop.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs (renamed from src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr (renamed from src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed (renamed from src/test/ui/lint/issue-81314-unused-span-ident.fixed)0
-rw-r--r--src/test/ui/lint/unused/issue-81314-unused-span-ident.rs (renamed from src/test/ui/lint/issue-81314-unused-span-ident.rs)0
-rw-r--r--src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr (renamed from src/test/ui/lint/issue-81314-unused-span-ident.stderr)0
-rw-r--r--src/test/ui/lint/unused/issue-85913.rs13
-rw-r--r--src/test/ui/lint/unused/issue-85913.stderr18
-rw-r--r--src/test/ui/lint/unused/lint-unused-extern-crate.rs (renamed from src/test/ui/lint/lint-unused-extern-crate.rs)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-extern-crate.stderr (renamed from src/test/ui/lint/lint-unused-extern-crate.stderr)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-imports.rs (renamed from src/test/ui/lint/lint-unused-imports.rs)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-imports.stderr (renamed from src/test/ui/lint/lint-unused-imports.stderr)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-mut-self.fixed (renamed from src/test/ui/lint/lint-unused-mut-self.fixed)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-mut-self.rs (renamed from src/test/ui/lint/lint-unused-mut-self.rs)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-mut-self.stderr (renamed from src/test/ui/lint/lint-unused-mut-self.stderr)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-mut-variables.rs (renamed from src/test/ui/lint/lint-unused-mut-variables.rs)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-mut-variables.stderr (renamed from src/test/ui/lint/lint-unused-mut-variables.stderr)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-variables.rs (renamed from src/test/ui/lint/lint-unused-variables.rs)0
-rw-r--r--src/test/ui/lint/unused/lint-unused-variables.stderr (renamed from src/test/ui/lint/lint-unused-variables.stderr)0
-rw-r--r--src/test/ui/lint/unused/must-use-ops.rs (renamed from src/test/ui/lint/must-use-ops.rs)0
-rw-r--r--src/test/ui/lint/unused/must-use-ops.stderr238
-rw-r--r--src/test/ui/lint/unused/must_use-array.rs (renamed from src/test/ui/lint/must_use-array.rs)0
-rw-r--r--src/test/ui/lint/unused/must_use-array.stderr (renamed from src/test/ui/lint/must_use-array.stderr)0
-rw-r--r--src/test/ui/lint/unused/must_use-in-stdlib-traits.rs (renamed from src/test/ui/lint/must_use-in-stdlib-traits.rs)0
-rw-r--r--src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr (renamed from src/test/ui/lint/must_use-in-stdlib-traits.stderr)0
-rw-r--r--src/test/ui/lint/unused/must_use-trait.rs (renamed from src/test/ui/lint/must_use-trait.rs)0
-rw-r--r--src/test/ui/lint/unused/must_use-trait.stderr (renamed from src/test/ui/lint/must_use-trait.stderr)0
-rw-r--r--src/test/ui/lint/unused/must_use-tuple.rs (renamed from src/test/ui/lint/must_use-tuple.rs)0
-rw-r--r--src/test/ui/lint/unused/must_use-tuple.stderr (renamed from src/test/ui/lint/must_use-tuple.stderr)0
-rw-r--r--src/test/ui/lint/unused/must_use-unit.rs (renamed from src/test/ui/lint/must_use-unit.rs)0
-rw-r--r--src/test/ui/lint/unused/must_use-unit.stderr (renamed from src/test/ui/lint/must_use-unit.stderr)0
-rw-r--r--src/test/ui/lint/unused/no-unused-parens-return-block.rs (renamed from src/test/ui/lint/no-unused-parens-return-block.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-attr-macro-rules.rs (renamed from src/test/ui/unused/unused-attr-macro-rules.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-attr-macro-rules.stderr (renamed from src/test/ui/unused/unused-attr-macro-rules.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-attr.rs (renamed from src/test/ui/unused/unused-attr.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-attr.stderr (renamed from src/test/ui/unused/unused-attr.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-closure.rs (renamed from src/test/ui/unused/unused-closure.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-closure.stderr (renamed from src/test/ui/unused/unused-closure.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs (renamed from src/test/ui/unused/unused-doc-comments-edge-cases.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr (renamed from src/test/ui/unused/unused-doc-comments-edge-cases.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-for-macros.rs (renamed from src/test/ui/unused/unused-doc-comments-for-macros.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr (renamed from src/test/ui/unused/unused-doc-comments-for-macros.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-rules.rs (renamed from src/test/ui/unused/unused-macro-rules.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-rules.stderr (renamed from src/test/ui/unused/unused-macro-rules.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs (renamed from src/test/ui/unused/unused-macro-with-bad-frag-spec.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr (renamed from src/test/ui/unused/unused-macro-with-bad-frag-spec.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-with-follow-violation.rs (renamed from src/test/ui/unused/unused-macro-with-follow-violation.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr (renamed from src/test/ui/unused/unused-macro-with-follow-violation.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-macro.rs (renamed from src/test/ui/unused/unused-macro.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-macro.stderr (renamed from src/test/ui/unused/unused-macro.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed (renamed from src/test/ui/unused/unused-mut-warning-captured-var.fixed)0
-rw-r--r--src/test/ui/lint/unused/unused-mut-warning-captured-var.rs (renamed from src/test/ui/unused/unused-mut-warning-captured-var.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr (renamed from src/test/ui/unused/unused-mut-warning-captured-var.stderr)0
-rw-r--r--src/test/ui/lint/unused/unused-result.rs (renamed from src/test/ui/unused/unused-result.rs)0
-rw-r--r--src/test/ui/lint/unused/unused-result.stderr (renamed from src/test/ui/unused/unused-result.stderr)0
-rw-r--r--src/test/ui/lint/unused/useless-comment.rs (renamed from src/test/ui/unused/useless-comment.rs)0
-rw-r--r--src/test/ui/lint/unused/useless-comment.stderr (renamed from src/test/ui/unused/useless-comment.stderr)0
-rw-r--r--src/test/ui/macros/macro-context.rs2
-rw-r--r--src/test/ui/macros/macro-context.stderr16
-rw-r--r--src/test/ui/macros/macro-in-expression-context.fixed12
-rw-r--r--src/test/ui/macros/macro-in-expression-context.rs12
-rw-r--r--src/test/ui/macros/macro-in-expression-context.stderr20
-rw-r--r--src/test/ui/mismatched_types/abridged.stderr20
-rw-r--r--src/test/ui/never_type/issue-52443.stderr9
-rw-r--r--src/test/ui/occurs-check-2.stderr10
-rw-r--r--src/test/ui/occurs-check.stderr10
-rw-r--r--src/test/ui/packed/issue-27060-2.stderr4
-rw-r--r--src/test/ui/parser/expr-as-stmt-2.stderr7
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr36
-rw-r--r--src/test/ui/proc-macro/nested-nonterminal-tokens.rs2
-rw-r--r--src/test/ui/regions/region-borrow-params-issue-29793-big.stderr4
-rw-r--r--src/test/ui/regions/region-borrow-params-issue-29793-small.stderr40
-rw-r--r--src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr20
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.fixed37
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.rs37
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.stderr34
-rw-r--r--src/test/ui/rust-2021/prelude2021.rs (renamed from src/test/ui/prelude2021.rs)0
-rw-r--r--src/test/ui/span/coerce-suggestions.stderr10
-rw-r--r--src/test/ui/static/bad-const-type.stderr3
-rw-r--r--src/test/ui/str/str-lit-type-mismatch.stderr30
-rw-r--r--src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr4
-rw-r--r--src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr18
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.fixed3
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.rs3
-rw-r--r--src/test/ui/suggestions/for-i-in-vec.stderr25
-rw-r--r--src/test/ui/suggestions/format-borrow.stderr44
-rw-r--r--src/test/ui/suggestions/issue-52820.stderr10
-rw-r--r--src/test/ui/suggestions/issue-59819.stderr25
-rw-r--r--src/test/ui/suggestions/issue-82361.stderr30
-rw-r--r--src/test/ui/suggestions/issue-83943.stderr3
-rw-r--r--src/test/ui/suggestions/mut-ref-reassignment.stderr4
-rw-r--r--src/test/ui/suggestions/option-content-move.stderr20
-rw-r--r--src/test/ui/suggestions/raw-byte-string-prefix.rs10
-rw-r--r--src/test/ui/suggestions/raw-byte-string-prefix.stderr20
-rw-r--r--src/test/ui/trait-bounds/unsized-bound.rs32
-rw-r--r--src/test/ui/trait-bounds/unsized-bound.stderr234
-rw-r--r--src/test/ui/traits/suggest-where-clause.stderr9
-rw-r--r--src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs13
-rw-r--r--src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs22
-rw-r--r--src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr14
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.rs33
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr80
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.rs34
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr61
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.rs22
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr33
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.rs32
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr47
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.rs13
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-74280.stderr14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-77179.rs14
-rw-r--r--src/test/ui/type-alias-impl-trait/issue-77179.stderr12
-rw-r--r--src/test/ui/typeck/conversion-methods.stderr19
-rw-r--r--src/test/ui/union/union-sized-field.stderr12
-rw-r--r--src/test/ui/unsized/unsized-bare-typaram.stderr5
-rw-r--r--src/test/ui/unsized/unsized-enum.stderr4
-rw-r--r--src/test/ui/unsized/unsized-enum2.stderr16
-rw-r--r--src/test/ui/unsized/unsized-fn-arg.fixed2
-rw-r--r--src/test/ui/unsized/unsized-fn-arg.stderr4
-rw-r--r--src/test/ui/unsized/unsized-inherent-impl-self-type.stderr4
-rw-r--r--src/test/ui/unsized/unsized-struct.stderr8
-rw-r--r--src/test/ui/unsized/unsized-trait-impl-self-type.stderr4
-rw-r--r--src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr4
-rw-r--r--src/test/ui/unsized/unsized3.stderr24
-rw-r--r--src/test/ui/unsized/unsized5.stderr16
-rw-r--r--src/test/ui/unsized/unsized6.stderr52
-rw-r--r--src/test/ui/unsized/unsized7.stderr4
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6250.stderr10
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow_pat.rs2
-rw-r--r--src/tools/clippy/tests/ui/ref_binding_to_reference.rs2
251 files changed, 2786 insertions, 736 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index fe67a14c0fe..a07342ee96c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -288,7 +288,7 @@ jobs:
           - name: dist-x86_64-apple
             env:
               SCRIPT: "./x.py dist"
-              RUST_CONFIGURE_ARGS: "--host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
+              RUST_CONFIGURE_ARGS: "--host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
               MACOSX_DEPLOYMENT_TARGET: 10.7
               NO_LLVM_ASSERTIONS: 1
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 2124f1efb99..9c6ad47427d 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -63,7 +63,11 @@ impl LitKind {
                         unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| {
                             match unescaped_char {
                                 Ok(c) => buf.push(c),
-                                Err(_) => error = Err(LitError::LexerError),
+                                Err(err) => {
+                                    if err.is_fatal() {
+                                        error = Err(LitError::LexerError);
+                                    }
+                                }
                             }
                         });
                         error?;
@@ -83,7 +87,11 @@ impl LitKind {
                         unescape_literal(&s, Mode::RawStr, &mut |_, unescaped_char| {
                             match unescaped_char {
                                 Ok(c) => buf.push(c),
-                                Err(_) => error = Err(LitError::LexerError),
+                                Err(err) => {
+                                    if err.is_fatal() {
+                                        error = Err(LitError::LexerError);
+                                    }
+                                }
                             }
                         });
                         error?;
@@ -100,7 +108,11 @@ impl LitKind {
                 unescape_byte_literal(&s, Mode::ByteStr, &mut |_, unescaped_byte| {
                     match unescaped_byte {
                         Ok(c) => buf.push(c),
-                        Err(_) => error = Err(LitError::LexerError),
+                        Err(err) => {
+                            if err.is_fatal() {
+                                error = Err(LitError::LexerError);
+                            }
+                        }
                     }
                 });
                 error?;
@@ -114,7 +126,11 @@ impl LitKind {
                     unescape_byte_literal(&s, Mode::RawByteStr, &mut |_, unescaped_byte| {
                         match unescaped_byte {
                             Ok(c) => buf.push(c),
-                            Err(_) => error = Err(LitError::LexerError),
+                            Err(err) => {
+                                if err.is_fatal() {
+                                    error = Err(LitError::LexerError);
+                                }
+                            }
                         }
                     });
                     error?;
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 0fddb0ee4cc..3acf69ec2b7 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1443,16 +1443,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             ImplTraitContext::disallowed(),
                         ),
                         bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
-                        bounds: this.arena.alloc_from_iter(bounds.iter().filter_map(|bound| {
-                            match *bound {
-                                // Ignore `?Trait` bounds.
-                                // They were copied into type parameters already.
-                                GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
-                                _ => Some(
-                                    this.lower_param_bound(bound, ImplTraitContext::disallowed()),
-                                ),
-                            }
-                        })),
+                        bounds: this.arena.alloc_from_iter(bounds.iter().map(
+                            |bound| match bound {
+                                // We used to ignore `?Trait` bounds, as they were copied into type
+                                // parameters already, but we need to keep them around only for
+                                // diagnostics when we suggest removal of `?Sized` bounds. See
+                                // `suggest_constraining_type_param`. This will need to change if
+                                // we ever allow something *other* than `?Sized`.
+                                GenericBound::Trait(p, TraitBoundModifier::Maybe) => {
+                                    hir::GenericBound::Unsized(p.span)
+                                }
+                                _ => this.lower_param_bound(bound, ImplTraitContext::disallowed()),
+                            },
+                        )),
                         span,
                     })
                 })
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 3bd42ba6090..581f177ad14 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -2160,12 +2160,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         tpb: &GenericBound,
         itctx: ImplTraitContext<'_, 'hir>,
     ) -> hir::GenericBound<'hir> {
-        match *tpb {
-            GenericBound::Trait(ref ty, modifier) => hir::GenericBound::Trait(
-                self.lower_poly_trait_ref(ty, itctx),
-                self.lower_trait_bound_modifier(modifier),
+        match tpb {
+            GenericBound::Trait(p, modifier) => hir::GenericBound::Trait(
+                self.lower_poly_trait_ref(p, itctx),
+                self.lower_trait_bound_modifier(*modifier),
             ),
-            GenericBound::Outlives(ref lifetime) => {
+            GenericBound::Outlives(lifetime) => {
                 hir::GenericBound::Outlives(self.lower_lifetime(lifetime))
             }
         }
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 45661ac1562..8199c44ee2a 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -444,6 +444,30 @@ impl Diagnostic {
         self
     }
 
+    /// Prints out a message with multiple suggested edits of the code.
+    /// See also [`Diagnostic::span_suggestion()`].
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: impl Iterator<Item = Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        self.suggestions.push(CodeSuggestion {
+            substitutions: suggestions
+                .map(|sugg| Substitution {
+                    parts: sugg
+                        .into_iter()
+                        .map(|(span, snippet)| SubstitutionPart { snippet, span })
+                        .collect(),
+                })
+                .collect(),
+            msg: msg.to_owned(),
+            style: SuggestionStyle::ShowCode,
+            applicability,
+            tool_metadata: Default::default(),
+        });
+        self
+    }
     /// Prints out a message with a suggested edit of the code. If the suggestion is presented
     /// inline, it will only show the message and not the suggestion.
     ///
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 282877d5dd1..d35b2924803 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -301,6 +301,20 @@ impl<'a> DiagnosticBuilder<'a> {
         self
     }
 
+    /// See [`Diagnostic::multipart_suggestions()`].
+    pub fn multipart_suggestions(
+        &mut self,
+        msg: &str,
+        suggestions: impl Iterator<Item = Vec<(Span, String)>>,
+        applicability: Applicability,
+    ) -> &mut Self {
+        if !self.0.allow_suggestions {
+            return self;
+        }
+        self.0.diagnostic.multipart_suggestions(msg, suggestions, applicability);
+        self
+    }
+
     /// See [`Diagnostic::span_suggestion_short()`].
     pub fn span_suggestion_short(
         &mut self,
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index b97593b92b3..9aee86c9e57 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -45,6 +45,8 @@ crate struct ParserAnyMacro<'a> {
     lint_node_id: NodeId,
     is_trailing_mac: bool,
     arm_span: Span,
+    /// Whether or not this macro is defined in the current crate
+    is_local: bool,
 }
 
 crate fn annotate_err_with_kind(
@@ -124,6 +126,7 @@ impl<'a> ParserAnyMacro<'a> {
             lint_node_id,
             arm_span,
             is_trailing_mac,
+            is_local,
         } = *self;
         let snapshot = &mut parser.clone();
         let fragment = match parse_ast_fragment(parser, kind) {
@@ -138,13 +141,15 @@ impl<'a> ParserAnyMacro<'a> {
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
         // but `m!()` is allowed in expression positions (cf. issue #34706).
         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
-            parser.sess.buffer_lint_with_diagnostic(
-                SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
-                parser.token.span,
-                lint_node_id,
-                "trailing semicolon in macro used in expression position",
-                BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
-            );
+            if is_local {
+                parser.sess.buffer_lint_with_diagnostic(
+                    SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
+                    parser.token.span,
+                    lint_node_id,
+                    "trailing semicolon in macro used in expression position",
+                    BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
+                );
+            }
             parser.bump();
         }
 
@@ -162,6 +167,7 @@ struct MacroRulesMacroExpander {
     lhses: Vec<mbe::TokenTree>,
     rhses: Vec<mbe::TokenTree>,
     valid: bool,
+    is_local: bool,
 }
 
 impl TTMacroExpander for MacroRulesMacroExpander {
@@ -183,6 +189,7 @@ impl TTMacroExpander for MacroRulesMacroExpander {
             input,
             &self.lhses,
             &self.rhses,
+            self.is_local,
         )
     }
 }
@@ -210,6 +217,7 @@ fn generic_extension<'cx>(
     arg: TokenStream,
     lhses: &[mbe::TokenTree],
     rhses: &[mbe::TokenTree],
+    is_local: bool,
 ) -> Box<dyn MacResult + 'cx> {
     let sess = &cx.sess.parse_sess;
 
@@ -311,6 +319,7 @@ fn generic_extension<'cx>(
                     lint_node_id: cx.current_expansion.lint_node_id,
                     is_trailing_mac: cx.current_expansion.is_trailing_mac,
                     arm_span,
+                    is_local,
                 });
             }
             Failure(token, msg) => match best_failure {
@@ -544,6 +553,9 @@ pub fn compile_declarative_macro(
         lhses,
         rhses,
         valid,
+        // Macros defined in the current crate have a real node id,
+        // whereas macros from an external crate have a dummy id.
+        is_local: def.id != DUMMY_NODE_ID,
     }))
 }
 
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 1ec9a0518b8..638330c904d 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -683,6 +683,10 @@ declare_features! (
     /// Allows the `?` operator in const contexts.
     (active, const_try, "1.56.0", Some(74935), None),
 
+    /// Allows upcasting trait objects via supertraits.
+    /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
+    (incomplete, trait_upcasting, "1.56.0", Some(65991), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index db7fe6cb12f..aac5d296f17 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -442,6 +442,7 @@ pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
     // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
     LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
+    Unsized(Span),
     Outlives(Lifetime),
 }
 
@@ -458,6 +459,7 @@ impl GenericBound<'_> {
             GenericBound::Trait(t, ..) => t.span,
             GenericBound::LangItemTrait(_, span, ..) => *span,
             GenericBound::Outlives(l) => l.span,
+            GenericBound::Unsized(span) => *span,
         }
     }
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 17835493cda..ae186d66004 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -889,6 +889,7 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
             visitor.visit_generic_args(span, args);
         }
         GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
+        GenericBound::Unsized(_) => {}
     }
 }
 
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 90ceb1d5c91..2b372392575 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2230,6 +2230,9 @@ impl<'a> State<'a> {
                 GenericBound::Outlives(lt) => {
                     self.print_lifetime(lt);
                 }
+                GenericBound::Unsized(_) => {
+                    self.s.word("?Sized");
+                }
             }
         }
     }
diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index b4dd0fc2449..9a96c03cd3c 100644
--- a/compiler/rustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
@@ -7,7 +7,7 @@ use std::str::Chars;
 #[cfg(test)]
 mod tests;
 
-/// Errors that can occur during string unescaping.
+/// Errors and warnings that can occur during string unescaping.
 #[derive(Debug, PartialEq, Eq)]
 pub enum EscapeError {
     /// Expected 1 char, but 0 were found.
@@ -56,6 +56,20 @@ pub enum EscapeError {
     NonAsciiCharInByte,
     /// Non-ascii character in byte string literal.
     NonAsciiCharInByteString,
+
+    /// After a line ending with '\', the next line contains whitespace
+    /// characters that are not skipped.
+    UnskippedWhitespaceWarning,
+}
+
+impl EscapeError {
+    /// Returns true for actual errors, as opposed to warnings.
+    pub fn is_fatal(&self) -> bool {
+        match self {
+            EscapeError::UnskippedWhitespaceWarning => false,
+            _ => true,
+        }
+    }
 }
 
 /// Takes a contents of a literal (without quotes) and produces a
@@ -283,7 +297,7 @@ where
                         // if unescaped '\' character is followed by '\n'.
                         // For details see [Rust language reference]
                         // (https://doc.rust-lang.org/reference/tokens.html#string-literals).
-                        skip_ascii_whitespace(&mut chars);
+                        skip_ascii_whitespace(&mut chars, start, callback);
                         continue;
                     }
                     _ => scan_escape(first_char, &mut chars, mode),
@@ -297,13 +311,25 @@ where
         callback(start..end, unescaped_char);
     }
 
-    fn skip_ascii_whitespace(chars: &mut Chars<'_>) {
+    fn skip_ascii_whitespace<F>(chars: &mut Chars<'_>, start: usize, callback: &mut F)
+    where
+        F: FnMut(Range<usize>, Result<char, EscapeError>),
+    {
         let str = chars.as_str();
         let first_non_space = str
             .bytes()
             .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r')
             .unwrap_or(str.len());
-        *chars = str[first_non_space..].chars()
+        let tail = &str[first_non_space..];
+        if let Some(c) = tail.chars().nth(0) {
+            // For error reporting, we would like the span to contain the character that was not
+            // skipped.  The +1 is necessary to account for the leading \ that started the escape.
+            let end = start + first_non_space + c.len_utf8() + 1;
+            if c.is_whitespace() {
+                callback(start..end, Err(EscapeError::UnskippedWhitespaceWarning));
+            }
+        }
+        *chars = tail.chars();
     }
 }
 
diff --git a/compiler/rustc_lexer/src/unescape/tests.rs b/compiler/rustc_lexer/src/unescape/tests.rs
index f2b751a78f2..1f4dbb20f4e 100644
--- a/compiler/rustc_lexer/src/unescape/tests.rs
+++ b/compiler/rustc_lexer/src/unescape/tests.rs
@@ -99,6 +99,25 @@ fn test_unescape_char_good() {
 }
 
 #[test]
+fn test_unescape_str_warn() {
+    fn check(literal: &str, expected: &[(Range<usize>, Result<char, EscapeError>)]) {
+        let mut unescaped = Vec::with_capacity(literal.len());
+        unescape_literal(literal, Mode::Str, &mut |range, res| unescaped.push((range, res)));
+        assert_eq!(unescaped, expected);
+    }
+
+    check(
+        "\\\n \u{a0} x",
+        &[
+            (0..5, Err(EscapeError::UnskippedWhitespaceWarning)),
+            (3..5, Ok('\u{a0}')),
+            (5..6, Ok(' ')),
+            (6..7, Ok('x')),
+        ],
+    );
+}
+
+#[test]
 fn test_unescape_str_good() {
     fn check(literal_text: &str, expected: &str) {
         let mut buf = Ok(String::with_capacity(literal_text.len()));
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index c431c048ca0..2b580452a60 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -161,7 +161,15 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
 
         if let Some(must_use_op) = must_use_op {
             cx.struct_span_lint(UNUSED_MUST_USE, expr.span, |lint| {
-                lint.build(&format!("unused {} that must be used", must_use_op)).emit()
+                let mut lint = lint.build(&format!("unused {} that must be used", must_use_op));
+                lint.span_label(expr.span, &format!("the {} produces a value", must_use_op));
+                lint.span_suggestion_verbose(
+                    expr.span.shrink_to_lo(),
+                    "use `let _ = ...` to ignore the resulting value",
+                    "let _ = ".to_string(),
+                    Applicability::MachineApplicable,
+                );
+                lint.emit();
             });
             op_warned = true;
         }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 5b1cd0bcb3f..7195c41eae9 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2799,7 +2799,7 @@ declare_lint! {
     /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
     /// [future-incompatible]: ../index.md#future-incompatible-lints
     pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
-    Allow,
+    Warn,
     "trailing semicolon in macro body used as expression",
     @future_incompatible = FutureIncompatibleInfo {
         reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 452d1b19a18..964b7cace9c 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -182,7 +182,7 @@ fn main() {
     } else if target.contains("windows-gnu") {
         println!("cargo:rustc-link-lib=shell32");
         println!("cargo:rustc-link-lib=uuid");
-    } else if target.contains("netbsd") || target.contains("haiku") {
+    } else if target.contains("netbsd") || target.contains("haiku") || target.contains("darwin") {
         println!("cargo:rustc-link-lib=z");
     }
     cmd.args(&components);
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index bfb4c0cb538..4cfb104bee3 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -2,6 +2,7 @@
 
 use crate::ty::TyKind::*;
 use crate::ty::{InferTy, TyCtxt, TyS};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
@@ -105,6 +106,116 @@ pub fn suggest_arbitrary_trait_bound(
     true
 }
 
+fn suggest_removing_unsized_bound(
+    generics: &hir::Generics<'_>,
+    err: &mut DiagnosticBuilder<'_>,
+    param_name: &str,
+    param: &hir::GenericParam<'_>,
+    def_id: Option<DefId>,
+) {
+    // See if there's a `?Sized` bound that can be removed to suggest that.
+    // First look at the `where` clause because we can have `where T: ?Sized`, but that
+    // `?Sized` bound is *also* included in the `GenericParam` as a bound, which breaks
+    // the spans. Hence the somewhat involved logic that follows.
+    let mut where_unsized_bounds = FxHashSet::default();
+    for (where_pos, predicate) in generics.where_clause.predicates.iter().enumerate() {
+        match predicate {
+            WherePredicate::BoundPredicate(WhereBoundPredicate {
+                bounded_ty:
+                    hir::Ty {
+                        kind:
+                            hir::TyKind::Path(hir::QPath::Resolved(
+                                None,
+                                hir::Path {
+                                    segments: [segment],
+                                    res: hir::def::Res::Def(hir::def::DefKind::TyParam, _),
+                                    ..
+                                },
+                            )),
+                        ..
+                    },
+                bounds,
+                span,
+                ..
+            }) if segment.ident.as_str() == param_name => {
+                for (pos, bound) in bounds.iter().enumerate() {
+                    match bound {
+                        hir::GenericBound::Unsized(_) => {}
+                        hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe)
+                            if poly.trait_ref.trait_def_id() == def_id => {}
+                        _ => continue,
+                    }
+                    let sp = match (
+                        bounds.len(),
+                        pos,
+                        generics.where_clause.predicates.len(),
+                        where_pos,
+                    ) {
+                        // where T: ?Sized
+                        // ^^^^^^^^^^^^^^^
+                        (1, _, 1, _) => generics.where_clause.span,
+                        // where Foo: Bar, T: ?Sized,
+                        //               ^^^^^^^^^^^
+                        (1, _, len, pos) if pos == len - 1 => generics.where_clause.predicates
+                            [pos - 1]
+                            .span()
+                            .shrink_to_hi()
+                            .to(*span),
+                        // where T: ?Sized, Foo: Bar,
+                        //       ^^^^^^^^^^^
+                        (1, _, _, pos) => {
+                            span.until(generics.where_clause.predicates[pos + 1].span())
+                        }
+                        // where T: ?Sized + Bar, Foo: Bar,
+                        //          ^^^^^^^^^
+                        (_, 0, _, _) => bound.span().to(bounds[1].span().shrink_to_lo()),
+                        // where T: Bar + ?Sized, Foo: Bar,
+                        //             ^^^^^^^^^
+                        (_, pos, _, _) => bounds[pos - 1].span().shrink_to_hi().to(bound.span()),
+                    };
+                    where_unsized_bounds.insert(bound.span());
+                    err.span_suggestion_verbose(
+                        sp,
+                        "consider removing the `?Sized` bound to make the \
+                            type parameter `Sized`",
+                        String::new(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+            }
+            _ => {}
+        }
+    }
+    for (pos, bound) in param.bounds.iter().enumerate() {
+        match bound {
+            hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe)
+                if poly.trait_ref.trait_def_id() == def_id
+                    && !where_unsized_bounds.contains(&bound.span()) =>
+            {
+                let sp = match (param.bounds.len(), pos) {
+                    // T: ?Sized,
+                    //  ^^^^^^^^
+                    (1, _) => param.span.shrink_to_hi().to(bound.span()),
+                    // T: ?Sized + Bar,
+                    //    ^^^^^^^^^
+                    (_, 0) => bound.span().to(param.bounds[1].span().shrink_to_lo()),
+                    // T: Bar + ?Sized,
+                    //       ^^^^^^^^^
+                    (_, pos) => param.bounds[pos - 1].span().shrink_to_hi().to(bound.span()),
+                };
+                err.span_suggestion_verbose(
+                    sp,
+                    "consider removing the `?Sized` bound to make the type parameter \
+                        `Sized`",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            _ => {}
+        }
+    }
+}
+
 /// Suggest restricting a type param with a new bound.
 pub fn suggest_constraining_type_param(
     tcx: TyCtxt<'_>,
@@ -130,6 +241,7 @@ pub fn suggest_constraining_type_param(
     if def_id == tcx.lang_items().sized_trait() {
         // Type parameters are already `Sized` by default.
         err.span_label(param.span, &format!("this type parameter needs to be `{}`", constraint));
+        suggest_removing_unsized_bound(generics, err, param_name, param, def_id);
         return true;
     }
     let mut suggest_restrict = |span| {
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index 2e854ea5be7..a9bfbb51573 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
@@ -12,7 +12,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
 use rustc_span::source_map::DesugaringKind;
 use rustc_span::symbol::sym;
-use rustc_span::{MultiSpan, Span, DUMMY_SP};
+use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
 use rustc_trait_selection::infer::InferCtxtExt;
 
 use crate::dataflow::drop_flag_effects;
@@ -1393,18 +1393,19 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let tcx = self.infcx.tcx;
         let args_span = use_span.args_or_use();
 
-        let suggestion = match tcx.sess.source_map().span_to_snippet(args_span) {
-            Ok(mut string) => {
+        let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
+            Ok(string) => {
                 if string.starts_with("async ") {
-                    string.insert_str(6, "move ");
+                    let pos = args_span.lo() + BytePos(6);
+                    (args_span.with_lo(pos).with_hi(pos), "move ".to_string())
                 } else if string.starts_with("async|") {
-                    string.insert_str(5, " move");
+                    let pos = args_span.lo() + BytePos(5);
+                    (args_span.with_lo(pos).with_hi(pos), " move".to_string())
                 } else {
-                    string.insert_str(0, "move ");
-                };
-                string
+                    (args_span.shrink_to_lo(), "move ".to_string())
+                }
             }
-            Err(_) => "move |<args>| <body>".to_string(),
+            Err(_) => (args_span, "move |<args>| <body>".to_string()),
         };
         let kind = match use_span.generator_kind() {
             Some(generator_kind) => match generator_kind {
@@ -1420,8 +1421,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         let mut err =
             self.cannot_capture_in_long_lived_closure(args_span, kind, captured_var, var_span);
-        err.span_suggestion(
-            args_span,
+        err.span_suggestion_verbose(
+            sugg_span,
             &format!(
                 "to force the {} to take ownership of {} (and any \
                  other referenced variables), use the `move` keyword",
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
index 3f87d9c7ac9..2be23159bf5 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/move_errors.rs
@@ -2,7 +2,8 @@ use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_middle::mir::*;
 use rustc_middle::ty;
 use rustc_span::source_map::DesugaringKind;
-use rustc_span::{sym, Span};
+use rustc_span::{sym, Span, DUMMY_SP};
+use rustc_trait_selection::traits::type_known_to_meet_bound_modulo_regions;
 
 use crate::borrow_check::diagnostics::UseSpans;
 use crate::borrow_check::prefixes::PrefixSet;
@@ -384,36 +385,44 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 }
             }
         };
-        if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
-            let def_id = match *move_place.ty(self.body, self.infcx.tcx).ty.kind() {
-                ty::Adt(self_def, _) => self_def.did,
-                ty::Foreign(def_id)
-                | ty::FnDef(def_id, _)
-                | ty::Closure(def_id, _)
-                | ty::Generator(def_id, ..)
-                | ty::Opaque(def_id, _) => def_id,
-                _ => return err,
+        let ty = move_place.ty(self.body, self.infcx.tcx).ty;
+        let def_id = match *ty.kind() {
+            ty::Adt(self_def, _) => self_def.did,
+            ty::Foreign(def_id)
+            | ty::FnDef(def_id, _)
+            | ty::Closure(def_id, _)
+            | ty::Generator(def_id, ..)
+            | ty::Opaque(def_id, _) => def_id,
+            _ => return err,
+        };
+        let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
+        let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
+        if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
+            err.span_suggestion_verbose(
+                span.shrink_to_hi(),
+                &format!(
+                    "consider borrowing the `{}`'s content",
+                    if is_option { "Option" } else { "Result" }
+                ),
+                ".as_ref()".to_string(),
+                Applicability::MaybeIncorrect,
+            );
+        } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_))) {
+            let suggest = match self.infcx.tcx.get_diagnostic_item(sym::IntoIterator) {
+                Some(def_id) => type_known_to_meet_bound_modulo_regions(
+                    &self.infcx,
+                    self.param_env,
+                    self.infcx.tcx.mk_imm_ref(self.infcx.tcx.lifetimes.re_erased, ty),
+                    def_id,
+                    DUMMY_SP,
+                ),
+                _ => false,
             };
-            let is_option = self.infcx.tcx.is_diagnostic_item(sym::option_type, def_id);
-            let is_result = self.infcx.tcx.is_diagnostic_item(sym::result_type, def_id);
-            if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
-                err.span_suggestion(
-                    span,
-                    &format!(
-                        "consider borrowing the `{}`'s content",
-                        if is_option { "Option" } else { "Result" }
-                    ),
-                    format!("{}.as_ref()", snippet),
-                    Applicability::MaybeIncorrect,
-                );
-            } else if matches!(span.desugaring_kind(), Some(DesugaringKind::ForLoop(_)))
-                && self.infcx.tcx.is_diagnostic_item(sym::vec_type, def_id)
-            {
-                // FIXME: suggest for anything that implements `IntoIterator`.
-                err.span_suggestion(
-                    span,
-                    "consider iterating over a slice of the `Vec<_>`'s content",
-                    format!("&{}", snippet),
+            if suggest {
+                err.span_suggestion_verbose(
+                    span.shrink_to_lo(),
+                    &format!("consider iterating over a slice of the `{}`'s content", ty),
+                    "&".to_string(),
                     Applicability::MaybeIncorrect,
                 );
             }
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 98befe4066b..1e65cc27154 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -505,7 +505,8 @@ impl<'a> StringReader<'a> {
     // identifier tokens.
     fn report_unknown_prefix(&self, start: BytePos) {
         let prefix_span = self.mk_sp(start, self.pos);
-        let msg = format!("prefix `{}` is unknown", self.str_from_to(start, self.pos));
+        let prefix_str = self.str_from_to(start, self.pos);
+        let msg = format!("prefix `{}` is unknown", prefix_str);
 
         let expn_data = prefix_span.ctxt().outer_expn_data();
 
@@ -513,12 +514,19 @@ impl<'a> StringReader<'a> {
             // In Rust 2021, this is a hard error.
             let mut err = self.sess.span_diagnostic.struct_span_err(prefix_span, &msg);
             err.span_label(prefix_span, "unknown prefix");
-            if expn_data.is_root() {
+            if prefix_str == "rb" {
+                err.span_suggestion_verbose(
+                    prefix_span,
+                    "use `br` for a raw byte string",
+                    "br".to_string(),
+                    Applicability::MaybeIncorrect,
+                );
+            } else if expn_data.is_root() {
                 err.span_suggestion_verbose(
                     prefix_span.shrink_to_hi(),
                     "consider inserting whitespace here",
                     " ".into(),
-                    Applicability::MachineApplicable,
+                    Applicability::MaybeIncorrect,
                 );
             }
             err.note("prefixed identifiers and literals are reserved since Rust 2021");
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index a580f0c55d0..1c5be61130b 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -253,6 +253,12 @@ pub(crate) fn emit_unescape_error(
             let msg = "invalid trailing slash in literal";
             handler.struct_span_err(span, msg).span_label(span, msg).emit();
         }
+        EscapeError::UnskippedWhitespaceWarning => {
+            let (c, char_span) = last_char();
+            let msg =
+                format!("non-ASCII whitespace symbol '{}' is not skipped", c.escape_unicode());
+            handler.struct_span_warn(span, &msg).span_label(char_span, &msg).emit();
+        }
     }
 }
 
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 9818bd8d314..273fbea3580 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1770,7 +1770,7 @@ impl<'a> Parser<'a> {
         let mut err = self.struct_span_err(span, &msg);
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp, None);
+            self.sess.expr_parentheses_needed(&mut err, *sp);
         }
         err.span_label(span, "expected expression");
         err
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ef05f64da94..b774c76103f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
             &format!("expected expression, found `{}`", pprust::token_to_string(&self.token),),
         );
         err.span_label(self.token.span, "expected expression");
-        self.sess.expr_parentheses_needed(&mut err, lhs.span, Some(pprust::expr_to_string(&lhs)));
+        self.sess.expr_parentheses_needed(&mut err, lhs.span);
         err.emit();
     }
 
@@ -696,20 +696,18 @@ impl<'a> Parser<'a> {
                         let expr =
                             mk_expr(self, lhs, self.mk_ty(path.span, TyKind::Path(None, path)));
 
-                        let expr_str = self
-                            .span_to_snippet(expr.span)
-                            .unwrap_or_else(|_| pprust::expr_to_string(&expr));
-
                         self.struct_span_err(self.token.span, &msg)
                             .span_label(
                                 self.look_ahead(1, |t| t.span).to(span_after_type),
                                 "interpreted as generic arguments",
                             )
                             .span_label(self.token.span, format!("not interpreted as {}", op_noun))
-                            .span_suggestion(
-                                expr.span,
+                            .multipart_suggestion(
                                 &format!("try {} the cast value", op_verb),
-                                format!("({})", expr_str),
+                                vec![
+                                    (expr.span.shrink_to_lo(), "(".to_string()),
+                                    (expr.span.shrink_to_hi(), ")".to_string()),
+                                ],
                                 Applicability::MachineApplicable,
                             )
                             .emit();
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 7219e39ea6b..b03b5459981 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -763,7 +763,7 @@ impl<'a> Parser<'a> {
 
         let sp = self.sess.source_map().start_point(self.token.span);
         if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
-            self.sess.expr_parentheses_needed(&mut err, *sp, None);
+            self.sess.expr_parentheses_needed(&mut err, *sp);
         }
 
         Err(err)
diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs
index 4f8dc7d16d4..34302c3fb42 100644
--- a/compiler/rustc_save_analysis/src/dump_visitor.rs
+++ b/compiler/rustc_save_analysis/src/dump_visitor.rs
@@ -689,6 +689,7 @@ impl<'tcx> DumpVisitor<'tcx> {
                     (Some(self.tcx.require_lang_item(lang_item, Some(span))), span)
                 }
                 hir::GenericBound::Outlives(..) => continue,
+                hir::GenericBound::Unsized(_) => continue,
             };
 
             if let Some(id) = def_id {
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 226fde2343a..a007b530302 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -228,20 +228,12 @@ impl ParseSess {
 
     /// Extend an error with a suggestion to wrap an expression with parentheses to allow the
     /// parser to continue parsing the following operation as part of the same expression.
-    pub fn expr_parentheses_needed(
-        &self,
-        err: &mut DiagnosticBuilder<'_>,
-        span: Span,
-        alt_snippet: Option<String>,
-    ) {
-        if let Some(snippet) = self.source_map().span_to_snippet(span).ok().or(alt_snippet) {
-            err.span_suggestion(
-                span,
-                "parentheses are required to parse this as an expression",
-                format!("({})", snippet),
-                Applicability::MachineApplicable,
-            );
-        }
+    pub fn expr_parentheses_needed(&self, err: &mut DiagnosticBuilder<'_>, span: Span) {
+        err.multipart_suggestion(
+            "parentheses are required to parse this as an expression",
+            vec![(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_hi(), ")".to_string())],
+            Applicability::MachineApplicable,
+        );
     }
 
     pub fn save_proc_macro_span(&self, span: Span) -> usize {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 295e53aba35..1ac489f600a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1270,6 +1270,7 @@ symbols! {
         trace_macros,
         track_caller,
         trait_alias,
+        trait_upcasting,
         transmute,
         transparent,
         transparent_enums,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 9a33875d6e4..712fea84a8b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1163,15 +1163,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             if is_object_safe {
                 // Suggest `-> Box<dyn Trait>` and `Box::new(returned_value)`.
                 // Get all the return values and collect their span and suggestion.
-                if let Some(mut suggestions) = visitor
+                let mut suggestions: Vec<_> = visitor
                     .returns
                     .iter()
-                    .map(|expr| {
-                        let snip = sm.span_to_snippet(expr.span).ok()?;
-                        Some((expr.span, format!("Box::new({})", snip)))
+                    .flat_map(|expr| {
+                        vec![
+                            (expr.span.shrink_to_lo(), "Box::new(".to_string()),
+                            (expr.span.shrink_to_hi(), ")".to_string()),
+                        ]
+                        .into_iter()
                     })
-                    .collect::<Option<Vec<_>>>()
-                {
+                    .collect();
+                if !suggestions.is_empty() {
                     // Add the suggestion for the return type.
                     suggestions.push((ret_ty.span, format!("Box<dyn {}>", trait_obj)));
                     err.multipart_suggestion(
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 752f6a8debc..c7bf1f2a943 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -693,22 +693,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let may_apply = match (source.kind(), target.kind()) {
             // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
             (&ty::Dynamic(ref data_a, ..), &ty::Dynamic(ref data_b, ..)) => {
-                // Upcasts permit two things:
-                //
-                // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
-                // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
-                //
-                // Note that neither of these changes requires any
-                // change at runtime. Eventually this will be
-                // generalized.
-                //
-                // We always upcast when we can because of reason
-                // #2 (region bounds).
-                data_a.principal_def_id() == data_b.principal_def_id()
-                    && data_b
-                        .auto_traits()
-                        // All of a's auto traits need to be in b's auto traits.
-                        .all(|b| data_a.auto_traits().any(|a| a == b))
+                // See `confirm_builtin_unsize_candidate` for more info.
+                let auto_traits_compatible = data_b
+                    .auto_traits()
+                    // All of a's auto traits need to be in b's auto traits.
+                    .all(|b| data_a.auto_traits().any(|a| a == b));
+                auto_traits_compatible
             }
 
             // `T` -> `Trait`
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index f8297ee3a07..0c2099593a2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -703,10 +703,56 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         match (source.kind(), target.kind()) {
             // Trait+Kx+'a -> Trait+Ky+'b (upcasts).
             (&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
-                // See `assemble_candidates_for_unsizing` for more info.
-                let iter = data_a
-                    .principal()
-                    .map(|b| b.map_bound(ty::ExistentialPredicate::Trait))
+                // Upcast coercions permit several things:
+                //
+                // 1. Dropping auto traits, e.g., `Foo + Send` to `Foo`
+                // 2. Tightening the region bound, e.g., `Foo + 'a` to `Foo + 'b` if `'a: 'b`
+                // 3. Tightening trait to its super traits, eg. `Foo` to `Bar` if `Foo: Bar`
+                //
+                // Note that neither of the first two of these changes requires any
+                // change at runtime. The third needs to change pointer metadata at runtime.
+                //
+                // We always perform upcasting coercions when we can because of reason
+                // #2 (region bounds).
+
+                // We already checked the compatiblity of auto traits within `assemble_candidates_for_unsizing`.
+
+                let principal_a = data_a.principal();
+                let principal_def_id_b = data_b.principal_def_id();
+
+                let existential_predicate = if let Some(principal_a) = principal_a {
+                    let source_trait_ref = principal_a.with_self_ty(tcx, source);
+                    let target_trait_did = principal_def_id_b.ok_or_else(|| Unimplemented)?;
+                    let upcast_idx = util::supertraits(tcx, source_trait_ref)
+                        .position(|upcast_trait_ref| upcast_trait_ref.def_id() == target_trait_did)
+                        .ok_or_else(|| Unimplemented)?;
+                    // FIXME(crlf0710): This is less than ideal, for example,
+                    // if the trait is defined as `trait Foo: Bar<u32> + Bar<i32>`,
+                    // the coercion from Box<Foo> to Box<dyn Bar<_>> is actually ambiguous.
+                    // We currently make this coercion fail for now.
+                    //
+                    // see #65991 for more information.
+                    if util::supertraits(tcx, source_trait_ref)
+                        .skip(upcast_idx + 1)
+                        .any(|upcast_trait_ref| upcast_trait_ref.def_id() == target_trait_did)
+                    {
+                        return Err(Unimplemented);
+                    }
+                    let target_trait_ref =
+                        util::supertraits(tcx, source_trait_ref).nth(upcast_idx).unwrap();
+                    let existential_predicate = target_trait_ref.map_bound(|trait_ref| {
+                        ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef::erase_self_ty(
+                            tcx, trait_ref,
+                        ))
+                    });
+                    Some(existential_predicate)
+                } else if principal_def_id_b.is_none() {
+                    None
+                } else {
+                    return Err(Unimplemented);
+                };
+
+                let iter = existential_predicate
                     .into_iter()
                     .chain(
                         data_a
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 9871b14754e..92583f2b0ea 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -943,7 +943,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         false,
                     );
                 }
-                hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {}
+                hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe)
+                | hir::GenericBound::Unsized(_) => {}
                 hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
                     .instantiate_lang_item_trait_ref(
                         lang_item, span, hir_id, args, param_ty, bounds,
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index ba76b9c8dd5..a83b39a1108 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -576,6 +576,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         )];
 
         let mut has_unsized_tuple_coercion = false;
+        let mut has_trait_upcasting_coercion = false;
 
         // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
         // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
@@ -590,7 +591,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     if traits.contains(&trait_pred.def_id()) =>
                 {
                     if unsize_did == trait_pred.def_id() {
+                        let self_ty = trait_pred.self_ty();
                         let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
+                        if let (ty::Dynamic(ref data_a, ..), ty::Dynamic(ref data_b, ..)) =
+                            (self_ty.kind(), unsize_ty.kind())
+                        {
+                            if data_a.principal_def_id() != data_b.principal_def_id() {
+                                debug!("coerce_unsized: found trait upcasting coercion");
+                                has_trait_upcasting_coercion = true;
+                            }
+                        }
                         if let ty::Tuple(..) = unsize_ty.kind() {
                             debug!("coerce_unsized: found unsized tuple coercion");
                             has_unsized_tuple_coercion = true;
@@ -666,6 +676,16 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             .emit();
         }
 
+        if has_trait_upcasting_coercion && !self.tcx().features().trait_upcasting {
+            feature_err(
+                &self.tcx.sess.parse_sess,
+                sym::trait_upcasting,
+                self.cause.span,
+                "trait upcasting coercion is experimental",
+            )
+            .emit();
+        }
+
         Ok(coercion)
     }
 
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 3ea59906d3d..e5a00f70639 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -13,7 +13,7 @@ use rustc_middle::ty::adjustment::AllowTwoPhase;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, AssocItem, Ty, TypeAndMut};
 use rustc_span::symbol::sym;
-use rustc_span::Span;
+use rustc_span::{BytePos, Span};
 
 use super::method::probe;
 
@@ -415,7 +415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
         expected: Ty<'tcx>,
-    ) -> Option<(Span, &'static str, String, Applicability)> {
+    ) -> Option<(Span, &'static str, String, Applicability, bool /* verbose */)> {
         let sess = self.sess();
         let sp = expr.span;
 
@@ -441,12 +441,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(src) = replace_prefix(&src, "b\"", "\"") {
+                            if let Some(_) = replace_prefix(&src, "b\"", "\"") {
+                                let pos = sp.lo() + BytePos(1);
                                 return Some((
-                                    sp,
+                                    sp.with_hi(pos),
                                     "consider removing the leading `b`",
-                                    src,
+                                    String::new(),
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
@@ -455,12 +457,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
                     if let hir::ExprKind::Lit(_) = expr.kind {
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            if let Some(src) = replace_prefix(&src, "\"", "b\"") {
+                            if let Some(_) = replace_prefix(&src, "\"", "b\"") {
                                 return Some((
-                                    sp,
+                                    sp.shrink_to_lo(),
                                     "consider adding a leading `b`",
-                                    src,
+                                    "b".to_string(),
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
@@ -520,6 +523,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 sugg.1,
                                 sugg.2,
                                 Applicability::MachineApplicable,
+                                false,
                             ));
                         }
                         let field_name = if is_struct_pat_shorthand_field {
@@ -539,13 +543,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 //                                   |     |
                                 //    consider dereferencing here: `*opt`  |
                                 // expected mutable reference, found enum `Option`
-                                if let Ok(src) = sm.span_to_snippet(left_expr.span) {
+                                if sm.span_to_snippet(left_expr.span).is_ok() {
                                     return Some((
-                                        left_expr.span,
+                                        left_expr.span.shrink_to_lo(),
                                         "consider dereferencing here to assign to the mutable \
                                          borrowed piece of memory",
-                                        format!("*{}", src),
+                                        "*".to_string(),
                                         Applicability::MachineApplicable,
+                                        true,
                                     ));
                                 }
                             }
@@ -557,12 +562,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 "consider mutably borrowing here",
                                 format!("{}&mut {}", field_name, sugg_expr),
                                 Applicability::MachineApplicable,
+                                false,
                             ),
                             hir::Mutability::Not => (
                                 sp,
                                 "consider borrowing here",
                                 format!("{}&{}", field_name, sugg_expr),
                                 Applicability::MachineApplicable,
+                                false,
                             ),
                         });
                     }
@@ -584,24 +591,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if let Some(call_span) =
                         iter::successors(Some(expr.span), |s| s.parent()).find(|&s| sp.contains(s))
                     {
-                        if let Ok(code) = sm.span_to_snippet(call_span) {
+                        if sm.span_to_snippet(call_span).is_ok() {
                             return Some((
-                                sp,
+                                sp.with_hi(call_span.lo()),
                                 "consider removing the borrow",
-                                code,
+                                String::new(),
                                 Applicability::MachineApplicable,
+                                true,
                             ));
                         }
                     }
                     return None;
                 }
                 if sp.contains(expr.span) {
-                    if let Ok(code) = sm.span_to_snippet(expr.span) {
+                    if sm.span_to_snippet(expr.span).is_ok() {
                         return Some((
-                            sp,
+                            sp.with_hi(expr.span.lo()),
                             "consider removing the borrow",
-                            code,
+                            String::new(),
                             Applicability::MachineApplicable,
+                            true,
                         ));
                     }
                 }
@@ -616,36 +625,59 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if steps > 0 {
                         // The pointer type implements `Copy` trait so the suggestion is always valid.
                         if let Ok(src) = sm.span_to_snippet(sp) {
-                            let derefs = &"*".repeat(steps);
-                            if let Some((src, applicability)) = match mutbl_b {
+                            let derefs = "*".repeat(steps);
+                            if let Some((span, src, applicability)) = match mutbl_b {
                                 hir::Mutability::Mut => {
-                                    let new_prefix = "&mut ".to_owned() + derefs;
+                                    let new_prefix = "&mut ".to_owned() + &derefs;
                                     match mutbl_a {
                                         hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(5);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                         hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix)
-                                                .map(|s| (s, Applicability::Unspecified))
+                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(1);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (
+                                                    sp,
+                                                    format!("mut {}", derefs),
+                                                    Applicability::Unspecified,
+                                                )
+                                            })
                                         }
                                     }
                                 }
                                 hir::Mutability::Not => {
-                                    let new_prefix = "&".to_owned() + derefs;
+                                    let new_prefix = "&".to_owned() + &derefs;
                                     match mutbl_a {
                                         hir::Mutability::Mut => {
-                                            replace_prefix(&src, "&mut ", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
+                                                let lo = sp.lo() + BytePos(1);
+                                                let hi = sp.lo() + BytePos(5);
+                                                let sp = sp.with_lo(lo).with_hi(hi);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                         hir::Mutability::Not => {
-                                            replace_prefix(&src, "&", &new_prefix)
-                                                .map(|s| (s, Applicability::MachineApplicable))
+                                            replace_prefix(&src, "&", &new_prefix).map(|_| {
+                                                let pos = sp.lo() + BytePos(1);
+                                                let sp = sp.with_lo(pos).with_hi(pos);
+                                                (sp, derefs, Applicability::MachineApplicable)
+                                            })
                                         }
                                     }
                                 }
                             } {
-                                return Some((sp, "consider dereferencing", src, applicability));
+                                return Some((
+                                    span,
+                                    "consider dereferencing",
+                                    src,
+                                    applicability,
+                                    true,
+                                ));
                             }
                         }
                     }
@@ -669,6 +701,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 message,
                                 suggestion,
                                 Applicability::MachineApplicable,
+                                false,
                             ));
                         } else if self.infcx.type_is_copy_modulo_regions(
                             self.param_env,
@@ -682,21 +715,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 } else {
                                     "consider dereferencing the type"
                                 };
-                                let suggestion = if is_struct_pat_shorthand_field {
-                                    format!("{}: *{}", code, code)
+                                let (span, suggestion) = if is_struct_pat_shorthand_field {
+                                    (expr.span, format!("{}: *{}", code, code))
                                 } else if self.is_else_if_block(expr) {
                                     // Don't suggest nonsense like `else *if`
                                     return None;
                                 } else if let Some(expr) = self.maybe_get_block_expr(expr.hir_id) {
-                                    format!("*{}", sm.span_to_snippet(expr.span).unwrap_or(code))
+                                    (expr.span.shrink_to_lo(), "*".to_string())
                                 } else {
-                                    format!("*{}", code)
+                                    (expr.span.shrink_to_lo(), "*".to_string())
                                 };
                                 return Some((
-                                    expr.span,
+                                    span,
                                     message,
                                     suggestion,
                                     Applicability::MachineApplicable,
+                                    true,
                                 ));
                             }
                         }
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index cfe1d1c6871..08258aac96f 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -344,7 +344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let Some(sp) =
                             tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
                         {
-                            tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp, None);
+                            tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
                         }
                         err.emit();
                         oprnd_t = tcx.ty_error();
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
index 54aab271fdb..0acf1d26e25 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs
@@ -213,8 +213,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>,
     ) {
         let expr = expr.peel_blocks();
-        if let Some((sp, msg, suggestion, applicability)) = self.check_ref(expr, found, expected) {
-            err.span_suggestion(sp, msg, suggestion, applicability);
+        if let Some((sp, msg, suggestion, applicability, verbose)) =
+            self.check_ref(expr, found, expected)
+        {
+            if verbose {
+                err.span_suggestion_verbose(sp, msg, suggestion, applicability);
+            } else {
+                err.span_suggestion(sp, msg, suggestion, applicability);
+            }
         } else if let (ty::FnDef(def_id, ..), true) =
             (&found.kind(), self.suggest_fn_call(err, expr, expected, found))
         {
@@ -234,29 +240,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             None // do not suggest code that is already there (#53348)
                         } else {
                             let method_call_list = [".to_vec()", ".to_string()"];
-                            let sugg = if receiver.ends_with(".clone()")
+                            let mut sugg = if receiver.ends_with(".clone()")
                                 && method_call_list.contains(&method_call.as_str())
                             {
                                 let max_len = receiver.rfind('.').unwrap();
-                                format!("{}{}", &receiver[..max_len], method_call)
+                                vec![(
+                                    expr.span,
+                                    format!("{}{}", &receiver[..max_len], method_call),
+                                )]
                             } else {
                                 if expr.precedence().order() < ExprPrecedence::MethodCall.order() {
-                                    format!("({}){}", receiver, method_call)
+                                    vec![
+                                        (expr.span.shrink_to_lo(), "(".to_string()),
+                                        (expr.span.shrink_to_hi(), format!("){}", method_call)),
+                                    ]
                                 } else {
-                                    format!("{}{}", receiver, method_call)
+                                    vec![(expr.span.shrink_to_hi(), method_call)]
                                 }
                             };
-                            Some(if is_struct_pat_shorthand_field {
-                                format!("{}: {}", receiver, sugg)
-                            } else {
-                                sugg
-                            })
+                            if is_struct_pat_shorthand_field {
+                                sugg.insert(
+                                    0,
+                                    (expr.span.shrink_to_lo(), format!("{}: ", receiver)),
+                                );
+                            }
+                            Some(sugg)
                         }
                     })
                     .peekable();
                 if suggestions.peek().is_some() {
-                    err.span_suggestions(
-                        expr.span,
+                    err.multipart_suggestions(
                         "try using a conversion method",
                         suggestions,
                         Applicability::MaybeIncorrect,
@@ -283,14 +296,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         }
         let boxed_found = self.tcx.mk_box(found);
-        if let (true, Ok(snippet)) = (
-            self.can_coerce(boxed_found, expected),
-            self.sess().source_map().span_to_snippet(expr.span),
-        ) {
-            err.span_suggestion(
-                expr.span,
+        if self.can_coerce(boxed_found, expected) {
+            err.multipart_suggestion(
                 "store this in the heap by calling `Box::new`",
-                format!("Box::new({})", snippet),
+                vec![
+                    (expr.span.shrink_to_lo(), "Box::new(".to_string()),
+                    (expr.span.shrink_to_hi(), ")".to_string()),
+                ],
                 Applicability::MachineApplicable,
             );
             err.note(
@@ -357,19 +369,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
         let boxed_found = self.tcx.mk_box(found);
         let new_found = self.tcx.mk_lang_item(boxed_found, LangItem::Pin).unwrap();
-        if let (true, Ok(snippet)) = (
-            self.can_coerce(new_found, expected),
-            self.sess().source_map().span_to_snippet(expr.span),
-        ) {
+        if self.can_coerce(new_found, expected) {
             match found.kind() {
                 ty::Adt(def, _) if def.is_box() => {
                     err.help("use `Box::pin`");
                 }
                 _ => {
-                    err.span_suggestion(
-                        expr.span,
+                    err.multipart_suggestion(
                         "you need to pin and box this expression",
-                        format!("Box::pin({})", snippet),
+                        vec![
+                            (expr.span.shrink_to_lo(), "Box::pin(".to_string()),
+                            (expr.span.shrink_to_hi(), ")".to_string()),
+                        ],
                         Applicability::MachineApplicable,
                     );
                 }
@@ -547,7 +558,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let sp = self.tcx.sess.source_map().start_point(expr.span);
         if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
             // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
-            self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp, None);
+            self.tcx.sess.parse_sess.expr_parentheses_needed(err, *sp);
         }
     }
 
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index f13e23914f7..6eb8af98640 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -5,7 +5,7 @@ use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{Ref, Ty};
+use rustc_middle::ty::{Adt, Ref, Ty};
 use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
 use rustc_span::symbol::kw::Underscore;
 use rustc_span::symbol::{sym, Ident};
@@ -255,16 +255,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 method_name.name
             ));
 
-            let self_ty = self
+            let self_ty_name = self
                 .sess()
                 .source_map()
                 .span_to_snippet(self_ty_span)
                 .unwrap_or_else(|_| self_ty.to_string());
 
+            let self_ty_generics_count = match self_ty.kind() {
+                // Get the number of generics the self type has (if an Adt) unless we can determine that
+                // the user has written the self type with generics already which we (naively) do by looking
+                // for a "<" in `self_ty_name`.
+                Adt(def, _) if !self_ty_name.contains("<") => self.tcx.generics_of(def.did).count(),
+                _ => 0,
+            };
+            let self_ty_generics = if self_ty_generics_count > 0 {
+                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
+            } else {
+                String::new()
+            };
             lint.span_suggestion(
                 span,
                 "disambiguate the associated function",
-                format!("<{} as {}>::{}", self_ty, trait_name, method_name.name,),
+                format!(
+                    "<{}{} as {}>::{}",
+                    self_ty_name, self_ty_generics, trait_name, method_name.name,
+                ),
                 Applicability::MachineApplicable,
             );
 
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 997fdcefe03..ce74d6fec9e 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2230,7 +2230,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                             let constness = match modifier {
                                 hir::TraitBoundModifier::MaybeConst => hir::Constness::NotConst,
                                 hir::TraitBoundModifier::None => constness,
-                                hir::TraitBoundModifier::Maybe => bug!("this wasn't handled"),
+                                // We ignore `where T: ?Sized`, it is already part of
+                                // type parameter `T`.
+                                hir::TraitBoundModifier::Maybe => continue,
                             };
 
                             let mut bounds = Bounds::default();
@@ -2260,6 +2262,8 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                             predicates.extend(bounds.predicates(tcx, ty));
                         }
 
+                        hir::GenericBound::Unsized(_) => {}
+
                         hir::GenericBound::Outlives(lifetime) => {
                             let region =
                                 <dyn AstConv<'_>>::ast_region_to_region(&icx, lifetime, None);
@@ -2521,6 +2525,7 @@ fn predicates_from_bound<'tcx>(
             );
             bounds.predicates(astconv.tcx(), param_ty)
         }
+        hir::GenericBound::Unsized(_) => vec![],
         hir::GenericBound::Outlives(ref lifetime) => {
             let region = astconv.ast_region_to_region(lifetime, None);
             let pred = ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region))
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 06a7c335bf0..ba47da4821b 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1372,9 +1372,11 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert_eq!(v, [1, 3]);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[track_caller]
     pub fn remove(&mut self, index: usize) -> T {
         #[cold]
         #[inline(never)]
+        #[track_caller]
         fn assert_failed(index: usize, len: usize) -> ! {
             panic!("removal index (is {}) should be < len (is {})", index, len);
         }
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 78b799cd709..3bc9f71375c 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -293,6 +293,28 @@ impl<T, const N: usize> [T; N] {
     /// Returns an array of the same size as `self`, with function `f` applied to each element
     /// in order.
     ///
+    /// If you don't necessarily need a new fixed-size array, consider using
+    /// [`Iterator::map`] instead.
+    ///
+    ///
+    /// # Note on performance and stack usage
+    ///
+    /// Unfortunately, usages of this method are currently not always optimized
+    /// as well as they could be. This mainly concerns large arrays, as mapping
+    /// over small arrays seem to be optimized just fine. Also note that in
+    /// debug mode (i.e. without any optimizations), this method can use a lot
+    /// of stack space (a few times the size of the array or more).
+    ///
+    /// Therefore, in performance-critical code, try to avoid using this method
+    /// on large arrays or check the emitted code. Also try to avoid chained
+    /// maps (e.g. `arr.map(...).map(...)`).
+    ///
+    /// In many cases, you can instead use [`Iterator::map`] by calling `.iter()`
+    /// or `.into_iter()` on your array. `[T; N]::map` is only necessary if you
+    /// really need a new array of the same size as the result. Rust's lazy
+    /// iterators tend to get optimized very well.
+    ///
+    ///
     /// # Examples
     ///
     /// ```
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 3ab40f1faa1..032df7f5a80 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -71,6 +71,16 @@ impl<T: Sized> NonNull<T> {
     /// a `T`, which means this must not be used as a "not yet initialized"
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let ptr = NonNull::<u32>::dangling();
+    /// // Important: don't try to access the value of `ptr` without
+    /// // initializing it first! The pointer is not null but isn't valid either!
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_dangling", since = "1.36.0")]
     #[inline]
@@ -155,6 +165,18 @@ impl<T: ?Sized> NonNull<T> {
     /// # Safety
     ///
     /// `ptr` must be non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = unsafe { NonNull::new_unchecked(&mut x as *mut _) };
+    ///
+    /// // NEVER DO THAT!!!
+    /// let ptr = unsafe { NonNull::<u32>::new_unchecked(std::ptr::null_mut()) };
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")]
     #[inline]
@@ -164,6 +186,19 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Creates a new `NonNull` if `ptr` is non-null.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::<u32>::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// if let Some(ptr) = NonNull::<u32>::new(std::ptr::null_mut()) {
+    ///     unreachable!();
+    /// }
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
     pub fn new(ptr: *mut T) -> Option<Self> {
@@ -205,6 +240,22 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Acquires the underlying `*mut` pointer.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x).expect("ptr is null!");
+    ///
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 0);
+    ///
+    /// unsafe { *ptr.as_ptr() += 2; }
+    /// let x_value = unsafe { *ptr.as_ptr() };
+    /// assert_eq!(x_value, 2);
+    /// ```
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[rustc_const_stable(feature = "const_nonnull_as_ptr", since = "1.32.0")]
     #[inline]
@@ -239,6 +290,18 @@ impl<T: ?Sized> NonNull<T> {
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
     ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!");
+    ///
+    /// let ref_x = unsafe { ptr.as_ref() };
+    /// println!("{}", ref_x);
+    /// ```
+    ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
     #[inline]
@@ -274,6 +337,19 @@ impl<T: ?Sized> NonNull<T> {
     /// This applies even if the result of this method is unused!
     /// (The part about being initialized is not yet fully decided, but until
     /// it is, the only safe approach is to ensure that they are indeed initialized.)
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let mut ptr = NonNull::new(&mut x).expect("null pointer");
+    ///
+    /// let x_ref = unsafe { ptr.as_mut() };
+    /// assert_eq!(*x_ref, 0);
+    /// *x_ref += 2;
+    /// assert_eq!(*x_ref, 2);
+    /// ```
     ///
     /// [the module documentation]: crate::ptr#safety
     #[stable(feature = "nonnull", since = "1.25.0")]
@@ -285,6 +361,18 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Casts to a pointer of another type.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::ptr::NonNull;
+    ///
+    /// let mut x = 0u32;
+    /// let ptr = NonNull::new(&mut x as *mut _).expect("null pointer");
+    ///
+    /// let casted_ptr = ptr.cast::<i8>();
+    /// let raw_ptr: *mut i8 = casted_ptr.as_ptr();
+    /// ```
     #[stable(feature = "nonnull_cast", since = "1.27.0")]
     #[rustc_const_stable(feature = "const_nonnull_cast", since = "1.36.0")]
     #[inline]
diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs
index 457b2a3605e..791a88dd97f 100644
--- a/library/core/src/slice/iter/macros.rs
+++ b/library/core/src/slice/iter/macros.rs
@@ -185,6 +185,13 @@ macro_rules! iterator {
                 }
             }
 
+            fn advance_by(&mut self, n: usize) -> Result<(), usize> {
+                let advance = cmp::min(n, len!(self));
+                // SAFETY: By construction, `advance` does not exceed `self.len()`.
+                unsafe { self.post_inc_start(advance as isize) };
+                if advance == n { Ok(()) } else { Err(advance) }
+            }
+
             #[inline]
             fn last(mut self) -> Option<$elem> {
                 self.next_back()
@@ -371,6 +378,14 @@ macro_rules! iterator {
                     Some(next_back_unchecked!(self))
                 }
             }
+
+            #[inline]
+            fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
+                let advance = cmp::min(n, len!(self));
+                // SAFETY: By construction, `advance` does not exceed `self.len()`.
+                unsafe { self.pre_dec_end(advance as isize) };
+                if advance == n { Ok(()) } else { Err(advance) }
+            }
         }
 
         #[stable(feature = "fused", since = "1.26.0")]
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index 3a98cd9d2ee..240b894057c 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -135,6 +135,48 @@ fn test_partition_point() {
 }
 
 #[test]
+fn test_iterator_advance_by() {
+    let v = &[0, 1, 2, 3, 4];
+
+    for i in 0..=v.len() {
+        let mut iter = v.iter();
+        iter.advance_by(i).unwrap();
+        assert_eq!(iter.as_slice(), &v[i..]);
+    }
+
+    let mut iter = v.iter();
+    assert_eq!(iter.advance_by(v.len() + 1), Err(v.len()));
+    assert_eq!(iter.as_slice(), &[]);
+
+    let mut iter = v.iter();
+    iter.advance_by(3).unwrap();
+    assert_eq!(iter.as_slice(), &v[3..]);
+    iter.advance_by(2).unwrap();
+    assert_eq!(iter.as_slice(), &[]);
+}
+
+#[test]
+fn test_iterator_advance_back_by() {
+    let v = &[0, 1, 2, 3, 4];
+
+    for i in 0..=v.len() {
+        let mut iter = v.iter();
+        iter.advance_back_by(i).unwrap();
+        assert_eq!(iter.as_slice(), &v[..v.len() - i]);
+    }
+
+    let mut iter = v.iter();
+    assert_eq!(iter.advance_back_by(v.len() + 1), Err(v.len()));
+    assert_eq!(iter.as_slice(), &[]);
+
+    let mut iter = v.iter();
+    iter.advance_back_by(3).unwrap();
+    assert_eq!(iter.as_slice(), &v[..v.len() - 3]);
+    iter.advance_back_by(2).unwrap();
+    assert_eq!(iter.as_slice(), &[]);
+}
+
+#[test]
 fn test_iterator_nth() {
     let v: &[_] = &[0, 1, 2, 3, 4];
     for i in 0..v.len() {
diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs
index 7afe52a3fd6..676695795ba 100644
--- a/library/std/src/macros.rs
+++ b/library/std/src/macros.rs
@@ -290,7 +290,7 @@ macro_rules! dbg {
     // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!`
     // will be malformed.
     () => {
-        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!());
+        $crate::eprintln!("[{}:{}]", $crate::file!(), $crate::line!())
     };
     ($val:expr $(,)?) => {
         // Use of `match` here is intentional because it affects the lifetimes
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 128897e580b..59a1d06dabd 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -451,7 +451,7 @@ jobs:
           - name: dist-x86_64-apple
             env:
               SCRIPT: ./x.py dist
-              RUST_CONFIGURE_ARGS: --host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false
+              RUST_CONFIGURE_ARGS: --host=x86_64-apple-darwin --target=x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
               MACOSX_DEPLOYMENT_TARGET: 10.7
               NO_LLVM_ASSERTIONS: 1
diff --git a/src/doc/rustdoc/src/command-line-arguments.md b/src/doc/rustdoc/src/command-line-arguments.md
index c8af369a969..d6948622662 100644
--- a/src/doc/rustdoc/src/command-line-arguments.md
+++ b/src/doc/rustdoc/src/command-line-arguments.md
@@ -94,7 +94,7 @@ $ rustdoc src/lib.rs --document-private-items
 By default, `rustdoc` only documents items that are publicly reachable.
 
 ```rust
-pub fn public() {} // this item is public and will documented
+pub fn public() {} // this item is public and will be documented
 mod private { // this item is private and will not be documented
     pub fn unreachable() {} // this item is public, but unreachable, so it will not be documented
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index fd79292477c..75ea30bb565 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -128,6 +128,7 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
         match *self {
             hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
+            hir::GenericBound::Unsized(_) => GenericBound::maybe_sized(cx),
             hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
                 let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
 
@@ -562,13 +563,19 @@ impl Clean<Generics> for hir::Generics<'_> {
                 WherePredicate::BoundPredicate {
                     ty: Generic(ref name), ref mut bounds, ..
                 } => {
-                    if bounds.is_empty() {
+                    if let [] | [GenericBound::TraitBound(_, hir::TraitBoundModifier::Maybe)] =
+                        &bounds[..]
+                    {
                         for param in &mut generics.params {
                             match param.kind {
                                 GenericParamDefKind::Lifetime => {}
                                 GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
                                     if &param.name == name {
                                         mem::swap(bounds, ty_bounds);
+                                        // We now keep track of `?Sized` obligations in the HIR.
+                                        // If we don't clear `ty_bounds` we end up with
+                                        // `fn foo<X: ?Sized>(_: X) where X: ?Sized`.
+                                        ty_bounds.clear();
                                         break;
                                     }
                                 }
diff --git a/src/llvm-project b/src/llvm-project
-Subproject bdb386270f55cb8e95793daa296f27a95a6d483
+Subproject 260e0f8682098faab68af9c608534756ad37836
diff --git a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
index 599d0e13557..d0c91c4ab44 100644
--- a/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
+++ b/src/test/ui/async-await/async-borrowck-escaping-block-error.stderr
@@ -15,7 +15,7 @@ LL | fn test_boxed() -> Box<impl std::future::Future<Output = u32>> {
 help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new(async move { x } )
-   |                    ^^^^^^^^^^
+   |                    ^^^^
 
 error[E0373]: async block may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/async-borrowck-escaping-block-error.rs:11:11
@@ -34,7 +34,7 @@ LL |     async { *x }
 help: to force the async block to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     async move { *x }
-   |           ^^^^^^^^^^^
+   |           ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
index 8bcfcf98920..1bcaaf0d6b3 100644
--- a/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
+++ b/src/test/ui/async-await/async-borrowck-escaping-closure-error.stderr
@@ -14,7 +14,7 @@ LL |     Box::new((async || x)())
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new((async move || x)())
-   |               ^^^^^^^^^^^^^
+   |                     ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/issues/issue-62097.nll.stderr b/src/test/ui/async-await/issues/issue-62097.nll.stderr
index ab10e5f1810..1139175f8a0 100644
--- a/src/test/ui/async-await/issues/issue-62097.nll.stderr
+++ b/src/test/ui/async-await/issues/issue-62097.nll.stderr
@@ -14,7 +14,7 @@ LL |         foo(|| self.bar()).await;
 help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
    |
 LL |         foo(move || self.bar()).await;
-   |             ^^^^^^^
+   |             ^^^^
 
 error[E0521]: borrowed data escapes outside of associated function
   --> $DIR/issue-62097.rs:13:9
diff --git a/src/test/ui/async-await/issues/issue-78938-async-block.stderr b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
index 01ffc48d654..22ebd86d85c 100644
--- a/src/test/ui/async-await/issues/issue-78938-async-block.stderr
+++ b/src/test/ui/async-await/issues/issue-78938-async-block.stderr
@@ -12,9 +12,7 @@ LL | |     });
 help: to force the async block to take ownership of `room_ref` (and any other referenced variables), use the `move` keyword
    |
 LL |     let gameloop_handle = spawn(async move {
-LL |         game_loop(Arc::clone(&room_ref))
-LL |     });
-   |
+   |                                       ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/block-result/issue-5500.stderr b/src/test/ui/block-result/issue-5500.stderr
index 9d9f7ac2e4a..ef3e2da81b2 100644
--- a/src/test/ui/block-result/issue-5500.stderr
+++ b/src/test/ui/block-result/issue-5500.stderr
@@ -4,13 +4,14 @@ error[E0308]: mismatched types
 LL | fn main() {
    |           - expected `()` because of default return type
 LL |     &panic!()
-   |     ^^^^^^^^^
-   |     |
-   |     expected `()`, found reference
-   |     help: consider removing the borrow: `panic!()`
+   |     ^^^^^^^^^ expected `()`, found reference
    |
    = note: expected unit type `()`
               found reference `&_`
+help: consider removing the borrow
+   |
+LL |     panic!()
+   |    --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
index 3195120cba2..161e4610d61 100644
--- a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
+++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.stderr
@@ -14,7 +14,7 @@ LL |     spawn(|| books.push(4));
 help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword
    |
 LL |     spawn(move || books.push(4));
-   |           ^^^^^^^
+   |           ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
index 3227aa9bb68..b07db6e12ad 100644
--- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
+++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.stderr
@@ -14,7 +14,7 @@ LL |     Box::new(|| books.push(4))
 help: to force the closure to take ownership of `books` (and any other referenced variables), use the `move` keyword
    |
 LL |     Box::new(move || books.push(4))
-   |              ^^^^^^^
+   |              ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
index 29bd4b27d6b..311a1b84e0c 100644
--- a/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
+++ b/src/test/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.stderr
@@ -15,7 +15,7 @@ LL | fn foo () -> impl FnMut()->() {
 help: to force the closure to take ownership of `p` (and any other referenced variables), use the `move` keyword
    |
 LL |     let mut c = move || {
-   |                 ^^^^^^^
+   |                 ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
index 1b0e0902d67..7823e357009 100644
--- a/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
+++ b/src/test/ui/closures/closure-bounds-static-cant-capture-borrowed.nll.stderr
@@ -27,7 +27,7 @@ LL | |     })
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |     bar(move || {
-   |         ^^^^^^^
+   |         ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/const-generics/const-argument-if-length.full.stderr b/src/test/ui/const-generics/const-argument-if-length.full.stderr
index c6088e665a2..a9f1d0eb657 100644
--- a/src/test/ui/const-generics/const-argument-if-length.full.stderr
+++ b/src/test/ui/const-generics/const-argument-if-length.full.stderr
@@ -10,6 +10,11 @@ LL |     if std::mem::size_of::<T>() == 0 {
    |
 LL | pub const fn size_of<T>() -> usize {
    |                      - required by this bound in `std::mem::size_of`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | pub const fn is_zst<T>() -> usize {
+   |                     --
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/const-argument-if-length.rs:16:12
@@ -21,6 +26,10 @@ LL |     value: T,
    |
    = note: only the last field of a struct may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | pub struct AtLeastByte<T> {
+   |                        --
 help: borrowed types always have a statically known size
    |
 LL |     value: &T,
diff --git a/src/test/ui/const-generics/const-argument-if-length.min.stderr b/src/test/ui/const-generics/const-argument-if-length.min.stderr
index bc06e8d7fb1..173a1471663 100644
--- a/src/test/ui/const-generics/const-argument-if-length.min.stderr
+++ b/src/test/ui/const-generics/const-argument-if-length.min.stderr
@@ -17,6 +17,10 @@ LL |     value: T,
    |
    = note: only the last field of a struct may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | pub struct AtLeastByte<T> {
+   |                        --
 help: borrowed types always have a statically known size
    |
 LL |     value: &T,
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
index 2551d68f974..fd8f8b2693a 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-3.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/unused-substs-3.rs:16:9
    |
 LL |     t = foo;
-   |         ^^^
+   |         ^^^- help: try using a conversion method: `.to_vec()`
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `foo.to_vec()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
index 239569dab09..be289f44f1b 100644
--- a/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
+++ b/src/test/ui/const-generics/occurs-check/unused-substs-5.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/unused-substs-5.rs:15:9
    |
 LL |     x = q::<_, N>(x);
-   |         ^^^^^^^^^^^^
+   |         ^^^^^^^^^^^^- help: try using a conversion method: `.to_vec()`
    |         |
    |         cyclic type of infinite size
-   |         help: try using a conversion method: `q::<_, N>(x).to_vec()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/deref-suggestion.stderr b/src/test/ui/deref-suggestion.stderr
index b3f7b042aac..8c004148a5d 100644
--- a/src/test/ui/deref-suggestion.stderr
+++ b/src/test/ui/deref-suggestion.stderr
@@ -2,37 +2,42 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:8:9
    |
 LL |     foo(s);
-   |         ^
+   |         ^- help: try using a conversion method: `.to_string()`
    |         |
    |         expected struct `String`, found `&String`
-   |         help: try using a conversion method: `s.to_string()`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:14:10
    |
 LL |     foo3(u);
+   |          ^ expected `u32`, found `&u32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     foo3(*u);
    |          ^
-   |          |
-   |          expected `u32`, found `&u32`
-   |          help: consider dereferencing the borrow: `*u`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:30:9
    |
 LL |     foo(&"aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^
-   |         |
-   |         expected struct `String`, found `&String`
-   |         help: consider removing the borrow: `"aaa".to_owned()`
+   |         ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |
+help: consider removing the borrow
+   |
+LL |     foo("aaa".to_owned());
+   |        --
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:32:9
    |
 LL |     foo(&mut "aaa".to_owned());
-   |         ^^^^^^^^^^^^^^^^^^^^^
-   |         |
-   |         expected struct `String`, found `&mut String`
-   |         help: consider removing the borrow: `"aaa".to_owned()`
+   |         ^^^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |
+help: consider removing the borrow
+   |
+LL |     foo("aaa".to_owned());
+   |        --
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:2:20
@@ -75,37 +80,45 @@ error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:44:17
    |
 LL |     let r = R { i };
-   |                 ^
-   |                 |
-   |                 expected `u32`, found `&{integer}`
-   |                 help: consider dereferencing the borrow: `i: *i`
+   |                 ^ expected `u32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let r = R { i: *i };
+   |                 ^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:46:20
    |
 LL |     let r = R { i: i };
+   |                    ^ expected `u32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let r = R { i: *i };
    |                    ^
-   |                    |
-   |                    expected `u32`, found `&{integer}`
-   |                    help: consider dereferencing the borrow: `*i`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:55:9
    |
 LL |         b
+   |         ^ expected `i32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
    |         ^
-   |         |
-   |         expected `i32`, found `&{integer}`
-   |         help: consider dereferencing the borrow: `*b`
 
 error[E0308]: mismatched types
   --> $DIR/deref-suggestion.rs:63:9
    |
 LL |         b
+   |         ^ expected `i32`, found `&{integer}`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
    |         ^
-   |         |
-   |         expected `i32`, found `&{integer}`
-   |         help: consider dereferencing the borrow: `*b`
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/deref-suggestion.rs:68:12
diff --git a/src/test/ui/diverging-tuple-parts-39485.stderr b/src/test/ui/diverging-tuple-parts-39485.stderr
index ad3e5ab3dc9..017b73a0d86 100644
--- a/src/test/ui/diverging-tuple-parts-39485.stderr
+++ b/src/test/ui/diverging-tuple-parts-39485.stderr
@@ -13,7 +13,7 @@ LL | fn g() -> &_ {
 help: consider removing the borrow
    |
 LL |     panic!()
-   |     ^^^^^^^^
+   |    --
 
 error[E0308]: mismatched types
   --> $DIR/diverging-tuple-parts-39485.rs:12:5
diff --git a/src/test/ui/dst/dst-object-from-unsized-type.stderr b/src/test/ui/dst/dst-object-from-unsized-type.stderr
index 2d12265df98..6c57dd9316f 100644
--- a/src/test/ui/dst/dst-object-from-unsized-type.stderr
+++ b/src/test/ui/dst/dst-object-from-unsized-type.stderr
@@ -7,6 +7,10 @@ LL |     let u: &dyn Foo = t;
    |                       ^ doesn't have a size known at compile-time
    |
    = note: required for the cast to the object type `dyn Foo`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn test1<T: Foo>(t: &T) {
+   |            --
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/dst-object-from-unsized-type.rs:13:23
@@ -17,6 +21,10 @@ LL |     let v: &dyn Foo = t as &dyn Foo;
    |                       ^ doesn't have a size known at compile-time
    |
    = note: required for the cast to the object type `dyn Foo`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn test2<T: Foo>(t: &T) {
+   |            --
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/dst-object-from-unsized-type.rs:18:28
diff --git a/src/test/ui/estr-subtyping.stderr b/src/test/ui/estr-subtyping.stderr
index 268ec63a80d..d929c32633a 100644
--- a/src/test/ui/estr-subtyping.stderr
+++ b/src/test/ui/estr-subtyping.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/estr-subtyping.rs:10:15
    |
 LL |    wants_uniq(x);
-   |               ^
+   |               ^- help: try using a conversion method: `.to_string()`
    |               |
    |               expected struct `String`, found `&str`
-   |               help: try using a conversion method: `x.to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/expr/if/if-no-match-bindings.stderr b/src/test/ui/expr/if/if-no-match-bindings.stderr
index 3f382e023a7..554cc3a2bcf 100644
--- a/src/test/ui/expr/if/if-no-match-bindings.stderr
+++ b/src/test/ui/expr/if/if-no-match-bindings.stderr
@@ -2,73 +2,89 @@ error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:18:8
    |
 LL |     if b_ref() {}
-   |        ^^^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider dereferencing the borrow: `*b_ref()`
+   |        ^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     if *b_ref() {}
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:19:8
    |
 LL |     if b_mut_ref() {}
-   |        ^^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&mut bool`
-   |        help: consider dereferencing the borrow: `*b_mut_ref()`
+   |        ^^^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     if *b_mut_ref() {}
+   |        ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:20:8
    |
 LL |     if &true {}
-   |        ^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider removing the borrow: `true`
+   |        ^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if true {}
+   |       --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:21:8
    |
 LL |     if &mut true {}
-   |        ^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&mut bool`
-   |        help: consider removing the borrow: `true`
+   |        ^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if true {}
+   |       --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:24:11
    |
 LL |     while b_ref() {}
-   |           ^^^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider dereferencing the borrow: `*b_ref()`
+   |           ^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while *b_ref() {}
+   |           ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:25:11
    |
 LL |     while b_mut_ref() {}
-   |           ^^^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&mut bool`
-   |           help: consider dereferencing the borrow: `*b_mut_ref()`
+   |           ^^^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while *b_mut_ref() {}
+   |           ^
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:26:11
    |
 LL |     while &true {}
-   |           ^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider removing the borrow: `true`
+   |           ^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while true {}
+   |          --
 
 error[E0308]: mismatched types
   --> $DIR/if-no-match-bindings.rs:27:11
    |
 LL |     while &mut true {}
-   |           ^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&mut bool`
-   |           help: consider removing the borrow: `true`
+   |           ^^^^^^^^^ expected `bool`, found `&mut bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while true {}
+   |          --
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
index 7b731a1d71d..74c6e501c91 100644
--- a/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
+++ b/src/test/ui/extern/issue-64655-allow-unwind-when-calling-panic-directly.rs
@@ -19,9 +19,7 @@
 
 // revisions: no thin fat
 //[no]compile-flags: -C lto=no
-// FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator
-//  when executed in i686-gnu-nopt runner.
-//[thin]compile-flags: -C lto=thin -Ccodegen-units=2
+//[thin]compile-flags: -C lto=thin
 //[fat]compile-flags: -C lto=fat
 
 #![feature(core_panic)]
diff --git a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
index 32e6d0c90b2..bc15fcb0e39 100644
--- a/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
+++ b/src/test/ui/extern/issue-64655-extern-rust-must-allow-unwind.rs
@@ -40,9 +40,7 @@
 //[no1]compile-flags: -C opt-level=1 -C lto=no
 //[no2]compile-flags: -C opt-level=2 -C lto=no
 //[no3]compile-flags: -C opt-level=3 -C lto=no
-// FIXME(#83854) running this revision with 1 CGU triggers llvm assert in register allocator
-//  when executed in dist-i586-gnu-i586-i686-musl runner.
-//[thin0]compile-flags: -C opt-level=0 -C lto=thin -Ccodegen-units=2
+//[thin0]compile-flags: -C opt-level=0 -C lto=thin
 //[thin1]compile-flags: -C opt-level=1 -C lto=thin
 //[thin2]compile-flags: -C opt-level=2 -C lto=thin
 //[thin3]compile-flags: -C opt-level=3 -C lto=thin
diff --git a/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs b/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs
new file mode 100644
index 00000000000..e4102f1cfa7
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-trait_upcasting.rs
@@ -0,0 +1,13 @@
+trait Foo {}
+
+trait Bar: Foo {}
+
+impl Foo for () {}
+
+impl Bar for () {}
+
+fn main() {
+    let bar: &dyn Bar = &();
+    let foo: &dyn Foo = bar;
+    //~^ ERROR trait upcasting coercion is experimental [E0658]
+}
diff --git a/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr
new file mode 100644
index 00000000000..bc13a5d7d7b
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-trait_upcasting.stderr
@@ -0,0 +1,12 @@
+error[E0658]: trait upcasting coercion is experimental
+  --> $DIR/feature-gate-trait_upcasting.rs:11:25
+   |
+LL |     let foo: &dyn Foo = bar;
+   |                         ^^^
+   |
+   = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+   = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/hygiene/auxiliary/intercrate.rs b/src/test/ui/hygiene/auxiliary/intercrate.rs
index 10d399ba54e..0685358851e 100644
--- a/src/test/ui/hygiene/auxiliary/intercrate.rs
+++ b/src/test/ui/hygiene/auxiliary/intercrate.rs
@@ -5,7 +5,7 @@ pub mod foo {
     mod bar {
         fn f() -> u32 { 1 }
         pub macro m() {
-            f();
+            f()
         }
     }
 }
diff --git a/src/test/ui/hygiene/hygienic-label-1.rs b/src/test/ui/hygiene/hygienic-label-1.rs
index 66361eec21a..a06d9255ab5 100644
--- a/src/test/ui/hygiene/hygienic-label-1.rs
+++ b/src/test/ui/hygiene/hygienic-label-1.rs
@@ -3,5 +3,5 @@ macro_rules! foo {
 }
 
 pub fn main() {
-    'x: loop { foo!() }
+    'x: loop { foo!(); }
 }
diff --git a/src/test/ui/hygiene/hygienic-label-1.stderr b/src/test/ui/hygiene/hygienic-label-1.stderr
index 97a7240b906..c1ed861836c 100644
--- a/src/test/ui/hygiene/hygienic-label-1.stderr
+++ b/src/test/ui/hygiene/hygienic-label-1.stderr
@@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
 LL |     () => { break 'x; }
    |                   ^^ undeclared label `'x`
 ...
-LL |     'x: loop { foo!() }
-   |                ------ in this macro invocation
+LL |     'x: loop { foo!(); }
+   |                ------- in this macro invocation
    |
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/hygiene/hygienic-label-3.rs b/src/test/ui/hygiene/hygienic-label-3.rs
index a81eb842259..ab0559e1b6a 100644
--- a/src/test/ui/hygiene/hygienic-label-3.rs
+++ b/src/test/ui/hygiene/hygienic-label-3.rs
@@ -4,6 +4,6 @@ macro_rules! foo {
 
 pub fn main() {
     'x: for _ in 0..1 {
-        foo!()
+        foo!();
     };
 }
diff --git a/src/test/ui/hygiene/hygienic-label-3.stderr b/src/test/ui/hygiene/hygienic-label-3.stderr
index 52840049f82..29d1b67e09f 100644
--- a/src/test/ui/hygiene/hygienic-label-3.stderr
+++ b/src/test/ui/hygiene/hygienic-label-3.stderr
@@ -4,8 +4,8 @@ error[E0426]: use of undeclared label `'x`
 LL |     () => { break 'x; }
    |                   ^^ undeclared label `'x`
 ...
-LL |         foo!()
-   |         ------ in this macro invocation
+LL |         foo!();
+   |         ------- in this macro invocation
    |
    = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
 
diff --git a/src/test/ui/impl-trait/does-not-live-long-enough.stderr b/src/test/ui/impl-trait/does-not-live-long-enough.stderr
index 468c2f36629..73fd5e8ded3 100644
--- a/src/test/ui/impl-trait/does-not-live-long-enough.stderr
+++ b/src/test/ui/impl-trait/does-not-live-long-enough.stderr
@@ -14,7 +14,7 @@ LL |     fn started_with<'a>(&'a self, prefix: &'a str) -> impl Iterator<Item=&'
 help: to force the closure to take ownership of `prefix` (and any other referenced variables), use the `move` keyword
    |
 LL |         self.data.iter().filter(move |s| s.starts_with(prefix)).map(|s| s.as_ref())
-   |                                 ^^^^^^^^
+   |                                 ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
index 00145d10ed7..0ecec5eea36 100644
--- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
+++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr
@@ -140,14 +140,15 @@ LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         return Struct;
-   |                ^^^^^^
-   |                |
-   |                expected struct `Box`, found struct `Struct`
-   |                help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
+   |                ^^^^^^ expected struct `Box`, found struct `Struct`
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
               found struct `Struct`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         return Box::new(Struct);
+   |                ^^^^^^^^^      ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:36:5
@@ -156,14 +157,15 @@ LL | fn bam() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |     42
-   |     ^^
-   |     |
-   |     expected struct `Box`, found integer
-   |     help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |     ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Box::new(42)
+   |     ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:40:16
@@ -172,14 +174,15 @@ LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         return 0;
-   |                ^
-   |                |
-   |                expected struct `Box`, found integer
-   |                help: store this in the heap by calling `Box::new`: `Box::new(0)`
+   |                ^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         return Box::new(0);
+   |                ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:42:5
@@ -188,14 +191,15 @@ LL | fn baq() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |     42
-   |     ^^
-   |     |
-   |     expected struct `Box`, found integer
-   |     help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |     ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Box::new(42)
+   |     ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:46:9
@@ -204,14 +208,15 @@ LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         Struct
-   |         ^^^^^^
-   |         |
-   |         expected struct `Box`, found struct `Struct`
-   |         help: store this in the heap by calling `Box::new`: `Box::new(Struct)`
+   |         ^^^^^^ expected struct `Box`, found struct `Struct`
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
               found struct `Struct`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(Struct)
+   |         ^^^^^^^^^      ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:48:9
@@ -220,14 +225,15 @@ LL | fn baz() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |         42
-   |         ^^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |         ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(42)
+   |         ^^^^^^^^^  ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:53:9
@@ -236,14 +242,15 @@ LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 LL |     if true {
 LL |         0
-   |         ^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(0)`
+   |         ^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(0)
+   |         ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:55:9
@@ -252,14 +259,15 @@ LL | fn baw() -> Box<dyn Trait> {
    |             -------------- expected `Box<(dyn Trait + 'static)>` because of return type
 ...
 LL |         42
-   |         ^^
-   |         |
-   |         expected struct `Box`, found integer
-   |         help: store this in the heap by calling `Box::new`: `Box::new(42)`
+   |         ^^ expected struct `Box`, found integer
    |
    = note: expected struct `Box<(dyn Trait + 'static)>`
                 found type `{integer}`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |         Box::new(42)
+   |         ^^^^^^^^^  ^
 
 error[E0746]: return type cannot have an unboxed trait object
   --> $DIR/dyn-trait-return-should-be-impl-trait.rs:60:13
diff --git a/src/test/ui/infinite/infinite-autoderef.stderr b/src/test/ui/infinite/infinite-autoderef.stderr
index e7d90f00d24..957ab2a7548 100644
--- a/src/test/ui/infinite/infinite-autoderef.stderr
+++ b/src/test/ui/infinite/infinite-autoderef.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/infinite-autoderef.rs:20:13
    |
 LL |         x = box x;
-   |             ^^^^^
-   |             |
-   |             cyclic type of infinite size
-   |             help: try using a conversion method: `(box x).to_string()`
+   |             ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |         x = (box x).to_string();
+   |             ^     ^^^^^^^^^^^^^
 
 error[E0055]: reached the recursion limit while auto-dereferencing `Foo`
   --> $DIR/infinite-autoderef.rs:25:5
diff --git a/src/test/ui/issues/issue-11515.rs b/src/test/ui/issues/issue-11515.rs
index a7671b9282a..2072f9c47e2 100644
--- a/src/test/ui/issues/issue-11515.rs
+++ b/src/test/ui/issues/issue-11515.rs
@@ -1,10 +1,10 @@
 #![feature(box_syntax)]
 
 struct Test {
-    func: Box<dyn FnMut() + 'static>
+    func: Box<dyn FnMut() + 'static>,
 }
 
 fn main() {
     let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
-    let test = box Test { func: closure }; //~ ERROR mismatched types
+    let test = box Test { func: closure }; //~ ERROR trait upcasting coercion is experimental [E0658]
 }
diff --git a/src/test/ui/issues/issue-11515.stderr b/src/test/ui/issues/issue-11515.stderr
index 7935615ad7e..a70e7c416bc 100644
--- a/src/test/ui/issues/issue-11515.stderr
+++ b/src/test/ui/issues/issue-11515.stderr
@@ -1,12 +1,12 @@
-error[E0308]: mismatched types
+error[E0658]: trait upcasting coercion is experimental
   --> $DIR/issue-11515.rs:9:33
    |
 LL |     let test = box Test { func: closure };
-   |                                 ^^^^^^^ expected trait `FnMut`, found trait `Fn`
+   |                                 ^^^^^^^
    |
-   = note: expected struct `Box<(dyn FnMut() + 'static)>`
-              found struct `Box<(dyn Fn() + 'static)>`
+   = note: see issue #65991 <https://github.com/rust-lang/rust/issues/65991> for more information
+   = help: add `#![feature(trait_upcasting)]` to the crate attributes to enable
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0308`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/issues/issue-22644.stderr b/src/test/ui/issues/issue-22644.stderr
index 1be26949b25..99ff9ac0a0d 100644
--- a/src/test/ui/issues/issue-22644.stderr
+++ b/src/test/ui/issues/issue-22644.stderr
@@ -2,46 +2,66 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a com
   --> $DIR/issue-22644.rs:8:31
    |
 LL |     println!("{}", a as usize < long_name);
-   |                    ---------- ^ --------- interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as comparison
-   |                    help: try comparing the cast value: `(a as usize)`
+   |                               ^ --------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a as usize) < long_name);
+   |                    ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:9:33
    |
 LL |     println!("{}{}", a as usize < long_name, long_name);
-   |                      ---------- ^ -------------------- interpreted as generic arguments
-   |                      |          |
-   |                      |          not interpreted as comparison
-   |                      help: try comparing the cast value: `(a as usize)`
+   |                                 ^ -------------------- interpreted as generic arguments
+   |                                 |
+   |                                 not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}{}", (a as usize) < long_name, long_name);
+   |                      ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:11:31
    |
 LL |     println!("{}", a as usize < 4);
-   |                    ---------- ^ - interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as comparison
-   |                    help: try comparing the cast value: `(a as usize)`
+   |                               ^ - interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a as usize) < 4);
+   |                    ^          ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:13:31
    |
 LL |     println!("{}{}", a: usize < long_name, long_name);
-   |                      -------- ^ -------------------- interpreted as generic arguments
-   |                      |        |
-   |                      |        not interpreted as comparison
-   |                      help: try comparing the cast value: `(a: usize)`
+   |                               ^ -------------------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}{}", (a: usize) < long_name, long_name);
+   |                      ^        ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:15:29
    |
 LL |     println!("{}", a: usize < 4);
-   |                    -------- ^ - interpreted as generic arguments
-   |                    |        |
-   |                    |        not interpreted as comparison
-   |                    help: try comparing the cast value: `(a: usize)`
+   |                             ^ - interpreted as generic arguments
+   |                             |
+   |                             not interpreted as comparison
+   |
+help: try comparing the cast value
+   |
+LL |     println!("{}", (a: usize) < 4);
+   |                    ^        ^
 
 error: `<` is interpreted as a start of generic arguments for `usize`, not a comparison
   --> $DIR/issue-22644.rs:20:20
@@ -80,10 +100,14 @@ error: `<` is interpreted as a start of generic arguments for `usize`, not a shi
   --> $DIR/issue-22644.rs:32:31
    |
 LL |     println!("{}", a as usize << long_name);
-   |                    ---------- ^^ --------- interpreted as generic arguments
-   |                    |          |
-   |                    |          not interpreted as shift
-   |                    help: try shifting the cast value: `(a as usize)`
+   |                               ^^ --------- interpreted as generic arguments
+   |                               |
+   |                               not interpreted as shift
+   |
+help: try shifting the cast value
+   |
+LL |     println!("{}", (a as usize) << long_name);
+   |                    ^          ^
 
 error: expected type, found `4`
   --> $DIR/issue-22644.rs:34:28
diff --git a/src/test/ui/issues/issue-32122-1.stderr b/src/test/ui/issues/issue-32122-1.stderr
index dfbd3223efc..b3362ae44b6 100644
--- a/src/test/ui/issues/issue-32122-1.stderr
+++ b/src/test/ui/issues/issue-32122-1.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-32122-1.rs:16:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Foo`
-   |            |           help: consider dereferencing: `&*a`
+   |            ---------   ^^ expected `u8`, found struct `Foo`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Foo`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &*a;
+   |                         ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-32122-2.stderr b/src/test/ui/issues/issue-32122-2.stderr
index 2e199e2a19f..bcf71638127 100644
--- a/src/test/ui/issues/issue-32122-2.stderr
+++ b/src/test/ui/issues/issue-32122-2.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-32122-2.rs:27:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-42954.stderr b/src/test/ui/issues/issue-42954.stderr
index 8227f8df1e0..4f41c95323a 100644
--- a/src/test/ui/issues/issue-42954.stderr
+++ b/src/test/ui/issues/issue-42954.stderr
@@ -2,15 +2,18 @@ error: `<` is interpreted as a start of generic arguments for `u32`, not a compa
   --> $DIR/issue-42954.rs:7:19
    |
 LL |         $i as u32 < 0
-   |         --------- ^ - interpreted as generic arguments
-   |         |         |
-   |         |         not interpreted as comparison
-   |         help: try comparing the cast value: `($i as u32)`
+   |                   ^ - interpreted as generic arguments
+   |                   |
+   |                   not interpreted as comparison
 ...
 LL |     is_plainly_printable!(c);
    |     ------------------------- in this macro invocation
    |
    = note: this error originates in the macro `is_plainly_printable` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: try comparing the cast value
+   |
+LL |         ($i as u32) < 0
+   |         ^         ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
index f6adfc87dad..a9404c1c46a 100644
--- a/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
+++ b/src/test/ui/issues/issue-50687-ice-on-borrow.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-50687-ice-on-borrow.rs:40:17
    |
 LL |     let _: () = Borrow::borrow(&owned);
-   |            --   ^^^^^^^^^^^^^^^^^^^^^^
-   |            |    |
-   |            |    expected `()`, found reference
-   |            |    help: consider dereferencing the borrow: `*Borrow::borrow(&owned)`
+   |            --   ^^^^^^^^^^^^^^^^^^^^^^ expected `()`, found reference
+   |            |
    |            expected due to this
    |
    = note: expected unit type `()`
               found reference `&_`
+help: consider dereferencing the borrow
+   |
+LL |     let _: () = *Borrow::borrow(&owned);
+   |                 ^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-71676-1.stderr b/src/test/ui/issues/issue-71676-1.stderr
index bbabc2202dc..14913c93bf7 100644
--- a/src/test/ui/issues/issue-71676-1.stderr
+++ b/src/test/ui/issues/issue-71676-1.stderr
@@ -2,53 +2,61 @@ error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:43:24
    |
 LL |     let _: *const u8 = &a;
-   |            ---------   ^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*const u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:46:22
    |
 LL |     let _: *mut u8 = &a;
-   |            -------   ^^
-   |            |         |
-   |            |         types differ in mutability
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^ types differ in mutability
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*mut u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                       ^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:49:24
    |
 LL |     let _: *const u8 = &mut a;
-   |            ---------   ^^^^^^
-   |            |           |
-   |            |           expected `u8`, found struct `Emm`
-   |            |           help: consider dereferencing: `&***a`
+   |            ---------   ^^^^^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note:    expected raw pointer `*const u8`
            found mutable reference `&mut Emm`
+help: consider dereferencing
+   |
+LL |     let _: *const u8 = &***a;
+   |                         ^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-71676-1.rs:52:22
    |
 LL |     let _: *mut u8 = &mut a;
-   |            -------   ^^^^^^
-   |            |         |
-   |            |         expected `u8`, found struct `Emm`
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^^^^^ expected `u8`, found struct `Emm`
+   |            |
    |            expected due to this
    |
    = note:    expected raw pointer `*mut u8`
            found mutable reference `&mut Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                           ^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issues/issue-71676-2.stderr b/src/test/ui/issues/issue-71676-2.stderr
index ebdd345809a..0544deda4ae 100644
--- a/src/test/ui/issues/issue-71676-2.stderr
+++ b/src/test/ui/issues/issue-71676-2.stderr
@@ -2,14 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/issue-71676-2.rs:41:22
    |
 LL |     let _: *mut u8 = &a;
-   |            -------   ^^
-   |            |         |
-   |            |         types differ in mutability
-   |            |         help: consider dereferencing: `&mut ***a`
+   |            -------   ^^ types differ in mutability
+   |            |
    |            expected due to this
    |
    = note: expected raw pointer `*mut u8`
                 found reference `&Emm`
+help: consider dereferencing
+   |
+LL |     let _: *mut u8 = &mut ***a;
+   |                       ^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-77218.stderr b/src/test/ui/issues/issue-77218.stderr
index 4f6fbaa2265..f945f7f38f9 100644
--- a/src/test/ui/issues/issue-77218.stderr
+++ b/src/test/ui/issues/issue-77218.stderr
@@ -21,10 +21,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-77218.rs:3:16
    |
 LL |     while Some(0) = value.get(0) {
+   |                ^ expected integer, found `&u8`
+   |
+help: consider dereferencing the borrow
+   |
+LL |     while Some(*0) = value.get(0) {
    |                ^
-   |                |
-   |                expected integer, found `&u8`
-   |                help: consider dereferencing the borrow: `*0`
 
 error[E0308]: mismatched types
   --> $DIR/issue-77218.rs:3:11
diff --git a/src/test/ui/json-bom-plus-crlf-multifile.stderr b/src/test/ui/json-bom-plus-crlf-multifile.stderr
index da8849a8284..02f3bc687cb 100644
--- a/src/test/ui/json-bom-plus-crlf-multifile.stderr
+++ b/src/test/ui/json-bom-plus-crlf-multifile.stderr
@@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":621,"byte_end":622,"line_start":17,"line_end":17,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":612,"byte_end":618,"line_start":17,"line_end":17,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":622,"byte_end":622,"line_start":17,"line_end":17,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:17:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":681,"byte_end":682,"line_start":19,"line_end":19,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":672,"byte_end":678,"line_start":19,"line_end":19,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":682,"byte_end":682,"line_start":19,"line_end":19,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:19:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":745,"byte_end":746,"line_start":23,"line_end":23,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":735,"byte_end":741,"line_start":22,"line_end":22,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf-multifile-aux.rs","byte_start":746,"byte_end":746,"line_start":23,"line_end":23,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf-multifile-aux.rs:23:1: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
diff --git a/src/test/ui/json-bom-plus-crlf.stderr b/src/test/ui/json-bom-plus-crlf.stderr
index 811206f9aa0..df6bd7286a6 100644
--- a/src/test/ui/json-bom-plus-crlf.stderr
+++ b/src/test/ui/json-bom-plus-crlf.stderr
@@ -24,7 +24,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":606,"byte_end":607,"line_start":16,"line_end":16,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":597,"byte_end":603,"line_start":16,"line_end":16,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":607,"byte_end":607,"line_start":16,"line_end":16,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1;  // Error in the middle of line.","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:16:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -52,7 +52,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":666,"byte_end":667,"line_start":18,"line_end":18,"column_start":22,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":22,"highlight_end":23}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":657,"byte_end":663,"line_start":18,"line_end":18,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String = 1","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":667,"byte_end":667,"line_start":18,"line_end":18,"column_start":23,"column_end":23,"is_primary":true,"text":[{"text":"    let s : String = 1","highlight_start":23,"highlight_end":23}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:18:22: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
@@ -80,7 +80,7 @@ This error occurs when an expression was used in a place where the compiler
 expected an expression of a different type. It can occur in several cases, the
 most common being when calling a function and passing an argument which has a
 different type than the matching type in the function declaration.
-"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":null,"suggested_replacement":"1.to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types
+"},"level":"error","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":730,"byte_end":731,"line_start":22,"line_end":22,"column_start":1,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":1,"highlight_end":2}],"label":"expected struct `String`, found integer","suggested_replacement":null,"suggestion_applicability":null,"expansion":null},{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":720,"byte_end":726,"line_start":21,"line_end":21,"column_start":13,"column_end":19,"is_primary":false,"text":[{"text":"    let s : String =","highlight_start":13,"highlight_end":19}],"label":"expected due to this","suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"try using a conversion method","code":null,"level":"help","spans":[{"file_name":"$DIR/json-bom-plus-crlf.rs","byte_start":731,"byte_end":731,"line_start":22,"line_end":22,"column_start":2,"column_end":2,"is_primary":true,"text":[{"text":"1;  // Error after the newline.","highlight_start":2,"highlight_end":2}],"label":null,"suggested_replacement":".to_string()","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"$DIR/json-bom-plus-crlf.rs:22:1: error[E0308]: mismatched types
 "}
 {"message":"mismatched types","code":{"code":"E0308","explanation":"Expected type did not match the received type.
 
diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
index 34470119112..1fef8fc69e2 100644
--- a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
+++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr
@@ -14,7 +14,7 @@ LL |     [0].iter().flat_map(|a| [0].iter().map(|_| &a));
 help: to force the closure to take ownership of `a` (and any other referenced variables), use the `move` keyword
    |
 LL |     [0].iter().flat_map(|a| [0].iter().map(move |_| &a));
-   |                                            ^^^^^^^^
+   |                                            ^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/lint/fn_must_use.stderr b/src/test/ui/lint/fn_must_use.stderr
index d6b1cf3ae1f..6a5fdac4d91 100644
--- a/src/test/ui/lint/fn_must_use.stderr
+++ b/src/test/ui/lint/fn_must_use.stderr
@@ -47,13 +47,23 @@ warning: unused comparison that must be used
   --> $DIR/fn_must_use.rs:74:5
    |
 LL |     2 == 3;
-   |     ^^^^^^
+   |     ^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 2 == 3;
+   |     ^^^^^^^
 
 warning: unused comparison that must be used
   --> $DIR/fn_must_use.rs:75:5
    |
 LL |     m == n;
-   |     ^^^^^^
+   |     ^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = m == n;
+   |     ^^^^^^^
 
 warning: 8 warnings emitted
 
diff --git a/src/test/ui/lint/must-use-ops.stderr b/src/test/ui/lint/must-use-ops.stderr
deleted file mode 100644
index 3fb80f7e798..00000000000
--- a/src/test/ui/lint/must-use-ops.stderr
+++ /dev/null
@@ -1,134 +0,0 @@
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:12:5
-   |
-LL |     val == 1;
-   |     ^^^^^^^^
-   |
-note: the lint level is defined here
-  --> $DIR/must-use-ops.rs:5:9
-   |
-LL | #![warn(unused_must_use)]
-   |         ^^^^^^^^^^^^^^^
-
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:13:5
-   |
-LL |     val < 1;
-   |     ^^^^^^^
-
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:14:5
-   |
-LL |     val <= 1;
-   |     ^^^^^^^^
-
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:15:5
-   |
-LL |     val != 1;
-   |     ^^^^^^^^
-
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:16:5
-   |
-LL |     val >= 1;
-   |     ^^^^^^^^
-
-warning: unused comparison that must be used
-  --> $DIR/must-use-ops.rs:17:5
-   |
-LL |     val > 1;
-   |     ^^^^^^^
-
-warning: unused arithmetic operation that must be used
-  --> $DIR/must-use-ops.rs:20:5
-   |
-LL |     val + 2;
-   |     ^^^^^^^
-
-warning: unused arithmetic operation that must be used
-  --> $DIR/must-use-ops.rs:21:5
-   |
-LL |     val - 2;
-   |     ^^^^^^^
-
-warning: unused arithmetic operation that must be used
-  --> $DIR/must-use-ops.rs:22:5
-   |
-LL |     val / 2;
-   |     ^^^^^^^
-
-warning: unused arithmetic operation that must be used
-  --> $DIR/must-use-ops.rs:23:5
-   |
-LL |     val * 2;
-   |     ^^^^^^^
-
-warning: unused arithmetic operation that must be used
-  --> $DIR/must-use-ops.rs:24:5
-   |
-LL |     val % 2;
-   |     ^^^^^^^
-
-warning: unused logical operation that must be used
-  --> $DIR/must-use-ops.rs:27:5
-   |
-LL |     true && true;
-   |     ^^^^^^^^^^^^
-
-warning: unused logical operation that must be used
-  --> $DIR/must-use-ops.rs:28:5
-   |
-LL |     false || true;
-   |     ^^^^^^^^^^^^^
-
-warning: unused bitwise operation that must be used
-  --> $DIR/must-use-ops.rs:31:5
-   |
-LL |     5 ^ val;
-   |     ^^^^^^^
-
-warning: unused bitwise operation that must be used
-  --> $DIR/must-use-ops.rs:32:5
-   |
-LL |     5 & val;
-   |     ^^^^^^^
-
-warning: unused bitwise operation that must be used
-  --> $DIR/must-use-ops.rs:33:5
-   |
-LL |     5 | val;
-   |     ^^^^^^^
-
-warning: unused bitwise operation that must be used
-  --> $DIR/must-use-ops.rs:34:5
-   |
-LL |     5 << val;
-   |     ^^^^^^^^
-
-warning: unused bitwise operation that must be used
-  --> $DIR/must-use-ops.rs:35:5
-   |
-LL |     5 >> val;
-   |     ^^^^^^^^
-
-warning: unused unary operation that must be used
-  --> $DIR/must-use-ops.rs:38:5
-   |
-LL |     !val;
-   |     ^^^^
-
-warning: unused unary operation that must be used
-  --> $DIR/must-use-ops.rs:39:5
-   |
-LL |     -val;
-   |     ^^^^
-
-warning: unused unary operation that must be used
-  --> $DIR/must-use-ops.rs:40:5
-   |
-LL |     *val_pointer;
-   |     ^^^^^^^^^^^^
-
-warning: 21 warnings emitted
-
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs
deleted file mode 100644
index 6f9e6ec0a57..00000000000
--- a/src/test/ui/lint/semicolon-in-expressions-from-macros/allow-semicolon-in-expressions-from-macros.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// check-pass
-// Ensure that trailing semicolons are allowed by default
-
-macro_rules! foo {
-    () => {
-        true;
-    }
-}
-
-fn main() {
-    let val = match true {
-        true => false,
-        _ => foo!()
-    };
-}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs
new file mode 100644
index 00000000000..781391cc574
--- /dev/null
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/auxiliary/foreign-crate.rs
@@ -0,0 +1,4 @@
+#[macro_export]
+macro_rules! my_macro {
+    () => { true; }
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs
new file mode 100644
index 00000000000..374506366f8
--- /dev/null
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/foreign-crate.rs
@@ -0,0 +1,9 @@
+// aux-build:foreign-crate.rs
+// check-pass
+
+extern crate foreign_crate;
+
+// Test that we do not lint for a macro in a foreign crate
+fn main() {
+    let _ = foreign_crate::my_macro!();
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs
new file mode 100644
index 00000000000..2c63311e659
--- /dev/null
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.rs
@@ -0,0 +1,16 @@
+// check-pass
+// Ensure that trailing semicolons cause warnings by default
+
+macro_rules! foo {
+    () => {
+        true; //~  WARN trailing semicolon in macro
+              //~| WARN this was previously
+    }
+}
+
+fn main() {
+    let _val = match true {
+        true => false,
+        _ => foo!()
+    };
+}
diff --git a/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
new file mode 100644
index 00000000000..d770a8c8f36
--- /dev/null
+++ b/src/test/ui/lint/semicolon-in-expressions-from-macros/warn-semicolon-in-expressions-from-macros.stderr
@@ -0,0 +1,16 @@
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/warn-semicolon-in-expressions-from-macros.rs:6:13
+   |
+LL |         true;
+   |             ^
+...
+LL |         _ => foo!()
+   |              ------ in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/lint/unused-borrows.stderr b/src/test/ui/lint/unused-borrows.stderr
index 24899fe992b..e91e02df476 100644
--- a/src/test/ui/lint/unused-borrows.stderr
+++ b/src/test/ui/lint/unused-borrows.stderr
@@ -2,43 +2,72 @@ error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:6:5
    |
 LL |     &42;
-   |     ^^^
+   |     ^^^ the borrow produces a value
    |
 note: the lint level is defined here
   --> $DIR/unused-borrows.rs:1:9
    |
 LL | #![deny(unused_must_use)]
    |         ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = &42;
+   |     ^^^^^^^
 
 error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:9:5
    |
 LL |     &mut foo(42);
-   |     ^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^ the borrow produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = &mut foo(42);
+   |     ^^^^^^^
 
 error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:12:5
    |
 LL |     &&42;
-   |     ^^^^
+   |     ^^^^ the borrow produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = &&42;
+   |     ^^^^^^^
 
 error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:15:5
    |
 LL |     &&mut 42;
-   |     ^^^^^^^^
+   |     ^^^^^^^^ the borrow produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = &&mut 42;
+   |     ^^^^^^^
 
 error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:18:5
    |
 LL |     &mut &42;
-   |     ^^^^^^^^
+   |     ^^^^^^^^ the borrow produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = &mut &42;
+   |     ^^^^^^^
 
 error: unused borrow that must be used
   --> $DIR/unused-borrows.rs:23:5
    |
 LL |     && foo(42);
-   |     ^^^^^^^^^^
+   |     ^^^^^^^^^^ the borrow produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = && foo(42);
+   |     ^^^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs
index b76b4321d62..b76b4321d62 100644
--- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate.rs
+++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate.rs
diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate2.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs
index b76b4321d62..b76b4321d62 100644
--- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate2.rs
+++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate2.rs
diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate3.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs
index b76b4321d62..b76b4321d62 100644
--- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate3.rs
+++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate3.rs
diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate4.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs
index d11c69f812a..d11c69f812a 100644
--- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate4.rs
+++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate4.rs
diff --git a/src/test/ui/lint/auxiliary/lint_unused_extern_crate5.rs b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs
index d11c69f812a..d11c69f812a 100644
--- a/src/test/ui/lint/auxiliary/lint_unused_extern_crate5.rs
+++ b/src/test/ui/lint/unused/auxiliary/lint_unused_extern_crate5.rs
diff --git a/src/test/ui/unused/issue-30730.rs b/src/test/ui/lint/unused/issue-30730.rs
index d6be90c8148..d6be90c8148 100644
--- a/src/test/ui/unused/issue-30730.rs
+++ b/src/test/ui/lint/unused/issue-30730.rs
diff --git a/src/test/ui/unused/issue-30730.stderr b/src/test/ui/lint/unused/issue-30730.stderr
index b299e99a3a9..b299e99a3a9 100644
--- a/src/test/ui/unused/issue-30730.stderr
+++ b/src/test/ui/lint/unused/issue-30730.stderr
diff --git a/src/test/ui/unused/issue-46576.rs b/src/test/ui/lint/unused/issue-46576.rs
index 15f458f3844..15f458f3844 100644
--- a/src/test/ui/unused/issue-46576.rs
+++ b/src/test/ui/lint/unused/issue-46576.rs
diff --git a/src/test/ui/unused/issue-46576.stderr b/src/test/ui/lint/unused/issue-46576.stderr
index 6f4d97068b3..6f4d97068b3 100644
--- a/src/test/ui/unused/issue-46576.stderr
+++ b/src/test/ui/lint/unused/issue-46576.stderr
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs
index 0ad014e3361..0ad014e3361 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.rs
+++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.rs
diff --git a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
index 2ef655efdbd..2ef655efdbd 100644
--- a/src/test/ui/lint/issue-47390-unused-variable-in-struct-pattern.stderr
+++ b/src/test/ui/lint/unused/issue-47390-unused-variable-in-struct-pattern.stderr
diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.fixed b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed
index 1350b7ca699..1350b7ca699 100644
--- a/src/test/ui/lint/issue-54180-unused-ref-field.fixed
+++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.fixed
diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.rs b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs
index 7b3392b609a..7b3392b609a 100644
--- a/src/test/ui/lint/issue-54180-unused-ref-field.rs
+++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.rs
diff --git a/src/test/ui/lint/issue-54180-unused-ref-field.stderr b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr
index c501aa25f13..c501aa25f13 100644
--- a/src/test/ui/lint/issue-54180-unused-ref-field.stderr
+++ b/src/test/ui/lint/unused/issue-54180-unused-ref-field.stderr
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.fixed b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed
index 0b3fe9371f7..0b3fe9371f7 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.fixed
+++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.fixed
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs
index 1e78ec5f7d9..1e78ec5f7d9 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.rs
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr
index e6d0a359c5c..e6d0a359c5c 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/unused/issue-54538-unused-parens-lint.stderr
diff --git a/src/test/ui/unused/issue-59896.rs b/src/test/ui/lint/unused/issue-59896.rs
index ff9f19acf84..ff9f19acf84 100644
--- a/src/test/ui/unused/issue-59896.rs
+++ b/src/test/ui/lint/unused/issue-59896.rs
diff --git a/src/test/ui/unused/issue-59896.stderr b/src/test/ui/lint/unused/issue-59896.stderr
index 95b7938ae03..95b7938ae03 100644
--- a/src/test/ui/unused/issue-59896.stderr
+++ b/src/test/ui/lint/unused/issue-59896.stderr
diff --git a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.rs b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs
index e3631d014d6..e3631d014d6 100644
--- a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.rs
+++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.rs
diff --git a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.stderr b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr
index 8aefe243a94..8aefe243a94 100644
--- a/src/test/ui/lint/issue-67691-unused-field-in-or-pattern.stderr
+++ b/src/test/ui/lint/unused/issue-67691-unused-field-in-or-pattern.stderr
diff --git a/src/test/ui/unused/issue-70041.rs b/src/test/ui/lint/unused/issue-70041.rs
index 22e42295eed..22e42295eed 100644
--- a/src/test/ui/unused/issue-70041.rs
+++ b/src/test/ui/lint/unused/issue-70041.rs
diff --git a/src/test/ui/unused/issue-70041.stderr b/src/test/ui/lint/unused/issue-70041.stderr
index ecd618eae8b..ecd618eae8b 100644
--- a/src/test/ui/unused/issue-70041.stderr
+++ b/src/test/ui/lint/unused/issue-70041.stderr
diff --git a/src/test/ui/lint/issue-71290-unused-paren-binop.rs b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs
index 24d77e36d94..24d77e36d94 100644
--- a/src/test/ui/lint/issue-71290-unused-paren-binop.rs
+++ b/src/test/ui/lint/unused/issue-71290-unused-paren-binop.rs
diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs
index 8064c3a88d1..8064c3a88d1 100644
--- a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.rs
+++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.rs
diff --git a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr
index 3f6260dc6e1..3f6260dc6e1 100644
--- a/src/test/ui/lint/issue-74883-unused-paren-baren-yield.stderr
+++ b/src/test/ui/lint/unused/issue-74883-unused-paren-baren-yield.stderr
diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.fixed b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed
index aac918f2bc8..aac918f2bc8 100644
--- a/src/test/ui/lint/issue-81314-unused-span-ident.fixed
+++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.fixed
diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.rs b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs
index 78296f4258d..78296f4258d 100644
--- a/src/test/ui/lint/issue-81314-unused-span-ident.rs
+++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.rs
diff --git a/src/test/ui/lint/issue-81314-unused-span-ident.stderr b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr
index 519c71e9413..519c71e9413 100644
--- a/src/test/ui/lint/issue-81314-unused-span-ident.stderr
+++ b/src/test/ui/lint/unused/issue-81314-unused-span-ident.stderr
diff --git a/src/test/ui/lint/unused/issue-85913.rs b/src/test/ui/lint/unused/issue-85913.rs
new file mode 100644
index 00000000000..7f3817b6ef1
--- /dev/null
+++ b/src/test/ui/lint/unused/issue-85913.rs
@@ -0,0 +1,13 @@
+#![deny(unused_must_use)]
+
+pub fn fun() -> i32 {
+    function() && return 1;
+    //~^ ERROR: unused logical operation that must be used
+    return 0;
+}
+
+fn function() -> bool {
+    true
+}
+
+fn main() {}
diff --git a/src/test/ui/lint/unused/issue-85913.stderr b/src/test/ui/lint/unused/issue-85913.stderr
new file mode 100644
index 00000000000..4835cfae46f
--- /dev/null
+++ b/src/test/ui/lint/unused/issue-85913.stderr
@@ -0,0 +1,18 @@
+error: unused logical operation that must be used
+  --> $DIR/issue-85913.rs:4:5
+   |
+LL |     function() && return 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^ the logical operation produces a value
+   |
+note: the lint level is defined here
+  --> $DIR/issue-85913.rs:1:9
+   |
+LL | #![deny(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = function() && return 1;
+   |     ^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/lint/lint-unused-extern-crate.rs b/src/test/ui/lint/unused/lint-unused-extern-crate.rs
index d5e4da526a1..d5e4da526a1 100644
--- a/src/test/ui/lint/lint-unused-extern-crate.rs
+++ b/src/test/ui/lint/unused/lint-unused-extern-crate.rs
diff --git a/src/test/ui/lint/lint-unused-extern-crate.stderr b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr
index 46d8f3beeab..46d8f3beeab 100644
--- a/src/test/ui/lint/lint-unused-extern-crate.stderr
+++ b/src/test/ui/lint/unused/lint-unused-extern-crate.stderr
diff --git a/src/test/ui/lint/lint-unused-imports.rs b/src/test/ui/lint/unused/lint-unused-imports.rs
index 4754d888076..4754d888076 100644
--- a/src/test/ui/lint/lint-unused-imports.rs
+++ b/src/test/ui/lint/unused/lint-unused-imports.rs
diff --git a/src/test/ui/lint/lint-unused-imports.stderr b/src/test/ui/lint/unused/lint-unused-imports.stderr
index 0574ca4569f..0574ca4569f 100644
--- a/src/test/ui/lint/lint-unused-imports.stderr
+++ b/src/test/ui/lint/unused/lint-unused-imports.stderr
diff --git a/src/test/ui/lint/lint-unused-mut-self.fixed b/src/test/ui/lint/unused/lint-unused-mut-self.fixed
index 92ce103586c..92ce103586c 100644
--- a/src/test/ui/lint/lint-unused-mut-self.fixed
+++ b/src/test/ui/lint/unused/lint-unused-mut-self.fixed
diff --git a/src/test/ui/lint/lint-unused-mut-self.rs b/src/test/ui/lint/unused/lint-unused-mut-self.rs
index 70736ce216e..70736ce216e 100644
--- a/src/test/ui/lint/lint-unused-mut-self.rs
+++ b/src/test/ui/lint/unused/lint-unused-mut-self.rs
diff --git a/src/test/ui/lint/lint-unused-mut-self.stderr b/src/test/ui/lint/unused/lint-unused-mut-self.stderr
index 01a524bd323..01a524bd323 100644
--- a/src/test/ui/lint/lint-unused-mut-self.stderr
+++ b/src/test/ui/lint/unused/lint-unused-mut-self.stderr
diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/unused/lint-unused-mut-variables.rs
index 67ec7facf17..67ec7facf17 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.rs
+++ b/src/test/ui/lint/unused/lint-unused-mut-variables.rs
diff --git a/src/test/ui/lint/lint-unused-mut-variables.stderr b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr
index 805ed2b40bb..805ed2b40bb 100644
--- a/src/test/ui/lint/lint-unused-mut-variables.stderr
+++ b/src/test/ui/lint/unused/lint-unused-mut-variables.stderr
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/unused/lint-unused-variables.rs
index 6850e999242..6850e999242 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/unused/lint-unused-variables.rs
diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/unused/lint-unused-variables.stderr
index d6e684e8306..d6e684e8306 100644
--- a/src/test/ui/lint/lint-unused-variables.stderr
+++ b/src/test/ui/lint/unused/lint-unused-variables.stderr
diff --git a/src/test/ui/lint/must-use-ops.rs b/src/test/ui/lint/unused/must-use-ops.rs
index 3e425727e78..3e425727e78 100644
--- a/src/test/ui/lint/must-use-ops.rs
+++ b/src/test/ui/lint/unused/must-use-ops.rs
diff --git a/src/test/ui/lint/unused/must-use-ops.stderr b/src/test/ui/lint/unused/must-use-ops.stderr
new file mode 100644
index 00000000000..4dd739088b9
--- /dev/null
+++ b/src/test/ui/lint/unused/must-use-ops.stderr
@@ -0,0 +1,238 @@
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:12:5
+   |
+LL |     val == 1;
+   |     ^^^^^^^^ the comparison produces a value
+   |
+note: the lint level is defined here
+  --> $DIR/must-use-ops.rs:5:9
+   |
+LL | #![warn(unused_must_use)]
+   |         ^^^^^^^^^^^^^^^
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val == 1;
+   |     ^^^^^^^
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:13:5
+   |
+LL |     val < 1;
+   |     ^^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val < 1;
+   |     ^^^^^^^
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:14:5
+   |
+LL |     val <= 1;
+   |     ^^^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val <= 1;
+   |     ^^^^^^^
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:15:5
+   |
+LL |     val != 1;
+   |     ^^^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val != 1;
+   |     ^^^^^^^
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:16:5
+   |
+LL |     val >= 1;
+   |     ^^^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val >= 1;
+   |     ^^^^^^^
+
+warning: unused comparison that must be used
+  --> $DIR/must-use-ops.rs:17:5
+   |
+LL |     val > 1;
+   |     ^^^^^^^ the comparison produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val > 1;
+   |     ^^^^^^^
+
+warning: unused arithmetic operation that must be used
+  --> $DIR/must-use-ops.rs:20:5
+   |
+LL |     val + 2;
+   |     ^^^^^^^ the arithmetic operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val + 2;
+   |     ^^^^^^^
+
+warning: unused arithmetic operation that must be used
+  --> $DIR/must-use-ops.rs:21:5
+   |
+LL |     val - 2;
+   |     ^^^^^^^ the arithmetic operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val - 2;
+   |     ^^^^^^^
+
+warning: unused arithmetic operation that must be used
+  --> $DIR/must-use-ops.rs:22:5
+   |
+LL |     val / 2;
+   |     ^^^^^^^ the arithmetic operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val / 2;
+   |     ^^^^^^^
+
+warning: unused arithmetic operation that must be used
+  --> $DIR/must-use-ops.rs:23:5
+   |
+LL |     val * 2;
+   |     ^^^^^^^ the arithmetic operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val * 2;
+   |     ^^^^^^^
+
+warning: unused arithmetic operation that must be used
+  --> $DIR/must-use-ops.rs:24:5
+   |
+LL |     val % 2;
+   |     ^^^^^^^ the arithmetic operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = val % 2;
+   |     ^^^^^^^
+
+warning: unused logical operation that must be used
+  --> $DIR/must-use-ops.rs:27:5
+   |
+LL |     true && true;
+   |     ^^^^^^^^^^^^ the logical operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = true && true;
+   |     ^^^^^^^
+
+warning: unused logical operation that must be used
+  --> $DIR/must-use-ops.rs:28:5
+   |
+LL |     false || true;
+   |     ^^^^^^^^^^^^^ the logical operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = false || true;
+   |     ^^^^^^^
+
+warning: unused bitwise operation that must be used
+  --> $DIR/must-use-ops.rs:31:5
+   |
+LL |     5 ^ val;
+   |     ^^^^^^^ the bitwise operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 5 ^ val;
+   |     ^^^^^^^
+
+warning: unused bitwise operation that must be used
+  --> $DIR/must-use-ops.rs:32:5
+   |
+LL |     5 & val;
+   |     ^^^^^^^ the bitwise operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 5 & val;
+   |     ^^^^^^^
+
+warning: unused bitwise operation that must be used
+  --> $DIR/must-use-ops.rs:33:5
+   |
+LL |     5 | val;
+   |     ^^^^^^^ the bitwise operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 5 | val;
+   |     ^^^^^^^
+
+warning: unused bitwise operation that must be used
+  --> $DIR/must-use-ops.rs:34:5
+   |
+LL |     5 << val;
+   |     ^^^^^^^^ the bitwise operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 5 << val;
+   |     ^^^^^^^
+
+warning: unused bitwise operation that must be used
+  --> $DIR/must-use-ops.rs:35:5
+   |
+LL |     5 >> val;
+   |     ^^^^^^^^ the bitwise operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = 5 >> val;
+   |     ^^^^^^^
+
+warning: unused unary operation that must be used
+  --> $DIR/must-use-ops.rs:38:5
+   |
+LL |     !val;
+   |     ^^^^ the unary operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = !val;
+   |     ^^^^^^^
+
+warning: unused unary operation that must be used
+  --> $DIR/must-use-ops.rs:39:5
+   |
+LL |     -val;
+   |     ^^^^ the unary operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = -val;
+   |     ^^^^^^^
+
+warning: unused unary operation that must be used
+  --> $DIR/must-use-ops.rs:40:5
+   |
+LL |     *val_pointer;
+   |     ^^^^^^^^^^^^ the unary operation produces a value
+   |
+help: use `let _ = ...` to ignore the resulting value
+   |
+LL |     let _ = *val_pointer;
+   |     ^^^^^^^
+
+warning: 21 warnings emitted
+
diff --git a/src/test/ui/lint/must_use-array.rs b/src/test/ui/lint/unused/must_use-array.rs
index 97825dd2f6c..97825dd2f6c 100644
--- a/src/test/ui/lint/must_use-array.rs
+++ b/src/test/ui/lint/unused/must_use-array.rs
diff --git a/src/test/ui/lint/must_use-array.stderr b/src/test/ui/lint/unused/must_use-array.stderr
index c42223b5198..c42223b5198 100644
--- a/src/test/ui/lint/must_use-array.stderr
+++ b/src/test/ui/lint/unused/must_use-array.stderr
diff --git a/src/test/ui/lint/must_use-in-stdlib-traits.rs b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs
index 70dddf61fb7..70dddf61fb7 100644
--- a/src/test/ui/lint/must_use-in-stdlib-traits.rs
+++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.rs
diff --git a/src/test/ui/lint/must_use-in-stdlib-traits.stderr b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
index 76978d29dc8..76978d29dc8 100644
--- a/src/test/ui/lint/must_use-in-stdlib-traits.stderr
+++ b/src/test/ui/lint/unused/must_use-in-stdlib-traits.stderr
diff --git a/src/test/ui/lint/must_use-trait.rs b/src/test/ui/lint/unused/must_use-trait.rs
index 0aa751443a0..0aa751443a0 100644
--- a/src/test/ui/lint/must_use-trait.rs
+++ b/src/test/ui/lint/unused/must_use-trait.rs
diff --git a/src/test/ui/lint/must_use-trait.stderr b/src/test/ui/lint/unused/must_use-trait.stderr
index 11555d80825..11555d80825 100644
--- a/src/test/ui/lint/must_use-trait.stderr
+++ b/src/test/ui/lint/unused/must_use-trait.stderr
diff --git a/src/test/ui/lint/must_use-tuple.rs b/src/test/ui/lint/unused/must_use-tuple.rs
index 0f0aa20253c..0f0aa20253c 100644
--- a/src/test/ui/lint/must_use-tuple.rs
+++ b/src/test/ui/lint/unused/must_use-tuple.rs
diff --git a/src/test/ui/lint/must_use-tuple.stderr b/src/test/ui/lint/unused/must_use-tuple.stderr
index 0532d89e039..0532d89e039 100644
--- a/src/test/ui/lint/must_use-tuple.stderr
+++ b/src/test/ui/lint/unused/must_use-tuple.stderr
diff --git a/src/test/ui/lint/must_use-unit.rs b/src/test/ui/lint/unused/must_use-unit.rs
index 4dd4798abb7..4dd4798abb7 100644
--- a/src/test/ui/lint/must_use-unit.rs
+++ b/src/test/ui/lint/unused/must_use-unit.rs
diff --git a/src/test/ui/lint/must_use-unit.stderr b/src/test/ui/lint/unused/must_use-unit.stderr
index 7f25a193508..7f25a193508 100644
--- a/src/test/ui/lint/must_use-unit.stderr
+++ b/src/test/ui/lint/unused/must_use-unit.stderr
diff --git a/src/test/ui/lint/no-unused-parens-return-block.rs b/src/test/ui/lint/unused/no-unused-parens-return-block.rs
index 37dc519a204..37dc519a204 100644
--- a/src/test/ui/lint/no-unused-parens-return-block.rs
+++ b/src/test/ui/lint/unused/no-unused-parens-return-block.rs
diff --git a/src/test/ui/unused/unused-attr-macro-rules.rs b/src/test/ui/lint/unused/unused-attr-macro-rules.rs
index 396137a11d0..396137a11d0 100644
--- a/src/test/ui/unused/unused-attr-macro-rules.rs
+++ b/src/test/ui/lint/unused/unused-attr-macro-rules.rs
diff --git a/src/test/ui/unused/unused-attr-macro-rules.stderr b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr
index 4606be01ac0..4606be01ac0 100644
--- a/src/test/ui/unused/unused-attr-macro-rules.stderr
+++ b/src/test/ui/lint/unused/unused-attr-macro-rules.stderr
diff --git a/src/test/ui/unused/unused-attr.rs b/src/test/ui/lint/unused/unused-attr.rs
index cb8ac0e6a05..cb8ac0e6a05 100644
--- a/src/test/ui/unused/unused-attr.rs
+++ b/src/test/ui/lint/unused/unused-attr.rs
diff --git a/src/test/ui/unused/unused-attr.stderr b/src/test/ui/lint/unused/unused-attr.stderr
index 707521b7802..707521b7802 100644
--- a/src/test/ui/unused/unused-attr.stderr
+++ b/src/test/ui/lint/unused/unused-attr.stderr
diff --git a/src/test/ui/unused/unused-closure.rs b/src/test/ui/lint/unused/unused-closure.rs
index c96c907318c..c96c907318c 100644
--- a/src/test/ui/unused/unused-closure.rs
+++ b/src/test/ui/lint/unused/unused-closure.rs
diff --git a/src/test/ui/unused/unused-closure.stderr b/src/test/ui/lint/unused/unused-closure.stderr
index 265d3e8e075..265d3e8e075 100644
--- a/src/test/ui/unused/unused-closure.stderr
+++ b/src/test/ui/lint/unused/unused-closure.stderr
diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.rs b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs
index fd9baf8c6b9..fd9baf8c6b9 100644
--- a/src/test/ui/unused/unused-doc-comments-edge-cases.rs
+++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.rs
diff --git a/src/test/ui/unused/unused-doc-comments-edge-cases.stderr b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
index 14db5f64b0c..14db5f64b0c 100644
--- a/src/test/ui/unused/unused-doc-comments-edge-cases.stderr
+++ b/src/test/ui/lint/unused/unused-doc-comments-edge-cases.stderr
diff --git a/src/test/ui/unused/unused-doc-comments-for-macros.rs b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs
index 05828ebb2c3..05828ebb2c3 100644
--- a/src/test/ui/unused/unused-doc-comments-for-macros.rs
+++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.rs
diff --git a/src/test/ui/unused/unused-doc-comments-for-macros.stderr b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr
index f4f5bb71e55..f4f5bb71e55 100644
--- a/src/test/ui/unused/unused-doc-comments-for-macros.stderr
+++ b/src/test/ui/lint/unused/unused-doc-comments-for-macros.stderr
diff --git a/src/test/ui/unused/unused-macro-rules.rs b/src/test/ui/lint/unused/unused-macro-rules.rs
index 1a714b8f0a0..1a714b8f0a0 100644
--- a/src/test/ui/unused/unused-macro-rules.rs
+++ b/src/test/ui/lint/unused/unused-macro-rules.rs
diff --git a/src/test/ui/unused/unused-macro-rules.stderr b/src/test/ui/lint/unused/unused-macro-rules.stderr
index 55072bd81bf..55072bd81bf 100644
--- a/src/test/ui/unused/unused-macro-rules.stderr
+++ b/src/test/ui/lint/unused/unused-macro-rules.stderr
diff --git a/src/test/ui/unused/unused-macro-with-bad-frag-spec.rs b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs
index ce187047bb7..ce187047bb7 100644
--- a/src/test/ui/unused/unused-macro-with-bad-frag-spec.rs
+++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.rs
diff --git a/src/test/ui/unused/unused-macro-with-bad-frag-spec.stderr b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr
index 6edf0a2cf8d..6edf0a2cf8d 100644
--- a/src/test/ui/unused/unused-macro-with-bad-frag-spec.stderr
+++ b/src/test/ui/lint/unused/unused-macro-with-bad-frag-spec.stderr
diff --git a/src/test/ui/unused/unused-macro-with-follow-violation.rs b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs
index 1666dae69b9..1666dae69b9 100644
--- a/src/test/ui/unused/unused-macro-with-follow-violation.rs
+++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.rs
diff --git a/src/test/ui/unused/unused-macro-with-follow-violation.stderr b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr
index 5eced4f06c0..5eced4f06c0 100644
--- a/src/test/ui/unused/unused-macro-with-follow-violation.stderr
+++ b/src/test/ui/lint/unused/unused-macro-with-follow-violation.stderr
diff --git a/src/test/ui/unused/unused-macro.rs b/src/test/ui/lint/unused/unused-macro.rs
index 302b0727d77..302b0727d77 100644
--- a/src/test/ui/unused/unused-macro.rs
+++ b/src/test/ui/lint/unused/unused-macro.rs
diff --git a/src/test/ui/unused/unused-macro.stderr b/src/test/ui/lint/unused/unused-macro.stderr
index f5eb76179bf..f5eb76179bf 100644
--- a/src/test/ui/unused/unused-macro.stderr
+++ b/src/test/ui/lint/unused/unused-macro.stderr
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.fixed b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed
index c21f18015c1..c21f18015c1 100644
--- a/src/test/ui/unused/unused-mut-warning-captured-var.fixed
+++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.fixed
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.rs b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs
index 3119d83a0eb..3119d83a0eb 100644
--- a/src/test/ui/unused/unused-mut-warning-captured-var.rs
+++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.rs
diff --git a/src/test/ui/unused/unused-mut-warning-captured-var.stderr b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr
index 20aeedcc241..20aeedcc241 100644
--- a/src/test/ui/unused/unused-mut-warning-captured-var.stderr
+++ b/src/test/ui/lint/unused/unused-mut-warning-captured-var.stderr
diff --git a/src/test/ui/unused/unused-result.rs b/src/test/ui/lint/unused/unused-result.rs
index a65e98990dc..a65e98990dc 100644
--- a/src/test/ui/unused/unused-result.rs
+++ b/src/test/ui/lint/unused/unused-result.rs
diff --git a/src/test/ui/unused/unused-result.stderr b/src/test/ui/lint/unused/unused-result.stderr
index 1b1dcab3a1b..1b1dcab3a1b 100644
--- a/src/test/ui/unused/unused-result.stderr
+++ b/src/test/ui/lint/unused/unused-result.stderr
diff --git a/src/test/ui/unused/useless-comment.rs b/src/test/ui/lint/unused/useless-comment.rs
index 7d2e5ab6f2b..7d2e5ab6f2b 100644
--- a/src/test/ui/unused/useless-comment.rs
+++ b/src/test/ui/lint/unused/useless-comment.rs
diff --git a/src/test/ui/unused/useless-comment.stderr b/src/test/ui/lint/unused/useless-comment.stderr
index 0054426fb1e..0054426fb1e 100644
--- a/src/test/ui/unused/useless-comment.stderr
+++ b/src/test/ui/lint/unused/useless-comment.stderr
diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs
index 13e179578ad..d09fdf118e6 100644
--- a/src/test/ui/macros/macro-context.rs
+++ b/src/test/ui/macros/macro-context.rs
@@ -6,6 +6,8 @@ macro_rules! m {
                             //~| ERROR macro expansion ignores token `;`
                             //~| ERROR cannot find type `i` in this scope
                             //~| ERROR cannot find value `i` in this scope
+                            //~| WARN trailing semicolon in macro
+                            //~| WARN this was previously
 }
 
 fn main() {
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index 5ed73b7fb93..3b8a6f17491 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -64,7 +64,21 @@ LL |     let i = m!();
    |
    = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-context.rs:3:15
+   |
+LL |     () => ( i ; typeof );
+   |               ^
+...
+LL |     let i = m!();
+   |             ---- in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0412, E0425.
 For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/macros/macro-in-expression-context.fixed b/src/test/ui/macros/macro-in-expression-context.fixed
index df36db0f49e..f22caf2793f 100644
--- a/src/test/ui/macros/macro-in-expression-context.fixed
+++ b/src/test/ui/macros/macro-in-expression-context.fixed
@@ -3,6 +3,12 @@
 macro_rules! foo {
     () => {
         assert_eq!("A", "A");
+        //~^ WARN trailing semicolon in macro
+        //~| WARN this was previously
+        //~| NOTE macro invocations at the end of a block
+        //~| NOTE to ignore the value produced by the macro
+        //~| NOTE for more information
+        //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
         assert_eq!("B", "B");
     }
     //~^^ ERROR macro expansion ignores token `assert_eq` and any following
@@ -12,4 +18,10 @@ macro_rules! foo {
 fn main() {
     foo!();
     //~^ NOTE caused by the macro expansion here
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
 }
diff --git a/src/test/ui/macros/macro-in-expression-context.rs b/src/test/ui/macros/macro-in-expression-context.rs
index b3f5e568967..1a056e582ff 100644
--- a/src/test/ui/macros/macro-in-expression-context.rs
+++ b/src/test/ui/macros/macro-in-expression-context.rs
@@ -3,6 +3,12 @@
 macro_rules! foo {
     () => {
         assert_eq!("A", "A");
+        //~^ WARN trailing semicolon in macro
+        //~| WARN this was previously
+        //~| NOTE macro invocations at the end of a block
+        //~| NOTE to ignore the value produced by the macro
+        //~| NOTE for more information
+        //~| NOTE `#[warn(semicolon_in_expressions_from_macros)]` on by default
         assert_eq!("B", "B");
     }
     //~^^ ERROR macro expansion ignores token `assert_eq` and any following
@@ -12,4 +18,10 @@ macro_rules! foo {
 fn main() {
     foo!()
     //~^ NOTE caused by the macro expansion here
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
+    //~| NOTE in this expansion
 }
diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr
index d27d6fbaef7..1840babd61d 100644
--- a/src/test/ui/macros/macro-in-expression-context.stderr
+++ b/src/test/ui/macros/macro-in-expression-context.stderr
@@ -1,5 +1,5 @@
 error: macro expansion ignores token `assert_eq` and any following
-  --> $DIR/macro-in-expression-context.rs:6:9
+  --> $DIR/macro-in-expression-context.rs:12:9
    |
 LL |         assert_eq!("B", "B");
    |         ^^^^^^^^^
@@ -11,5 +11,21 @@ LL |     foo!()
    |
    = note: the usage of `foo!` is likely invalid in expression context
 
-error: aborting due to previous error
+warning: trailing semicolon in macro used in expression position
+  --> $DIR/macro-in-expression-context.rs:5:29
+   |
+LL |         assert_eq!("A", "A");
+   |                             ^
+...
+LL |     foo!()
+   |     ------ in this macro invocation
+   |
+   = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #79813 <https://github.com/rust-lang/rust/issues/79813>
+   = note: macro invocations at the end of a block are treated as expressions
+   = note: to ignore the value produced by the macro, add a semicolon after the invocation of `foo`
+   = note: this warning originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error; 1 warning emitted
 
diff --git a/src/test/ui/mismatched_types/abridged.stderr b/src/test/ui/mismatched_types/abridged.stderr
index 61994e5bfee..7697a375fd8 100644
--- a/src/test/ui/mismatched_types/abridged.stderr
+++ b/src/test/ui/mismatched_types/abridged.stderr
@@ -78,10 +78,12 @@ error[E0308]: mismatched types
 LL | fn f() -> String {
    |           ------ expected `String` because of return type
 LL |     1+2
-   |     ^^^
-   |     |
-   |     expected struct `String`, found integer
-   |     help: try using a conversion method: `(1+2).to_string()`
+   |     ^^^ expected struct `String`, found integer
+   |
+help: try using a conversion method
+   |
+LL |     (1+2).to_string()
+   |     ^   ^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/abridged.rs:59:5
@@ -89,10 +91,12 @@ error[E0308]: mismatched types
 LL | fn g() -> String {
    |           ------ expected `String` because of return type
 LL |     -2
-   |     ^^
-   |     |
-   |     expected struct `String`, found integer
-   |     help: try using a conversion method: `(-2).to_string()`
+   |     ^^ expected struct `String`, found integer
+   |
+help: try using a conversion method
+   |
+LL |     (-2).to_string()
+   |     ^  ^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr
index 26ab5f43a27..3453f031623 100644
--- a/src/test/ui/never_type/issue-52443.stderr
+++ b/src/test/ui/never_type/issue-52443.stderr
@@ -19,13 +19,14 @@ error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:2:10
    |
 LL |     [(); & { loop { continue } } ];
-   |          ^^^^^^^^^^^^^^^^^^^^^^^
-   |          |
-   |          expected `usize`, found reference
-   |          help: consider removing the borrow: `{ loop { continue } }`
+   |          ^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found reference
    |
    = note:   expected type `usize`
            found reference `&_`
+help: consider removing the borrow
+   |
+LL |     [(); { loop { continue } } ];
+   |         --
 
 error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:4:17
diff --git a/src/test/ui/occurs-check-2.stderr b/src/test/ui/occurs-check-2.stderr
index 7f93697c6f7..b2c8775e78c 100644
--- a/src/test/ui/occurs-check-2.stderr
+++ b/src/test/ui/occurs-check-2.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/occurs-check-2.rs:7:9
    |
 LL |     f = box g;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box g).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box g).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/occurs-check.stderr b/src/test/ui/occurs-check.stderr
index 01e2b1f7749..a657106ad91 100644
--- a/src/test/ui/occurs-check.stderr
+++ b/src/test/ui/occurs-check.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/occurs-check.rs:5:9
    |
 LL |     f = box f;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box f).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box f).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/packed/issue-27060-2.stderr b/src/test/ui/packed/issue-27060-2.stderr
index 5dbcc96e874..64e061a89b4 100644
--- a/src/test/ui/packed/issue-27060-2.stderr
+++ b/src/test/ui/packed/issue-27060-2.stderr
@@ -8,6 +8,10 @@ LL |     data: T,
    |
    = note: the last field of a packed struct may only have a dynamically sized type if it does not need drop to be run
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | pub struct Bad<T> {
+   |                --
 help: borrowed types always have a statically known size
    |
 LL |     data: &T,
diff --git a/src/test/ui/parser/expr-as-stmt-2.stderr b/src/test/ui/parser/expr-as-stmt-2.stderr
index 2a701274857..affcb6ed224 100644
--- a/src/test/ui/parser/expr-as-stmt-2.stderr
+++ b/src/test/ui/parser/expr-as-stmt-2.stderr
@@ -31,12 +31,15 @@ error[E0308]: mismatched types
    |
 LL |   fn foo(a: Option<u32>, b: Option<u32>) -> bool {
    |                                             ---- expected `bool` because of return type
-LL |       if let Some(x) = a { true } else { false }
-   |       ------------------------------------------ help: parentheses are required to parse this as an expression: `(if let Some(x) = a { true } else { false })`
 ...
 LL | /     &&
 LL | |     if let Some(y) = a { true } else { false }
    | |______________________________________________^ expected `bool`, found `&&bool`
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     (if let Some(x) = a { true } else { false })
+   |     ^                                          ^
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index 067b7edc770..2bb320e7321 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -2,25 +2,34 @@ error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:8:9
    |
 LL |     {2} + {2}
-   |     --- ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({2})`
+   |         ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({2}) + {2}
+   |     ^   ^
 
 error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:13:9
    |
 LL |     {2} + 2
-   |     --- ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({2})`
+   |         ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({2}) + 2
+   |     ^   ^
 
 error: expected expression, found `+`
   --> $DIR/expr-as-stmt.rs:19:12
    |
 LL |     { 42 } + foo;
-   |     ------ ^ expected expression
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({ 42 })`
+   |            ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({ 42 }) + foo;
+   |     ^      ^
 
 error: expected expression, found `>`
   --> $DIR/expr-as-stmt.rs:32:7
@@ -83,9 +92,12 @@ error[E0614]: type `{integer}` cannot be dereferenced
   --> $DIR/expr-as-stmt.rs:25:11
    |
 LL |     { 3 } * 3
-   |     ----- ^^^
-   |     |
-   |     help: parentheses are required to parse this as an expression: `({ 3 })`
+   |           ^^^
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     ({ 3 }) * 3
+   |     ^     ^
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs
index 2f5af10a40a..04d34e21cdc 100644
--- a/src/test/ui/proc-macro/nested-nonterminal-tokens.rs
+++ b/src/test/ui/proc-macro/nested-nonterminal-tokens.rs
@@ -17,7 +17,7 @@ macro_rules! wrap {
     (first, $e:expr) => { wrap!(second, $e + 1) };
     (second, $e:expr) => { wrap!(third, $e + 2) };
     (third, $e:expr) => {
-        print_bang!($e + 3);
+        print_bang!($e + 3)
     };
 }
 
diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
index 328e602ca76..4bd16c71137 100644
--- a/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
+++ b/src/test/ui/regions/region-borrow-params-issue-29793-big.stderr
@@ -14,7 +14,7 @@ LL |         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
-   |                          ^^^^^^^^^^^^^^
+   |                          ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-big.rs:67:26
@@ -32,7 +32,7 @@ LL |         WrapB::new().set(|t: bool| if t { x } else { y }) // (separate erro
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         WrapB::new().set(move |t: bool| if t { x } else { y }) // (separate errors for `x` vs `y`)
-   |                          ^^^^^^^^^^^^^^
+   |                          ^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
index 18610b7cffb..f70e4ea9fbc 100644
--- a/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
+++ b/src/test/ui/regions/region-borrow-params-issue-29793-small.stderr
@@ -14,7 +14,7 @@ LL |         return f;
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:9:17
@@ -32,7 +32,7 @@ LL |         return f;
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:24:17
@@ -50,7 +50,7 @@ LL |         f
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:24:17
@@ -68,7 +68,7 @@ LL |         f
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:55:17
@@ -86,7 +86,7 @@ LL |         return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:55:17
@@ -104,7 +104,7 @@ LL |         return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:66:17
@@ -122,7 +122,7 @@ LL |         Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:66:17
@@ -140,7 +140,7 @@ LL |         Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |         let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                 ^^^^^^^^^^^^^^
+   |                 ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:90:21
@@ -158,7 +158,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:90:21
@@ -176,7 +176,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:104:21
@@ -194,7 +194,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:104:21
@@ -212,7 +212,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:132:21
@@ -230,7 +230,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:132:21
@@ -248,7 +248,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:147:21
@@ -266,7 +266,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:147:21
@@ -284,7 +284,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:175:21
@@ -302,7 +302,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:175:21
@@ -320,7 +320,7 @@ LL |             return Box::new(f);
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:189:21
@@ -338,7 +338,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `x` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error[E0373]: closure may outlive the current function, but it borrows `y`, which is owned by the current function
   --> $DIR/region-borrow-params-issue-29793-small.rs:189:21
@@ -356,7 +356,7 @@ LL |             Box::new(f)
 help: to force the closure to take ownership of `y` (and any other referenced variables), use the `move` keyword
    |
 LL |             let f = move |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`)
-   |                     ^^^^^^^^^^^^^^
+   |                     ^^^^
 
 error: aborting due to 20 previous errors
 
diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
index 4950b654141..23eabfa3b3e 100644
--- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
+++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr
@@ -478,10 +478,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:32:8
    |
 LL |     if &let 0 = 0 {}
-   |        ^^^^^^^^^^
-   |        |
-   |        expected `bool`, found `&bool`
-   |        help: consider removing the borrow: `let 0 = 0`
+   |        ^^^^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     if let 0 = 0 {}
+   |       --
 
 error[E0614]: type `bool` cannot be dereferenced
   --> $DIR/disallowed-positions.rs:36:8
@@ -678,10 +680,12 @@ error[E0308]: mismatched types
   --> $DIR/disallowed-positions.rs:96:11
    |
 LL |     while &let 0 = 0 {}
-   |           ^^^^^^^^^^
-   |           |
-   |           expected `bool`, found `&bool`
-   |           help: consider removing the borrow: `let 0 = 0`
+   |           ^^^^^^^^^^ expected `bool`, found `&bool`
+   |
+help: consider removing the borrow
+   |
+LL |     while let 0 = 0 {}
+   |          --
 
 error[E0614]: type `bool` cannot be dereferenced
   --> $DIR/disallowed-positions.rs:100:11
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
new file mode 100644
index 00000000000..f0d8cb944cf
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+    fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+        todo!()
+    }
+}
+
+fn main() {
+    <Generic<_, _> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    <Generic::<i32, i32> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    <Generic::<_, _> as MyFromIter>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
new file mode 100644
index 00000000000..19840537059
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
@@ -0,0 +1,37 @@
+// test for https://github.com/rust-lang/rust/issues/86940
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+struct Generic<T, U>(T, U);
+
+trait MyFromIter {
+    fn from_iter(_: i32) -> Self;
+}
+
+impl MyFromIter for Generic<i32, i32> {
+    fn from_iter(x: i32) -> Self {
+        Self(x, x)
+    }
+}
+
+impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+    fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
+        todo!()
+    }
+}
+
+fn main() {
+    Generic::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    Generic::<i32, i32>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+    Generic::<_, _>::from_iter(1);
+    //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
+    //~| this is accepted in the current edition (Rust 2018)
+}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
new file mode 100644
index 00000000000..2c6a63df42f
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
@@ -0,0 +1,34 @@
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:28:5
+   |
+LL |     Generic::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
+   |
+note: the lint level is defined here
+  --> $DIR/future-prelude-collision-generic.rs:5:9
+   |
+LL | #![warn(rust_2021_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:31:5
+   |
+LL |     Generic::<i32, i32>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic.rs:34:5
+   |
+LL |     Generic::<_, _>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see issue #85684 <https://github.com/rust-lang/rust/issues/85684>
+
+warning: 3 warnings emitted
+
diff --git a/src/test/ui/prelude2021.rs b/src/test/ui/rust-2021/prelude2021.rs
index 3a9fd693228..3a9fd693228 100644
--- a/src/test/ui/prelude2021.rs
+++ b/src/test/ui/rust-2021/prelude2021.rs
diff --git a/src/test/ui/span/coerce-suggestions.stderr b/src/test/ui/span/coerce-suggestions.stderr
index 0e40ca67351..2595cd91dc1 100644
--- a/src/test/ui/span/coerce-suggestions.stderr
+++ b/src/test/ui/span/coerce-suggestions.stderr
@@ -38,10 +38,12 @@ error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:17:9
    |
 LL |     f = box f;
-   |         ^^^^^
-   |         |
-   |         cyclic type of infinite size
-   |         help: try using a conversion method: `(box f).to_string()`
+   |         ^^^^^ cyclic type of infinite size
+   |
+help: try using a conversion method
+   |
+LL |     f = (box f).to_string();
+   |         ^     ^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/coerce-suggestions.rs:21:9
diff --git a/src/test/ui/static/bad-const-type.stderr b/src/test/ui/static/bad-const-type.stderr
index a9c84b4b41c..dcc1ee07cbd 100644
--- a/src/test/ui/static/bad-const-type.stderr
+++ b/src/test/ui/static/bad-const-type.stderr
@@ -2,10 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/bad-const-type.rs:1:20
    |
 LL | static i: String = 10;
-   |                    ^^
+   |                    ^^- help: try using a conversion method: `.to_string()`
    |                    |
    |                    expected struct `String`, found integer
-   |                    help: try using a conversion method: `10.to_string()`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/str/str-lit-type-mismatch.stderr b/src/test/ui/str/str-lit-type-mismatch.stderr
index 64ddfcc9b47..e8e2c4e24f5 100644
--- a/src/test/ui/str/str-lit-type-mismatch.stderr
+++ b/src/test/ui/str/str-lit-type-mismatch.stderr
@@ -2,40 +2,46 @@ error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:2:20
    |
 LL |     let x: &[u8] = "foo";
-   |            -----   ^^^^^
-   |            |       |
-   |            |       expected slice `[u8]`, found `str`
-   |            |       help: consider adding a leading `b`: `b"foo"`
+   |            -----   ^^^^^ expected slice `[u8]`, found `str`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&[u8]`
               found reference `&'static str`
+help: consider adding a leading `b`
+   |
+LL |     let x: &[u8] = b"foo";
+   |                    ^
 
 error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:3:23
    |
 LL |     let y: &[u8; 4] = "baaa";
-   |            --------   ^^^^^^
-   |            |          |
-   |            |          expected array `[u8; 4]`, found `str`
-   |            |          help: consider adding a leading `b`: `b"baaa"`
+   |            --------   ^^^^^^ expected array `[u8; 4]`, found `str`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&[u8; 4]`
               found reference `&'static str`
+help: consider adding a leading `b`
+   |
+LL |     let y: &[u8; 4] = b"baaa";
+   |                       ^
 
 error[E0308]: mismatched types
   --> $DIR/str-lit-type-mismatch.rs:4:19
    |
 LL |     let z: &str = b"foo";
-   |            ----   ^^^^^^
-   |            |      |
-   |            |      expected `str`, found array `[u8; 3]`
-   |            |      help: consider removing the leading `b`: `"foo"`
+   |            ----   ^^^^^^ expected `str`, found array `[u8; 3]`
+   |            |
    |            expected due to this
    |
    = note: expected reference `&str`
               found reference `&'static [u8; 3]`
+help: consider removing the leading `b`
+   |
+LL |     let z: &str = "foo";
+   |                  --
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
index 18ba7254446..ac3902dc6de 100644
--- a/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
+++ b/src/test/ui/suggestions/adt-param-with-implicit-sized-bound.stderr
@@ -91,6 +91,10 @@ LL | struct X<T>(T);
    |          ^  - ...if indirection were used here: `Box<T>`
    |          |
    |          this could be changed to `T: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | struct Struct5<T>{
+   |                --
 
 error: aborting due to 5 previous errors
 
diff --git a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
index d5d51324e63..119599c22a6 100644
--- a/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
+++ b/src/test/ui/suggestions/expected-boxed-future-isnt-pinned.stderr
@@ -5,13 +5,14 @@ LL | fn foo<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static,
    |        - this type parameter                            ----------------------- expected `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>` because of return type
 LL |     // We could instead use an `async` block, but this way we have no std spans.
 LL |     x
-   |     ^
-   |     |
-   |     expected struct `Pin`, found type parameter `F`
-   |     help: you need to pin and box this expression: `Box::pin(x)`
+   |     ^ expected struct `Pin`, found type parameter `F`
    |
    = note:      expected struct `Pin<Box<(dyn Future<Output = i32> + Send + 'static)>>`
            found type parameter `F`
+help: you need to pin and box this expression
+   |
+LL |     Box::pin(x)
+   |     ^^^^^^^^^ ^
 
 error[E0308]: mismatched types
   --> $DIR/expected-boxed-future-isnt-pinned.rs:18:5
@@ -31,14 +32,15 @@ error[E0308]: mismatched types
 LL | fn baz<F: Future<Output=i32> + Send + 'static>(x: F) -> BoxFuture<'static, i32> {
    |        - this type parameter
 LL |     Pin::new(x)
-   |              ^
-   |              |
-   |              expected struct `Box`, found type parameter `F`
-   |              help: store this in the heap by calling `Box::new`: `Box::new(x)`
+   |              ^ expected struct `Box`, found type parameter `F`
    |
    = note:      expected struct `Box<dyn Future<Output = i32> + Send>`
            found type parameter `F`
    = note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
+help: store this in the heap by calling `Box::new`
+   |
+LL |     Pin::new(Box::new(x))
+   |              ^^^^^^^^^ ^
 
 error[E0277]: `dyn Future<Output = i32> + Send` cannot be unpinned
   --> $DIR/expected-boxed-future-isnt-pinned.rs:22:5
diff --git a/src/test/ui/suggestions/for-i-in-vec.fixed b/src/test/ui/suggestions/for-i-in-vec.fixed
index ec7358bd08a..223ddf0f0ad 100644
--- a/src/test/ui/suggestions/for-i-in-vec.fixed
+++ b/src/test/ui/suggestions/for-i-in-vec.fixed
@@ -3,12 +3,15 @@
 
 struct Foo {
     v: Vec<u32>,
+    h: std::collections::HashMap<i32, i32>,
 }
 
 impl Foo {
     fn bar(&self) {
         for _ in &self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
         }
+        for _ in &self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
+        }
     }
 }
 
diff --git a/src/test/ui/suggestions/for-i-in-vec.rs b/src/test/ui/suggestions/for-i-in-vec.rs
index 304fe8cc81f..7942698cc8e 100644
--- a/src/test/ui/suggestions/for-i-in-vec.rs
+++ b/src/test/ui/suggestions/for-i-in-vec.rs
@@ -3,12 +3,15 @@
 
 struct Foo {
     v: Vec<u32>,
+    h: std::collections::HashMap<i32, i32>,
 }
 
 impl Foo {
     fn bar(&self) {
         for _ in self.v { //~ ERROR cannot move out of `self.v` which is behind a shared reference
         }
+        for _ in self.h { //~ ERROR cannot move out of `self.h` which is behind a shared reference
+        }
     }
 }
 
diff --git a/src/test/ui/suggestions/for-i-in-vec.stderr b/src/test/ui/suggestions/for-i-in-vec.stderr
index 48f3f423ac6..011fdf34c28 100644
--- a/src/test/ui/suggestions/for-i-in-vec.stderr
+++ b/src/test/ui/suggestions/for-i-in-vec.stderr
@@ -1,12 +1,25 @@
 error[E0507]: cannot move out of `self.v` which is behind a shared reference
-  --> $DIR/for-i-in-vec.rs:10:18
+  --> $DIR/for-i-in-vec.rs:11:18
    |
 LL |         for _ in self.v {
-   |                  ^^^^^^
-   |                  |
-   |                  move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
-   |                  help: consider iterating over a slice of the `Vec<_>`'s content: `&self.v`
+   |                  ^^^^^^ move occurs because `self.v` has type `Vec<u32>`, which does not implement the `Copy` trait
+   |
+help: consider iterating over a slice of the `Vec<u32>`'s content
+   |
+LL |         for _ in &self.v {
+   |                  ^
+
+error[E0507]: cannot move out of `self.h` which is behind a shared reference
+  --> $DIR/for-i-in-vec.rs:13:18
+   |
+LL |         for _ in self.h {
+   |                  ^^^^^^ move occurs because `self.h` has type `HashMap<i32, i32>`, which does not implement the `Copy` trait
+   |
+help: consider iterating over a slice of the `HashMap<i32, i32>`'s content
+   |
+LL |         for _ in &self.h {
+   |                  ^
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/suggestions/format-borrow.stderr b/src/test/ui/suggestions/format-borrow.stderr
index 0881b024712..15cb845a06d 100644
--- a/src/test/ui/suggestions/format-borrow.stderr
+++ b/src/test/ui/suggestions/format-borrow.stderr
@@ -2,41 +2,53 @@ error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:2:21
    |
 LL |     let a: String = &String::from("a");
-   |            ------   ^^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&String`
-   |            |        help: consider removing the borrow: `String::from("a")`
+   |            ------   ^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let a: String = String::from("a");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:4:21
    |
 LL |     let b: String = &format!("b");
-   |            ------   ^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&String`
-   |            |        help: consider removing the borrow: `format!("b")`
+   |            ------   ^^^^^^^^^^^^^ expected struct `String`, found `&String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let b: String = format!("b");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:6:21
    |
 LL |     let c: String = &mut format!("c");
-   |            ------   ^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&mut String`
-   |            |        help: consider removing the borrow: `format!("c")`
+   |            ------   ^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let c: String = format!("c");
+   |                    --
 
 error[E0308]: mismatched types
   --> $DIR/format-borrow.rs:8:21
    |
 LL |     let d: String = &mut (format!("d"));
-   |            ------   ^^^^^^^^^^^^^^^^^^^
-   |            |        |
-   |            |        expected struct `String`, found `&mut String`
-   |            |        help: consider removing the borrow: `format!("d")`
+   |            ------   ^^^^^^^^^^^^^^^^^^^ expected struct `String`, found `&mut String`
+   |            |
    |            expected due to this
+   |
+help: consider removing the borrow
+   |
+LL |     let d: String = format!("d"));
+   |                    --
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/suggestions/issue-52820.stderr b/src/test/ui/suggestions/issue-52820.stderr
index ece784de3e2..62c04584d3c 100644
--- a/src/test/ui/suggestions/issue-52820.stderr
+++ b/src/test/ui/suggestions/issue-52820.stderr
@@ -2,10 +2,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-52820.rs:9:9
    |
 LL |         guts,
-   |         ^^^^
-   |         |
-   |         expected struct `String`, found `&str`
-   |         help: try using a conversion method: `guts: guts.to_string()`
+   |         ^^^^ expected struct `String`, found `&str`
+   |
+help: try using a conversion method
+   |
+LL |         guts: guts.to_string(),
+   |         ^^^^^     ^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-52820.rs:10:17
diff --git a/src/test/ui/suggestions/issue-59819.stderr b/src/test/ui/suggestions/issue-59819.stderr
index 43e0016ee20..ac9b6d975f4 100644
--- a/src/test/ui/suggestions/issue-59819.stderr
+++ b/src/test/ui/suggestions/issue-59819.stderr
@@ -2,30 +2,35 @@ error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:28:18
    |
 LL |     let y: i32 = x;
-   |            ---   ^
-   |            |     |
-   |            |     expected `i32`, found struct `Foo`
-   |            |     help: consider dereferencing the type: `*x`
+   |            ---   ^ expected `i32`, found struct `Foo`
+   |            |
    |            expected due to this
+   |
+help: consider dereferencing the type
+   |
+LL |     let y: i32 = *x;
+   |                  ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:30:18
    |
 LL |     let b: i32 = a;
-   |            ---   ^
-   |            |     |
-   |            |     expected `i32`, found `&{integer}`
-   |            |     help: consider dereferencing the borrow: `*a`
+   |            ---   ^ expected `i32`, found `&{integer}`
+   |            |
    |            expected due to this
+   |
+help: consider dereferencing the borrow
+   |
+LL |     let b: i32 = *a;
+   |                  ^
 
 error[E0308]: mismatched types
   --> $DIR/issue-59819.rs:34:21
    |
 LL |     let g: String = f;
-   |            ------   ^
+   |            ------   ^- help: try using a conversion method: `.to_string()`
    |            |        |
    |            |        expected struct `String`, found struct `Bar`
-   |            |        help: try using a conversion method: `f.to_string()`
    |            expected due to this
 
 error: aborting due to 3 previous errors
diff --git a/src/test/ui/suggestions/issue-82361.stderr b/src/test/ui/suggestions/issue-82361.stderr
index 4c78293ebb7..91b380e4e0d 100644
--- a/src/test/ui/suggestions/issue-82361.stderr
+++ b/src/test/ui/suggestions/issue-82361.stderr
@@ -6,12 +6,14 @@ LL | |         a
    | |         - expected because of this
 LL | |     } else {
 LL | |         b
-   | |         ^
-   | |         |
-   | |         expected `usize`, found `&usize`
-   | |         help: consider dereferencing the borrow: `*b`
+   | |         ^ expected `usize`, found `&usize`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider dereferencing the borrow
+   |
+LL |         *b
+   |         ^
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/issue-82361.rs:16:9
@@ -21,12 +23,14 @@ LL | |         1
    | |         - expected because of this
 LL | |     } else {
 LL | |         &1
-   | |         ^^
-   | |         |
-   | |         expected integer, found `&{integer}`
-   | |         help: consider removing the borrow: `1`
+   | |         ^^ expected integer, found `&{integer}`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider removing the borrow
+   |
+LL |         1
+   |        --
 
 error[E0308]: `if` and `else` have incompatible types
   --> $DIR/issue-82361.rs:22:9
@@ -36,12 +40,14 @@ LL | |         1
    | |         - expected because of this
 LL | |     } else {
 LL | |         &mut 1
-   | |         ^^^^^^
-   | |         |
-   | |         expected integer, found `&mut {integer}`
-   | |         help: consider removing the borrow: `1`
+   | |         ^^^^^^ expected integer, found `&mut {integer}`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
+   |
+help: consider removing the borrow
+   |
+LL |         1
+   |        --
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/suggestions/issue-83943.stderr b/src/test/ui/suggestions/issue-83943.stderr
index a26700ea3c7..885106e8429 100644
--- a/src/test/ui/suggestions/issue-83943.stderr
+++ b/src/test/ui/suggestions/issue-83943.stderr
@@ -6,10 +6,9 @@ LL | |         "A".to_string()
    | |         --------------- expected because of this
 LL | |     } else {
 LL | |         "B"
-   | |         ^^^
+   | |         ^^^- help: try using a conversion method: `.to_string()`
    | |         |
    | |         expected struct `String`, found `&str`
-   | |         help: try using a conversion method: `"B".to_string()`
 LL | |     };
    | |_____- `if` and `else` have incompatible types
 
diff --git a/src/test/ui/suggestions/mut-ref-reassignment.stderr b/src/test/ui/suggestions/mut-ref-reassignment.stderr
index 327bbee1968..13b6182c0f5 100644
--- a/src/test/ui/suggestions/mut-ref-reassignment.stderr
+++ b/src/test/ui/suggestions/mut-ref-reassignment.stderr
@@ -9,7 +9,7 @@ LL |     opt = None;
 help: consider dereferencing here to assign to the mutable borrowed piece of memory
    |
 LL |     *opt = None;
-   |     ^^^^
+   |     ^
 
 error[E0308]: mismatched types
   --> $DIR/mut-ref-reassignment.rs:6:11
@@ -31,7 +31,7 @@ LL |     opt = Some(String::new())
 help: consider dereferencing here to assign to the mutable borrowed piece of memory
    |
 LL |     *opt = Some(String::new())
-   |     ^^^^
+   |     ^
 
 error[E0308]: mismatched types
   --> $DIR/mut-ref-reassignment.rs:14:11
diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr
index c00a0f1700b..94766530091 100644
--- a/src/test/ui/suggestions/option-content-move.stderr
+++ b/src/test/ui/suggestions/option-content-move.stderr
@@ -2,19 +2,23 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
   --> $DIR/option-content-move.rs:11:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^
-   |                    |
-   |                    move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
-   |                    help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
+   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the `Option`'s content
+   |
+LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
+   |                               ^^^^^^^^^
 
 error[E0507]: cannot move out of `selection.1` which is behind a shared reference
   --> $DIR/option-content-move.rs:29:20
    |
 LL |                 if selection.1.unwrap().contains(selection.0) {
-   |                    ^^^^^^^^^^^
-   |                    |
-   |                    move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
-   |                    help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
+   |                    ^^^^^^^^^^^ move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
+   |
+help: consider borrowing the `Result`'s content
+   |
+LL |                 if selection.1.as_ref().unwrap().contains(selection.0) {
+   |                               ^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/suggestions/raw-byte-string-prefix.rs b/src/test/ui/suggestions/raw-byte-string-prefix.rs
new file mode 100644
index 00000000000..576561c315c
--- /dev/null
+++ b/src/test/ui/suggestions/raw-byte-string-prefix.rs
@@ -0,0 +1,10 @@
+// `br` and `rb` are easy to confuse; check that we issue a suggestion to help.
+
+// edition:2021
+
+fn main() {
+    rb"abc";
+    //~^ ERROR: prefix `rb` is unknown
+    //~| HELP: use `br` for a raw byte string
+    //~| ERROR: expected one of
+}
diff --git a/src/test/ui/suggestions/raw-byte-string-prefix.stderr b/src/test/ui/suggestions/raw-byte-string-prefix.stderr
new file mode 100644
index 00000000000..1498f5ac935
--- /dev/null
+++ b/src/test/ui/suggestions/raw-byte-string-prefix.stderr
@@ -0,0 +1,20 @@
+error: prefix `rb` is unknown
+  --> $DIR/raw-byte-string-prefix.rs:6:5
+   |
+LL |     rb"abc";
+   |     ^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: use `br` for a raw byte string
+   |
+LL |     br"abc";
+   |     ^^
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `"abc"`
+  --> $DIR/raw-byte-string-prefix.rs:6:7
+   |
+LL |     rb"abc";
+   |       ^^^^^ expected one of 8 possible tokens
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/trait-bounds/unsized-bound.rs b/src/test/ui/trait-bounds/unsized-bound.rs
new file mode 100644
index 00000000000..035b8ef1bde
--- /dev/null
+++ b/src/test/ui/trait-bounds/unsized-bound.rs
@@ -0,0 +1,32 @@
+trait Trait<A> {}
+impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+//~^ ERROR E0277
+//~| ERROR E0277
+impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+//~^ ERROR E0277
+//~| ERROR E0277
+//~| ERROR E0277
+trait Trait2<A> {}
+impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+//~^ ERROR E0277
+//~| ERROR E0277
+trait Trait3<A> {}
+impl<A> Trait3<A> for A where A: ?Sized {}
+//~^ ERROR E0277
+trait Trait4<A> {}
+impl<A: ?Sized> Trait4<A> for A {}
+//~^ ERROR E0277
+trait Trait5<A, B> {}
+impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
+//~^ ERROR E0277
+trait Trait6<A, B> {}
+impl<X: ?Sized, Y> Trait6<X, Y> for X {}
+//~^ ERROR E0277
+trait Trait7<A, B> {}
+impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
+//~^ ERROR E0277
+trait Trait8<A, B> {}
+impl<X, Y: ?Sized> Trait8<X, Y> for X {}
+//~^ ERROR E0277
+
+fn main() {}
diff --git a/src/test/ui/trait-bounds/unsized-bound.stderr b/src/test/ui/trait-bounds/unsized-bound.stderr
new file mode 100644
index 00000000000..30163ab7978
--- /dev/null
+++ b/src/test/ui/trait-bounds/unsized-bound.stderr
@@ -0,0 +1,234 @@
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:2:12
+   |
+LL | trait Trait<A> {}
+   |             - required by this bound in `Trait`
+LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+   |         -  ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |         |
+   |         this type parameter needs to be `std::marker::Sized`
+   |
+   = note: required because it appears within the type `(A, B)`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, {}
+   |                                                   --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait<A: ?Sized> {}
+   |              ^^^^^^^^
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:2:30
+   |
+LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
+   |      -                       ^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+   = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B> Trait<(A, B)> for (A, B) where B: ?Sized, {}
+   |                                          --
+
+error[E0277]: the size for values of type `C` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:5:31
+   |
+LL | trait Trait<A> {}
+   |             - required by this bound in `Trait`
+...
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+   |                    -          ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                    |
+   |                    this type parameter needs to be `std::marker::Sized`
+   |
+   = note: required because it appears within the type `(A, B, C)`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B: ?Sized, C> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+   |                    --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait<A: ?Sized> {}
+   |              ^^^^^^^^
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:5:52
+   |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+   |      -                                             ^^^^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+   = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C)  {}
+   |                                                             --
+
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:5:52
+   |
+LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+   |         -                                          ^^^^^^^^^ doesn't have a size known at compile-time
+   |         |
+   |         this type parameter needs to be `std::marker::Sized`
+   |
+   = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
+   |         --
+
+error[E0277]: the size for values of type `B` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:10:28
+   |
+LL | trait Trait2<A> {}
+   |              - required by this bound in `Trait2`
+LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+   |                 -          ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |                 |
+   |                 this type parameter needs to be `std::marker::Sized`
+   |
+   = note: required because it appears within the type `(A, B)`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A: ?Sized, B> Trait2<(A, B)> for (A, B) {}
+   |                 --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait2<A: ?Sized> {}
+   |               ^^^^^^^^
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:10:47
+   |
+LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+   |      -                                        ^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+   = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A, B: ?Sized> Trait2<(A, B)> for (A, B) {}
+   |      --
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:14:9
+   |
+LL | trait Trait3<A> {}
+   |              - required by this bound in `Trait3`
+LL | impl<A> Trait3<A> for A where A: ?Sized {}
+   |      -  ^^^^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A> Trait3<A> for A  {}
+   |                        --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait3<A: ?Sized> {}
+   |               ^^^^^^^^
+
+error[E0277]: the size for values of type `A` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:17:17
+   |
+LL | trait Trait4<A> {}
+   |              - required by this bound in `Trait4`
+LL | impl<A: ?Sized> Trait4<A> for A {}
+   |      -          ^^^^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<A> Trait4<A> for A {}
+   |      --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait4<A: ?Sized> {}
+   |               ^^^^^^^^
+
+error[E0277]: the size for values of type `X` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:20:12
+   |
+LL | trait Trait5<A, B> {}
+   |              - required by this bound in `Trait5`
+LL | impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
+   |      -     ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X, Y> Trait5<X, Y> for X  {}
+   |                              --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait5<A: ?Sized, B> {}
+   |               ^^^^^^^^
+
+error[E0277]: the size for values of type `X` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:23:20
+   |
+LL | trait Trait6<A, B> {}
+   |              - required by this bound in `Trait6`
+LL | impl<X: ?Sized, Y> Trait6<X, Y> for X {}
+   |      -             ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |      |
+   |      this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X, Y> Trait6<X, Y> for X {}
+   |      --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait6<A: ?Sized, B> {}
+   |               ^^^^^^^^
+
+error[E0277]: the size for values of type `Y` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:26:12
+   |
+LL | trait Trait7<A, B> {}
+   |                 - required by this bound in `Trait7`
+LL | impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
+   |         -  ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |         |
+   |         this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X, Y> Trait7<X, Y> for X  {}
+   |                              --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait7<A, B: ?Sized> {}
+   |                  ^^^^^^^^
+
+error[E0277]: the size for values of type `Y` cannot be known at compilation time
+  --> $DIR/unsized-bound.rs:29:20
+   |
+LL | trait Trait8<A, B> {}
+   |                 - required by this bound in `Trait8`
+LL | impl<X, Y: ?Sized> Trait8<X, Y> for X {}
+   |         -          ^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |         |
+   |         this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X, Y> Trait8<X, Y> for X {}
+   |         --
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | trait Trait8<A, B: ?Sized> {}
+   |                  ^^^^^^^^
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/suggest-where-clause.stderr b/src/test/ui/traits/suggest-where-clause.stderr
index f15e7e35839..47f287807d4 100644
--- a/src/test/ui/traits/suggest-where-clause.stderr
+++ b/src/test/ui/traits/suggest-where-clause.stderr
@@ -11,6 +11,11 @@ LL |     mem::size_of::<U>();
    |
 LL | pub const fn size_of<T>() -> usize {
    |                      - required by this bound in `std::mem::size_of`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn check<T: Iterator, U>() {
+   |                       --
 
 error[E0277]: the size for values of type `U` cannot be known at compilation time
   --> $DIR/suggest-where-clause.rs:10:5
@@ -31,6 +36,10 @@ note: required because it appears within the type `Misc<U>`
    |
 LL | struct Misc<T:?Sized>(T);
    |        ^^^^
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn check<T: Iterator, U>() {
+   |                       --
 
 error[E0277]: the trait bound `u64: From<T>` is not satisfied
   --> $DIR/suggest-where-clause.rs:15:5
diff --git a/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
new file mode 100644
index 00000000000..277d9eabe4f
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/issue-11515-upcast-fn_mut-fn.rs
@@ -0,0 +1,13 @@
+// run-pass
+#![feature(box_syntax, trait_upcasting)]
+#![allow(incomplete_features)]
+
+struct Test {
+    func: Box<dyn FnMut() + 'static>,
+}
+
+fn main() {
+    let closure: Box<dyn Fn() + 'static> = Box::new(|| ());
+    let mut test = box Test { func: closure };
+    (test.func)();
+}
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs
new file mode 100644
index 00000000000..6986ad62172
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.rs
@@ -0,0 +1,22 @@
+// check-fail
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+trait Bar<T> {
+    fn bar(&self, _: T) {}
+}
+
+trait Foo : Bar<i32> + Bar<u32> {
+    fn foo(&self, _: ()) {}
+}
+
+struct S;
+
+impl Bar<i32> for S {}
+impl Bar<u32> for S {}
+impl Foo for S {}
+
+fn main() {
+    let s: &dyn Foo = &S;
+    let t: &dyn Bar<_> = s; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr
new file mode 100644
index 00000000000..e9670ad7def
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/multiple-occurence-ambiguousity.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/multiple-occurence-ambiguousity.rs:21:26
+   |
+LL |     let t: &dyn Bar<_> = s;
+   |            -----------   ^ expected trait `Bar`, found trait `Foo`
+   |            |
+   |            expected due to this
+   |
+   = note: expected reference `&dyn Bar<_>`
+              found reference `&dyn Foo`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
new file mode 100644
index 00000000000..1a0e5072843
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -0,0 +1,33 @@
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+trait Foo: Bar<i32> + Bar<u32> {}
+trait Bar<T> {
+    fn bar(&self) -> Option<T> {
+        None
+    }
+}
+
+fn test_specific(x: &dyn Foo) {
+    let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+                                //~^ ERROR non-primitive cast
+                                //~^^ ERROR the trait bound `&dyn Foo: Bar<i32>` is not satisfied
+    let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
+                                //~^ ERROR non-primitive cast
+                                //~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
+}
+
+fn test_unknown_version(x: &dyn Foo) {
+    let _ = x as &dyn Bar<_>; // Ambiguous
+                              //~^ ERROR non-primitive cast
+                              //~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
+}
+
+fn test_infer_version(x: &dyn Foo) {
+    let a = x as &dyn Bar<_>; // FIXME: OK, eventually
+                              //~^ ERROR non-primitive cast
+                              //~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
+    let _: Option<u32> = a.bar();
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
new file mode 100644
index 00000000000..6aaa8a4a904
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -0,0 +1,80 @@
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<i32>`
+  --> $DIR/type-checking-test-1.rs:12:13
+   |
+LL |     let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^^^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^
+
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
+  --> $DIR/type-checking-test-1.rs:15:13
+   |
+LL |     let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
+   |             ^^^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let _ = &x as &dyn Bar<u32>; // FIXME: OK, eventually
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo: Bar<i32>` is not satisfied
+  --> $DIR/type-checking-test-1.rs:12:13
+   |
+LL |     let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^ the trait `Bar<i32>` is not implemented for `&dyn Foo`
+   |
+   = note: required for the cast to the object type `dyn Bar<i32>`
+
+error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
+  --> $DIR/type-checking-test-1.rs:15:13
+   |
+LL |     let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
+   |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
+   |
+   = note: required for the cast to the object type `dyn Bar<u32>`
+
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
+  --> $DIR/type-checking-test-1.rs:21:13
+   |
+LL |     let _ = x as &dyn Bar<_>; // Ambiguous
+   |             ^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let _ = &x as &dyn Bar<_>; // Ambiguous
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
+  --> $DIR/type-checking-test-1.rs:21:13
+   |
+LL |     let _ = x as &dyn Bar<_>; // Ambiguous
+   |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
+   |
+   = note: required for the cast to the object type `dyn Bar<_>`
+
+error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
+  --> $DIR/type-checking-test-1.rs:27:13
+   |
+LL |     let a = x as &dyn Bar<_>; // FIXME: OK, eventually
+   |             ^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let a = &x as &dyn Bar<_>; // FIXME: OK, eventually
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
+  --> $DIR/type-checking-test-1.rs:27:13
+   |
+LL |     let a = x as &dyn Bar<_>; // FIXME: OK, eventually
+   |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
+   |
+   = note: required for the cast to the object type `dyn Bar<u32>`
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0277, E0605.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
new file mode 100644
index 00000000000..326df74211e
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -0,0 +1,34 @@
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+trait Foo<T>: Bar<i32> + Bar<T> {}
+trait Bar<T> {
+    fn bar(&self) -> Option<T> {
+        None
+    }
+}
+
+fn test_specific(x: &dyn Foo<i32>) {
+    let _ = x as &dyn Bar<i32>; // OK
+}
+
+fn test_specific2(x: &dyn Foo<u32>) {
+    let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+                                //~^ ERROR non-primitive cast
+                                //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
+}
+
+fn test_specific3(x: &dyn Foo<i32>) {
+    let _ = x as &dyn Bar<u32>; // Error
+                                //~^ ERROR non-primitive cast
+                                //~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
+}
+
+fn test_infer_arg(x: &dyn Foo<u32>) {
+    let a = x as &dyn Bar<_>; // Ambiguous
+                              //~^ ERROR non-primitive cast
+                              //~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
+    let _ = a.bar();
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
new file mode 100644
index 00000000000..a38f8a14604
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -0,0 +1,61 @@
+error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<i32>`
+  --> $DIR/type-checking-test-2.rs:16:13
+   |
+LL |     let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^^^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
+  --> $DIR/type-checking-test-2.rs:16:13
+   |
+LL |     let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
+   |             ^ the trait `Bar<i32>` is not implemented for `&dyn Foo<u32>`
+   |
+   = note: required for the cast to the object type `dyn Bar<i32>`
+
+error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
+  --> $DIR/type-checking-test-2.rs:22:13
+   |
+LL |     let _ = x as &dyn Bar<u32>; // Error
+   |             ^^^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let _ = &x as &dyn Bar<u32>; // Error
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
+  --> $DIR/type-checking-test-2.rs:22:13
+   |
+LL |     let _ = x as &dyn Bar<u32>; // Error
+   |             ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
+   |
+   = note: required for the cast to the object type `dyn Bar<u32>`
+
+error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
+  --> $DIR/type-checking-test-2.rs:28:13
+   |
+LL |     let a = x as &dyn Bar<_>; // Ambiguous
+   |             ^^^^^^^^^^^^^^^^ invalid cast
+   |
+help: consider borrowing the value
+   |
+LL |     let a = &x as &dyn Bar<_>; // Ambiguous
+   |             ^
+
+error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
+  --> $DIR/type-checking-test-2.rs:28:13
+   |
+LL |     let a = x as &dyn Bar<_>; // Ambiguous
+   |             ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
+   |
+   = note: required for the cast to the object type `dyn Bar<_>`
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0277, E0605.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
new file mode 100644
index 00000000000..49c24e404dc
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
@@ -0,0 +1,22 @@
+// ignore-compare-mode-nll
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+trait Foo<'a>: Bar<'a> {}
+trait Bar<'a> {}
+
+fn test_correct(x: &dyn Foo<'static>) {
+    let _ = x as &dyn Bar<'static>;
+}
+
+fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+    let _ = x as &dyn Bar<'a>; // Error
+                               //~^ ERROR mismatched types
+}
+
+fn test_wrong2<'a>(x: &dyn Foo<'a>) {
+    let _ = x as &dyn Bar<'static>; // Error
+                                    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
new file mode 100644
index 00000000000..593ee0a3430
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
@@ -0,0 +1,33 @@
+error[E0308]: mismatched types
+  --> $DIR/type-checking-test-3.rs:13:13
+   |
+LL |     let _ = x as &dyn Bar<'a>; // Error
+   |             ^ lifetime mismatch
+   |
+   = note: expected trait object `dyn Bar<'a>`
+              found trait object `dyn Bar<'static>`
+note: the lifetime `'a` as defined on the function body at 12:16...
+  --> $DIR/type-checking-test-3.rs:12:16
+   |
+LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+   |                ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error[E0308]: mismatched types
+  --> $DIR/type-checking-test-3.rs:18:13
+   |
+LL |     let _ = x as &dyn Bar<'static>; // Error
+   |             ^ lifetime mismatch
+   |
+   = note: expected trait object `dyn Bar<'static>`
+              found trait object `dyn Bar<'a>`
+note: the lifetime `'a` as defined on the function body at 17:16...
+  --> $DIR/type-checking-test-3.rs:17:16
+   |
+LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
+   |                ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
new file mode 100644
index 00000000000..9b27fd46f7a
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
@@ -0,0 +1,32 @@
+// ignore-compare-mode-nll
+#![feature(trait_upcasting)]
+#![allow(incomplete_features)]
+
+trait Foo<'a>: Bar<'a, 'a> {}
+trait Bar<'a, 'b> {
+    fn get_b(&self) -> Option<&'a u32> {
+        None
+    }
+}
+
+fn test_correct(x: &dyn Foo<'static>) {
+    let _ = x as &dyn Bar<'static, 'static>;
+}
+
+fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+    let _ = x as &dyn Bar<'static, 'a>; // Error
+                                        //~^ ERROR mismatched types
+}
+
+fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+    let _ = x as &dyn Bar<'a, 'static>; // Error
+                                        //~^ ERROR mismatched types
+}
+
+fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+    let y = x as &dyn Bar<'_, '_>;
+    //~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+    y.get_b() // ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
new file mode 100644
index 00000000000..811e524eda7
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
@@ -0,0 +1,47 @@
+error[E0308]: mismatched types
+  --> $DIR/type-checking-test-4.rs:17:13
+   |
+LL |     let _ = x as &dyn Bar<'static, 'a>; // Error
+   |             ^ lifetime mismatch
+   |
+   = note: expected trait object `dyn Bar<'static, 'a>`
+              found trait object `dyn Bar<'static, 'static>`
+note: the lifetime `'a` as defined on the function body at 16:16...
+  --> $DIR/type-checking-test-4.rs:16:16
+   |
+LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+   |                ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error[E0308]: mismatched types
+  --> $DIR/type-checking-test-4.rs:22:13
+   |
+LL |     let _ = x as &dyn Bar<'a, 'static>; // Error
+   |             ^ lifetime mismatch
+   |
+   = note: expected trait object `dyn Bar<'a, 'static>`
+              found trait object `dyn Bar<'static, 'static>`
+note: the lifetime `'a` as defined on the function body at 21:16...
+  --> $DIR/type-checking-test-4.rs:21:16
+   |
+LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
+   |                ^^
+   = note: ...does not necessarily outlive the static lifetime
+
+error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
+  --> $DIR/type-checking-test-4.rs:27:27
+   |
+LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
+   |                       ------------ this data with lifetime `'a`...
+LL |     let y = x as &dyn Bar<'_, '_>;
+   |             -             ^^
+   |             |
+   |             ...is captured here...
+LL |
+LL |     y.get_b() // ERROR
+   |     --------- ...and is required to live as long as `'static` here
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0308, E0759.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.rs b/src/test/ui/type-alias-impl-trait/issue-74280.rs
new file mode 100644
index 00000000000..d5b90a49b05
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.rs
@@ -0,0 +1,13 @@
+// Regression test for #74280.
+
+#![feature(type_alias_impl_trait)]
+
+type Test = impl Copy;
+
+fn test() -> Test {
+    let y = || -> Test { () };
+    //~^ ERROR: concrete type differs from previous defining opaque type use
+    7
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/issue-74280.stderr b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
new file mode 100644
index 00000000000..79c7df788f4
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-74280.stderr
@@ -0,0 +1,14 @@
+error: concrete type differs from previous defining opaque type use
+  --> $DIR/issue-74280.rs:8:13
+   |
+LL |     let y = || -> Test { () };
+   |             ^^^^^^^^^^^^^^^^^ expected `i32`, got `()`
+   |
+note: previous use here
+  --> $DIR/issue-74280.rs:7:1
+   |
+LL | fn test() -> Test {
+   | ^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.rs b/src/test/ui/type-alias-impl-trait/issue-77179.rs
new file mode 100644
index 00000000000..31c45a2093a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-77179.rs
@@ -0,0 +1,14 @@
+// Regression test for #77179.
+
+#![feature(type_alias_impl_trait)]
+
+type Pointer<T> = impl std::ops::Deref<Target=T>;
+
+fn test() -> Pointer<_> {
+    //~^ ERROR: the type placeholder `_` is not allowed within types
+    Box::new(1)
+}
+
+fn main() {
+    test();
+}
diff --git a/src/test/ui/type-alias-impl-trait/issue-77179.stderr b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
new file mode 100644
index 00000000000..593aeeacb83
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/issue-77179.stderr
@@ -0,0 +1,12 @@
+error[E0121]: the type placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/issue-77179.rs:7:22
+   |
+LL | fn test() -> Pointer<_> {
+   |              --------^-
+   |              |       |
+   |              |       not allowed in type signatures
+   |              help: replace with the correct return type: `Box<i32>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0121`.
diff --git a/src/test/ui/typeck/conversion-methods.stderr b/src/test/ui/typeck/conversion-methods.stderr
index 4f47e1fd0ff..15848c66c15 100644
--- a/src/test/ui/typeck/conversion-methods.stderr
+++ b/src/test/ui/typeck/conversion-methods.stderr
@@ -2,44 +2,43 @@ error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:5:41
    |
 LL |     let _tis_an_instants_play: String = "'Tis a fond Ambush—";
-   |                                ------   ^^^^^^^^^^^^^^^^^^^^^
+   |                                ------   ^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_string()`
    |                                |        |
    |                                |        expected struct `String`, found `&str`
-   |                                |        help: try using a conversion method: `"'Tis a fond Ambush—".to_string()`
    |                                expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:6:40
    |
 LL |     let _just_to_make_bliss: PathBuf = Path::new("/ern/her/own/surprise");
-   |                              -------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                              -------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- help: try using a conversion method: `.to_path_buf()`
    |                              |         |
    |                              |         expected struct `PathBuf`, found `&Path`
-   |                              |         help: try using a conversion method: `Path::new("/ern/her/own/surprise").to_path_buf()`
    |                              expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:9:40
    |
 LL |     let _but_should_the_play: String = 2; // Perhaps surprisingly, we suggest .to_string() here
-   |                               ------   ^
+   |                               ------   ^- help: try using a conversion method: `.to_string()`
    |                               |        |
    |                               |        expected struct `String`, found integer
-   |                               |        help: try using a conversion method: `2.to_string()`
    |                               expected due to this
 
 error[E0308]: mismatched types
   --> $DIR/conversion-methods.rs:12:47
    |
 LL |     let _prove_piercing_earnest: Vec<usize> = &[1, 2, 3];
-   |                                  ----------   ^^^^^^^^^^
-   |                                  |            |
-   |                                  |            expected struct `Vec`, found `&[{integer}; 3]`
-   |                                  |            help: try using a conversion method: `(&[1, 2, 3]).to_vec()`
+   |                                  ----------   ^^^^^^^^^^ expected struct `Vec`, found `&[{integer}; 3]`
+   |                                  |
    |                                  expected due to this
    |
    = note: expected struct `Vec<usize>`
            found reference `&[{integer}; 3]`
+help: try using a conversion method
+   |
+LL |     let _prove_piercing_earnest: Vec<usize> = (&[1, 2, 3]).to_vec();
+   |                                               ^          ^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/union/union-sized-field.stderr b/src/test/ui/union/union-sized-field.stderr
index b916bbe8ad1..ef86c624e9b 100644
--- a/src/test/ui/union/union-sized-field.stderr
+++ b/src/test/ui/union/union-sized-field.stderr
@@ -8,6 +8,10 @@ LL |     value: T,
    |
    = note: no field of a union may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | union Foo<T> {
+   |           --
 help: borrowed types always have a statically known size
    |
 LL |     value: &T,
@@ -27,6 +31,10 @@ LL |     value: T,
    |
    = note: only the last field of a struct may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | struct Foo2<T> {
+   |             --
 help: borrowed types always have a statically known size
    |
 LL |     value: &T,
@@ -46,6 +54,10 @@ LL |     Value(T),
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum Foo3<T> {
+   |           --
 help: borrowed types always have a statically known size
    |
 LL |     Value(&T),
diff --git a/src/test/ui/unsized/unsized-bare-typaram.stderr b/src/test/ui/unsized/unsized-bare-typaram.stderr
index 19978ae24ca..35bba1c103a 100644
--- a/src/test/ui/unsized/unsized-bare-typaram.stderr
+++ b/src/test/ui/unsized/unsized-bare-typaram.stderr
@@ -7,6 +7,11 @@ LL | fn foo<T: ?Sized>() { bar::<T>() }
    |        -                    ^ doesn't have a size known at compile-time
    |        |
    |        this type parameter needs to be `std::marker::Sized`
+   |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn foo<T>() { bar::<T>() }
+   |        --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-enum.stderr b/src/test/ui/unsized/unsized-enum.stderr
index 601db7d1cd9..f66ce2af304 100644
--- a/src/test/ui/unsized/unsized-enum.stderr
+++ b/src/test/ui/unsized/unsized-enum.stderr
@@ -16,6 +16,10 @@ LL | enum Foo<U> { FooSome(U), FooNone }
    |          ^            - ...if indirection were used here: `Box<U>`
    |          |
    |          this could be changed to `U: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn foo2<T>() { not_sized::<Foo<T>>() }
+   |         --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-enum2.stderr b/src/test/ui/unsized/unsized-enum2.stderr
index 1b6c8585815..b9a03d904af 100644
--- a/src/test/ui/unsized/unsized-enum2.stderr
+++ b/src/test/ui/unsized/unsized-enum2.stderr
@@ -9,6 +9,10 @@ LL |     VA(W),
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum E<W, X: ?Sized, Y: ?Sized, Z: ?Sized> {
+   |        --
 help: borrowed types always have a statically known size
    |
 LL |     VA(&W),
@@ -29,6 +33,10 @@ LL |     VB{x: X},
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum E<W: ?Sized, X, Y: ?Sized, Z: ?Sized> {
+   |                   --
 help: borrowed types always have a statically known size
    |
 LL |     VB{x: &X},
@@ -49,6 +57,10 @@ LL |     VC(isize, Y),
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum E<W: ?Sized, X: ?Sized, Y, Z: ?Sized> {
+   |                              --
 help: borrowed types always have a statically known size
    |
 LL |     VC(isize, &Y),
@@ -69,6 +81,10 @@ LL |     VD{u: isize, x: Z},
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z> {
+   |                                         --
 help: borrowed types always have a statically known size
    |
 LL |     VD{u: isize, x: &Z},
diff --git a/src/test/ui/unsized/unsized-fn-arg.fixed b/src/test/ui/unsized/unsized-fn-arg.fixed
index 2c686c6c2b2..fd9b159a481 100644
--- a/src/test/ui/unsized/unsized-fn-arg.fixed
+++ b/src/test/ui/unsized/unsized-fn-arg.fixed
@@ -2,5 +2,5 @@
 #![crate_type="lib"]
 #![allow(unused)]
 
-fn f<T: ?Sized>(t: &T) {}
+fn f<T>(t: &T) {}
 //~^ ERROR the size for values of type `T` cannot be known at compilation time
diff --git a/src/test/ui/unsized/unsized-fn-arg.stderr b/src/test/ui/unsized/unsized-fn-arg.stderr
index 6b802ddf542..acb8a598d2c 100644
--- a/src/test/ui/unsized/unsized-fn-arg.stderr
+++ b/src/test/ui/unsized/unsized-fn-arg.stderr
@@ -7,6 +7,10 @@ LL | fn f<T: ?Sized>(t: T) {}
    |      this type parameter needs to be `std::marker::Sized`
    |
    = help: unsized fn params are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f<T>(t: T) {}
+   |      --
 help: function arguments must have a statically known size, borrowed types always have a known size
    |
 LL | fn f<T: ?Sized>(t: &T) {}
diff --git a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
index 9d072eda4e8..99f75d8c5b3 100644
--- a/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
+++ b/src/test/ui/unsized/unsized-inherent-impl-self-type.stderr
@@ -16,6 +16,10 @@ LL | struct S5<Y>(Y);
    |           ^  - ...if indirection were used here: `Box<Y>`
    |           |
    |           this could be changed to `Y: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X> S5<X> {
+   |      --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-struct.stderr b/src/test/ui/unsized/unsized-struct.stderr
index e38375bff46..71693b8130d 100644
--- a/src/test/ui/unsized/unsized-struct.stderr
+++ b/src/test/ui/unsized/unsized-struct.stderr
@@ -16,6 +16,10 @@ LL | struct Foo<T> { data: T }
    |            ^          - ...if indirection were used here: `Box<T>`
    |            |
    |            this could be changed to `T: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn foo2<T>() { not_sized::<Foo<T>>() }
+   |         --
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> $DIR/unsized-struct.rs:13:24
@@ -33,6 +37,10 @@ note: required because it appears within the type `Bar<T>`
    |
 LL | struct Bar<T: ?Sized> { data: T }
    |        ^^^
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn bar2<T>() { is_sized::<Bar<T>>() }
+   |         --
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
index aef0d0cbb83..201dbf85d20 100644
--- a/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
+++ b/src/test/ui/unsized/unsized-trait-impl-self-type.stderr
@@ -16,6 +16,10 @@ LL | struct S5<Y>(Y);
    |           ^  - ...if indirection were used here: `Box<Y>`
    |           |
    |           this could be changed to `Y: ?Sized`...
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X> T3<X> for S5<X> {
+   |      --
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
index f48d4ef9f14..f8f8aa8e3e9 100644
--- a/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
+++ b/src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr
@@ -9,6 +9,10 @@ LL | impl<X: ?Sized> T2<X> for S4<X> {
    |      |
    |      this type parameter needs to be `std::marker::Sized`
    |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X> T2<X> for S4<X> {
+   |      --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | trait T2<Z: ?Sized> {
diff --git a/src/test/ui/unsized/unsized3.stderr b/src/test/ui/unsized/unsized3.stderr
index bd36008aca0..10ddfe34eac 100644
--- a/src/test/ui/unsized/unsized3.stderr
+++ b/src/test/ui/unsized/unsized3.stderr
@@ -9,6 +9,10 @@ LL |     f2::<X>(x);
 LL | fn f2<X>(x: &X) {
    |       - required by this bound in `f2`
    |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f1<X>(x: &X) {
+   |       --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | fn f2<X: ?Sized>(x: &X) {
@@ -25,6 +29,10 @@ LL |     f4::<X>(x);
 LL | fn f4<X: T>(x: &X) {
    |       - required by this bound in `f4`
    |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f3<X: T>(x: &X) {
+   |         --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | fn f4<X: T + ?Sized>(x: &X) {
@@ -46,6 +54,10 @@ note: required because it appears within the type `S<X>`
    |
 LL | struct S<X: ?Sized> {
    |        ^
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f8<X>(x1: &S<X>, x2: &S<X>) {
+   |       --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | fn f5<Y: ?Sized>(x: &Y) {}
@@ -65,6 +77,10 @@ note: required because it appears within the type `S<X>`
 LL | struct S<X: ?Sized> {
    |        ^
    = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f9<X>(x1: Box<S<X>>) {
+   |       --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:45:9
@@ -81,6 +97,10 @@ LL | struct S<X: ?Sized> {
    |        ^
    = note: required because it appears within the type `({integer}, S<X>)`
    = note: tuples must have a statically known size to be initialized
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f10<X>(x1: Box<S<X>>) {
+   |        --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized3.rs:45:8
@@ -99,6 +119,10 @@ note: required because it appears within the type `S<X>`
 LL | struct S<X: ?Sized> {
    |        ^
    = note: required because it appears within the type `({integer}, S<X>)`
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f10<X>(x1: Box<S<X>>) {
+   |        --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | fn f5<Y: ?Sized>(x: &Y) {}
diff --git a/src/test/ui/unsized/unsized5.stderr b/src/test/ui/unsized/unsized5.stderr
index 0bfd4565529..6e5b3556429 100644
--- a/src/test/ui/unsized/unsized5.stderr
+++ b/src/test/ui/unsized/unsized5.stderr
@@ -8,6 +8,10 @@ LL |     f1: X,
    |
    = note: only the last field of a struct may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | struct S1<X> {
+   |           --
 help: borrowed types always have a statically known size
    |
 LL |     f1: &X,
@@ -28,6 +32,10 @@ LL |     g: X,
    |
    = note: only the last field of a struct may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | struct S2<X> {
+   |           --
 help: borrowed types always have a statically known size
    |
 LL |     g: &X,
@@ -83,6 +91,10 @@ LL |     V1(X, isize),
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum E<X> {
+   |        --
 help: borrowed types always have a statically known size
    |
 LL |     V1(&X, isize),
@@ -102,6 +114,10 @@ LL |     V2{f1: X, f: isize},
    |
    = note: no field of an enum variant may have a dynamically sized type
    = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | enum F<X> {
+   |        --
 help: borrowed types always have a statically known size
    |
 LL |     V2{f1: &X, f: isize},
diff --git a/src/test/ui/unsized/unsized6.stderr b/src/test/ui/unsized/unsized6.stderr
index 8e5734dffb1..5eff89d971f 100644
--- a/src/test/ui/unsized/unsized6.stderr
+++ b/src/test/ui/unsized/unsized6.stderr
@@ -9,6 +9,10 @@ LL |     let y: Y;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f1<W: ?Sized, X: ?Sized, Y, Z: ?Sized>(x: &X) {
+   |                             --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:7:12
@@ -20,6 +24,10 @@ LL |     let _: (isize, (X, isize));
    |            ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f1<W: ?Sized, X, Y: ?Sized, Z: ?Sized>(x: &X) {
+   |                  --
 
 error[E0277]: the size for values of type `Z` cannot be known at compilation time
   --> $DIR/unsized6.rs:11:12
@@ -31,6 +39,10 @@ LL |     let y: (isize, (Z, usize));
    |            ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f1<W: ?Sized, X: ?Sized, Y: ?Sized, Z>(x: &X) {
+   |                                        --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:15:9
@@ -42,6 +54,10 @@ LL |     let y: X;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f2<X, Y: ?Sized>(x: &X) {
+   |       --
 
 error[E0277]: the size for values of type `Y` cannot be known at compilation time
   --> $DIR/unsized6.rs:17:12
@@ -53,6 +69,10 @@ LL |     let y: (isize, (Y, isize));
    |            ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = note: only the last element of a tuple may have a dynamically sized type
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f2<X: ?Sized, Y>(x: &X) {
+   |                  --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:22:9
@@ -64,6 +84,10 @@ LL |     let y: X = *x1;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |       --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:24:9
@@ -76,6 +100,10 @@ LL |     let y = *x2;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |       --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:26:10
@@ -88,6 +116,10 @@ LL |     let (y, z) = (*x3, 4);
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f3<X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |       --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:30:9
@@ -99,6 +131,10 @@ LL |     let y: X = *x1;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |         --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:32:9
@@ -111,6 +147,10 @@ LL |     let y = *x2;
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |         --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:34:10
@@ -123,6 +163,10 @@ LL |     let (y, z) = (*x3, 4);
    |
    = note: all local variables must have a statically known size
    = help: unsized locals are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn f4<X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+   |         --
 
 error[E0277]: the size for values of type `X` cannot be known at compilation time
   --> $DIR/unsized6.rs:38:18
@@ -133,6 +177,10 @@ LL | fn g1<X: ?Sized>(x: X) {}
    |       this type parameter needs to be `std::marker::Sized`
    |
    = help: unsized fn params are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn g1<X>(x: X) {}
+   |       --
 help: function arguments must have a statically known size, borrowed types always have a known size
    |
 LL | fn g1<X: ?Sized>(x: &X) {}
@@ -147,6 +195,10 @@ LL | fn g2<X: ?Sized + T>(x: X) {}
    |       this type parameter needs to be `std::marker::Sized`
    |
    = help: unsized fn params are gated as an unstable feature
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | fn g2<X: T>(x: X) {}
+   |         --
 help: function arguments must have a statically known size, borrowed types always have a known size
    |
 LL | fn g2<X: ?Sized + T>(x: &X) {}
diff --git a/src/test/ui/unsized/unsized7.stderr b/src/test/ui/unsized/unsized7.stderr
index 7dbddd4ed24..e0d95e21296 100644
--- a/src/test/ui/unsized/unsized7.stderr
+++ b/src/test/ui/unsized/unsized7.stderr
@@ -9,6 +9,10 @@ LL | impl<X: ?Sized + T> T1<X> for S3<X> {
    |      |
    |      this type parameter needs to be `std::marker::Sized`
    |
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL | impl<X: T> T1<X> for S3<X> {
+   |        --
 help: consider relaxing the implicit `Sized` restriction
    |
 LL | trait T1<Z: T + ?Sized> {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
index c38727316cd..320b3bb42f8 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-6250.stderr
@@ -25,10 +25,12 @@ error[E0308]: mismatched types
   --> $DIR/ice-6250.rs:12:14
    |
 LL |         Some(reference) = cache.data.get(key) {
-   |              ^^^^^^^^^
-   |              |
-   |              expected integer, found `&i32`
-   |              help: consider dereferencing the borrow: `*reference`
+   |              ^^^^^^^^^ expected integer, found `&i32`
+   |
+help: consider dereferencing the borrow
+   |
+LL |         Some(*reference) = cache.data.get(key) {
+   |              ^
 
 error[E0308]: mismatched types
   --> $DIR/ice-6250.rs:12:9
diff --git a/src/tools/clippy/tests/ui/needless_borrow_pat.rs b/src/tools/clippy/tests/ui/needless_borrow_pat.rs
index f0926220755..7a8137778b4 100644
--- a/src/tools/clippy/tests/ui/needless_borrow_pat.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow_pat.rs
@@ -7,7 +7,7 @@
 fn f1(_: &str) {}
 macro_rules! m1 {
     ($e:expr) => {
-        f1($e);
+        f1($e)
     };
 }
 macro_rules! m3 {
diff --git a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
index c7235e1c221..cd6db8ddc88 100644
--- a/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
+++ b/src/tools/clippy/tests/ui/ref_binding_to_reference.rs
@@ -7,7 +7,7 @@
 fn f1(_: &str) {}
 macro_rules! m2 {
     ($e:expr) => {
-        f1(*$e);
+        f1(*$e)
     };
 }
 macro_rules! m3 {