ICE on "Error constructed but not emitted"
dwrensha opened this issue · 5 comments
I'm seeing an internal compiler error on the following input (found by fuzz-rustc):
fn i(n{...,f #
error: this file contains an un-closed delimiter
--> main.rs:2:2
|
1 | fn i(n{...,f #
| - - un-closed delimiter
| |
| un-closed delimiter
2 |
| ^
error: expected field pattern, found `...`
--> main.rs:1:8
|
1 | fn i(n{...,f #
| ^^^ help: to omit remaining fields, use one fewer `.`: `..`
error: internal compiler error: the following error was constructed but not emitted
error: expected `}`, found `,`
--> main.rs:1:11
|
1 | fn i(n{...,f #
| ---^
| | |
| | expected `}`
| `..` must be at the end and cannot have a trailing comma
thread 'rustc' panicked at 'explicit panic', src/librustc_errors/diagnostic_builder.rs:390:13
stack backtrace:
0: std::panicking::default_hook::{{closure}}
1: std::panicking::default_hook
2: rustc::util::common::panic_hook
3: std::panicking::rust_panic_with_hook
4: std::panicking::begin_panic
5: <rustc_errors::diagnostic_builder::DiagnosticBuilder as core::ops::drop::Drop>::drop
6: syntax::parse::parser::Parser::parse_pat_fields
7: syntax::parse::parser::Parser::parse_pat_with_range_pat
8: syntax::parse::parser::Parser::parse_fn_args::{{closure}}
9: syntax::parse::parser::Parser::parse_seq_to_before_tokens
10: syntax::parse::parser::Parser::parse_fn_args
11: syntax::parse::parser::Parser::parse_fn_decl
12: syntax::parse::parser::Parser::parse_item_fn
13: syntax::parse::parser::Parser::parse_item_implementation
14: syntax::parse::parser::Parser::parse_item_
15: syntax::parse::parser::Parser::parse_item
16: syntax::parse::parser::Parser::parse_mod_items
17: syntax::parse::parser::Parser::parse_crate_mod
18: syntax::parse::parse_crate_from_file
19: rustc_interface::passes::parse::{{closure}}
20: rustc::util::common::time
21: rustc_interface::passes::parse
22: rustc_interface::queries::Query<T>::compute
23: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::parse
24: rustc_interface::interface::run_compiler_in_existing_thread_pool
25: std::thread::local::LocalKey<T>::with
26: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
query stack during panic:
end of query stack
error: aborting due to 4 previous errors
error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: rustc 1.38.0-nightly (04b88a9eb 2019-07-29) running on x86_64-apple-darwin
The error happens on stable, beta, and nightly.
The only early return I see that doesn't emit delayed_error
is here:
https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs#L3623
Applying the most obvious patch, I get the following non-ICE output:
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fb5ff7e8f9..665308eda2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3620,7 +3620,15 @@ impl<'a> Parser<'a> {
let mut etc_span = None;
while self.token != token::CloseDelim(token::Brace) {
- let attrs = self.parse_outer_attributes()?;
+ let attrs = match self.parse_outer_attributes() {
+ Ok(attrs) => attrs,
+ Err(err) => {
+ if let Some(mut delayed) = delayed_err {
+ delayed.emit();
+ }
+ return Err(err);
+ },
+ };
let lo = self.token.span;
// check that a comma comes after every field
Compiling lolr v0.1.0 (/home/lampam/cpp/throwaway/lolr)
error: this file contains an un-closed delimiter
--> src/main.rs:1:16
|
1 | fn i(n{...,f #
| - - ^
| | |
| | un-closed delimiter
| un-closed delimiter
error: expected field pattern, found `...`
--> src/main.rs:1:8
|
1 | fn i(n{...,f #
| ^^^ help: to omit remaining fields, use one fewer `.`: `..`
error: expected `}`, found `,`
--> src/main.rs:1:11
|
1 | fn i(n{...,f #
| ---^
| | |
| | expected `}`
| `..` must be at the end and cannot have a trailing comma
error: expected `[`, found `}`
--> src/main.rs:1:15
|
1 | fn i(n{...,f #
| ^ expected `[`
error: expected `:`, found `)`
--> src/main.rs:1:15
|
1 | fn i(n{...,f #
| ^ expected `:`
error: expected one of `->`, `where`, or `{`, found `<eof>`
--> src/main.rs:1:15
|
1 | fn i(n{...,f #
| ^ expected one of `->`, `where`, or `{` here
error: aborting due to 6 previous errors
error: Could not compile `lolr`.
To learn more, run the command again with --verbose.
The "expected :
, found )
" bit doesn't seem quite right. 🙂
@ExpHP expected <something>, found <closing delimiter>
is an unfortunate side effect of the unmatched delimiter recovery logic not accounting for TokenTree
s. Submit a PR with this patch to fix this ICE as fixing the slightly misleading message will require a much larger (unrelated) change.
I'll toss one up after I finish running the test suite.
One thing: I'm not sure how to annotate the test. It looks like there's four errors that all point to EOF, but whatever I try to write, only one of them gets recognized as referring to that line.
fn i(n{...,f #
//~^ ERROR expected field pattern
//~| ERROR expected `}`, found `,`
//~ ERROR expected `[`, found `}`
//~ ERROR expected `:`, found `)`
//~ ERROR expected one of `->`, `where`, or `{`, found `<eof>`"
//~ ERROR this file contains an un-closed delimiter
unexpected errors (from JSON output): [
Error {
line_num: 7,
kind: Some(
Error,
),
msg: "7:52: 7:53: expected `[`, found `}`",
},
Error {
line_num: 7,
kind: Some(
Error,
),
msg: "7:52: 7:53: expected `:`, found `)`",
},
Error {
line_num: 7,
kind: Some(
Error,
),
msg: "7:52: 7:53: expected one of `->`, `where`, or `{`, found `<eof>`",
},
]
not found errors (from test file): [
Error {
line_num: 4,
kind: Some(
Error,
),
msg: "expected `[`, found `}`",
},
Error {
line_num: 5,
kind: Some(
Error,
),
msg: "expected `:`, found `)`",
},
Error {
line_num: 6,
kind: Some(
Error,
),
msg: "expected one of `->`, `where`, or `{`, found `<eof>`",
},
]