// Generated by Lisette bindgen
// Source: go/types (Go stdlib)
// Go: 1.25.5
// Lisette: 0.1.11

import "go:bytes"
import "go:go/ast"
import "go:go/constant"
import "go:go/token"
import "go:io"
import "go:iter"

pub enum BasicKind: int {
  Bool = 1,
  Byte = 8,
  Complex128 = 16,
  Complex64 = 15,
  Float32 = 13,
  Float64 = 14,
  Int = 2,
  Int16 = 4,
  Int32 = 5,
  Int64 = 6,
  Int8 = 3,
  Invalid = 0,
  Rune = 5,
  String = 17,
  Uint = 7,
  Uint16 = 9,
  Uint32 = 10,
  Uint64 = 11,
  Uint8 = 8,
  Uintptr = 12,
  UnsafePointer = 18,
  UntypedBool = 19,
  UntypedComplex = 23,
  UntypedFloat = 22,
  UntypedInt = 20,
  UntypedNil = 25,
  UntypedRune = 21,
  UntypedString = 24,
}

pub const Bool: BasicKind = 1

pub const Byte: BasicKind = 8

pub const Complex128: BasicKind = 16

pub const Complex64: BasicKind = 15

pub const Float32: BasicKind = 13

pub const Float64: BasicKind = 14

pub const Int: BasicKind = 2

pub const Int16: BasicKind = 4

pub const Int32: BasicKind = 5

pub const Int64: BasicKind = 6

pub const Int8: BasicKind = 3

pub const Invalid: BasicKind = 0

pub const Rune: BasicKind = 5

pub const String: BasicKind = 17

pub const Uint: BasicKind = 7

pub const Uint16: BasicKind = 9

pub const Uint32: BasicKind = 10

pub const Uint64: BasicKind = 11

pub const Uint8: BasicKind = 8

pub const Uintptr: BasicKind = 12

pub const UnsafePointer: BasicKind = 18

pub const UntypedBool: BasicKind = 19

pub const UntypedComplex: BasicKind = 23

pub const UntypedFloat: BasicKind = 22

pub const UntypedInt: BasicKind = 20

pub const UntypedNil: BasicKind = 25

pub const UntypedRune: BasicKind = 21

pub const UntypedString: BasicKind = 24

pub enum VarKind: uint8 {
  FieldVar = 6,
  LocalVar = 2,
  PackageVar = 1,
  ParamVar = 4,
  RecvVar = 3,
  ResultVar = 5,
}

pub const FieldVar: VarKind = 6

pub const LocalVar: VarKind = 2

pub const PackageVar: VarKind = 1

pub const ParamVar: VarKind = 4

pub const RecvVar: VarKind = 3

pub const ResultVar: VarKind = 5

/// AssertableTo reports whether a value of type V can be asserted to have type T.
/// 
/// The behavior of AssertableTo is unspecified in three cases:
///   - if T is Typ[Invalid]
///   - if V is a generalized interface; i.e., an interface that may only be used
///     as a type constraint in Go code
///   - if T is an uninstantiated generic type
pub fn AssertableTo(v: Ref<Interface>, t: Type) -> bool

/// AssignableTo reports whether a value of type V is assignable to a variable
/// of type T.
/// 
/// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an
/// uninstantiated generic type.
pub fn AssignableTo(v: Type, t: Type) -> bool

/// CheckExpr type checks the expression expr as if it had appeared at position
/// pos of package pkg. [Type] information about the expression is recorded in
/// info. The expression may be an identifier denoting an uninstantiated generic
/// function or type.
/// 
/// If pkg == nil, the [Universe] scope is used and the provided
/// position pos is ignored. If pkg != nil, and pos is invalid,
/// the package scope is used. Otherwise, pos must belong to the
/// package.
/// 
/// An error is returned if pos is not within the package or
/// if the node cannot be type-checked.
/// 
/// Note: [Eval] and CheckExpr should not be used instead of running Check
/// to compute types and values, but in addition to Check, as these
/// functions ignore the context in which an expression is used (e.g., an
/// assignment). Thus, top-level untyped constants will return an
/// untyped type rather than the respective context-specific type.
pub fn CheckExpr(
  fset: Ref<token.FileSet>,
  pkg: Ref<Package>,
  pos: token.Pos,
  expr: ast.Expr,
  info: Ref<Info>,
) -> Result<(), error>

/// Comparable reports whether values of type T are comparable.
pub fn Comparable(t: Type) -> bool

/// ConvertibleTo reports whether a value of type V is convertible to a value of
/// type T.
/// 
/// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an
/// uninstantiated generic type.
pub fn ConvertibleTo(v: Type, t: Type) -> bool

/// DefPredeclaredTestFuncs defines the assert and trace built-ins.
/// These built-ins are intended for debugging and testing of this
/// package only.
pub fn DefPredeclaredTestFuncs()

pub fn Default(t: Type) -> Type

pub fn Eval(
  fset: Ref<token.FileSet>,
  pkg: Ref<Package>,
  pos: token.Pos,
  expr: string,
) -> Result<TypeAndValue, error>

/// ExprString returns the (possibly shortened) string representation for x.
/// Shortened representations are suitable for user interfaces but may not
/// necessarily follow Go syntax.
pub fn ExprString(x: ast.Expr) -> string

/// Id returns name if it is exported, otherwise it
/// returns the name qualified with the package path.
pub fn Id(pkg: Ref<Package>, name: string) -> string

/// Identical reports whether x and y are identical types.
/// Receivers of [Signature] types are ignored.
/// 
/// Predicates such as [Identical], [Implements], and
/// [Satisfies] assume that both operands belong to a
/// consistent collection of symbols ([Object] values).
/// For example, two [Named] types can be identical only if their
/// [Named.Obj] methods return the same [TypeName] symbol.
/// A collection of symbols is consistent if, for each logical
/// package whose path is P, the creation of those symbols
/// involved at most one call to [NewPackage](P, ...).
/// To ensure consistency, use a single [Importer] for
/// all loaded packages and their dependencies.
/// For more information, see https://github.com/golang/go/issues/57497.
pub fn Identical(x: Type, y: Type) -> bool

/// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
/// Receivers of [Signature] types are ignored.
pub fn IdenticalIgnoreTags(x: Type, y: Type) -> bool

/// Implements reports whether type V implements interface T.
/// 
/// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated
/// generic type.
pub fn Implements(v: Type, t: Ref<Interface>) -> bool

pub fn Instantiate(
  ctxt: Ref<Context>,
  orig: Type,
  targs: Slice<Type>,
  validate: bool,
) -> Result<Type, error>

/// IsInterface reports whether t is an interface type.
pub fn IsInterface(t: Type) -> bool

pub fn LookupFieldOrMethod(
  t: Type,
  addressable: bool,
  pkg: Ref<Package>,
  name: string,
) -> Option<(Object, Slice<int>)>

pub fn LookupSelection(
  t: Type,
  addressable: bool,
  pkg: Ref<Package>,
  name: string,
) -> Option<Selection>

#[go(comma_ok)]
pub fn MissingMethod(v: Type, t: Ref<Interface>, static: bool) -> Option<Ref<Func>>

pub fn NewAlias(obj: Ref<TypeName>, rhs: Type) -> Ref<Alias>

pub fn NewArray(elem: Type, len: int64) -> Ref<Array>

pub fn NewChan(dir: ChanDir, elem: Type) -> Ref<Chan>

pub fn NewChecker(
  conf: Ref<Config>,
  fset: Ref<token.FileSet>,
  pkg: Ref<Package>,
  info: Ref<Info>,
) -> Ref<Checker>

pub fn NewConst(
  pos: token.Pos,
  pkg: Ref<Package>,
  name: string,
  typ: Type,
  val: constant.Value,
) -> Ref<Const>

pub fn NewContext() -> Ref<Context>

pub fn NewField(
  pos: token.Pos,
  pkg: Ref<Package>,
  name: string,
  typ: Type,
  embedded: bool,
) -> Ref<Var>

pub fn NewFunc(
  pos: token.Pos,
  pkg: Ref<Package>,
  name: string,
  sig: Ref<Signature>,
) -> Ref<Func>

pub fn NewInterface(methods: Slice<Ref<Func>>, embeddeds: Slice<Ref<Named>>) -> Ref<Interface>

pub fn NewInterfaceType(methods: Slice<Ref<Func>>, embeddeds: Slice<Type>) -> Ref<Interface>

pub fn NewLabel(pos: token.Pos, pkg: Ref<Package>, name: string) -> Ref<Label>

pub fn NewMap(key: Type, elem: Type) -> Ref<Map>

pub fn NewMethodSet(t: Type) -> Ref<MethodSet>

pub fn NewNamed(obj: Ref<TypeName>, underlying: Type, methods: Slice<Ref<Func>>) -> Ref<Named>

pub fn NewPackage(path: string, name: string) -> Ref<Package>

pub fn NewParam(pos: token.Pos, pkg: Ref<Package>, name: string, typ: Type) -> Ref<Var>

pub fn NewPkgName(
  pos: token.Pos,
  pkg: Ref<Package>,
  name: string,
  imported: Ref<Package>,
) -> Ref<PkgName>

pub fn NewPointer(elem: Type) -> Ref<Pointer>

pub fn NewScope(
  parent: Ref<Scope>,
  pos: token.Pos,
  end: token.Pos,
  comment: string,
) -> Ref<Scope>

pub fn NewSignature(
  recv: Ref<Var>,
  params: Ref<Tuple>,
  results: Ref<Tuple>,
  variadic: bool,
) -> Ref<Signature>

pub fn NewSignatureType(
  recv: Ref<Var>,
  recvTypeParams: Slice<Ref<TypeParam>>,
  typeParams: Slice<Ref<TypeParam>>,
  params: Ref<Tuple>,
  results: Ref<Tuple>,
  variadic: bool,
) -> Ref<Signature>

pub fn NewSlice(elem: Type) -> Ref<Slice>

pub fn NewStruct(fields: Slice<Ref<Var>>, tags: Slice<string>) -> Ref<Struct>

pub fn NewTerm(tilde: bool, typ: Type) -> Ref<Term>

pub fn NewTuple(x: VarArgs<Ref<Var>>) -> Ref<Tuple>

pub fn NewTypeName(pos: token.Pos, pkg: Ref<Package>, name: string, typ: Type) -> Ref<TypeName>

pub fn NewTypeParam(obj: Ref<TypeName>, constraint: Type) -> Ref<TypeParam>

pub fn NewUnion(terms: Slice<Ref<Term>>) -> Ref<Union>

pub fn NewVar(pos: token.Pos, pkg: Ref<Package>, name: string, typ: Type) -> Ref<Var>

/// ObjectString returns the string form of obj.
/// The Qualifier controls the printing of
/// package-level objects, and may be nil.
pub fn ObjectString(obj: Object, qf: Qualifier) -> string

pub fn RelativeTo(pkg: Ref<Package>) -> Qualifier

/// Satisfies reports whether type V satisfies the constraint T.
/// 
/// The behavior of Satisfies is unspecified if V is Typ[Invalid] or an uninstantiated
/// generic type.
pub fn Satisfies(v: Type, t: Ref<Interface>) -> bool

/// SelectionString returns the string form of s.
/// The Qualifier controls the printing of
/// package-level objects, and may be nil.
/// 
/// Examples:
/// 
/// 	"field (T) f int"
/// 	"method (T) f(X) Y"
/// 	"method expr (T) f(X) Y"
pub fn SelectionString(s: Ref<Selection>, qf: Qualifier) -> string

pub fn SizesFor(compiler: string, arch: string) -> Option<Sizes>

/// TypeString returns the string representation of typ.
/// The [Qualifier] controls the printing of
/// package-level objects, and may be nil.
pub fn TypeString(typ: Type, qf: Qualifier) -> string

pub fn Unalias(t: Type) -> Type

/// WriteExpr writes the (possibly shortened) string representation for x to buf.
/// Shortened representations are suitable for user interfaces but may not
/// necessarily follow Go syntax.
pub fn WriteExpr(buf: Ref<bytes.Buffer>, x: ast.Expr)

/// WriteSignature writes the representation of the signature sig to buf,
/// without a leading "func" keyword. The [Qualifier] controls the printing
/// of package-level objects, and may be nil.
pub fn WriteSignature(
  buf: Ref<bytes.Buffer>,
  sig: Ref<Signature>,
  qf: Qualifier,
)

/// WriteType writes the string representation of typ to buf.
/// The [Qualifier] controls the printing of
/// package-level objects, and may be nil.
pub fn WriteType(buf: Ref<bytes.Buffer>, typ: Type, qf: Qualifier)

/// An Alias represents an alias type.
/// 
/// Alias types are created by alias declarations such as:
/// 
/// 	type A = int
/// 
/// The type on the right-hand side of the declaration can be accessed
/// using [Alias.Rhs]. This type may itself be an alias.
/// Call [Unalias] to obtain the first non-alias type in a chain of
/// alias type declarations.
/// 
/// Like a defined ([Named]) type, an alias type has a name.
/// Use the [Alias.Obj] method to access its [TypeName] object.
/// 
/// Historically, Alias types were not materialized so that, in the example
/// above, A's type was represented by a Basic (int), not an Alias
/// whose [Alias.Rhs] is int. But Go 1.24 allows you to declare an
/// alias type with type parameters or arguments:
/// 
/// 	type Set[K comparable] = map[K]bool
/// 	s := make(Set[String])
/// 
/// and this requires that Alias types be materialized. Use the
/// [Alias.TypeParams] and [Alias.TypeArgs] methods to access them.
/// 
/// To ease the transition, the Alias type was introduced in go1.22,
/// but the type-checker would not construct values of this type unless
/// the GODEBUG=gotypesalias=1 environment variable was provided.
/// Starting in go1.23, this variable is enabled by default.
/// This setting also causes the predeclared type "any" to be
/// represented as an Alias, not a bare [Interface].
pub type Alias

/// An ArgumentError holds an error associated with an argument index.
pub struct ArgumentError {
  pub Index: int,
  pub Err: error,
}

/// An Array represents an array type.
pub type Array

/// A Basic represents a basic type.
pub type Basic

/// BasicInfo is a set of flags describing properties of a basic type.
pub struct BasicInfo(int)

/// A Builtin represents a built-in function.
/// Builtins don't have a valid type.
pub type Builtin

/// A Chan represents a channel type.
pub type Chan

/// A ChanDir value indicates a channel direction.
pub struct ChanDir(int)

/// A Checker maintains the state of the type checker.
/// It must be created with [NewChecker].
pub struct Checker {
  pub Info: Option<Ref<Info>>,
}

/// A Config specifies the configuration for type checking.
/// The zero value for Config is a ready-to-use default configuration.
pub struct Config {
  pub Context: Option<Ref<Context>>,
  pub GoVersion: string,
  pub IgnoreFuncBodies: bool,
  pub FakeImportC: bool,
  pub Error: fn(error) -> (),
  pub Importer: Option<Importer>,
  pub Sizes: Option<Sizes>,
  pub DisableUnusedImportCheck: bool,
}

/// A Const represents a declared constant.
pub type Const

/// A Context is an opaque type checking context. It may be used to share
/// identical type instances across type-checked packages or calls to
/// Instantiate. Contexts are safe for concurrent use.
/// 
/// The use of a shared context does not guarantee that identical instances are
/// deduplicated in all cases.
pub type Context

/// An Error describes a type-checking error; it implements the error interface.
/// A "soft" error is an error that still permits a valid interpretation of a
/// package (such as "unused variable"); "hard" errors may lead to unpredictable
/// behavior if ignored.
pub struct Error {
  pub Fset: Option<Ref<token.FileSet>>,
  pub Pos: token.Pos,
  pub Msg: string,
  pub Soft: bool,
}

/// A Func represents a declared function, concrete method, or abstract
/// (interface) method. Its Type() is always a *Signature.
/// An abstract method may belong to many interfaces due to embedding.
pub type Func

/// ImportMode is reserved for future use.
pub struct ImportMode(int)

/// An Importer resolves import paths to Packages.
/// 
/// CAUTION: This interface does not support the import of locally
/// vendored packages. See https://golang.org/s/go15vendor.
/// If possible, external implementations should implement [ImporterFrom].
pub interface Importer {
  fn Import(path: string) -> Result<Ref<Package>, error>
}

/// An ImporterFrom resolves import paths to packages; it
/// supports vendoring per https://golang.org/s/go15vendor.
/// Use go/importer to obtain an ImporterFrom implementation.
pub interface ImporterFrom {
  fn Import(path: string) -> Result<Ref<Package>, error>
  fn ImportFrom(path: string, dir: string, mode: ImportMode) -> Result<Ref<Package>, error>
}

/// Info holds result type information for a type-checked package.
/// Only the information for which a map is provided is collected.
/// If the package has type errors, the collected information may
/// be incomplete.
pub struct Info {
  pub Types: Map<ast.Expr, TypeAndValue>,
  pub Instances: Map<Ref<ast.Ident>, Instance>,
  pub Defs: Map<Ref<ast.Ident>, Option<Object>>,
  pub Uses: Map<Ref<ast.Ident>, Option<Object>>,
  pub Implicits: Map<ast.Node, Option<Object>>,
  pub Selections: Map<Ref<ast.SelectorExpr>, Option<Ref<Selection>>>,
  pub Scopes: Map<ast.Node, Option<Ref<Scope>>>,
  pub InitOrder: Slice<Option<Ref<Initializer>>>,
  pub FileVersions: Map<Ref<ast.File>, string>,
}

/// An Initializer describes a package-level variable, or a list of variables in case
/// of a multi-valued initialization expression, and the corresponding initialization
/// expression.
pub struct Initializer {
  pub Lhs: Slice<Option<Ref<Var>>>,
  pub Rhs: Option<ast.Expr>,
}

/// Instance reports the type arguments and instantiated type for type and
/// function instantiations. For type instantiations, [Type] will be of dynamic
/// type *[Named]. For function instantiations, [Type] will be of dynamic type
/// *Signature.
pub struct Instance {
  pub TypeArgs: Option<Ref<TypeList>>,
  pub Type: Option<Type>,
}

/// An Interface represents an interface type.
pub type Interface

/// A Label represents a declared label.
/// Labels don't have a type.
pub type Label

/// A Map represents a map type.
pub type Map

/// A MethodSet is an ordered set of concrete or abstract (interface) methods;
/// a method is a [MethodVal] selection, and they are ordered by ascending m.Obj().Id().
/// The zero value for a MethodSet is a ready-to-use empty method set.
pub type MethodSet

/// A Named represents a named (defined) type.
/// 
/// A declaration such as:
/// 
/// 	type S struct { ... }
/// 
/// creates a defined type whose underlying type is a struct,
/// and binds this type to the object S, a [TypeName].
/// Use [Named.Underlying] to access the underlying type.
/// Use [Named.Obj] to obtain the object S.
/// 
/// Before type aliases (Go 1.9), the spec called defined types "named types".
pub type Named

/// Nil represents the predeclared value nil.
pub type Nil

/// An Object is a named language entity.
/// An Object may be a constant ([Const]), type name ([TypeName]),
/// variable or struct field ([Var]), function or method ([Func]),
/// imported package ([PkgName]), label ([Label]),
/// built-in function ([Builtin]),
/// or the predeclared identifier 'nil' ([Nil]).
/// 
/// The environment, which is structured as a tree of Scopes,
/// maps each name to the unique Object that it denotes.
pub interface Object {
  fn Exported() -> bool
  fn Id() -> string
  fn Name() -> string
  fn Parent() -> Ref<Scope>
  fn Pkg() -> Ref<Package>
  fn Pos() -> token.Pos
  fn String() -> string
  fn Type() -> Type
}

/// A Package describes a Go package.
pub type Package

/// A PkgName represents an imported Go package.
/// PkgNames don't have a type.
pub type PkgName

/// A Pointer represents a pointer type.
pub type Pointer

/// A Qualifier controls how named package-level objects are printed in
/// calls to [TypeString], [ObjectString], and [SelectionString].
/// 
/// These three formatting routines call the Qualifier for each
/// package-level object O, and if the Qualifier returns a non-empty
/// string p, the object is printed in the form p.O.
/// If it returns an empty string, only the object name O is printed.
/// 
/// Using a nil Qualifier is equivalent to using (*[Package]).Path: the
/// object is qualified by the import path, e.g., "encoding/json.Marshal".
pub type Qualifier = fn(Ref<Package>) -> string

/// A Scope maintains a set of objects and links to its containing
/// (parent) and contained (children) scopes. Objects may be inserted
/// and looked up by name. The zero value for Scope is a ready-to-use
/// empty scope.
pub type Scope

/// A Selection describes a selector expression x.f.
/// For the declarations:
/// 
/// 	type T struct{ x int; E }
/// 	type E struct{}
/// 	func (e E) m() {}
/// 	var p *T
/// 
/// the following relations exist:
/// 
/// 	Selector    Kind          Recv    Obj    Type       Index     Indirect
/// 
/// 	p.x         FieldVal      T       x      int        {0}       true
/// 	p.m         MethodVal     *T      m      func()     {1, 0}    true
/// 	T.m         MethodExpr    T       m      func(T)    {1, 0}    false
pub type Selection

/// SelectionKind describes the kind of a selector expression x.f
/// (excluding qualified identifiers).
/// 
/// If x is a struct or *struct, a selector expression x.f may denote a
/// sequence of selection operations x.a.b.c.f. The SelectionKind
/// describes the kind of the final (explicit) operation; all the
/// previous (implicit) operations are always field selections.
/// Each element of Indices specifies an implicit field (a, b, c)
/// by its index in the struct type of the field selection operand.
/// 
/// For a FieldVal operation, the final selection refers to the field
/// specified by Selection.Obj.
/// 
/// For a MethodVal operation, the final selection refers to a method.
/// If the "pointerness" of the method's declared receiver does not
/// match that of the effective receiver after implicit field
/// selection, then an & or * operation is implicitly applied to the
/// receiver variable or value.
/// So, x.f denotes (&x.a.b.c).f when f requires a pointer receiver but
/// x.a.b.c is a non-pointer variable; and it denotes (*x.a.b.c).f when
/// f requires a non-pointer receiver but x.a.b.c is a pointer value.
/// 
/// All pointer indirections, whether due to implicit or explicit field
/// selections or * operations inserted for "pointerness", panic if
/// applied to a nil pointer, so a method call x.f() may panic even
/// before the function call.
/// 
/// By contrast, a MethodExpr operation T.f is essentially equivalent
/// to a function literal of the form:
/// 
/// 	func(x T, args) (results) { return x.f(args) }
/// 
/// Consequently, any implicit field selections and * operations
/// inserted for "pointerness" are not evaluated until the function is
/// called, so a T.f or (*T).f expression never panics.
pub struct SelectionKind(int)

/// A Signature represents a (non-builtin) function or method type.
/// The receiver is ignored when comparing signatures for identity.
pub type Signature

/// Sizes defines the sizing functions for package unsafe.
pub interface Sizes {
  fn Alignof(t: Type) -> int64
  fn Offsetsof(fields: Slice<Ref<Var>>) -> Slice<int64>
  fn Sizeof(t: Type) -> int64
}

/// A Slice represents a slice type.
pub type Slice

/// StdSizes is a convenience type for creating commonly used Sizes.
/// It makes the following simplifying assumptions:
/// 
///   - The size of explicitly sized basic types (int16, etc.) is the
///     specified size.
///   - The size of strings and interfaces is 2*WordSize.
///   - The size of slices is 3*WordSize.
///   - The size of an array of n elements corresponds to the size of
///     a struct of n consecutive fields of the array's element type.
///   - The size of a struct is the offset of the last field plus that
///     field's size. As with all element types, if the struct is used
///     in an array its size must first be aligned to a multiple of the
///     struct's alignment.
///   - All other types have size WordSize.
///   - Arrays and structs are aligned per spec definition; all other
///     types are naturally aligned with a maximum alignment MaxAlign.
/// 
/// *StdSizes implements Sizes.
pub struct StdSizes {
  pub WordSize: int64,
  pub MaxAlign: int64,
}

/// A Struct represents a struct type.
pub type Struct

/// A Term represents a term in a [Union].
pub type Term

/// A Tuple represents an ordered list of variables; a nil *Tuple is a valid (empty) tuple.
/// Tuples are used as components of signatures and to represent the type of multiple
/// assignments; they are not first class types of Go.
pub type Tuple

/// A Type represents a type of Go.
/// All types implement the Type interface.
pub interface Type {
  fn String() -> string
  fn Underlying() -> Type
}

/// TypeAndValue reports the type and value (for constants)
/// of the corresponding expression.
pub struct TypeAndValue {
  pub Type: Option<Type>,
  pub Value: Option<constant.Value>,
}

/// TypeList holds a list of types.
pub type TypeList

/// A TypeName is an [Object] that represents a type with a name:
/// a defined type ([Named]),
/// an alias type ([Alias]),
/// a type parameter ([TypeParam]),
/// or a predeclared type such as int or error.
pub type TypeName

/// A TypeParam represents the type of a type parameter in a generic declaration.
/// 
/// A TypeParam has a name; use the [TypeParam.Obj] method to access
/// its [TypeName] object.
pub type TypeParam

/// TypeParamList holds a list of type parameters.
pub type TypeParamList

/// A Union represents a union of terms embedded in an interface.
pub type Union

/// A Variable represents a declared variable (including function parameters and results, and struct fields).
pub type Var

const FieldVal: SelectionKind = 0

const IsBoolean: BasicInfo = 1

const IsComplex: BasicInfo = 16

const IsConstType: BasicInfo = 59

const IsFloat: BasicInfo = 8

const IsInteger: BasicInfo = 2

const IsNumeric: BasicInfo = 26

const IsOrdered: BasicInfo = 42

const IsString: BasicInfo = 32

const IsUnsigned: BasicInfo = 4

const IsUntyped: BasicInfo = 64

const MethodExpr: SelectionKind = 2

const MethodVal: SelectionKind = 1

const RecvOnly: ChanDir = 2

const SendOnly: ChanDir = 1

const SendRecv: ChanDir = 0

/// Typ contains the predeclared *Basic types indexed by their
/// corresponding BasicKind.
/// 
/// The *Basic type for Typ[Byte] will have the name "uint8".
/// Use Universe.Lookup("byte").Type() to obtain the specific
/// alias basic type named "byte" (and analogous for "rune").
pub var Typ: Slice<Ref<Basic>>

pub var Universe: Ref<Scope>

pub var Unsafe: Ref<Package>

impl Alias {
  /// Obj returns the type name for the declaration defining the alias type a.
  /// For instantiated types, this is same as the type name of the origin type.
  fn Obj(self: Ref<Alias>) -> Ref<TypeName>

  /// Origin returns the generic Alias type of which a is an instance.
  /// If a is not an instance of a generic alias, Origin returns a.
  fn Origin(self: Ref<Alias>) -> Ref<Alias>

  /// Rhs returns the type R on the right-hand side of an alias
  /// declaration "type A = R", which may be another alias.
  fn Rhs(self: Ref<Alias>) -> Type

  /// SetTypeParams sets the type parameters of the alias type a.
  /// The alias a must not have type arguments.
  fn SetTypeParams(self: Ref<Alias>, tparams: Slice<Ref<TypeParam>>)

  fn String(self: Ref<Alias>) -> string

  /// TypeArgs returns the type arguments used to instantiate the Alias type.
  /// If a is not an instance of a generic alias, the result is nil.
  fn TypeArgs(self: Ref<Alias>) -> Option<Ref<TypeList>>

  /// TypeParams returns the type parameters of the alias type a, or nil.
  /// A generic Alias and its instances have the same type parameters.
  fn TypeParams(self: Ref<Alias>) -> Option<Ref<TypeParamList>>

  /// Underlying returns the [underlying type] of the alias type a, which is the
  /// underlying type of the aliased type. Underlying types are never Named,
  /// TypeParam, or Alias types.
  /// 
  /// [underlying type]: https://go.dev/ref/spec#Underlying_types.
  fn Underlying(self: Ref<Alias>) -> Type
}

impl ArgumentError {
  fn Error(self: Ref<ArgumentError>) -> string

  fn Unwrap(self: Ref<ArgumentError>) -> Option<error>
}

impl Array {
  /// Elem returns element type of array a.
  fn Elem(self: Ref<Array>) -> Type

  /// Len returns the length of array a.
  /// A negative result indicates an unknown length.
  fn Len(self: Ref<Array>) -> int64

  fn String(self: Ref<Array>) -> string

  fn Underlying(self: Ref<Array>) -> Type
}

impl Basic {
  /// Info returns information about properties of basic type b.
  fn Info(self: Ref<Basic>) -> BasicInfo

  /// Kind returns the kind of basic type b.
  fn Kind(self: Ref<Basic>) -> BasicKind

  /// Name returns the name of basic type b.
  fn Name(self: Ref<Basic>) -> string

  fn String(self: Ref<Basic>) -> string

  fn Underlying(self: Ref<Basic>) -> Type
}

impl Builtin {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Builtin>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Builtin>) -> string

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Builtin>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Builtin>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<Builtin>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Builtin>) -> token.Pos

  fn String(self: Ref<Builtin>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Builtin>) -> Type
}

impl Chan {
  /// Dir returns the direction of channel c.
  fn Dir(self: Ref<Chan>) -> ChanDir

  /// Elem returns the element type of channel c.
  fn Elem(self: Ref<Chan>) -> Type

  fn String(self: Ref<Chan>) -> string

  fn Underlying(self: Ref<Chan>) -> Type
}

impl Checker {
  /// Files checks the provided files as part of the checker's package.
  fn Files(self: Ref<Checker>, files: Slice<Ref<ast.File>>) -> Result<(), error>

  /// ObjectOf returns the object denoted by the specified id,
  /// or nil if not found.
  /// 
  /// If id is an embedded struct field, [Info.ObjectOf] returns the field (*[Var])
  /// it defines, not the type (*[TypeName]) it uses.
  /// 
  /// Precondition: the Uses and Defs maps are populated.
  fn ObjectOf(self, id: Ref<ast.Ident>) -> Option<Object>

  /// PkgNameOf returns the local package name defined by the import,
  /// or nil if not found.
  /// 
  /// For dot-imports, the package name is ".".
  /// 
  /// Precondition: the Defs and Implicts maps are populated.
  fn PkgNameOf(self, imp: Ref<ast.ImportSpec>) -> Option<Ref<PkgName>>

  /// TypeOf returns the type of expression e, or nil if not found.
  /// Precondition: the Types, Uses and Defs maps are populated.
  fn TypeOf(self, e: ast.Expr) -> Option<Type>
}

impl Config {
  /// Check type-checks a package and returns the resulting package object and
  /// the first error if any. Additionally, if info != nil, Check populates each
  /// of the non-nil maps in the [Info] struct.
  /// 
  /// The package is marked as complete if no errors occurred, otherwise it is
  /// incomplete. See [Config.Error] for controlling behavior in the presence of
  /// errors.
  /// 
  /// The package is specified by a list of *ast.Files and corresponding
  /// file set, and the package path the package is identified with.
  /// The clean path must not be empty or dot (".").
  fn Check(
    self: Ref<Config>,
    path: string,
    fset: Ref<token.FileSet>,
    files: Slice<Ref<ast.File>>,
    info: Ref<Info>,
  ) -> Result<Ref<Package>, error>
}

impl Const {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Const>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Const>) -> string

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Const>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Const>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<Const>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Const>) -> token.Pos

  fn String(self: Ref<Const>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Const>) -> Type

  /// Val returns the constant's value.
  fn Val(self: Ref<Const>) -> Option<constant.Value>
}

impl Error {
  /// Error returns an error string formatted as follows:
  /// filename:line:column: message
  fn Error(self) -> string
}

impl Func {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Func>) -> bool

  /// FullName returns the package- or receiver-type-qualified name of
  /// function or method obj.
  fn FullName(self: Ref<Func>) -> string

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Func>) -> string

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Func>) -> string

  /// Origin returns the canonical Func for its receiver, i.e. the Func object
  /// recorded in Info.Defs.
  /// 
  /// For synthetic functions created during instantiation (such as methods on an
  /// instantiated Named type or interface methods that depend on type arguments),
  /// this will be the corresponding Func on the generic (uninstantiated) type.
  /// For all other Funcs Origin returns the receiver.
  fn Origin(self: Ref<Func>) -> Ref<Func>

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Func>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the function belongs.
  /// 
  /// The result is nil for methods of types in the Universe scope,
  /// like method Error of the error built-in interface type.
  fn Pkg(self: Ref<Func>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Func>) -> token.Pos

  /// Scope returns the scope of the function's body block.
  /// The result is nil for imported or instantiated functions and methods
  /// (but there is also no mechanism to get to an instantiated function).
  fn Scope(self: Ref<Func>) -> Option<Ref<Scope>>

  /// Signature returns the signature (type) of the function or method.
  fn Signature(self: Ref<Func>) -> Ref<Signature>

  fn String(self: Ref<Func>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Func>) -> Type
}

impl Info {
  /// ObjectOf returns the object denoted by the specified id,
  /// or nil if not found.
  /// 
  /// If id is an embedded struct field, [Info.ObjectOf] returns the field (*[Var])
  /// it defines, not the type (*[TypeName]) it uses.
  /// 
  /// Precondition: the Uses and Defs maps are populated.
  fn ObjectOf(self: Ref<Info>, id: Ref<ast.Ident>) -> Option<Object>

  /// PkgNameOf returns the local package name defined by the import,
  /// or nil if not found.
  /// 
  /// For dot-imports, the package name is ".".
  /// 
  /// Precondition: the Defs and Implicts maps are populated.
  fn PkgNameOf(self: Ref<Info>, imp: Ref<ast.ImportSpec>) -> Option<Ref<PkgName>>

  /// TypeOf returns the type of expression e, or nil if not found.
  /// Precondition: the Types, Uses and Defs maps are populated.
  fn TypeOf(self: Ref<Info>, e: ast.Expr) -> Option<Type>
}

impl Initializer {
  fn String(self: Ref<Initializer>) -> string
}

impl Interface {
  /// Complete computes the interface's type set. It must be called by users of
  /// [NewInterfaceType] and [NewInterface] after the interface's embedded types are
  /// fully defined and before using the interface type in any way other than to
  /// form other types. The interface must not contain duplicate methods or a
  /// panic occurs. Complete returns the receiver.
  /// 
  /// Interface types that have been completed are safe for concurrent use.
  fn Complete(self: Ref<Interface>) -> Ref<Interface>

  /// Embedded returns the i'th embedded defined (*[Named]) type of interface t for 0 <= i < t.NumEmbeddeds().
  /// The result is nil if the i'th embedded type is not a defined type.
  /// 
  /// Deprecated: Use [Interface.EmbeddedType] which is not restricted to defined (*[Named]) types.
  fn Embedded(self: Ref<Interface>, i: int) -> Option<Ref<Named>>

  /// EmbeddedType returns the i'th embedded type of interface t for 0 <= i < t.NumEmbeddeds().
  fn EmbeddedType(self: Ref<Interface>, i: int) -> Type

  /// EmbeddedTypes returns a go1.23 iterator over the types embedded within an interface.
  /// 
  /// Example: for e := range t.EmbeddedTypes() { ... }
  fn EmbeddedTypes(self: Ref<Interface>) -> iter.Seq<Type>

  /// Empty reports whether t is the empty interface.
  fn Empty(self: Ref<Interface>) -> bool

  /// ExplicitMethod returns the i'th explicitly declared method of interface t for 0 <= i < t.NumExplicitMethods().
  /// The methods are ordered by their unique [Id].
  fn ExplicitMethod(self: Ref<Interface>, i: int) -> Ref<Func>

  /// ExplicitMethods returns a go1.23 iterator over the explicit methods of
  /// an interface, ordered by Id.
  /// 
  /// Example: for m := range t.ExplicitMethods() { ... }
  fn ExplicitMethods(self: Ref<Interface>) -> iter.Seq<Ref<Func>>

  /// IsComparable reports whether each type in interface t's type set is comparable.
  fn IsComparable(self: Ref<Interface>) -> bool

  /// IsImplicit reports whether the interface t is a wrapper for a type set literal.
  fn IsImplicit(self: Ref<Interface>) -> bool

  /// IsMethodSet reports whether the interface t is fully described by its method
  /// set.
  fn IsMethodSet(self: Ref<Interface>) -> bool

  /// MarkImplicit marks the interface t as implicit, meaning this interface
  /// corresponds to a constraint literal such as ~T or A|B without explicit
  /// interface embedding. MarkImplicit should be called before any concurrent use
  /// of implicit interfaces.
  fn MarkImplicit(self: Ref<Interface>)

  /// Method returns the i'th method of interface t for 0 <= i < t.NumMethods().
  /// The methods are ordered by their unique Id.
  fn Method(self: Ref<Interface>, i: int) -> Ref<Func>

  /// Methods returns a go1.23 iterator over all the methods of an
  /// interface, ordered by Id.
  /// 
  /// Example: for m := range t.Methods() { ... }
  fn Methods(self: Ref<Interface>) -> iter.Seq<Ref<Func>>

  /// NumEmbeddeds returns the number of embedded types in interface t.
  fn NumEmbeddeds(self: Ref<Interface>) -> int

  /// NumExplicitMethods returns the number of explicitly declared methods of interface t.
  fn NumExplicitMethods(self: Ref<Interface>) -> int

  /// NumMethods returns the total number of methods of interface t.
  fn NumMethods(self: Ref<Interface>) -> int

  fn String(self: Ref<Interface>) -> string

  fn Underlying(self: Ref<Interface>) -> Type
}

impl Label {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Label>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Label>) -> string

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Label>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Label>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<Label>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Label>) -> token.Pos

  fn String(self: Ref<Label>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Label>) -> Type
}

impl Map {
  /// Elem returns the element type of map m.
  fn Elem(self: Ref<Map>) -> Type

  /// Key returns the key type of map m.
  fn Key(self: Ref<Map>) -> Type

  fn String(self: Ref<Map>) -> string

  fn Underlying(self: Ref<Map>) -> Type
}

impl MethodSet {
  /// At returns the i'th method in s for 0 <= i < s.Len().
  fn At(self: Ref<MethodSet>, i: int) -> Ref<Selection>

  /// Len returns the number of methods in s.
  fn Len(self: Ref<MethodSet>) -> int

  /// Lookup returns the method with matching package and name, or nil if not found.
  fn Lookup(self: Ref<MethodSet>, pkg: Ref<Package>, name: string) -> Option<Ref<Selection>>

  /// Methods returns a go1.23 iterator over the methods of a method set.
  /// 
  /// Example: for method := range s.Methods() { ... }
  fn Methods(self: Ref<MethodSet>) -> iter.Seq<Ref<Selection>>

  fn String(self: Ref<MethodSet>) -> string
}

impl Named {
  /// AddMethod adds method m unless it is already in the method list.
  /// The method must be in the same package as t, and t must not have
  /// type arguments.
  fn AddMethod(self: Ref<Named>, m: Ref<Func>)

  /// Method returns the i'th method of named type t for 0 <= i < t.NumMethods().
  /// 
  /// For an ordinary or instantiated type t, the receiver base type of this
  /// method is the named type t. For an uninstantiated generic type t, each
  /// method receiver is instantiated with its receiver type parameters.
  /// 
  /// Methods are numbered deterministically: given the same list of source files
  /// presented to the type checker, or the same sequence of NewMethod and AddMethod
  /// calls, the mapping from method index to corresponding method remains the same.
  /// But the specific ordering is not specified and must not be relied on as it may
  /// change in the future.
  fn Method(self: Ref<Named>, i: int) -> Ref<Func>

  /// Methods returns a go1.23 iterator over the declared methods of a named type.
  /// 
  /// Example: for m := range t.Methods() { ... }
  fn Methods(self: Ref<Named>) -> iter.Seq<Ref<Func>>

  /// NumMethods returns the number of explicit methods defined for t.
  fn NumMethods(self: Ref<Named>) -> int

  /// Obj returns the type name for the declaration defining the named type t. For
  /// instantiated types, this is same as the type name of the origin type.
  fn Obj(self: Ref<Named>) -> Ref<TypeName>

  /// Origin returns the generic type from which the named type t is
  /// instantiated. If t is not an instantiated type, the result is t.
  fn Origin(self: Ref<Named>) -> Ref<Named>

  /// SetTypeParams sets the type parameters of the named type t.
  /// t must not have type arguments.
  fn SetTypeParams(self: Ref<Named>, tparams: Slice<Ref<TypeParam>>)

  /// SetUnderlying sets the underlying type and marks t as complete.
  /// t must not have type arguments.
  fn SetUnderlying(self: Ref<Named>, underlying: Type)

  fn String(self: Ref<Named>) -> string

  /// TypeArgs returns the type arguments used to instantiate the named type t.
  fn TypeArgs(self: Ref<Named>) -> Option<Ref<TypeList>>

  /// TypeParams returns the type parameters of the named type t, or nil.
  /// The result is non-nil for an (originally) generic type even if it is instantiated.
  fn TypeParams(self: Ref<Named>) -> Option<Ref<TypeParamList>>

  /// Underlying returns the [underlying type] of the named type t, resolving all
  /// forwarding declarations. Underlying types are never Named, TypeParam, or
  /// Alias types.
  /// 
  /// [underlying type]: https://go.dev/ref/spec#Underlying_types.
  fn Underlying(self: Ref<Named>) -> Type
}

impl Nil {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Nil>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Nil>) -> string

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Nil>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Nil>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<Nil>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Nil>) -> token.Pos

  fn String(self: Ref<Nil>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Nil>) -> Type
}

impl Package {
  /// A package is complete if its scope contains (at least) all
  /// exported objects; otherwise it is incomplete.
  fn Complete(self: Ref<Package>) -> bool

  /// GoVersion returns the minimum Go version required by this package.
  /// If the minimum version is unknown, GoVersion returns the empty string.
  /// Individual source files may specify a different minimum Go version,
  /// as reported in the [go/ast.File.GoVersion] field.
  fn GoVersion(self: Ref<Package>) -> string

  /// Imports returns the list of packages directly imported by
  /// pkg; the list is in source order.
  /// 
  /// If pkg was loaded from export data, Imports includes packages that
  /// provide package-level objects referenced by pkg. This may be more or
  /// less than the set of packages directly imported by pkg's source code.
  /// 
  /// If pkg uses cgo and the FakeImportC configuration option
  /// was enabled, the imports list may contain a fake "C" package.
  fn Imports(self: Ref<Package>) -> Slice<Ref<Package>>

  /// MarkComplete marks a package as complete.
  fn MarkComplete(self: Ref<Package>)

  /// Name returns the package name.
  fn Name(self: Ref<Package>) -> string

  /// Path returns the package path.
  fn Path(self: Ref<Package>) -> string

  /// Scope returns the (complete or incomplete) package scope
  /// holding the objects declared at package level (TypeNames,
  /// Consts, Vars, and Funcs).
  /// For a nil pkg receiver, Scope returns the Universe scope.
  fn Scope(self: Ref<Package>) -> Ref<Scope>

  /// SetImports sets the list of explicitly imported packages to list.
  /// It is the caller's responsibility to make sure list elements are unique.
  fn SetImports(self: Ref<Package>, list: Slice<Ref<Package>>)

  /// SetName sets the package name.
  fn SetName(self: Ref<Package>, name: string)

  fn String(self: Ref<Package>) -> string
}

impl PkgName {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<PkgName>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<PkgName>) -> string

  /// Imported returns the package that was imported.
  /// It is distinct from Pkg(), which is the package containing the import statement.
  fn Imported(self: Ref<PkgName>) -> Ref<Package>

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<PkgName>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<PkgName>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<PkgName>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<PkgName>) -> token.Pos

  fn String(self: Ref<PkgName>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<PkgName>) -> Type
}

impl Pointer {
  /// Elem returns the element type for the given pointer p.
  fn Elem(self: Ref<Pointer>) -> Type

  fn String(self: Ref<Pointer>) -> string

  fn Underlying(self: Ref<Pointer>) -> Type
}

impl Scope {
  /// Child returns the i'th child scope for 0 <= i < NumChildren().
  fn Child(self: Ref<Scope>, i: int) -> Ref<Scope>

  /// Children returns a go1.23 iterator over the child scopes nested within scope s.
  /// 
  /// Example: for child := range scope.Children() { ... }
  fn Children(self: Ref<Scope>) -> iter.Seq<Ref<Scope>>

  /// Contains reports whether pos is within the scope's extent.
  /// The result is guaranteed to be valid only if the type-checked
  /// AST has complete position information.
  fn Contains(self: Ref<Scope>, pos: token.Pos) -> bool

  fn End(self: Ref<Scope>) -> token.Pos

  /// Innermost returns the innermost (child) scope containing
  /// pos. If pos is not within any scope, the result is nil.
  /// The result is also nil for the Universe scope.
  /// The result is guaranteed to be valid only if the type-checked
  /// AST has complete position information.
  fn Innermost(self: Ref<Scope>, pos: token.Pos) -> Option<Ref<Scope>>

  /// Insert attempts to insert an object obj into scope s.
  /// If s already contains an alternative object alt with
  /// the same name, Insert leaves s unchanged and returns alt.
  /// Otherwise it inserts obj, sets the object's parent scope
  /// if not already set, and returns nil.
  fn Insert(self: Ref<Scope>, obj: Object) -> Option<Object>

  /// Len returns the number of scope elements.
  fn Len(self: Ref<Scope>) -> int

  /// Lookup returns the object in scope s with the given name if such an
  /// object exists; otherwise the result is nil.
  fn Lookup(self: Ref<Scope>, name: string) -> Option<Object>

  /// LookupParent follows the parent chain of scopes starting with s until
  /// it finds a scope where Lookup(name) returns a non-nil object, and then
  /// returns that scope and object. If a valid position pos is provided,
  /// only objects that were declared at or before pos are considered.
  /// If no such scope and object exists, the result is (nil, nil).
  /// The results are guaranteed to be valid only if the type-checked
  /// AST has complete position information.
  /// 
  /// Note that obj.Parent() may be different from the returned scope if the
  /// object was inserted into the scope and already had a parent at that
  /// time (see Insert). This can only happen for dot-imported objects
  /// whose parent is the scope of the package that exported them.
  fn LookupParent(self: Ref<Scope>, name: string, pos: token.Pos) -> (Ref<Scope>, Object)

  /// Names returns the scope's element names in sorted order.
  fn Names(self: Ref<Scope>) -> Slice<string>

  /// NumChildren returns the number of scopes nested in s.
  fn NumChildren(self: Ref<Scope>) -> int

  /// Parent returns the scope's containing (parent) scope.
  fn Parent(self: Ref<Scope>) -> Option<Ref<Scope>>

  /// Pos and End describe the scope's source code extent [pos, end).
  /// The results are guaranteed to be valid only if the type-checked
  /// AST has complete position information. The extent is undefined
  /// for Universe and package scopes.
  fn Pos(self: Ref<Scope>) -> token.Pos

  /// String returns a string representation of the scope, for debugging.
  fn String(self: Ref<Scope>) -> string

  /// WriteTo writes a string representation of the scope to w,
  /// with the scope elements sorted by name.
  /// The level of indentation is controlled by n >= 0, with
  /// n == 0 for no indentation.
  /// If recurse is set, it also writes nested (children) scopes.
  fn WriteTo(self: Ref<Scope>, w: io.Writer, n: int, recurse: bool)
}

impl Selection {
  /// Index describes the path from x to f in x.f.
  /// The last index entry is the field or method index of the type declaring f;
  /// either:
  /// 
  ///  1. the list of declared methods of a named type; or
  ///  2. the list of methods of an interface type; or
  ///  3. the list of fields of a struct type.
  /// 
  /// The earlier index entries are the indices of the embedded fields implicitly
  /// traversed to get from (the type of) x to f, starting at embedding depth 0.
  fn Index(self: Ref<Selection>) -> Slice<int>

  /// Indirect reports whether any pointer indirection was required to get from
  /// x to f in x.f.
  /// 
  /// Beware: Indirect spuriously returns true (Go issue #8353) for a
  /// MethodVal selection in which the receiver argument and parameter
  /// both have type *T so there is no indirection.
  /// Unfortunately, a fix is too risky.
  fn Indirect(self: Ref<Selection>) -> bool

  /// Kind returns the selection kind.
  fn Kind(self: Ref<Selection>) -> SelectionKind

  /// Obj returns the object denoted by x.f; a *Var for
  /// a field selection, and a *Func in all other cases.
  fn Obj(self: Ref<Selection>) -> Object

  /// Recv returns the type of x in x.f.
  fn Recv(self: Ref<Selection>) -> Type

  fn String(self: Ref<Selection>) -> string

  /// Type returns the type of x.f, which may be different from the type of f.
  /// See Selection for more information.
  fn Type(self: Ref<Selection>) -> Type
}

impl Signature {
  /// Params returns the parameters of signature s, or nil.
  fn Params(self: Ref<Signature>) -> Option<Ref<Tuple>>

  /// Recv returns the receiver of signature s (if a method), or nil if a
  /// function. It is ignored when comparing signatures for identity.
  /// 
  /// For an abstract method, Recv returns the enclosing interface either
  /// as a *[Named] or an *[Interface]. Due to embedding, an interface may
  /// contain methods whose receiver type is a different interface.
  fn Recv(self: Ref<Signature>) -> Option<Ref<Var>>

  /// RecvTypeParams returns the receiver type parameters of signature s, or nil.
  fn RecvTypeParams(self: Ref<Signature>) -> Option<Ref<TypeParamList>>

  /// Results returns the results of signature s, or nil.
  fn Results(self: Ref<Signature>) -> Option<Ref<Tuple>>

  fn String(self: Ref<Signature>) -> string

  /// TypeParams returns the type parameters of signature s, or nil.
  fn TypeParams(self: Ref<Signature>) -> Option<Ref<TypeParamList>>

  fn Underlying(self: Ref<Signature>) -> Type

  /// Variadic reports whether the signature s is variadic.
  fn Variadic(self: Ref<Signature>) -> bool
}

impl Slice {
  /// Elem returns the element type of slice s.
  fn Elem(self: Ref<Slice>) -> Type

  fn String(self: Ref<Slice>) -> string

  fn Underlying(self: Ref<Slice>) -> Type
}

impl StdSizes {
  fn Alignof(self: Ref<StdSizes>, t: Type) -> int64

  fn Offsetsof(self: Ref<StdSizes>, fields: Slice<Ref<Var>>) -> Slice<int64>

  fn Sizeof(self: Ref<StdSizes>, t: Type) -> int64
}

impl Struct {
  /// Field returns the i'th field for 0 <= i < NumFields().
  fn Field(self: Ref<Struct>, i: int) -> Ref<Var>

  /// Fields returns a go1.23 iterator over the fields of a struct type.
  /// 
  /// Example: for field := range s.Fields() { ... }
  fn Fields(self: Ref<Struct>) -> iter.Seq<Ref<Var>>

  /// NumFields returns the number of fields in the struct (including blank and embedded fields).
  fn NumFields(self: Ref<Struct>) -> int

  fn String(self: Ref<Struct>) -> string

  /// Tag returns the i'th field tag for 0 <= i < NumFields().
  fn Tag(self: Ref<Struct>, i: int) -> string

  fn Underlying(self: Ref<Struct>) -> Type
}

impl Term {
  fn String(self: Ref<Term>) -> string

  fn Tilde(self: Ref<Term>) -> bool

  fn Type(self: Ref<Term>) -> Type
}

impl Tuple {
  /// At returns the i'th variable of tuple t.
  fn At(self: Ref<Tuple>, i: int) -> Ref<Var>

  /// Len returns the number variables of tuple t.
  fn Len(self: Ref<Tuple>) -> int

  fn String(self: Ref<Tuple>) -> string

  fn Underlying(self: Ref<Tuple>) -> Type

  /// Variables returns a go1.23 iterator over the variables of a tuple type.
  /// 
  /// Example: for v := range tuple.Variables() { ... }
  fn Variables(self: Ref<Tuple>) -> iter.Seq<Ref<Var>>
}

impl TypeAndValue {
  /// Addressable reports whether the corresponding expression
  /// is addressable (https://golang.org/ref/spec#Address_operators).
  fn Addressable(self) -> bool

  /// Assignable reports whether the corresponding expression
  /// is assignable to (provided a value of the right type).
  fn Assignable(self) -> bool

  /// HasOk reports whether the corresponding expression may be
  /// used on the rhs of a comma-ok assignment.
  fn HasOk(self) -> bool

  /// IsBuiltin reports whether the corresponding expression denotes
  /// a (possibly parenthesized) built-in function.
  fn IsBuiltin(self) -> bool

  /// IsNil reports whether the corresponding expression denotes the
  /// predeclared value nil.
  fn IsNil(self) -> bool

  /// IsType reports whether the corresponding expression specifies a type.
  fn IsType(self) -> bool

  /// IsValue reports whether the corresponding expression is a value.
  /// Builtins are not considered values. Constant values have a non-
  /// nil Value.
  fn IsValue(self) -> bool

  /// IsVoid reports whether the corresponding expression
  /// is a function call without results.
  fn IsVoid(self) -> bool
}

impl TypeList {
  /// At returns the i'th type in the list.
  fn At(self: Ref<TypeList>, i: int) -> Type

  /// Len returns the number of types in the list.
  /// It is safe to call on a nil receiver.
  fn Len(self: Ref<TypeList>) -> int

  /// Types returns a go1.23 iterator over the elements of a list of types.
  /// 
  /// Example: for t := range l.Types() { ... }
  fn Types(self: Ref<TypeList>) -> iter.Seq<Type>
}

impl TypeName {
  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<TypeName>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<TypeName>) -> string

  /// IsAlias reports whether obj is an alias name for a type.
  fn IsAlias(self: Ref<TypeName>) -> bool

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<TypeName>) -> string

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<TypeName>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<TypeName>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<TypeName>) -> token.Pos

  fn String(self: Ref<TypeName>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<TypeName>) -> Type
}

impl TypeParam {
  /// Constraint returns the type constraint specified for t.
  fn Constraint(self: Ref<TypeParam>) -> Type

  /// Index returns the index of the type param within its param list, or -1 if
  /// the type parameter has not yet been bound to a type.
  fn Index(self: Ref<TypeParam>) -> int

  /// Obj returns the type name for the type parameter t.
  fn Obj(self: Ref<TypeParam>) -> Ref<TypeName>

  /// SetConstraint sets the type constraint for t.
  /// 
  /// It must be called by users of NewTypeParam after the bound's underlying is
  /// fully defined, and before using the type parameter in any way other than to
  /// form other types. Once SetConstraint returns the receiver, t is safe for
  /// concurrent use.
  fn SetConstraint(self: Ref<TypeParam>, bound: Type)

  fn String(self: Ref<TypeParam>) -> string

  /// Underlying returns the [underlying type] of the type parameter t, which is
  /// the underlying type of its constraint. This type is always an interface.
  /// 
  /// [underlying type]: https://go.dev/ref/spec#Underlying_types.
  fn Underlying(self: Ref<TypeParam>) -> Type
}

impl TypeParamList {
  /// At returns the i'th type parameter in the list.
  fn At(self: Ref<TypeParamList>, i: int) -> Ref<TypeParam>

  /// Len returns the number of type parameters in the list.
  /// It is safe to call on a nil receiver.
  fn Len(self: Ref<TypeParamList>) -> int

  /// TypeParams returns a go1.23 iterator over a list of type parameters.
  /// 
  /// Example: for tparam := range l.TypeParams() { ... }
  fn TypeParams(self: Ref<TypeParamList>) -> iter.Seq<Ref<TypeParam>>
}

impl Union {
  fn Len(self: Ref<Union>) -> int

  fn String(self: Ref<Union>) -> string

  fn Term(self: Ref<Union>, i: int) -> Ref<Term>

  /// Terms returns a go1.23 iterator over the terms of a union.
  /// 
  /// Example: for term := range union.Terms() { ... }
  fn Terms(self: Ref<Union>) -> iter.Seq<Ref<Term>>

  fn Underlying(self: Ref<Union>) -> Type
}

impl Var {
  /// Anonymous reports whether the variable is an embedded field.
  /// Same as Embedded; only present for backward-compatibility.
  fn Anonymous(self: Ref<Var>) -> bool

  /// Embedded reports whether the variable is an embedded field.
  fn Embedded(self: Ref<Var>) -> bool

  /// Exported reports whether the object is exported (starts with a capital letter).
  /// It doesn't take into account whether the object is in a local (function) scope
  /// or not.
  fn Exported(self: Ref<Var>) -> bool

  /// Id is a wrapper for Id(obj.Pkg(), obj.Name()).
  fn Id(self: Ref<Var>) -> string

  /// IsField reports whether the variable is a struct field.
  fn IsField(self: Ref<Var>) -> bool

  /// Kind reports what kind of variable v is.
  fn Kind(self: Ref<Var>) -> VarKind

  /// Name returns the object's (package-local, unqualified) name.
  fn Name(self: Ref<Var>) -> string

  /// Origin returns the canonical Var for its receiver, i.e. the Var object
  /// recorded in Info.Defs.
  /// 
  /// For synthetic Vars created during instantiation (such as struct fields or
  /// function parameters that depend on type arguments), this will be the
  /// corresponding Var on the generic (uninstantiated) type. For all other Vars
  /// Origin returns the receiver.
  fn Origin(self: Ref<Var>) -> Ref<Var>

  /// Parent returns the scope in which the object is declared.
  /// The result is nil for methods and struct fields.
  fn Parent(self: Ref<Var>) -> Option<Ref<Scope>>

  /// Pkg returns the package to which the object belongs.
  /// The result is nil for labels and objects in the Universe scope.
  fn Pkg(self: Ref<Var>) -> Option<Ref<Package>>

  /// Pos returns the declaration position of the object's identifier.
  fn Pos(self: Ref<Var>) -> token.Pos

  /// SetKind sets the kind of the variable.
  /// It should be used only immediately after [NewVar] or [NewParam].
  fn SetKind(self: Ref<Var>, kind: VarKind)

  fn String(self: Ref<Var>) -> string

  /// Type returns the object's type.
  fn Type(self: Ref<Var>) -> Type
}

impl VarKind {
  fn String(self) -> string
}
