Rollup merge of #105019 - chenyukang:yukang/fix-104961-borrow, r=cjgillot
Add parentheses properly for borrowing suggestion Fixes #104961
This commit is contained in:
commit
0781d5dd8e
4 changed files with 104 additions and 7 deletions
|
@ -19,6 +19,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
|
use rustc_hir::is_range_literal;
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
|
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
|
||||||
use rustc_hir::{Expr, HirId};
|
use rustc_hir::{Expr, HirId};
|
||||||
|
@ -1349,14 +1350,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
// Issue #104961, we need to add parentheses properly for compond expressions
|
||||||
|
// for example, `x.starts_with("hi".to_string() + "you")`
|
||||||
|
// should be `x.starts_with(&("hi".to_string() + "you"))`
|
||||||
|
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; };
|
||||||
|
let body = self.tcx.hir().body(body_id);
|
||||||
|
let mut expr_finder = FindExprBySpan::new(span);
|
||||||
|
expr_finder.visit_expr(body.value);
|
||||||
|
let Some(expr) = expr_finder.result else { return false; };
|
||||||
|
let needs_parens = match expr.kind {
|
||||||
|
// parenthesize if needed (Issue #46756)
|
||||||
|
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
|
||||||
|
// parenthesize borrows of range literals (Issue #54505)
|
||||||
|
_ if is_range_literal(expr) => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
|
let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
|
||||||
err.span_suggestion_verbose(
|
let span = if needs_parens { span } else { span.shrink_to_lo() };
|
||||||
span.shrink_to_lo(),
|
let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" });
|
||||||
&format!(
|
let sugg_msg = &format!(
|
||||||
"consider{} borrowing here",
|
"consider{} borrowing here",
|
||||||
if is_mut { " mutably" } else { "" }
|
if is_mut { " mutably" } else { "" }
|
||||||
),
|
);
|
||||||
format!("&{}", if is_mut { "mut " } else { "" }),
|
|
||||||
|
let suggestions = if !needs_parens {
|
||||||
|
vec![(span.shrink_to_lo(), format!("{}", sugg_prefix))]
|
||||||
|
} else {
|
||||||
|
vec![
|
||||||
|
(span.shrink_to_lo(), format!("{}(", sugg_prefix)),
|
||||||
|
(span.shrink_to_hi(), ")".to_string()),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
err.multipart_suggestion_verbose(
|
||||||
|
sugg_msg,
|
||||||
|
suggestions,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
16
tests/ui/suggestions/issue-104961.fixed
Normal file
16
tests/ui/suggestions/issue-104961.fixed
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
fn foo(x: &str) -> bool {
|
||||||
|
x.starts_with(&("hi".to_string() + " you"))
|
||||||
|
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo2(x: &str) -> bool {
|
||||||
|
x.starts_with(&"hi".to_string())
|
||||||
|
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo("hi you");
|
||||||
|
foo2("hi");
|
||||||
|
}
|
16
tests/ui/suggestions/issue-104961.rs
Normal file
16
tests/ui/suggestions/issue-104961.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
fn foo(x: &str) -> bool {
|
||||||
|
x.starts_with("hi".to_string() + " you")
|
||||||
|
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo2(x: &str) -> bool {
|
||||||
|
x.starts_with("hi".to_string())
|
||||||
|
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo("hi you");
|
||||||
|
foo2("hi");
|
||||||
|
}
|
37
tests/ui/suggestions/issue-104961.stderr
Normal file
37
tests/ui/suggestions/issue-104961.stderr
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
--> $DIR/issue-104961.rs:4:19
|
||||||
|
|
|
||||||
|
LL | x.starts_with("hi".to_string() + " you")
|
||||||
|
| ----------- ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= note: the trait bound `String: Pattern<'_>` is not satisfied
|
||||||
|
= note: required for `String` to implement `Pattern<'_>`
|
||||||
|
note: required by a bound in `core::str::<impl str>::starts_with`
|
||||||
|
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | x.starts_with(&("hi".to_string() + " you"))
|
||||||
|
| ++ +
|
||||||
|
|
||||||
|
error[E0277]: expected a `FnMut<(char,)>` closure, found `String`
|
||||||
|
--> $DIR/issue-104961.rs:9:19
|
||||||
|
|
|
||||||
|
LL | x.starts_with("hi".to_string())
|
||||||
|
| ----------- ^^^^^^^^^^^^^^^^ the trait `Pattern<'_>` is not implemented for `String`
|
||||||
|
| |
|
||||||
|
| required by a bound introduced by this call
|
||||||
|
|
|
||||||
|
= note: the trait bound `String: Pattern<'_>` is not satisfied
|
||||||
|
= note: required for `String` to implement `Pattern<'_>`
|
||||||
|
note: required by a bound in `core::str::<impl str>::starts_with`
|
||||||
|
--> $SRC_DIR/core/src/str/mod.rs:LL:COL
|
||||||
|
help: consider borrowing here
|
||||||
|
|
|
||||||
|
LL | x.starts_with(&"hi".to_string())
|
||||||
|
| +
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
Add table
Add a link
Reference in a new issue