pub struct TypeChecker<'a> {
pub(crate) symbol_table: &'a mut SymbolTable,
pub(crate) type_table: &'a TypeTable,
pub(crate) struct_graph: StructGraph,
pub(crate) call_graph: CallGraph,
pub(crate) handler: &'a Handler,
pub(crate) scope_state: ScopeState,
pub(crate) async_function_input_types: IndexMap<Location, Vec<Type>>,
pub(crate) async_function_callers: IndexMap<Location, IndexSet<Location>>,
pub(crate) used_structs: IndexSet<Symbol>,
pub(crate) limits: NetworkLimits,
conditional_scopes: Vec<IndexSet<Symbol>>,
}
Fields§
§symbol_table: &'a mut SymbolTable
The symbol table for the program.
type_table: &'a TypeTable
A mapping from node IDs to their types.
struct_graph: StructGraph
A dependency graph of the structs in program.
call_graph: CallGraph
The call graph for the program.
handler: &'a Handler
The error handler.
scope_state: ScopeState
The state of the current scope being traversed.
async_function_input_types: IndexMap<Location, Vec<Type>>
Mapping from async function stub name to the inferred input types.
async_function_callers: IndexMap<Location, IndexSet<Location>>
Mapping from async function name to the names of async transition callers.
used_structs: IndexSet<Symbol>
The set of used composites.
limits: NetworkLimits
So we can check if we exceed limits on array size, number of mappings, or number of functions.
conditional_scopes: Vec<IndexSet<Symbol>>
For detecting the error TypeCheckerError::async_cannot_assign_outside_conditional
.
Implementations§
Source§impl<'a> TypeChecker<'a>
impl<'a> TypeChecker<'a>
Sourcepub fn new(
symbol_table: &'a mut SymbolTable,
type_table: &'a TypeTable,
handler: &'a Handler,
limits: NetworkLimits,
) -> Self
pub fn new( symbol_table: &'a mut SymbolTable, type_table: &'a TypeTable, handler: &'a Handler, limits: NetworkLimits, ) -> Self
Returns a new type checker given a symbol table and error handler.
pub(crate) fn in_scope<T>( &mut self, id: NodeID, func: impl FnOnce(&mut Self) -> T, ) -> T
pub(crate) fn in_conditional_scope<T>( &mut self, func: impl FnOnce(&mut Self) -> T, ) -> T
pub(crate) fn insert_symbol_conditional_scope(&mut self, symbol: Symbol)
pub(crate) fn symbol_in_conditional_scope(&mut self, symbol: Symbol) -> bool
Sourcepub(crate) fn emit_err(&self, err: TypeCheckerError)
pub(crate) fn emit_err(&self, err: TypeCheckerError)
Emits a type checker error.
Sourcepub fn emit_warning(&self, warning: TypeCheckerWarning)
pub fn emit_warning(&self, warning: TypeCheckerWarning)
Emits a type checker warning
Sourcepub(crate) fn check_eq_types(
&self,
t1: &Option<Type>,
t2: &Option<Type>,
span: Span,
)
pub(crate) fn check_eq_types( &self, t1: &Option<Type>, t2: &Option<Type>, span: Span, )
Emits an error if the two given types are not equal.
Sourcepub(crate) fn assert_and_return_type(
&mut self,
actual: Type,
expected: &Option<Type>,
span: Span,
) -> Type
pub(crate) fn assert_and_return_type( &mut self, actual: Type, expected: &Option<Type>, span: Span, ) -> Type
Use this method when you know the actual type.
Emits an error to the handler if the actual
type is not equal to the expected
type.
pub(crate) fn maybe_assert_type( &mut self, actual: &Type, expected: &Option<Type>, span: Span, )
pub(crate) fn assert_type(&mut self, actual: &Type, expected: &Type, span: Span)
pub(crate) fn assert_int_type(&self, type_: &Type, span: Span)
pub(crate) fn assert_unsigned_type(&self, type_: &Type, span: Span)
pub(crate) fn assert_bool_int_type(&self, type_: &Type, span: Span)
pub(crate) fn assert_field_int_type(&self, type_: &Type, span: Span)
pub(crate) fn assert_field_group_int_type(&self, type_: &Type, span: Span)
Sourcepub(crate) fn get_core_constant(
&self,
type_: &Type,
constant: &Identifier,
) -> Option<CoreConstant>
pub(crate) fn get_core_constant( &self, type_: &Type, constant: &Identifier, ) -> Option<CoreConstant>
Type checks the inputs to an associated constant and returns the expected output type.
Sourcepub(crate) fn get_core_function_call(
&self,
struct_: &Identifier,
function: &Identifier,
) -> Option<CoreFunction>
pub(crate) fn get_core_function_call( &self, struct_: &Identifier, function: &Identifier, ) -> Option<CoreFunction>
Emits an error if the struct
is not a core library struct.
Emits an error if the function
is not supported by the struct.
Sourcepub(crate) fn check_core_function_call(
&mut self,
core_function: CoreFunction,
arguments: &[(Type, Span)],
function_span: Span,
) -> Type
pub(crate) fn check_core_function_call( &mut self, core_function: CoreFunction, arguments: &[(Type, Span)], function_span: Span, ) -> Type
Type checks the inputs to a core function call and returns the expected output type. Emits an error if the correct number of arguments are not provided. Emits an error if the arguments are not of the correct type.
Sourcepub(crate) fn assert_member_is_not_record(
&mut self,
span: Span,
parent: Symbol,
type_: &Type,
)
pub(crate) fn assert_member_is_not_record( &mut self, span: Span, parent: Symbol, type_: &Type, )
Emits an error if the struct member is a record type.
Sourcepub(crate) fn assert_type_is_valid(&mut self, type_: &Type, span: Span)
pub(crate) fn assert_type_is_valid(&mut self, type_: &Type, span: Span)
Emits an error if the type or its constituent types is not valid.
Sourcepub(crate) fn assert_mapping_type(&self, type_: &Type, span: Span)
pub(crate) fn assert_mapping_type(&self, type_: &Type, span: Span)
Emits an error if the type is not a mapping.
pub(crate) fn assert_array_type(&self, type_: &Type, span: Span)
Sourcepub(crate) fn check_function_signature(
&mut self,
function: &Function,
is_stub: bool,
)
pub(crate) fn check_function_signature( &mut self, function: &Function, is_stub: bool, )
Helper function to check that the input and output of function are valid
Sourcefn merge_types(&self, lhs: &mut Type, rhs: &Type)
fn merge_types(&self, lhs: &mut Type, rhs: &Type)
Merge inferred types into lhs
.
That is, if lhs
and rhs
aren’t equal, set lhs
to Type::Err;
or, if they’re both futures, set any member of lhs
that isn’t
equal to the equivalent member of rhs
to Type::Err
.
Sourcepub(crate) fn eq_user(&self, t1: &Type, t2: &Type) -> bool
pub(crate) fn eq_user(&self, t1: &Type, t2: &Type) -> bool
Are the types considered equal as far as the Leo user is concerned?
In particular, any comparison involving an Err
is true
,
composite types are resolved to the current program if not specified,
and Futures which aren’t explicit compare equal to other Futures.
Sourcepub(crate) fn lookup_struct(
&mut self,
program: Option<Symbol>,
name: Symbol,
) -> Option<Composite>
pub(crate) fn lookup_struct( &mut self, program: Option<Symbol>, name: Symbol, ) -> Option<Composite>
Wrapper around lookup_struct that additionally records all structs that are used in the program.
Sourcepub(crate) fn insert_variable(
&mut self,
inferred_type: Option<Type>,
name: &Identifier,
type_: Type,
span: Span,
)
pub(crate) fn insert_variable( &mut self, inferred_type: Option<Type>, name: &Identifier, type_: Type, span: Span, )
Inserts variable to symbol table.
pub(crate) fn check_access_allowed( &mut self, name: &str, finalize_op: bool, span: Span, )
Trait Implementations§
Source§impl ExpressionVisitor for TypeChecker<'_>
impl ExpressionVisitor for TypeChecker<'_>
type AdditionalInput = Option<Type>
type Output = Type
fn visit_expression( &mut self, input: &Expression, additional: &Self::AdditionalInput, ) -> Self::Output
fn visit_access( &mut self, input: &AccessExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_array( &mut self, input: &ArrayExpression, additional: &Self::AdditionalInput, ) -> Self::Output
fn visit_binary( &mut self, input: &BinaryExpression, destination: &Self::AdditionalInput, ) -> Self::Output
fn visit_call( &mut self, input: &CallExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_cast( &mut self, input: &CastExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_struct_init( &mut self, input: &StructExpression, additional: &Self::AdditionalInput, ) -> Self::Output
fn visit_err( &mut self, _input: &ErrExpression, _additional: &Self::AdditionalInput, ) -> Self::Output
fn visit_identifier( &mut self, input: &Identifier, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_literal( &mut self, input: &Literal, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_locator( &mut self, input: &LocatorExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_ternary( &mut self, input: &TernaryExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_tuple( &mut self, input: &TupleExpression, expected: &Self::AdditionalInput, ) -> Self::Output
fn visit_unary( &mut self, input: &UnaryExpression, destination: &Self::AdditionalInput, ) -> Self::Output
fn visit_unit( &mut self, _input: &UnitExpression, _additional: &Self::AdditionalInput, ) -> Self::Output
Source§impl<'a> Pass for TypeChecker<'a>
impl<'a> Pass for TypeChecker<'a>
Source§impl ProgramVisitor for TypeChecker<'_>
impl ProgramVisitor for TypeChecker<'_>
fn visit_program(&mut self, input: &Program)
fn visit_program_scope(&mut self, input: &ProgramScope)
fn visit_stub(&mut self, input: &Stub)
fn visit_struct(&mut self, input: &Composite)
fn visit_mapping(&mut self, input: &Mapping)
fn visit_function(&mut self, function: &Function)
fn visit_function_stub(&mut self, input: &FunctionStub)
fn visit_struct_stub(&mut self, input: &Composite)
fn visit_import(&mut self, input: &Program)
Source§impl StatementVisitor for TypeChecker<'_>
impl StatementVisitor for TypeChecker<'_>
fn visit_statement(&mut self, input: &Statement)
fn visit_assert(&mut self, input: &AssertStatement)
fn visit_assign(&mut self, input: &AssignStatement)
fn visit_block(&mut self, input: &Block)
fn visit_conditional(&mut self, input: &ConditionalStatement)
fn visit_console(&mut self, _: &ConsoleStatement)
fn visit_const(&mut self, input: &ConstDeclaration)
fn visit_definition(&mut self, input: &DefinitionStatement)
fn visit_expression_statement(&mut self, input: &ExpressionStatement)
fn visit_iteration(&mut self, input: &IterationStatement)
fn visit_return(&mut self, input: &ReturnStatement)
Auto Trait Implementations§
impl<'a> Freeze for TypeChecker<'a>
impl<'a> !RefUnwindSafe for TypeChecker<'a>
impl<'a> !Send for TypeChecker<'a>
impl<'a> !Sync for TypeChecker<'a>
impl<'a> Unpin for TypeChecker<'a>
impl<'a> !UnwindSafe for TypeChecker<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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