Checker

Struct Checker 

Source
pub struct Checker<'a, S: SourceRead> {
    pub tc_objs: &'a mut TCObjects,
    pub ast_objs: &'a mut AstObjects,
    pub fset: &'a mut FileSet,
    pub all_pkgs: &'a mut Map<String, PackageKey>,
    pub pkg: PackageKey,
    pub obj_map: Map<ObjKey, DeclInfoKey>,
    pub imp_map: Map<ImportKey, PackageKey>,
    pub octx: ObjContext,
    pub result: TypeInfo,
    pub indent: Rc<RefCell<usize>>,
    /* private fields */
}

Fields§

§tc_objs: &'a mut TCObjects§ast_objs: &'a mut AstObjects§fset: &'a mut FileSet§all_pkgs: &'a mut Map<String, PackageKey>§pkg: PackageKey§obj_map: Map<ObjKey, DeclInfoKey>§imp_map: Map<ImportKey, PackageKey>§octx: ObjContext§result: TypeInfo§indent: Rc<RefCell<usize>>

Implementations§

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn unparen(x: &Expr) -> &Expr

Source

pub fn invalid_ast(&self, pos: Pos, err: &str)

invalid_ast helps to report ast error

Source

pub fn invalid_arg(&self, pos: Pos, err: &str)

Source

pub fn invalid_op(&self, pos: Pos, err: &str)

Source

pub fn obj_path_str(&self, path: &Vec<ObjKey>) -> String

Source

pub fn dump(&self, pos: Option<Pos>, msg: &str)

Source

pub fn print_trace(&self, pos: Pos, msg: &str)

Source

pub fn trace_begin(&self, pos: Pos, msg: &str)

Source

pub fn trace_end(&self, pos: Pos, msg: &str)

Source

pub fn has_cycle(&self, okey: ObjKey, path: &[ObjKey], report: bool) -> bool

Source

pub fn comma_ok_type( tc_objs: &mut TCObjects, pos: usize, pkg: PackageKey, t: &[TypeKey; 2], ) -> TypeKey

Source

pub fn unpack<'b>( &mut self, rhs: &'b Vec<Expr>, lhs_len: usize, allow_comma_ok: bool, variadic: bool, fctx: &mut FilesContext<'_, S>, ) -> UnpackResult<'b>

Source

pub fn use_exprs(&mut self, exprs: &Vec<Expr>, fctx: &mut FilesContext<'_, S>)

Source

pub fn use_lhs(&mut self, lhs: &Vec<Expr>, fctx: &mut FilesContext<'_, S>)

Source

pub fn lookup(&self, name: &str) -> Option<ObjKey>

Source

pub fn add_decl_dep(&mut self, to: ObjKey)

Source

pub fn insert_obj_to_set( &self, set: &mut Map<String, ObjKey>, okey: ObjKey, ) -> Option<ObjKey>

Source

pub fn ast_ident(&self, key: IdentKey) -> &Ident

Source

pub fn lobj(&self, key: ObjKey) -> &LangObj

Source

pub fn lobj_mut(&mut self, key: ObjKey) -> &mut LangObj

Source

pub fn otype(&self, key: TypeKey) -> &Type

Source

pub fn otype_mut(&mut self, key: TypeKey) -> &mut Type

Source

pub fn otype_interface(&self, key: TypeKey) -> &InterfaceDetail

Source

pub fn otype_signature(&self, key: TypeKey) -> &SignatureDetail

Source

pub fn otype_interface_mut(&mut self, key: TypeKey) -> &mut InterfaceDetail

Source

pub fn otype_signature_mut(&mut self, key: TypeKey) -> &mut SignatureDetail

Source

pub fn package(&self, key: PackageKey) -> &Package

Source

pub fn package_mut(&mut self, key: PackageKey) -> &mut Package

Source

pub fn scope(&self, key: ScopeKey) -> &Scope

Source

pub fn decl_info(&self, key: DeclInfoKey) -> &DeclInfo

Source

pub fn position(&self, pos: Pos) -> FilePos

Source

pub fn builtin_info(&self, id: Builtin) -> &BuiltinInfo

Source

pub fn basic_type(&self, t: BasicType) -> TypeKey

Source

pub fn invalid_type(&self) -> TypeKey

Source

pub fn new_dis<'b>(&'b self, x: &'b impl Display) -> Displayer<'b>

Source

pub fn new_td_o<'t>(&'t self, t: &'t Option<TypeKey>) -> Displayer<'t>

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn assignment( &mut self, x: &mut Operand, t: Option<TypeKey>, note: &str, fctx: &mut FilesContext<'_, S>, )

assignment reports whether x can be assigned to a variable of type t, if necessary by attempting to convert untyped values to the appropriate type. context describes the context in which the assignment takes place. Use t == None to indicate assignment to an untyped blank identifier. x.mode is set to invalid if the assignment failed.

Source

pub fn init_const( &mut self, lhskey: ObjKey, x: &mut Operand, fctx: &mut FilesContext<'_, S>, )

Source

pub fn init_var( &mut self, lhskey: ObjKey, x: &mut Operand, msg: &str, fctx: &mut FilesContext<'_, S>, ) -> Option<TypeKey>

Source

pub fn assign_var( &mut self, lhs: &Expr, x: &mut Operand, fctx: &mut FilesContext<'_, S>, ) -> Option<TypeKey>

Source

pub fn init_vars( &mut self, lhs: &Vec<ObjKey>, rhs: &Vec<Expr>, return_pos: Option<Pos>, fctx: &mut FilesContext<'_, S>, )

If return_pos is_some, init_vars is called to type-check the assignment of return expressions, and return_pos is the position of the return statement.

Source

pub fn assign_vars( &mut self, lhs: &Vec<Expr>, rhs: &Vec<Expr>, fctx: &mut FilesContext<'_, S>, )

Source

pub fn short_var_decl( &mut self, lhs: &Vec<Expr>, rhs: &Vec<Expr>, pos: Pos, fctx: &mut FilesContext<'_, S>, )

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn builtin( &mut self, x: &mut Operand, call: &Rc<CallExpr>, id: Builtin, fctx: &mut FilesContext<'_, S>, ) -> bool

builtin type-checks a call to the built-in specified by id and reports whether the call is valid, with *x holding the result; but x.expr is not set. If the call is invalid, the result is false, and *x is undefined.

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn call( &mut self, x: &mut Operand, e: &Rc<CallExpr>, fctx: &mut FilesContext<'_, S>, ) -> ExprKind

Source

pub fn arguments( &mut self, x: &mut Operand, call: &CallExpr, sig: TypeKey, re: &UnpackedResultLeftovers<'_>, n: usize, fctx: &mut FilesContext<'_, S>, )

arguments checks argument passing for the call with the given signature.

Source

pub fn selector( &mut self, x: &mut Operand, e: &Rc<SelectorExpr>, fctx: &mut FilesContext<'_, S>, )

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn new( tc_objs: &'a mut TCObjects, ast_objs: &'a mut AstObjects, fset: &'a mut FileSet, errors: &'a ErrorList, pkgs: &'a mut Map<String, PackageKey>, all_results: &'a mut Map<PackageKey, TypeInfo>, pkg: PackageKey, cfg: &'a TraceConfig, reader: &'a S, ) -> Checker<'a, S>

Source

pub fn check(self, files: Vec<File>) -> Result<PackageKey, ()>

Source

pub fn errors(&self) -> &ErrorList

Source

pub fn trace(&self) -> bool

Source

pub fn new_importer(&mut self, pos: Pos) -> Importer<'_, S>

Source

pub fn error(&self, pos: Pos, err: String)

Source

pub fn error_str(&self, pos: Pos, err: &str)

Source

pub fn soft_error(&self, pos: Pos, err: String)

Source

pub fn soft_error_str(&self, pos: Pos, err: &str)

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn conversion( &mut self, x: &mut Operand, t: TypeKey, fctx: &mut FilesContext<'_, S>, )

Source

pub fn convertable_to( &mut self, x: &Operand, t: TypeKey, fctx: &mut FilesContext<'_, S>, ) -> bool

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn report_alt_decl(&self, okey: ObjKey)

Source

pub fn declare( &mut self, skey: ScopeKey, ikey: Option<IdentKey>, okey: ObjKey, pos: Pos, )

Source

pub fn obj_decl( &mut self, okey: ObjKey, def: Option<TypeKey>, fctx: &mut FilesContext<'_, S>, )

Source

pub fn invalid_type_cycle( &self, okey: ObjKey, fctx: &mut FilesContext<'_, S>, ) -> bool

invalid_type_cycle returns true if the cycle starting with obj is invalid and reports an error.

Source

pub fn const_decl( &mut self, okey: ObjKey, typ: &Option<Expr>, init: &Option<Expr>, fctx: &mut FilesContext<'_, S>, )

Source

pub fn var_decl( &mut self, okey: ObjKey, lhs: Option<&Vec<ObjKey>>, typ: &Option<Expr>, init: &Option<Expr>, fctx: &mut FilesContext<'_, S>, )

Source

pub fn type_decl( &mut self, okey: ObjKey, typ: &Expr, def: Option<TypeKey>, alias: bool, fctx: &mut FilesContext<'_, S>, )

Source

pub fn func_decl( &mut self, okey: ObjKey, dkey: DeclInfoKey, fctx: &mut FilesContext<'_, S>, )

Source

pub fn add_method_decls(&mut self, okey: ObjKey, fctx: &mut FilesContext<'_, S>)

Source

pub fn decl_stmt(&mut self, decl: Decl, fctx: &mut FilesContext<'_, S>)

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Basic algorithm:

Expressions are checked recursively, top down. Expression checker functions are generally of the form:

fn f(x &mut operand, e &Expr, …)

where e is the expression to be checked, and x is the result of the check. The check performed by f may fail in which case x.mode == OperandMode::invalid, and related error messages will have been issued by f.

If a hint argument is present, it is the composite literal element type of an outer composite literal; it is used to type-check composite literal elements that have no explicit type specification in the source (e.g.: []T{{…}, {…}}, the hint is the type T in this case).

All expressions are checked via raw_expr, which dispatches according to expression kind. Upon returning, raw_expr is recording the types and constant values for all expressions that have an untyped type (those types may change on the way up in the expression tree). Usually these are constants, but the results of comparisons or non-constant shifts of untyped constants may also be untyped, but not constant.

Untyped expressions may eventually become fully typed (i.e., not untyped), typically when the value is assigned to a variable, or is used otherwise. The update_expr_type method is used to record this final type and update the recorded types: the type-checked expression tree is again traversed down, and the new type is propagated as needed. Untyped constant expression values that become fully typed must now be representable by the full type (constant sub-expression trees are left alone except for their roots). This mechanism ensures that a client sees the actual (run-time) type an untyped value would have. It also permits type-checking of lhs shift operands “as if the shift were not present”: when update_expr_type visits an untyped lhs shift operand and assigns it it’s final type, that type must be an integer type, and a constant lhs must be representable as an integer.

When an expression gets its final type, either on the way out from raw_expr, on the way down in update_expr_type, or at the end of the type checker run, the type (and constant value, if any) is recorded via Info.Types, if present.

Source

pub fn representable(&mut self, x: &mut Operand, t: TypeKey)

representable checks that a constant operand is representable in the given basic type.

Source

pub fn update_expr_type( &mut self, e: &Expr, t: TypeKey, final_: bool, fctx: &mut FilesContext<'_, S>, )

update_expr_type updates the type of x to typ and invokes itself recursively for the operands of x, depending on expression kind. If typ is still an untyped and not the final type, update_expr_type only updates the recorded untyped type for x and possibly its operands. Otherwise (i.e., typ is not an untyped type anymore, or it is the final type for x), the type and value are recorded. Also, if x is a constant, it must be representable as a value of typ, and if x is the (formerly untyped) lhs operand of a non-constant shift, it must be an integer value.

Source

pub fn convert_untyped( &mut self, x: &mut Operand, target: TypeKey, fctx: &mut FilesContext<'_, S>, )

convert_untyped attempts to set the type of an untyped value to the target type.

Source

pub fn comparison( &mut self, x: &mut Operand, y: &Operand, op: &Token, fctx: &mut FilesContext<'_, S>, )

Source

pub fn binary( &mut self, x: &mut Operand, e: Option<&Expr>, lhs: &Expr, rhs: &Expr, op: &Token, fctx: &mut FilesContext<'_, S>, )

The binary expression e may be None. It’s passed in for better error messages only.

Source

pub fn index( &mut self, index: &Expr, max: Option<u64>, fctx: &mut FilesContext<'_, S>, ) -> Result<Option<u64>, ()>

index checks an index expression for validity. max is the upper bound for index. returns the value of the index when it’s a constant, returns None if it’s not

Source

pub fn raw_expr( &mut self, x: &mut Operand, e: &Expr, hint: Option<TypeKey>, fctx: &mut FilesContext<'_, S>, ) -> ExprKind

raw_expr typechecks expression e and initializes x with the expression value or type. If an error occurred, x.mode is set to invalid. If hint is_some(), it is the type of a composite literal element.

Source

pub fn type_assertion( &mut self, pos: Option<Pos>, x: &mut Operand, xtype: TypeKey, t: TypeKey, fctx: &mut FilesContext<'_, S>, )

type_assertion checks that x.(T) is legal; xtyp must be the type of x.

Source

pub fn single_value(&self, x: &mut Operand)

Source

pub fn expr( &mut self, x: &mut Operand, e: &Expr, fctx: &mut FilesContext<'_, S>, )

expr typechecks expression e and initializes x with the expression value. The result must be a single value. If an error occurred, x.mode is set to invalid.

Source

pub fn multi_expr( &mut self, x: &mut Operand, e: &Expr, fctx: &mut FilesContext<'_, S>, )

multi_expr is like expr but the result may be a multi-value.

Source

pub fn expr_or_type( &mut self, x: &mut Operand, e: &Expr, fctx: &mut FilesContext<'_, S>, )

expr_or_type typechecks expression or type e and initializes x with the expression value or type. If an error occurred, x.mode is set to invalid.

Source

pub fn expr_with_hint( &mut self, x: &mut Operand, e: &Expr, hint: TypeKey, fctx: &mut FilesContext<'_, S>, )

expr_with_hint typechecks expression e and initializes x with the expression value; hint is the type of a composite literal element. If an error occurred, x.mode is set to invalid.

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn init_order(&mut self)

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn info_from_type_lit( &self, skey: ScopeKey, iface: &Rc<InterfaceType>, tname: Option<ObjKey>, path: &Vec<ObjKey>, fctx: &mut FilesContext<'_, S>, ) -> Option<Rc<IfaceInfo>>

info_from_type_lit computes the method set for the given interface iface declared in scope. If a corresponding type name exists (tname is_some), it is used for cycle detection and to cache the method set. The result is the method set, or None if there is a cycle via embedded interfaces. A is_some result doesn’t mean that there were no errors, but they were either reported (e.g., blank methods), or will be found (again) when computing the interface’s type. If tname is not None it must be the last element in path.

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn labels(&mut self, body: &Rc<BlockStmt>)

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn collect_objects(&mut self, fctx: &mut FilesContext<'_, S>)

Source

pub fn package_objects(&mut self, fctx: &mut FilesContext<'_, S>)

package_objects typechecks all package objects, but not function bodies.

Source

pub fn unused_imports(&mut self, fctx: &mut FilesContext<'_, S>)

unused_imports checks for unused imports.

Source

pub fn arity_match(&self, s: &ValueSpec, cst: bool, init: Option<&ValueSpec>)

arity_match checks that the lhs and rhs of a const or var decl have the appropriate number of names and init exprs. set ‘cst’ as true for const decls, ‘init’ is not used for var decls.

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn is_terminating(&self, s: &Stmt, label: Option<&String>) -> bool

is_terminating returns if s is a terminating statement. If s is labeled, label is the label name

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn func_body( &mut self, di: Option<DeclInfoKey>, name: &str, sig: TypeKey, body: BodyContainer, iota: Option<Value>, fctx: &mut FilesContext<'_, S>, )

Source§

impl<'a, S: SourceRead> Checker<'a, S>

Source

pub fn ident( &mut self, x: &mut Operand, ikey: IdentKey, def: Option<TypeKey>, want_type: bool, fctx: &mut FilesContext<'_, S>, )

ident type-checks identifier ikey and initializes x with the value or type of ikey. If an error occurred, x.mode is set to invalid. For the meaning of def, see Checker.defined_type, below. If want_type is set, the identifier e is expected to denote a type.

Source

pub fn type_expr(&mut self, e: &Expr, fctx: &mut FilesContext<'_, S>) -> TypeKey

type_expr type-checks the type expression e and returns its type, or Invalid Type.

Source

pub fn defined_type( &mut self, e: &Expr, def: Option<TypeKey>, fctx: &mut FilesContext<'_, S>, ) -> TypeKey

defined_type is like type_expr but also accepts a type name def. If def is_some(), e is the type specification for the defined type def, declared in a type declaration, and def.underlying will be set to the type of e before any components of e are type-checked.

Source

pub fn indirect_type( &mut self, e: &Expr, fctx: &mut FilesContext<'_, S>, ) -> TypeKey

indirect_type is like type_expr but it also breaks the (otherwise) infinite size of recursivetypes by introducing an indirection. It should be called for components of types that are not laid out in place in memory, such as pointer base types, slice or map element types, function parameter types, etc.

Source

pub fn func_type( &mut self, recv: Option<&FieldList>, ftype: FuncTypeKey, fctx: &mut FilesContext<'_, S>, ) -> TypeKey

func_type type-checks a function or method type.

Source

pub fn type_or_nil( &mut self, e: &Expr, fctx: &mut FilesContext<'_, S>, ) -> Option<TypeKey>

type_or_nil type-checks the type expression (or nil value) e and returns the typ of e, or None. If e is neither a type nor nil, typOrNil returns Typ[Invalid].

Auto Trait Implementations§

§

impl<'a, S> Freeze for Checker<'a, S>

§

impl<'a, S> !RefUnwindSafe for Checker<'a, S>

§

impl<'a, S> !Send for Checker<'a, S>

§

impl<'a, S> !Sync for Checker<'a, S>

§

impl<'a, S> Unpin for Checker<'a, S>

§

impl<'a, S> !UnwindSafe for Checker<'a, S>

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