Skip to content

Commit 4061118

Browse files
authored
Rollup merge of #141670 - chenyukang:yukang-fix-ice-from-contracts, r=nnethercote
Fix ICE in tokenstream with contracts from parser recovery Fixes #140683 After two times of parsing error, the `recover_stmt_` constructs an error ast, then when we expand macors, the invalid tokenstream triggered ICE because of mismatched delims. Expected `{` and get other tokens is an obvious error message, too much effort on recovery may introduce noise. r? ``@nnethercote``
2 parents d6ef1e6 + adcd0bf commit 4061118

6 files changed

+60
-26
lines changed

compiler/rustc_parse/src/parser/stmt.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -515,8 +515,8 @@ impl<'a> Parser<'a> {
515515
fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
516516
let prev = self.prev_token.span;
517517
let sp = self.token.span;
518-
let mut e = self.dcx().struct_span_err(sp, msg);
519-
self.label_expected_raw_ref(&mut e);
518+
let mut err = self.dcx().struct_span_err(sp, msg);
519+
self.label_expected_raw_ref(&mut err);
520520

521521
let do_not_suggest_help = self.token.is_keyword(kw::In)
522522
|| self.token == token::Colon
@@ -558,20 +558,19 @@ impl<'a> Parser<'a> {
558558
stmt.span
559559
};
560560
self.suggest_fixes_misparsed_for_loop_head(
561-
&mut e,
561+
&mut err,
562562
prev.between(sp),
563563
stmt_span,
564564
&stmt.kind,
565565
);
566566
}
567567
Err(e) => {
568-
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
569-
e.cancel();
568+
e.delay_as_bug();
570569
}
571570
_ => {}
572571
}
573-
e.span_label(sp, "expected `{`");
574-
e
572+
err.span_label(sp, "expected `{`");
573+
err
575574
}
576575

577576
fn suggest_fixes_misparsed_for_loop_head(

tests/crashes/140683.rs

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(contracts)]
2+
#![allow(incomplete_features)]
3+
4+
struct T;
5+
6+
impl T {
7+
#[core::contracts::ensures] //~ ERROR expected a `Fn(&_)` closure, found `()`
8+
fn b() {(loop)}
9+
//~^ ERROR expected `{`, found `)`
10+
//~| ERROR expected `{`, found `)`
11+
}
12+
13+
fn main() {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
error: expected `{`, found `)`
2+
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18
3+
|
4+
LL | fn b() {(loop)}
5+
| ----^ expected `{`
6+
| |
7+
| while parsing this `loop` expression
8+
9+
error: expected `{`, found `)`
10+
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18
11+
|
12+
LL | fn b() {(loop)}
13+
| ----^ expected `{`
14+
| |
15+
| while parsing this `loop` expression
16+
|
17+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
18+
19+
error[E0277]: expected a `Fn(&_)` closure, found `()`
20+
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5
21+
|
22+
LL | #[core::contracts::ensures]
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
24+
| |
25+
| expected an `Fn(&_)` closure, found `()`
26+
| required by a bound introduced by this call
27+
|
28+
= help: the trait `for<'a> Fn(&'a _)` is not implemented for `()`
29+
note: required by a bound in `build_check_ensures`
30+
--> $SRC_DIR/core/src/contracts.rs:LL:COL
31+
32+
error: aborting due to 3 previous errors
33+
34+
For more information about this error, try `rustc --explain E0277`.

tests/ui/macros/no-close-delim-issue-139248.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
macro_rules! m {
44
(static a : () = $e:expr) => {
5-
static a : () = $e;
6-
//~^ ERROR macro expansion ends with an incomplete expression: expected expression
7-
}
5+
static a: () = $e;
6+
};
87
}
98

109
m! { static a : () = (if b) }
Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,27 @@
11
error: expected `{`, found `)`
2-
--> $DIR/no-close-delim-issue-139248.rs:10:27
2+
--> $DIR/no-close-delim-issue-139248.rs:9:27
33
|
44
LL | m! { static a : () = (if b) }
55
| ^ expected `{`
66
|
77
note: the `if` expression is missing a block after this condition
8-
--> $DIR/no-close-delim-issue-139248.rs:10:26
8+
--> $DIR/no-close-delim-issue-139248.rs:9:26
99
|
1010
LL | m! { static a : () = (if b) }
1111
| ^
1212

1313
error: expected `{`, found `)`
14-
--> $DIR/no-close-delim-issue-139248.rs:10:27
14+
--> $DIR/no-close-delim-issue-139248.rs:9:27
1515
|
1616
LL | m! { static a : () = (if b) }
1717
| ^ expected `{`
1818
|
1919
note: the `if` expression is missing a block after this condition
20-
--> $DIR/no-close-delim-issue-139248.rs:10:26
20+
--> $DIR/no-close-delim-issue-139248.rs:9:26
2121
|
2222
LL | m! { static a : () = (if b) }
2323
| ^
2424
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2525

26-
error: macro expansion ends with an incomplete expression: expected expression
27-
--> $DIR/no-close-delim-issue-139248.rs:5:28
28-
|
29-
LL | static a : () = $e;
30-
| ^ expected expression
31-
32-
error: aborting due to 3 previous errors
26+
error: aborting due to 2 previous errors
3327

0 commit comments

Comments
 (0)