about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs27
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs49
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs11
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs6
-rw-r--r--compiler/rustc_error_codes/src/error_codes.rs1
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0744.md4
-rw-r--r--compiler/rustc_hir/src/hir.rs153
-rw-r--r--compiler/rustc_infer/src/infer/at.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs16
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs5
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs1
-rw-r--r--compiler/rustc_lint/src/unused.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs10
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs6
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs4
-rw-r--r--compiler/rustc_passes/src/check_const.rs9
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--library/alloc/src/alloc.rs3
-rw-r--r--library/alloc/src/collections/mod.rs1
-rw-r--r--library/alloc/src/rc.rs1
-rw-r--r--library/alloc/src/sync.rs1
-rw-r--r--library/alloc/src/vec/mod.rs5
-rw-r--r--library/core/src/lib.rs5
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/sys/xous/mod.rs1
-rw-r--r--library/std/src/sys/xous/thread_parking.rs94
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/precedence.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs2
-rw-r--r--src/tools/rustfmt/src/expr.rs2
-rw-r--r--src/tools/rustfmt/src/pairs.rs2
-rw-r--r--tests/ui/async-await/issue-70594.rs3
-rw-r--r--tests/ui/async-await/issue-70594.stderr37
-rw-r--r--tests/ui/async-await/issues/issue-62009-1.rs1
-rw-r--r--tests/ui/async-await/issues/issue-62009-1.stderr18
-rw-r--r--tests/ui/coroutine/auxiliary/unwind-aux.rs11
-rw-r--r--tests/ui/coroutine/unwind-abort-mix.rs13
39 files changed, 220 insertions, 325 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 10776f31c07..2b56e9f3a86 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -817,7 +817,7 @@ pub enum BorrowKind {
     Raw,
 }
 
-#[derive(Clone, PartialEq, Encodable, Decodable, Debug, Copy)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum BinOpKind {
     /// The `+` operator (addition)
     Add,
@@ -858,9 +858,9 @@ pub enum BinOpKind {
 }
 
 impl BinOpKind {
-    pub fn to_string(&self) -> &'static str {
+    pub fn as_str(&self) -> &'static str {
         use BinOpKind::*;
-        match *self {
+        match self {
             Add => "+",
             Sub => "-",
             Mul => "*",
@@ -881,19 +881,25 @@ impl BinOpKind {
             Gt => ">",
         }
     }
-    pub fn lazy(&self) -> bool {
+
+    pub fn is_lazy(&self) -> bool {
         matches!(self, BinOpKind::And | BinOpKind::Or)
     }
 
     pub fn is_comparison(&self) -> bool {
         use BinOpKind::*;
-        // Note for developers: please keep this as is;
+        // Note for developers: please keep this match exhaustive;
         // we want compilation to fail if another variant is added.
         match *self {
             Eq | Lt | Le | Ne | Gt | Ge => true,
             And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
         }
     }
+
+    /// Returns `true` if the binary operator takes its arguments by value.
+    pub fn is_by_value(self) -> bool {
+        !self.is_comparison()
+    }
 }
 
 pub type BinOp = Spanned<BinOpKind>;
@@ -901,7 +907,7 @@ pub type BinOp = Spanned<BinOpKind>;
 /// Unary operator.
 ///
 /// Note that `&data` is not an operator, it's an `AddrOf` expression.
-#[derive(Clone, Encodable, Decodable, Debug, Copy)]
+#[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable, HashStable_Generic)]
 pub enum UnOp {
     /// The `*` operator for dereferencing
     Deref,
@@ -912,13 +918,18 @@ pub enum UnOp {
 }
 
 impl UnOp {
-    pub fn to_string(op: UnOp) -> &'static str {
-        match op {
+    pub fn as_str(&self) -> &'static str {
+        match self {
             UnOp::Deref => "*",
             UnOp::Not => "!",
             UnOp::Neg => "-",
         }
     }
+
+    /// Returns `true` if the unary operator takes its argument by value.
+    pub fn is_by_value(self) -> bool {
+        matches!(self, Self::Neg | Self::Not)
+    }
 }
 
 /// A statement
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 068f2199105..be5671f1bf7 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -72,7 +72,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             let kind = match &e.kind {
                 ExprKind::Array(exprs) => hir::ExprKind::Array(self.lower_exprs(exprs)),
                 ExprKind::ConstBlock(c) => {
-                    let c = self.with_new_scopes(|this| hir::ConstBlock {
+                    let c = self.with_new_scopes(c.value.span, |this| hir::ConstBlock {
                         def_id: this.local_def_id(c.id),
                         hir_id: this.lower_node_id(c.id),
                         body: this.lower_const_body(c.value.span, Some(&c.value)),
@@ -189,7 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     None,
                     e.span,
                     hir::CoroutineSource::Block,
-                    |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
+                    |this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
                 ),
                 ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
                 ExprKind::Closure(box Closure {
@@ -323,7 +323,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     None,
                     e.span,
                     hir::CoroutineSource::Block,
-                    |this| this.with_new_scopes(|this| this.lower_block_expr(block)),
+                    |this| this.with_new_scopes(e.span, |this| this.lower_block_expr(block)),
                 ),
                 ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
                 ExprKind::Err => hir::ExprKind::Err(
@@ -350,30 +350,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         }
     }
 
-    fn lower_binop(&mut self, b: BinOp) -> hir::BinOp {
-        Spanned {
-            node: match b.node {
-                BinOpKind::Add => hir::BinOpKind::Add,
-                BinOpKind::Sub => hir::BinOpKind::Sub,
-                BinOpKind::Mul => hir::BinOpKind::Mul,
-                BinOpKind::Div => hir::BinOpKind::Div,
-                BinOpKind::Rem => hir::BinOpKind::Rem,
-                BinOpKind::And => hir::BinOpKind::And,
-                BinOpKind::Or => hir::BinOpKind::Or,
-                BinOpKind::BitXor => hir::BinOpKind::BitXor,
-                BinOpKind::BitAnd => hir::BinOpKind::BitAnd,
-                BinOpKind::BitOr => hir::BinOpKind::BitOr,
-                BinOpKind::Shl => hir::BinOpKind::Shl,
-                BinOpKind::Shr => hir::BinOpKind::Shr,
-                BinOpKind::Eq => hir::BinOpKind::Eq,
-                BinOpKind::Lt => hir::BinOpKind::Lt,
-                BinOpKind::Le => hir::BinOpKind::Le,
-                BinOpKind::Ne => hir::BinOpKind::Ne,
-                BinOpKind::Ge => hir::BinOpKind::Ge,
-                BinOpKind::Gt => hir::BinOpKind::Gt,
-            },
-            span: self.lower_span(b.span),
-        }
+    fn lower_binop(&mut self, b: BinOp) -> BinOp {
+        Spanned { node: b.node, span: self.lower_span(b.span) }
     }
 
     fn lower_legacy_const_generics(
@@ -781,10 +759,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
         match self.coroutine_kind {
             Some(hir::CoroutineKind::Async(_)) => {}
             Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) | None => {
-                self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
+                return hir::ExprKind::Err(self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
                     await_kw_span,
                     item_span: self.current_item,
-                });
+                }));
             }
         }
         let span = self.mark_span_with_reason(DesugaringKind::Await, await_kw_span, None);
@@ -944,9 +922,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     ) -> hir::ExprKind<'hir> {
         let (binder_clause, generic_params) = self.lower_closure_binder(binder);
 
-        let (body_id, coroutine_option) = self.with_new_scopes(move |this| {
-            let prev = this.current_item;
-            this.current_item = Some(fn_decl_span);
+        let (body_id, coroutine_option) = self.with_new_scopes(fn_decl_span, move |this| {
             let mut coroutine_kind = None;
             let body_id = this.lower_fn_body(decl, |this| {
                 let e = this.lower_expr_mut(body);
@@ -955,7 +931,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             });
             let coroutine_option =
                 this.coroutine_movability_for_fn(decl, fn_decl_span, coroutine_kind, movability);
-            this.current_item = prev;
             (body_id, coroutine_option)
         });
 
@@ -1041,7 +1016,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let outer_decl =
             FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
 
-        let body = self.with_new_scopes(|this| {
+        let body = self.with_new_scopes(fn_decl_span, |this| {
             // FIXME(cramertj): allow `async` non-`move` closures with arguments.
             if capture_clause == CaptureBy::Ref && !decl.inputs.is_empty() {
                 this.tcx.sess.emit_err(AsyncNonMoveClosureNotSupported { fn_decl_span });
@@ -1063,7 +1038,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     async_ret_ty,
                     body.span,
                     hir::CoroutineSource::Closure,
-                    |this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
+                    |this| this.with_new_scopes(fn_decl_span, |this| this.lower_expr_mut(body)),
                 );
                 let hir_id = this.lower_node_id(inner_closure_id);
                 this.maybe_forward_track_caller(body.span, closure_hir_id, hir_id);
@@ -1503,7 +1478,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
         match self.coroutine_kind {
             Some(hir::CoroutineKind::Gen(_)) => {}
             Some(hir::CoroutineKind::Async(_)) => {
-                self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
+                return hir::ExprKind::Err(
+                    self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }),
+                );
             }
             Some(hir::CoroutineKind::Coroutine) | None => {
                 if !self.tcx.features().coroutines {
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index e9779a9bf94..c47c5fc8fcc 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -202,9 +202,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 body,
                 ..
             }) => {
-                self.with_new_scopes(|this| {
-                    this.current_item = Some(ident.span);
-
+                self.with_new_scopes(ident.span, |this| {
                     // Note: we don't need to change the return type from `T` to
                     // `impl Future<Output = T>` here because lower_body
                     // only cares about the input argument patterns in the function
@@ -837,7 +835,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 },
             ),
             AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
-                self.current_item = Some(i.span);
                 let asyncness = sig.header.asyncness;
                 let body_id = self.lower_maybe_async_body(
                     i.span,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1a92657ed48..4abd0f135c6 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -878,7 +878,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         result
     }
 
-    fn with_new_scopes<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
+    fn with_new_scopes<T>(&mut self, scope_span: Span, f: impl FnOnce(&mut Self) -> T) -> T {
+        let current_item = self.current_item;
+        self.current_item = Some(scope_span);
+
         let was_in_loop_condition = self.is_in_loop_condition;
         self.is_in_loop_condition = false;
 
@@ -890,6 +893,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
 
         self.is_in_loop_condition = was_in_loop_condition;
 
+        self.current_item = current_item;
+
         ret
     }
 
@@ -1239,7 +1244,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                     tokens: None,
                                 };
 
-                                let ct = self.with_new_scopes(|this| hir::AnonConst {
+                                let ct = self.with_new_scopes(span, |this| hir::AnonConst {
                                     def_id,
                                     hir_id: this.lower_node_id(node_id),
                                     body: this.lower_const_body(path_expr.span, Some(&path_expr)),
@@ -2246,7 +2251,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 
     fn lower_anon_const(&mut self, c: &AnonConst) -> hir::AnonConst {
-        self.with_new_scopes(|this| hir::AnonConst {
+        self.with_new_scopes(c.value.span, |this| hir::AnonConst {
             def_id: this.local_def_id(c.id),
             hir_id: this.lower_node_id(c.id),
             body: this.lower_const_body(c.value.span, Some(&c.value)),
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index ed9b68a1d5a..45a55e20ca7 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -255,12 +255,12 @@ impl<'a> State<'a> {
 
         self.print_expr_maybe_paren(lhs, left_prec);
         self.space();
-        self.word_space(op.node.to_string());
+        self.word_space(op.node.as_str());
         self.print_expr_maybe_paren(rhs, right_prec)
     }
 
     fn print_expr_unary(&mut self, op: ast::UnOp, expr: &ast::Expr) {
-        self.word(ast::UnOp::to_string(op));
+        self.word(op.as_str());
         self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
     }
 
@@ -470,7 +470,7 @@ impl<'a> State<'a> {
                 let prec = AssocOp::Assign.precedence() as i8;
                 self.print_expr_maybe_paren(lhs, prec + 1);
                 self.space();
-                self.word(op.node.to_string());
+                self.word(op.node.as_str());
                 self.word_space("=");
                 self.print_expr_maybe_paren(rhs, prec);
             }
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs
index 6680e8875c3..1028d43f9c5 100644
--- a/compiler/rustc_error_codes/src/error_codes.rs
+++ b/compiler/rustc_error_codes/src/error_codes.rs
@@ -653,3 +653,4 @@ E0795: include_str!("./error_codes/E0795.md"),
 //  E0721, // `await` keyword
 //  E0723, // unstable feature in `const` context
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
+//  E0744, // merged into E0728
diff --git a/compiler/rustc_error_codes/src/error_codes/E0744.md b/compiler/rustc_error_codes/src/error_codes/E0744.md
index 9a8ef3b840d..e56c45db176 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0744.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0744.md
@@ -1,8 +1,10 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 An unsupported expression was used inside a const context.
 
 Erroneous code example:
 
-```compile_fail,edition2018,E0744
+```ignore (removed error code)
 const _: i32 = {
     async { 0 }.await
 };
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index d2b83d0eb00..bd6eba37547 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -7,8 +7,8 @@ use crate::LangItem;
 use rustc_ast as ast;
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_ast::{Attribute, FloatTy, IntTy, Label, LitKind, TraitObjectSyntax, UintTy};
-pub use rustc_ast::{BindingAnnotation, BorrowKind, ByRef, ImplPolarity, IsAuto};
-pub use rustc_ast::{CaptureBy, Movability, Mutability};
+pub use rustc_ast::{BinOp, BinOpKind, BindingAnnotation, BorrowKind, ByRef, CaptureBy};
+pub use rustc_ast::{ImplPolarity, IsAuto, Movability, Mutability, UnOp};
 use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
@@ -1174,155 +1174,6 @@ pub enum PatKind<'hir> {
     Slice(&'hir [Pat<'hir>], Option<&'hir Pat<'hir>>, &'hir [Pat<'hir>]),
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
-pub enum BinOpKind {
-    /// The `+` operator (addition).
-    Add,
-    /// The `-` operator (subtraction).
-    Sub,
-    /// The `*` operator (multiplication).
-    Mul,
-    /// The `/` operator (division).
-    Div,
-    /// The `%` operator (modulus).
-    Rem,
-    /// The `&&` operator (logical and).
-    And,
-    /// The `||` operator (logical or).
-    Or,
-    /// The `^` operator (bitwise xor).
-    BitXor,
-    /// The `&` operator (bitwise and).
-    BitAnd,
-    /// The `|` operator (bitwise or).
-    BitOr,
-    /// The `<<` operator (shift left).
-    Shl,
-    /// The `>>` operator (shift right).
-    Shr,
-    /// The `==` operator (equality).
-    Eq,
-    /// The `<` operator (less than).
-    Lt,
-    /// The `<=` operator (less than or equal to).
-    Le,
-    /// The `!=` operator (not equal to).
-    Ne,
-    /// The `>=` operator (greater than or equal to).
-    Ge,
-    /// The `>` operator (greater than).
-    Gt,
-}
-
-impl BinOpKind {
-    pub fn as_str(self) -> &'static str {
-        match self {
-            BinOpKind::Add => "+",
-            BinOpKind::Sub => "-",
-            BinOpKind::Mul => "*",
-            BinOpKind::Div => "/",
-            BinOpKind::Rem => "%",
-            BinOpKind::And => "&&",
-            BinOpKind::Or => "||",
-            BinOpKind::BitXor => "^",
-            BinOpKind::BitAnd => "&",
-            BinOpKind::BitOr => "|",
-            BinOpKind::Shl => "<<",
-            BinOpKind::Shr => ">>",
-            BinOpKind::Eq => "==",
-            BinOpKind::Lt => "<",
-            BinOpKind::Le => "<=",
-            BinOpKind::Ne => "!=",
-            BinOpKind::Ge => ">=",
-            BinOpKind::Gt => ">",
-        }
-    }
-
-    pub fn is_lazy(self) -> bool {
-        matches!(self, BinOpKind::And | BinOpKind::Or)
-    }
-
-    pub fn is_comparison(self) -> bool {
-        match self {
-            BinOpKind::Eq
-            | BinOpKind::Lt
-            | BinOpKind::Le
-            | BinOpKind::Ne
-            | BinOpKind::Gt
-            | BinOpKind::Ge => true,
-            BinOpKind::And
-            | BinOpKind::Or
-            | BinOpKind::Add
-            | BinOpKind::Sub
-            | BinOpKind::Mul
-            | BinOpKind::Div
-            | BinOpKind::Rem
-            | BinOpKind::BitXor
-            | BinOpKind::BitAnd
-            | BinOpKind::BitOr
-            | BinOpKind::Shl
-            | BinOpKind::Shr => false,
-        }
-    }
-
-    /// Returns `true` if the binary operator takes its arguments by value.
-    pub fn is_by_value(self) -> bool {
-        !self.is_comparison()
-    }
-}
-
-impl Into<ast::BinOpKind> for BinOpKind {
-    fn into(self) -> ast::BinOpKind {
-        match self {
-            BinOpKind::Add => ast::BinOpKind::Add,
-            BinOpKind::Sub => ast::BinOpKind::Sub,
-            BinOpKind::Mul => ast::BinOpKind::Mul,
-            BinOpKind::Div => ast::BinOpKind::Div,
-            BinOpKind::Rem => ast::BinOpKind::Rem,
-            BinOpKind::And => ast::BinOpKind::And,
-            BinOpKind::Or => ast::BinOpKind::Or,
-            BinOpKind::BitXor => ast::BinOpKind::BitXor,
-            BinOpKind::BitAnd => ast::BinOpKind::BitAnd,
-            BinOpKind::BitOr => ast::BinOpKind::BitOr,
-            BinOpKind::Shl => ast::BinOpKind::Shl,
-            BinOpKind::Shr => ast::BinOpKind::Shr,
-            BinOpKind::Eq => ast::BinOpKind::Eq,
-            BinOpKind::Lt => ast::BinOpKind::Lt,
-            BinOpKind::Le => ast::BinOpKind::Le,
-            BinOpKind::Ne => ast::BinOpKind::Ne,
-            BinOpKind::Ge => ast::BinOpKind::Ge,
-            BinOpKind::Gt => ast::BinOpKind::Gt,
-        }
-    }
-}
-
-pub type BinOp = Spanned<BinOpKind>;
-
-#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
-pub enum UnOp {
-    /// The `*` operator (dereferencing).
-    Deref,
-    /// The `!` operator (logical negation).
-    Not,
-    /// The `-` operator (negation).
-    Neg,
-}
-
-impl UnOp {
-    pub fn as_str(self) -> &'static str {
-        match self {
-            Self::Deref => "*",
-            Self::Not => "!",
-            Self::Neg => "-",
-        }
-    }
-
-    /// Returns `true` if the unary operator takes its argument by value.
-    pub fn is_by_value(self) -> bool {
-        matches!(self, Self::Neg | Self::Not)
-    }
-}
-
 /// A statement.
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub struct Stmt<'hir> {
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index c32c3aa6d29..09313cd9738 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -448,7 +448,11 @@ impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> {
     ) -> TypeTrace<'tcx> {
         TypeTrace {
             cause: cause.clone(),
-            values: TraitRefs(ExpectedFound::new(a_is_expected, a, b)),
+            values: PolyTraitRefs(ExpectedFound::new(
+                a_is_expected,
+                ty::Binder::dummy(a),
+                ty::Binder::dummy(b),
+            )),
         }
     }
 }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index bf9edb5b83d..3be23796550 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1667,9 +1667,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             .report(diag);
                         (false, Mismatch::Fixed("signature"))
                     }
-                    ValuePairs::TraitRefs(_) | ValuePairs::PolyTraitRefs(_) => {
-                        (false, Mismatch::Fixed("trait"))
-                    }
+                    ValuePairs::PolyTraitRefs(_) => (false, Mismatch::Fixed("trait")),
                     ValuePairs::Aliases(infer::ExpectedFound { expected, .. }) => {
                         (false, Mismatch::Fixed(self.tcx.def_descr(expected.def_id)))
                     }
@@ -2219,18 +2217,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             infer::Aliases(exp_found) => self.expected_found_str(exp_found),
             infer::ExistentialTraitRef(exp_found) => self.expected_found_str(exp_found),
             infer::ExistentialProjection(exp_found) => self.expected_found_str(exp_found),
-            infer::TraitRefs(exp_found) => {
-                let pretty_exp_found = ty::error::ExpectedFound {
-                    expected: exp_found.expected.print_only_trait_path(),
-                    found: exp_found.found.print_only_trait_path(),
-                };
-                match self.expected_found_str(pretty_exp_found) {
-                    Some((expected, found, _, _)) if expected == found => {
-                        self.expected_found_str(exp_found)
-                    }
-                    ret => ret,
-                }
-            }
             infer::PolyTraitRefs(exp_found) => {
                 let pretty_exp_found = ty::error::ExpectedFound {
                     expected: exp_found.expected.print_only_trait_path(),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index c38e5b8cd09..d98ca995d71 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -197,11 +197,6 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
         value_pairs: &ValuePairs<'tcx>,
     ) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
         let (expected_args, found_args, trait_def_id) = match value_pairs {
-            ValuePairs::TraitRefs(ExpectedFound { expected, found })
-                if expected.def_id == found.def_id =>
-            {
-                (expected.args, found.args, expected.def_id)
-            }
             ValuePairs::PolyTraitRefs(ExpectedFound { expected, found })
                 if expected.def_id() == found.def_id() =>
             {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 24c5d7bbe21..bb16d97eb85 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -384,7 +384,6 @@ pub enum ValuePairs<'tcx> {
     Regions(ExpectedFound<ty::Region<'tcx>>),
     Terms(ExpectedFound<ty::Term<'tcx>>),
     Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
-    TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
     PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
     ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index b4535c72d6c..a7a4709e887 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -656,7 +656,7 @@ trait UnusedDelimLint {
     ) -> bool {
         if followed_by_else {
             match inner.kind {
-                ast::ExprKind::Binary(op, ..) if op.node.lazy() => return true,
+                ast::ExprKind::Binary(op, ..) if op.node.is_lazy() => return true,
                 _ if classify::expr_trailing_brace(inner).is_some() => return true,
                 _ => {}
             }
@@ -1016,7 +1016,7 @@ impl UnusedDelimLint for UnusedParens {
                                 rustc_span::source_map::Spanned { node, .. },
                                 _,
                                 _,
-                            ) if node.lazy()))
+                            ) if node.is_lazy()))
                 {
                     self.emit_unused_delims_expr(cx, value, ctx, left_pos, right_pos, is_kw)
                 }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 1cb1a9886a0..d626fed3275 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -51,7 +51,6 @@
 //! Otherwise it drops all the values in scope at the last suspension point.
 
 use crate::abort_unwinding_calls;
-use crate::add_call_guards;
 use crate::deref_separator::deref_finder;
 use crate::errors;
 use crate::pass_manager as pm;
@@ -1168,18 +1167,9 @@ fn create_coroutine_drop_shim<'tcx>(
     simplify::remove_dead_blocks(&mut body);
 
     // Update the body's def to become the drop glue.
-    // This needs to be updated before the AbortUnwindingCalls pass.
     let coroutine_instance = body.source.instance;
     let drop_in_place = tcx.require_lang_item(LangItem::DropInPlace, None);
     let drop_instance = InstanceDef::DropGlue(drop_in_place, Some(coroutine_ty));
-    body.source.instance = drop_instance;
-
-    pm::run_passes_no_validate(
-        tcx,
-        &mut body,
-        &[&abort_unwinding_calls::AbortUnwindingCalls, &add_call_guards::CriticalCallEdges],
-        None,
-    );
 
     // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible
     // filename.
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index f24a2d07e49..fba73d5195b 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -74,11 +74,13 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
                 let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
                 debug!("make_shim({:?}) = {:?}", instance, body);
 
-                // Run empty passes to mark phase change and perform validation.
                 pm::run_passes(
                     tcx,
                     &mut body,
-                    &[],
+                    &[
+                        &abort_unwinding_calls::AbortUnwindingCalls,
+                        &add_call_guards::CriticalCallEdges,
+                    ],
                     Some(MirPhase::Runtime(RuntimePhase::Optimized)),
                 );
 
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 620ba4a3cb3..1ee5a96d5dc 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -384,10 +384,10 @@ impl<'a> Parser<'a> {
 
     fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
         if let ast::ExprKind::Binary(op, ..) = init.kind {
-            if op.node.lazy() {
+            if op.node.is_lazy() {
                 self.sess.emit_err(errors::InvalidExpressionInLetElse {
                     span: init.span,
-                    operator: op.node.to_string(),
+                    operator: op.node.as_str(),
                     sugg: errors::WrapExpressionInParentheses {
                         left: init.span.shrink_to_lo(),
                         right: init.span.shrink_to_hi(),
diff --git a/compiler/rustc_passes/src/check_const.rs b/compiler/rustc_passes/src/check_const.rs
index de96746e215..76c7467346d 100644
--- a/compiler/rustc_passes/src/check_const.rs
+++ b/compiler/rustc_passes/src/check_const.rs
@@ -17,7 +17,7 @@ use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_span::{sym, Span, Symbol};
 
-use crate::errors::{ExprNotAllowedInContext, SkippingConstChecks};
+use crate::errors::SkippingConstChecks;
 
 /// An expression that is not *always* legal in a const context.
 #[derive(Clone, Copy)]
@@ -138,11 +138,10 @@ impl<'tcx> CheckConstVisitor<'tcx> {
 
         match missing_gates.as_slice() {
             [] => {
-                tcx.sess.emit_err(ExprNotAllowedInContext {
+                span_bug!(
                     span,
-                    expr: expr.name(),
-                    context: const_kind.keyword_name(),
-                });
+                    "we should not have reached this point, since `.await` is denied earlier"
+                );
             }
 
             [missing_primary, ref missing_secondary @ ..] => {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 411c9410195..58127445322 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1005,15 +1005,6 @@ pub struct FeaturePreviouslyDeclared<'a, 'b> {
     pub prev_declared: &'b str,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_expr_not_allowed_in_context, code = "E0744")]
-pub struct ExprNotAllowedInContext<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub expr: String,
-    pub context: &'a str,
-}
-
 pub struct BreakNonLoop<'a> {
     pub span: Span,
     pub head: Option<Span>,
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index 2499f1053d8..1663aa84921 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -423,12 +423,14 @@ pub mod __alloc_error_handler {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 /// Specialize clones into pre-allocated, uninitialized memory.
 /// Used by `Box::clone` and `Rc`/`Arc::make_mut`.
 pub(crate) trait WriteCloneIntoRaw: Sized {
     unsafe fn write_clone_into_raw(&self, target: *mut Self);
 }
 
+#[cfg(not(no_global_oom_handling))]
 impl<T: Clone> WriteCloneIntoRaw for T {
     #[inline]
     default unsafe fn write_clone_into_raw(&self, target: *mut Self) {
@@ -438,6 +440,7 @@ impl<T: Clone> WriteCloneIntoRaw for T {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 impl<T: Copy> WriteCloneIntoRaw for T {
     #[inline]
     unsafe fn write_clone_into_raw(&self, target: *mut Self) {
diff --git a/library/alloc/src/collections/mod.rs b/library/alloc/src/collections/mod.rs
index 3e0b0f73550..705b81535c2 100644
--- a/library/alloc/src/collections/mod.rs
+++ b/library/alloc/src/collections/mod.rs
@@ -148,6 +148,7 @@ impl Display for TryReserveError {
 
 /// An intermediate trait for specialization of `Extend`.
 #[doc(hidden)]
+#[cfg(not(no_global_oom_handling))]
 trait SpecExtend<I: IntoIterator> {
     /// Extends `self` with the contents of the given iterator.
     fn spec_extend(&mut self, iter: I);
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index dd7876bed76..98983e670d0 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2023,6 +2023,7 @@ impl<T, A: Allocator> Rc<[T], A> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 /// Specialization trait used for `From<&[T]>`.
 trait RcFromSlice<T> {
     fn from_slice(slice: &[T]) -> Self;
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 351e6c1a4b3..da0abdc9746 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -3503,6 +3503,7 @@ impl<T> FromIterator<T> for Arc<[T]> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 /// Specialization trait used for collecting into `Arc<[T]>`.
 trait ToArcSlice<T>: Iterator<Item = T> + Sized {
     fn to_arc_slice(self) -> Arc<[T]>;
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index ea7d6f6f4a6..bcf4163e39c 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -58,6 +58,7 @@ use core::cmp;
 use core::cmp::Ordering;
 use core::fmt;
 use core::hash::{Hash, Hasher};
+#[cfg(not(no_global_oom_handling))]
 use core::iter;
 use core::marker::PhantomData;
 use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties};
@@ -101,6 +102,7 @@ mod into_iter;
 #[cfg(not(no_global_oom_handling))]
 use self::is_zero::IsZero;
 
+#[cfg(not(no_global_oom_handling))]
 mod is_zero;
 
 #[cfg(not(no_global_oom_handling))]
@@ -2599,6 +2601,7 @@ pub fn from_elem_in<T: Clone, A: Allocator>(elem: T, n: usize, alloc: A) -> Vec<
     <T as SpecFromElem>::from_elem(elem, n, alloc)
 }
 
+#[cfg(not(no_global_oom_handling))]
 trait ExtendFromWithinSpec {
     /// # Safety
     ///
@@ -2607,6 +2610,7 @@ trait ExtendFromWithinSpec {
     unsafe fn spec_extend_from_within(&mut self, src: Range<usize>);
 }
 
+#[cfg(not(no_global_oom_handling))]
 impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
     default unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
         // SAFETY:
@@ -2626,6 +2630,7 @@ impl<T: Clone, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
     }
 }
 
+#[cfg(not(no_global_oom_handling))]
 impl<T: Copy, A: Allocator> ExtendFromWithinSpec for Vec<T, A> {
     unsafe fn spec_extend_from_within(&mut self, src: Range<usize>) {
         let count = src.len();
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 86f5fc56361..dec9a6d991d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -24,9 +24,8 @@
 //!   which are generated by Rust codegen backends. Additionally, this library can make explicit
 //!   calls to `strlen`. Their signatures are the same as found in C, but there are extra
 //!   assumptions about their semantics: For `memcpy`, `memmove`, `memset`, `memcmp`, and `bcmp`, if
-//!   the `n` parameter is 0, the function is assumed to not be UB. Furthermore, for `memcpy`, if
-//!   source and target pointer are equal, the function is assumed to not be UB.
-//!   (Note that these are standard assumptions among compilers:
+//!   the `n` parameter is 0, the function is assumed to not be UB, even if the pointers are NULL or
+//!   dangling. (Note that making extra assumptions about these functions is common among compilers:
 //!   [clang](https://reviews.llvm.org/D86993) and [GCC](https://gcc.gnu.org/onlinedocs/gcc/Standards.html#C-Language) do the same.)
 //!   These functions are often provided by the system libc, but can also be provided by the
 //!   [compiler-builtins crate](https://crates.io/crates/compiler_builtins).
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index d06012c14dc..8dc5b07ce10 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -336,6 +336,7 @@
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
+#![feature(ptr_from_ref)]
 #![feature(raw_os_nonzero)]
 #![feature(round_ties_even)]
 #![feature(slice_internals)]
diff --git a/library/std/src/sys/xous/mod.rs b/library/std/src/sys/xous/mod.rs
index 6d5c218d195..c2550dcfd83 100644
--- a/library/std/src/sys/xous/mod.rs
+++ b/library/std/src/sys/xous/mod.rs
@@ -28,7 +28,6 @@ pub mod process;
 pub mod stdio;
 pub mod thread;
 pub mod thread_local_key;
-#[path = "../unsupported/thread_parking.rs"]
 pub mod thread_parking;
 pub mod time;
 
diff --git a/library/std/src/sys/xous/thread_parking.rs b/library/std/src/sys/xous/thread_parking.rs
new file mode 100644
index 00000000000..aa39c6d2718
--- /dev/null
+++ b/library/std/src/sys/xous/thread_parking.rs
@@ -0,0 +1,94 @@
+use crate::os::xous::ffi::{blocking_scalar, scalar};
+use crate::os::xous::services::{ticktimer_server, TicktimerScalar};
+use crate::pin::Pin;
+use crate::ptr;
+use crate::sync::atomic::{
+    AtomicI8,
+    Ordering::{Acquire, Release},
+};
+use crate::time::Duration;
+
+const NOTIFIED: i8 = 1;
+const EMPTY: i8 = 0;
+const PARKED: i8 = -1;
+
+pub struct Parker {
+    state: AtomicI8,
+}
+
+impl Parker {
+    pub unsafe fn new_in_place(parker: *mut Parker) {
+        unsafe { parker.write(Parker { state: AtomicI8::new(EMPTY) }) }
+    }
+
+    fn index(&self) -> usize {
+        ptr::from_ref(self).addr()
+    }
+
+    pub unsafe fn park(self: Pin<&Self>) {
+        // Change NOTIFIED to EMPTY and EMPTY to PARKED.
+        let state = self.state.fetch_sub(1, Acquire);
+        if state == NOTIFIED {
+            return;
+        }
+
+        // The state was set to PARKED. Wait until the `unpark` wakes us up.
+        blocking_scalar(
+            ticktimer_server(),
+            TicktimerScalar::WaitForCondition(self.index(), 0).into(),
+        )
+        .expect("failed to send WaitForCondition command");
+
+        self.state.swap(EMPTY, Acquire);
+    }
+
+    pub unsafe fn park_timeout(self: Pin<&Self>, timeout: Duration) {
+        // Change NOTIFIED to EMPTY and EMPTY to PARKED.
+        let state = self.state.fetch_sub(1, Acquire);
+        if state == NOTIFIED {
+            return;
+        }
+
+        // A value of zero indicates an indefinite wait. Clamp the number of
+        // milliseconds to the allowed range.
+        let millis = usize::max(timeout.as_millis().try_into().unwrap_or(usize::MAX), 1);
+
+        let was_timeout = blocking_scalar(
+            ticktimer_server(),
+            TicktimerScalar::WaitForCondition(self.index(), millis).into(),
+        )
+        .expect("failed to send WaitForCondition command")[0]
+            != 0;
+
+        let state = self.state.swap(EMPTY, Acquire);
+        if was_timeout && state == NOTIFIED {
+            // The state was set to NOTIFIED after we returned from the wait
+            // but before we reset the state. Therefore, a wakeup is on its
+            // way, which we need to consume here.
+            // NOTICE: this is a priority hole.
+            blocking_scalar(
+                ticktimer_server(),
+                TicktimerScalar::WaitForCondition(self.index(), 0).into(),
+            )
+            .expect("failed to send WaitForCondition command");
+        }
+    }
+
+    pub fn unpark(self: Pin<&Self>) {
+        let state = self.state.swap(NOTIFIED, Release);
+        if state == PARKED {
+            // The thread is parked, wake it up.
+            blocking_scalar(
+                ticktimer_server(),
+                TicktimerScalar::NotifyCondition(self.index(), 1).into(),
+            )
+            .expect("failed to send NotifyCondition command");
+        }
+    }
+}
+
+impl Drop for Parker {
+    fn drop(&mut self) {
+        scalar(ticktimer_server(), TicktimerScalar::FreeCondition(self.index()).into()).ok();
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index 70892ce608f..2ab04682f1d 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note};
 use clippy_utils::is_span_if;
 use clippy_utils::source::snippet_opt;
-use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind, UnOp};
+use rustc_ast::ast::{BinOpKind, Block, Expr, ExprKind, StmtKind};
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -144,7 +144,7 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {
             let eq_span = lhs.span.between(rhs.span);
             if let ExprKind::Unary(op, ref sub_rhs) = rhs.kind {
                 if let Some(eq_snippet) = snippet_opt(cx, eq_span) {
-                    let op = UnOp::to_string(op);
+                    let op = op.as_str();
                     let eqop_span = lhs.span.between(sub_rhs.span);
                     if eq_snippet.ends_with('=') {
                         span_lint_and_note(
@@ -177,11 +177,11 @@ fn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {
         && let unop_operand_span = rhs.span.until(un_rhs.span)
         && let Some(binop_snippet) = snippet_opt(cx, binop_span)
         && let Some(unop_operand_snippet) = snippet_opt(cx, unop_operand_span)
-        && let binop_str = BinOpKind::to_string(&binop.node)
+        && let binop_str = binop.node.as_str()
         // no space after BinOp operator and space after UnOp operator
         && binop_snippet.ends_with(binop_str) && unop_operand_snippet.ends_with(' ')
     {
-        let unop_str = UnOp::to_string(op);
+        let unop_str = op.as_str();
         let eqop_span = lhs.span.between(un_rhs.span);
         span_lint_and_help(
             cx,
diff --git a/src/tools/clippy/clippy_lints/src/precedence.rs b/src/tools/clippy/clippy_lints/src/precedence.rs
index b638e83997a..52cec437378 100644
--- a/src/tools/clippy/clippy_lints/src/precedence.rs
+++ b/src/tools/clippy/clippy_lints/src/precedence.rs
@@ -78,7 +78,7 @@ impl EarlyLintPass for Precedence {
                     let sugg = format!(
                         "({}) {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
-                        op.to_string(),
+                        op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
                     span_sugg(expr, sugg, applicability);
@@ -87,7 +87,7 @@ impl EarlyLintPass for Precedence {
                     let sugg = format!(
                         "({}) {} {}",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
-                        op.to_string(),
+                        op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
                     span_sugg(expr, sugg, applicability);
@@ -96,7 +96,7 @@ impl EarlyLintPass for Precedence {
                     let sugg = format!(
                         "{} {} ({})",
                         snippet_with_applicability(cx, left.span, "..", &mut applicability),
-                        op.to_string(),
+                        op.as_str(),
                         snippet_with_applicability(cx, right.span, "..", &mut applicability)
                     );
                     span_sugg(expr, sugg, applicability);
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
index 92de7917871..b332309a552 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_operation_groupings.rs
@@ -298,7 +298,7 @@ fn replace_left_sugg(
 ) -> String {
     format!(
         "{left_suggestion} {} {}",
-        binop.op.to_string(),
+        binop.op.as_str(),
         snippet_with_applicability(cx, binop.right.span, "..", applicability),
     )
 }
@@ -312,7 +312,7 @@ fn replace_right_sugg(
     format!(
         "{} {} {right_suggestion}",
         snippet_with_applicability(cx, binop.left.span, "..", applicability),
-        binop.op.to_string(),
+        binop.op.as_str(),
     )
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index db79dd78801..f143163152e 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -382,7 +382,7 @@ fn binop_to_string(op: AssocOp, lhs: &str, rhs: &str) -> String {
         | AssocOp::GreaterEqual => {
             format!(
                 "{lhs} {} {rhs}",
-                op.to_ast_binop().expect("Those are AST ops").to_string()
+                op.to_ast_binop().expect("Those are AST ops").as_str()
             )
         },
         AssocOp::Assign => format!("{lhs} = {rhs}"),
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index fa941e6146a..60e0e007b1d 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -1933,7 +1933,7 @@ fn rewrite_unary_op(
     shape: Shape,
 ) -> Option<String> {
     // For some reason, an UnOp is not spanned like BinOp!
-    rewrite_unary_prefix(context, ast::UnOp::to_string(op), expr, shape)
+    rewrite_unary_prefix(context, op.as_str(), expr, shape)
 }
 
 pub(crate) enum RhsAssignKind<'ast> {
diff --git a/src/tools/rustfmt/src/pairs.rs b/src/tools/rustfmt/src/pairs.rs
index 07c05193739..bfc2ffed383 100644
--- a/src/tools/rustfmt/src/pairs.rs
+++ b/src/tools/rustfmt/src/pairs.rs
@@ -339,7 +339,7 @@ impl FlattenPair for ast::Expr {
                     if let Some(pop) = stack.pop() {
                         match pop.kind {
                             ast::ExprKind::Binary(op, _, ref rhs) => {
-                                separators.push(op.node.to_string());
+                                separators.push(op.node.as_str());
                                 node = rhs;
                             }
                             _ => unreachable!(),
diff --git a/tests/ui/async-await/issue-70594.rs b/tests/ui/async-await/issue-70594.rs
index 9e7c5847b3b..4c8209348b3 100644
--- a/tests/ui/async-await/issue-70594.rs
+++ b/tests/ui/async-await/issue-70594.rs
@@ -3,9 +3,6 @@
 async fn fun() {
     [1; ().await];
     //~^ error: `await` is only allowed inside `async` functions and blocks
-    //~| error: `.await` is not allowed in a `const`
-    //~| error: `.await` is not allowed in a `const`
-    //~| error: `()` is not a future
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/issue-70594.stderr b/tests/ui/async-await/issue-70594.stderr
index 9866e00bb83..aed99ec3f1f 100644
--- a/tests/ui/async-await/issue-70594.stderr
+++ b/tests/ui/async-await/issue-70594.stderr
@@ -1,37 +1,12 @@
 error[E0728]: `await` is only allowed inside `async` functions and blocks
   --> $DIR/issue-70594.rs:4:12
    |
-LL | async fn fun() {
-   |          --- this is not `async`
 LL |     [1; ().await];
-   |            ^^^^^ only allowed inside `async` functions and blocks
+   |         ---^^^^^
+   |         |  |
+   |         |  only allowed inside `async` functions and blocks
+   |         this is not `async`
 
-error[E0744]: `.await` is not allowed in a `const`
-  --> $DIR/issue-70594.rs:4:9
-   |
-LL |     [1; ().await];
-   |         ^^^^^^^^
-
-error[E0744]: `.await` is not allowed in a `const`
-  --> $DIR/issue-70594.rs:4:12
-   |
-LL |     [1; ().await];
-   |            ^^^^^
-
-error[E0277]: `()` is not a future
-  --> $DIR/issue-70594.rs:4:12
-   |
-LL |     [1; ().await];
-   |           -^^^^^
-   |           ||
-   |           |`()` is not a future
-   |           help: remove the `.await`
-   |
-   = help: the trait `Future` is not implemented for `()`
-   = note: () must be a future or must implement `IntoFuture` to be awaited
-   = note: required for `()` to implement `IntoFuture`
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0277, E0728, E0744.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0728`.
diff --git a/tests/ui/async-await/issues/issue-62009-1.rs b/tests/ui/async-await/issues/issue-62009-1.rs
index 40ccf25712e..51d216408d7 100644
--- a/tests/ui/async-await/issues/issue-62009-1.rs
+++ b/tests/ui/async-await/issues/issue-62009-1.rs
@@ -11,5 +11,4 @@ fn main() {
     //~^ ERROR `await` is only allowed inside `async` functions and blocks
     (|_| 2333).await;
     //~^ ERROR `await` is only allowed inside `async` functions and blocks
-    //~| ERROR is not a future
 }
diff --git a/tests/ui/async-await/issues/issue-62009-1.stderr b/tests/ui/async-await/issues/issue-62009-1.stderr
index bb617d09076..02933f4f2f2 100644
--- a/tests/ui/async-await/issues/issue-62009-1.stderr
+++ b/tests/ui/async-await/issues/issue-62009-1.stderr
@@ -24,20 +24,6 @@ LL | fn main() {
 LL |     (|_| 2333).await;
    |                ^^^^^ only allowed inside `async` functions and blocks
 
-error[E0277]: `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
-  --> $DIR/issue-62009-1.rs:12:16
-   |
-LL |     (|_| 2333).await;
-   |               -^^^^^
-   |               ||
-   |               |`{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` is not a future
-   |               help: remove the `.await`
-   |
-   = help: the trait `Future` is not implemented for closure `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}`
-   = note: {closure@$DIR/issue-62009-1.rs:12:6: 12:9} must be a future or must implement `IntoFuture` to be awaited
-   = note: required for `{closure@$DIR/issue-62009-1.rs:12:6: 12:9}` to implement `IntoFuture`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0277, E0728.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0728`.
diff --git a/tests/ui/coroutine/auxiliary/unwind-aux.rs b/tests/ui/coroutine/auxiliary/unwind-aux.rs
new file mode 100644
index 00000000000..215d6769116
--- /dev/null
+++ b/tests/ui/coroutine/auxiliary/unwind-aux.rs
@@ -0,0 +1,11 @@
+// compile-flags: -Cpanic=unwind  --crate-type=lib
+// no-prefer-dynamic
+// edition:2021
+
+#![feature(coroutines)]
+pub fn run<T>(a: T) {
+    let _ = move || {
+        drop(a);
+        yield;
+    };
+}
diff --git a/tests/ui/coroutine/unwind-abort-mix.rs b/tests/ui/coroutine/unwind-abort-mix.rs
new file mode 100644
index 00000000000..869b3e4f433
--- /dev/null
+++ b/tests/ui/coroutine/unwind-abort-mix.rs
@@ -0,0 +1,13 @@
+// Ensure that coroutine drop glue is valid when mixing different panic
+// strategies. Regression test for #116953.
+//
+// no-prefer-dynamic
+// build-pass
+// aux-build:unwind-aux.rs
+// compile-flags: -Cpanic=abort
+// needs-unwind
+extern crate unwind_aux;
+
+pub fn main() {
+    unwind_aux::run(String::new());
+}