Suggest better place to add call parentheses for method expressions wrapped in parentheses

This commit is contained in:
Jakub Beránek 2021-09-17 22:18:05 +02:00
parent 207d9558d0
commit 68147ebd60
No known key found for this signature in database
GPG Key ID: DBC553E540C2F619
5 changed files with 47 additions and 4 deletions

View File

@ -1844,6 +1844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
field, field,
expr_t, expr_t,
expr, expr,
None,
); );
} }
err.emit(); err.emit();
@ -1870,9 +1871,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
let expr_snippet = let expr_snippet =
self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new()); self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or(String::new());
if expr_is_call && expr_snippet.starts_with("(") && expr_snippet.ends_with(")") { let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")");
let after_open = expr.span.lo() + rustc_span::BytePos(1); let after_open = expr.span.lo() + rustc_span::BytePos(1);
let before_close = expr.span.hi() - rustc_span::BytePos(1); let before_close = expr.span.hi() - rustc_span::BytePos(1);
if expr_is_call && is_wrapped {
err.multipart_suggestion( err.multipart_suggestion(
"remove wrapping parentheses to call the method", "remove wrapping parentheses to call the method",
vec![ vec![
@ -1882,12 +1885,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} else if !self.expr_in_place(expr.hir_id) { } else if !self.expr_in_place(expr.hir_id) {
// Suggest call parentheses inside the wrapping parentheses
let span = if is_wrapped {
expr.span.with_lo(after_open).with_hi(before_close)
} else {
expr.span
};
self.suggest_method_call( self.suggest_method_call(
&mut err, &mut err,
"use parentheses to call the method", "use parentheses to call the method",
field, field,
expr_t, expr_t,
expr, expr,
Some(span),
); );
} else { } else {
err.help("methods are immutable and cannot be assigned to"); err.help("methods are immutable and cannot be assigned to");

View File

@ -141,6 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
method_name: Ident, method_name: Ident,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
call_expr: &hir::Expr<'_>, call_expr: &hir::Expr<'_>,
span: Option<Span>,
) { ) {
let params = self let params = self
.probe_for_name( .probe_for_name(
@ -159,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.unwrap_or(0); .unwrap_or(0);
// Account for `foo.bar<T>`; // Account for `foo.bar<T>`;
let sugg_span = call_expr.span.shrink_to_hi(); let sugg_span = span.unwrap_or_else(|| call_expr.span).shrink_to_hi();
let (suggestion, applicability) = ( let (suggestion, applicability) = (
format!("({})", (0..params).map(|_| "_").collect::<Vec<_>>().join(", ")), format!("({})", (0..params).map(|_| "_").collect::<Vec<_>>().join(", ")),
if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect }, if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect },

View File

@ -0,0 +1,9 @@
// run-rustfix
fn main() {
let a = Some(42);
println!(
"The value is {}.",
(a.unwrap()) //~ERROR [E0615]
);
}

View File

@ -0,0 +1,9 @@
// run-rustfix
fn main() {
let a = Some(42);
println!(
"The value is {}.",
(a.unwrap) //~ERROR [E0615]
);
}

View File

@ -0,0 +1,14 @@
error[E0615]: attempted to take value of method `unwrap` on type `Option<{integer}>`
--> $DIR/issue-89044-wrapped-expr-method.rs:7:12
|
LL | (a.unwrap)
| ^^^^^^ method, not a field
|
help: use parentheses to call the method
|
LL | (a.unwrap())
| ++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0615`.