Skip to main content

Parser

Struct Parser 

Source
pub struct Parser<'a> { /* private fields */ }

Implementations§

Source§

impl<'a> Parser<'a>

Source

pub fn new(toks: Vec<Token<'a>>) -> Self

Source

pub fn parse_expression(self) -> Result<Expr<'a>, Diagnostic>

Entry point for a single expression (#{...} interpolations, REPL).

Source

pub fn parse_module(self) -> Result<Module<'a>, Vec<Diagnostic>>

Debug builds parse on a thread with a 64 MiB stack. MAX_PARSE_DEPTH already caps the recursion at 256 frames, which a release build clears in tens of kilobytes — but a debug frame is roughly ten times larger, and 256 of them can approach the ~1 MiB default stack on Windows before the guard trips.

Release builds — and wasm, which has no threads at all — recurse on the stack they are given. This is not a weakening: the guard is what makes the parser DoS-safe, and it is unconditional. The thread only ever bought head room for fat debug frames.

It bought that head room expensively. Spawning the thread costs about 115 µs, against 7.8 µs for parsing the reference manifest — sixteen times the work it protects, paid on every check, every eval, and every reparse the language server does while someone types.

Auto Trait Implementations§

§

impl<'a> Freeze for Parser<'a>

§

impl<'a> RefUnwindSafe for Parser<'a>

§

impl<'a> Send for Parser<'a>

§

impl<'a> Sync for Parser<'a>

§

impl<'a> Unpin for Parser<'a>

§

impl<'a> UnsafeUnpin for Parser<'a>

§

impl<'a> UnwindSafe for Parser<'a>

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> 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> Same for T

Source§

type Output = T

Should always be Self
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.