X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=compiler%2Frustc_hir_typeck%2Fsrc%2Fdemand.rs;h=24184bdbf5cdcd74b125f185243919086905910f;hb=552b63c1619498f1a17fd482f4bb87815d8fdc48;hp=934d12404427e150a815484f3d9b3a1bca6afa9f;hpb=341d8b8a2c290b4535e965867e876b095461ff6e;p=rust.git diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 934d1240442..24184bdbf5c 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -19,6 +19,7 @@ use super::method::probe; +use std::cmp::min; use std::iter; impl<'a, 'tcx> FnCtxt<'a, 'tcx> { @@ -56,8 +57,8 @@ pub fn emit_coerce_suggestions( self.note_internal_mutation_in_method(err, expr, expected, expr_ty); } - // Requires that the two types unify, and prints an error message if - // they don't. + /// Requires that the two types unify, and prints an error message if + /// they don't. pub fn demand_suptype(&self, sp: Span, expected: Ty<'tcx>, actual: Ty<'tcx>) { if let Some(mut e) = self.demand_suptype_diag(sp, expected, actual) { e.emit(); @@ -855,31 +856,21 @@ pub fn check_ref( .. })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id)) { - if mutability == hir::Mutability::Mut { + if mutability.is_mut() { // Suppressing this diagnostic, we'll properly print it in `check_expr_assign` return None; } } let sugg_expr = if needs_parens { format!("({src})") } else { src }; - return Some(match mutability { - hir::Mutability::Mut => ( - sp, - "consider mutably borrowing here".to_string(), - format!("{prefix}&mut {sugg_expr}"), - Applicability::MachineApplicable, - false, - false, - ), - hir::Mutability::Not => ( - sp, - "consider borrowing here".to_string(), - format!("{prefix}&{sugg_expr}"), - Applicability::MachineApplicable, - false, - false, - ), - }); + return Some(( + sp, + format!("consider {}borrowing here", mutability.mutably_str()), + format!("{prefix}{}{sugg_expr}", mutability.ref_prefix_str()), + Applicability::MachineApplicable, + false, + false, + )); } } } @@ -937,51 +928,24 @@ pub fn check_ref( && let Ok(src) = sm.span_to_snippet(sp) { let derefs = "*".repeat(steps); - if let Some((span, src, applicability)) = match mutbl_b { - hir::Mutability::Mut => { - let new_prefix = "&mut ".to_owned() + &derefs; - match mutbl_a { - hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(5); - let sp = sp.with_lo(pos).with_hi(pos); - (sp, derefs, Applicability::MachineApplicable) - }) - } - hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(1); - let sp = sp.with_lo(pos).with_hi(pos); - ( - sp, - format!("mut {derefs}"), - Applicability::Unspecified, - ) - }) - } - } - } - hir::Mutability::Not => { - let new_prefix = "&".to_owned() + &derefs; - match mutbl_a { - hir::Mutability::Mut => { - replace_prefix(&src, "&mut ", &new_prefix).map(|_| { - let lo = sp.lo() + BytePos(1); - let hi = sp.lo() + BytePos(5); - let sp = sp.with_lo(lo).with_hi(hi); - (sp, derefs, Applicability::MachineApplicable) - }) - } - hir::Mutability::Not => { - replace_prefix(&src, "&", &new_prefix).map(|_| { - let pos = sp.lo() + BytePos(1); - let sp = sp.with_lo(pos).with_hi(pos); - (sp, derefs, Applicability::MachineApplicable) - }) - } - } - } - } { + let old_prefix = mutbl_a.ref_prefix_str(); + let new_prefix = mutbl_b.ref_prefix_str().to_owned() + &derefs; + + let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| { + // skip `&` or `&mut ` if both mutabilities are mutable + let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _); + // skip `&` or `&mut ` + let hi = sp.lo() + BytePos(old_prefix.len() as _); + let sp = sp.with_lo(lo).with_hi(hi); + + ( + sp, + format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }), + if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect } + ) + }); + + if let Some((span, src, applicability)) = suggestion { return Some(( span, "consider dereferencing".to_string(), @@ -1005,10 +969,7 @@ pub fn check_ref( // If the expression has `&`, removing it would fix the error prefix_span = prefix_span.with_hi(inner.span.lo()); expr = inner; - remove += match mutbl { - hir::Mutability::Not => "&", - hir::Mutability::Mut => "&mut ", - }; + remove.push_str(mutbl.ref_prefix_str()); steps -= 1; } else { break;