Skip to content

Commit 8f8b325

Browse files
committed
lex_via_rustc: report compiler errors rather than propagating the panic
1 parent 08208d4 commit 8f8b325

File tree

3 files changed

+30
-19
lines changed

3 files changed

+30
-19
lines changed

src/comparison.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ pub fn regularised_from_rustc(input: &str, edition: Edition) -> Regularisation {
2929
match lex_via_rustc::analyse(input, edition) {
3030
Accepts(tokens) => Regularisation::Accepts(regularise_from_rustc(tokens)),
3131
Rejects(_, messages) => Regularisation::Rejects(messages),
32+
CompilerError => Regularisation::ModelError(vec!["rustc compiler error".into()]),
3233
}
3334
}
3435

src/lex_via_rustc.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ pub enum RustcStringStyle {
147147
///
148148
/// If the input is accepted, returns a list of tokens, in [`RustcToken`] form.
149149
/// Otherwise returns at least one error message.
150+
///
151+
/// If rustc panics (ie, it would report an ICE), the panic message is sent to
152+
/// standard error and this function returns CompilerError.
150153
pub fn analyse(input: &str, edition: Edition) -> Analysis {
151154
let error_list = Arc::new(Mutex::new(Vec::new()));
152155
fn extract_errors(error_list: ErrorAccumulator) -> Vec<String> {
@@ -158,27 +161,29 @@ pub fn analyse(input: &str, edition: Edition) -> Analysis {
158161
Edition::E2021 => rustc_span::edition::Edition::Edition2021,
159162
};
160163

161-
match rustc_driver::catch_fatal_errors(|| {
162-
rustc_span::create_session_globals_then(rustc_edition, || {
163-
run_lexer(input, error_list.clone())
164-
})
165-
}) {
166-
Ok(rustc_tokens) => {
167-
let messages = extract_errors(error_list);
168-
if messages.is_empty() {
169-
// Lexing succeeded
170-
Analysis::Accepts(rustc_tokens)
171-
} else {
172-
// Lexing reported a non-fatal error
173-
Analysis::Rejects(rustc_tokens, messages)
164+
std::panic::catch_unwind(|| {
165+
match rustc_driver::catch_fatal_errors(|| {
166+
rustc_span::create_session_globals_then(rustc_edition, || {
167+
run_lexer(input, error_list.clone())
168+
})
169+
}) {
170+
Ok(rustc_tokens) => {
171+
let messages = extract_errors(error_list);
172+
if messages.is_empty() {
173+
// Lexing succeeded
174+
Analysis::Accepts(rustc_tokens)
175+
} else {
176+
// Lexing reported a non-fatal error
177+
Analysis::Rejects(rustc_tokens, messages)
178+
}
179+
}
180+
Err(_) => {
181+
let mut messages = extract_errors(error_list);
182+
messages.push("reported fatal error (panicked)".into());
183+
Analysis::Rejects(Vec::new(), messages)
174184
}
175185
}
176-
Err(_) => {
177-
let mut messages = extract_errors(error_list);
178-
messages.push("reported fatal error (panicked)".into());
179-
Analysis::Rejects(Vec::new(), messages)
180-
}
181-
}
186+
}).unwrap_or(Analysis::CompilerError)
182187
}
183188

184189
/// Result of running lexical analysis on a string.
@@ -192,6 +197,8 @@ pub enum Analysis {
192197
///
193198
/// The strings are error messages. There's always at least one message.
194199
Rejects(Vec<RustcToken>, Vec<String>),
200+
/// The input provoked an internal compiler error.
201+
CompilerError,
195202
}
196203

197204
/// Runs rustc's lexical analysis on the specified input.

src/simple_reports.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ fn show_detail(input: &str, edition: Edition) {
182182
}
183183
}
184184
}
185+
lex_via_rustc::Analysis::CompilerError => {
186+
println!("rustc: internal compiler error");
187+
}
185188
}
186189
let cleaned = cleaning::clean(input);
187190
match lexlucid::analyse(&cleaned, edition) {

0 commit comments

Comments
 (0)