pub struct Session<C> { /* private fields */ }Expand description
The ambient state threaded through one compilation run.
Every Stage in a pipeline receives &mut Session<C>. The
session is where the shared, cross-stage state lives: the compilation
configuration (C — target, options, input paths, whatever a language
needs), and the diagnostics every stage emits as it works. It is the one
piece of state a driver carries from the first phase to the last, so a later
stage can read what an earlier one recorded.
The session is generic over the configuration type C and never inspects it —
it hands out &C / &mut C and otherwise leaves it alone. This keeps the
crate free of any opinion about what a language’s configuration looks like.
Diagnostics are stored in emission order, and the count of
error-severity diagnostics is maintained
incrementally, so error_count and
has_errors are O(1) — a driver can check them between
every phase without re-scanning the list.
§Examples
use driver_lang::{Diagnostic, Session};
// The configuration is whatever a language needs; here, a target triple.
let mut session = Session::new("x86_64-unknown-linux-gnu");
session.warn("unused import `std::mem`");
session.error("cannot find type `Foo`");
assert_eq!(session.config(), &"x86_64-unknown-linux-gnu");
assert_eq!(session.error_count(), 1); // the warning does not count
assert_eq!(session.diagnostics().len(), 2);
assert!(session.has_errors());Implementations§
Source§impl<C> Session<C>
impl<C> Session<C>
Sourcepub fn new(config: C) -> Self
pub fn new(config: C) -> Self
Create a session over a configuration, with no diagnostics recorded yet.
§Examples
use driver_lang::Session;
let session = Session::new(());
assert!(!session.has_errors());
assert!(session.diagnostics().is_empty());Sourcepub fn config(&self) -> &C
pub fn config(&self) -> &C
Borrow the compilation configuration.
§Examples
use driver_lang::Session;
let session = Session::new(42u32);
assert_eq!(*session.config(), 42);Sourcepub fn config_mut(&mut self) -> &mut C
pub fn config_mut(&mut self) -> &mut C
Mutably borrow the compilation configuration, so a stage can update options that later stages read.
Sourcepub fn into_config(self) -> C
pub fn into_config(self) -> C
Consume the session and return the configuration, discarding the recorded
diagnostics. Use take_diagnostics first if you
need to keep them.
§Examples
use driver_lang::Session;
let session = Session::new(String::from("opts"));
let config = session.into_config();
assert_eq!(config, "opts");Sourcepub fn emit(&mut self, diagnostic: Diagnostic) -> &mut Self
pub fn emit(&mut self, diagnostic: Diagnostic) -> &mut Self
Record a Diagnostic, updating the error count if it is an error.
Returns &mut Self so emissions can be chained. This is the one path by
which diagnostics enter the session; the error,
warn, and note shorthands all route through
it.
§Examples
use driver_lang::{Diagnostic, Session};
let mut session = Session::new(());
session
.emit(Diagnostic::error("first"))
.emit(Diagnostic::warning("second"));
assert_eq!(session.diagnostics().len(), 2);
assert_eq!(session.error_count(), 1);Sourcepub fn warn(&mut self, message: impl Into<Cow<'static, str>>) -> &mut Self
pub fn warn(&mut self, message: impl Into<Cow<'static, str>>) -> &mut Self
Emit a warning-severity diagnostic.
Shorthand for self.emit(Diagnostic::warning(message)).
Sourcepub fn note(&mut self, message: impl Into<Cow<'static, str>>) -> &mut Self
pub fn note(&mut self, message: impl Into<Cow<'static, str>>) -> &mut Self
Emit a note-severity diagnostic.
Shorthand for self.emit(Diagnostic::note(message)).
Sourcepub fn diagnostics(&self) -> &[Diagnostic]
pub fn diagnostics(&self) -> &[Diagnostic]
All diagnostics recorded so far, in emission order.
§Examples
use driver_lang::Session;
let mut session = Session::new(());
session.note("a").warn("b");
let messages: Vec<_> = session.diagnostics().iter().map(|d| d.message()).collect();
assert_eq!(messages, ["a", "b"]);Sourcepub fn error_count(&self) -> usize
pub fn error_count(&self) -> usize
How many error-severity diagnostics have been
emitted. Maintained incrementally, so this is O(1).
Sourcepub fn has_errors(&self) -> bool
pub fn has_errors(&self) -> bool
Whether any error has been emitted. O(1).
§Examples
use driver_lang::Session;
let mut session = Session::new(());
assert!(!session.has_errors());
session.warn("just a warning");
assert!(!session.has_errors());
session.error("a real error");
assert!(session.has_errors());Sourcepub fn abort_if_errors(&self) -> Result<(), DriverError>
pub fn abort_if_errors(&self) -> Result<(), DriverError>
Stop the run if any error has been emitted.
This is the driver’s checkpoint primitive: emit diagnostics through a phase,
then call abort_if_errors to turn accumulated errors into the
DriverError that ends the pipeline — the “aborting due to N previous
errors” step at the end of a compiler phase. Because a stage can emit
several errors before this is checked, one checkpoint can report many
diagnostics at once instead of stopping at the first.
Returns Ok(()) when the session is clean, so session.abort_if_errors()?
inside Stage::run is a no-op on a healthy run and a
clean stop otherwise. The returned error has no stage name yet; the
Pipeline stamps in the stage that made the call.
§Errors
Returns a DriverError reporting the error count when
has_errors is true.
§Examples
use driver_lang::Session;
let mut session = Session::new(());
assert!(session.abort_if_errors().is_ok());
session.error("first");
session.error("second");
let err = session.abort_if_errors().unwrap_err();
assert_eq!(err.message(), "aborting due to 2 previous errors");Sourcepub fn take_diagnostics(&mut self) -> Vec<Diagnostic>
pub fn take_diagnostics(&mut self) -> Vec<Diagnostic>
Remove and return all recorded diagnostics, resetting the error count to zero. The configuration is left untouched.
Use this to drain diagnostics for rendering between runs, or to hand them
off before into_config discards the session.
§Examples
use driver_lang::Session;
let mut session = Session::new(());
session.error("boom");
let drained = session.take_diagnostics();
assert_eq!(drained.len(), 1);
assert!(!session.has_errors()); // count reset
assert!(session.diagnostics().is_empty());