Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8195e12

Browse files
committed
Add Mutability::ref_prefix_str, order Mutability, simplify code
1 parent d121aa3 commit 8195e12

File tree

8 files changed

+51
-97
lines changed

8 files changed

+51
-97
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,9 @@ pub enum PatKind {
775775
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
776776
#[derive(HashStable_Generic, Encodable, Decodable)]
777777
pub enum Mutability {
778-
Mut,
778+
// N.B. Order is deliberate, so that Not < Mut
779779
Not,
780+
Mut,
780781
}
781782

782783
impl Mutability {
@@ -787,12 +788,21 @@ impl Mutability {
787788
}
788789
}
789790

791+
/// Returns `""` (empty string) or `"mut "` depending on the mutability.
790792
pub fn prefix_str(&self) -> &'static str {
791793
match self {
792794
Mutability::Mut => "mut ",
793795
Mutability::Not => "",
794796
}
795797
}
798+
799+
/// Returns `"&"` or `"&mut "` depending on the mutability.
800+
pub fn ref_prefix_str(&self) -> &'static str {
801+
match self {
802+
Mutability::Not => "&",
803+
Mutability::Mut => "&mut ",
804+
}
805+
}
796806
}
797807

798808
/// The kind of borrow in an `AddrOf` expression,

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -571,11 +571,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
571571
let moved_place = &self.move_data.move_paths[move_out.path].place;
572572
let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
573573
let move_span = move_spans.args_or_use();
574-
let suggestion = if borrow_level == hir::Mutability::Mut {
575-
"&mut ".to_string()
576-
} else {
577-
"&".to_string()
578-
};
574+
let suggestion = borrow_level.ref_prefix_str().to_owned();
579575
(move_span.shrink_to_lo(), suggestion)
580576
})
581577
.collect();

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -389,13 +389,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
389389
// diagnostic: if the span starts with a mutable borrow of
390390
// a local variable, then just suggest the user remove it.
391391
PlaceRef { local: _, projection: [] }
392-
if {
393-
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
394-
snippet.starts_with("&mut ")
395-
} else {
396-
false
397-
}
398-
} =>
392+
if self
393+
.infcx
394+
.tcx
395+
.sess
396+
.source_map()
397+
.span_to_snippet(span)
398+
.map_or(false, |snippet| snippet.starts_with("&mut ")) =>
399399
{
400400
err.span_label(span, format!("cannot {ACT}", ACT = act));
401401
err.span_suggestion(

compiler/rustc_hir_typeck/src/demand.rs

Lines changed: 20 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use rustc_trait_selection::traits::ObligationCause;
1919

2020
use super::method::probe;
2121

22+
use std::cmp::min;
2223
use std::iter;
2324

2425
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@@ -937,51 +938,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
937938
&& let Ok(src) = sm.span_to_snippet(sp)
938939
{
939940
let derefs = "*".repeat(steps);
940-
if let Some((span, src, applicability)) = match mutbl_b {
941-
hir::Mutability::Mut => {
942-
let new_prefix = "&mut ".to_owned() + &derefs;
943-
match mutbl_a {
944-
hir::Mutability::Mut => {
945-
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
946-
let pos = sp.lo() + BytePos(5);
947-
let sp = sp.with_lo(pos).with_hi(pos);
948-
(sp, derefs, Applicability::MachineApplicable)
949-
})
950-
}
951-
hir::Mutability::Not => {
952-
replace_prefix(&src, "&", &new_prefix).map(|_| {
953-
let pos = sp.lo() + BytePos(1);
954-
let sp = sp.with_lo(pos).with_hi(pos);
955-
(
956-
sp,
957-
format!("mut {derefs}"),
958-
Applicability::Unspecified,
959-
)
960-
})
961-
}
962-
}
963-
}
964-
hir::Mutability::Not => {
965-
let new_prefix = "&".to_owned() + &derefs;
966-
match mutbl_a {
967-
hir::Mutability::Mut => {
968-
replace_prefix(&src, "&mut ", &new_prefix).map(|_| {
969-
let lo = sp.lo() + BytePos(1);
970-
let hi = sp.lo() + BytePos(5);
971-
let sp = sp.with_lo(lo).with_hi(hi);
972-
(sp, derefs, Applicability::MachineApplicable)
973-
})
974-
}
975-
hir::Mutability::Not => {
976-
replace_prefix(&src, "&", &new_prefix).map(|_| {
977-
let pos = sp.lo() + BytePos(1);
978-
let sp = sp.with_lo(pos).with_hi(pos);
979-
(sp, derefs, Applicability::MachineApplicable)
980-
})
981-
}
982-
}
983-
}
984-
} {
941+
let old_prefix = mutbl_a.ref_prefix_str();
942+
let new_prefix = mutbl_b.ref_prefix_str().to_owned() + &derefs;
943+
944+
let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| {
945+
// skip `&` or `&mut ` if both mutabilities are mutable
946+
let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
947+
// skip `&` or `&mut `
948+
let hi = sp.lo() + BytePos(old_prefix.len() as _);
949+
let sp = sp.with_lo(lo).with_hi(hi);
950+
951+
(
952+
sp,
953+
format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }),
954+
if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }
955+
)
956+
});
957+
958+
if let Some((span, src, applicability)) = suggestion {
985959
return Some((
986960
span,
987961
"consider dereferencing".to_string(),
@@ -1005,10 +979,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1005979
// If the expression has `&`, removing it would fix the error
1006980
prefix_span = prefix_span.with_hi(inner.span.lo());
1007981
expr = inner;
1008-
remove += match mutbl {
1009-
hir::Mutability::Not => "&",
1010-
hir::Mutability::Mut => "&mut ",
1011-
};
982+
remove.push_str(mutbl.ref_prefix_str());
1012983
steps -= 1;
1013984
} else {
1014985
break;

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,8 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
345345
}
346346
if annotation {
347347
let suggest_annotation = match expr.peel_drop_temps().kind {
348-
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, _) => "&",
349-
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, _) => "&mut ",
348+
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, _) => mutbl.ref_prefix_str(),
350349
_ => return true,
351350
};
352351
let mut tuple_indexes = Vec::new();

compiler/rustc_hir_typeck/src/method/prelude2021.rs

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use crate::{
55
use hir::def_id::DefId;
66
use hir::HirId;
77
use hir::ItemKind;
8-
use rustc_ast::Mutability;
98
use rustc_errors::Applicability;
109
use rustc_hir as hir;
1110
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@@ -88,14 +87,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8887
let derefs = "*".repeat(pick.autoderefs);
8988

9089
let autoref = match pick.autoref_or_ptr_adjustment {
91-
Some(probe::AutorefOrPtrAdjustment::Autoref {
92-
mutbl: Mutability::Mut,
93-
..
94-
}) => "&mut ",
95-
Some(probe::AutorefOrPtrAdjustment::Autoref {
96-
mutbl: Mutability::Not,
97-
..
98-
}) => "&",
90+
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => {
91+
mutbl.ref_prefix_str()
92+
}
9993
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
10094
};
10195
if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span)
@@ -386,8 +380,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386380
let derefs = "*".repeat(pick.autoderefs);
387381

388382
let autoref = match pick.autoref_or_ptr_adjustment {
389-
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Mut, .. }) => "&mut ",
390-
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Not, .. }) => "&",
383+
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => mutbl.ref_prefix_str(),
391384
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
392385
};
393386

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,19 +1147,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11471147
&& assoc.kind == ty::AssocKind::Fn
11481148
{
11491149
let sig = self.tcx.fn_sig(assoc.def_id);
1150-
if let Some(first) = sig.inputs().skip_binder().get(0) {
1151-
if first.peel_refs() == rcvr_ty.peel_refs() {
1152-
None
1153-
} else {
1154-
Some(if first.is_region_ptr() {
1155-
if first.is_mutable_ptr() { "&mut " } else { "&" }
1156-
} else {
1157-
""
1158-
})
1159-
}
1160-
} else {
1150+
sig.inputs().skip_binder().get(0).and_then(|first| if first.peel_refs() == rcvr_ty.peel_refs() {
11611151
None
1162-
}
1152+
} else {
1153+
Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()))
1154+
})
11631155
} else {
11641156
None
11651157
};
@@ -2625,11 +2617,7 @@ fn print_disambiguation_help<'tcx>(
26252617
let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
26262618
let args = format!(
26272619
"({}{})",
2628-
if rcvr_ty.is_region_ptr() {
2629-
if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
2630-
} else {
2631-
""
2632-
},
2620+
rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
26332621
std::iter::once(receiver)
26342622
.chain(args.iter())
26352623
.map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {

compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::intravisit::{self, Visitor};
1515
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
1616
use rustc_middle::hir::nested_filter;
1717
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
18-
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
18+
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
1919
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
2020
use rustc_middle::ty::{self, DefIdTree, InferConst};
2121
use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef};
@@ -508,10 +508,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
508508
[
509509
..,
510510
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), target: _ },
511-
] => match mut_ {
512-
AutoBorrowMutability::Mut { .. } => "&mut ",
513-
AutoBorrowMutability::Not => "&",
514-
},
511+
] => hir::Mutability::from(*mut_).ref_prefix_str(),
515512
_ => "",
516513
};
517514

0 commit comments

Comments
 (0)