Skip to main content

Session

Struct Session 

Source
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>

Source

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());
Source

pub fn config(&self) -> &C

Borrow the compilation configuration.

§Examples
use driver_lang::Session;

let session = Session::new(42u32);
assert_eq!(*session.config(), 42);
Source

pub fn config_mut(&mut self) -> &mut C

Mutably borrow the compilation configuration, so a stage can update options that later stages read.

Source

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");
Source

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);
Source

pub fn error(&mut self, message: impl Into<Cow<'static, str>>) -> &mut Self

Emit an error-severity diagnostic.

Shorthand for self.emit(Diagnostic::error(message)).

§Examples
use driver_lang::Session;

let mut session = Session::new(());
session.error("cannot find value `x`");
assert!(session.has_errors());
Source

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)).

Source

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)).

Source

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"]);
Source

pub fn error_count(&self) -> usize

How many error-severity diagnostics have been emitted. Maintained incrementally, so this is O(1).

Source

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());
Source

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");
Source

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());

Trait Implementations§

Source§

impl<C: Clone> Clone for Session<C>

Source§

fn clone(&self) -> Session<C>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<C: Debug> Debug for Session<C>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<C> Freeze for Session<C>
where C: Freeze,

§

impl<C> RefUnwindSafe for Session<C>
where C: RefUnwindSafe,

§

impl<C> Send for Session<C>
where C: Send,

§

impl<C> Sync for Session<C>
where C: Sync,

§

impl<C> Unpin for Session<C>
where C: Unpin,

§

impl<C> UnsafeUnpin for Session<C>
where C: UnsafeUnpin,

§

impl<C> UnwindSafe for Session<C>
where C: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.