l0_expr_types::ExpressionTypeChecker class

Defined in module l0_expr_types (l0_expr_types.py).

Expression-level type checker for L0.

This checker implements:

  • Expression typing: literals, variables, operators, calls, constructors, casts, dereference, indexing, field access, try-operator, sizeof.
  • Structs and enums: construction, field access, variant patterns, ord.
  • Function calls: argument validation and signature matching.
  • Type compatibility: int, bool, string, pointers, nullability.
  • Statement checking: let (with inference), return, if, while, match, drop.
  • Control flow: return path analysis, unreachable code detection.
  • Memory safety: flow-sensitive liveness for dropped variables.

Public static attributes

static AnalysisResult analysis

Public functions

auto __post_init__(self) -> None
Initialize checker with analysis data and cache builtin types.
auto check(self) -> None
Run expression/type checking for all non-extern functions.

Public attributes

struct_infos
enum_infos
func_types
func_envs
diagnostics
expr_types
module_envs
void_type
int_type
byte_type
bool_type
string_type

Protected functions

auto _check_function(self, FunctionEnv func_env, FuncType func_type) -> None
Check a single function definition.
auto _make_param_scope(self, FunctionEnv func_env, FuncType func_type) -> Dict[str, Type]
Create a name-to-type mapping for function parameters.
auto _make_param_alive_scope(self, FunctionEnv func_env) -> Dict[str, bool]
Initialize liveness tracking for function parameters.
auto _push_scope(self) -> None
Enter a new lexical scope.
auto _pop_scope(self) -> None
Exit the current lexical scope.
auto _declare_local(self, str name, Type typ, Node node) -> None
Declare a local variable in the innermost scope.
auto _lookup_local(self, str name) -> Optional[Type]
Look up a local variable's type in the scope stack.
auto _lookup_local_scope_index(self, str name) -> Optional[int]
Return scope index where local resolves (nearest scope wins).
auto _is_guarded_cleanup_header_ref(self, str name, int scope_index) -> bool
True when a local resolves to a guarded maybe-uninitialized header let.
auto _expr_contains_try(self, Expr expr) -> bool
Check if an expression contains a '?' try operator.
auto _stmt_contains_try(self, Stmt stmt) -> bool
Check if a statement contains a '?' try operator.
auto _lookup_alive(self, str name) -> Optional[bool]
Check if a variable is currently alive (not dropped).
auto _set_alive(self, str name, bool alive) -> None
Set the liveness state of a variable.
auto _clone_alive_scopes(self) -> List[Dict[str, bool]]
Clone the current definite-liveness stack.
auto _meet_alive_scopes(self, *List] states[Dict[str, bool]) -> None
Keep a binding alive only when every incoming state keeps it alive.
auto _meet_alive_state(self, *List] states[Dict[str, bool]) -> List[Dict[str, bool]]
Return the definite-liveness meet of several states.
auto _check_dead_liveness_block(self, Block block, *bool check_return_paths) -> StmtFlow
Type-check an unreachable branch without exporting liveness or loop exits.
auto _check_update_from_backedge_states(self, Optional update[Stmt], List]] states[List[Dict[str, bool]) -> List[List[Dict[str, bool]]]
Check a for-update statement from all reachable body backedges.
auto _check_loop_iteration(self, Block body, *Optional update[Stmt] = None, bool check_return_paths = False) -> Tuple[LoopFlowCapture, List[List[Dict[str, bool]]], StmtFlow]
Check one loop iteration and return captured flow states.
auto _loop_liveness_fixed_point(self, List] pre_loop[Dict[str, bool], Block body, *Optional cond[Expr] = None, Optional update[Stmt] = None) -> Tuple[List[Dict[str, bool]], LoopFlowCapture, List[List[Dict[str, bool]]]]
Converge loop-head liveness and diagnose later-iteration uses.
auto _check_block(self, Block block, *bool check_return_paths = False, bool push_new_scope = True) -> StmtFlow
Check a block of statements.
auto _check_stmt(self, Stmt stmt, *bool check_return_paths = False) -> StmtFlow
Check a single statement.
auto _infer_type_expr(self, TypeExpr expr) -> Optional[Type]
TypeExpr is only valid as an argument to type-accepting intrinsics.
auto _check_expr_liveness(self, Expr expr) -> None
Replay only local-variable use checks for an already typed expression.
auto _infer_expr(self, Optional expr[Expr], *Optional widening_type[Type] = None, str context_code = "TYP-0319", str context_descriptor = "expression") -> Optional[Type]
Infer the type of an expression.
auto _store_var_resolution(self, VarRef expr, VarRefResolution resolution) -> None
Record stable resolution metadata outside liveness-only replay.
auto _infer_var_ref(self, VarRef expr) -> Optional[Type]
Infer type for a variable reference.
auto _infer_unary(self, UnaryOp expr) -> Optional[Type]
Infer type for a unary operation.
auto _infer_binary(self, BinaryOp expr) -> Optional[Type]
Infer type for a binary operation.
auto _binary_expect_both_int(self, BinaryOp expr, Optional left[Type], Optional right[Type], Optional result[Type]) -> Optional[Type]
Check that both operands of a binary op are int-assignable.
auto _binary_expect_both_bool(self, BinaryOp expr, Optional left[Type], Optional right[Type], Optional result[Type]) -> Optional[Type]
Check that both operands of a binary op are bool.
auto _binary_equality(self, BinaryOp expr, Optional left[Type], Optional right[Type]) -> Optional[Type]
Infer type for equality/inequality comparison.
auto _try_infer_intrinsic(self, CallExpr expr) -> Optional[Type]
Handle compiler intrinsics calls.
auto _infer_sizeof_intrinsic(self, CallExpr expr) -> Type
Handle sizeof(T) or sizeof(expr) intrinsic.
auto _try_resolve_type_name(self, str name, *Optional node[Node] = None, Optional] module_path[List[str] = None) -> Optional[Type]
Try to resolve an identifier as a type name.
auto _store_sizeof_target(self, CallExpr expr, Type target_ty) -> None
Store the resolved sizeof target type for codegen.
auto _infer_ord_intrinsic(self, CallExpr expr) -> Type
Handle ord(enum_value) intrinsic - returns 0-based ordinal of enum variant.
auto _infer_call(self, CallExpr expr) -> Optional[Type]
Infer type for a function or constructor call.
auto _infer_struct_constructor(self, CallExpr expr, Symbol sym) -> Optional[Type]
Infer type for a struct constructor call.
auto _infer_variant_constructor(self, CallExpr expr, Symbol sym) -> Optional[Type]
Infer type for an enum variant constructor call.
auto _infer_index(self, IndexExpr expr) -> Optional[Type]
Infer type for an indexing expression.
auto _infer_field_access(self, FieldAccessExpr expr) -> Optional[Type]
Infer type for a field access expression.
auto _infer_cast(self, CastExpr expr) -> Optional[Type]
Infer type for a cast expression and validate compatibility.
auto _infer_try(self, TryExpr expr) -> Optional[Type]
Infer type for a '?' try operator expression.
auto _check_return(self, ReturnStmt stmt) -> None
Check return statement validity and type compatibility.
auto _resolve_type_ref(self, tref) -> Optional[Type]
Resolve a TypeRef to a semantic Type.
auto _can_assign(self, Type target, Type source, * allow_promotion = False) -> bool
Check if 'source' type can be assigned to 'target' type.
auto _is_nullable_or_ptr(self, Type t) -> bool
Check if type is nullable or a pointer.
auto _error(self, Optional node[Node], str message) -> None
Report an error diagnostic.
auto _warn(self, Optional node[Node], str message) -> None
Report a warning diagnostic.
auto _diagnostic(self, Optional node[Node], str message, str kind = "info") -> None
Internal helper to create and append a diagnostic.
auto _is_int_assignable(self, Optional typ[Type]) -> bool
Check if type is 'int' or 'byte'.
auto _get_const_int_for_explicit_cast(self, Expr expr) -> Optional[int]
Extract a compile-time integer value from a cast operand when available.
auto _is_const_null_for_explicit_cast(self, Expr expr) -> bool
Check whether a cast operand is provably null at compile time.
auto _is_bool(self, Optional typ[Type]) -> bool
Check if type is 'bool'.
auto _is_string(self, NullType|Type typ) -> bool
Check if type is 'string'.
auto _case_literal_info(self, Expr expr) -> Optional[tuple[Type, object]]
Get type and value for a case arm literal.
auto _decode_escaped_bytes(self, str text, Node node) -> Optional[bytes]
Decode a string literal, reporting errors.
auto _is_void(self, Type typ) -> bool
Check if type is 'void'.
auto _types_equal(self, Type a, Type b) -> bool
Check if two types are exactly the same.
auto _describe_lvalue(self, Expr expr) -> str
Generate a human-readable description of an lvalue expression.
auto _reject_name_qualifier(self, Node node, str name, Optional] name_qualifier[List[str], Optional] module_path[List[str]) -> bool
Check for and reject unsupported qualified name syntax (::).
auto _validate_match_variant_pattern(self, VariantPattern pattern, EnumType scrutinee_ty, Optional enum_info[EnumInfo]) -> Optional[str]
Validate one match variant and return its canonical enum name.
auto _infer_new(self, NewExpr expr) -> Optional[Type]
Infer type for a 'new' heap allocation expression.

Protected attributes

_current_func_env
_current_func_type
_local_scopes
_alive_scopes
_return_paths
_breakable_loop_depth
_next_stmt_unreachable
_cleanup_header_ref_guard_stack
_loop_flow_capture_stack
_suppress_liveness_diagnostics
_suppress_diagnostics
_liveness_diagnostics_only

Function documentation

None l0_expr_types::ExpressionTypeChecker::check(self)

Run expression/type checking for all non-extern functions.

This is the main entry point for expression analysis. It should be called after top-level signature resolution is complete and local scopes have been built.

None l0_expr_types::ExpressionTypeChecker::_check_function(self, FunctionEnv func_env, FuncType func_type) protected

Check a single function definition.

Parameters
func_env The function's environment containing AST and module info.
func_type The function's resolved signature.

None l0_expr_types::ExpressionTypeChecker::_declare_local(self, str name, Type typ, Node node) protected

Declare a local variable in the innermost scope.

Parameters
name The name of the variable.
typ The resolved Type of the variable.
node The AST node where the declaration occurs.

StmtFlow l0_expr_types::ExpressionTypeChecker::_check_block(self, Block block, *bool check_return_paths = False, bool push_new_scope = True) protected

Check a block of statements.

Parameters
block The Block node.
check_return_paths Whether to track return paths in this block.
push_new_scope Whether to push a new lexical scope for this block.

StmtFlow l0_expr_types::ExpressionTypeChecker::_check_stmt(self, Stmt stmt, *bool check_return_paths = False) protected

Check a single statement.

Parameters
stmt The Stmt node.
check_return_paths Whether to update return path tracking.

Optional[Type] l0_expr_types::ExpressionTypeChecker::_infer_expr(self, Optional expr[Expr], *Optional widening_type[Type] = None, str context_code = "TYP-0319", str context_descriptor = "expression") protected

Infer the type of an expression.

Parameters
expr The expression to type-check.
widening_type Optional expected type for context-sensitive checking.
context_code Diagnostic code for type mismatch.
context_descriptor Description of context for diagnostic.
Returns The resolved Type of the expression, or None on error.