diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 7fecf537cfbd3..bacf5662bc005 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -442,18 +442,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         then: &Block,
         else_opt: Option<&Expr>,
     ) -> hir::ExprKind<'hir> {
-        macro_rules! make_if {
-            ($opt:expr) => {{
-                let cond = self.lower_expr(cond);
-                let then_expr = self.lower_block_expr(then);
-                hir::ExprKind::If(cond, self.arena.alloc(then_expr), $opt)
-            }};
-        }
-        if let Some(rslt) = else_opt {
-            make_if!(Some(self.lower_expr(rslt)))
-        } else {
-            make_if!(None)
-        }
+        let cond = self.lower_expr(cond);
+        let then = self.arena.alloc(self.lower_block_expr(then));
+        let els = else_opt.map(|els| self.lower_expr(els));
+        hir::ExprKind::If(cond, then, els)
     }
 
     fn lower_expr_if_let(
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index 638330c904d75..db8d01e31b74d 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -687,6 +687,9 @@ declare_features! (
     /// Trait upcasting is casting, e.g., `dyn Foo -> dyn Bar` where `Foo: Bar`.
     (incomplete, trait_upcasting, "1.56.0", Some(65991), None),
 
+    /// Allows explicit generic arguments specification with `impl Trait` present.
+    (active, explicit_generic_args_with_impl_trait, "1.56.0", Some(83701), None),
+
     // -------------------------------------------------------------------------
     // feature-group-end: actual feature gates
     // -------------------------------------------------------------------------
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index f885c0a4b87bd..cdc9a21253145 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -71,7 +71,7 @@ use rustc_middle::ty::{
     subst::{GenericArgKind, Subst, SubstsRef},
     Region, Ty, TyCtxt, TypeFoldable,
 };
-use rustc_span::{sym, BytePos, DesugaringKind, Pos, Span};
+use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
 use rustc_target::spec::abi;
 use std::ops::ControlFlow;
 use std::{cmp, fmt, iter};
@@ -1485,31 +1485,49 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                     let count = values.len();
                     let kind = key.descr();
                     let mut returned_async_output_error = false;
-                    for sp in values {
-                        err.span_label(
-                            *sp,
-                            format!(
-                                "{}{}{} {}{}",
-                                if sp.is_desugaring(DesugaringKind::Async)
-                                    && !returned_async_output_error
-                                {
-                                    "checked the `Output` of this `async fn`, "
-                                } else if count == 1 {
-                                    "the "
-                                } else {
-                                    ""
-                                },
-                                if count > 1 { "one of the " } else { "" },
-                                target,
-                                kind,
-                                pluralize!(count),
-                            ),
-                        );
-                        if sp.is_desugaring(DesugaringKind::Async)
-                            && returned_async_output_error == false
-                        {
-                            err.note("while checking the return type of the `async fn`");
+                    for &sp in values {
+                        if sp.is_desugaring(DesugaringKind::Async) && !returned_async_output_error {
+                            if &[sp] != err.span.primary_spans() {
+                                let mut span: MultiSpan = sp.into();
+                                span.push_span_label(
+                                    sp,
+                                    format!(
+                                        "checked the `Output` of this `async fn`, {}{} {}{}",
+                                        if count > 1 { "one of the " } else { "" },
+                                        target,
+                                        kind,
+                                        pluralize!(count),
+                                    ),
+                                );
+                                err.span_note(
+                                    span,
+                                    "while checking the return type of the `async fn`",
+                                );
+                            } else {
+                                err.span_label(
+                                    sp,
+                                    format!(
+                                        "checked the `Output` of this `async fn`, {}{} {}{}",
+                                        if count > 1 { "one of the " } else { "" },
+                                        target,
+                                        kind,
+                                        pluralize!(count),
+                                    ),
+                                );
+                                err.note("while checking the return type of the `async fn`");
+                            }
                             returned_async_output_error = true;
+                        } else {
+                            err.span_label(
+                                sp,
+                                format!(
+                                    "{}{} {}{}",
+                                    if count == 1 { "the " } else { "one of the " },
+                                    target,
+                                    kind,
+                                    pluralize!(count),
+                                ),
+                            );
                         }
                     }
                 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index 9a718102cf11d..a15eecd2414c2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -769,7 +769,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
 
                 // (#83606): Do not emit a suggestion if the parent has an `impl Trait`
                 // as an argument otherwise it will cause the E0282 error.
-                if !has_impl_trait {
+                if !has_impl_trait || self.tcx.features().explicit_generic_args_with_impl_trait {
                     err.span_suggestion_verbose(
                         span,
                         "consider specifying the const argument",
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 1c5be61130b61..4e95cdc0efa5f 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -153,16 +153,37 @@ pub(crate) fn emit_unescape_error(
         EscapeError::NonAsciiCharInByte => {
             assert!(mode.is_bytes());
             let (c, span) = last_char();
-            handler
-                .struct_span_err(span, "non-ASCII character in byte constant")
-                .span_label(span, "byte constant must be ASCII")
-                .span_suggestion(
+            let mut err = handler.struct_span_err(span, "non-ASCII character in byte constant");
+            err.span_label(span, "byte constant must be ASCII");
+            if (c as u32) <= 0xFF {
+                err.span_suggestion(
                     span,
-                    "use a \\xHH escape for a non-ASCII byte",
+                    &format!(
+                        "if you meant to use the unicode code point for '{}', use a \\xHH escape",
+                        c
+                    ),
                     format!("\\x{:X}", c as u32),
-                    Applicability::MachineApplicable,
-                )
-                .emit();
+                    Applicability::MaybeIncorrect,
+                );
+            } else if matches!(mode, Mode::Byte) {
+                err.span_label(span, "this multibyte character does not fit into a single byte");
+            } else if matches!(mode, Mode::ByteStr) {
+                let mut utf8 = String::new();
+                utf8.push(c);
+                err.span_suggestion(
+                    span,
+                    &format!(
+                        "if you meant to use the UTF-8 encoding of '{}', use \\xHH escapes",
+                        c
+                    ),
+                    utf8.as_bytes()
+                        .iter()
+                        .map(|b: &u8| format!("\\x{:X}", *b))
+                        .fold("".to_string(), |a, c| a + &c),
+                    Applicability::MaybeIncorrect,
+                );
+            }
+            err.emit();
         }
         EscapeError::NonAsciiCharInByteString => {
             assert!(mode.is_bytes());
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 1ac489f600a40..95b92fd34c8aa 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -554,6 +554,7 @@ symbols! {
         expected,
         expf32,
         expf64,
+        explicit_generic_args_with_impl_trait,
         export_name,
         expr,
         extended_key_value_attributes,
diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs
index eb6265dec89c0..9e700d9e8d8ba 100644
--- a/compiler/rustc_typeck/src/astconv/generics.rs
+++ b/compiler/rustc_typeck/src/astconv/generics.rs
@@ -459,7 +459,32 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let default_counts = gen_params.own_defaults();
         let param_counts = gen_params.own_counts();
-        let named_type_param_count = param_counts.types - has_self as usize;
+
+        // Subtracting from param count to ensure type params synthesized from `impl Trait`
+        // cannot be explictly specified even with `explicit_generic_args_with_impl_trait`
+        // feature enabled.
+        let synth_type_param_count = if tcx.features().explicit_generic_args_with_impl_trait {
+            gen_params
+                .params
+                .iter()
+                .filter(|param| {
+                    matches!(
+                        param.kind,
+                        ty::GenericParamDefKind::Type {
+                            synthetic: Some(
+                                hir::SyntheticTyParamKind::ImplTrait
+                                    | hir::SyntheticTyParamKind::FromAttr
+                            ),
+                            ..
+                        }
+                    )
+                })
+                .count()
+        } else {
+            0
+        };
+        let named_type_param_count =
+            param_counts.types - has_self as usize - synth_type_param_count;
         let infer_lifetimes =
             gen_pos != GenericArgPosition::Type && !gen_args.has_lifetime_params();
 
@@ -588,6 +613,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 param_counts.consts + named_type_param_count
                     - default_counts.types
                     - default_counts.consts
+                    - synth_type_param_count
             };
             debug!("expected_min: {:?}", expected_min);
             debug!("arg_counts.lifetimes: {:?}", gen_args.num_lifetime_params());
@@ -617,7 +643,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         seg: &hir::PathSegment<'_>,
         generics: &ty::Generics,
     ) -> bool {
-        let explicit = !seg.infer_args;
+        if seg.infer_args || tcx.features().explicit_generic_args_with_impl_trait {
+            return false;
+        }
+
         let impl_trait = generics.params.iter().any(|param| {
             matches!(
                 param.kind,
@@ -630,7 +659,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             )
         });
 
-        if explicit && impl_trait {
+        if impl_trait {
             let spans = seg
                 .args()
                 .args
diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs
index d056f2c90f988..dee81510b795b 100644
--- a/compiler/rustc_typeck/src/check/_match.rs
+++ b/compiler/rustc_typeck/src/check/_match.rs
@@ -13,41 +13,6 @@ use rustc_trait_selection::traits::{
     StatementAsExpression,
 };
 
-macro_rules! create_maybe_get_coercion_reason {
-    ($fn_name:ident, $node:expr) => {
-        pub(crate) fn $fn_name(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
-            let node = $node(self.tcx.hir(), hir_id);
-            if let hir::Node::Block(block) = node {
-                // check that the body's parent is an fn
-                let parent = self.tcx.hir().get(
-                    self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(block.hir_id)),
-                );
-                if let (
-                    Some(expr),
-                    hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }),
-                ) = (&block.expr, parent)
-                {
-                    // check that the `if` expr without `else` is the fn body's expr
-                    if expr.span == sp {
-                        return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
-                            let span = fn_decl.output.span();
-                            let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
-                            Some((
-                                span,
-                                format!("expected `{}` because of this return type", snippet),
-                            ))
-                        });
-                    }
-                }
-            }
-            if let hir::Node::Local(hir::Local { ty: Some(_), pat, .. }) = node {
-                return Some((pat.span, "expected because of this assignment".to_string()));
-            }
-            None
-        }
-    };
-}
-
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn check_match(
         &self,
@@ -154,7 +119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     expr.span,
                     &arms[0].body,
                     &mut coercion,
-                    |hir_id, span| self.maybe_get_coercion_reason(hir_id, span),
+                    |hir_id, span| self.coercion_reason_match(hir_id, span),
                 ) {
                 tcx.ty_error()
             } else {
@@ -373,23 +338,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error
     }
 
-    create_maybe_get_coercion_reason!(
-        maybe_get_coercion_reason,
-        |hir: rustc_middle::hir::map::Map<'a>, id| {
-            let arm_id = hir.get_parent_node(id);
-            let match_id = hir.get_parent_node(arm_id);
-            let containing_id = hir.get_parent_node(match_id);
-            hir.get(containing_id)
-        }
-    );
+    pub(crate) fn coercion_reason_if(
+        &self,
+        hir_id: hir::HirId,
+        span: Span,
+    ) -> Option<(Span, String)> {
+        self.coercion_reason_inner(hir_id, span, 1)
+    }
 
-    create_maybe_get_coercion_reason!(
-        maybe_get_coercion_reason_if,
-        |hir: rustc_middle::hir::map::Map<'a>, id| {
-            let rslt = hir.get_parent_node(hir.get_parent_node(id));
-            hir.get(rslt)
+    pub(crate) fn coercion_reason_match(
+        &self,
+        hir_id: hir::HirId,
+        span: Span,
+    ) -> Option<(Span, String)> {
+        self.coercion_reason_inner(hir_id, span, 2)
+    }
+
+    fn coercion_reason_inner(
+        &self,
+        hir_id: hir::HirId,
+        span: Span,
+        parent_index: usize,
+    ) -> Option<(Span, String)> {
+        let hir = self.tcx.hir();
+        let mut parent_iter = hir.parent_iter(hir_id);
+        let (_, node) = parent_iter.nth(parent_index)?;
+        match node {
+            hir::Node::Block(block) => {
+                let expr = block.expr?;
+                // check that the body's parent is an fn
+                let (_, parent) = parent_iter.nth(1)?;
+                if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. }) = parent {
+                    // check that the `if` expr without `else` is the fn body's expr
+                    if expr.span == span {
+                        let (fn_decl, _) = self.get_fn_decl(hir_id)?;
+                        let span = fn_decl.output.span();
+                        let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
+                        return Some((
+                            span,
+                            format!("expected `{}` because of this return type", snippet),
+                        ));
+                    }
+                }
+                None
+            }
+            hir::Node::Local(hir::Local { ty: Some(_), pat, .. }) => {
+                Some((pat.span, "expected because of this assignment".to_string()))
+            }
+            _ => None,
         }
-    );
+    }
 
     pub(crate) fn if_cause(
         &self,
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 08258aac96f2f..e95884ae23b93 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -838,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.diverges.set(cond_diverges | then_diverges & else_diverges);
         } else {
             self.if_fallback_coercion(sp, then_expr, &mut coerce, |hir_id, span| {
-                self.maybe_get_coercion_reason_if(hir_id, span)
+                self.coercion_reason_if(hir_id, span)
             });
 
             // If the condition is false we can't diverge.
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 8057ff0759107..d4e9c384f9302 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -285,6 +285,19 @@
 //! assert_eq!(res, ["error!", "error!", "foo", "error!", "bar"]);
 //! ```
 //!
+//! ## Comparison operators
+//!
+//! If `T` implements [`PartialOrd`] then [`Option<T>`] will derive its
+//! [`PartialOrd`] implementation.  With this order, [`None`] compares as
+//! less than any [`Some`], and two [`Some`] compare the same way as their
+//! contained values would in `T`.  If `T` also implements
+//! [`Ord`], then so does [`Option<T>`].
+//!
+//! ```
+//! assert!(None < Some(0));
+//! assert!(Some(0) < Some(1));
+//! ```
+//!
 //! ## Iterating over `Option`
 //!
 //! An [`Option`] can be iterated over. This can be helpful if you need an
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 32b6920b59d22..98a4cb59a6629 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -596,6 +596,7 @@ impl<T: ?Sized> *mut T {
     /// enables more aggressive compiler optimizations.
     ///
     /// [`wrapping_add`]: #method.wrapping_add
+    /// [allocated object]: crate::ptr#allocated-object
     ///
     /// # Examples
     ///
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 53aaa5219b1d4..861790e8a4099 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -379,6 +379,24 @@
 //! [`and_then`]: Result::and_then
 //! [`or_else`]: Result::or_else
 //!
+//! ## Comparison operators
+//!
+//! If `T` and `E` both implement [`PartialOrd`] then [`Result<T, E>`] will
+//! derive its [`PartialOrd`] implementation.  With this order, an [`Ok`]
+//! compares as less than any [`Err`], while two [`Ok`] or two [`Err`]
+//! compare as their contained values would in `T` or `E` respectively.  If `T`
+//! and `E` both also implement [`Ord`], then so does [`Result<T, E>`].
+//!
+//! ```
+//! assert!(Ok(1) < Err(0));
+//! let x: Result<i32, ()> = Ok(0);
+//! let y = Ok(1);
+//! assert!(x < y);
+//! let x: Result<(), i32> = Err(0);
+//! let y = Err(1);
+//! assert!(x < y);
+//! ```
+//!
 //! ## Iterating over `Result`
 //!
 //! A [`Result`] can be iterated over. This can be helpful if you need an
diff --git a/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md b/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md
new file mode 100644
index 0000000000000..479571d85fe05
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/explicit-generic-args-with-impl-trait.md
@@ -0,0 +1,53 @@
+# `explicit_generic_args_with_impl_trait`
+
+The tracking issue for this feature is: [#83701]
+
+[#83701]: https://github.com/rust-lang/rust/issues/83701
+
+------------------------
+
+The `explicit_generic_args_with_impl_trait` feature gate lets you specify generic arguments even
+when `impl Trait` is used in argument position.
+
+A simple example is:
+
+```rust
+#![feature(explicit_generic_args_with_impl_trait)]
+
+fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+
+fn main() {
+    foo::<str>("".to_string());
+}
+```
+
+This is currently rejected:
+
+```text
+error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
+ --> src/main.rs:6:11
+  |
+6 |     foo::<str>("".to_string());
+  |           ^^^ explicit generic argument not allowed
+
+```
+
+However it would compile if `explicit_generic_args_with_impl_trait` is enabled.
+
+Note that the synthetic type parameters from `impl Trait` are still implicit and you
+cannot explicitly specify these:
+
+```rust,compile_fail
+#![feature(explicit_generic_args_with_impl_trait)]
+
+fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+fn bar<T: ?Sized, F: AsRef<T>>(_f: F) {}
+
+fn main() {
+    bar::<str, _>("".to_string()); // Okay
+    bar::<str, String>("".to_string()); // Okay
+
+    foo::<str>("".to_string()); // Okay
+    foo::<str, String>("".to_string()); // Error, you cannot specify `impl Trait` explicitly
+}
+```
diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr
index 654a3bcc92dd8..4dc5cafb98614 100644
--- a/src/test/ui/async-await/dont-suggest-missing-await.stderr
+++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr
@@ -1,13 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/dont-suggest-missing-await.rs:14:18
    |
-LL | async fn make_u32() -> u32 {
-   |                        --- checked the `Output` of this `async fn`, found opaque type
-...
 LL |         take_u32(x)
    |                  ^ expected `u32`, found opaque type
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/dont-suggest-missing-await.rs:7:24
+   |
+LL | async fn make_u32() -> u32 {
+   |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future`
 help: consider `await`ing on the `Future`
diff --git a/src/test/ui/async-await/generator-desc.stderr b/src/test/ui/async-await/generator-desc.stderr
index 04f191cc5e8cb..a7aedbb2b322f 100644
--- a/src/test/ui/async-await/generator-desc.stderr
+++ b/src/test/ui/async-await/generator-desc.stderr
@@ -12,16 +12,19 @@ LL |     fun(async {}, async {});
 error[E0308]: mismatched types
   --> $DIR/generator-desc.rs:12:16
    |
-LL | async fn one() {}
-   |                - checked the `Output` of this `async fn`, expected opaque type
-LL | async fn two() {}
-   |                - checked the `Output` of this `async fn`, found opaque type
-...
 LL |     fun(one(), two());
    |                ^^^^^ expected opaque type, found a different opaque type
    |
-   = note: while checking the return type of the `async fn`
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/generator-desc.rs:5:16
+   |
+LL | async fn one() {}
+   |                ^ checked the `Output` of this `async fn`, expected opaque type
+note: while checking the return type of the `async fn`
+  --> $DIR/generator-desc.rs:6:16
+   |
+LL | async fn two() {}
+   |                ^ checked the `Output` of this `async fn`, found opaque type
    = note: expected opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:5:16>)
               found opaque type `impl Future` (opaque type at <$DIR/generator-desc.rs:6:16>)
    = help: consider `await`ing on both `Future`s
diff --git a/src/test/ui/async-await/issue-61076.rs b/src/test/ui/async-await/issue-61076.rs
index 9fe3313ee6cc6..220f0774e2d54 100644
--- a/src/test/ui/async-await/issue-61076.rs
+++ b/src/test/ui/async-await/issue-61076.rs
@@ -57,6 +57,8 @@ async fn struct_() -> Struct {
 
 async fn tuple() -> Tuple {
     //~^ NOTE checked the `Output` of this `async fn`, expected opaque type
+    //~| NOTE while checking the return type of the `async fn`
+    //~| NOTE in this expansion of desugaring of `async` block or function
     Tuple(1i32)
 }
 
@@ -92,7 +94,6 @@ async fn match_() {
         Tuple(_) => {} //~ ERROR mismatched types
         //~^ NOTE expected opaque type, found struct `Tuple`
         //~| NOTE expected opaque type `impl Future`
-        //~| NOTE while checking the return type of the `async fn`
     }
 }
 
diff --git a/src/test/ui/async-await/issue-61076.stderr b/src/test/ui/async-await/issue-61076.stderr
index ba97e135790c1..9fb2d5bc6cb42 100644
--- a/src/test/ui/async-await/issue-61076.stderr
+++ b/src/test/ui/async-await/issue-61076.stderr
@@ -16,7 +16,7 @@ LL |     foo().await?;
    |          ^^^^^^
 
 error[E0277]: the `?` operator can only be applied to values that implement `Try`
-  --> $DIR/issue-61076.rs:65:5
+  --> $DIR/issue-61076.rs:67:5
    |
 LL |     t?;
    |     ^^ the `?` operator cannot be applied to type `T`
@@ -33,7 +33,7 @@ LL |     t.await?;
    |      ^^^^^^
 
 error[E0609]: no field `0` on type `impl Future`
-  --> $DIR/issue-61076.rs:76:26
+  --> $DIR/issue-61076.rs:78:26
    |
 LL |     let _: i32 = tuple().0;
    |                          ^ field not available in `impl Future`, but it is available in its `Output`
@@ -44,7 +44,7 @@ LL |     let _: i32 = tuple().await.0;
    |                         ^^^^^^
 
 error[E0609]: no field `a` on type `impl Future`
-  --> $DIR/issue-61076.rs:80:28
+  --> $DIR/issue-61076.rs:82:28
    |
 LL |     let _: i32 = struct_().a;
    |                            ^ field not available in `impl Future`, but it is available in its `Output`
@@ -55,7 +55,7 @@ LL |     let _: i32 = struct_().await.a;
    |                           ^^^^^^
 
 error[E0599]: no method named `method` found for opaque type `impl Future` in the current scope
-  --> $DIR/issue-61076.rs:84:15
+  --> $DIR/issue-61076.rs:86:15
    |
 LL |     struct_().method();
    |               ^^^^^^ method not found in `impl Future`
@@ -66,15 +66,16 @@ LL |     struct_().await.method();
    |               ^^^^^^
 
 error[E0308]: mismatched types
-  --> $DIR/issue-61076.rs:92:9
+  --> $DIR/issue-61076.rs:94:9
    |
-LL | async fn tuple() -> Tuple {
-   |                     ----- checked the `Output` of this `async fn`, expected opaque type
-...
 LL |         Tuple(_) => {}
    |         ^^^^^^^^ expected opaque type, found struct `Tuple`
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/issue-61076.rs:58:21
+   |
+LL | async fn tuple() -> Tuple {
+   |                     ^^^^^ checked the `Output` of this `async fn`, expected opaque type
    = note: expected opaque type `impl Future`
                    found struct `Tuple`
 help: consider `await`ing on the `Future`
diff --git a/src/test/ui/async-await/suggest-missing-await-closure.stderr b/src/test/ui/async-await/suggest-missing-await-closure.stderr
index 483e52536a1b4..9d742049046b2 100644
--- a/src/test/ui/async-await/suggest-missing-await-closure.stderr
+++ b/src/test/ui/async-await/suggest-missing-await-closure.stderr
@@ -1,13 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/suggest-missing-await-closure.rs:16:18
    |
-LL | async fn make_u32() -> u32 {
-   |                        --- checked the `Output` of this `async fn`, found opaque type
-...
 LL |         take_u32(x)
    |                  ^ expected `u32`, found opaque type
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/suggest-missing-await-closure.rs:8:24
+   |
+LL | async fn make_u32() -> u32 {
+   |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future`
 help: consider `await`ing on the `Future`
diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr
index 14b5ee95ee8ba..890f66c58d0f8 100644
--- a/src/test/ui/async-await/suggest-missing-await.stderr
+++ b/src/test/ui/async-await/suggest-missing-await.stderr
@@ -1,13 +1,14 @@
 error[E0308]: mismatched types
   --> $DIR/suggest-missing-await.rs:12:14
    |
-LL | async fn make_u32() -> u32 {
-   |                        --- checked the `Output` of this `async fn`, found opaque type
-...
 LL |     take_u32(x)
    |              ^ expected `u32`, found opaque type
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/suggest-missing-await.rs:5:24
+   |
+LL | async fn make_u32() -> u32 {
+   |                        ^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `u32`
            found opaque type `impl Future`
 help: consider `await`ing on the `Future`
@@ -18,13 +19,14 @@ LL |     take_u32(x.await)
 error[E0308]: mismatched types
   --> $DIR/suggest-missing-await.rs:22:5
    |
-LL | async fn dummy() {}
-   |                  - checked the `Output` of this `async fn`, found opaque type
-...
 LL |     dummy()
    |     ^^^^^^^ expected `()`, found opaque type
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/suggest-missing-await.rs:18:18
+   |
+LL | async fn dummy() {}
+   |                  ^ checked the `Output` of this `async fn`, found opaque type
    = note: expected unit type `()`
             found opaque type `impl Future`
 help: consider `await`ing on the `Future`
diff --git a/src/test/ui/attributes/key-value-non-ascii.stderr b/src/test/ui/attributes/key-value-non-ascii.stderr
index 1d4b0d5b2b130..01a07ad3b0ee4 100644
--- a/src/test/ui/attributes/key-value-non-ascii.stderr
+++ b/src/test/ui/attributes/key-value-non-ascii.stderr
@@ -2,10 +2,12 @@ error: non-ASCII character in byte constant
   --> $DIR/key-value-non-ascii.rs:3:19
    |
 LL | #[rustc_dummy = b"ffi.rs"]
-   |                   ^
-   |                   |
-   |                   byte constant must be ASCII
-   |                   help: use a \xHH escape for a non-ASCII byte: `\xFB03`
+   |                   ^ byte constant must be ASCII
+   |
+help: if you meant to use the UTF-8 encoding of 'ffi', use \xHH escapes
+   |
+LL | #[rustc_dummy = b"/xEF/xAC/x83.rs"]
+   |                   ^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs
new file mode 100644
index 0000000000000..832a3e3b7b10d
--- /dev/null
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.rs
@@ -0,0 +1,7 @@
+#![feature(explicit_generic_args_with_impl_trait)]
+
+fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+
+fn main() {
+    foo::<str, String>("".to_string()); //~ ERROR E0107
+}
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
new file mode 100644
index 0000000000000..739e55e294381
--- /dev/null
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args-for-impl.stderr
@@ -0,0 +1,17 @@
+error[E0107]: this function takes at most 1 generic argument but 2 generic arguments were supplied
+  --> $DIR/explicit-generic-args-for-impl.rs:6:5
+   |
+LL |     foo::<str, String>("".to_string());
+   |     ^^^        ------ help: remove this generic argument
+   |     |
+   |     expected at most 1 generic argument
+   |
+note: function defined here, with at most 1 generic parameter: `T`
+  --> $DIR/explicit-generic-args-for-impl.rs:3:4
+   |
+LL | fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+   |    ^^^ -
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs
new file mode 100644
index 0000000000000..a6585bcf84862
--- /dev/null
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/explicit-generic-args.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![feature(explicit_generic_args_with_impl_trait)]
+
+fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+
+fn main() {
+    foo::<str>("".to_string());
+}
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs
new file mode 100644
index 0000000000000..0e4d6986d46ec
--- /dev/null
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.rs
@@ -0,0 +1,7 @@
+// gate-test-explicit_generic_args_with_impl_trait
+
+fn foo<T: ?Sized>(_f: impl AsRef<T>) {}
+
+fn main() {
+    foo::<str>("".to_string()); //~ ERROR E0632
+}
diff --git a/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr
new file mode 100644
index 0000000000000..6adc4e6b23968
--- /dev/null
+++ b/src/test/ui/impl-trait/explicit-generic-args-with-impl-trait/feature-gate.stderr
@@ -0,0 +1,9 @@
+error[E0632]: cannot provide explicit generic arguments when `impl Trait` is used in argument position
+  --> $DIR/feature-gate.rs:6:11
+   |
+LL |     foo::<str>("".to_string());
+   |           ^^^ explicit generic argument not allowed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0632`.
diff --git a/src/test/ui/parser/byte-literals.stderr b/src/test/ui/parser/byte-literals.stderr
index 55be113e16b99..b9fb42088d9d3 100644
--- a/src/test/ui/parser/byte-literals.stderr
+++ b/src/test/ui/parser/byte-literals.stderr
@@ -36,10 +36,12 @@ error: non-ASCII character in byte constant
   --> $DIR/byte-literals.rs:10:7
    |
 LL |     b'é';
-   |       ^
-   |       |
-   |       byte constant must be ASCII
-   |       help: use a \xHH escape for a non-ASCII byte: `\xE9`
+   |       ^ byte constant must be ASCII
+   |
+help: if you meant to use the unicode code point for 'é', use a \xHH escape
+   |
+LL |     b'\xE9';
+   |       ^^^^
 
 error[E0763]: unterminated byte constant
   --> $DIR/byte-literals.rs:11:6
diff --git a/src/test/ui/parser/byte-string-literals.stderr b/src/test/ui/parser/byte-string-literals.stderr
index 3a5a8b331d339..4f22a16224f0c 100644
--- a/src/test/ui/parser/byte-string-literals.stderr
+++ b/src/test/ui/parser/byte-string-literals.stderr
@@ -24,10 +24,12 @@ error: non-ASCII character in byte constant
   --> $DIR/byte-string-literals.rs:6:7
    |
 LL |     b"é";
-   |       ^
-   |       |
-   |       byte constant must be ASCII
-   |       help: use a \xHH escape for a non-ASCII byte: `\xE9`
+   |       ^ byte constant must be ASCII
+   |
+help: if you meant to use the unicode code point for 'é', use a \xHH escape
+   |
+LL |     b"\xE9";
+   |       ^^^^
 
 error: raw byte string must be ASCII
   --> $DIR/byte-string-literals.rs:7:10
diff --git a/src/test/ui/suggestions/issue-81839.stderr b/src/test/ui/suggestions/issue-81839.stderr
index f907658708730..1e0aa9ce40d18 100644
--- a/src/test/ui/suggestions/issue-81839.stderr
+++ b/src/test/ui/suggestions/issue-81839.stderr
@@ -13,13 +13,12 @@ LL | |         _ => cx.answer_str("hi"),
    | |              ^^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
 LL | |     }
    | |_____- `match` arms have incompatible types
-   | 
-  ::: $DIR/auxiliary/issue-81839.rs:6:49
    |
-LL |       pub async fn answer_str(&self, _s: &str) -> Test {
-   |                                                   ---- checked the `Output` of this `async fn`, found opaque type
+note: while checking the return type of the `async fn`
+  --> $DIR/auxiliary/issue-81839.rs:6:49
    |
-   = note: while checking the return type of the `async fn`
+LL |     pub async fn answer_str(&self, _s: &str) -> Test {
+   |                                                 ^^^^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `()`
            found opaque type `impl Future`
 
diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
index 3b2cff3140d63..990a4469764f0 100644
--- a/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
+++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.rs
@@ -14,8 +14,14 @@ fn extra_semicolon() {
 }
 
 async fn async_dummy() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
+//~| NOTE while checking the return type of the `async fn`
+//~| NOTE in this expansion of desugaring of `async` block or function
 async fn async_dummy2() {} //~ NOTE checked the `Output` of this `async fn`, found opaque type
 //~| NOTE checked the `Output` of this `async fn`, found opaque type
+//~| NOTE while checking the return type of the `async fn`
+//~| NOTE in this expansion of desugaring of `async` block or function
+//~| NOTE while checking the return type of the `async fn`
+//~| NOTE in this expansion of desugaring of `async` block or function
 
 async fn async_extra_semicolon_same() {
     let _ = match true { //~ NOTE `match` arms have incompatible types
@@ -26,7 +32,6 @@ async fn async_extra_semicolon_same() {
         false => async_dummy(), //~ ERROR `match` arms have incompatible types
         //~^ NOTE expected `()`, found opaque type
         //~| NOTE expected type `()`
-        //~| NOTE while checking the return type of the `async fn`
         //~| HELP consider `await`ing on the `Future`
     };
 }
@@ -40,7 +45,6 @@ async fn async_extra_semicolon_different() {
         false => async_dummy2(), //~ ERROR `match` arms have incompatible types
         //~^ NOTE expected `()`, found opaque type
         //~| NOTE expected type `()`
-        //~| NOTE while checking the return type of the `async fn`
         //~| HELP consider `await`ing on the `Future`
     };
 }
@@ -53,7 +57,6 @@ async fn async_different_futures() {
         //~^ NOTE expected opaque type, found a different opaque type
         //~| NOTE expected type `impl Future`
         //~| NOTE distinct uses of `impl Trait` result in different opaque types
-        //~| NOTE while checking the return type of the `async fn`
     };
 }
 
diff --git a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
index e31ea9679b51d..9e64b539f0fdc 100644
--- a/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
+++ b/src/test/ui/suggestions/match-prev-arm-needing-semi.stderr
@@ -1,9 +1,6 @@
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:26:18
+  --> $DIR/match-prev-arm-needing-semi.rs:32:18
    |
-LL |   async fn async_dummy() {}
-   |                          - checked the `Output` of this `async fn`, found opaque type
-...
 LL |       let _ = match true {
    |  _____________-
 LL | |         true => {
@@ -18,7 +15,11 @@ LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/match-prev-arm-needing-semi.rs:16:24
+   |
+LL | async fn async_dummy() {}
+   |                        ^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `()`
            found opaque type `impl Future`
 help: consider `await`ing on the `Future`
@@ -31,11 +32,8 @@ LL |             async_dummy()
    |                         --
 
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:40:18
+  --> $DIR/match-prev-arm-needing-semi.rs:45:18
    |
-LL |   async fn async_dummy2() {}
-   |                           - checked the `Output` of this `async fn`, found opaque type
-...
 LL |       let _ = match true {
    |  _____________-
 LL | |         true => {
@@ -50,7 +48,11 @@ LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/match-prev-arm-needing-semi.rs:19:25
+   |
+LL | async fn async_dummy2() {}
+   |                         ^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `()`
            found opaque type `impl Future`
 help: consider `await`ing on the `Future`
@@ -66,11 +68,8 @@ LL |         false => Box::new(async_dummy2()),
    |
 
 error[E0308]: `match` arms have incompatible types
-  --> $DIR/match-prev-arm-needing-semi.rs:52:18
+  --> $DIR/match-prev-arm-needing-semi.rs:56:18
    |
-LL |   async fn async_dummy2() {}
-   |                           - checked the `Output` of this `async fn`, found opaque type
-...
 LL |       let _ = match true {
    |  _____________-
 LL | |         true => async_dummy(),
@@ -83,9 +82,13 @@ LL | |
 LL | |     };
    | |_____- `match` arms have incompatible types
    |
-   = note: while checking the return type of the `async fn`
+note: while checking the return type of the `async fn`
+  --> $DIR/match-prev-arm-needing-semi.rs:19:25
+   |
+LL | async fn async_dummy2() {}
+   |                         ^ checked the `Output` of this `async fn`, found opaque type
    = note:     expected type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:16:24>)
-           found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:17:25>)
+           found opaque type `impl Future` (opaque type at <$DIR/match-prev-arm-needing-semi.rs:19:25>)
    = note: distinct uses of `impl Trait` result in different opaque types
 help: consider `await`ing on both `Future`s
    |
diff --git a/src/test/ui/suggestions/multibyte-escapes.rs b/src/test/ui/suggestions/multibyte-escapes.rs
new file mode 100644
index 0000000000000..fd5d46a4e923e
--- /dev/null
+++ b/src/test/ui/suggestions/multibyte-escapes.rs
@@ -0,0 +1,18 @@
+// Regression test for #87397.
+
+fn main() {
+    b'µ';
+    //~^ ERROR: non-ASCII character in byte constant
+    //~| HELP: if you meant to use the unicode code point for 'µ', use a \xHH escape
+    //~| NOTE: byte constant must be ASCII
+
+    b'字';
+    //~^ ERROR: non-ASCII character in byte constant
+    //~| NOTE: this multibyte character does not fit into a single byte
+    //~| NOTE: byte constant must be ASCII
+
+    b"字";
+    //~^ ERROR: non-ASCII character in byte constant
+    //~| HELP: if you meant to use the UTF-8 encoding of '字', use \xHH escapes
+    //~| NOTE: byte constant must be ASCII
+}
diff --git a/src/test/ui/suggestions/multibyte-escapes.stderr b/src/test/ui/suggestions/multibyte-escapes.stderr
new file mode 100644
index 0000000000000..bb4f8e8c304a1
--- /dev/null
+++ b/src/test/ui/suggestions/multibyte-escapes.stderr
@@ -0,0 +1,33 @@
+error: non-ASCII character in byte constant
+  --> $DIR/multibyte-escapes.rs:4:7
+   |
+LL |     b'µ';
+   |       ^ byte constant must be ASCII
+   |
+help: if you meant to use the unicode code point for 'µ', use a \xHH escape
+   |
+LL |     b'\xB5';
+   |       ^^^^
+
+error: non-ASCII character in byte constant
+  --> $DIR/multibyte-escapes.rs:9:7
+   |
+LL |     b'字';
+   |       ^^
+   |       |
+   |       byte constant must be ASCII
+   |       this multibyte character does not fit into a single byte
+
+error: non-ASCII character in byte constant
+  --> $DIR/multibyte-escapes.rs:14:7
+   |
+LL |     b"字";
+   |       ^^ byte constant must be ASCII
+   |
+help: if you meant to use the UTF-8 encoding of '字', use \xHH escapes
+   |
+LL |     b"\xE5\xAD\x97";
+   |       ^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+