Skip to content

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 #

@[flag]
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 #

@[heap]
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
}