diff options
| author | bors <bors@rust-lang.org> | 2023-06-25 04:45:52 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-06-25 04:45:52 +0000 |
| commit | 3c5d71a99dd5ece7f6c87ca80b0adb1637c3b11a (patch) | |
| tree | 622774cf1a194ba9c888ca6cc3464c1a5daad6d3 /compiler | |
| parent | 7b9b1277009c407010298bd2f195f83af31fd06b (diff) | |
| parent | 33f73c2e939afb9c71555735acef2ee20e4f10bd (diff) | |
| download | rust-3c5d71a99dd5ece7f6c87ca80b0adb1637c3b11a.tar.gz rust-3c5d71a99dd5ece7f6c87ca80b0adb1637c3b11a.zip | |
Auto merge of #112476 - chenyukang:yukang-fix-109991, r=compiler-errors
Do not emit coerce_suggestions for expr from destructuring assignment desugaring Fixes #109991
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_typeck/src/demand.rs | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 9ce03060e0f..47f3c6b8407 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -83,6 +83,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.annotate_expected_due_to_let_ty(err, expr, error); + + if self.is_destruct_assignment_desugaring(expr) { + return; + } self.emit_type_mismatch_suggestions(err, expr, expr_ty, expected, expected_ty_expr, error); self.note_type_is_not_clone(err, expected, expr_ty, expr); self.note_internal_mutation_in_method(err, expr, Some(expected), expr_ty); @@ -1253,6 +1257,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { false } + // Returns whether the given expression is a destruct assignment desugaring. + // For example, `(a, b) = (1, &2);` + // Here we try to find the pattern binding of the expression, + // `default_binding_modes` is false only for destruct assignment desugaring. + pub(crate) fn is_destruct_assignment_desugaring(&self, expr: &hir::Expr<'_>) -> bool { + if let hir::ExprKind::Path(hir::QPath::Resolved( + _, + hir::Path { res: hir::def::Res::Local(bind_hir_id), .. }, + )) = expr.kind + { + let bind = self.tcx.hir().find(*bind_hir_id); + let parent = self.tcx.hir().find(self.tcx.hir().parent_id(*bind_hir_id)); + if let Some(hir::Node::Pat(hir::Pat { kind: hir::PatKind::Binding(_, _hir_id, _, _), .. })) = bind && + let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent { + return true; + } + } + return false; + } + /// This function is used to determine potential "simple" improvements or users' errors and /// provide them useful help. For example: /// @@ -1443,6 +1467,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _, &ty::Ref(_, checked, _), ) if self.can_sub(self.param_env, checked, expected) => { + let make_sugg = |start: Span, end: BytePos| { + // skip `(` for tuples such as `(c) = (&123)`. + // make sure we won't suggest like `(c) = 123)` which is incorrect. + let sp = sm.span_extend_while(start.shrink_to_lo(), |c| c == '(' || c.is_whitespace()) + .map_or(start, |s| s.shrink_to_hi()); + Some(( + vec![(sp.with_hi(end), String::new())], + "consider removing the borrow".to_string(), + Applicability::MachineApplicable, + true, + true, + )) + }; + // We have `&T`, check if what was expected was `T`. If so, // we may want to suggest removing a `&`. if sm.is_imported(expr.span) { @@ -1456,24 +1494,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .find(|&s| sp.contains(s)) && sm.is_span_accessible(call_span) { - return Some(( - vec![(sp.with_hi(call_span.lo()), String::new())], - "consider removing the borrow".to_string(), - Applicability::MachineApplicable, - true, - true, - )); + return make_sugg(sp, call_span.lo()) } return None; } if sp.contains(expr.span) && sm.is_span_accessible(expr.span) { - return Some(( - vec![(sp.with_hi(expr.span.lo()), String::new())], - "consider removing the borrow".to_string(), - Applicability::MachineApplicable, - true, - true, - )); + return make_sugg(sp, expr.span.lo()) } } ( |
