v2.types
Constants #
const bool_ = Primitive{
props: .boolean
}
primitives
const int_ = Primitive{
props: .integer
// size: 32
}
Todo: represent platform specific sizewill this be calculated at compile time?
const f64_ = Primitive{
props: .float
size: 64
}
const string_ = String(0)
complex / non primitives String struct is defined in cmd/v2/builtin/string.v: pub struct string { str &u8, len int, is_lit int }
const void_ = Void(0)
const voidptr_ = Alias{
name: 'voidptr'
base_type: Pointer{
base_type: Type(void_)
}
}
fn alias_base_type_name #
fn alias_base_type_name(t Type) ?string
fn builtin_type #
fn builtin_type(name string) ?Type
fn init_universe #
fn init_universe() &Scope
fn new_module #
fn new_module(name string, path string) &Module
fn new_scope #
fn new_scope(parent &Scope) &Scope
fn resolve_alias #
fn resolve_alias(t Type) Type
Safely unwrap all Alias layers, guarding against null data pointers from ARM64 codegen corruption.
fn same_scope_ptr #
fn same_scope_ptr(a &Scope, b &Scope) bool
same_scope_ptr compares scope identity by address instead of structural equality.
fn sum_type_name #
fn sum_type_name(t SumType) string
fn type_has_valid_payload #
fn type_has_valid_payload(t Type) bool
fn type_name #
fn type_name(t Type) string
fn Checker.new #
fn Checker.new(prefs &pref.Preferences, file_set &token.FileSet, env &Environment) &Checker
fn DeferredKind.from #
fn DeferredKind.from[W](input W) !DeferredKind
fn Environment.new #
fn Environment.new() &Environment
fn Environment.new_with_capacity #
fn Environment.new_with_capacity(expr_types_cap int, selector_names_cap int) &Environment
Environment.new_with_capacity returns a new checker environment with the hot expression metadata maps pre-sized for large flat-AST builds.
fn FnTypeAttribute.from #
fn FnTypeAttribute.from[W](input W) !FnTypeAttribute
fn FnTypeAttribute.zero #
fn FnTypeAttribute.zero() FnTypeAttribute
fn Properties.from #
fn Properties.from[W](input W) !Properties
fn Properties.zero #
fn Properties.zero() Properties
fn (Checker) add_deferred #
fn (mut c Checker) add_deferred(items []Deferred)
add_deferred is kept for compatibility with parallel type-checking plumbing.
fn (Checker) check_file #
fn (mut c Checker) check_file(file ast.File)
fn (Checker) check_file_from_flat #
fn (mut c Checker) check_file_from_flat(flat &ast.FlatAst, ff ast.FlatFile)
check_file_from_flat mirrors check_file but pulls mod + stmts straight from the FlatAst, so the heavy per-file pass no longer needs a rehydrated ast.File.
fn (Checker) check_files #
fn (mut c Checker) check_files(files []ast.File)
fn (Checker) check_final_default_exprs #
fn (mut c Checker) check_final_default_exprs(files []ast.File)
check_final_default_exprs visits struct field defaults and enum values after function signatures and deferred function bodies are registered.
fn (Checker) check_flat #
fn (mut c Checker) check_flat(flat &ast.FlatAst)
check_flat is the Phase 2 consumer entry point: accepts a FlatAst directly rather than []ast.File. Top-level passes walk the FlatAst and decode only the legacy nodes they still need internally.
fn (Checker) get_module_scope #
fn (mut c Checker) get_module_scope(module_name string, parent &Scope) &Scope
fn (Checker) is_copy_type #
fn (c &Checker) is_copy_type(t Type) bool
is_copy_type reports whether a type implements the Copy marker interface, either intrinsically (primitives, pointers, enums, function types, channels, strings) or explicitly via struct X implements Copy.
Copy types are never moved on assignment. Non-Copy types are not automatically moved either; only types that opt into ownership via implements Owned (struct), .to_owned() (string), or a non-Copy owned-tracked container are subject to move semantics. See is_owned_type.
Backward compatibility: string is treated as Copy here. Ownership is opted into per value via .to_owned(), preserving V's existing implicit auto-clone semantics for plain string literals.
fn (Checker) is_drop_type #
fn (c &Checker) is_drop_type(t Type) bool
is_drop_type reports whether t (or its alias / option / result base) is a struct that declares implements Drop. Drop types must provide a drop(mut self) method; the checker schedules a call to it at scope exit for every owned, non-moved binding via drop_schedule.
fn (Checker) is_owned_type #
fn (c &Checker) is_owned_type(t Type) bool
is_owned_type reports whether values of this type are tracked for ownership. A type is owned-tracked when the user has explicitly opted in:* struct: struct X implements Owned { ... }
- alias / option / result: opt-in propagates through transparently Untracked types behave like today (auto-clone / shared reference), so existing code keeps compiling. This is what the new "owned types beyond string" path keys off in
assign_stmt.
fn (Checker) preregister_fn_signatures #
fn (mut c Checker) preregister_fn_signatures(file ast.File)
fn (Checker) preregister_scopes #
fn (mut c Checker) preregister_scopes(file ast.File)
fn (Checker) preregister_types #
fn (mut c Checker) preregister_types(file ast.File)
fn (Checker) process_all_deferred #
fn (mut c Checker) process_all_deferred()
process_all_deferred is kept for compatibility with parallel type-checking plumbing.
fn (Checker) process_struct_deferred #
fn (mut c Checker) process_struct_deferred()
process_struct_deferred is kept for compatibility with parallel type-checking plumbing.
fn (Checker) take_deferred #
fn (mut c Checker) take_deferred() []Deferred
take_deferred is kept for compatibility with parallel type-checking plumbing.
fn (FnTypeAttribute) is_empty #
fn (e &FnTypeAttribute) is_empty() bool
fn (FnTypeAttribute) has #
fn (e &FnTypeAttribute) has(flag_ FnTypeAttribute) bool
fn (FnTypeAttribute) all #
fn (e &FnTypeAttribute) all(flag_ FnTypeAttribute) bool
fn (FnTypeAttribute) set #
fn (mut e FnTypeAttribute) set(flag_ FnTypeAttribute)
fn (FnTypeAttribute) set_all #
fn (mut e FnTypeAttribute) set_all()
fn (FnTypeAttribute) clear #
fn (mut e FnTypeAttribute) clear(flag_ FnTypeAttribute)
fn (FnTypeAttribute) clear_all #
fn (mut e FnTypeAttribute) clear_all()
fn (FnTypeAttribute) toggle #
fn (mut e FnTypeAttribute) toggle(flag_ FnTypeAttribute)
type Object #
type Object = Const | Fn | Global | Module | SmartCastSelector | Type | TypeObject
fn (Object) typ #
fn (obj &Object) typ() Type
fn (Tuple) get_types #
fn (t &Tuple) get_types() []Type
type Type #
type Type = Alias
| Array
| ArrayFixed
| Channel
| Char
| Enum
| FnType
| ISize
| Interface
| Map
| NamedType
| Nil
| None
| OptionType
| Pointer
| Primitive
| ResultType
| Rune
| String
| Struct
| SumType
| Thread
| Tuple
| USize
| Void
Todo: fix nested sum type in tinyv (like TS)
fn (Type) base_type #
fn (t Type) base_type() Type
fn (Type) channel_elem_type #
fn (t Type) channel_elem_type() ?Type
fn (Type) key_type #
fn (t Type) key_type() Type
return the key type used with for in loops
fn (Type) value_type #
fn (t Type) value_type() Type
return the value type used with for in loops
fn (Type) name #
fn (t Type) name() string
enum DeferredKind #
enum DeferredKind {
fn_decl
fn_decl_generic
struct_decl
const_decl
}
enum Properties #
enum Properties {
boolean
float
integer
unsigned
untyped
}
fn (Properties) all #
fn (e &Properties) all(flag_ Properties) bool
fn (Properties) clear #
fn (mut e Properties) clear(flag_ Properties)
fn (Properties) clear_all #
fn (mut e Properties) clear_all()
fn (Properties) has #
fn (e &Properties) has(flag_ Properties) bool
fn (Properties) is_empty #
fn (e &Properties) is_empty() bool
fn (Properties) set #
fn (mut e Properties) set(flag_ Properties)
fn (Properties) set_all #
fn (mut e Properties) set_all()
fn (Properties) toggle #
fn (mut e Properties) toggle(flag_ Properties)
struct Alias #
struct Alias {
pub:
name string
pub mut:
base_type Type
}
struct Array #
struct Array {
pub:
elem_type Type
}
struct ArrayFixed #
struct ArrayFixed {
pub:
len int
elem_type Type
}
struct BorrowInfo #
struct BorrowInfo {
pub:
borrower string // who is borrowing (function name or variable name)
pos token.Pos // position where borrow was created
is_mut bool // true if this is a mutable borrow
}
BorrowInfo tracks an active borrow of a variable.
struct Channel #
struct Channel {
pub:
elem_type ?Type
}
struct Const #
struct Const {
ObjectCommon
pub:
int_val int
}
struct Deferred #
struct Deferred {
pub:
kind DeferredKind
func fn () = unsafe { nil }
scope &Scope
}
struct DropEntry #
struct DropEntry {
pub:
var_name string // local binding to drop
type_name string // displayed type, for diagnostics / debug output
fn_name string // enclosing function (key into drop_schedule)
pos token.Pos // position where the binding became owned
}
DropEntry records a scheduled scope-exit destructor call. The codegen integration (a follow-up) reads Checker.drop_schedule and emits var_name.drop() immediately before each binding's owning scope ends.
struct Enum #
struct Enum {
pub:
// TODO: store attributes enum or bool?
is_flag bool
name string
fields []Field
// fields map[string]Type
}
struct Environment #
struct Environment {
pub mut:
// errors with no default value
scopes shared map[string]&Scope = map[string]&Scope{}
// Function scopes - stores the scope for each function by qualified name (module__fn_name)
// This allows later passes (transformer, codegen) to look up local variable types
fn_scopes shared map[string]&Scope = map[string]&Scope{}
// types map[int]Type
// methods - shared for parallel type checking
methods shared map[string][]&Fn = map[string][]&Fn{}
generic_types map[string][]map[string]Type
cur_generic_types []map[string]Type
// Expression types keyed by token.Pos.id. Positive IDs come from the parser;
// negative IDs come from transformer's synthesized nodes. This must stay sparse:
// parser position IDs are not dense enough to use as direct array indexes in
// large self-host builds.
expr_types map[int]Type
selector_names map[int]string
// Drop-codegen handoff: per-fn list of bindings whose `drop(mut self)`
// method must be called at the fn's natural exit, in declaration order.
// Populated by `ownership_snapshot_drops_at_fn_exit` after each fn body
// is checked (with moves removed), read by the cleanc backend to emit
// `Type__drop(&var)` calls before the fn's closing brace. Only populated
// when the checker runs with `-d ownership`; empty under plain V.
drop_at_fn_exit map[string][]DropEntry
// Drop-codegen handoff for early returns: per-fn list of per-return-stmt
// drop snapshots, in source order. The cleanc backend walks the fn body
// in the same order and maintains a parallel counter to match each
// ReturnStmt to its snapshot. Each inner []DropEntry is the set of
// bindings that must be dropped just BEFORE the corresponding return.
// Bindings that are themselves being returned (and thus moved out) are
// excluded by the checker — the return moves them. Only populated when
// the checker runs with `-d ownership`; empty under plain V.
drop_at_returns map[string][][]DropEntry
// Shared C-language scope. Phase 1 workers register C struct decls into
// here under c_scope_mu; phase 2 (sequential) registers C fn signatures.
// All checkers point their per-checker `c_scope` field at this instance
// so that the `C` Module pasted into each module scope resolves uniformly.
c_scope &Scope = unsafe { nil }
c_scope_mu &sync.Mutex = unsafe { nil }
}
fn (Environment) set_expr_type #
fn (mut e Environment) set_expr_type(id int, typ Type)
set_expr_type stores the computed type for an expression by its unique ID.
fn (Environment) get_expr_type #
fn (e &Environment) get_expr_type(id int) ?Type
get_expr_type retrieves the computed type for an expression by its unique ID.
fn (Environment) has_expr_type #
fn (e &Environment) has_expr_type(id int) bool
has_expr_type reports whether an expression has a stored type. Unlike get_expr_type, it treats an explicit void type as present.
fn (Environment) expr_type_count #
fn (e &Environment) expr_type_count() int
fn (Environment) all_expr_types #
fn (e &Environment) all_expr_types() []Type
fn (Environment) release_expr_type_cache_after_ssa #
fn (mut e Environment) release_expr_type_cache_after_ssa()
release_expr_type_cache_after_ssa releases expression-position metadata once SSA has consumed it. Native MIR/codegen keeps type IDs in SSA/MIR values and does not need these maps on the ARM64 path.
fn (Environment) lookup_method #
fn (e &Environment) lookup_method(type_name string, method_name string) ?FnType
lookup_method looks up a method by receiver type name and method name Returns the method's FnType if found
fn (Environment) lookup_fn #
fn (e &Environment) lookup_fn(module_name string, fn_name string) ?FnType
lookup_fn looks up a function by module and name in the environment's scopes Returns the function's FnType if found
fn (Environment) lookup_local_var #
fn (e &Environment) lookup_local_var(scope &Scope, name string) ?Type
lookup_local_var looks up a local variable by name in the given scope. Walks up the scope chain to find the variable and returns its type.
fn (Environment) set_fn_scope #
fn (mut e Environment) set_fn_scope(module_name string, fn_name string, scope &Scope)
set_fn_scope stores the scope for a function by its qualified name
fn (Environment) get_fn_scope #
fn (e &Environment) get_fn_scope(module_name string, fn_name string) ?&Scope
get_fn_scope retrieves the scope for a function by its qualified name
fn (Environment) get_scope #
fn (e &Environment) get_scope(module_name string) ?&Scope
get_scope retrieves a module scope by exact module name.
fn (Environment) get_fn_scope_by_key #
fn (e &Environment) get_fn_scope_by_key(key string) ?&Scope
get_fn_scope_by_key retrieves a function scope by its fully-qualified key.
fn (Environment) snapshot_scopes #
fn (e &Environment) snapshot_scopes() map[string]&Scope
snapshot_scopes returns a non-shared copy of the scopes map.
fn (Environment) snapshot_methods #
fn (e &Environment) snapshot_methods() map[string][]&Fn
snapshot_methods returns a non-shared copy of the methods map.
fn (Environment) snapshot_fn_scopes #
fn (e &Environment) snapshot_fn_scopes() map[string]&Scope
snapshot_fn_scopes returns a non-shared copy of the fn_scopes map.
struct Field #
struct Field {
pub:
name string
typ Type
default_expr ast.Expr = ast.empty_expr
attributes []ast.Attribute
is_public bool
is_mut bool
is_module_mut bool
is_interface_method bool
owner_module string
}
struct NamedType { name string }
struct Fn #
struct Fn {
name string
// typ FnType // signature
mut:
typ Type // signature
}
fn (Fn) get_name #
fn (f &Fn) get_name() string
get_name returns the function's name
fn (Fn) get_typ #
fn (f &Fn) get_typ() Type
get_typ returns the function's type (FnType)
struct FnType #
struct FnType {
// generic_params []NamedType // T ,Y
generic_params []string // T ,Y
// TODO: save in checker.env? or gere?
// I think I prefer checker env
// generic_types []Types // int,int
params []Parameter
return_type ?Type
is_variadic bool
attributes FnTypeAttribute
mut:
is_mut_receiver bool
generic_types []map[string]Type
// scope was originally used for deferred type checking
// but its better if we dont need it here, although it may
// be meeded for soething later im not thinking of??
// scope &Scope
}
fn (FnType) get_return_type #
fn (f &FnType) get_return_type() ?Type
get_return_type returns the function's return type, or none if void
fn (FnType) get_param_types #
fn (f &FnType) get_param_types() []Type
get_param_types returns function parameter types in declaration order.
fn (FnType) get_param_names #
fn (f &FnType) get_param_names() []string
get_param_names returns function parameter names in declaration order.
fn (FnType) get_generic_params #
fn (f &FnType) get_generic_params() []string
get_generic_params returns the declared generic parameter names.
fn (FnType) is_variadic_fn #
fn (f &FnType) is_variadic_fn() bool
is_variadic_fn reports whether this function type was declared variadic.
fn (FnType) get_generic_types #
fn (f &FnType) get_generic_types() []map[string]Type
get_generic_types returns the concrete generic instantiations inferred for this function.
struct Interface #
struct Interface {
pub:
name string
pub mut:
fields []Field
// fields map[string]Type
// TODO:
}
struct Map #
struct Map {
pub:
key_type Type
value_type Type
}
struct Module #
struct Module {
pub:
name string
path string
imports []Module
scope &Scope = new_scope(unsafe { nil })
}
fn (Module) lookup #
fn (m &Module) lookup(name string) ?Object
lookup resolves a symbol from this module scope.
struct MovedVar #
struct MovedVar {
pub:
moved_to string // name of the variable or function parameter it was moved to
move_pos token.Pos // position where the move occurred
is_fn_call bool // true if moved via function call argument
suggest_clone bool = true // show clone suggestion in diagnostics
fn_name string // function name (only when is_fn_call is true)
type_name string = 'string' // type that does not implement Copy
}
MovedVar tracks information about a variable that has been moved.
struct OptionType #
struct OptionType {
pub:
base_type Type
}
struct OwnershipArmState #
struct OwnershipArmState {
pub:
owned map[string]token.Pos
moved map[string]MovedVar
borrowed map[string][]BorrowInfo
terminates bool
}
OwnershipArmState is one match-arm's post-state snapshot. Used by ownership_merge_match_state to fold N arms into a single after-match ownership view, mirroring the if/else two-branch merge.
struct Pointer #
struct Pointer {
pub:
lifetime string
pub mut:
base_type Type
}
struct Primitive #
struct Primitive {
pub:
// kind PrimitiveKind
props Properties
size u8
}
Todo: decide if kind will be used or just propertiesenum PrimitiveKind { bool_ i8_ i16_ // i32_ int_ i64_ // u8_ byte_ u16_ u32_ u64_ untyped_int untyped_float }
struct ResultType #
struct ResultType {
pub:
base_type Type
}
struct Scope #
struct Scope {
pub:
parent &Scope = unsafe { nil }
pub mut:
objects map[string]Object
types map[string]Type
// TODO: try implement using original concept
field_smartcasts map[string]Type
// smartcasts map[string]Type
// TODO: it may be more efficient looking up local vars using an ID
// even if we had to store them in two different places. investigate.
// variables []Object
start int
end int
}
fn (Scope) lookup_field_smartcast #
fn (s &Scope) lookup_field_smartcast(name string) ?Type
Todo: try implement the alternate method I was experimenting with (SmartCastSelector)i'm not sure if it is actually possible though. need to explore it.
fn (Scope) lookup #
fn (s &Scope) lookup(name string) ?Object
fn (Scope) lookup_parent #
fn (s &Scope) lookup_parent(name string, pos int) ?Object
fn (Scope) lookup_type #
fn (s &Scope) lookup_type(name string) ?Type
fn (Scope) lookup_type_parent #
fn (s &Scope) lookup_type_parent(name string, pos int) ?Type
fn (Scope) lookup_var_type #
fn (s &Scope) lookup_var_type(name string) ?Type
lookup_var_type looks up a variable by name and returns its type. Walks up the scope chain to find the variable.
fn (Scope) lookup_parent_with_scope #
fn (s &Scope) lookup_parent_with_scope(name string, pos int) ?(&Scope, Object)
fn (Scope) insert #
fn (mut s Scope) insert(name string, obj Object)
fn (Scope) insert_or_update #
fn (mut s Scope) insert_or_update(name string, obj Object)
insert_or_update always overwrites an existing entry. Used for fn_root_scope where variables from nested scopes must be updated when re-declared.
fn (Scope) insert_type #
fn (mut s Scope) insert_type(name string, typ Type)
fn (Scope) print #
fn (s &Scope) print(recurse_parents bool)
struct Struct #
struct Struct {
pub:
name string
generic_params []string
implements []string
pub mut:
embedded []Struct
// embedded []Type
fields []Field
// fields map[string]Type
// methods []Method
is_soa bool // @[soa] - Structure of Arrays layout for better cache performance
}
struct Method { name string typ FnType }
struct SumType #
struct SumType {
pub:
name string
pub mut:
variants []Type
}
fn (SumType) get_name #
fn (t SumType) get_name() string
get_sum_type_name returns the name of a SumType (public accessor)
fn (SumType) get_variants #
fn (t SumType) get_variants() []Type
get_variants returns the variant types of a SumType
struct TypeObject #
struct TypeObject {
pub:
typ Type
}
- Constants
- fn alias_base_type_name
- fn builtin_type
- fn init_universe
- fn new_module
- fn new_scope
- fn resolve_alias
- fn same_scope_ptr
- fn sum_type_name
- fn type_has_valid_payload
- fn type_name
- fn Checker.new
- fn DeferredKind.from
- fn Environment.new
- fn Environment.new_with_capacity
- fn FnTypeAttribute.from
- fn FnTypeAttribute.zero
- fn Properties.from
- fn Properties.zero
- type Checker
- fn add_deferred
- fn check_file
- fn check_file_from_flat
- fn check_files
- fn check_final_default_exprs
- fn check_flat
- fn get_module_scope
- fn is_copy_type
- fn is_drop_type
- fn is_owned_type
- fn preregister_fn_signatures
- fn preregister_scopes
- fn preregister_types
- fn process_all_deferred
- fn process_struct_deferred
- fn take_deferred
- type FnTypeAttribute
- type Object
- type Tuple
- type Type
- enum DeferredKind
- enum Properties
- struct Alias
- struct Array
- struct ArrayFixed
- struct BorrowInfo
- struct Channel
- struct Const
- struct Deferred
- struct DropEntry
- struct Enum
- struct Environment
- fn set_expr_type
- fn get_expr_type
- fn has_expr_type
- fn expr_type_count
- fn all_expr_types
- fn release_expr_type_cache_after_ssa
- fn lookup_method
- fn lookup_fn
- fn lookup_local_var
- fn set_fn_scope
- fn get_fn_scope
- fn get_scope
- fn get_fn_scope_by_key
- fn snapshot_scopes
- fn snapshot_methods
- fn snapshot_fn_scopes
- struct Field
- struct Fn
- struct FnType
- struct Interface
- struct Map
- struct Module
- struct MovedVar
- struct OptionType
- struct OwnershipArmState
- struct Pointer
- struct Primitive
- struct ResultType
- struct Scope
- struct Struct
- struct SumType
- struct TypeObject