Skip to content

Commit

Permalink
Replace convenient function remove_prefix() with replace_prefix()
Browse files Browse the repository at this point in the history
  • Loading branch information
ldm0 committed May 2, 2020
1 parent 089d4bb commit 9a212c1
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 51 deletions.
109 changes: 60 additions & 49 deletions src/librustc_typeck/check/demand.rs
Expand Up @@ -353,6 +353,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
false
}

fn replace_prefix<A, B, C>(&self, s: A, old: B, new: C) -> Option<String>
where
A: AsRef<str>,
B: AsRef<str>,
C: AsRef<str>,
{
let s = s.as_ref();
let old = old.as_ref();
if s.starts_with(old) { Some(new.as_ref().to_owned() + &s[old.len()..]) } else { None }
}

/// This function is used to determine potential "simple" improvements or users' errors and
/// provide them useful help. For example:
///
Expand Down Expand Up @@ -393,20 +404,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
let expr = expr.peel_drop_temps();

let remove_prefix = |s: String, prefix: &str| {
if s.starts_with(prefix) { Some(s[prefix.len()..].to_string()) } else { None }
};

match (&expr.kind, &expected.kind, &checked_ty.kind) {
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (&exp.kind, &check.kind) {
(&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
if let hir::ExprKind::Lit(_) = expr.kind {
if let Ok(src) = sm.span_to_snippet(sp) {
if let Some(src) = remove_prefix(src, "b\"") {
if let Some(src) = self.replace_prefix(src, "b\"", "\"") {
return Some((
sp,
"consider removing the leading `b`",
format!("\"{}", src),
src,
Applicability::MachineApplicable,
));
}
Expand All @@ -416,11 +423,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => {
if let hir::ExprKind::Lit(_) = expr.kind {
if let Ok(src) = sm.span_to_snippet(sp) {
if let Some(src) = remove_prefix(src, "\"") {
if let Some(src) = self.replace_prefix(src, "\"", "b\"") {
return Some((
sp,
"consider adding a leading `b`",
format!("b\"{}", src),
src,
Applicability::MachineApplicable,
));
}
Expand Down Expand Up @@ -539,7 +546,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// we may want to suggest removing a `&`.
if sm.is_imported(expr.span) {
if let Ok(src) = sm.span_to_snippet(sp) {
if let Some(src) = remove_prefix(src, "&") {
if let Some(src) = self.replace_prefix(src, "&", "") {
return Some((
sp,
"consider removing the borrow",
Expand Down Expand Up @@ -569,52 +576,56 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if steps > 0 {
// The pointer type implements `Copy` trait so the suggestion is always valid.
if let Ok(src) = sm.span_to_snippet(sp) {
let derefs = "*".repeat(steps);
match mutbl_b {
hir::Mutability::Mut => match mutbl_a {
hir::Mutability::Mut => {
if let Some(src) = remove_prefix(src, "&mut ") {
return Some((
sp,
"consider dereferencing",
format!("&mut {}{}", derefs, src),
Applicability::MachineApplicable,
));
let derefs = &"*".repeat(steps);
if let Some((src, applicability)) = match mutbl_b {
hir::Mutability::Mut => {
let new_prefix = "&mut ".to_owned() + derefs;
match mutbl_a {
hir::Mutability::Mut => {
if let Some(s) =
self.replace_prefix(src, "&mut ", new_prefix)
{
Some((s, Applicability::MachineApplicable))
} else {
None
}
}
}
hir::Mutability::Not => {
if let Some(src) = remove_prefix(src, "&") {
return Some((
sp,
"consider dereferencing",
format!("&mut {}{}", derefs, src),
Applicability::Unspecified,
));
hir::Mutability::Not => {
if let Some(s) =
self.replace_prefix(src, "&", new_prefix)
{
Some((s, Applicability::Unspecified))
} else {
None
}
}
}
},
hir::Mutability::Not => match mutbl_a {
hir::Mutability::Mut => {
if let Some(src) = remove_prefix(src, "&mut ") {
return Some((
sp,
"consider dereferencing",
format!("&{}{}", derefs, src),
Applicability::MachineApplicable,
));
}
hir::Mutability::Not => {
let new_prefix = "&".to_owned() + derefs;
match mutbl_a {
hir::Mutability::Mut => {
if let Some(s) =
self.replace_prefix(src, "&mut ", new_prefix)
{
Some((s, Applicability::MachineApplicable))
} else {
None
}
}
}
hir::Mutability::Not => {
if let Some(src) = remove_prefix(src, "&") {
return Some((
sp,
"consider dereferencing",
format!("&{}{}", derefs, src),
Applicability::MachineApplicable,
));
hir::Mutability::Not => {
if let Some(s) =
self.replace_prefix(src, "&", new_prefix)
{
Some((s, Applicability::MachineApplicable))
} else {
None
}
}
}
},
}
} {
return Some((sp, "consider dereferencing", src, applicability));
}
}
}
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-71676-1.fixed
Expand Up @@ -50,5 +50,4 @@ fn main() {

let mut a = Emm(Foo(Bar(0)));
let _: *mut u8 = &mut ***a; //~ ERROR mismatched types

}
1 change: 0 additions & 1 deletion src/test/ui/issues/issue-71676-1.rs
Expand Up @@ -50,5 +50,4 @@ fn main() {

let mut a = Emm(Foo(Bar(0)));
let _: *mut u8 = &mut a; //~ ERROR mismatched types

}

0 comments on commit 9a212c1

Please sign in to comment.