]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Suggest possible clone when we have &T
[rust.git] / compiler / rustc_hir_typeck / src / fn_ctxt / suggestions.rs
index e38d1bccc10657199fcc4ff2515c2136867a19d2..991b0399542bf3037b19024fb9b7e37899c9fe48 100644 (file)
@@ -32,7 +32,7 @@ pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
         self.typeck_results
             .borrow()
             .liberated_fn_sigs()
-            .get(self.tcx.hir().get_parent_node(self.body_id))
+            .get(self.tcx.hir().parent_id(self.body_id))
             .copied()
     }
 
@@ -642,7 +642,7 @@ pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
                 // Check if the parent expression is a call to Pin::new.  If it
                 // is and we were expecting a Box, ergo Pin<Box<expected>>, we
                 // can suggest Box::pin.
-                let parent = self.tcx.hir().get_parent_node(expr.hir_id);
+                let parent = self.tcx.hir().parent_id(expr.hir_id);
                 let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) = self.tcx.hir().find(parent) else {
                     return false;
                 };
@@ -974,7 +974,7 @@ pub(in super::super) fn suggest_missing_parentheses(
         err: &mut Diagnostic,
         expr: &hir::Expr<'_>,
     ) -> bool {
-        let sp = self.tcx.sess.source_map().start_point(expr.span);
+        let sp = self.tcx.sess.source_map().start_point(expr.span).with_parent(None);
         if let Some(sp) = self.tcx.sess.parse_sess.ambiguous_block_expr_parse.borrow().get(&sp) {
             // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
             err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp));
@@ -1014,6 +1014,35 @@ pub(crate) fn suggest_block_to_brackets_peeling_refs(
         }
     }
 
+    pub(crate) fn suggest_clone_for_ref(
+        &self,
+        diag: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        expr_ty: Ty<'tcx>,
+        expected_ty: Ty<'tcx>,
+    ) -> bool {
+        if let ty::Ref(_, inner_ty, hir::Mutability::Not) = expr_ty.kind() &&
+            let Some(clone_trait_def) = self.tcx.lang_items().clone_trait() &&
+                expected_ty == *inner_ty &&
+                self
+                .infcx
+                .type_implements_trait(
+                    clone_trait_def,
+                    [self.tcx.erase_regions(expected_ty)],
+                    self.param_env
+                )
+                .must_apply_modulo_regions() {
+                    diag.span_suggestion_verbose(
+                        expr.span.shrink_to_hi(),
+                        "consider using clone here",
+                        ".clone()",
+                        Applicability::MachineApplicable,
+                    );
+                    return true;
+                }
+        false
+    }
+
     pub(crate) fn suggest_copied_or_cloned(
         &self,
         diag: &mut Diagnostic,