Skip to content

Commit

Permalink
Auto merge of #114474 - estebank:missing-semi, r=compiler-errors
Browse files Browse the repository at this point in the history
Detect missing `;` that parses as function call

Fix #106515.
  • Loading branch information
bors committed Aug 10, 2023
2 parents faee636 + 8ecb486 commit 439d066
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 13 deletions.
29 changes: 17 additions & 12 deletions compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
38 changes: 38 additions & 0 deletions tests/ui/suggestions/missing-semicolon.fixed
Original file line number Diff line number Diff line change
@@ -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() {}
38 changes: 38 additions & 0 deletions tests/ui/suggestions/missing-semicolon.rs
Original file line number Diff line number Diff line change
@@ -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() {}
75 changes: 75 additions & 0 deletions tests/ui/suggestions/missing-semicolon.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 439d066

Please sign in to comment.