Skip to main content

TypeChecker

Struct TypeChecker 

Source
pub struct TypeChecker {
Show 14 fields pub scopes: Vec<HashMap<String, ScopeItem>>, pub source_file: Option<SourceFile>, pub root_module: Module, pub errors: Vec<Error>, pub return_type_stack: Vec<TypeAnnotation>, pub loop_depth: u32, pub stdlib_fn_names: HashSet<String>, pub hovers: Vec<(Span, String)>, pub base_dir: Option<PathBuf>, pub importing: Vec<PathBuf>, pub imported: HashSet<PathBuf>, pub ast_arena: Ast, pub records: HashMap<String, Vec<(String, TypeAnnotation)>>, pub tags: HashMap<String, Vec<String>>,
}
Expand description

The stateful type checker, threaded through the entire AST walk.

Fields§

§scopes: Vec<HashMap<String, ScopeItem>>

Stack of scopes, each mapping variable/function names to their ScopeItem.

§source_file: Option<SourceFile>

Source file attached for Ariadne error rendering; None in LSP-less contexts.

§root_module: Module

The stdlib module tree, used to resolve stdlib call paths.

§errors: Vec<Error>

All type errors accumulated during the check pass.

§return_type_stack: Vec<TypeAnnotation>

Stack of expected return types, pushed/popped on function and lambda entry/exit.

§loop_depth: u32

Nesting depth of loops - used to validate break and continue.

§stdlib_fn_names: HashSet<String>

Flat set of all stdlib function names for fast single-name lookup.

§hovers: Vec<(Span, String)>

(span, markdown) pairs collected at every declaration and usage site, consumed by the LSP hover provider.

§base_dir: Option<PathBuf>§importing: Vec<PathBuf>§imported: HashSet<PathBuf>§ast_arena: Ast§records: HashMap<String, Vec<(String, TypeAnnotation)>>

Maps record type names to their declared (field name, field type) list.

§tags: HashMap<String, Vec<String>>

Maps tag (enum) type names to their declared variant name list.

Implementations§

Source§

impl TypeChecker

Source

pub fn check_binary_operator( &mut self, left: CheckType, right: CheckType, op: &TokenType, span: Span, ) -> CheckType

Source§

impl TypeChecker

Source

pub fn check_index_assign( &mut self, target: ExprId, index: ExprId, value: ExprId, span: Span, ) -> CheckType

Source§

impl TypeChecker

Source

pub fn check_unary_operator( &mut self, operand: CheckType, _operand_span: Span, op: &TokenType, span: Span, ) -> CheckType

Source§

impl TypeChecker

Source

pub fn assign(&mut self, name: &str, value_type: CheckType, span: Span)

Checks that assigning value_type to name is valid.

Walks scopes from innermost to outermost. Emits an error if:

  • The variable is declared const
  • The value type doesn’t match the declared type
  • The name is not declared in any scope (with a “did you mean?” suggestion)
Source§

impl TypeChecker

Source

pub fn check_call_path( &mut self, path: &[String], arg_types: &[(CheckType, Span)], span: Span, ) -> CheckType

Resolves a call path and checks argument types.

Resolution order:

  1. Full stdlib path (std::io::print) via [root_module]
  2. Single-name stdlib shorthand (print) via [stdlib_fn_names]
  3. User-defined name via [lookup]
  4. Error - unknown function, with a “did you mean?” suggestion from stdlib keywords

Stdlib calls always return CheckType::Unknown since their return types are not tracked statically.

Source

pub fn check_call_value( &mut self, callee_type: CheckType, arg_types: &[(CheckType, Span)], span: Span, ) -> CheckType

Checks that a resolved callee value is callable and receives the correct arguments.

  • Unknown and Known(Fn) pass through without argument checking
  • Function { params, return_type } validates arity and argument types, then returns Known(return_type)
  • Anything else emits a “not callable” error
Source§

impl TypeChecker

Source

pub fn declare( &mut self, name: String, item_type: CheckType, is_const: bool, span: Span, )

Declares name in the current (innermost) scope.

For constants, emits an error if the name is already declared in the same scope. On success, pushes a hover entry showing the kind, name, and type.

Source§

impl TypeChecker

Source

pub fn push_scope(&mut self)

Pushes a new empty scope onto the scope stack.

Source

pub fn pop_scope(&mut self)

Pops the innermost scope from the stack.

Source

pub fn lookup(&mut self, name: &str, span: Span) -> CheckType

Looks up name in all scopes from innermost to outermost.

On success, pushes a hover entry with the variable’s type and kind, then returns the CheckType. On failure, emits an undefined variable error with a “did you mean?” suggestion and returns CheckType::Unknown.

Source§

impl TypeChecker

Source

pub fn check_expression(&mut self, expression: ExprId) -> CheckType

Source§

impl TypeChecker

Source

pub fn check_statement(&mut self, statement: &Statement)

Source

fn import_module(&mut self, path: &[String], span: Span)

Source§

impl TypeChecker

Source

pub fn current_return_type(&self) -> Option<&TypeAnnotation>

Returns the expected return type of the current function or lambda, if any.

Source

pub fn push_return_type(&mut self, ty: TypeAnnotation)

Pushes ty as the expected return type when entering a function or lambda body.

Source

pub fn pop_return_type(&mut self)

Pops the expected return type when exiting a function or lambda body.

Source

pub fn loop_depth(&self) -> u32

Source

pub fn enter_loop(&mut self)

Source

pub fn exit_loop(&mut self)

Source

pub fn check_block(&mut self, statements: &[Statement])

Checks all statements in statements inside a fresh scope.

Source

pub fn check_is_null(&mut self, item_type: &CheckType, span: Span) -> bool

Emits a "value is null" error if item_type is [CheckType::Known(Null)].

Returns false if null, true otherwise.

Source

pub(crate) fn to_type_annotation(item_type: &CheckType) -> TypeAnnotation

Converts a CheckType to a TypeAnnotation, mapping Unknown to Null.

Source

pub(crate) fn is_hashable_key_type(ty: &TypeAnnotation) -> bool

Source§

impl TypeChecker

Source

pub fn new() -> Self

Source

pub fn with_source_file(self, file: SourceFile) -> Self

Source

pub fn set_source_file(&mut self, file: SourceFile)

Source

pub fn with_base_dir(self, dir: impl Into<PathBuf>) -> Self

Source

pub fn with_ast_arena(self, arena: Ast) -> Self

Source

pub fn check(&mut self, statements: &[Statement]) -> &[Error]

Source

pub fn err(&self, message: impl Into<String>, span: Span) -> Error

Source

pub fn error(&mut self, message: impl Into<String>, span: Span)

Source

pub fn error_with_help( &mut self, message: impl Into<String>, span: Span, help: Option<&str>, )

Source

pub fn push_hover(&mut self, span: Span, text: impl Into<String>)

Source

fn push_stdlib_hover(&mut self, path: &[String], span: Span)

Trait Implementations§

Source§

impl Default for TypeChecker

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

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

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

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

§

fn fg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the foreground set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like red() and green(), which have the same functionality but are pithier.

§Example

Set foreground color to white using fg():

use yansi::{Paint, Color};

painted.fg(Color::White);

Set foreground color to white using white().

use yansi::Paint;

painted.white();
§

fn primary(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Primary].

§Example
println!("{}", value.primary());
§

fn fixed(&self, color: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Fixed].

§Example
println!("{}", value.fixed(color));
§

fn rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the fg() set to [Color :: Rgb].

§Example
println!("{}", value.rgb(r, g, b));
§

fn black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Black].

§Example
println!("{}", value.black());
§

fn red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Red].

§Example
println!("{}", value.red());
§

fn green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Green].

§Example
println!("{}", value.green());
§

fn yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Yellow].

§Example
println!("{}", value.yellow());
§

fn blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Blue].

§Example
println!("{}", value.blue());
§

fn magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Magenta].

§Example
println!("{}", value.magenta());
§

fn cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: Cyan].

§Example
println!("{}", value.cyan());
§

fn white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: White].

§Example
println!("{}", value.white());
§

fn bright_black(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlack].

§Example
println!("{}", value.bright_black());
§

fn bright_red(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightRed].

§Example
println!("{}", value.bright_red());
§

fn bright_green(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightGreen].

§Example
println!("{}", value.bright_green());
§

fn bright_yellow(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightYellow].

§Example
println!("{}", value.bright_yellow());
§

fn bright_blue(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightBlue].

§Example
println!("{}", value.bright_blue());
§

fn bright_magenta(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.bright_magenta());
§

fn bright_cyan(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightCyan].

§Example
println!("{}", value.bright_cyan());
§

fn bright_white(&self) -> Painted<&T>

Returns self with the fg() set to [Color :: BrightWhite].

§Example
println!("{}", value.bright_white());
§

fn bg(&self, value: Color) -> Painted<&T>

Returns a styled value derived from self with the background set to value.

This method should be used rarely. Instead, prefer to use color-specific builder methods like on_red() and on_green(), which have the same functionality but are pithier.

§Example

Set background color to red using fg():

use yansi::{Paint, Color};

painted.bg(Color::Red);

Set background color to red using on_red().

use yansi::Paint;

painted.on_red();
§

fn on_primary(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Primary].

§Example
println!("{}", value.on_primary());
§

fn on_fixed(&self, color: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Fixed].

§Example
println!("{}", value.on_fixed(color));
§

fn on_rgb(&self, r: u8, g: u8, b: u8) -> Painted<&T>

Returns self with the bg() set to [Color :: Rgb].

§Example
println!("{}", value.on_rgb(r, g, b));
§

fn on_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Black].

§Example
println!("{}", value.on_black());
§

fn on_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Red].

§Example
println!("{}", value.on_red());
§

fn on_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Green].

§Example
println!("{}", value.on_green());
§

fn on_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Yellow].

§Example
println!("{}", value.on_yellow());
§

fn on_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Blue].

§Example
println!("{}", value.on_blue());
§

fn on_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Magenta].

§Example
println!("{}", value.on_magenta());
§

fn on_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: Cyan].

§Example
println!("{}", value.on_cyan());
§

fn on_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: White].

§Example
println!("{}", value.on_white());
§

fn on_bright_black(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlack].

§Example
println!("{}", value.on_bright_black());
§

fn on_bright_red(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightRed].

§Example
println!("{}", value.on_bright_red());
§

fn on_bright_green(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightGreen].

§Example
println!("{}", value.on_bright_green());
§

fn on_bright_yellow(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightYellow].

§Example
println!("{}", value.on_bright_yellow());
§

fn on_bright_blue(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightBlue].

§Example
println!("{}", value.on_bright_blue());
§

fn on_bright_magenta(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightMagenta].

§Example
println!("{}", value.on_bright_magenta());
§

fn on_bright_cyan(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightCyan].

§Example
println!("{}", value.on_bright_cyan());
§

fn on_bright_white(&self) -> Painted<&T>

Returns self with the bg() set to [Color :: BrightWhite].

§Example
println!("{}", value.on_bright_white());
§

fn attr(&self, value: Attribute) -> Painted<&T>

Enables the styling [Attribute] value.

This method should be used rarely. Instead, prefer to use attribute-specific builder methods like bold() and underline(), which have the same functionality but are pithier.

§Example

Make text bold using attr():

use yansi::{Paint, Attribute};

painted.attr(Attribute::Bold);

Make text bold using using bold().

use yansi::Paint;

painted.bold();
§

fn bold(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Bold].

§Example
println!("{}", value.bold());
§

fn dim(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Dim].

§Example
println!("{}", value.dim());
§

fn italic(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Italic].

§Example
println!("{}", value.italic());
§

fn underline(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Underline].

§Example
println!("{}", value.underline());

Returns self with the attr() set to [Attribute :: Blink].

§Example
println!("{}", value.blink());

Returns self with the attr() set to [Attribute :: RapidBlink].

§Example
println!("{}", value.rapid_blink());
§

fn invert(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Invert].

§Example
println!("{}", value.invert());
§

fn conceal(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Conceal].

§Example
println!("{}", value.conceal());
§

fn strike(&self) -> Painted<&T>

Returns self with the attr() set to [Attribute :: Strike].

§Example
println!("{}", value.strike());
§

fn quirk(&self, value: Quirk) -> Painted<&T>

Enables the yansi [Quirk] value.

This method should be used rarely. Instead, prefer to use quirk-specific builder methods like mask() and wrap(), which have the same functionality but are pithier.

§Example

Enable wrapping using .quirk():

use yansi::{Paint, Quirk};

painted.quirk(Quirk::Wrap);

Enable wrapping using wrap().

use yansi::Paint;

painted.wrap();
§

fn mask(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Mask].

§Example
println!("{}", value.mask());
§

fn wrap(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Wrap].

§Example
println!("{}", value.wrap());
§

fn linger(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Linger].

§Example
println!("{}", value.linger());
§

fn clear(&self) -> Painted<&T>

👎Deprecated since 1.0.1:

renamed to resetting() due to conflicts with Vec::clear(). The clear() method will be removed in a future release.

Returns self with the quirk() set to [Quirk :: Clear].

§Example
println!("{}", value.clear());
§

fn resetting(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Resetting].

§Example
println!("{}", value.resetting());
§

fn bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: Bright].

§Example
println!("{}", value.bright());
§

fn on_bright(&self) -> Painted<&T>

Returns self with the quirk() set to [Quirk :: OnBright].

§Example
println!("{}", value.on_bright());
§

fn whenever(&self, value: Condition) -> Painted<&T>

Conditionally enable styling based on whether the [Condition] value applies. Replaces any previous condition.

See the crate level docs for more details.

§Example

Enable styling painted only when both stdout and stderr are TTYs:

use yansi::{Paint, Condition};

painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);
§

fn new(self) -> Painted<Self>
where Self: Sized,

Create a new [Painted] with a default [Style]. Read more
§

fn paint<S>(&self, style: S) -> Painted<&Self>
where S: Into<Style>,

Apply a style wholesale to self. Any previous style is replaced. 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.