about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs14
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs12
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs6
-rw-r--r--compiler/rustc_lint/src/unused.rs120
-rw-r--r--compiler/rustc_macros/src/session_diagnostic.rs8
-rw-r--r--compiler/rustc_metadata/src/locator.rs5
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs8
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs4
-rw-r--r--compiler/rustc_passes/src/region.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs6
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs2
-rw-r--r--compiler/rustc_typeck/src/check/op.rs81
23 files changed, 171 insertions, 143 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index aca4503903c..e9dce953c73 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -422,11 +422,25 @@ impl<'a> AstValidator<'a> {
     }
 
     fn check_fn_decl(&self, fn_decl: &FnDecl, self_semantic: SelfSemantic) {
+        self.check_decl_num_args(fn_decl);
         self.check_decl_cvaradic_pos(fn_decl);
         self.check_decl_attrs(fn_decl);
         self.check_decl_self_param(fn_decl, self_semantic);
     }
 
+    /// Emits fatal error if function declaration has more than `u16::MAX` arguments
+    /// Error is fatal to prevent errors during typechecking
+    fn check_decl_num_args(&self, fn_decl: &FnDecl) {
+        let max_num_args: usize = u16::MAX.into();
+        if fn_decl.inputs.len() > max_num_args {
+            let Param { span, .. } = fn_decl.inputs[0];
+            self.err_handler().span_fatal(
+                span,
+                &format!("function can not have more than {} arguments", max_num_args),
+            );
+        }
+    }
+
     fn check_decl_cvaradic_pos(&self, fn_decl: &FnDecl) {
         match &*fn_decl.inputs {
             [Param { ty, span, .. }] => {
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 48e45a9b1ce..b28f8ce1d8b 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -1739,7 +1739,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     category: constraint.category,
                     from_closure: false,
                     span,
-                    variance_info: constraint.variance_info.clone(),
+                    variance_info: constraint.variance_info,
                 };
             }
             Locations::Single(loc) => loc,
@@ -1752,13 +1752,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                 category,
                 from_closure: true,
                 span: span,
-                variance_info: constraint.variance_info.clone(),
+                variance_info: constraint.variance_info,
             })
             .unwrap_or(BlameConstraint {
                 category: constraint.category,
                 from_closure: false,
                 span: body.source_info(loc).span,
-                variance_info: constraint.variance_info.clone(),
+                variance_info: constraint.variance_info,
             })
     }
 
@@ -2001,7 +2001,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                         category: constraint.category,
                         from_closure: false,
                         span: constraint.locations.span(body),
-                        variance_info: constraint.variance_info.clone(),
+                        variance_info: constraint.variance_info,
                     }
                 }
             })
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 693114e3786..c032364c008 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -117,6 +117,10 @@ fn parse_args<'a>(
         let mut explicit_reg = false;
         let op = if !is_global_asm && p.eat_keyword(kw::In) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             ast::InlineAsmOperand::In { reg, expr }
         } else if !is_global_asm && p.eat_keyword(sym::out) {
@@ -129,6 +133,10 @@ fn parse_args<'a>(
             ast::InlineAsmOperand::Out { reg, expr, late: true }
         } else if !is_global_asm && p.eat_keyword(sym::inout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
                 let out_expr =
@@ -139,6 +147,10 @@ fn parse_args<'a>(
             }
         } else if !is_global_asm && p.eat_keyword(sym::inlateout) {
             let reg = parse_reg(&mut p, &mut explicit_reg)?;
+            if p.eat_keyword(kw::Underscore) {
+                let err = ecx.struct_span_err(p.token.span, "_ cannot be used for input operands");
+                return Err(err);
+            }
             let expr = p.parse_expr()?;
             if p.eat(&token::FatArrow) {
                 let out_expr =
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 36054c04847..67f92bc0a51 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1036,7 +1036,7 @@ impl<'a> State<'a> {
         self.maybe_print_comment(st.span.lo());
         match st.kind {
             hir::StmtKind::Local(ref loc) => {
-                self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc));
+                self.print_local(loc.init, |this| this.print_local_decl(&loc));
             }
             hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
             hir::StmtKind::Expr(ref expr) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 32150c7f4c6..1139b714d0a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2345,7 +2345,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 );
                 err.span_suggestion(
                     generics.where_clause.tail_span_for_suggestion(),
-                    "consider adding a where clause".into(),
+                    "consider adding a where clause",
                     suggestion,
                     Applicability::MaybeIncorrect,
                 );
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index c211d8e94a6..e88c6608aca 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -519,7 +519,7 @@ where
 
         let old_ambient_variance = self.ambient_variance;
         self.ambient_variance = self.ambient_variance.xform(variance);
-        self.ambient_variance_info = self.ambient_variance_info.clone().xform(info);
+        self.ambient_variance_info = self.ambient_variance_info.xform(info);
 
         debug!("relate_with_variance: ambient_variance = {:?}", self.ambient_variance);
 
@@ -597,12 +597,12 @@ where
 
         if self.ambient_covariance() {
             // Covariance: a <= b. Hence, `b: a`.
-            self.push_outlives(v_b, v_a, self.ambient_variance_info.clone());
+            self.push_outlives(v_b, v_a, self.ambient_variance_info);
         }
 
         if self.ambient_contravariance() {
             // Contravariant: b <= a. Hence, `a: b`.
-            self.push_outlives(v_a, v_b, self.ambient_variance_info.clone());
+            self.push_outlives(v_a, v_b, self.ambient_variance_info);
         }
 
         Ok(a)
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 7a42e8c1037..48b955e41ac 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -3,7 +3,6 @@ use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext}
 use rustc_ast as ast;
 use rustc_ast::util::{classify, parser};
 use rustc_ast::{ExprKind, StmtKind};
-use rustc_ast_pretty::pprust;
 use rustc_errors::{pluralize, Applicability};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -12,7 +11,7 @@ use rustc_middle::ty::adjustment;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::symbol::Symbol;
 use rustc_span::symbol::{kw, sym};
-use rustc_span::{BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, MultiSpan, Span, DUMMY_SP};
 
 declare_lint! {
     /// The `unused_must_use` lint detects unused result of a type flagged as
@@ -491,77 +490,60 @@ trait UnusedDelimLint {
         left_pos: Option<BytePos>,
         right_pos: Option<BytePos>,
     ) {
-        let expr_text = if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-            snippet
-        } else {
-            pprust::expr_to_string(value)
+        let spans = match value.kind {
+            ast::ExprKind::Block(ref block, None) if block.stmts.len() > 0 => {
+                let start = block.stmts[0].span;
+                let end = block.stmts[block.stmts.len() - 1].span;
+                if value.span.from_expansion() || start.from_expansion() || end.from_expansion() {
+                    (
+                        value.span.with_hi(value.span.lo() + BytePos(1)),
+                        value.span.with_lo(value.span.hi() - BytePos(1)),
+                    )
+                } else {
+                    (value.span.with_hi(start.lo()), value.span.with_lo(end.hi()))
+                }
+            }
+            ast::ExprKind::Paren(ref expr) => {
+                if value.span.from_expansion() || expr.span.from_expansion() {
+                    (
+                        value.span.with_hi(value.span.lo() + BytePos(1)),
+                        value.span.with_lo(value.span.hi() - BytePos(1)),
+                    )
+                } else {
+                    (value.span.with_hi(expr.span.lo()), value.span.with_lo(expr.span.hi()))
+                }
+            }
+            _ => return,
         };
         let keep_space = (
             left_pos.map_or(false, |s| s >= value.span.lo()),
             right_pos.map_or(false, |s| s <= value.span.hi()),
         );
-        self.emit_unused_delims(cx, value.span, &expr_text, ctx.into(), keep_space);
+        self.emit_unused_delims(cx, spans, ctx.into(), keep_space);
     }
 
     fn emit_unused_delims(
         &self,
         cx: &EarlyContext<'_>,
-        span: Span,
-        pattern: &str,
+        spans: (Span, Span),
         msg: &str,
         keep_space: (bool, bool),
     ) {
         // FIXME(flip1995): Quick and dirty fix for #70814. This should be fixed in rustdoc
         // properly.
-        if span == DUMMY_SP {
+        if spans.0 == DUMMY_SP || spans.1 == DUMMY_SP {
             return;
         }
 
-        cx.struct_span_lint(self.lint(), span, |lint| {
+        cx.struct_span_lint(self.lint(), MultiSpan::from(vec![spans.0, spans.1]), |lint| {
             let span_msg = format!("unnecessary {} around {}", Self::DELIM_STR, msg);
             let mut err = lint.build(&span_msg);
-            let mut ate_left_paren = false;
-            let mut ate_right_paren = false;
-            let parens_removed = pattern
-                .trim_matches(|c| match c {
-                    '(' | '{' => {
-                        if ate_left_paren {
-                            false
-                        } else {
-                            ate_left_paren = true;
-                            true
-                        }
-                    }
-                    ')' | '}' => {
-                        if ate_right_paren {
-                            false
-                        } else {
-                            ate_right_paren = true;
-                            true
-                        }
-                    }
-                    _ => false,
-                })
-                .trim();
-
-            let replace = {
-                let mut replace = if keep_space.0 {
-                    let mut s = String::from(" ");
-                    s.push_str(parens_removed);
-                    s
-                } else {
-                    String::from(parens_removed)
-                };
-
-                if keep_space.1 {
-                    replace.push(' ');
-                }
-                replace
-            };
-
+            let replacement = vec![
+                (spans.0, if keep_space.0 { " ".into() } else { "".into() }),
+                (spans.1, if keep_space.1 { " ".into() } else { "".into() }),
+            ];
             let suggestion = format!("remove these {}", Self::DELIM_STR);
-
-            err.span_suggestion_short(span, &suggestion, replace, Applicability::MachineApplicable);
+            err.multipart_suggestion(&suggestion, replacement, Applicability::MachineApplicable);
             err.emit();
         });
     }
@@ -770,14 +752,15 @@ impl UnusedParens {
                 // Otherwise proceed with linting.
                 _ => {}
             }
-
-            let pattern_text =
-                if let Ok(snippet) = cx.sess().source_map().span_to_snippet(value.span) {
-                    snippet
-                } else {
-                    pprust::pat_to_string(value)
-                };
-            self.emit_unused_delims(cx, value.span, &pattern_text, "pattern", (false, false));
+            let spans = if value.span.from_expansion() || inner.span.from_expansion() {
+                (
+                    value.span.with_hi(value.span.lo() + BytePos(1)),
+                    value.span.with_lo(value.span.hi() - BytePos(1)),
+                )
+            } else {
+                (value.span.with_hi(inner.span.lo()), value.span.with_lo(inner.span.hi()))
+            };
+            self.emit_unused_delims(cx, spans, "pattern", (false, false));
         }
     }
 }
@@ -870,14 +853,15 @@ impl EarlyLintPass for UnusedParens {
                     );
                 }
                 _ => {
-                    let pattern_text =
-                        if let Ok(snippet) = cx.sess().source_map().span_to_snippet(ty.span) {
-                            snippet
-                        } else {
-                            pprust::ty_to_string(ty)
-                        };
-
-                    self.emit_unused_delims(cx, ty.span, &pattern_text, "type", (false, false));
+                    let spans = if ty.span.from_expansion() || r.span.from_expansion() {
+                        (
+                            ty.span.with_hi(ty.span.lo() + BytePos(1)),
+                            ty.span.with_lo(ty.span.hi() - BytePos(1)),
+                        )
+                    } else {
+                        (ty.span.with_hi(r.span.lo()), ty.span.with_lo(r.span.hi()))
+                    };
+                    self.emit_unused_delims(cx, spans, "type", (false, false));
                 }
             }
         }
diff --git a/compiler/rustc_macros/src/session_diagnostic.rs b/compiler/rustc_macros/src/session_diagnostic.rs
index 8a0fce209b7..80dcf99da62 100644
--- a/compiler/rustc_macros/src/session_diagnostic.rs
+++ b/compiler/rustc_macros/src/session_diagnostic.rs
@@ -448,7 +448,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                                             span_idx = Some(syn::Index::from(idx));
                                         } else {
                                             throw_span_err!(
-                                                info.span.clone().unwrap(),
+                                                info.span.unwrap(),
                                                 "type of field annotated with `#[suggestion(...)]` contains more than one Span"
                                             );
                                         }
@@ -460,7 +460,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                                             applicability_idx = Some(syn::Index::from(idx));
                                         } else {
                                             throw_span_err!(
-                                                info.span.clone().unwrap(),
+                                                info.span.unwrap(),
                                                 "type of field annotated with `#[suggestion(...)]` contains more than one Applicability"
                                             );
                                         }
@@ -479,7 +479,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                                     return Ok((span, applicability));
                                 }
                                 throw_span_err!(
-                                    info.span.clone().unwrap(),
+                                    info.span.unwrap(),
                                     "wrong types for suggestion",
                                     |diag| {
                                         diag.help("#[suggestion(...)] on a tuple field must be applied to fields of type (Span, Applicability)")
@@ -487,7 +487,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
                                 );
                             }
                             _ => throw_span_err!(
-                                info.span.clone().unwrap(),
+                                info.span.unwrap(),
                                 "wrong field type for suggestion",
                                 |diag| {
                                     diag.help("#[suggestion(...)] should be applied to fields of type Span or (Span, Applicability)")
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index d3512b6cf57..b6922e0d72a 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -1095,6 +1095,11 @@ impl CrateError {
                         == Symbol::intern(&sess.opts.debugging_opts.profiler_runtime)
                     {
                         err.note(&"the compiler may have been built without the profiler runtime");
+                    } else if crate_name.as_str().starts_with("rustc_") {
+                        err.help(
+                            "maybe you need to install the missing components with: \
+                             `rustup component add rust-src rustc-dev llvm-tools-preview`",
+                        );
                     }
                     err.span_label(span, "can't find crate");
                     err
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 38d4c5b4bd1..e40227530cd 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1736,7 +1736,7 @@ pub struct Place<'tcx> {
     pub projection: &'tcx List<PlaceElem<'tcx>>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Place<'_>, 16);
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -2062,7 +2062,7 @@ pub enum Operand<'tcx> {
     Constant(Box<Constant<'tcx>>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Operand<'_>, 24);
 
 impl<'tcx> Debug for Operand<'tcx> {
@@ -2200,7 +2200,7 @@ pub enum Rvalue<'tcx> {
     Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Rvalue<'_>, 40);
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
@@ -2226,7 +2226,7 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, SubstsRef<'tcx>, hir::Movability),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(AggregateKind<'_>, 48);
 
 #[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 0ff3fc60995..4df073c40e2 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -2060,7 +2060,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 source_info.span, ascription.source, ascription.user_ty,
             );
 
-            let user_ty = ascription.user_ty.clone().user_ty(
+            let user_ty = ascription.user_ty.user_ty(
                 &mut self.canonical_user_type_annotations,
                 ascription.source.ty(&self.local_decls, self.tcx).ty,
                 source_info.span,
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index 30de374a2d8..a2cce9f1eda 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -75,13 +75,11 @@ fn lower_slice_len_call<'tcx>(
                     let deref_arg = tcx.mk_place_deref(arg);
                     let r_value = Rvalue::Len(deref_arg);
                     let len_statement_kind = StatementKind::Assign(Box::new((*dest, r_value)));
-                    let add_statement = Statement {
-                        kind: len_statement_kind,
-                        source_info: terminator.source_info.clone(),
-                    };
+                    let add_statement =
+                        Statement { kind: len_statement_kind, source_info: terminator.source_info };
 
                     // modify terminator into simple Goto
-                    let new_terminator_kind = TerminatorKind::Goto { target: bb.clone() };
+                    let new_terminator_kind = TerminatorKind::Goto { target: *bb };
 
                     let patch = SliceLenPatchInformation { add_statement, new_terminator_kind };
 
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index 9f06bdcc135..568682cc3e4 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -34,7 +34,7 @@ pub struct AttrWrapper {
 
 // This struct is passed around very frequently,
 // so make sure it doesn't accidentally get larger
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(AttrWrapper, 16);
 
 impl AttrWrapper {
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index ab9bfea9694..0d7abeba1a7 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -775,7 +775,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
         if blk.targeted_by_break {
             self.break_ln.insert(blk.hir_id, succ);
         }
-        let succ = self.propagate_through_opt_expr(blk.expr.as_deref(), succ);
+        let succ = self.propagate_through_opt_expr(blk.expr, succ);
         blk.stmts.iter().rev().fold(succ, |succ, stmt| self.propagate_through_stmt(stmt, succ))
     }
 
@@ -796,7 +796,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                 // initialization, which is mildly more complex than checking
                 // once at the func header but otherwise equivalent.
 
-                let succ = self.propagate_through_opt_expr(local.init.as_deref(), succ);
+                let succ = self.propagate_through_opt_expr(local.init, succ);
                 self.define_bindings_in_pat(&local.pat, succ)
             }
             hir::StmtKind::Item(..) => succ,
diff --git a/compiler/rustc_passes/src/region.rs b/compiler/rustc_passes/src/region.rs
index 08702cad41c..5fc8e230d72 100644
--- a/compiler/rustc_passes/src/region.rs
+++ b/compiler/rustc_passes/src/region.rs
@@ -812,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
         resolve_expr(self, ex);
     }
     fn visit_local(&mut self, l: &'tcx Local<'tcx>) {
-        resolve_local(self, Some(&l.pat), l.init.as_deref());
+        resolve_local(self, Some(&l.pat), l.init);
     }
 }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 6d2961db9e3..392d618995a 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -1487,7 +1487,7 @@ impl<'a> Resolver<'a> {
                 .iter()
                 .map(|(ident, entry)| (ident.name, entry.introduced_by_item))
                 .collect(),
-            main_def: self.main_def.clone(),
+            main_def: self.main_def,
             trait_impls: self.trait_impls.clone(),
             proc_macros,
             confused_type_with_std_module: self.confused_type_with_std_module.clone(),
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index c22093c5a42..ef60608a27c 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1357,9 +1357,7 @@ fn for_all_expns_in<E>(
     mut f: impl FnMut(ExpnId, &ExpnData, ExpnHash) -> Result<(), E>,
 ) -> Result<(), E> {
     let all_data: Vec<_> = HygieneData::with(|data| {
-        expns
-            .map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn).clone()))
-            .collect()
+        expns.map(|expn| (expn, data.expn_data(expn).clone(), data.expn_hash(expn))).collect()
     });
     for (expn, data, hash) in all_data.into_iter() {
         f(expn, &data, hash)?;
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 9ce6c58a0f1..52367661a4c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -249,10 +249,10 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                 if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
                     root_obligation.cause.code.peel_derives()
                 {
-                    if let Some(cause) = self.tcx.diagnostic_hir_wf_check((
-                        tcx.erase_regions(obligation.predicate),
-                        wf_loc.clone(),
-                    )) {
+                    if let Some(cause) = self
+                        .tcx
+                        .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc))
+                    {
                         obligation.cause = cause;
                         span = obligation.cause.span;
                     }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 7038f16a2c9..92db0ca2a7c 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -595,7 +595,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
             ty::ReLateBound(debruijn, br) if debruijn >= self.current_index => {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderRegion { universe, name: br.kind };
-                self.mapped_regions.insert(p.clone(), br);
+                self.mapped_regions.insert(p, br);
                 self.infcx.tcx.mk_region(ty::RePlaceholder(p))
             }
             _ => r,
@@ -613,7 +613,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
             ty::Bound(debruijn, bound_ty) if debruijn >= self.current_index => {
                 let universe = self.universe_for(debruijn);
                 let p = ty::PlaceholderType { universe, name: bound_ty.var };
-                self.mapped_types.insert(p.clone(), bound_ty);
+                self.mapped_types.insert(p, bound_ty);
                 self.infcx.tcx.mk_ty(ty::Placeholder(p))
             }
             _ if t.has_vars_bound_at_or_above(self.current_index) => t.super_fold_with(self),
@@ -637,7 +637,7 @@ impl TypeFolder<'tcx> for BoundVarReplacer<'_, 'tcx> {
                     universe,
                     name: ty::BoundConst { var: bound_const, ty },
                 };
-                self.mapped_consts.insert(p.clone(), bound_const);
+                self.mapped_consts.insert(p, bound_const);
                 self.infcx.tcx.mk_const(ty::Const { val: ty::ConstKind::Placeholder(p), ty })
             }
             _ if ct.has_vars_bound_at_or_above(self.current_index) => ct.super_fold_with(self),
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 22013fb79cf..9824b644c3e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2445,7 +2445,7 @@ impl<'tcx> ProvisionalEvaluationCache<'tcx> {
             "get_provisional = {:#?}",
             self.map.borrow().get(&fresh_trait_ref),
         );
-        Some(self.map.borrow().get(&fresh_trait_ref)?.clone())
+        Some(*self.map.borrow().get(&fresh_trait_ref)?)
     }
 
     /// Insert a provisional result into the cache. The result came
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 3bfab9d513f..6fe96e4cc27 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -1003,6 +1003,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             exprs.len()
         );
 
+        // The following check fixes #88097, where the compiler erroneously
+        // attempted to coerce a closure type to itself via a function pointer.
+        if prev_ty == new_ty {
+            return Ok(prev_ty);
+        }
+
         // Special-case that coercion alone cannot handle:
         // Function items or non-capturing closures of differing IDs or InternalSubsts.
         let (a_sig, b_sig) = {
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 1c7d68a3d57..cbfdce96bc5 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -186,7 +186,7 @@ pub enum AutorefOrPtrAdjustment<'tcx> {
 impl<'tcx> AutorefOrPtrAdjustment<'tcx> {
     fn get_unsize(&self) -> Option<Ty<'tcx>> {
         match self {
-            AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => unsize.clone(),
+            AutorefOrPtrAdjustment::Autoref { mutbl: _, unsize } => *unsize,
             AutorefOrPtrAdjustment::ToConstPtr => None,
         }
     }
diff --git a/compiler/rustc_typeck/src/check/op.rs b/compiler/rustc_typeck/src/check/op.rs
index 9b495fba197..a574a63d63b 100644
--- a/compiler/rustc_typeck/src/check/op.rs
+++ b/compiler/rustc_typeck/src/check/op.rs
@@ -680,42 +680,53 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ex.span,
                         format!("cannot apply unary operator `{}`", op.as_str()),
                     );
-                    match actual.kind() {
-                        Uint(_) if op == hir::UnOp::Neg => {
-                            err.note("unsigned values cannot be negated");
-
-                            if let hir::ExprKind::Unary(
-                                _,
-                                hir::Expr {
-                                    kind:
-                                        hir::ExprKind::Lit(Spanned {
-                                            node: ast::LitKind::Int(1, _),
-                                            ..
-                                        }),
-                                    ..
-                                },
-                            ) = ex.kind
-                            {
-                                err.span_suggestion(
-                                    ex.span,
-                                    &format!(
-                                        "you may have meant the maximum value of `{}`",
-                                        actual
-                                    ),
-                                    format!("{}::MAX", actual),
-                                    Applicability::MaybeIncorrect,
-                                );
+
+                    let sp = self.tcx.sess.source_map().start_point(ex.span);
+                    if let Some(sp) =
+                        self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp)
+                    {
+                        // If the previous expression was a block expression, suggest parentheses
+                        // (turning this into a binary subtraction operation instead.)
+                        // for example, `{2} - 2` -> `({2}) - 2` (see src\test\ui\parser\expr-as-stmt.rs)
+                        self.tcx.sess.parse_sess.expr_parentheses_needed(&mut err, *sp);
+                    } else {
+                        match actual.kind() {
+                            Uint(_) if op == hir::UnOp::Neg => {
+                                err.note("unsigned values cannot be negated");
+
+                                if let hir::ExprKind::Unary(
+                                    _,
+                                    hir::Expr {
+                                        kind:
+                                            hir::ExprKind::Lit(Spanned {
+                                                node: ast::LitKind::Int(1, _),
+                                                ..
+                                            }),
+                                        ..
+                                    },
+                                ) = ex.kind
+                                {
+                                    err.span_suggestion(
+                                        ex.span,
+                                        &format!(
+                                            "you may have meant the maximum value of `{}`",
+                                            actual
+                                        ),
+                                        format!("{}::MAX", actual),
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
+                            }
+                            Str | Never | Char | Tuple(_) | Array(_, _) => {}
+                            Ref(_, ref lty, _) if *lty.kind() == Str => {}
+                            _ => {
+                                let missing_trait = match op {
+                                    hir::UnOp::Neg => "std::ops::Neg",
+                                    hir::UnOp::Not => "std::ops::Not",
+                                    hir::UnOp::Deref => "std::ops::UnDerf",
+                                };
+                                suggest_impl_missing(&mut err, operand_ty, &missing_trait);
                             }
-                        }
-                        Str | Never | Char | Tuple(_) | Array(_, _) => {}
-                        Ref(_, ref lty, _) if *lty.kind() == Str => {}
-                        _ => {
-                            let missing_trait = match op {
-                                hir::UnOp::Neg => "std::ops::Neg",
-                                hir::UnOp::Not => "std::ops::Not",
-                                hir::UnOp::Deref => "std::ops::UnDerf",
-                            };
-                            suggest_impl_missing(&mut err, operand_ty, &missing_trait);
                         }
                     }
                     err.emit();