about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-08-10 20:30:18 +0000
committerbors <bors@rust-lang.org>2023-08-10 20:30:18 +0000
commit439d066bcf9496b1b8c8dde8bef3bce607a621bb (patch)
treeb5e9226036ee461340fd3180c4582d074bc5d939
parentfaee636ebfff793ea9dcff17960a611b580e3cd5 (diff)
parent8ecb486add8eb58dedc6fa88f2fe42e8941335c3 (diff)
downloadrust-439d066bcf9496b1b8c8dde8bef3bce607a621bb.tar.gz
rust-439d066bcf9496b1b8c8dde8bef3bce607a621bb.zip
Auto merge of #114474 - estebank:missing-semi, r=compiler-errors
Detect missing `;` that parses as function call

Fix #106515.
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs29
-rw-r--r--tests/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr2
-rw-r--r--tests/ui/suggestions/missing-semicolon.fixed38
-rw-r--r--tests/ui/suggestions/missing-semicolon.rs38
-rw-r--r--tests/ui/suggestions/missing-semicolon.stderr75
5 files changed, 169 insertions, 13 deletions
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index ba00954db91..dd79d1afc62 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -645,18 +645,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.typeck_results.borrow().qpath_res(qpath, callee_expr.hir_id)
             }
             hir::ExprKind::Call(ref inner_callee, _) => {
-                // If the call spans more than one line and the callee kind is
-                // itself another `ExprCall`, that's a clue that we might just be
-                // missing a semicolon (Issue #51055)
-                let call_is_multiline = self.tcx.sess.source_map().is_multiline(call_expr.span);
-                if call_is_multiline {
-                    err.span_suggestion(
-                        callee_expr.span.shrink_to_hi(),
-                        "consider using a semicolon here",
-                        ";",
-                        Applicability::MaybeIncorrect,
-                    );
-                }
                 if let hir::ExprKind::Path(ref inner_qpath) = inner_callee.kind {
                     inner_callee_path = Some(inner_qpath);
                     self.typeck_results.borrow().qpath_res(inner_qpath, inner_callee.hir_id)
@@ -668,6 +656,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         if !self.maybe_suggest_bad_array_definition(&mut err, call_expr, callee_expr) {
+            // If the call spans more than one line and the callee kind is
+            // itself another `ExprCall`, that's a clue that we might just be
+            // missing a semicolon (#51055, #106515).
+            let call_is_multiline = self
+                .tcx
+                .sess
+                .source_map()
+                .is_multiline(call_expr.span.with_lo(callee_expr.span.hi()))
+                && call_expr.span.ctxt() == callee_expr.span.ctxt();
+            if call_is_multiline {
+                err.span_suggestion(
+                    callee_expr.span.shrink_to_hi(),
+                    "consider using a semicolon here to finish the statement",
+                    ";",
+                    Applicability::MaybeIncorrect,
+                );
+            }
             if let Some((maybe_def, output_ty, _)) = self.extract_callable_info(callee_ty)
                 && !self.type_is_sized_modulo_regions(self.param_env, output_ty)
             {
diff --git a/tests/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr b/tests/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr
index 438075083d3..bb8b9b37067 100644
--- a/tests/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr
+++ b/tests/ui/suggestions/issue-51055-missing-semicolon-between-call-and-tuple.stderr
@@ -5,7 +5,7 @@ LL |   fn vindictive() -> bool { true }
    |   ----------------------- `vindictive` defined here returns `bool`
 ...
 LL |       vindictive()
-   |       -^^^^^^^^^^^- help: consider using a semicolon here: `;`
+   |       -^^^^^^^^^^^- help: consider using a semicolon here to finish the statement: `;`
    |  _____|
    | |
 LL | |     (1, 2)
diff --git a/tests/ui/suggestions/missing-semicolon.fixed b/tests/ui/suggestions/missing-semicolon.fixed
new file mode 100644
index 00000000000..df355f0b007
--- /dev/null
+++ b/tests/ui/suggestions/missing-semicolon.fixed
@@ -0,0 +1,38 @@
+// run-rustfix
+#![allow(dead_code, unused_variables, path_statements)]
+fn a() {
+    let x = 5;
+    let y = x; //~ ERROR expected function
+    (); //~ ERROR expected `;`, found `}`
+}
+
+fn b() {
+    let x = 5;
+    let y = x; //~ ERROR expected function
+    ();
+}
+fn c() {
+    let x = 5;
+    x; //~ ERROR expected function
+    ()
+}
+fn d() { // ok
+    let x = || ();
+    x
+    ()
+}
+fn e() { // ok
+    let x = || ();
+    x
+    ();
+}
+fn f()
+ {
+    let y = 5; //~ ERROR expected function
+    (); //~ ERROR expected `;`, found `}`
+}
+fn g() {
+    5; //~ ERROR expected function
+    ();
+}
+fn main() {}
diff --git a/tests/ui/suggestions/missing-semicolon.rs b/tests/ui/suggestions/missing-semicolon.rs
new file mode 100644
index 00000000000..12ef3d33e5f
--- /dev/null
+++ b/tests/ui/suggestions/missing-semicolon.rs
@@ -0,0 +1,38 @@
+// run-rustfix
+#![allow(dead_code, unused_variables, path_statements)]
+fn a() {
+    let x = 5;
+    let y = x //~ ERROR expected function
+    () //~ ERROR expected `;`, found `}`
+}
+
+fn b() {
+    let x = 5;
+    let y = x //~ ERROR expected function
+    ();
+}
+fn c() {
+    let x = 5;
+    x //~ ERROR expected function
+    ()
+}
+fn d() { // ok
+    let x = || ();
+    x
+    ()
+}
+fn e() { // ok
+    let x = || ();
+    x
+    ();
+}
+fn f()
+ {
+    let y = 5 //~ ERROR expected function
+    () //~ ERROR expected `;`, found `}`
+}
+fn g() {
+    5 //~ ERROR expected function
+    ();
+}
+fn main() {}
diff --git a/tests/ui/suggestions/missing-semicolon.stderr b/tests/ui/suggestions/missing-semicolon.stderr
new file mode 100644
index 00000000000..54a64f664b5
--- /dev/null
+++ b/tests/ui/suggestions/missing-semicolon.stderr
@@ -0,0 +1,75 @@
+error: expected `;`, found `}`
+  --> $DIR/missing-semicolon.rs:6:7
+   |
+LL |     ()
+   |       ^ help: add `;` here
+LL | }
+   | - unexpected token
+
+error: expected `;`, found `}`
+  --> $DIR/missing-semicolon.rs:32:7
+   |
+LL |     ()
+   |       ^ help: add `;` here
+LL | }
+   | - unexpected token
+
+error[E0618]: expected function, found `{integer}`
+  --> $DIR/missing-semicolon.rs:5:13
+   |
+LL |       let x = 5;
+   |           - `x` has type `{integer}`
+LL |       let y = x
+   |               ^- help: consider using a semicolon here to finish the statement: `;`
+   |  _____________|
+   | |
+LL | |     ()
+   | |______- call expression requires function
+
+error[E0618]: expected function, found `{integer}`
+  --> $DIR/missing-semicolon.rs:11:13
+   |
+LL |       let x = 5;
+   |           - `x` has type `{integer}`
+LL |       let y = x
+   |               ^- help: consider using a semicolon here to finish the statement: `;`
+   |  _____________|
+   | |
+LL | |     ();
+   | |______- call expression requires function
+
+error[E0618]: expected function, found `{integer}`
+  --> $DIR/missing-semicolon.rs:16:5
+   |
+LL |       let x = 5;
+   |           - `x` has type `{integer}`
+LL |       x
+   |       ^- help: consider using a semicolon here to finish the statement: `;`
+   |  _____|
+   | |
+LL | |     ()
+   | |______- call expression requires function
+
+error[E0618]: expected function, found `{integer}`
+  --> $DIR/missing-semicolon.rs:31:13
+   |
+LL |       let y = 5
+   |               ^- help: consider using a semicolon here to finish the statement: `;`
+   |  _____________|
+   | |
+LL | |     ()
+   | |______- call expression requires function
+
+error[E0618]: expected function, found `{integer}`
+  --> $DIR/missing-semicolon.rs:35:5
+   |
+LL |       5
+   |       ^- help: consider using a semicolon here to finish the statement: `;`
+   |  _____|
+   | |
+LL | |     ();
+   | |______- call expression requires function
+
+error: aborting due to 7 previous errors
+
+For more information about this error, try `rustc --explain E0618`.