Add Mutability::ref_prefix_str
, order Mutability
, simplify code
This commit is contained in:
parent
d121aa3b55
commit
8195e12dd9
8 changed files with 51 additions and 97 deletions
|
@ -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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 => "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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(|_| {
|
||||||
|
|
|
@ -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 => "&",
|
|
||||||
},
|
|
||||||
_ => "",
|
_ => "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue