Skip to content

Commit 0d0f753

Browse files
authored
Rollup merge of rust-lang#64698 - Centril:infer-const-with-stash, r=estebank
Recover on `const X = 42;` and infer type + Error Stash API Here we: 1. Introduce a notion of the "error stash". This is a map in the `Handler` to which you can `err.stash(...)` away your diagnostics and then steal them in a later "phase" of the compiler (e.g. stash in parser, steal in typeck) to enrich them with more information that isn't available in the previous "phase". I believe I've covered all the bases to make sure these diagnostics are actually emitted eventually even under `#[cfg(FALSE)]` but please check my logic. 2. Recover when parsing `[const | static mut?] $ident = $expr;` which has a missing type. Use the "error stash" to stash away the error and later steal the error in typeck where we emit the error as `MachineApplicable` with the actual inferred type. This builds on rust-lang#62804. cc rust-lang/rfcs#2545 r? @estebank
2 parents 6a4be43 + f70665a commit 0d0f753

File tree

12 files changed

+447
-188
lines changed

12 files changed

+447
-188
lines changed

src/librustc/session/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ impl Session {
321321
}
322322
pub fn compile_status(&self) -> Result<(), ErrorReported> {
323323
if self.has_errors() {
324+
self.diagnostic().emit_stashed_diagnostics();
324325
Err(ErrorReported)
325326
} else {
326327
Ok(())

src/librustc_driver/lib.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ pub fn run_compiler(
296296
);
297297
Ok(())
298298
})?;
299-
return sess.compile_status();
300299
} else {
301300
let mut krate = compiler.parse()?.take();
302301
pretty::visit_crate(sess, &mut krate, ppm);
@@ -307,8 +306,8 @@ pub fn run_compiler(
307306
ppm,
308307
compiler.output_file().as_ref().map(|p| &**p),
309308
);
310-
return sess.compile_status();
311309
}
310+
return sess.compile_status();
312311
}
313312

314313
if callbacks.after_parsing(compiler) == Compilation::Stop {

src/librustc_errors/diagnostic_builder.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
1-
use crate::Diagnostic;
2-
use crate::DiagnosticId;
3-
use crate::DiagnosticStyledString;
4-
use crate::Applicability;
1+
use crate::{Diagnostic, DiagnosticId, DiagnosticStyledString};
2+
use crate::{Applicability, Level, Handler, StashKey};
53

6-
use crate::Level;
7-
use crate::Handler;
84
use std::fmt::{self, Debug};
95
use std::ops::{Deref, DerefMut};
106
use std::thread::panicking;
@@ -117,18 +113,30 @@ impl<'a> DiagnosticBuilder<'a> {
117113
}
118114
}
119115

120-
/// Buffers the diagnostic for later emission, unless handler
121-
/// has disabled such buffering.
122-
pub fn buffer(mut self, buffered_diagnostics: &mut Vec<Diagnostic>) {
116+
/// Stashes diagnostic for possible later improvement in a different,
117+
/// later stage of the compiler. The diagnostic can be accessed with
118+
/// the provided `span` and `key` through `.steal_diagnostic` on `Handler`.
119+
///
120+
/// As with `buffer`, this is unless the handler has disabled such buffering.
121+
pub fn stash(self, span: Span, key: StashKey) {
122+
if let Some((diag, handler)) = self.into_diagnostic() {
123+
handler.stash_diagnostic(span, key, diag);
124+
}
125+
}
126+
127+
/// Converts the builder to a `Diagnostic` for later emission,
128+
/// unless handler has disabled such buffering.
129+
pub fn into_diagnostic(mut self) -> Option<(Diagnostic, &'a Handler)> {
123130
if self.0.handler.flags.dont_buffer_diagnostics ||
124131
self.0.handler.flags.treat_err_as_bug.is_some()
125132
{
126133
self.emit();
127-
return;
134+
return None;
128135
}
129136

130-
// We need to use `ptr::read` because `DiagnosticBuilder`
131-
// implements `Drop`.
137+
let handler = self.0.handler;
138+
139+
// We need to use `ptr::read` because `DiagnosticBuilder` implements `Drop`.
132140
let diagnostic;
133141
unsafe {
134142
diagnostic = std::ptr::read(&self.0.diagnostic);
@@ -137,7 +145,14 @@ impl<'a> DiagnosticBuilder<'a> {
137145
// Logging here is useful to help track down where in logs an error was
138146
// actually emitted.
139147
debug!("buffer: diagnostic={:?}", diagnostic);
140-
buffered_diagnostics.push(diagnostic);
148+
149+
Some((diagnostic, handler))
150+
}
151+
152+
/// Buffers the diagnostic for later emission,
153+
/// unless handler has disabled such buffering.
154+
pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) {
155+
buffered_diagnostics.extend(self.into_diagnostic().map(|(diag, _)| diag));
141156
}
142157

143158
/// Convenience function for internal use, clients should use one of the

0 commit comments

Comments
 (0)