diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-10-26 11:29:53 +0530 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-26 11:29:53 +0530 |
| commit | bf6bfcddf6bf9774022001d5a5d1f859d39a0a8a (patch) | |
| tree | bedf6f9780b35856a9360b8f1bff783cbffb3357 /compiler | |
| parent | a5406feb1cf1a9f2479b72917cf4225e5f6aa240 (diff) | |
| parent | 0fca075ce8a2247b6d59cd8eaf2fd1d6b89855d8 (diff) | |
| download | rust-bf6bfcddf6bf9774022001d5a5d1f859d39a0a8a.tar.gz rust-bf6bfcddf6bf9774022001d5a5d1f859d39a0a8a.zip | |
Rollup merge of #102951 - SparrowLii:type_annotation, r=estebank
suggest type annotation for local statement initialed by ref expression In a local statement with a type declaration, if a ref expression is used on the right side and not used on the left side, in addition to removing the `&` and `&mut` on the right side, we can add them on the left side alternatively Fixes #102892
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/demand.rs | 19 | ||||
| -rw-r--r-- | compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 47 |
2 files changed, 62 insertions, 4 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 2974ac97f23..be14234afe2 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -714,7 +714,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expr: &hir::Expr<'tcx>, checked_ty: Ty<'tcx>, expected: Ty<'tcx>, - ) -> Option<(Span, String, String, Applicability, bool /* verbose */)> { + ) -> Option<( + Span, + String, + String, + Applicability, + bool, /* verbose */ + bool, /* suggest `&` or `&mut` type annotation */ + )> { let sess = self.sess(); let sp = expr.span; @@ -746,6 +753,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { String::new(), Applicability::MachineApplicable, true, + false, )); } } @@ -760,6 +768,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "b".to_string(), Applicability::MachineApplicable, true, + false, )); } } @@ -817,6 +826,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { sugg.2, Applicability::MachineApplicable, false, + false, )); } @@ -844,6 +854,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("{prefix}&mut {sugg_expr}"), Applicability::MachineApplicable, false, + false, ), hir::Mutability::Not => ( sp, @@ -851,6 +862,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { format!("{prefix}&{sugg_expr}"), Applicability::MachineApplicable, false, + false, ), }); } @@ -880,6 +892,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { String::new(), Applicability::MachineApplicable, true, + true )); } return None; @@ -893,6 +906,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { String::new(), Applicability::MachineApplicable, true, + true, )); } } @@ -959,6 +973,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { src, applicability, true, + false, )); } } @@ -999,6 +1014,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable }, true, + false, )); } @@ -1050,6 +1066,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggestion, Applicability::MachineApplicable, true, + false, )); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index cd2e41aff0f..4db9c56f98f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -327,7 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expected_ty_expr: Option<&'tcx hir::Expr<'tcx>>, ) -> bool { let expr = expr.peel_blocks(); - if let Some((sp, msg, suggestion, applicability, verbose)) = + if let Some((sp, msg, suggestion, applicability, verbose, annotation)) = self.check_ref(expr, found, expected) { if verbose { @@ -335,9 +335,50 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { err.span_suggestion(sp, &msg, suggestion, applicability); } + if annotation { + let suggest_annotation = match expr.peel_drop_temps().kind { + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, _) => "&", + hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, _) => "&mut ", + _ => return true, + }; + let mut tuple_indexes = Vec::new(); + let mut expr_id = expr.hir_id; + for (parent_id, node) in self.tcx.hir().parent_iter(expr.hir_id) { + match node { + Node::Expr(&Expr { kind: ExprKind::Tup(subs), .. }) => { + tuple_indexes.push( + subs.iter() + .enumerate() + .find(|(_, sub_expr)| sub_expr.hir_id == expr_id) + .unwrap() + .0, + ); + expr_id = parent_id; + } + Node::Local(local) => { + if let Some(mut ty) = local.ty { + while let Some(index) = tuple_indexes.pop() { + match ty.kind { + TyKind::Tup(tys) => ty = &tys[index], + _ => return true, + } + } + let annotation_span = ty.span; + err.span_suggestion( + annotation_span.with_hi(annotation_span.lo()), + format!("alternatively, consider changing the type annotation"), + suggest_annotation, + Applicability::MaybeIncorrect, + ); + } + break; + } + _ => break, + } + } + } return true; - } else if self.suggest_else_fn_with_closure(err, expr, found, expected) - { + } else if self.suggest_else_fn_with_closure(err, expr, found, expected) { return true; } else if self.suggest_fn_call(err, expr, found, |output| self.can_coerce(output, expected)) && let ty::FnDef(def_id, ..) = &found.kind() |
