Documentation Index
Fetch the complete documentation index at: https://mintlify.com/golang/go/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The go/types package implements type-checking for Go packages. It provides the algorithms and data structures for analyzing Go code beyond just parsing - including name resolution, type inference, constant evaluation, and semantic validation.
Key capabilities:
- Type checking Go source code
- Name resolution (mapping identifiers to declarations)
- Constant folding and evaluation
- Type inference
- Method set computation
- Interface satisfaction checking
Core Types
Config
Specifies the configuration for type checking.
type Config struct {
Context *Context
GoVersion string
IgnoreFuncBodies bool
FakeImportC bool
// Error handling
Error func(err error)
// Import resolution
Importer ImporterFrom
// Size calculation
Sizes Sizes
}
Common configuration:
conf := &types.Config{
Importer: importer.Default(),
Error: func(err error) {
fmt.Println("Type error:", err)
},
}
Package
Represents a type-checked Go package.
type Package struct {
// Read-only fields
}
func (pkg *Package) Path() string
func (pkg *Package) Name() string
func (pkg *Package) Scope() *Scope
func (pkg *Package) Imports() []*Package
func (pkg *Package) Complete() bool
Info
Stores type-checking results.
type Info struct {
Types map[ast.Expr]TypeAndValue // type info for expressions
Instances map[*ast.Ident]Instance // generic instantiations
Defs map[*ast.Ident]Object // identifier definitions
Uses map[*ast.Ident]Object // identifier uses
Implicits map[ast.Node]Object // implicit objects
Selections map[*ast.SelectorExpr]*Selection
Scopes map[ast.Node]*Scope // lexical scopes
InitOrder []*Initializer // initialization order
FileVersions map[*ast.File]string // Go version per file
}
Example:
info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
}
Type Checking
Check Function
Type-checks a package.
func (conf *Config) Check(
path string,
fset *token.FileSet,
files []*ast.File,
info *Info,
) (*Package, error)
Example:
package main
import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"log"
)
func main() {
src := `package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}`
// Parse the source
fset := token.NewFileSet()
file, err := parser.ParseFile(fset, "hello.go", src, 0)
if err != nil {
log.Fatal(err)
}
// Type-check the package
conf := types.Config{Importer: importer.Default()}
info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
}
pkg, err := conf.Check("main", fset, []*ast.File{file}, info)
if err != nil {
log.Fatal(err)
}
println("Package:", pkg.Name())
}
Type Interface
The fundamental type interface.
type Type interface {
Underlying() Type
String() string
}
Concrete Type Implementations
Basic - Basic types (int, string, bool, etc.)
type Basic struct {
Kind BasicKind
Info BasicInfo
Name string
}
Named - Named types (type declarations)
type Named struct { /* ... */ }
func (n *Named) Obj() *TypeName
func (n *Named) NumMethods() int
func (n *Named) Method(i int) *Func
Pointer - Pointer types
type Pointer struct { /* ... */ }
func NewPointer(elem Type) *Pointer
func (p *Pointer) Elem() Type
Slice - Slice types
type Slice struct { /* ... */ }
func NewSlice(elem Type) *Slice
func (s *Slice) Elem() Type
Array - Array types
type Array struct { /* ... */ }
func NewArray(elem Type, len int64) *Array
func (a *Array) Len() int64
func (a *Array) Elem() Type
Map - Map types
type Map struct { /* ... */ }
func NewMap(key, elem Type) *Map
func (m *Map) Key() Type
func (m *Map) Elem() Type
Chan - Channel types
type Chan struct { /* ... */ }
func NewChan(dir ChanDir, elem Type) *Chan
func (c *Chan) Dir() ChanDir
func (c *Chan) Elem() Type
Struct - Struct types
type Struct struct { /* ... */ }
func NewStruct(fields []*Var, tags []string) *Struct
func (s *Struct) NumFields() int
func (s *Struct) Field(i int) *Var
func (s *Struct) Tag(i int) string
Interface - Interface types
type Interface struct { /* ... */ }
func NewInterface(methods []*Func, embeddeds []Type) *Interface
func (i *Interface) NumMethods() int
func (i *Interface) Method(i int) *Func
func (i *Interface) Empty() bool
Signature - Function types
type Signature struct { /* ... */ }
func NewSignature(recv *Var, params, results *Tuple, variadic bool) *Signature
func (s *Signature) Recv() *Var
func (s *Signature) Params() *Tuple
func (s *Signature) Results() *Tuple
func (s *Signature) Variadic() bool
Object Types
Objects represent declared entities.
type Object interface {
Parent() *Scope
Pos() token.Pos
Pkg() *Package
Name() string
Type() Type
Exported() bool
}
Concrete object types:
*Const - Constant
*Var - Variable (including parameters, results, struct fields)
*Func - Function or method
*TypeName - Type name
*Label - Statement label
*PkgName - Imported package
*Builtin - Built-in function
*Nil - Predeclared nil
Scope
Represents a lexical scope.
type Scope struct { /* ... */ }
func (s *Scope) Parent() *Scope
func (s *Scope) NumChildren() int
func (s *Scope) Child(i int) *Scope
func (s *Scope) Lookup(name string) Object
func (s *Scope) Insert(obj Object) Object
func (s *Scope) Pos() token.Pos
func (s *Scope) End() token.Pos
Example:
pkg, _ := conf.Check("example", fset, files, nil)
scope := pkg.Scope()
// Look up a name
obj := scope.Lookup("MyFunc")
if obj != nil {
fmt.Printf("Found: %s of type %s\n", obj.Name(), obj.Type())
}
Type Checking Examples
Basic Type Checking
package main
import (
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"fmt"
)
func main() {
src := `package main
type Celsius float64
func FToC(f float64) Celsius {
return Celsius(f - 32) * 5 / 9
}`
fset := token.NewFileSet()
file, _ := parser.ParseFile(fset, "temp.go", src, 0)
conf := types.Config{Importer: importer.Default()}
pkg, err := conf.Check("temperature", fset, []*ast.File{file}, nil)
if err != nil {
fmt.Println("Type error:", err)
return
}
// Look up the FToC function
obj := pkg.Scope().Lookup("FToC")
fmt.Printf("%s: %s\n", obj.Name(), obj.Type())
// Output: FToC: func(f float64) temperature.Celsius
}
Analyzing Expressions
func analyzeExpressions(src string) {
fset := token.NewFileSet()
file, _ := parser.ParseFile(fset, "", src, 0)
info := &types.Info{
Types: make(map[ast.Expr]types.TypeAndValue),
}
conf := types.Config{Importer: importer.Default()}
conf.Check("", fset, []*ast.File{file}, info)
// Print type of each expression
for expr, tv := range info.Types {
pos := fset.Position(expr.Pos())
fmt.Printf("%s: %s\n", pos, tv.Type)
}
}
Finding Definitions and Uses
func findReferences(src string, name string) {
fset := token.NewFileSet()
file, _ := parser.ParseFile(fset, "", src, 0)
info := &types.Info{
Defs: make(map[*ast.Ident]types.Object),
Uses: make(map[*ast.Ident]types.Object),
}
conf := types.Config{}
conf.Check("", fset, []*ast.File{file}, info)
// Find definition
for ident, obj := range info.Defs {
if obj != nil && obj.Name() == name {
pos := fset.Position(ident.Pos())
fmt.Printf("Defined at %s\n", pos)
}
}
// Find uses
for ident, obj := range info.Uses {
if obj != nil && obj.Name() == name {
pos := fset.Position(ident.Pos())
fmt.Printf("Used at %s\n", pos)
}
}
}
Method Sets
MethodSet
Computes the method set of a type.
func NewMethodSet(T Type) *MethodSet
type MethodSet struct { /* ... */ }
func (s *MethodSet) Len() int
func (s *MethodSet) At(i int) *Selection
func (s *MethodSet) Lookup(pkg *Package, name string) *Selection
Example:
package main
import (
"go/importer"
"go/parser"
"go/token"
"go/types"
"fmt"
)
func main() {
src := `package main
type Celsius float64
func (c Celsius) String() string {
return fmt.Sprintf("%g°C", c)
}
func (c *Celsius) Set(f float64) {
*c = Celsius(f-32) * 5 / 9
}`
fset := token.NewFileSet()
file, _ := parser.ParseFile(fset, "", src, 0)
conf := types.Config{Importer: importer.Default()}
pkg, _ := conf.Check("main", fset, []*ast.File{file}, nil)
celsius := pkg.Scope().Lookup("Celsius").Type()
// Method set of Celsius (value)
fmt.Println("Methods of Celsius:")
mset := types.NewMethodSet(celsius)
for i := 0; i < mset.Len(); i++ {
fmt.Printf(" %s\n", mset.At(i))
}
// Method set of *Celsius (pointer)
fmt.Println("Methods of *Celsius:")
ptrCelsius := types.NewPointer(celsius)
mset = types.NewMethodSet(ptrCelsius)
for i := 0; i < mset.Len(); i++ {
fmt.Printf(" %s\n", mset.At(i))
}
}
// Output:
// Methods of Celsius:
// method (Celsius) String() string
// Methods of *Celsius:
// method (*Celsius) Set(f float64)
// method (*Celsius) String() string
Type Predicates
Utility functions for checking type properties.
// Identity comparisons
func Identical(x, y Type) bool
func IdenticalIgnoreTags(x, y Type) bool
// Assignability
func AssignableTo(V, T Type) bool
func ConvertibleTo(V, T Type) bool
// Interface implementation
func Implements(V Type, T *Interface) bool
func Satisfies(V Type, T *Interface) bool
// Comparability
func Comparable(T Type) bool
Example:
// Check if type implements interface
if types.Implements(myType, ioWriterInterface) {
fmt.Println("Type implements io.Writer")
}
// Check assignability
if types.AssignableTo(srcType, dstType) {
fmt.Println("Can assign src to dst")
}
Sizes Interface
Calculates size and alignment of types.
type Sizes interface {
Alignof(T Type) int64
Offsetsof(fields []*Var) []int64
Sizeof(T Type) int64
}
// Standard sizes for common architectures
func SizesFor(compiler, arch string) Sizes
Example:
sizes := types.SizesFor("gc", "amd64")
size := sizes.Sizeof(myType)
align := sizes.Alignof(myType)
fmt.Printf("Size: %d bytes, Alignment: %d\n", size, align)
Error Handling
conf := types.Config{
Error: func(err error) {
// Custom error handling
if typeErr, ok := err.(types.Error); ok {
fmt.Printf("%s: %s\n",
typeErr.Fset.Position(typeErr.Pos),
typeErr.Msg)
}
},
}
go/ast - Abstract syntax tree representation
go/parser - Parse Go source into AST
go/token - Token and position definitions
go/constant - Constant values and operations
go/importer - Package import mechanisms
golang.org/x/tools/go/types/typeutil - Type utilities
golang.org/x/tools/go/packages - High-level package loading and type checking