1
Fork 0

Add Mutability::ref_prefix_str, order Mutability, simplify code

This commit is contained in:
Maybe Waffle 2022-11-23 17:59:26 +00:00
parent d121aa3b55
commit 8195e12dd9
8 changed files with 51 additions and 97 deletions

View file

@ -775,8 +775,9 @@ pub enum PatKind {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)] #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Copy)]
#[derive(HashStable_Generic, Encodable, Decodable)] #[derive(HashStable_Generic, Encodable, Decodable)]
pub enum Mutability { pub enum Mutability {
Mut, // N.B. Order is deliberate, so that Not < Mut
Not, Not,
Mut,
} }
impl Mutability { impl Mutability {
@ -787,12 +788,21 @@ impl Mutability {
} }
} }
/// Returns `""` (empty string) or `"mut "` depending on the mutability.
pub fn prefix_str(&self) -> &'static str { pub fn prefix_str(&self) -> &'static str {
match self { match self {
Mutability::Mut => "mut ", Mutability::Mut => "mut ",
Mutability::Not => "", Mutability::Not => "",
} }
} }
/// Returns `"&"` or `"&mut "` depending on the mutability.
pub fn ref_prefix_str(&self) -> &'static str {
match self {
Mutability::Not => "&",
Mutability::Mut => "&mut ",
}
}
} }
/// The kind of borrow in an `AddrOf` expression, /// The kind of borrow in an `AddrOf` expression,

View file

@ -571,11 +571,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let moved_place = &self.move_data.move_paths[move_out.path].place; let moved_place = &self.move_data.move_paths[move_out.path].place;
let move_spans = self.move_spans(moved_place.as_ref(), move_out.source); let move_spans = self.move_spans(moved_place.as_ref(), move_out.source);
let move_span = move_spans.args_or_use(); let move_span = move_spans.args_or_use();
let suggestion = if borrow_level == hir::Mutability::Mut { let suggestion = borrow_level.ref_prefix_str().to_owned();
"&mut ".to_string()
} else {
"&".to_string()
};
(move_span.shrink_to_lo(), suggestion) (move_span.shrink_to_lo(), suggestion)
}) })
.collect(); .collect();

View file

@ -389,13 +389,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// diagnostic: if the span starts with a mutable borrow of // diagnostic: if the span starts with a mutable borrow of
// a local variable, then just suggest the user remove it. // a local variable, then just suggest the user remove it.
PlaceRef { local: _, projection: [] } PlaceRef { local: _, projection: [] }
if { if self
if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { .infcx
snippet.starts_with("&mut ") .tcx
} else { .sess
false .source_map()
} .span_to_snippet(span)
} => .map_or(false, |snippet| snippet.starts_with("&mut ")) =>
{ {
err.span_label(span, format!("cannot {ACT}", ACT = act)); err.span_label(span, format!("cannot {ACT}", ACT = act));
err.span_suggestion( err.span_suggestion(

View file

@ -19,6 +19,7 @@ use rustc_trait_selection::traits::ObligationCause;
use super::method::probe; use super::method::probe;
use std::cmp::min;
use std::iter; use std::iter;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
@ -937,51 +938,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let Ok(src) = sm.span_to_snippet(sp) && let Ok(src) = sm.span_to_snippet(sp)
{ {
let derefs = "*".repeat(steps); let derefs = "*".repeat(steps);
if let Some((span, src, applicability)) = match mutbl_b { let old_prefix = mutbl_a.ref_prefix_str();
hir::Mutability::Mut => { let new_prefix = mutbl_b.ref_prefix_str().to_owned() + &derefs;
let new_prefix = "&mut ".to_owned() + &derefs;
match mutbl_a { let suggestion = replace_prefix(&src, old_prefix, &new_prefix).map(|_| {
hir::Mutability::Mut => { // skip `&` or `&mut ` if both mutabilities are mutable
replace_prefix(&src, "&mut ", &new_prefix).map(|_| { let lo = sp.lo() + BytePos(min(old_prefix.len(), mutbl_b.ref_prefix_str().len()) as _);
let pos = sp.lo() + BytePos(5); // skip `&` or `&mut `
let sp = sp.with_lo(pos).with_hi(pos); let hi = sp.lo() + BytePos(old_prefix.len() as _);
(sp, derefs, Applicability::MachineApplicable) let sp = sp.with_lo(lo).with_hi(hi);
})
} (
hir::Mutability::Not => { sp,
replace_prefix(&src, "&", &new_prefix).map(|_| { format!("{}{derefs}", if mutbl_a != mutbl_b { mutbl_b.prefix_str() } else { "" }),
let pos = sp.lo() + BytePos(1); if mutbl_b <= mutbl_a { Applicability::MachineApplicable } else { Applicability::MaybeIncorrect }
let sp = sp.with_lo(pos).with_hi(pos); )
( });
sp,
format!("mut {derefs}"), if let Some((span, src, applicability)) = suggestion {
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)
})
}
}
}
} {
return Some(( return Some((
span, span,
"consider dereferencing".to_string(), "consider dereferencing".to_string(),
@ -1005,10 +979,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If the expression has `&`, removing it would fix the error // If the expression has `&`, removing it would fix the error
prefix_span = prefix_span.with_hi(inner.span.lo()); prefix_span = prefix_span.with_hi(inner.span.lo());
expr = inner; expr = inner;
remove += match mutbl { remove.push_str(mutbl.ref_prefix_str());
hir::Mutability::Not => "&",
hir::Mutability::Mut => "&mut ",
};
steps -= 1; steps -= 1;
} else { } else {
break; break;

View file

@ -345,8 +345,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
if annotation { if annotation {
let suggest_annotation = match expr.peel_drop_temps().kind { let suggest_annotation = match expr.peel_drop_temps().kind {
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, _) => "&", hir::ExprKind::AddrOf(hir::BorrowKind::Ref, mutbl, _) => mutbl.ref_prefix_str(),
hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, _) => "&mut ",
_ => return true, _ => return true,
}; };
let mut tuple_indexes = Vec::new(); let mut tuple_indexes = Vec::new();

View file

@ -5,7 +5,6 @@ use crate::{
use hir::def_id::DefId; use hir::def_id::DefId;
use hir::HirId; use hir::HirId;
use hir::ItemKind; use hir::ItemKind;
use rustc_ast::Mutability;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
@ -88,14 +87,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let derefs = "*".repeat(pick.autoderefs); let derefs = "*".repeat(pick.autoderefs);
let autoref = match pick.autoref_or_ptr_adjustment { let autoref = match pick.autoref_or_ptr_adjustment {
Some(probe::AutorefOrPtrAdjustment::Autoref { Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => {
mutbl: Mutability::Mut, mutbl.ref_prefix_str()
.. }
}) => "&mut ",
Some(probe::AutorefOrPtrAdjustment::Autoref {
mutbl: Mutability::Not,
..
}) => "&",
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
}; };
if let Ok(self_expr) = self.sess().source_map().span_to_snippet(self_expr.span) 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> {
let derefs = "*".repeat(pick.autoderefs); let derefs = "*".repeat(pick.autoderefs);
let autoref = match pick.autoref_or_ptr_adjustment { let autoref = match pick.autoref_or_ptr_adjustment {
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Mut, .. }) => "&mut ", Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl, .. }) => mutbl.ref_prefix_str(),
Some(probe::AutorefOrPtrAdjustment::Autoref { mutbl: Mutability::Not, .. }) => "&",
Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "", Some(probe::AutorefOrPtrAdjustment::ToConstPtr) | None => "",
}; };

View file

@ -1147,19 +1147,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& assoc.kind == ty::AssocKind::Fn && assoc.kind == ty::AssocKind::Fn
{ {
let sig = self.tcx.fn_sig(assoc.def_id); let sig = self.tcx.fn_sig(assoc.def_id);
if let Some(first) = sig.inputs().skip_binder().get(0) { sig.inputs().skip_binder().get(0).and_then(|first| if first.peel_refs() == rcvr_ty.peel_refs() {
if first.peel_refs() == rcvr_ty.peel_refs() {
None
} else {
Some(if first.is_region_ptr() {
if first.is_mutable_ptr() { "&mut " } else { "&" }
} else {
""
})
}
} else {
None None
} } else {
Some(first.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()))
})
} else { } else {
None None
}; };
@ -2625,11 +2617,7 @@ fn print_disambiguation_help<'tcx>(
let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) { let (span, sugg) = if let (ty::AssocKind::Fn, Some((receiver, args))) = (kind, args) {
let args = format!( let args = format!(
"({}{})", "({}{})",
if rcvr_ty.is_region_ptr() { rcvr_ty.ref_mutability().map_or("", |mutbl| mutbl.ref_prefix_str()),
if rcvr_ty.is_mutable_ptr() { "&mut " } else { "&" }
} else {
""
},
std::iter::once(receiver) std::iter::once(receiver)
.chain(args.iter()) .chain(args.iter())
.map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| { .map(|arg| source_map.span_to_snippet(arg.span).unwrap_or_else(|_| {

View file

@ -15,7 +15,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource}; use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer}; use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter, Print, Printer};
use rustc_middle::ty::{self, DefIdTree, InferConst}; use rustc_middle::ty::{self, DefIdTree, InferConst};
use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef}; use rustc_middle::ty::{GenericArg, GenericArgKind, SubstsRef};
@ -508,10 +508,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
[ [
.., ..,
Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), target: _ }, Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)), target: _ },
] => match mut_ { ] => hir::Mutability::from(*mut_).ref_prefix_str(),
AutoBorrowMutability::Mut { .. } => "&mut ",
AutoBorrowMutability::Not => "&",
},
_ => "", _ => "",
}; };