From 68147ebd603129c9f2c56bc47a5d2417a5df1777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 17 Sep 2021 22:18:05 +0200 Subject: [PATCH] Suggest better place to add call parentheses for method expressions wrapped in parentheses --- compiler/rustc_typeck/src/check/expr.rs | 16 +++++++++++++--- compiler/rustc_typeck/src/check/method/mod.rs | 3 ++- .../typeck/issue-89044-wrapped-expr-method.fixed | 9 +++++++++ .../ui/typeck/issue-89044-wrapped-expr-method.rs | 9 +++++++++ .../issue-89044-wrapped-expr-method.stderr | 14 ++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed create mode 100644 src/test/ui/typeck/issue-89044-wrapped-expr-method.rs create mode 100644 src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 917adf0e2b9..1d08ecee558 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -1844,6 +1844,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { field, expr_t, expr, + None, ); } err.emit(); @@ -1870,9 +1871,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }; let expr_snippet = 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 after_open = expr.span.lo() + rustc_span::BytePos(1); - let before_close = expr.span.hi() - rustc_span::BytePos(1); + let is_wrapped = expr_snippet.starts_with("(") && expr_snippet.ends_with(")"); + let after_open = expr.span.lo() + rustc_span::BytePos(1); + let before_close = expr.span.hi() - rustc_span::BytePos(1); + + if expr_is_call && is_wrapped { err.multipart_suggestion( "remove wrapping parentheses to call the method", vec![ @@ -1882,12 +1885,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Applicability::MachineApplicable, ); } 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( &mut err, "use parentheses to call the method", field, expr_t, expr, + Some(span), ); } else { err.help("methods are immutable and cannot be assigned to"); diff --git a/compiler/rustc_typeck/src/check/method/mod.rs b/compiler/rustc_typeck/src/check/method/mod.rs index 2136d925423..8e09aa97dcf 100644 --- a/compiler/rustc_typeck/src/check/method/mod.rs +++ b/compiler/rustc_typeck/src/check/method/mod.rs @@ -141,6 +141,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { method_name: Ident, self_ty: Ty<'tcx>, call_expr: &hir::Expr<'_>, + span: Option, ) { let params = self .probe_for_name( @@ -159,7 +160,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .unwrap_or(0); // Account for `foo.bar`; - 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) = ( format!("({})", (0..params).map(|_| "_").collect::>().join(", ")), if params > 0 { Applicability::HasPlaceholders } else { Applicability::MaybeIncorrect }, diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed new file mode 100644 index 00000000000..0a3086a345d --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.fixed @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap()) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs new file mode 100644 index 00000000000..83617e035e9 --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.rs @@ -0,0 +1,9 @@ +// run-rustfix + +fn main() { + let a = Some(42); + println!( + "The value is {}.", + (a.unwrap) //~ERROR [E0615] + ); +} diff --git a/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr new file mode 100644 index 00000000000..6fa0915dcaf --- /dev/null +++ b/src/test/ui/typeck/issue-89044-wrapped-expr-method.stderr @@ -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`.