gotypes: a tutorial on go/types, the Go type checker

Better late than never.

Change-Id: Iedd3aaa9dc3eb40b79b7430ed2d69e2d4f87dc86
Reviewed-on: https://go-review.googlesource.com/17388
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/gotypes/Makefile b/gotypes/Makefile
new file mode 100644
index 0000000..b7eb3d9
--- /dev/null
+++ b/gotypes/Makefile
@@ -0,0 +1,12 @@
+
+all: README.md
+
+README.md: go-types.md weave.go $(wildcard */*.go)
+	go run weave.go go-types.md >README.md
+
+# This is for previewing using github.
+# $HOME/markdown must be a github client.
+test: README.md
+	cp README.md $$HOME/markdown/
+	(cd $$HOME/markdown/ && git commit -m . README.md && git push)
+
diff --git a/gotypes/README.md b/gotypes/README.md
new file mode 100644
index 0000000..d551420
--- /dev/null
+++ b/gotypes/README.md
@@ -0,0 +1,2530 @@
+<!-- Autogenerated by weave; DO NOT EDIT -->
+
+# `go/types`: The Go Type Checker
+
+This document is maintained by Alan Donovan `adonovan@google.com`.
+
+[October 2015 GothamGo talk on go/types](https://docs.google.com/presentation/d/13OvHYozAUBeISPRoLgG7kMBuja1NsU1D_mMlmbaYojk/view)
+
+
+# Contents
+
+1. [Introduction](#introduction)
+1. [An Example](#an-example)
+1. [Objects](#objects)
+1. [Identifier Resolution](#identifier-resolution)
+1. [Scopes](#scopes)
+1. [Initialization Order](#initialization-order)
+1. [Types](#types)
+	1. [Basic types](#basic-types)
+	1. [Simple Composite Types](#simple-composite-types)
+	1. [Struct Types](#struct-types)
+	1. [Tuple Types](#tuple-types)
+	1. [Function and Method Types](#function-and-method-types)
+	1. [Named Types](#named-types)
+	1. [Interface Types](#interface-types)
+	1. [TypeAndValue](#typeandvalue)
+1. [Selections](#selections)
+1. [Ids](#ids)
+1. [Method Sets](#method-sets)
+1. [Constants](#constants)
+1. [Size and Alignment](#size-and-alignment)
+1. [Imports](#imports)
+1. [Formatting support](#formatting-support)
+1. [Getting from A to B](#getting-from-a-to-b)
+
+# Introduction
+
+
+The [`go/types` package]('https://golang.org/pkg/go/types) is a
+type-checker for Go programs, designed by Robert Griesemer.
+Measured by lines of code and by API surface area, it is one of the
+most complex packages in Go's standard library, and using it requires
+a firm grasp of the structure of Go programs.
+This tutorial will help you find your bearings.
+It comes with several example programs that you can obtain with `go get` and play with.
+We assume you are a proficient Go programmer who wants to build tools
+to analyze or manipulate Go programs and that you have some knowledge
+of how a typical compiler works.
+
+
+
+The `go/types` package became part of Go's standard library in Go 1.5.
+Prior to that, it was located at
+[`golang.org/x/tools/go/types`](https://godoc.org/golang.org/x/tools/go/types),
+though that package will be deleted one month after the release
+of Go 1.6 in early 2016.
+
+
+
+The type checker complements several existing
+standard packages for analyzing Go programs.
+We've listed them below.
+
+
+	→   go/types
+	    go/constant
+	    go/parser
+	    go/ast
+	    go/scanner
+	    go/token
+
+
+Starting at the bottom, the
+[`go/token` package](http://golang.org/pkg/go/token)
+defines the lexical tokens of Go.
+The [`go/scanner` package](http://golang.org/pkg/go/scanner) tokenizes an input stream and records
+file position information for use in diagnostics
+or for file surgery in a refactoring tool.
+The [`go/ast` package](http://golang.org/pkg/go/ast)
+defines the data types of the abstract syntax tree (AST).
+The [`go/parser` package](http://golang.org/pkg/go/parser)
+provides a robust recursive-descent parser that constructs the AST.
+And [`go/constant`](http://golang.org/pkg/go/constant)
+provides representations and arithmetic operations for the values of compile-time
+constant expressions, as we'll see in
+[Constants](#constants).
+
+
+
+The [`golang.org/x/tools/go/loader` package](https://godoc.org/golang.org/x/tools/go/loader)
+from the `x/tools` repository is a client of the type
+checker that loads, parses, and type-checks a complete Go program from
+source code.
+We use it in some of our examples and you may find it useful too.
+(Please note that until March 2016, the
+`golang.org/x/tools/...` packages will continue to depend on the
+old `golang.org/x/tools/go/types` package, not on the
+new standard `go/types` package.  The two are almost identical.)
+
+
+
+The Go type checker does three main things.
+First, for every name in the program, it determines which declaration
+the name refers to; this is known as _identifier resolution_.
+Second, for every expression in the program, it determines what type
+that expression has, or reports an error if the expression has no
+type, or has an inappropriate type for its context; this is known as
+_type deduction_.
+Third, for every constant expression in the program, it determines the
+value of that constant; this is known as _constant evaluation_.
+
+
+
+Superficially, it appears that these three processes could be done
+sequentially, in the order above, but perhaps surprisingly, they must
+be done together.
+For example, the value of a constant may depend on the type of an
+expression due to operators like `unsafe.Sizeof`.
+Conversely, the type of an expression may depend on the value of a
+constant, since array types contain constants.
+As a result, type deduction and constant evaluation must be done
+together.
+
+
+
+As another example, we cannot resolve the identifier `k` in the composite
+literal `T{k: 0}` until we know whether `T` is a struct type.
+If it is, then `k` must be found among `T`'s fields.
+If not, then `k` is an ordinary reference
+to a constant or variable in the lexical environment.
+Consequently, identifier resolution and type deduction are also
+inseparable in the general case.
+
+
+
+Nonetheless, the three processes of identifier resolution, type
+deduction, and constant evaluation can be separated for the purpose of
+explanation.
+
+
+# An Example
+
+
+The code below shows the most basic use of the type checker to check
+the _hello, world_ program, supplied as a string.
+Later examples will be variations on this one, and we'll often omit
+boilerplate details such as parsing.
+To check out and build the examples,
+run `go get github.com/golang/example/gotypes/...`.
+
+
+	// go get github.com/golang/example/gotypes/pkginfo
+
+```
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+const hello = `package main
+
+import "fmt"
+
+func main() {
+        fmt.Println("Hello, world")
+}`
+
+func main() {
+	fset := token.NewFileSet()
+
+	// Parse the input string, []byte, or io.Reader,
+	// recording position information in fset.
+	// ParseFile returns an *ast.File, a syntax tree.
+	f, err := parser.ParseFile(fset, "hello.go", hello, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+
+	// A Config controls various options of the type checker.
+	// The defaults work fine except for one setting:
+	// we must specify how to deal with imports.
+	conf := types.Config{Importer: importer.Default()}
+
+	// Type-check the package containing only file f.
+	// Check returns a *types.Package.
+	pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err) // type error
+	}
+
+	fmt.Printf("Package  %q\n", pkg.Path())
+	fmt.Printf("Name:    %s\n", pkg.Name())
+	fmt.Printf("Imports: %s\n", pkg.Imports())
+	fmt.Printf("Scope:   %s\n", pkg.Scope())
+}
+```
+
+
+First, the program creates a
+[`token.FileSet`](http://golang.org/pkg/go/token/#FileSet).
+To avoid the need to store file names and line and column
+numbers in every node of the syntax tree, the `go/token` package
+provides `FileSet`, a data structure that stores this information
+compactly for a sequence of files.
+A `FileSet` records each file name only once, and records
+only the byte offsets of each newline, allowing a position within
+any file to be identified using a small integer called a
+`token.Pos`.
+Many tools create a single `FileSet` at startup.
+Any part of the program that needs to convert a `token.Pos` into
+an intelligible location---as part of an error message, for
+instance---must have access to the `FileSet`.
+
+
+
+Second, the program parses the input string.
+More realistic packages contain several source files, so the parsing
+step must be repeated for each one, or better still, done in parallel.
+Third, it creates a `Config` that specifies type-checking options.
+Since the _hello, world_ program uses imports, we must indicate
+how to locate the imported packages.
+Here we use `importer.Default()`, which loads compiler-generated
+export data, but we'll explore alternatives in [Imports](#imports).
+
+	
+
+Fourth, the program calls `Check`.
+This creates a `Package` whose path is `"cmd/hello"`, and
+type-checks each of the specified files---just one in this example.
+The final (nil) argument is a pointer to an optional `Info`
+struct that returns additional deductions from the type checker; more
+on that later.
+`Check` returns a `Package` even when it also returns an error.
+The type checker is robust to ill-formed input,
+and goes to great lengths to report accurate
+partial information even in the vicinity of syntax or type errors.
+`Package` has this definition:
+
+
+	type Package struct{ ... }
+	func (*Package) Path() string
+	func (*Package) Name() string
+	func (*Package) Scope() *Scope
+	func (*Package) Imports() []*Package
+
+
+Finally, the program prints the attributes of the package, shown below.
+(The hexadecimal number may vary from one run to the next.)
+
+
+```
+$ go build github.com/golang/example/gotypes/pkginfo
+$ ./pkginfo
+Package  "cmd/hello"
+Name:    main
+Imports: [package fmt ("fmt")]
+Scope:   package "cmd/hello" scope 0x820533590 {
+.  func cmd/hello.main()
+}
+```
+
+
+A package's `Path`, such as `"encoding/json"`, is the string
+by which import declarations identify it.
+It is unique within a `$GOPATH` workspace,
+and for published packages it must be globally unique.
+
+
+A package's `Name` is the identifier in the `package`
+declaration of each source file within the package, such as `json`.
+The type checker reports an error if not all the package declarations in
+the package agree.
+The package name determines how the package is known when it is
+imported into a file (unless a renaming import is used),
+but is otherwise not visible to a program.
+
+
+`Scope` returns the package's [_lexical block_](#scopes),
+which provides access to all the named entities or
+[_objects_](#objects) declared at package level.
+`Imports` returns the set of packages directly imported by this
+one, and  may be useful for computing dependencies
+([Initialization Order](#initialization_order)).
+
+
+
+# Objects
+
+
+The task of identifier resolution is to map every identifier in the
+syntax tree, that is, every `ast.Ident`, to an object.
+For our purposes, an _object_ is a named entity created by a
+declaration, such as a `var`, `type`, or `func`
+declaration.
+(This is different from the everyday meaning of object in
+object-oriented programming.)
+
+
+
+Objects are represented by the `Object` interface, shown below:
+
+
+	type Object interface {
+	    Name() string   // package local object name
+	    Exported() bool // reports whether the name starts with a capital letter
+	    Type() Type     // object type
+	    Pos() token.Pos // position of object identifier in declaration
+	
+	    Parent() *Scope // scope in which this object is declared
+	    Pkg() *Package  // nil for objects in the Universe scope and labels
+	    Id() string     // object id (see Ids section below)
+	}
+
+
+The first four methods are straightforward; we'll explain the other
+three later.
+`Name` returns the objects's name---an identifier.
+`Exported` is a convenience method that reports whether the first
+letter of `Name` is a capital, indicating that the object may be
+visible from outside the package.
+It's a shorthand for `ast.IsExported(obj.Name())`.
+`Type` returns the object's type; we'll come back to that in
+[Types](#types).
+
+
+
+`Pos` returns the source position of the object's declaring identifier.
+To make sense of a `token.Pos`, we need to call the
+`(*token.FileSet).Position` method, which returns a struct with
+individual fields for the file name, line number, column, and byte
+offset, though usually we just call its `String` method:
+
+
+	fmt.Fprintln(fset.Position(obj.Pos())) // "hello.go:10:6"
+
+
+Not all objects carry position information.
+Since the file format for compiler export data ([Imports](#imports))
+does not record position information, calling `Pos` on an object
+imported from such a file returns zero, also known as
+`token.NoPos`.
+
+
+
+There are eight kinds of objects in the Go type checker.
+Most familiar are the kinds that can be declared at package level:
+constants, variables, functions, and types.
+Less familiar are statement labels, imported package names
+(such as `json` in a file containing an `import "encoding/json"`
+declaration), built-in functions (such as `append` and
+`len`), and the pre-declared `nil`.
+The eight types shown below are the only concrete types that satisfy
+the `Object` interface.
+In other words, `Object` is a _discriminated union_ of 8
+possible types, and we commonly use a type switch to distinguish them.
+
+
+	Object = *Func         // function, concrete method, or abstract method
+	       | *Var          // variable, parameter, result, or struct field
+	       | *Const        // constant
+	       | *TypeName     // named type (except for predeclared ones)
+	       | *Label        // statement label
+	       | *PkgName      // package name, e.g. json after import "encoding/json"
+	       | *Builtin      // predeclared function such as append or len
+	       | *Nil          // predeclared nil
+
+
+`Object`s are canonical.
+That is, two `Object`s `x` and `y` denote the same
+entity if and only if `x==y`.
+Object identity is significant, and objects are routinely compared by
+the addresses of the underlying pointers.
+Although a package-level object is uniquely identified by its name
+and enclosing package, for other objects there is no simple way to
+obtain a string that uniquely identifies it.
+
+
+
+The `Parent` method returns the `Scope` (lexical block) in
+which the object was declared; we'll come back to this in
+[Scopes](#scopes).
+Fields and methods are not found in the lexical environment, so
+their objects have no `Parent`.
+
+
+
+The `Pkg` method returns the `Package` to which this object
+belongs, even for objects not declared at package level.
+Only predeclared objects have no package.
+The `Id` method will be explained in [Ids](#ids).
+
+
+
+Not all methods make sense for each kind of object.  For instance,
+the last four kinds above have no meaningful `Type` method.
+And some kinds of object have methods in addition to those required by the
+`Object` interface:
+
+
+	func (*Func) Scope() *Scope
+	func (*Var) Anonymous() bool
+	func (*Var) IsField() bool
+	func (*Const) Val() constant.Value
+	func (*PkgName) Imported() *Package
+
+
+`(*Func).Scope` returns the [lexical block](#scopes)
+containing the function's parameters, results,
+and other local declarations.
+`(*Var).IsField` distinguishes struct fields from ordinary
+variables, and `(*Var).Anonymous` discriminates named fields like
+the one in `struct{T T}` from anonymous fields like the one in `struct{T}`.
+`(*Const).Val` returns the value of a named [constant](#constants).
+
+
+
+`(*PkgName).Imported` returns the package (for instance,
+`encoding/json`) denoted by a given import name such as `json`.
+Each time a package is imported, a new `PkgName` object is
+created, usually with the same name as the `Package` it
+denotes, but not always, as in the case of a renaming import.
+`PkgName`s are objects, but `Package`s are not.
+We'll look more closely at this in [Imports](#imports).
+
+
+
+All relationships between the syntax trees (`ast.Node`s) and type
+checker data structures such as `Object`s and `Type`s are
+stored in mappings outside the syntax tree itself.
+Be aware that the `go/ast` package also defines a type called
+`Object` that resembles---and predates---the type checker's
+`Object`, and that `ast.Object`s are held directly by
+identifiers in the AST.
+They are created by the parser, which has a necessarily limited view
+of the package, so the information they represent is at best partial and
+in some cases wrong, as in the `T{k: 0}` example mentioned above.
+If you are using the type checker, there is no reason to use the older
+`ast.Object` mechanism.
+
+
+
+# Identifier Resolution
+
+
+Identifier resolution computes the relationship between
+identifiers and objects.
+Its results are recorded in the `Info` struct optionally passed
+to `Check`.
+The fields related to identifier resolution are shown below.
+
+
+	type Info struct {
+		Defs       map[*ast.Ident]Object
+		Uses       map[*ast.Ident]Object
+		Implicits  map[ast.Node]Object
+		Selections map[*ast.SelectorExpr]*Selection
+		Scopes     map[ast.Node]*Scope
+		...
+	}
+
+
+Since not all facts computed by the type checker are needed by every
+client, the API lets clients control which components of the result
+should be recorded and which discarded: only fields that hold a
+non-nil map will be populated during the call to `Check`.
+
+
+
+The two fields of type `map[*ast.Ident]Object` are the most important:
+`Defs` records _declaring_ identifiers and
+`Uses` records _referring_ identifiers.
+In the example below, the comments indicate which identifiers are of
+which kind.
+
+
+	var x int        // def of x, use of int
+	fmt.Println(x)   // uses of fmt, Println, and x
+	type T struct{U} // def of T, use of U (type), def of U (field)
+
+
+The final line above illustrates why we don't combine `Defs` and
+`Uses` into one map.
+In the anonymous field declaration `struct{U}`, the
+identifier `U` is both a use of the type `U` (a
+`TypeName`) and a definition of the anonymous field (a
+`Var`).
+
+
+
+The function below prints the location of each referring and defining
+identifier in the input program, and the object it refers to.
+
+
+	// go get github.com/golang/example/gotypes/defsuses
+
+```
+func PrintDefsUses(fset *token.FileSet, files ...*ast.File) error {
+	conf := types.Config{Importer: importer.Default()}
+	info := &types.Info{
+		Defs: make(map[*ast.Ident]types.Object),
+		Uses: make(map[*ast.Ident]types.Object),
+	}
+	_, err := conf.Check("hello", fset, files, info)
+	if err != nil {
+		return err // type error
+	}
+
+	for id, obj := range info.Defs {
+		fmt.Printf("%s: %q defines %v\n",
+			fset.Position(id.Pos()), id.Name, obj)
+	}
+	for id, obj := range info.Uses {
+		fmt.Printf("%s: %q uses %v\n",
+			fset.Position(id.Pos()), id.Name, obj)
+	}
+	return nil
+}
+```
+
+
+Let's use the _hello, world_ program again as the input:
+
+
+	// go get github.com/golang/example/gotypes/hello
+
+```
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("Hello, 世界")
+}
+```
+
+
+This is what it prints:
+
+
+```
+$ go build github.com/golang/example/gotypes/defsuses
+$ ./defsuses
+hello.go:1:9: "main" defines <nil>
+hello.go:5:6: "main" defines func hello.main()
+hello.go:6:9: "fmt" uses package fmt
+hello.go:6:13: "Println" uses func fmt.Println(a ...interface{}) (n int, err error)
+```
+
+
+Notice that the `Defs` mapping may contain nil entries in a few
+cases.
+The first line of output reports that the package identifier
+`main` is present in the `Defs` mapping, but has no
+associated object.
+
+
+
+The `Implicits` mapping handles two cases of the syntax in
+which an `Object` is declared without an `ast.Ident`, namely type
+switches and import declarations.
+<!--
+A third case: an anonymous function parameter or result variable.
+These objects are returned by Signature.Param and Signature.Result.
+-->
+In the type switch below, which declares a local variable `y`,
+the type of `y` is different in each case of the switch:
+
+
+	switch y := x.(type) {
+	case int:
+		fmt.Printf("%d", y)
+	case string:
+		fmt.Printf("%q", y)
+	default:
+		fmt.Print(y)
+	}
+
+
+To represent this, for each single-type case, the type checker creates
+a separate `Var` object for `y` with the appropriate type,
+and `Implicits` maps each `ast.CaseClause` to the `Var`
+for that case.
+The `default` case, the `nil` case, and cases with more than one
+type all use the regular `Var` object that is associated with the
+identifier `y`, which is found in the `Defs` mapping.
+
+
+
+The import declaration below defines the name `json` without an
+`ast.Ident`:
+
+
+	import "encoding/json"
+
+
+`Implicits` maps this `ast.ImportSpec` to the `PkgName`
+object named `json` that it implicitly declares.
+
+
+
+The `Selections` mapping, of type
+`map[*ast.SelectorExpr]*Selection`, records the meaning of each
+expression of the form _`expr`_`.f`, where _`expr`_ is
+an expression or type and `f` is the name of a field or method.
+These expressions, called _selections_, are represented by
+`ast.SelectorExpr` nodes in the AST.
+We'll talk more about the `Selection` type in [Selections](#selections).
+
+
+
+Not all `ast.SelectorExpr` nodes represent selections.
+Expressions like `fmt.Println`, in which a package name precedes
+the dot, are _qualified identifiers_.
+They do not appear in the `Selections` mapping, but their
+constituent identifiers (such as `fmt` and `Println`) both
+appear in `Uses`.
+
+
+
+Referring identifiers that are not part of an `ast.SelectorExpr`
+are _lexical references_.
+That is, they are resolved to an object by searching for the
+innermost enclosing lexical declaration of that name.
+We'll see how that search works in the next section.
+
+
+# Scopes
+
+
+The `Scope` type is a mapping from names to objects.
+
+
+	type Scope struct{ ... }
+	
+	func (s *Scope) Names() []string
+	func (s *Scope) Lookup(name string) Object
+
+
+`Names` returns the set of names in the mapping, in sorted order.
+(It is not a simple accessor though, so call it sparingly.)
+The `Lookup ` method returns the object for a given name, so we
+can print all the entries or _bindings_ in a scope like this:
+
+
+	for _, name := range scope.Names() {
+		fmt.Println(scope.Lookup(name))
+	}
+
+
+The _scope_ of a declaration of a name is the region of
+program source in which a reference to the name resolves to that
+declaration.  That is, scope is a property of a declaration.
+However, in the `go/types` API, the `Scope` type represents
+a _lexical block_, which is one component of the lexical
+environment.
+Consider the _hello, world_ program again:
+
+
+	package main
+	
+	import "fmt"
+	
+	func main() {
+		const message = "hello, world"
+		fmt.Println(message)
+	}
+
+
+There are four lexical blocks in this program.
+The outermost one is the _universe block_, which maps the
+pre-declared names like `int`, `true`, and `append` to
+their objects---a `TypeName`, a `Const`, and a
+`Builtin`, respectively.
+The universe block is represented by the global variable
+`Universe`, of type `*Scope`, although it's logically a
+constant so you shouldn't modify it.
+
+
+
+Next is the _package block_, which maps `"main"` to the
+`main` function.
+Following that is the _file block_, which maps `"fmt"` to
+the `PkgName` object for this import of the `fmt` package.
+And finally, the innermost block is that of function `main`, a
+local block, which contains the declaration of `message`, a `Const`.
+The `main` function is trivial, but many functions contain
+several blocks since each `if`, `for`, `switch`,
+`case`, or `select` statement creates at least one
+additional block.
+Local blocks nest to arbitrary depths.
+
+
+
+The structure of the lexical environment thus forms a tree, with the
+universe block at the root, the package blocks beneath it, the file
+blocks beneath them, and then any number of local blocks beneath the
+files.
+The following methods of `Scope` make this tree structure
+accessible and navigable:
+
+
+	func (s *Scope) Parent() *Scope
+	func (s *Scope) NumChildren() int
+	func (s *Scope) Child(i int) *Scope
+
+
+`Parent` lets us walk up the tree, and `Child`
+lets us walk down it.
+Note that although the `Parent` of every package `Scope` is
+`Universe`, `Universe` has no children.
+This asymmetry is a consequence of using a global variable to hold
+`Universe`.
+
+
+
+To obtain the universe block, we use the `Universe` global variable.
+To obtain the lexical block of a `Package`, we call its
+`Scope` method.
+To obtain the scope of a file (`*ast.File`), or any smaller piece
+of syntax such as an `*ast.IfStmt`, we consult the `Scopes`
+mapping in the `Info` struct, which maps each block-creating
+syntax node to its block.
+The lexical block of a named function or method can also be obtained
+by calling its `(*Func).Scope` method.
+
+
+<!--
+TODO: explain explicit and implicit blocks 
+TODO: explain Dot imports.
+TODO: explain that Func blocks are associated with FuncType (not FuncDecl or FuncLit)
+-->
+
+
+To look up a name in the lexical environment, we must search the tree
+of lexical blocks, starting at a particular `Scope` and walking
+up to the root until a declaration of the name is found.
+For convenience, the `LookupParent` method does this, returning
+not just the object, if found, but also the `Scope` in which it was
+declared, which may be an ancestor of the initial one:
+
+
+	func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object)
+
+
+The `pos` parameter determines the position in the source code at
+which the name should be resolved.
+The effective lexical environment is different at each point in the
+block because it depends on which local declarations appear
+before or after that point.
+(We'll see an illustration in a moment.)
+
+
+
+`Scope` has several other methods relating to source positions:
+
+
+	func (s *Scope) Pos() token.Pos
+	func (s *Scope) End() token.Pos
+	func (s *Scope) Contains(pos token.Pos) bool
+	func (s *Scope) Innermost(pos token.Pos) *Scope
+
+
+`Pos` and `End` report the `Scope`'s start and end
+position which, for explicit blocks, are coincident with its curly
+braces.
+`Contains` is a convenience method that reports whether a
+position lies in this interval.
+`Innermost` returns the innermost scope containing the specified
+position, which may be a child or other descendent of the initial
+scope.
+
+
+
+These features are useful for tools that wish to resolve names or
+evaluate constant expressions as if they had appeared at a particular
+point within the program.
+The next example program finds all the comments in the input,
+treating the contents of each one as a name.  It looks up each name in
+the environment at the position of the comment, and prints what it
+finds.
+Observe that the `ParseComments` flag directs the parser to
+preserve comments in the input.
+
+
+	// go get github.com/golang/example/gotypes/lookup
+
+```
+func main() {
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+
+	conf := types.Config{Importer: importer.Default()}
+	pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err) // type error
+	}
+
+	// Each comment contains a name.
+	// Look up that name in the innermost scope enclosing the comment.
+	for _, comment := range f.Comments {
+		pos := comment.Pos()
+		name := strings.TrimSpace(comment.Text())
+		fmt.Printf("At %s,\t%q = ", fset.Position(pos), name)
+		inner := pkg.Scope().Innermost(pos)
+		if _, obj := inner.LookupParent(name, pos); obj != nil {
+			fmt.Println(obj)
+		} else {
+			fmt.Println("not found")
+		}
+	}
+}
+```
+
+
+The expression `pkg.Scope().Innermost(pos)` finds the innermost
+`Scope` that encloses the comment, and `LookupParent(name, pos)`
+does a name lookup at a specific position in that lexical block.
+
+
+
+A typical input is shown below. 
+The first comment causes a lookup of `"append"` in the file block.
+The second comment looks up `"fmt"` in the `main` function's block,
+and so on.
+
+
+```
+const hello = `
+package main
+
+import "fmt"
+
+// append
+func main() {
+        // fmt
+        fmt.Println("Hello, world")
+        // main
+        main, x := 1, 2
+        // main
+        print(main, x)
+        // x
+}
+// x
+`
+```
+
+
+Here's the output:
+
+
+```
+$ go build github.com/golang/example/gotypes/lookup
+$ ./lookup
+At hello.go:6:1,        "append" = builtin append
+At hello.go:8:9,        "fmt" = package fmt
+At hello.go:10:9,       "main" = func cmd/hello.main()
+At hello.go:12:9,       "main" = var main int
+At hello.go:14:9,       "x" = var x int
+At hello.go:16:1,       "x" = not found
+```
+
+
+Notice how the two lookups of `main` return different results,
+even though they occur in the same block, because one precedes the
+declaration of the local variable named `main` and the other
+follows it.
+Also notice that there are two lookups of the name `x` but only
+the first one, in the function block, succeeds.
+
+
+
+Download the program and modify both the input program and
+the set of comments to get a better feel for how name resolution works.
+
+
+
+The table below summarizes which kinds of object may be declared at
+each level of the tree of lexical blocks.
+
+
+                Universe File Package Local
+    Builtin        ✔
+    Nil            ✔
+    Const          ✔            ✔      ✔
+    TypeName       ✔            ✔      ✔
+    Func                        ✔
+    Var                         ✔      ✔
+    PkgName               ✔
+    Label                              ✔
+
+# Initialization Order
+
+
+In the course of identifier resolution, the type checker constructs a
+graph of references among declarations of package-level variables and
+functions.
+The type checker reports an error if the initializer expression for a
+variable refers to that variable, whether directly or indirectly.
+
+
+
+The reference graph determines the initialization order of the
+package-level variables, as required by the Go spec, using a
+breadth-first algorithm.
+First, variables in the graph with no successors are removed, sorted
+into the order in which they appear in the source code, then added
+to a list.  This creates more variables that have no successors.
+The process repeats until they have all been removed.
+
+
+
+The result is available in the `InitOrder` field of the
+`Info` struct, whose type is `[]Initializer`.
+
+
+	type Info struct {
+		...
+		InitOrder []Initializer
+		...
+	}
+	
+	type Initializer struct {
+		Lhs []*Var // var Lhs = Rhs
+		Rhs ast.Expr
+	}
+
+
+Each element of the list represents a single initializer expression
+that must be executed, and the variables to which it is assigned.
+The variables may number zero, one, or more, as in these examples:
+
+
+	var _ io.Writer = new(bytes.Buffer)
+	var rx = regexp.MustCompile("^b(an)*a$")
+	var cwd, cwdErr = os.Getwd()
+
+
+This process governs the initialization order of variables within a
+package.
+Across packages, dependencies must be initialized first, although the
+order among them is not specified.
+That is, any topological order of the import graph will do.
+The `(*Package).Imports` method returns the set of direct
+dependencies of a package, in an unspecified order.
+
+
+# Types
+
+
+The main job of the type checker is, of course, to deduce the type
+of each expression and to report type errors.
+Like `Object`, `Type` is an interface type used as a
+discriminated union of several concrete types but, unlike
+`Object`, `Type` has very few methods because types have
+little in common with each other.
+Here is the interface:
+
+
+	type Type interface {
+		Underlying() Type
+	}
+
+
+And here are the eleven concrete types that satisfy it:
+
+
+	Type = *Basic
+	     | *Pointer
+	     | *Array
+	     | *Slice
+	     | *Map
+	     | *Chan
+	     | *Struct
+	     | *Tuple
+	     | *Signature
+	     | *Named
+	     | *Interface
+
+
+With the exception of `Named` types, instances of `Type` are
+not canonical.
+That is, it is usually a mistake to compare types using `t1==t2`
+since this equivalence is not the same as the
+[type identity relation](https://golang.org/ref/spec#Type_identity)
+defined by the Go spec.
+Use this function instead:
+
+
+	func Identical(t1, t2 Type) bool
+
+
+For the same reason, you should not use a `Type` as a key in a map.
+The [`golang.org/x/tools/go/types/typeutil` package](https://godoc.org/golang.org/x/tools/go/types/typeutil)
+provides a map keyed by types that uses the correct
+equivalence relation.
+
+
+The Go spec defines three relations over types.
+[_Assignability_](https://golang.org/ref/spec#Assignability)
+governs which pairs of types may appear on the
+left- and right-hand side of an assignment, including implicit
+assignments such as function calls, map and channel operations, and so
+on.
+[_Comparability_](https://golang.org/ref/spec#Comparison_operators)
+determines which types may appear in a comparison `x==y` or a
+switch case or may be used as a map key.
+[_Convertibility_](https://golang.org/ref/spec#Conversions)
+governs which pairs of types are allowed in a conversion operation
+`T(v)`.
+You can query these relations with the following predicate functions:
+
+
+	func AssignableTo(V, T Type) bool
+	func Comparable(T Type) bool
+	func ConvertibleTo(V, T Type) bool
+
+
+Let's take a look at each kind of type.
+
+
+## Basic types
+
+
+`Basic` represents all types that are not composed from simpler
+types.
+This is essentially the set of underlying types that a constant expression is
+permitted to have--strings, booleans, and numbers---but it also
+includes `unsafe.Pointer` and untyped nil.
+
+
+	type Basic struct{...}
+	func (*Basic) Kind() BasicKind
+	func (*Basic) Name() string
+	func (*Basic) Info() BasicInfo
+
+
+The `Kind` method returns an "enum" value that indicates which
+basic type this is.
+The kinds `Bool`, `String`, `Int16`, and so on,
+represent the corresponding predeclared boolean, string, or numeric
+types.
+There are two synonyms: `Byte` is equivalent to `Uint8`
+and `Rune` is equivalent to `Int32`.
+The kind `UnsafePointer` represents `unsafe.Pointer`.
+The kinds `UntypedBool`, `UntypedInt` and so on represent
+the six kinds of "untyped" constant types: boolean, integer, rune,
+float, complex, and string.
+The kind `UntypedNil` represents the type of the predeclared
+`nil` value.
+And the kind `Invalid` indicates the invalid type, which is used
+for expressions containing errors, or for objects without types, like
+`Label`, `Builtin`, or `PkgName`.
+
+
+
+The `Name` method returns the name of the type, such as
+`"float64"`, and the `Info` method returns a bitfield that
+encodes information about the type, such as whether it is signed or
+unsigned, integer or floating point, real or complex.
+
+
+
+`Typ` is a table of canonical basic types, indexed by
+kind, so `Typ[String]` returns the `*Basic` that represents
+`string`, for instance.
+Like `Universe`, `Typ` is logically a constant, so don't
+modify it.
+
+
+
+A few minor subtleties:
+According to the Go spec, pre-declared types such as `int` are
+named types for the purposes of assignability, even though the type
+checker does not represent them using `Named`.
+And `unsafe.Pointer` is a pointer type for the purpose of
+determining whether the receiver type of a method is legal, even
+though the type checker does not represet it using `Pointer`.
+
+
+
+The "untyped" types are usually only ascribed to constant expressions,
+but there is one exception.
+A comparison `x==y` has type "untyped bool", so the result of
+this expression may be assigned to a variable of type `bool` or
+any other named boolean type.
+
+
+
+## Simple Composite Types
+
+
+The types `Pointer`, `Array`, `Slice`, `Map`,
+and `Chan` are pretty self-explanatory.
+All have an `Elem` method that returns the element type `T`
+for a pointer `*T`, an array `[n]T`, a slice `[]T`, a
+map `map[K]T`, or a channel `chan T`.
+This should feel familiar if you've used the `reflect.Value` API.
+
+
+
+In addition, the `*Map`, `*Chan`, and `*Array` types
+have accessor methods that return their key type, direction, and
+length, respectively:
+
+
+	func (*Map) Key() Type
+	func (*Chan) Dir() ChanDir      // = Send | Recv | SendRecv
+	func (*Array) Len() int64
+
+
+
+## Struct Types
+
+
+A struct type has an ordered list of fields and a corresponding
+ordered list of field tags.
+
+
+	type Struct struct{ ... } 
+	func (*Struct) NumFields() int
+	func (*Struct) Field(i int) *Var
+	func (*Struct) Tag(i int) string
+
+
+Each field is a `Var` object whose `IsField` method returns true.
+Field objects have no `Parent` scope, because they are
+resolved through selections, not through the lexical environment.
+
+
+
+Thanks to embedding, the expression `new(S).f` may be a shorthand
+for a longer expression such as `new(S).d.e.f`, but in the
+representation of `Struct` types, these field selection
+operations are explicit.
+That is, the set of fields of struct type `S` does not include `f`.
+An anonymous field is represented like a regular field, but its
+`Anonymous` method returns true.
+
+
+
+One subtlety is relevent to tools that generate documentation.
+When analyzing a declaration such as this,
+
+
+	type T struct{x int}
+
+
+it may be tempting to consider the `Var` object for field `x` as if it
+had the name `"T.x"`, but beware: field objects do not have
+canonical names and there is no way to obtain the name `"T"`
+from the `Var` for `x`.
+That's because several types may have the same underlying struct type,
+as in this code:
+
+
+	type T struct{x int}
+	type U T
+
+
+Here, the `Var` for field `x` belongs equally to `T`
+and to `U`, and short of inspecting source positions or walking
+the AST---neither of which is possible for objects loaded from compiler
+export data---it is not possible to ascertain that `x` was declared as
+part of `T`.
+The type checker computes the exact same data structures given this input:
+
+
+	type T U
+	type U struct{x int}
+
+
+A similar issue applies to the methods of named interface types.
+
+					 
+## Tuple Types
+
+
+Like a struct, a tuple type has an ordered list of fields, and fields
+may be named.
+
+
+	type Tuple struct{ ... }
+	func (*Tuple) Len() int
+	func (*Tuple) At(i int) *Var
+
+
+Although tuples are not the type of any variable in Go, they are
+the type of some expressions, such as the right-hand sides of these
+assignments:
+
+
+	v, ok = m[key]
+	v, ok = <-ch
+	v, ok = x.(T)
+	f, err = os.Open(filename)
+
+
+Tuples also represent the types of the parameter list and the result
+list of a function, as we will see.
+
+
+
+Since empty tuples are common, the nil `*Tuple` pointer is a valid empty tuple.
+
+
+
+## Function and Method Types
+
+
+The types of functions and methods are represented by a `Signature`,
+which has a tuple of parameter types and a tuple of result types.
+
+
+	type Signature struct{ ... }
+	func (*Signature) Recv() *Var
+	func (*Signature) Params() *Tuple
+	func (*Signature) Results() *Tuple
+	func (*Signature) Variadic() bool
+
+
+Variadic functions such as `fmt.Println` have the `Variadic`
+flag set.
+The final parameter of such functions is always a slice, or in the
+special case of certain calls to `append`, a string.
+
+
+
+A `Signature` for a method, whether concrete or abstract, has a
+non-nil receiver parameter, `Recv`.
+The type of the receiver is usually a named type or a pointer to a named type, 
+but it may be an unnamed struct or interface type in some cases.
+Method types are rather second-class: they are only used for the
+`Func` objects created by method declarations, and no Go
+expression has a method type.
+When printing a method type, the receiver does not appear, and the
+`Identical` predicate ignores the receiver.
+
+
+
+The types of `Builtin` objects like `append` cannot be
+expressed as a `Signature` since those types require parametric
+polymorphism.
+`Builtin` objects are thus ascribed the `Invalid` basic type.
+However, the type of each _call_ to a built-in function has a specific
+and expressible Go type.
+These types are recorded during type checking for later use
+([TypeAndValue](#typeandvalue)).
+
+
+
+## Named Types
+
+
+A type declaration creates a `TypeName` object, and the type of
+that object is a `Named`.
+These two entities, an object and a type, are distinct but closely
+related, and they exist in one-to-one correpondence.
+
+
+	type Named struct{ ... }
+	func (*Named) NumMethods() int
+	func (*Named) Method(i int) *Func
+	func (*Named) Obj() *TypeName
+	func (*Named) Underlying() Type
+
+
+The `Named` type's `Obj` method returns the `TypeName` object, which
+provides the name, position, and other properties of the declaration.
+Conversely, the `TypeName` object's `Type` method returns the `Named` type.
+
+
+
+The `NumMethods` and `Method` methods enumerate the declared
+methods associated with this `Named` type (or a pointer to it),
+in the order they were declared.
+However, due to the subtleties of anonymous fields and the difference
+between value and pointer receivers, a named type may have more or fewer
+methods than this list.  We'll return to this in [Method Sets](#method_sets).
+
+
+
+Every `Type` has an `Underlying` method, but for all of them
+except `*Named`, it is simply the identity function.
+For a named type, `Underlying` returns its underlying type, which
+is always an unnamed type.
+Thus `Underlying` returns `int` for both `T` and
+`U` below.
+
+
+	type T int
+	type U T
+
+
+Clients of the type checker often use type assertions or type switches
+with a `Type` operand.
+When doing so, it is often necessary to switch on the type that
+_underlies_ the type of interest, and failure to do so may be a
+bug.
+
+This is a common pattern:
+
+
+	// handle types of composite literal
+	switch u := t.Underlying().(type) {
+	case *Struct:        // ...
+	case *Map:           // ...
+	case *Array, *Slice: // ...
+	default:
+		panic("impossible")
+	}
+
+## Interface Types
+
+
+Interface types are represented by `Interface`.
+
+
+	type Interface struct{ ... }
+	func (*Interface) Empty() bool
+	func (*Interface) NumMethods() int
+	func (*Interface) Method(i int) *Func
+	func (*Interface) NumEmbeddeds() int
+	func (*Interface) Embedded(i int) *Named
+	func (*Interface) NumExplicitMethods() int
+	func (*Interface) ExplicitMethod(i int) *Func
+
+
+Syntactically, an interface type has a list of explicitly declared
+methods (`ExplicitMethod`), and a list of embedded named
+interface types (`Embedded`), but many clients care only about
+the complete set of methods, which can be enumerated via
+`Method`.
+All three lists are ordered by name.
+Since the empty interface is an important special case, the
+`Empty` predicate provides a shorthand for `NumMethods() ==
+0`.
+
+
+
+As with the fields of structs (see above), the methods of interfaces
+may belong equally to more than one interface type.
+The `Func` object for method `f` in the code below is shared
+by `I` and `J`:
+
+
+	type I interface { f() }
+	type J I
+
+
+Because the difference between interface (abstract) and
+non-interface (concrete) types is so important in Go, the
+`IsInterface` predicate is provided for convenience.
+
+
+	func IsInterface(Type) bool
+
+
+The type checker provides three utility methods relating to interface
+satisfaction:
+
+
+	func Implements(V Type, T *Interface) bool
+	func AssertableTo(V *Interface, T Type) bool
+	func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool)
+
+
+The `Implements` predicate reports whether a type satisifies an
+interface type.
+`MissingMethod` is like `Implements`, but instead of
+returning false, it explains why a type does not satisfy the
+interface, for use in diagnostics.
+
+
+
+`AssertableTo` reports whether a type assertion `v.(T)` is legal.
+If `T` is a concrete type that doesn't have all the methods of
+interface `v`, then the type assertion is not legal, as in this example:
+
+
+	// error: io.Writer is not assertible to int
+	func f(w io.Writer) int { return w.(int) } 
+
+
+
+## TypeAndValue
+
+
+The type checker records the type of each expression in another field
+of the `Info` struct, namely `Types`:
+
+
+	type Info struct {
+		...
+		Types map[ast.Expr]TypeAndValue
+	}
+
+
+No entry is recorded for identifiers since the `Defs` and
+`Uses` maps provide more information about them.
+Also, no entry is recorded for pseudo-expressions like
+`*ast.KeyValuePair` or `*ast.Ellipsis`.
+
+
+
+The value of the `Types` map is a `TypeAndValue`, which
+(unsurprisingly) holds the `Type` and value of the expression, and in
+addition, its _mode_.
+The mode is opaque, but has predicates to answer questions such as:
+Does this expression denote a value or a type?  Does this value have an
+address?  Does this expression appear on the left-hand side of an
+assignment?  Does this expression appear in a context that expects two
+results?
+The comments in the code below give examples of expressions that
+satisfy each predicate.
+
+
+	type TypeAndValue struct {
+		Type  Type
+		Value constant.Value // for constant expressions only
+		...
+	}
+	
+	func (TypeAndValue) IsVoid() bool      // e.g. "main()"
+	func (TypeAndValue) IsType() bool      // e.g. "*os.File"
+	func (TypeAndValue) IsBuiltin() bool   // e.g. "len(x)"
+	func (TypeAndValue) IsValue() bool     // e.g. "*os.Stdout"
+	func (TypeAndValue) IsNil() bool       // e.g. "nil"
+	func (TypeAndValue) Addressable() bool // e.g. "a[i]" but not "f()", "m[key]"
+	func (TypeAndValue) Assignable() bool  // e.g. "a[i]", "m[key]"
+	func (TypeAndValue) HasOk() bool       // e.g. "&lt;-ch", "m[key]"
+
+
+The statement below inspects every expression within the AST of a single
+type-checked file and prints its type, value, and mode:
+
+
+	// go get github.com/golang/example/gotypes/typeandvalue
+
+```
+// f is a parsed, type-checked *ast.File.
+ast.Inspect(f, func(n ast.Node) bool {
+	if expr, ok := n.(ast.Expr); ok {
+		if tv, ok := info.Types[expr]; ok {
+			fmt.Printf("%-24s\tmode:  %s\n", nodeString(expr), mode(tv))
+			fmt.Printf("\t\t\t\ttype:  %v\n", tv.Type)
+			if tv.Value != nil {
+				fmt.Printf("\t\t\t\tvalue: %v\n", tv.Value)
+			}
+		}
+	}
+	return true
+})
+```
+
+
+It makes use of these two helper functions, which are not shown:
+
+
+	// nodeString formats a syntax tree in the style of gofmt.
+	func nodeString(n ast.Node) string
+	
+	// mode returns a string describing the mode of an expression.
+	func mode(tv types.TypeAndValue) string
+
+
+Given this input:
+
+
+```
+const input = `
+package main
+
+var m = make(map[string]int)
+
+func main() {
+	v, ok := m["hello, " + "world"]
+	print(rune(v), ok)
+}
+`
+```
+
+
+the program prints:
+
+
+```
+$ go build github.com/golang/example/gotypes/typeandvalue
+$ ./typeandvalue
+make(map[string]int)            mode:  value
+                                type:  map[string]int
+make                            mode:  builtin
+                                type:  func(map[string]int) map[string]int
+map[string]int                  mode:  type
+                                type:  map[string]int
+m["hello"]                      mode:  value,assignable,ok
+                                type:  (int, bool)
+m                               mode:  value,addressable,assignable
+                                type:  map[string]int
+"hello, " + "world"             mode:  value
+                                type:  string
+                                value: "hello, world"
+"hello, "                       mode:  value
+                                type:  untyped string
+                                value: "hello, "
+"world"                         mode:  value
+                                type:  untyped string
+                                value: "world"
+print(rune(v), ok)              mode:  void
+                                type:  ()
+print                           mode:  builtin
+                                type:  func(rune, bool)
+rune(v)                         mode:  value
+                                type:  rune
+rune                            mode:  type
+                                type:  rune
+...more not shown...
+```
+
+
+Notice that the identifiers for the built-ins `make` and
+`print` have types that are specific to the particular calls in
+which they appear.
+Also notice `m["hello"]` has a 2-tuple type `(int, bool)`
+and that it is assignable, but unlike the variable `m`, it is not
+addressable.
+
+
+
+Download the example and vary the inputs and see what the program prints.
+
+
+
+Here's another example, adapted from the `govet` static checking tool.
+It checks for accidental uses of a method value `x.f` when a
+call `x.f()` was intended;
+comparing a method `x.f` against nil is a common mistake.
+
+
+	// go get github.com/golang/example/gotypes/nilfunc
+
+```
+// CheckNilFuncComparison reports unintended comparisons
+// of functions against nil, e.g., "if x.Method == nil {".
+func CheckNilFuncComparison(info *types.Info, n ast.Node) {
+	e, ok := n.(*ast.BinaryExpr)
+	if !ok {
+		return // not a binary operation
+	}
+	if e.Op != token.EQL && e.Op != token.NEQ {
+		return // not a comparison
+	}
+
+	// If this is a comparison against nil, find the other operand.
+	var other ast.Expr
+	if info.Types[e.X].IsNil() {
+		other = e.Y
+	} else if info.Types[e.Y].IsNil() {
+		other = e.X
+	} else {
+		return // not a comparison against nil
+	}
+
+	// Find the object.
+	var obj types.Object
+	switch v := other.(type) {
+	case *ast.Ident:
+		obj = info.Uses[v]
+	case *ast.SelectorExpr:
+		obj = info.Uses[v.Sel]
+	default:
+		return // not an identifier or selection
+	}
+
+	if _, ok := obj.(*types.Func); !ok {
+		return // not a function or method
+	}
+
+	fmt.Printf("%s: comparison of function %v %v nil is always %v\n",
+		fset.Position(e.Pos()), obj.Name(), e.Op, e.Op == token.NEQ)
+}
+```
+
+
+Given this input,
+
+
+```
+const input = `package main
+
+import "bytes"
+
+func main() {
+	var buf bytes.Buffer
+	if buf.Bytes == nil && bytes.Repeat != nil && main == nil {
+		// ...
+	}
+}
+`
+```
+
+
+the program reports these errors:
+
+
+```
+$ go build github.com/golang/example/gotypes/nilfunc
+$ ./nilfunc
+input.go:7:5: comparison of function Bytes == nil is always false
+input.go:7:25: comparison of function Repeat != nil is always true
+input.go:7:48: comparison of function main == nil is always false
+```
+
+# Selections
+
+
+A _selection_ is an expression _`expr`_`.f` in which
+`f` denotes either a struct field or a method.
+A selection is resolved not by looking for a name in the lexical
+environment, but by looking within a _type_.
+The type checker ascertains the meaning of each selection in the
+package---a surprisingly tricky business---and records it in the
+`Selections` mapping of the `Info` struct, whose values are
+of type `Selection`:
+
+
+	type Selection struct{ ... }
+	func (s *Selection) Kind() SelectionKind // = FieldVal | MethodVal | MethodExpr
+	func (s *Selection) Recv() Type
+	func (s *Selection) Obj() Object
+	func (s *Selection) Type() Type
+	func (s *Selection) Index() []int
+	func (s *Selection) Indirect() bool
+
+
+The `Kind` method discriminates between the three (legal) kinds
+of selections, as indicated by the comments below.
+
+
+	type T struct{Field int}
+	func (T) Method() {}
+	var v T
+	
+                         // Kind            Type
+        var _ = v.Field  // FieldVal        int
+        var _ = v.Method // MethodVal       func()
+        var _ = T.Method // MethodExpr      func(T)
+
+
+Because of embedding, a selection may denote more than one field or
+method, in which case it is ambiguous, and no `Selection` is
+recorded for it.
+
+
+
+The `Obj` method returns the `Object` for the selected field
+(`*Var`) or method (`*Func`).
+Due to embedding, the object may belong to a different type than that
+of the receiver expression _`expr`_.
+The `Type` method returns the type of the selection.  For a field
+selection, this is the type of the field, but for method selections,
+the result is a function type that is not the same as the type of the
+method.
+For a `MethodVal`, the receiver parameter is dropped, and
+for a `MethodExpr`, the receiver parameter becomes a regular
+parameter, as shown in the example above.
+
+
+
+The `Index` and `Indirect` methods report information about
+implicit operations occurring during the selection that a compiler
+would need to know about.
+Because of embedding, a selection _`expr`_`.f` may be
+shorthand for a sequence containing several implicit field selections,
+_`expr`_`.d.e.f`, and `Index` reports the complete
+sequence.
+And because of automatic pointer dereferencing during struct field
+accesses and method calls, a selection may imply one or more indirect
+loads from memory; `Indirect` reports whether this occurs.
+
+
+
+Clients of the type checker can call `LookupFieldOrMethod` to
+look up a name within a type, as if by a selection.
+This function has an intimidating signature, but conceptually it
+accepts just a `Type` and a name, and returns a `Selection`:
+
+
+	func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) \
+	    (obj Object, index []int, indirect bool)
+
+
+The result is not actually a `Selection`, but it contains the
+three main components of one: `Obj`, `Index`,
+and `Indirect`.
+
+
+
+The `addressable` flag should be set if the receiver is a
+_variable_ of type `T`, since in a method selection on a
+variable, an implicit address-of operation (`&amp;`) may occur.
+The flag indicates whether the methods of type `*T` should be
+considered during the lookup.
+
+
+
+(You may wonder why this parameter is necessary.  Couldn't clients
+instead call `LookupFieldOrMethod` on the pointer type `*T`
+if the receiver is a `T` variable?  The answer is that if
+`T` is an interface type, the type `*T` has no methods at
+all.)
+
+
+
+The final two parameters of `LookupFieldOrMethod` are `(pkg
+*Package, name string)`.  
+Together they specify the name of the field or method to look up.
+This brings us to `Id`s.
+
+
+
+# Ids
+
+
+`LookupFieldOrMethod`'s need for a `Package` parameter
+is a subtle consequence of the
+[_Uniqueness of identifiers_](https://golang.org/ref/spec#Uniqueness_of_identifiers)
+section in the Go spec: "Two
+identifiers are different if they are spelled differently, or if they
+appear in different packages and are not exported."
+In practical terms, this means that a type may have have two methods
+(or two fields, or one of each) both named `f` so long as those
+methods are defined in different packages, as in this example:
+
+
+	package a
+	type A int
+	func (A) f()
+	
+	package b
+	type B int
+	func (B) f()
+	
+	package c
+	import ( "a"; "b" )
+	type C struct{a.A; b.B} // C has two methods called f
+
+
+The type `c.C` has two methods named `f`, but there is
+no ambiguity because the two `f`s are distinct
+identifiers---think of them as `fᵃ` and `fᵇ`.
+For an exported method, this situation _would_ be ambiguous
+because there is no distinction between `Fᵃ` and `Fᵇ`; there
+is only `F`.
+
+
+
+Despite having two methods called `f`, neither of them can be
+called from within package `c` because `c` has no way to
+identify them.
+Within `c`,  `f` is the identifier `fᶜ`, and
+type `C` has no method of that name.
+But if we pass an instance of `C` to code in package `a`
+and call its `f` method via an interface, `fᵃ` is called.
+
+
+
+The practical consequence for tool builders is that any time you need
+to look up a field or method by name, or construct a map of fields and/or
+methods keyed by name, it is not sufficient to use the object's name
+as a key.
+Instead, you must call the `Object.Id` method, which returns
+a string that incorporates the object name, and for unexported
+objects, the package path too.
+There is also a standalone function `Id` that combines a name and
+the package path in the same way:
+
+
+	func Id(pkg *Package, name string) string
+
+
+This distinction applies to selections _`expr`_`.f`, but not
+to lexical references `x` because for unexported identifiers,
+declarations and references always appear in the same package.
+
+
+
+Fun fact: the `reflect.StructField` type records both the
+`Name` and the `PkgPath` strings for the same reason.
+The `FieldByName` methods of `reflect.Value` and
+`reflect.Type` match field names without regard to the package.
+If there is more than one match, they return an invalid value.
+
+
+
+
+# Method Sets
+
+
+The _method set_ of a type is the set of methods that can be
+called on any value of that type.
+(A variable of type `T` has access to all the methods of type
+`*T` as well, due to the implicit address-of operation during
+method calls, but those extra methods are not part of the method set
+of `T`.)
+
+
+
+Clients can request the method set of a type `T` by calling
+`NewMethodSet(T)`:
+
+
+	type MethodSet struct{ ... }
+	func NewMethodSet(T Type) *MethodSet
+	func (s *MethodSet) Len() int
+	func (s *MethodSet) At(i int) *Selection
+	func (s *MethodSet) Lookup(pkg *Package, name string) *Selection
+
+
+The `Len` and `At` methods access a a list of
+`Selections`, all of kind `MethodVal`, ordered by `Id`.
+The `Lookup` function allows lookup of a single method by
+name (and package path, as explained in the previous section).
+
+
+
+`NewMethodSet` can be expensive, so for applications that compute
+method sets repeatedly, `golang.org/x/tools/go/types/typeutil`
+provides a `MethodSetCache` type that records previous results.
+If you only need a single method, don't construct the
+`MethodSet` at all; it's cheaper to use
+`LookupFieldOrMethod`.
+
+
+
+The next program generates a boilerplate
+declaration of a new concrete type that satisifies an existing
+interface.
+Here's an example:
+
+
+```
+$ ./skeleton io ReadWriteCloser buffer
+// *buffer implements io.ReadWriteCloser.
+type buffer struct{}
+func (b *buffer) Close() error {
+	panic("unimplemented")
+}
+func (b *buffer) Read(p []byte) (n int, err error) {
+	panic("unimplemented")
+}
+func (b *buffer) Write(p []byte) (n int, err error) {
+	panic("unimplemented")
+}
+```
+
+
+The three arguments are the package and the name of the existing
+interface type, and the name of the new concrete type.
+The `main` function (not shown) loads the specified package and
+calls `PrintSkeleton` with the remaining two arguments:
+
+
+	// go get github.com/golang/example/gotypes/skeleton
+
+```
+func PrintSkeleton(pkg *types.Package, ifacename, concname string) error {
+	obj := pkg.Scope().Lookup(ifacename)
+	if obj == nil {
+		return fmt.Errorf("%s.%s not found", pkg.Path(), ifacename)
+	}
+	if _, ok := obj.(*types.TypeName); !ok {
+		return fmt.Errorf("%v is not a named type", obj)
+	}
+	iface, ok := obj.Type().Underlying().(*types.Interface)
+	if !ok {
+		return fmt.Errorf("type %v is a %T, not an interface",
+			obj, obj.Type().Underlying())
+	}
+	// Use first letter of type name as receiver parameter.
+	if !isValidIdentifier(concname) {
+		return fmt.Errorf("invalid concrete type name: %q", concname)
+	}
+	r, _ := utf8.DecodeRuneInString(concname)
+
+	fmt.Printf("// *%s implements %s.%s.\n", concname, pkg.Path(), ifacename)
+	fmt.Printf("type %s struct{}\n", concname)
+	mset := types.NewMethodSet(iface)
+	for i := 0; i < mset.Len(); i++ {
+		meth := mset.At(i).Obj()
+		sig := types.TypeString(meth.Type(), (*types.Package).Name)
+		fmt.Printf("func (%c *%s) %s%s {\n\tpanic(\"unimplemented\")\n}\n",
+			r, concname, meth.Name(),
+			strings.TrimPrefix(sig, "func"))
+	}
+	return nil
+}
+```
+
+
+First, `PrintSkeleton` locates the package-level named interface
+type, handling various error cases.
+Then it chooses the name for the receiver of the new methods: the
+first letter of the concrete type.
+Finally, it iterates over the method set of the interface, printing
+the corresponding concrete method declarations.
+
+
+
+There's a subtlety in the declaration of `sig`, which is the
+string form of the method signature.
+We could have obtained this string from `meth.Type().String()`,
+but this would cause any named types within it to be formatted with
+the complete package path, for instance
+`net/http.ResponseWriter`, which is informative in diagnostics
+but not legal Go syntax.
+The `TypeString` function (explained in [Formatting Values](#formatting-values)) allows the
+caller to control how packages are printed.
+Passing `(*types.Package).Name` causes only the package name
+`http` to be printed, not the complete path.
+Here's another example that illustrates it:
+
+
+```
+$ ./skeleton net/http Handler myHandler
+// *myHandler implements net/http.Handler.
+type myHandler struct{}
+func (m *myHandler) ServeHTTP(http.ResponseWriter, *http.Request) {
+	panic("unimplemented")
+}
+```
+
+
+The following program inspects all pairs of package-level named types
+in `pkg`, and reports the types that satisfy each interface type.
+
+
+	// go get github.com/golang/example/gotypes/implements
+
+```
+// Find all named types at package level.
+var allNamed []*types.Named
+for _, name := range pkg.Scope().Names() {
+	if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok {
+		allNamed = append(allNamed, obj.Type().(*types.Named))
+	}
+}
+
+// Test assignability of all distinct pairs of
+// named types (T, U) where U is an interface.
+for _, T := range allNamed {
+	for _, U := range allNamed {
+		if T == U || !types.IsInterface(U) {
+			continue
+		}
+		if types.AssignableTo(T, U) {
+			fmt.Printf("%s satisfies %s\n", T, U)
+		} else if !types.IsInterface(T) &&
+			types.AssignableTo(types.NewPointer(T), U) {
+			fmt.Printf("%s satisfies %s\n", types.NewPointer(T), U)
+		}
+	}
+}
+```
+
+
+Given this input,
+
+
+	// go get github.com/golang/example/gotypes/implements
+
+```
+const input = `package main
+
+type A struct{}
+func (*A) f()
+
+type B int
+func (B) f()
+func (*B) g()
+
+type I interface { f() }
+type J interface { g() }
+`
+```
+
+
+the program prints:
+
+
+```
+$ go build github.com/golang/example/gotypes/implements
+$ ./implements
+*hello.A satisfies hello.I
+hello.B satisfies hello.I
+*hello.B satisfies hello.J
+```
+
+
+Notice that the method set of `B` does not include `g`, but
+the method set of `*B` does.
+That's why we needed the second assignability check, using the pointer
+type `types.NewPointer(T)`.
+
+
+
+# Constants
+
+
+A constant expression is one whose value is guaranteed to be computed at
+compile time.
+Constant expressions may appear in types, specifically as the length
+of an array type such as `[16]byte`, so one of the jobs of the
+type checker is to compute the value of each constant expression.
+
+
+
+As we saw in the `typeandvalue` example, the type checker records
+the value of each constant expression like `"Hello, " + "world"`,
+storing it in the `Value` field of the `TypeAndValue` struct.
+Constants are represented using the `Value` interface from the
+`go/constant` package.
+
+
+	package constant // go/constant
+	
+	type Value interface {
+		Kind() Kind 
+	}
+	
+	type Kind int // one of Unknown, Bool, String, Int, Float, Complex
+
+
+The interface has only one method, for discriminating the various
+kinds of constants, but the package provides many functions for
+inspecting a value of a known kind,
+
+
+	// Accessors
+	func BoolVal(x Value) bool
+	func Float32Val(x Value) (float32, bool)
+	func Float64Val(x Value) (float64, bool)
+	func Int64Val(x Value) (int64, bool)
+	func StringVal(x Value) string
+	func Uint64Val(x Value) (uint64, bool)
+	func Bytes(x Value) []byte
+	func BitLen(x Value) int
+	func Sign(x Value) int
+
+
+for performing arithmetic on values,
+
+
+	// Operations
+	func Compare(x Value, op token.Token, y Value) bool
+	func UnaryOp(op token.Token, y Value, prec uint) Value
+	func BinaryOp(x Value, op token.Token, y Value) Value
+	func Shift(x Value, op token.Token, s uint) Value
+	func Denom(x Value) Value
+	func Num(x Value) Value
+	func Real(x Value) Value
+	func Imag(x Value) Value
+
+
+and for constructing new values:
+
+
+	// Constructors
+	func MakeBool(b bool) Value
+	func MakeFloat64(x float64) Value
+	func MakeFromBytes(bytes []byte) Value
+	func MakeFromLiteral(lit string, tok token.Token, prec uint) Value
+	func MakeImag(x Value) Value
+	func MakeInt64(x int64) Value
+	func MakeString(s string) Value
+	func MakeUint64(x uint64) Value
+	func MakeUnknown() Value
+
+
+All numeric `Value`s, whether integer or floating-point, signed or
+unsigned, or real or complex, are represented more precisely than the
+ordinary Go types like `int64` and `float64`.
+Internally, the `go/constant` package uses multi-precision data types
+like `Int`, `Rat`, and `Float` from the `math/big` package so that
+`Values` and their arithmetic operations are accurate to at least 256
+bits, as required by the Go specification.
+
+
+<!-- TODO example -->
+
+
+# Size and Alignment
+
+
+Because the calls `unsafe.Sizeof(v)`, `unsafe.Alignof(v)`,
+and `unsafe.Offsetof(v.f)` are all constant expressions, the type
+checker must be able to compute the memory layout of any value
+`v`.
+
+
+
+By default, the type checker uses the same layout algorithm as the Go
+1.5 `gc` compiler targeting `amd64`.
+Clients can configure the type checker to use a different algorithm by
+providing an instance of the `types.Sizes` interface in the
+`types.Config` struct:
+
+
+	package types
+	
+	type Sizes interface {
+		Alignof(T Type) int64
+		Offsetsof(fields []*Var) []int64
+		Sizeof(T Type) int64
+	}
+
+
+
+For common changes, like reducing the word size to 32 bits, clients
+can use an instance of `StdSizes`:
+
+
+	type StdSizes struct {
+		WordSize int64
+		MaxAlign int64
+	}
+
+
+This type has two basic size and alignment parameters from which it
+derives all the other values using common assumptions.
+For example, pointers, functions, maps, and channels fit in one word,
+strings and interfaces require two words, and slices need three.
+The default behaviour is equivalent to `StdSizes{8, 8}`.
+For more esoteric layout changes, you'll need to write a new
+implementation of the `Sizes` interface.
+
+
+
+The `hugeparam` program below prints all function parameters and
+results whose size exceeds a threshold.
+By default, the threshold is 48 bytes, but you can set it via the
+`-bytes` command-line flag.
+Such a tool could help identify inefficient parameter passing in your
+programs.
+
+
+	// go get github.com/golang/example/gotypes/hugeparam
+
+```
+var bytesFlag = flag.Int("bytes", 48, "maximum parameter size in bytes")
+
+var sizeof = (&types.StdSizes{8, 8}).Sizeof // the sizeof function
+
+func PrintHugeParams(fset *token.FileSet, info *types.Info, files []*ast.File) {
+	checkTuple := func(descr string, tuple *types.Tuple) {
+		for i := 0; i < tuple.Len(); i++ {
+			v := tuple.At(i)
+			if sz := sizeof(v.Type()); sz > int64(*bytesFlag) {
+				fmt.Printf("%s: %q %s: %s = %d bytes\n",
+					fset.Position(v.Pos()),
+					v.Name(), descr, v.Type(), sz)
+			}
+		}
+	}
+	checkSig := func(sig *types.Signature) {
+		checkTuple("parameter", sig.Params())
+		checkTuple("result", sig.Results())
+	}
+	for _, file := range files {
+		ast.Inspect(file, func(n ast.Node) bool {
+			switch n := n.(type) {
+			case *ast.FuncDecl:
+				checkSig(info.Defs[n.Name].Type().(*types.Signature))
+			case *ast.FuncLit:
+				checkSig(info.Types[n.Type].Type.(*types.Signature))
+			}
+			return true
+		})
+	}
+}
+```
+
+
+As before, `Inspect` applies a function to every node in the AST.
+The function cares about two kinds of nodes: declarations of named
+functions and methods (`*ast.FuncDecl`) and function literals
+(`*ast.FuncLit`).
+Observe the two cases' different logic to obtain the type of each
+function.
+
+
+
+Here's a typical invocation on the standard `encoding/xml` package.
+It reports a number of places where the 7-word
+[`StartElement` type](https://godoc.org/encoding/xml#StartElement)
+is copied.
+
+
+```
+% ./hugeparam encoding/xml
+/go/src/encoding/xml/marshal.go:167:50: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:734:97: "" result: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:761:51: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:781:68: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/xml.go:72:30: "" result: encoding/xml.StartElement = 56 bytes
+```
+
+# Imports
+
+
+The type checker's `Check` function processes a slice of parsed
+files (`[]*ast.File`) that make up one package.
+When the type checker encounters an import declaration, it needs the
+type information for the objects in the imported package.
+It gets it by calling the `Import` method of the `Importer`
+interface shown below, an instance of which must be provided by the
+`Config`.
+This separation of concerns relieves the type checker from having to
+know any of the details of Go workspace organization, `GOPATH`,
+compiler file formats, and so on.
+
+
+	type Importer interface {
+		Import(path string) (*Package, error)
+	}
+
+
+Most of our examples used the simplest `Importer` implementation,
+`importer.Default()`, provided by the `go/importer` package.
+This importer looks in `$GOROOT` and `$GOPATH` for `.a`
+files written by the compiler (`gc` or `gccgo`)
+that was used to build the program.
+In addition to object code, these files contain _export data_,
+that is, a description of all the objects declared by the package, and
+also of any objects from other packages that were referred to indirectly.
+Because export data includes information about dependencies, the type
+checker need load at most one file per import, instead of one per
+transitive dependency.
+
+
+
+Compiler export data is compact and efficient to locate, load, and
+parse, but it has several shortcomings.
+First, it does not contain position information for imported
+objects, reducing the quality of certain diagnostic messages.
+Second, it does not contain complete syntax trees nor semantic information
+about the contents of function bodies, so it is not suitable for
+interprocedural analyses.
+Third, compiler object data may be stale.  Nothing detects or ensures
+that the object files are more recent than the source files from which
+they were derived.
+Generally, object data for standard packages is likely to be
+up-to-date, but for user packages, it depends on how recently the user
+ran a `go install` or `go build -i` command.
+
+
+
+The [`golang.org/tools/x/go/loader` package](https://godoc.org/golang.org/x/tools/go/loader)
+provides an alternative `Importer` that addresses
+some of these problems.
+It loads a complete program from source, performing
+[`cgo`](https://golang.org/cmd/cgo/cgo) preprocessing if
+necessary, followed by parsing and type-checking.
+It loads independent packages in parallel to hide I/O latency, and
+detects and reports import cycles.
+For each package, it provides the `types.Package` containing the
+package's lexical environment, the list of `ast.File` syntax
+trees for each file in the package, the `types.Info` containing
+type information for each syntax node, and a list of type errors
+associated with that package.
+(Please be aware that the `go/loader` package's API is likely to
+change before it finally stabilizes.)
+
+
+
+The `doc` program below demonstrates a simple use of the loader.
+It is a rudimentary implementation of `go doc` that prints the type,
+methods, and documentation of the package-level object specified on
+the command line.
+Here's an example:
+
+
+```
+$ ./doc net/http File
+type net/http.File interface{Readdir(count int) ([]os.FileInfo, error); Seek(offset int64, whence int) (int64, error); Stat() (os.FileInfo, error); io.Closer; io.Reader}
+/go/src/io/io.go:92:2: method (net/http.File) Close() error
+/go/src/io/io.go:71:2: method (net/http.File) Read(p []byte) (n int, err error)
+/go/src/net/http/fs.go:65:2: method (net/http.File) Readdir(count int) ([]os.FileInfo, error)
+/go/src/net/http/fs.go:66:2: method (net/http.File) Seek(offset int64, whence int) (int64, error)
+/go/src/net/http/fs.go:67:2: method (net/http.File) Stat() (os.FileInfo, error)
+
+ A File is returned by a FileSystem's Open method and can be
+served by the FileServer implementation.
+
+The methods should behave the same as those on an *os.File.
+```
+
+
+Observe that it prints the correct location of each method
+declaration, even though, due to embedding, some of
+`http.File`'s methods were declared in another package.
+Here's the first part of the program, showing how to load an entire
+program starting from the single package, `pkgpath`:
+
+
+	// go get github.com/golang/example/gotypes/doc
+
+```
+pkgpath, name := os.Args[1], os.Args[2]
+
+// The loader loads a complete Go program from source code.
+conf := loader.Config{ParserMode: parser.ParseComments}
+conf.Import(pkgpath)
+lprog, err := conf.Load()
+if err != nil {
+	log.Fatal(err) // load error
+}
+
+// Find the package and package-level object.
+pkg := lprog.Package(pkgpath).Pkg
+obj := pkg.Scope().Lookup(name)
+if obj == nil {
+	log.Fatalf("%s.%s not found", pkg.Path(), name)
+}
+```
+
+
+Notice that we instructed the parser to retain comments during parsing.
+The rest of the program prints the output:
+
+
+	// go get github.com/golang/example/gotypes/doc
+
+```
+// Print the object and its methods (incl. location of definition).
+fmt.Println(obj)
+for _, sel := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
+	fmt.Printf("%s: %s\n", lprog.Fset.Position(sel.Obj().Pos()), sel)
+}
+
+// Find the path from the root of the AST to the object's position.
+// Walk up to the enclosing ast.Decl for the doc comment.
+_, path, _ := lprog.PathEnclosingInterval(obj.Pos(), obj.Pos())
+for _, n := range path {
+	switch n := n.(type) {
+	case *ast.GenDecl:
+		fmt.Println("\n", n.Doc.Text())
+		return
+	case *ast.FuncDecl:
+		fmt.Println("\n", n.Doc.Text())
+		return
+	}
+}
+```
+
+
+We used `IntuitiveMethodSet` to compute the method set, instead
+of `NewMethodSet`.
+The result of this convenience function, which is intended for use in
+user interfaces, includes methods of `*T` as well as those of
+`T`, since that matches most users' intuition about the method
+set of a type.
+(Our example, `http.File`, didn't illustrate the difference, but  try
+running it on a type with both value and pointer methods.)
+
+
+
+Also notice `PathEnclosingInterval`, which finds the set of AST
+nodes that enclose a particular point, in this case, the object's
+declaring identifier.
+By walking up with path, we find the enclosing declaration, to which
+the documentation is attached.
+
+
+
+# Formatting support
+
+
+All types that satisfy `Type` or `Object` define a
+`String` method that formats the type or object in a readable
+notation.   `Selection` also provides a `String` method.
+All package-level objects within these data structures are
+printed with the complete package path, as in these examples:
+
+
+	[]encoding/json.Marshaler                                     // a *Slice type
+	encoding/json.Marshal                                         // a *Func object
+	(*encoding/json.Encoder).Encode                               // a *Func object (method)
+	func (enc *encoding/json.Encoder) Encode(v interface{}) error // a method *Signature
+	func NewEncoder(w io.Writer) *encoding/json.Encoder           // a function *Signature
+
+
+This notation is unambiguous, but it is not legal Go syntax.
+Also, package paths may be long, and the same package path may appear
+many times in a single string, for instance, when formatting a
+function of several parameters.
+Because these strings often form part of a tool's user interface---as
+with the diagnostic messages of `hugeparam` or the code generated
+by `skeleton`---many clients want more control over the
+formatting of package names.
+
+
+
+The `go/types` package provides these alternatives to the
+`String` methods:
+
+
+	func ObjectString(obj Object, qf Qualifier) string
+	func TypeString(typ Type, qf Qualifier) string
+	func SelectionString(s *Selection, qf Qualifier) string
+	
+	type Qualifier func(*Package) string
+
+
+The `TypeString`, `ObjectString`, and `SelectionString`
+functions are like the `String` methods of the respective types,
+but they accept an additional argument, a `Qualifier`.
+
+
+
+A `Qualifier` is a client-provided function that determines how a
+package name is rendered as a string.
+If it is nil, the default behavior is to print the package's
+path, just like the `String` methods do.
+If a caller passes `(*Package).Name` as the qualifier, that is, a
+function that accepts a package and returns its `Name`, then
+objects are qualified only by the package name.
+The above examples would look like this:
+
+
+	[]json.Marshaler
+	json.Marshal
+	(*json.Encoder).Encode
+	func (enc *json.Encoder) Encode(v interface{}) error
+	func NewEncoder(w io.Writer) *json.Encoder
+
+
+Often when a tool prints some output, it is implicitly in the
+context of a particular package, perhaps one specified by the
+command line or HTTP request.
+In that case, it is more natural to omit the package qualification
+altogether for objects belonging to that package, but to qualify all
+other objects by their package's path.
+That's what the `RelativeTo(pkg)` qualifier does:
+
+
+	func RelativeTo(pkg *Package) Qualifier
+
+
+The examples below show how `json.NewEncoder` would be printed
+using three qualifiers, each relative to a different package:
+
+
+	// RelativeTo "encoding/json":
+	func NewEncoder(w io.Writer) *Encoder
+	
+	// RelativeTo "io":
+	func NewEncoder(w Writer) *encoding/json.Encoder
+	
+	// RelativeTo any other package:
+	func NewEncoder(w io.Writer) *encoding/json.Encoder
+
+
+Another qualifier that may be relevant to refactoring tools (but is
+not currently provided by the type checker) is one that renders each
+package name using the locally appropriate name within a given source
+file.
+Its behavior would depend on the set of import declarations, including
+renaming imports, within that source file.
+
+
+
+# Getting from A to B
+
+
+The type checker and its related packages represent many aspects of a
+Go program in many different ways, and analysis tools must often map
+between them.
+For instance, a named entity may be identified by its `Object`;
+by its declaring identifier (`ast.Ident`) or by any referring
+identifier; by its declaring `ast.Node`; by the position
+(`token.Pos`) of any those nodes; or by the filename and
+line/column number (or byte offset) of those `token.Pos` values.
+
+
+
+In this section, we'll list solutions to a number of common problems
+of the form "I have an A; I need the corresponding B".
+
+
+
+To map **from a `token.Pos` to an `ast.Node`**, call the
+helper function
+[`astutil.PathEnclosingInterval`](https://godoc.org/golang.org/x/tools/go/ast/astutil#PathEnclosingInterval).
+It returns the enclosing `ast.Node`, and all its ancestors up to
+the root of the file.
+You must know which file `*ast.File` the `token.Pos` belongs to.
+Alternatively, you can search an entire program loaded by the
+`loader` package, using
+[`(*loader.Program).PathEnclosingInterval`](https://godoc.org/golang.org/x/tools/go/loader#Program.PathEnclosingInterval).
+
+
+
+To map **from an `Object` to its declaring syntax**, call
+`Pos` to get its position, then use `PathEnclosingInterval` as before.
+This approach is suitable for a one-off query.  For repeated use, it
+may be more efficient to visit the syntax tree and construct the
+mapping between declarations and objects.
+
+
+
+To map **from an `ast.Ident` to the `Object`** it refers to (or
+declares), consult the `Uses` or `Defs` map for the
+package, as shown in [Identifier Resolution](#identifier_resolution).
+
+
+
+To map **from an `Object` to its documentation**, find the
+object's declaration, and look at the attached `Doc` field.
+You must have set the parser's `ParseComments` flag.
+See the `doc` example in [Imports](#imports).
diff --git a/gotypes/defsuses/main.go b/gotypes/defsuses/main.go
new file mode 100644
index 0000000..608c529
--- /dev/null
+++ b/gotypes/defsuses/main.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+const hello = `package main
+
+import "fmt"
+
+func main() {
+        fmt.Println("Hello, world")
+}
+`
+
+//!+
+func PrintDefsUses(fset *token.FileSet, files ...*ast.File) error {
+	conf := types.Config{Importer: importer.Default()}
+	info := &types.Info{
+		Defs: make(map[*ast.Ident]types.Object),
+		Uses: make(map[*ast.Ident]types.Object),
+	}
+	_, err := conf.Check("hello", fset, files, info)
+	if err != nil {
+		return err // type error
+	}
+
+	for id, obj := range info.Defs {
+		fmt.Printf("%s: %q defines %v\n",
+			fset.Position(id.Pos()), id.Name, obj)
+	}
+	for id, obj := range info.Uses {
+		fmt.Printf("%s: %q uses %v\n",
+			fset.Position(id.Pos()), id.Name, obj)
+	}
+	return nil
+}
+
+//!-
+
+func main() {
+	// Parse one file.
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "hello.go", hello, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+	if err := PrintDefsUses(fset, f); err != nil {
+		log.Fatal(err) // type error
+	}
+}
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/defsuses
+$ ./defsuses
+hello.go:1:9: "main" defines <nil>
+hello.go:5:6: "main" defines func hello.main()
+hello.go:6:9: "fmt" uses package fmt
+hello.go:6:13: "Println" uses func fmt.Println(a ...interface{}) (n int, err error)
+//!-output
+*/
diff --git a/gotypes/doc/main.go b/gotypes/doc/main.go
new file mode 100644
index 0000000..3140f47
--- /dev/null
+++ b/gotypes/doc/main.go
@@ -0,0 +1,77 @@
+// The doc command prints the doc comment of a package-level object.
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"log"
+	"os"
+
+	// TODO: these will use std go/types after Feb 2016
+	"golang.org/x/tools/go/loader"
+	"golang.org/x/tools/go/types/typeutil"
+)
+
+func main() {
+	if len(os.Args) != 3 {
+		log.Fatal("Usage: doc <package> <object>")
+	}
+	//!+part1
+	pkgpath, name := os.Args[1], os.Args[2]
+
+	// The loader loads a complete Go program from source code.
+	conf := loader.Config{ParserMode: parser.ParseComments}
+	conf.Import(pkgpath)
+	lprog, err := conf.Load()
+	if err != nil {
+		log.Fatal(err) // load error
+	}
+
+	// Find the package and package-level object.
+	pkg := lprog.Package(pkgpath).Pkg
+	obj := pkg.Scope().Lookup(name)
+	if obj == nil {
+		log.Fatalf("%s.%s not found", pkg.Path(), name)
+	}
+	//!-part1
+	//!+part2
+
+	// Print the object and its methods (incl. location of definition).
+	fmt.Println(obj)
+	for _, sel := range typeutil.IntuitiveMethodSet(obj.Type(), nil) {
+		fmt.Printf("%s: %s\n", lprog.Fset.Position(sel.Obj().Pos()), sel)
+	}
+
+	// Find the path from the root of the AST to the object's position.
+	// Walk up to the enclosing ast.Decl for the doc comment.
+	_, path, _ := lprog.PathEnclosingInterval(obj.Pos(), obj.Pos())
+	for _, n := range path {
+		switch n := n.(type) {
+		case *ast.GenDecl:
+			fmt.Println("\n", n.Doc.Text())
+			return
+		case *ast.FuncDecl:
+			fmt.Println("\n", n.Doc.Text())
+			return
+		}
+	}
+	//!-part2
+}
+
+/*
+//!+output
+$ ./doc net/http File
+type net/http.File interface{Readdir(count int) ([]os.FileInfo, error); Seek(offset int64, whence int) (int64, error); Stat() (os.FileInfo, error); io.Closer; io.Reader}
+/go/src/io/io.go:92:2: method (net/http.File) Close() error
+/go/src/io/io.go:71:2: method (net/http.File) Read(p []byte) (n int, err error)
+/go/src/net/http/fs.go:65:2: method (net/http.File) Readdir(count int) ([]os.FileInfo, error)
+/go/src/net/http/fs.go:66:2: method (net/http.File) Seek(offset int64, whence int) (int64, error)
+/go/src/net/http/fs.go:67:2: method (net/http.File) Stat() (os.FileInfo, error)
+
+ A File is returned by a FileSystem's Open method and can be
+served by the FileServer implementation.
+
+The methods should behave the same as those on an *os.File.
+//!-output
+*/
diff --git a/gotypes/go-types.md b/gotypes/go-types.md
new file mode 100644
index 0000000..a00b0fd
--- /dev/null
+++ b/gotypes/go-types.md
@@ -0,0 +1,2035 @@
+
+# `go/types`: The Go Type Checker
+
+This document is maintained by Alan Donovan `adonovan@google.com`.
+
+[October 2015 GothamGo talk on go/types](https://docs.google.com/presentation/d/13OvHYozAUBeISPRoLgG7kMBuja1NsU1D_mMlmbaYojk/view)
+
+
+# Contents
+
+%toc
+
+# Introduction
+
+
+The [`go/types` package]('https://golang.org/pkg/go/types) is a
+type-checker for Go programs, designed by Robert Griesemer.
+Measured by lines of code and by API surface area, it is one of the
+most complex packages in Go's standard library, and using it requires
+a firm grasp of the structure of Go programs.
+This tutorial will help you find your bearings.
+It comes with several example programs that you can obtain with `go get` and play with.
+We assume you are a proficient Go programmer who wants to build tools
+to analyze or manipulate Go programs and that you have some knowledge
+of how a typical compiler works.
+
+
+
+The `go/types` package became part of Go's standard library in Go 1.5.
+Prior to that, it was located at
+[`golang.org/x/tools/go/types`](https://godoc.org/golang.org/x/tools/go/types),
+though that package will be deleted one month after the release
+of Go 1.6 in early 2016.
+
+
+
+The type checker complements several existing
+standard packages for analyzing Go programs.
+We've listed them below.
+
+
+	→   go/types
+	    go/constant
+	    go/parser
+	    go/ast
+	    go/scanner
+	    go/token
+
+
+Starting at the bottom, the
+[`go/token` package](http://golang.org/pkg/go/token)
+defines the lexical tokens of Go.
+The [`go/scanner` package](http://golang.org/pkg/go/scanner) tokenizes an input stream and records
+file position information for use in diagnostics
+or for file surgery in a refactoring tool.
+The [`go/ast` package](http://golang.org/pkg/go/ast)
+defines the data types of the abstract syntax tree (AST).
+The [`go/parser` package](http://golang.org/pkg/go/parser)
+provides a robust recursive-descent parser that constructs the AST.
+And [`go/constant`](http://golang.org/pkg/go/constant)
+provides representations and arithmetic operations for the values of compile-time
+constant expressions, as we'll see in
+[Constants](#constants).
+
+
+
+The [`golang.org/x/tools/go/loader` package](https://godoc.org/golang.org/x/tools/go/loader)
+from the `x/tools` repository is a client of the type
+checker that loads, parses, and type-checks a complete Go program from
+source code.
+We use it in some of our examples and you may find it useful too.
+(Please note that until March 2016, the
+`golang.org/x/tools/...` packages will continue to depend on the
+old `golang.org/x/tools/go/types` package, not on the
+new standard `go/types` package.  The two are almost identical.)
+
+
+
+The Go type checker does three main things.
+First, for every name in the program, it determines which declaration
+the name refers to; this is known as _identifier resolution_.
+Second, for every expression in the program, it determines what type
+that expression has, or reports an error if the expression has no
+type, or has an inappropriate type for its context; this is known as
+_type deduction_.
+Third, for every constant expression in the program, it determines the
+value of that constant; this is known as _constant evaluation_.
+
+
+
+Superficially, it appears that these three processes could be done
+sequentially, in the order above, but perhaps surprisingly, they must
+be done together.
+For example, the value of a constant may depend on the type of an
+expression due to operators like `unsafe.Sizeof`.
+Conversely, the type of an expression may depend on the value of a
+constant, since array types contain constants.
+As a result, type deduction and constant evaluation must be done
+together.
+
+
+
+As another example, we cannot resolve the identifier `k` in the composite
+literal `T{k: 0}` until we know whether `T` is a struct type.
+If it is, then `k` must be found among `T`'s fields.
+If not, then `k` is an ordinary reference
+to a constant or variable in the lexical environment.
+Consequently, identifier resolution and type deduction are also
+inseparable in the general case.
+
+
+
+Nonetheless, the three processes of identifier resolution, type
+deduction, and constant evaluation can be separated for the purpose of
+explanation.
+
+
+# An Example
+
+
+The code below shows the most basic use of the type checker to check
+the _hello, world_ program, supplied as a string.
+Later examples will be variations on this one, and we'll often omit
+boilerplate details such as parsing.
+To check out and build the examples,
+run `go get github.com/golang/example/gotypes/...`.
+
+
+%include pkginfo/main.go
+
+
+First, the program creates a
+[`token.FileSet`](http://golang.org/pkg/go/token/#FileSet).
+To avoid the need to store file names and line and column
+numbers in every node of the syntax tree, the `go/token` package
+provides `FileSet`, a data structure that stores this information
+compactly for a sequence of files.
+A `FileSet` records each file name only once, and records
+only the byte offsets of each newline, allowing a position within
+any file to be identified using a small integer called a
+`token.Pos`.
+Many tools create a single `FileSet` at startup.
+Any part of the program that needs to convert a `token.Pos` into
+an intelligible location---as part of an error message, for
+instance---must have access to the `FileSet`.
+
+
+
+Second, the program parses the input string.
+More realistic packages contain several source files, so the parsing
+step must be repeated for each one, or better still, done in parallel.
+Third, it creates a `Config` that specifies type-checking options.
+Since the _hello, world_ program uses imports, we must indicate
+how to locate the imported packages.
+Here we use `importer.Default()`, which loads compiler-generated
+export data, but we'll explore alternatives in [Imports](#imports).
+
+	
+
+Fourth, the program calls `Check`.
+This creates a `Package` whose path is `"cmd/hello"`, and
+type-checks each of the specified files---just one in this example.
+The final (nil) argument is a pointer to an optional `Info`
+struct that returns additional deductions from the type checker; more
+on that later.
+`Check` returns a `Package` even when it also returns an error.
+The type checker is robust to ill-formed input,
+and goes to great lengths to report accurate
+partial information even in the vicinity of syntax or type errors.
+`Package` has this definition:
+
+
+	type Package struct{ ... }
+	func (*Package) Path() string
+	func (*Package) Name() string
+	func (*Package) Scope() *Scope
+	func (*Package) Imports() []*Package
+
+
+Finally, the program prints the attributes of the package, shown below.
+(The hexadecimal number may vary from one run to the next.)
+
+
+%include pkginfo/main.go output -
+
+
+A package's `Path`, such as `"encoding/json"`, is the string
+by which import declarations identify it.
+It is unique within a `$GOPATH` workspace,
+and for published packages it must be globally unique.
+
+
+A package's `Name` is the identifier in the `package`
+declaration of each source file within the package, such as `json`.
+The type checker reports an error if not all the package declarations in
+the package agree.
+The package name determines how the package is known when it is
+imported into a file (unless a renaming import is used),
+but is otherwise not visible to a program.
+
+
+`Scope` returns the package's [_lexical block_](#scopes),
+which provides access to all the named entities or
+[_objects_](#objects) declared at package level.
+`Imports` returns the set of packages directly imported by this
+one, and  may be useful for computing dependencies
+([Initialization Order](#initialization_order)).
+
+
+
+# Objects
+
+
+The task of identifier resolution is to map every identifier in the
+syntax tree, that is, every `ast.Ident`, to an object.
+For our purposes, an _object_ is a named entity created by a
+declaration, such as a `var`, `type`, or `func`
+declaration.
+(This is different from the everyday meaning of object in
+object-oriented programming.)
+
+
+
+Objects are represented by the `Object` interface, shown below:
+
+
+	type Object interface {
+	    Name() string   // package local object name
+	    Exported() bool // reports whether the name starts with a capital letter
+	    Type() Type     // object type
+	    Pos() token.Pos // position of object identifier in declaration
+	
+	    Parent() *Scope // scope in which this object is declared
+	    Pkg() *Package  // nil for objects in the Universe scope and labels
+	    Id() string     // object id (see Ids section below)
+	}
+
+
+The first four methods are straightforward; we'll explain the other
+three later.
+`Name` returns the objects's name---an identifier.
+`Exported` is a convenience method that reports whether the first
+letter of `Name` is a capital, indicating that the object may be
+visible from outside the package.
+It's a shorthand for `ast.IsExported(obj.Name())`.
+`Type` returns the object's type; we'll come back to that in
+[Types](#types).
+
+
+
+`Pos` returns the source position of the object's declaring identifier.
+To make sense of a `token.Pos`, we need to call the
+`(*token.FileSet).Position` method, which returns a struct with
+individual fields for the file name, line number, column, and byte
+offset, though usually we just call its `String` method:
+
+
+	fmt.Fprintln(fset.Position(obj.Pos())) // "hello.go:10:6"
+
+
+Not all objects carry position information.
+Since the file format for compiler export data ([Imports](#imports))
+does not record position information, calling `Pos` on an object
+imported from such a file returns zero, also known as
+`token.NoPos`.
+
+
+
+There are eight kinds of objects in the Go type checker.
+Most familiar are the kinds that can be declared at package level:
+constants, variables, functions, and types.
+Less familiar are statement labels, imported package names
+(such as `json` in a file containing an `import "encoding/json"`
+declaration), built-in functions (such as `append` and
+`len`), and the pre-declared `nil`.
+The eight types shown below are the only concrete types that satisfy
+the `Object` interface.
+In other words, `Object` is a _discriminated union_ of 8
+possible types, and we commonly use a type switch to distinguish them.
+
+
+	Object = *Func         // function, concrete method, or abstract method
+	       | *Var          // variable, parameter, result, or struct field
+	       | *Const        // constant
+	       | *TypeName     // named type (except for predeclared ones)
+	       | *Label        // statement label
+	       | *PkgName      // package name, e.g. json after import "encoding/json"
+	       | *Builtin      // predeclared function such as append or len
+	       | *Nil          // predeclared nil
+
+
+`Object`s are canonical.
+That is, two `Object`s `x` and `y` denote the same
+entity if and only if `x==y`.
+Object identity is significant, and objects are routinely compared by
+the addresses of the underlying pointers.
+Although a package-level object is uniquely identified by its name
+and enclosing package, for other objects there is no simple way to
+obtain a string that uniquely identifies it.
+
+
+
+The `Parent` method returns the `Scope` (lexical block) in
+which the object was declared; we'll come back to this in
+[Scopes](#scopes).
+Fields and methods are not found in the lexical environment, so
+their objects have no `Parent`.
+
+
+
+The `Pkg` method returns the `Package` to which this object
+belongs, even for objects not declared at package level.
+Only predeclared objects have no package.
+The `Id` method will be explained in [Ids](#ids).
+
+
+
+Not all methods make sense for each kind of object.  For instance,
+the last four kinds above have no meaningful `Type` method.
+And some kinds of object have methods in addition to those required by the
+`Object` interface:
+
+
+	func (*Func) Scope() *Scope
+	func (*Var) Anonymous() bool
+	func (*Var) IsField() bool
+	func (*Const) Val() constant.Value
+	func (*PkgName) Imported() *Package
+
+
+`(*Func).Scope` returns the [lexical block](#scopes)
+containing the function's parameters, results,
+and other local declarations.
+`(*Var).IsField` distinguishes struct fields from ordinary
+variables, and `(*Var).Anonymous` discriminates named fields like
+the one in `struct{T T}` from anonymous fields like the one in `struct{T}`.
+`(*Const).Val` returns the value of a named [constant](#constants).
+
+
+
+`(*PkgName).Imported` returns the package (for instance,
+`encoding/json`) denoted by a given import name such as `json`.
+Each time a package is imported, a new `PkgName` object is
+created, usually with the same name as the `Package` it
+denotes, but not always, as in the case of a renaming import.
+`PkgName`s are objects, but `Package`s are not.
+We'll look more closely at this in [Imports](#imports).
+
+
+
+All relationships between the syntax trees (`ast.Node`s) and type
+checker data structures such as `Object`s and `Type`s are
+stored in mappings outside the syntax tree itself.
+Be aware that the `go/ast` package also defines a type called
+`Object` that resembles---and predates---the type checker's
+`Object`, and that `ast.Object`s are held directly by
+identifiers in the AST.
+They are created by the parser, which has a necessarily limited view
+of the package, so the information they represent is at best partial and
+in some cases wrong, as in the `T{k: 0}` example mentioned above.
+If you are using the type checker, there is no reason to use the older
+`ast.Object` mechanism.
+
+
+
+# Identifier Resolution
+
+
+Identifier resolution computes the relationship between
+identifiers and objects.
+Its results are recorded in the `Info` struct optionally passed
+to `Check`.
+The fields related to identifier resolution are shown below.
+
+
+	type Info struct {
+		Defs       map[*ast.Ident]Object
+		Uses       map[*ast.Ident]Object
+		Implicits  map[ast.Node]Object
+		Selections map[*ast.SelectorExpr]*Selection
+		Scopes     map[ast.Node]*Scope
+		...
+	}
+
+
+Since not all facts computed by the type checker are needed by every
+client, the API lets clients control which components of the result
+should be recorded and which discarded: only fields that hold a
+non-nil map will be populated during the call to `Check`.
+
+
+
+The two fields of type `map[*ast.Ident]Object` are the most important:
+`Defs` records _declaring_ identifiers and
+`Uses` records _referring_ identifiers.
+In the example below, the comments indicate which identifiers are of
+which kind.
+
+
+	var x int        // def of x, use of int
+	fmt.Println(x)   // uses of fmt, Println, and x
+	type T struct{U} // def of T, use of U (type), def of U (field)
+
+
+The final line above illustrates why we don't combine `Defs` and
+`Uses` into one map.
+In the anonymous field declaration `struct{U}`, the
+identifier `U` is both a use of the type `U` (a
+`TypeName`) and a definition of the anonymous field (a
+`Var`).
+
+
+
+The function below prints the location of each referring and defining
+identifier in the input program, and the object it refers to.
+
+
+%include defsuses/main.go
+
+
+Let's use the _hello, world_ program again as the input:
+
+
+%include hello/hello.go
+
+
+This is what it prints:
+
+
+%include defsuses/main.go output -
+
+
+Notice that the `Defs` mapping may contain nil entries in a few
+cases.
+The first line of output reports that the package identifier
+`main` is present in the `Defs` mapping, but has no
+associated object.
+
+
+
+The `Implicits` mapping handles two cases of the syntax in
+which an `Object` is declared without an `ast.Ident`, namely type
+switches and import declarations.
+<!--
+A third case: an anonymous function parameter or result variable.
+These objects are returned by Signature.Param and Signature.Result.
+-->
+In the type switch below, which declares a local variable `y`,
+the type of `y` is different in each case of the switch:
+
+
+	switch y := x.(type) {
+	case int:
+		fmt.Printf("%d", y)
+	case string:
+		fmt.Printf("%q", y)
+	default:
+		fmt.Print(y)
+	}
+
+
+To represent this, for each single-type case, the type checker creates
+a separate `Var` object for `y` with the appropriate type,
+and `Implicits` maps each `ast.CaseClause` to the `Var`
+for that case.
+The `default` case, the `nil` case, and cases with more than one
+type all use the regular `Var` object that is associated with the
+identifier `y`, which is found in the `Defs` mapping.
+
+
+
+The import declaration below defines the name `json` without an
+`ast.Ident`:
+
+
+	import "encoding/json"
+
+
+`Implicits` maps this `ast.ImportSpec` to the `PkgName`
+object named `json` that it implicitly declares.
+
+
+
+The `Selections` mapping, of type
+`map[*ast.SelectorExpr]*Selection`, records the meaning of each
+expression of the form _`expr`_`.f`, where _`expr`_ is
+an expression or type and `f` is the name of a field or method.
+These expressions, called _selections_, are represented by
+`ast.SelectorExpr` nodes in the AST.
+We'll talk more about the `Selection` type in [Selections](#selections).
+
+
+
+Not all `ast.SelectorExpr` nodes represent selections.
+Expressions like `fmt.Println`, in which a package name precedes
+the dot, are _qualified identifiers_.
+They do not appear in the `Selections` mapping, but their
+constituent identifiers (such as `fmt` and `Println`) both
+appear in `Uses`.
+
+
+
+Referring identifiers that are not part of an `ast.SelectorExpr`
+are _lexical references_.
+That is, they are resolved to an object by searching for the
+innermost enclosing lexical declaration of that name.
+We'll see how that search works in the next section.
+
+
+# Scopes
+
+
+The `Scope` type is a mapping from names to objects.
+
+
+	type Scope struct{ ... }
+	
+	func (s *Scope) Names() []string
+	func (s *Scope) Lookup(name string) Object
+
+
+`Names` returns the set of names in the mapping, in sorted order.
+(It is not a simple accessor though, so call it sparingly.)
+The `Lookup ` method returns the object for a given name, so we
+can print all the entries or _bindings_ in a scope like this:
+
+
+	for _, name := range scope.Names() {
+		fmt.Println(scope.Lookup(name))
+	}
+
+
+The _scope_ of a declaration of a name is the region of
+program source in which a reference to the name resolves to that
+declaration.  That is, scope is a property of a declaration.
+However, in the `go/types` API, the `Scope` type represents
+a _lexical block_, which is one component of the lexical
+environment.
+Consider the _hello, world_ program again:
+
+
+	package main
+	
+	import "fmt"
+	
+	func main() {
+		const message = "hello, world"
+		fmt.Println(message)
+	}
+
+
+There are four lexical blocks in this program.
+The outermost one is the _universe block_, which maps the
+pre-declared names like `int`, `true`, and `append` to
+their objects---a `TypeName`, a `Const`, and a
+`Builtin`, respectively.
+The universe block is represented by the global variable
+`Universe`, of type `*Scope`, although it's logically a
+constant so you shouldn't modify it.
+
+
+
+Next is the _package block_, which maps `"main"` to the
+`main` function.
+Following that is the _file block_, which maps `"fmt"` to
+the `PkgName` object for this import of the `fmt` package.
+And finally, the innermost block is that of function `main`, a
+local block, which contains the declaration of `message`, a `Const`.
+The `main` function is trivial, but many functions contain
+several blocks since each `if`, `for`, `switch`,
+`case`, or `select` statement creates at least one
+additional block.
+Local blocks nest to arbitrary depths.
+
+
+
+The structure of the lexical environment thus forms a tree, with the
+universe block at the root, the package blocks beneath it, the file
+blocks beneath them, and then any number of local blocks beneath the
+files.
+The following methods of `Scope` make this tree structure
+accessible and navigable:
+
+
+	func (s *Scope) Parent() *Scope
+	func (s *Scope) NumChildren() int
+	func (s *Scope) Child(i int) *Scope
+
+
+`Parent` lets us walk up the tree, and `Child`
+lets us walk down it.
+Note that although the `Parent` of every package `Scope` is
+`Universe`, `Universe` has no children.
+This asymmetry is a consequence of using a global variable to hold
+`Universe`.
+
+
+
+To obtain the universe block, we use the `Universe` global variable.
+To obtain the lexical block of a `Package`, we call its
+`Scope` method.
+To obtain the scope of a file (`*ast.File`), or any smaller piece
+of syntax such as an `*ast.IfStmt`, we consult the `Scopes`
+mapping in the `Info` struct, which maps each block-creating
+syntax node to its block.
+The lexical block of a named function or method can also be obtained
+by calling its `(*Func).Scope` method.
+
+
+<!--
+TODO: explain explicit and implicit blocks 
+TODO: explain Dot imports.
+TODO: explain that Func blocks are associated with FuncType (not FuncDecl or FuncLit)
+-->
+
+
+To look up a name in the lexical environment, we must search the tree
+of lexical blocks, starting at a particular `Scope` and walking
+up to the root until a declaration of the name is found.
+For convenience, the `LookupParent` method does this, returning
+not just the object, if found, but also the `Scope` in which it was
+declared, which may be an ancestor of the initial one:
+
+
+	func (s *Scope) LookupParent(name string, pos token.Pos) (*Scope, Object)
+
+
+The `pos` parameter determines the position in the source code at
+which the name should be resolved.
+The effective lexical environment is different at each point in the
+block because it depends on which local declarations appear
+before or after that point.
+(We'll see an illustration in a moment.)
+
+
+
+`Scope` has several other methods relating to source positions:
+
+
+	func (s *Scope) Pos() token.Pos
+	func (s *Scope) End() token.Pos
+	func (s *Scope) Contains(pos token.Pos) bool
+	func (s *Scope) Innermost(pos token.Pos) *Scope
+
+
+`Pos` and `End` report the `Scope`'s start and end
+position which, for explicit blocks, are coincident with its curly
+braces.
+`Contains` is a convenience method that reports whether a
+position lies in this interval.
+`Innermost` returns the innermost scope containing the specified
+position, which may be a child or other descendent of the initial
+scope.
+
+
+
+These features are useful for tools that wish to resolve names or
+evaluate constant expressions as if they had appeared at a particular
+point within the program.
+The next example program finds all the comments in the input,
+treating the contents of each one as a name.  It looks up each name in
+the environment at the position of the comment, and prints what it
+finds.
+Observe that the `ParseComments` flag directs the parser to
+preserve comments in the input.
+
+
+%include lookup/lookup.go main
+
+
+The expression `pkg.Scope().Innermost(pos)` finds the innermost
+`Scope` that encloses the comment, and `LookupParent(name, pos)`
+does a name lookup at a specific position in that lexical block.
+
+
+
+A typical input is shown below. 
+The first comment causes a lookup of `"append"` in the file block.
+The second comment looks up `"fmt"` in the `main` function's block,
+and so on.
+
+
+%include lookup/lookup.go input -
+
+
+Here's the output:
+
+
+%include lookup/lookup.go output -
+
+
+Notice how the two lookups of `main` return different results,
+even though they occur in the same block, because one precedes the
+declaration of the local variable named `main` and the other
+follows it.
+Also notice that there are two lookups of the name `x` but only
+the first one, in the function block, succeeds.
+
+
+
+Download the program and modify both the input program and
+the set of comments to get a better feel for how name resolution works.
+
+
+
+The table below summarizes which kinds of object may be declared at
+each level of the tree of lexical blocks.
+
+
+                Universe File Package Local
+    Builtin        ✔
+    Nil            ✔
+    Const          ✔            ✔      ✔
+    TypeName       ✔            ✔      ✔
+    Func                        ✔
+    Var                         ✔      ✔
+    PkgName               ✔
+    Label                              ✔
+
+# Initialization Order
+
+
+In the course of identifier resolution, the type checker constructs a
+graph of references among declarations of package-level variables and
+functions.
+The type checker reports an error if the initializer expression for a
+variable refers to that variable, whether directly or indirectly.
+
+
+
+The reference graph determines the initialization order of the
+package-level variables, as required by the Go spec, using a
+breadth-first algorithm.
+First, variables in the graph with no successors are removed, sorted
+into the order in which they appear in the source code, then added
+to a list.  This creates more variables that have no successors.
+The process repeats until they have all been removed.
+
+
+
+The result is available in the `InitOrder` field of the
+`Info` struct, whose type is `[]Initializer`.
+
+
+	type Info struct {
+		...
+		InitOrder []Initializer
+		...
+	}
+	
+	type Initializer struct {
+		Lhs []*Var // var Lhs = Rhs
+		Rhs ast.Expr
+	}
+
+
+Each element of the list represents a single initializer expression
+that must be executed, and the variables to which it is assigned.
+The variables may number zero, one, or more, as in these examples:
+
+
+	var _ io.Writer = new(bytes.Buffer)
+	var rx = regexp.MustCompile("^b(an)*a$")
+	var cwd, cwdErr = os.Getwd()
+
+
+This process governs the initialization order of variables within a
+package.
+Across packages, dependencies must be initialized first, although the
+order among them is not specified.
+That is, any topological order of the import graph will do.
+The `(*Package).Imports` method returns the set of direct
+dependencies of a package, in an unspecified order.
+
+
+# Types
+
+
+The main job of the type checker is, of course, to deduce the type
+of each expression and to report type errors.
+Like `Object`, `Type` is an interface type used as a
+discriminated union of several concrete types but, unlike
+`Object`, `Type` has very few methods because types have
+little in common with each other.
+Here is the interface:
+
+
+	type Type interface {
+		Underlying() Type
+	}
+
+
+And here are the eleven concrete types that satisfy it:
+
+
+	Type = *Basic
+	     | *Pointer
+	     | *Array
+	     | *Slice
+	     | *Map
+	     | *Chan
+	     | *Struct
+	     | *Tuple
+	     | *Signature
+	     | *Named
+	     | *Interface
+
+
+With the exception of `Named` types, instances of `Type` are
+not canonical.
+That is, it is usually a mistake to compare types using `t1==t2`
+since this equivalence is not the same as the
+[type identity relation](https://golang.org/ref/spec#Type_identity)
+defined by the Go spec.
+Use this function instead:
+
+
+	func Identical(t1, t2 Type) bool
+
+
+For the same reason, you should not use a `Type` as a key in a map.
+The [`golang.org/x/tools/go/types/typeutil` package](https://godoc.org/golang.org/x/tools/go/types/typeutil)
+provides a map keyed by types that uses the correct
+equivalence relation.
+
+
+The Go spec defines three relations over types.
+[_Assignability_](https://golang.org/ref/spec#Assignability)
+governs which pairs of types may appear on the
+left- and right-hand side of an assignment, including implicit
+assignments such as function calls, map and channel operations, and so
+on.
+[_Comparability_](https://golang.org/ref/spec#Comparison_operators)
+determines which types may appear in a comparison `x==y` or a
+switch case or may be used as a map key.
+[_Convertibility_](https://golang.org/ref/spec#Conversions)
+governs which pairs of types are allowed in a conversion operation
+`T(v)`.
+You can query these relations with the following predicate functions:
+
+
+	func AssignableTo(V, T Type) bool
+	func Comparable(T Type) bool
+	func ConvertibleTo(V, T Type) bool
+
+
+Let's take a look at each kind of type.
+
+
+## Basic types
+
+
+`Basic` represents all types that are not composed from simpler
+types.
+This is essentially the set of underlying types that a constant expression is
+permitted to have--strings, booleans, and numbers---but it also
+includes `unsafe.Pointer` and untyped nil.
+
+
+	type Basic struct{...}
+	func (*Basic) Kind() BasicKind
+	func (*Basic) Name() string
+	func (*Basic) Info() BasicInfo
+
+
+The `Kind` method returns an "enum" value that indicates which
+basic type this is.
+The kinds `Bool`, `String`, `Int16`, and so on,
+represent the corresponding predeclared boolean, string, or numeric
+types.
+There are two synonyms: `Byte` is equivalent to `Uint8`
+and `Rune` is equivalent to `Int32`.
+The kind `UnsafePointer` represents `unsafe.Pointer`.
+The kinds `UntypedBool`, `UntypedInt` and so on represent
+the six kinds of "untyped" constant types: boolean, integer, rune,
+float, complex, and string.
+The kind `UntypedNil` represents the type of the predeclared
+`nil` value.
+And the kind `Invalid` indicates the invalid type, which is used
+for expressions containing errors, or for objects without types, like
+`Label`, `Builtin`, or `PkgName`.
+
+
+
+The `Name` method returns the name of the type, such as
+`"float64"`, and the `Info` method returns a bitfield that
+encodes information about the type, such as whether it is signed or
+unsigned, integer or floating point, real or complex.
+
+
+
+`Typ` is a table of canonical basic types, indexed by
+kind, so `Typ[String]` returns the `*Basic` that represents
+`string`, for instance.
+Like `Universe`, `Typ` is logically a constant, so don't
+modify it.
+
+
+
+A few minor subtleties:
+According to the Go spec, pre-declared types such as `int` are
+named types for the purposes of assignability, even though the type
+checker does not represent them using `Named`.
+And `unsafe.Pointer` is a pointer type for the purpose of
+determining whether the receiver type of a method is legal, even
+though the type checker does not represet it using `Pointer`.
+
+
+
+The "untyped" types are usually only ascribed to constant expressions,
+but there is one exception.
+A comparison `x==y` has type "untyped bool", so the result of
+this expression may be assigned to a variable of type `bool` or
+any other named boolean type.
+
+
+
+## Simple Composite Types
+
+
+The types `Pointer`, `Array`, `Slice`, `Map`,
+and `Chan` are pretty self-explanatory.
+All have an `Elem` method that returns the element type `T`
+for a pointer `*T`, an array `[n]T`, a slice `[]T`, a
+map `map[K]T`, or a channel `chan T`.
+This should feel familiar if you've used the `reflect.Value` API.
+
+
+
+In addition, the `*Map`, `*Chan`, and `*Array` types
+have accessor methods that return their key type, direction, and
+length, respectively:
+
+
+	func (*Map) Key() Type
+	func (*Chan) Dir() ChanDir      // = Send | Recv | SendRecv
+	func (*Array) Len() int64
+
+
+
+## Struct Types
+
+
+A struct type has an ordered list of fields and a corresponding
+ordered list of field tags.
+
+
+	type Struct struct{ ... } 
+	func (*Struct) NumFields() int
+	func (*Struct) Field(i int) *Var
+	func (*Struct) Tag(i int) string
+
+
+Each field is a `Var` object whose `IsField` method returns true.
+Field objects have no `Parent` scope, because they are
+resolved through selections, not through the lexical environment.
+
+
+
+Thanks to embedding, the expression `new(S).f` may be a shorthand
+for a longer expression such as `new(S).d.e.f`, but in the
+representation of `Struct` types, these field selection
+operations are explicit.
+That is, the set of fields of struct type `S` does not include `f`.
+An anonymous field is represented like a regular field, but its
+`Anonymous` method returns true.
+
+
+
+One subtlety is relevent to tools that generate documentation.
+When analyzing a declaration such as this,
+
+
+	type T struct{x int}
+
+
+it may be tempting to consider the `Var` object for field `x` as if it
+had the name `"T.x"`, but beware: field objects do not have
+canonical names and there is no way to obtain the name `"T"`
+from the `Var` for `x`.
+That's because several types may have the same underlying struct type,
+as in this code:
+
+
+	type T struct{x int}
+	type U T
+
+
+Here, the `Var` for field `x` belongs equally to `T`
+and to `U`, and short of inspecting source positions or walking
+the AST---neither of which is possible for objects loaded from compiler
+export data---it is not possible to ascertain that `x` was declared as
+part of `T`.
+The type checker computes the exact same data structures given this input:
+
+
+	type T U
+	type U struct{x int}
+
+
+A similar issue applies to the methods of named interface types.
+
+					 
+## Tuple Types
+
+
+Like a struct, a tuple type has an ordered list of fields, and fields
+may be named.
+
+
+	type Tuple struct{ ... }
+	func (*Tuple) Len() int
+	func (*Tuple) At(i int) *Var
+
+
+Although tuples are not the type of any variable in Go, they are
+the type of some expressions, such as the right-hand sides of these
+assignments:
+
+
+	v, ok = m[key]
+	v, ok = <-ch
+	v, ok = x.(T)
+	f, err = os.Open(filename)
+
+
+Tuples also represent the types of the parameter list and the result
+list of a function, as we will see.
+
+
+
+Since empty tuples are common, the nil `*Tuple` pointer is a valid empty tuple.
+
+
+
+## Function and Method Types
+
+
+The types of functions and methods are represented by a `Signature`,
+which has a tuple of parameter types and a tuple of result types.
+
+
+	type Signature struct{ ... }
+	func (*Signature) Recv() *Var
+	func (*Signature) Params() *Tuple
+	func (*Signature) Results() *Tuple
+	func (*Signature) Variadic() bool
+
+
+Variadic functions such as `fmt.Println` have the `Variadic`
+flag set.
+The final parameter of such functions is always a slice, or in the
+special case of certain calls to `append`, a string.
+
+
+
+A `Signature` for a method, whether concrete or abstract, has a
+non-nil receiver parameter, `Recv`.
+The type of the receiver is usually a named type or a pointer to a named type, 
+but it may be an unnamed struct or interface type in some cases.
+Method types are rather second-class: they are only used for the
+`Func` objects created by method declarations, and no Go
+expression has a method type.
+When printing a method type, the receiver does not appear, and the
+`Identical` predicate ignores the receiver.
+
+
+
+The types of `Builtin` objects like `append` cannot be
+expressed as a `Signature` since those types require parametric
+polymorphism.
+`Builtin` objects are thus ascribed the `Invalid` basic type.
+However, the type of each _call_ to a built-in function has a specific
+and expressible Go type.
+These types are recorded during type checking for later use
+([TypeAndValue](#typeandvalue)).
+
+
+
+## Named Types
+
+
+A type declaration creates a `TypeName` object, and the type of
+that object is a `Named`.
+These two entities, an object and a type, are distinct but closely
+related, and they exist in one-to-one correpondence.
+
+
+	type Named struct{ ... }
+	func (*Named) NumMethods() int
+	func (*Named) Method(i int) *Func
+	func (*Named) Obj() *TypeName
+	func (*Named) Underlying() Type
+
+
+The `Named` type's `Obj` method returns the `TypeName` object, which
+provides the name, position, and other properties of the declaration.
+Conversely, the `TypeName` object's `Type` method returns the `Named` type.
+
+
+
+The `NumMethods` and `Method` methods enumerate the declared
+methods associated with this `Named` type (or a pointer to it),
+in the order they were declared.
+However, due to the subtleties of anonymous fields and the difference
+between value and pointer receivers, a named type may have more or fewer
+methods than this list.  We'll return to this in [Method Sets](#method_sets).
+
+
+
+Every `Type` has an `Underlying` method, but for all of them
+except `*Named`, it is simply the identity function.
+For a named type, `Underlying` returns its underlying type, which
+is always an unnamed type.
+Thus `Underlying` returns `int` for both `T` and
+`U` below.
+
+
+	type T int
+	type U T
+
+
+Clients of the type checker often use type assertions or type switches
+with a `Type` operand.
+When doing so, it is often necessary to switch on the type that
+_underlies_ the type of interest, and failure to do so may be a
+bug.
+
+This is a common pattern:
+
+
+	// handle types of composite literal
+	switch u := t.Underlying().(type) {
+	case *Struct:        // ...
+	case *Map:           // ...
+	case *Array, *Slice: // ...
+	default:
+		panic("impossible")
+	}
+
+## Interface Types
+
+
+Interface types are represented by `Interface`.
+
+
+	type Interface struct{ ... }
+	func (*Interface) Empty() bool
+	func (*Interface) NumMethods() int
+	func (*Interface) Method(i int) *Func
+	func (*Interface) NumEmbeddeds() int
+	func (*Interface) Embedded(i int) *Named
+	func (*Interface) NumExplicitMethods() int
+	func (*Interface) ExplicitMethod(i int) *Func
+
+
+Syntactically, an interface type has a list of explicitly declared
+methods (`ExplicitMethod`), and a list of embedded named
+interface types (`Embedded`), but many clients care only about
+the complete set of methods, which can be enumerated via
+`Method`.
+All three lists are ordered by name.
+Since the empty interface is an important special case, the
+`Empty` predicate provides a shorthand for `NumMethods() ==
+0`.
+
+
+
+As with the fields of structs (see above), the methods of interfaces
+may belong equally to more than one interface type.
+The `Func` object for method `f` in the code below is shared
+by `I` and `J`:
+
+
+	type I interface { f() }
+	type J I
+
+
+Because the difference between interface (abstract) and
+non-interface (concrete) types is so important in Go, the
+`IsInterface` predicate is provided for convenience.
+
+
+	func IsInterface(Type) bool
+
+
+The type checker provides three utility methods relating to interface
+satisfaction:
+
+
+	func Implements(V Type, T *Interface) bool
+	func AssertableTo(V *Interface, T Type) bool
+	func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType bool)
+
+
+The `Implements` predicate reports whether a type satisifies an
+interface type.
+`MissingMethod` is like `Implements`, but instead of
+returning false, it explains why a type does not satisfy the
+interface, for use in diagnostics.
+
+
+
+`AssertableTo` reports whether a type assertion `v.(T)` is legal.
+If `T` is a concrete type that doesn't have all the methods of
+interface `v`, then the type assertion is not legal, as in this example:
+
+
+	// error: io.Writer is not assertible to int
+	func f(w io.Writer) int { return w.(int) } 
+
+
+
+## TypeAndValue
+
+
+The type checker records the type of each expression in another field
+of the `Info` struct, namely `Types`:
+
+
+	type Info struct {
+		...
+		Types map[ast.Expr]TypeAndValue
+	}
+
+
+No entry is recorded for identifiers since the `Defs` and
+`Uses` maps provide more information about them.
+Also, no entry is recorded for pseudo-expressions like
+`*ast.KeyValuePair` or `*ast.Ellipsis`.
+
+
+
+The value of the `Types` map is a `TypeAndValue`, which
+(unsurprisingly) holds the `Type` and value of the expression, and in
+addition, its _mode_.
+The mode is opaque, but has predicates to answer questions such as:
+Does this expression denote a value or a type?  Does this value have an
+address?  Does this expression appear on the left-hand side of an
+assignment?  Does this expression appear in a context that expects two
+results?
+The comments in the code below give examples of expressions that
+satisfy each predicate.
+
+
+	type TypeAndValue struct {
+		Type  Type
+		Value constant.Value // for constant expressions only
+		...
+	}
+	
+	func (TypeAndValue) IsVoid() bool      // e.g. "main()"
+	func (TypeAndValue) IsType() bool      // e.g. "*os.File"
+	func (TypeAndValue) IsBuiltin() bool   // e.g. "len(x)"
+	func (TypeAndValue) IsValue() bool     // e.g. "*os.Stdout"
+	func (TypeAndValue) IsNil() bool       // e.g. "nil"
+	func (TypeAndValue) Addressable() bool // e.g. "a[i]" but not "f()", "m[key]"
+	func (TypeAndValue) Assignable() bool  // e.g. "a[i]", "m[key]"
+	func (TypeAndValue) HasOk() bool       // e.g. "&lt;-ch", "m[key]"
+
+
+The statement below inspects every expression within the AST of a single
+type-checked file and prints its type, value, and mode:
+
+
+%include typeandvalue/main.go inspect
+
+
+It makes use of these two helper functions, which are not shown:
+
+
+	// nodeString formats a syntax tree in the style of gofmt.
+	func nodeString(n ast.Node) string
+	
+	// mode returns a string describing the mode of an expression.
+	func mode(tv types.TypeAndValue) string
+
+
+Given this input:
+
+
+%include typeandvalue/main.go input -
+
+
+the program prints:
+
+
+%include typeandvalue/main.go output -
+
+
+Notice that the identifiers for the built-ins `make` and
+`print` have types that are specific to the particular calls in
+which they appear.
+Also notice `m["hello"]` has a 2-tuple type `(int, bool)`
+and that it is assignable, but unlike the variable `m`, it is not
+addressable.
+
+
+
+Download the example and vary the inputs and see what the program prints.
+
+
+
+Here's another example, adapted from the `govet` static checking tool.
+It checks for accidental uses of a method value `x.f` when a
+call `x.f()` was intended;
+comparing a method `x.f` against nil is a common mistake.
+
+
+%include nilfunc/main.go
+
+
+Given this input,
+
+
+%include nilfunc/main.go input -
+
+
+the program reports these errors:
+
+
+%include nilfunc/main.go output -
+
+# Selections
+
+
+A _selection_ is an expression _`expr`_`.f` in which
+`f` denotes either a struct field or a method.
+A selection is resolved not by looking for a name in the lexical
+environment, but by looking within a _type_.
+The type checker ascertains the meaning of each selection in the
+package---a surprisingly tricky business---and records it in the
+`Selections` mapping of the `Info` struct, whose values are
+of type `Selection`:
+
+
+	type Selection struct{ ... }
+	func (s *Selection) Kind() SelectionKind // = FieldVal | MethodVal | MethodExpr
+	func (s *Selection) Recv() Type
+	func (s *Selection) Obj() Object
+	func (s *Selection) Type() Type
+	func (s *Selection) Index() []int
+	func (s *Selection) Indirect() bool
+
+
+The `Kind` method discriminates between the three (legal) kinds
+of selections, as indicated by the comments below.
+
+
+	type T struct{Field int}
+	func (T) Method() {}
+	var v T
+	
+                         // Kind            Type
+        var _ = v.Field  // FieldVal        int
+        var _ = v.Method // MethodVal       func()
+        var _ = T.Method // MethodExpr      func(T)
+
+
+Because of embedding, a selection may denote more than one field or
+method, in which case it is ambiguous, and no `Selection` is
+recorded for it.
+
+
+
+The `Obj` method returns the `Object` for the selected field
+(`*Var`) or method (`*Func`).
+Due to embedding, the object may belong to a different type than that
+of the receiver expression _`expr`_.
+The `Type` method returns the type of the selection.  For a field
+selection, this is the type of the field, but for method selections,
+the result is a function type that is not the same as the type of the
+method.
+For a `MethodVal`, the receiver parameter is dropped, and
+for a `MethodExpr`, the receiver parameter becomes a regular
+parameter, as shown in the example above.
+
+
+
+The `Index` and `Indirect` methods report information about
+implicit operations occurring during the selection that a compiler
+would need to know about.
+Because of embedding, a selection _`expr`_`.f` may be
+shorthand for a sequence containing several implicit field selections,
+_`expr`_`.d.e.f`, and `Index` reports the complete
+sequence.
+And because of automatic pointer dereferencing during struct field
+accesses and method calls, a selection may imply one or more indirect
+loads from memory; `Indirect` reports whether this occurs.
+
+
+
+Clients of the type checker can call `LookupFieldOrMethod` to
+look up a name within a type, as if by a selection.
+This function has an intimidating signature, but conceptually it
+accepts just a `Type` and a name, and returns a `Selection`:
+
+
+	func LookupFieldOrMethod(T Type, addressable bool, pkg *Package, name string) \
+	    (obj Object, index []int, indirect bool)
+
+
+The result is not actually a `Selection`, but it contains the
+three main components of one: `Obj`, `Index`,
+and `Indirect`.
+
+
+
+The `addressable` flag should be set if the receiver is a
+_variable_ of type `T`, since in a method selection on a
+variable, an implicit address-of operation (`&amp;`) may occur.
+The flag indicates whether the methods of type `*T` should be
+considered during the lookup.
+
+
+
+(You may wonder why this parameter is necessary.  Couldn't clients
+instead call `LookupFieldOrMethod` on the pointer type `*T`
+if the receiver is a `T` variable?  The answer is that if
+`T` is an interface type, the type `*T` has no methods at
+all.)
+
+
+
+The final two parameters of `LookupFieldOrMethod` are `(pkg
+*Package, name string)`.  
+Together they specify the name of the field or method to look up.
+This brings us to `Id`s.
+
+
+
+# Ids
+
+
+`LookupFieldOrMethod`'s need for a `Package` parameter
+is a subtle consequence of the
+[_Uniqueness of identifiers_](https://golang.org/ref/spec#Uniqueness_of_identifiers)
+section in the Go spec: "Two
+identifiers are different if they are spelled differently, or if they
+appear in different packages and are not exported."
+In practical terms, this means that a type may have have two methods
+(or two fields, or one of each) both named `f` so long as those
+methods are defined in different packages, as in this example:
+
+
+	package a
+	type A int
+	func (A) f()
+	
+	package b
+	type B int
+	func (B) f()
+	
+	package c
+	import ( "a"; "b" )
+	type C struct{a.A; b.B} // C has two methods called f
+
+
+The type `c.C` has two methods named `f`, but there is
+no ambiguity because the two `f`s are distinct
+identifiers---think of them as `fᵃ` and `fᵇ`.
+For an exported method, this situation _would_ be ambiguous
+because there is no distinction between `Fᵃ` and `Fᵇ`; there
+is only `F`.
+
+
+
+Despite having two methods called `f`, neither of them can be
+called from within package `c` because `c` has no way to
+identify them.
+Within `c`,  `f` is the identifier `fᶜ`, and
+type `C` has no method of that name.
+But if we pass an instance of `C` to code in package `a`
+and call its `f` method via an interface, `fᵃ` is called.
+
+
+
+The practical consequence for tool builders is that any time you need
+to look up a field or method by name, or construct a map of fields and/or
+methods keyed by name, it is not sufficient to use the object's name
+as a key.
+Instead, you must call the `Object.Id` method, which returns
+a string that incorporates the object name, and for unexported
+objects, the package path too.
+There is also a standalone function `Id` that combines a name and
+the package path in the same way:
+
+
+	func Id(pkg *Package, name string) string
+
+
+This distinction applies to selections _`expr`_`.f`, but not
+to lexical references `x` because for unexported identifiers,
+declarations and references always appear in the same package.
+
+
+
+Fun fact: the `reflect.StructField` type records both the
+`Name` and the `PkgPath` strings for the same reason.
+The `FieldByName` methods of `reflect.Value` and
+`reflect.Type` match field names without regard to the package.
+If there is more than one match, they return an invalid value.
+
+
+
+
+# Method Sets
+
+
+The _method set_ of a type is the set of methods that can be
+called on any value of that type.
+(A variable of type `T` has access to all the methods of type
+`*T` as well, due to the implicit address-of operation during
+method calls, but those extra methods are not part of the method set
+of `T`.)
+
+
+
+Clients can request the method set of a type `T` by calling
+`NewMethodSet(T)`:
+
+
+	type MethodSet struct{ ... }
+	func NewMethodSet(T Type) *MethodSet
+	func (s *MethodSet) Len() int
+	func (s *MethodSet) At(i int) *Selection
+	func (s *MethodSet) Lookup(pkg *Package, name string) *Selection
+
+
+The `Len` and `At` methods access a a list of
+`Selections`, all of kind `MethodVal`, ordered by `Id`.
+The `Lookup` function allows lookup of a single method by
+name (and package path, as explained in the previous section).
+
+
+
+`NewMethodSet` can be expensive, so for applications that compute
+method sets repeatedly, `golang.org/x/tools/go/types/typeutil`
+provides a `MethodSetCache` type that records previous results.
+If you only need a single method, don't construct the
+`MethodSet` at all; it's cheaper to use
+`LookupFieldOrMethod`.
+
+
+
+The next program generates a boilerplate
+declaration of a new concrete type that satisifies an existing
+interface.
+Here's an example:
+
+
+%include skeleton/main.go output1 -
+
+
+The three arguments are the package and the name of the existing
+interface type, and the name of the new concrete type.
+The `main` function (not shown) loads the specified package and
+calls `PrintSkeleton` with the remaining two arguments:
+
+
+%include skeleton/main.go
+
+
+First, `PrintSkeleton` locates the package-level named interface
+type, handling various error cases.
+Then it chooses the name for the receiver of the new methods: the
+first letter of the concrete type.
+Finally, it iterates over the method set of the interface, printing
+the corresponding concrete method declarations.
+
+
+
+There's a subtlety in the declaration of `sig`, which is the
+string form of the method signature.
+We could have obtained this string from `meth.Type().String()`,
+but this would cause any named types within it to be formatted with
+the complete package path, for instance
+`net/http.ResponseWriter`, which is informative in diagnostics
+but not legal Go syntax.
+The `TypeString` function (explained in [Formatting Values](#formatting-values)) allows the
+caller to control how packages are printed.
+Passing `(*types.Package).Name` causes only the package name
+`http` to be printed, not the complete path.
+Here's another example that illustrates it:
+
+
+%include skeleton/main.go output2 -
+
+
+The following program inspects all pairs of package-level named types
+in `pkg`, and reports the types that satisfy each interface type.
+
+
+%include implements/main.go implements
+
+
+Given this input,
+
+
+%include implements/main.go input
+
+
+the program prints:
+
+
+%include implements/main.go output -
+
+
+Notice that the method set of `B` does not include `g`, but
+the method set of `*B` does.
+That's why we needed the second assignability check, using the pointer
+type `types.NewPointer(T)`.
+
+
+
+# Constants
+
+
+A constant expression is one whose value is guaranteed to be computed at
+compile time.
+Constant expressions may appear in types, specifically as the length
+of an array type such as `[16]byte`, so one of the jobs of the
+type checker is to compute the value of each constant expression.
+
+
+
+As we saw in the `typeandvalue` example, the type checker records
+the value of each constant expression like `"Hello, " + "world"`,
+storing it in the `Value` field of the `TypeAndValue` struct.
+Constants are represented using the `Value` interface from the
+`go/constant` package.
+
+
+	package constant // go/constant
+	
+	type Value interface {
+		Kind() Kind 
+	}
+	
+	type Kind int // one of Unknown, Bool, String, Int, Float, Complex
+
+
+The interface has only one method, for discriminating the various
+kinds of constants, but the package provides many functions for
+inspecting a value of a known kind,
+
+
+	// Accessors
+	func BoolVal(x Value) bool
+	func Float32Val(x Value) (float32, bool)
+	func Float64Val(x Value) (float64, bool)
+	func Int64Val(x Value) (int64, bool)
+	func StringVal(x Value) string
+	func Uint64Val(x Value) (uint64, bool)
+	func Bytes(x Value) []byte
+	func BitLen(x Value) int
+	func Sign(x Value) int
+
+
+for performing arithmetic on values,
+
+
+	// Operations
+	func Compare(x Value, op token.Token, y Value) bool
+	func UnaryOp(op token.Token, y Value, prec uint) Value
+	func BinaryOp(x Value, op token.Token, y Value) Value
+	func Shift(x Value, op token.Token, s uint) Value
+	func Denom(x Value) Value
+	func Num(x Value) Value
+	func Real(x Value) Value
+	func Imag(x Value) Value
+
+
+and for constructing new values:
+
+
+	// Constructors
+	func MakeBool(b bool) Value
+	func MakeFloat64(x float64) Value
+	func MakeFromBytes(bytes []byte) Value
+	func MakeFromLiteral(lit string, tok token.Token, prec uint) Value
+	func MakeImag(x Value) Value
+	func MakeInt64(x int64) Value
+	func MakeString(s string) Value
+	func MakeUint64(x uint64) Value
+	func MakeUnknown() Value
+
+
+All numeric `Value`s, whether integer or floating-point, signed or
+unsigned, or real or complex, are represented more precisely than the
+ordinary Go types like `int64` and `float64`.
+Internally, the `go/constant` package uses multi-precision data types
+like `Int`, `Rat`, and `Float` from the `math/big` package so that
+`Values` and their arithmetic operations are accurate to at least 256
+bits, as required by the Go specification.
+
+
+<!-- TODO example -->
+
+
+# Size and Alignment
+
+
+Because the calls `unsafe.Sizeof(v)`, `unsafe.Alignof(v)`,
+and `unsafe.Offsetof(v.f)` are all constant expressions, the type
+checker must be able to compute the memory layout of any value
+`v`.
+
+
+
+By default, the type checker uses the same layout algorithm as the Go
+1.5 `gc` compiler targeting `amd64`.
+Clients can configure the type checker to use a different algorithm by
+providing an instance of the `types.Sizes` interface in the
+`types.Config` struct:
+
+
+	package types
+	
+	type Sizes interface {
+		Alignof(T Type) int64
+		Offsetsof(fields []*Var) []int64
+		Sizeof(T Type) int64
+	}
+
+
+
+For common changes, like reducing the word size to 32 bits, clients
+can use an instance of `StdSizes`:
+
+
+	type StdSizes struct {
+		WordSize int64
+		MaxAlign int64
+	}
+
+
+This type has two basic size and alignment parameters from which it
+derives all the other values using common assumptions.
+For example, pointers, functions, maps, and channels fit in one word,
+strings and interfaces require two words, and slices need three.
+The default behaviour is equivalent to `StdSizes{8, 8}`.
+For more esoteric layout changes, you'll need to write a new
+implementation of the `Sizes` interface.
+
+
+
+The `hugeparam` program below prints all function parameters and
+results whose size exceeds a threshold.
+By default, the threshold is 48 bytes, but you can set it via the
+`-bytes` command-line flag.
+Such a tool could help identify inefficient parameter passing in your
+programs.
+
+
+%include hugeparam/main.go
+
+
+As before, `Inspect` applies a function to every node in the AST.
+The function cares about two kinds of nodes: declarations of named
+functions and methods (`*ast.FuncDecl`) and function literals
+(`*ast.FuncLit`).
+Observe the two cases' different logic to obtain the type of each
+function.
+
+
+
+Here's a typical invocation on the standard `encoding/xml` package.
+It reports a number of places where the 7-word
+[`StartElement` type](https://godoc.org/encoding/xml#StartElement)
+is copied.
+
+
+%include hugeparam/main.go output -
+
+# Imports
+
+
+The type checker's `Check` function processes a slice of parsed
+files (`[]*ast.File`) that make up one package.
+When the type checker encounters an import declaration, it needs the
+type information for the objects in the imported package.
+It gets it by calling the `Import` method of the `Importer`
+interface shown below, an instance of which must be provided by the
+`Config`.
+This separation of concerns relieves the type checker from having to
+know any of the details of Go workspace organization, `GOPATH`,
+compiler file formats, and so on.
+
+
+	type Importer interface {
+		Import(path string) (*Package, error)
+	}
+
+
+Most of our examples used the simplest `Importer` implementation,
+`importer.Default()`, provided by the `go/importer` package.
+This importer looks in `$GOROOT` and `$GOPATH` for `.a`
+files written by the compiler (`gc` or `gccgo`)
+that was used to build the program.
+In addition to object code, these files contain _export data_,
+that is, a description of all the objects declared by the package, and
+also of any objects from other packages that were referred to indirectly.
+Because export data includes information about dependencies, the type
+checker need load at most one file per import, instead of one per
+transitive dependency.
+
+
+
+Compiler export data is compact and efficient to locate, load, and
+parse, but it has several shortcomings.
+First, it does not contain position information for imported
+objects, reducing the quality of certain diagnostic messages.
+Second, it does not contain complete syntax trees nor semantic information
+about the contents of function bodies, so it is not suitable for
+interprocedural analyses.
+Third, compiler object data may be stale.  Nothing detects or ensures
+that the object files are more recent than the source files from which
+they were derived.
+Generally, object data for standard packages is likely to be
+up-to-date, but for user packages, it depends on how recently the user
+ran a `go install` or `go build -i` command.
+
+
+
+The [`golang.org/tools/x/go/loader` package](https://godoc.org/golang.org/x/tools/go/loader)
+provides an alternative `Importer` that addresses
+some of these problems.
+It loads a complete program from source, performing
+[`cgo`](https://golang.org/cmd/cgo/cgo) preprocessing if
+necessary, followed by parsing and type-checking.
+It loads independent packages in parallel to hide I/O latency, and
+detects and reports import cycles.
+For each package, it provides the `types.Package` containing the
+package's lexical environment, the list of `ast.File` syntax
+trees for each file in the package, the `types.Info` containing
+type information for each syntax node, and a list of type errors
+associated with that package.
+(Please be aware that the `go/loader` package's API is likely to
+change before it finally stabilizes.)
+
+
+
+The `doc` program below demonstrates a simple use of the loader.
+It is a rudimentary implementation of `go doc` that prints the type,
+methods, and documentation of the package-level object specified on
+the command line.
+Here's an example:
+
+
+%include doc/main.go output -
+
+
+Observe that it prints the correct location of each method
+declaration, even though, due to embedding, some of
+`http.File`'s methods were declared in another package.
+Here's the first part of the program, showing how to load an entire
+program starting from the single package, `pkgpath`:
+
+
+%include doc/main.go part1
+
+
+Notice that we instructed the parser to retain comments during parsing.
+The rest of the program prints the output:
+
+
+%include doc/main.go part2
+
+
+We used `IntuitiveMethodSet` to compute the method set, instead
+of `NewMethodSet`.
+The result of this convenience function, which is intended for use in
+user interfaces, includes methods of `*T` as well as those of
+`T`, since that matches most users' intuition about the method
+set of a type.
+(Our example, `http.File`, didn't illustrate the difference, but  try
+running it on a type with both value and pointer methods.)
+
+
+
+Also notice `PathEnclosingInterval`, which finds the set of AST
+nodes that enclose a particular point, in this case, the object's
+declaring identifier.
+By walking up with path, we find the enclosing declaration, to which
+the documentation is attached.
+
+
+
+# Formatting support
+
+
+All types that satisfy `Type` or `Object` define a
+`String` method that formats the type or object in a readable
+notation.   `Selection` also provides a `String` method.
+All package-level objects within these data structures are
+printed with the complete package path, as in these examples:
+
+
+	[]encoding/json.Marshaler                                     // a *Slice type
+	encoding/json.Marshal                                         // a *Func object
+	(*encoding/json.Encoder).Encode                               // a *Func object (method)
+	func (enc *encoding/json.Encoder) Encode(v interface{}) error // a method *Signature
+	func NewEncoder(w io.Writer) *encoding/json.Encoder           // a function *Signature
+
+
+This notation is unambiguous, but it is not legal Go syntax.
+Also, package paths may be long, and the same package path may appear
+many times in a single string, for instance, when formatting a
+function of several parameters.
+Because these strings often form part of a tool's user interface---as
+with the diagnostic messages of `hugeparam` or the code generated
+by `skeleton`---many clients want more control over the
+formatting of package names.
+
+
+
+The `go/types` package provides these alternatives to the
+`String` methods:
+
+
+	func ObjectString(obj Object, qf Qualifier) string
+	func TypeString(typ Type, qf Qualifier) string
+	func SelectionString(s *Selection, qf Qualifier) string
+	
+	type Qualifier func(*Package) string
+
+
+The `TypeString`, `ObjectString`, and `SelectionString`
+functions are like the `String` methods of the respective types,
+but they accept an additional argument, a `Qualifier`.
+
+
+
+A `Qualifier` is a client-provided function that determines how a
+package name is rendered as a string.
+If it is nil, the default behavior is to print the package's
+path, just like the `String` methods do.
+If a caller passes `(*Package).Name` as the qualifier, that is, a
+function that accepts a package and returns its `Name`, then
+objects are qualified only by the package name.
+The above examples would look like this:
+
+
+	[]json.Marshaler
+	json.Marshal
+	(*json.Encoder).Encode
+	func (enc *json.Encoder) Encode(v interface{}) error
+	func NewEncoder(w io.Writer) *json.Encoder
+
+
+Often when a tool prints some output, it is implicitly in the
+context of a particular package, perhaps one specified by the
+command line or HTTP request.
+In that case, it is more natural to omit the package qualification
+altogether for objects belonging to that package, but to qualify all
+other objects by their package's path.
+That's what the `RelativeTo(pkg)` qualifier does:
+
+
+	func RelativeTo(pkg *Package) Qualifier
+
+
+The examples below show how `json.NewEncoder` would be printed
+using three qualifiers, each relative to a different package:
+
+
+	// RelativeTo "encoding/json":
+	func NewEncoder(w io.Writer) *Encoder
+	
+	// RelativeTo "io":
+	func NewEncoder(w Writer) *encoding/json.Encoder
+	
+	// RelativeTo any other package:
+	func NewEncoder(w io.Writer) *encoding/json.Encoder
+
+
+Another qualifier that may be relevant to refactoring tools (but is
+not currently provided by the type checker) is one that renders each
+package name using the locally appropriate name within a given source
+file.
+Its behavior would depend on the set of import declarations, including
+renaming imports, within that source file.
+
+
+
+# Getting from A to B
+
+
+The type checker and its related packages represent many aspects of a
+Go program in many different ways, and analysis tools must often map
+between them.
+For instance, a named entity may be identified by its `Object`;
+by its declaring identifier (`ast.Ident`) or by any referring
+identifier; by its declaring `ast.Node`; by the position
+(`token.Pos`) of any those nodes; or by the filename and
+line/column number (or byte offset) of those `token.Pos` values.
+
+
+
+In this section, we'll list solutions to a number of common problems
+of the form "I have an A; I need the corresponding B".
+
+
+
+To map **from a `token.Pos` to an `ast.Node`**, call the
+helper function
+[`astutil.PathEnclosingInterval`](https://godoc.org/golang.org/x/tools/go/ast/astutil#PathEnclosingInterval).
+It returns the enclosing `ast.Node`, and all its ancestors up to
+the root of the file.
+You must know which file `*ast.File` the `token.Pos` belongs to.
+Alternatively, you can search an entire program loaded by the
+`loader` package, using
+[`(*loader.Program).PathEnclosingInterval`](https://godoc.org/golang.org/x/tools/go/loader#Program.PathEnclosingInterval).
+
+
+
+To map **from an `Object` to its declaring syntax**, call
+`Pos` to get its position, then use `PathEnclosingInterval` as before.
+This approach is suitable for a one-off query.  For repeated use, it
+may be more efficient to visit the syntax tree and construct the
+mapping between declarations and objects.
+
+
+
+To map **from an `ast.Ident` to the `Object`** it refers to (or
+declares), consult the `Uses` or `Defs` map for the
+package, as shown in [Identifier Resolution](#identifier_resolution).
+
+
+
+To map **from an `Object` to its documentation**, find the
+object's declaration, and look at the attached `Doc` field.
+You must have set the parser's `ParseComments` flag.
+See the `doc` example in [Imports](#imports).
diff --git a/gotypes/hello/hello.go b/gotypes/hello/hello.go
new file mode 100644
index 0000000..01a2862
--- /dev/null
+++ b/gotypes/hello/hello.go
@@ -0,0 +1,10 @@
+//!+
+package main
+
+import "fmt"
+
+func main() {
+	fmt.Println("Hello, 世界")
+}
+
+//!-
diff --git a/gotypes/hugeparam/main.go b/gotypes/hugeparam/main.go
new file mode 100644
index 0000000..ba62aaa
--- /dev/null
+++ b/gotypes/hugeparam/main.go
@@ -0,0 +1,81 @@
+// The hugeparam command identifies by-value parameters that are larger than n bytes.
+//
+// Example:
+//	$ ./hugeparams encoding/xml
+package main
+
+import (
+	"flag"
+	"fmt"
+	"go/ast"
+	"go/token"
+	"log"
+
+	"golang.org/x/tools/go/loader"
+	"golang.org/x/tools/go/types" // TODO: will use std go/types after Mar 2016
+)
+
+//!+
+var bytesFlag = flag.Int("bytes", 48, "maximum parameter size in bytes")
+
+var sizeof = (&types.StdSizes{8, 8}).Sizeof // the sizeof function
+
+func PrintHugeParams(fset *token.FileSet, info *types.Info, files []*ast.File) {
+	checkTuple := func(descr string, tuple *types.Tuple) {
+		for i := 0; i < tuple.Len(); i++ {
+			v := tuple.At(i)
+			if sz := sizeof(v.Type()); sz > int64(*bytesFlag) {
+				fmt.Printf("%s: %q %s: %s = %d bytes\n",
+					fset.Position(v.Pos()),
+					v.Name(), descr, v.Type(), sz)
+			}
+		}
+	}
+	checkSig := func(sig *types.Signature) {
+		checkTuple("parameter", sig.Params())
+		checkTuple("result", sig.Results())
+	}
+	for _, file := range files {
+		ast.Inspect(file, func(n ast.Node) bool {
+			switch n := n.(type) {
+			case *ast.FuncDecl:
+				checkSig(info.Defs[n.Name].Type().(*types.Signature))
+			case *ast.FuncLit:
+				checkSig(info.Types[n.Type].Type.(*types.Signature))
+			}
+			return true
+		})
+	}
+}
+
+//!-
+
+func main() {
+	flag.Parse()
+
+	// The loader loads a complete Go program from source code.
+	var conf loader.Config
+	_, err := conf.FromArgs(flag.Args(), false)
+	if err != nil {
+		log.Fatal(err) // command syntax error
+	}
+	lprog, err := conf.Load()
+	if err != nil {
+		log.Fatal(err) // load error
+	}
+
+	for _, info := range lprog.InitialPackages() {
+		PrintHugeParams(lprog.Fset, &info.Info, info.Files)
+	}
+}
+
+/*
+//!+output
+% ./hugeparam encoding/xml
+/go/src/encoding/xml/marshal.go:167:50: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:734:97: "" result: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:761:51: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/marshal.go:781:68: "start" parameter: encoding/xml.StartElement = 56 bytes
+/go/src/encoding/xml/xml.go:72:30: "" result: encoding/xml.StartElement = 56 bytes
+//!-output
+*/
diff --git a/gotypes/implements/main.go b/gotypes/implements/main.go
new file mode 100644
index 0000000..d7e5701
--- /dev/null
+++ b/gotypes/implements/main.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+//!+input
+const input = `package main
+
+type A struct{}
+func (*A) f()
+
+type B int
+func (B) f()
+func (*B) g()
+
+type I interface { f() }
+type J interface { g() }
+`
+
+//!-input
+
+func main() {
+	// Parse one file.
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "input.go", input, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+	conf := types.Config{Importer: importer.Default()}
+	pkg, err := conf.Check("hello", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err) // type error
+	}
+
+	//!+implements
+	// Find all named types at package level.
+	var allNamed []*types.Named
+	for _, name := range pkg.Scope().Names() {
+		if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok {
+			allNamed = append(allNamed, obj.Type().(*types.Named))
+		}
+	}
+
+	// Test assignability of all distinct pairs of
+	// named types (T, U) where U is an interface.
+	for _, T := range allNamed {
+		for _, U := range allNamed {
+			if T == U || !types.IsInterface(U) {
+				continue
+			}
+			if types.AssignableTo(T, U) {
+				fmt.Printf("%s satisfies %s\n", T, U)
+			} else if !types.IsInterface(T) &&
+				types.AssignableTo(types.NewPointer(T), U) {
+				fmt.Printf("%s satisfies %s\n", types.NewPointer(T), U)
+			}
+		}
+	}
+	//!-implements
+}
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/implements
+$ ./implements
+*hello.A satisfies hello.I
+hello.B satisfies hello.I
+*hello.B satisfies hello.J
+//!-output
+*/
diff --git a/gotypes/lookup/lookup.go b/gotypes/lookup/lookup.go
new file mode 100644
index 0000000..9bdc97d
--- /dev/null
+++ b/gotypes/lookup/lookup.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+	"strings"
+)
+
+//!+input
+const hello = `
+package main
+
+import "fmt"
+
+// append
+func main() {
+        // fmt
+        fmt.Println("Hello, world")
+        // main
+        main, x := 1, 2
+        // main
+        print(main, x)
+        // x
+}
+// x
+`
+
+//!-input
+
+//!+main
+func main() {
+	fset := token.NewFileSet()
+	f, err := parser.ParseFile(fset, "hello.go", hello, parser.ParseComments)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+
+	conf := types.Config{Importer: importer.Default()}
+	pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err) // type error
+	}
+
+	// Each comment contains a name.
+	// Look up that name in the innermost scope enclosing the comment.
+	for _, comment := range f.Comments {
+		pos := comment.Pos()
+		name := strings.TrimSpace(comment.Text())
+		fmt.Printf("At %s,\t%q = ", fset.Position(pos), name)
+		inner := pkg.Scope().Innermost(pos)
+		if _, obj := inner.LookupParent(name, pos); obj != nil {
+			fmt.Println(obj)
+		} else {
+			fmt.Println("not found")
+		}
+	}
+}
+
+//!-main
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/lookup
+$ ./lookup
+At hello.go:6:1,        "append" = builtin append
+At hello.go:8:9,        "fmt" = package fmt
+At hello.go:10:9,       "main" = func cmd/hello.main()
+At hello.go:12:9,       "main" = var main int
+At hello.go:14:9,       "x" = var x int
+At hello.go:16:1,       "x" = not found
+//!-output
+*/
diff --git a/gotypes/nilfunc/main.go b/gotypes/nilfunc/main.go
new file mode 100644
index 0000000..da4b79b
--- /dev/null
+++ b/gotypes/nilfunc/main.go
@@ -0,0 +1,104 @@
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+//!+input
+const input = `package main
+
+import "bytes"
+
+func main() {
+	var buf bytes.Buffer
+	if buf.Bytes == nil && bytes.Repeat != nil && main == nil {
+		// ...
+	}
+}
+`
+
+//!-input
+
+var fset = token.NewFileSet()
+
+func main() {
+	f, err := parser.ParseFile(fset, "input.go", input, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+	conf := types.Config{Importer: importer.Default()}
+	info := &types.Info{
+		Defs:  make(map[*ast.Ident]types.Object),
+		Uses:  make(map[*ast.Ident]types.Object),
+		Types: make(map[ast.Expr]types.TypeAndValue),
+	}
+	if _, err = conf.Check("cmd/hello", fset, []*ast.File{f}, info); err != nil {
+		log.Fatal(err) // type error
+	}
+
+	ast.Inspect(f, func(n ast.Node) bool {
+		if n != nil {
+			CheckNilFuncComparison(info, n)
+		}
+		return true
+	})
+}
+
+//!+
+// CheckNilFuncComparison reports unintended comparisons
+// of functions against nil, e.g., "if x.Method == nil {".
+func CheckNilFuncComparison(info *types.Info, n ast.Node) {
+	e, ok := n.(*ast.BinaryExpr)
+	if !ok {
+		return // not a binary operation
+	}
+	if e.Op != token.EQL && e.Op != token.NEQ {
+		return // not a comparison
+	}
+
+	// If this is a comparison against nil, find the other operand.
+	var other ast.Expr
+	if info.Types[e.X].IsNil() {
+		other = e.Y
+	} else if info.Types[e.Y].IsNil() {
+		other = e.X
+	} else {
+		return // not a comparison against nil
+	}
+
+	// Find the object.
+	var obj types.Object
+	switch v := other.(type) {
+	case *ast.Ident:
+		obj = info.Uses[v]
+	case *ast.SelectorExpr:
+		obj = info.Uses[v.Sel]
+	default:
+		return // not an identifier or selection
+	}
+
+	if _, ok := obj.(*types.Func); !ok {
+		return // not a function or method
+	}
+
+	fmt.Printf("%s: comparison of function %v %v nil is always %v\n",
+		fset.Position(e.Pos()), obj.Name(), e.Op, e.Op == token.NEQ)
+}
+
+//!-
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/nilfunc
+$ ./nilfunc
+input.go:7:5: comparison of function Bytes == nil is always false
+input.go:7:25: comparison of function Repeat != nil is always true
+input.go:7:48: comparison of function main == nil is always false
+//!-output
+*/
diff --git a/gotypes/pkginfo/main.go b/gotypes/pkginfo/main.go
new file mode 100644
index 0000000..3050f80
--- /dev/null
+++ b/gotypes/pkginfo/main.go
@@ -0,0 +1,64 @@
+//!+
+package main
+
+import (
+	"fmt"
+	"go/ast"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+const hello = `package main
+
+import "fmt"
+
+func main() {
+        fmt.Println("Hello, world")
+}`
+
+func main() {
+	fset := token.NewFileSet()
+
+	// Parse the input string, []byte, or io.Reader,
+	// recording position information in fset.
+	// ParseFile returns an *ast.File, a syntax tree.
+	f, err := parser.ParseFile(fset, "hello.go", hello, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+
+	// A Config controls various options of the type checker.
+	// The defaults work fine except for one setting:
+	// we must specify how to deal with imports.
+	conf := types.Config{Importer: importer.Default()}
+
+	// Type-check the package containing only file f.
+	// Check returns a *types.Package.
+	pkg, err := conf.Check("cmd/hello", fset, []*ast.File{f}, nil)
+	if err != nil {
+		log.Fatal(err) // type error
+	}
+
+	fmt.Printf("Package  %q\n", pkg.Path())
+	fmt.Printf("Name:    %s\n", pkg.Name())
+	fmt.Printf("Imports: %s\n", pkg.Imports())
+	fmt.Printf("Scope:   %s\n", pkg.Scope())
+}
+
+//!-
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/pkginfo
+$ ./pkginfo
+Package  "cmd/hello"
+Name:    main
+Imports: [package fmt ("fmt")]
+Scope:   package "cmd/hello" scope 0x820533590 {
+.  func cmd/hello.main()
+}
+//!-output
+*/
diff --git a/gotypes/skeleton/main.go b/gotypes/skeleton/main.go
new file mode 100644
index 0000000..1d8ed14
--- /dev/null
+++ b/gotypes/skeleton/main.go
@@ -0,0 +1,115 @@
+// The skeleton command prints the boilerplate for a concrete type
+// that implements the specified interface type.
+//
+// Example:
+//	$ ./skeleton io ReadWriteCloser buffer
+//	// *buffer implements io.ReadWriteCloser.
+//	type buffer struct{ /* ... */ }
+//	func (b *buffer) Close() error { panic("unimplemented") }
+//	func (b *buffer) Read(p []byte) (n int, err error) { panic("unimplemented") }
+//	func (b *buffer) Write(p []byte) (n int, err error) { panic("unimplemented") }
+package main
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"golang.org/x/tools/go/loader"
+	"golang.org/x/tools/go/types" // TODO: will use std go/types after Feb 2016
+)
+
+const usage = "Usage: skeleton <package> <interface> <concrete>"
+
+//!+
+func PrintSkeleton(pkg *types.Package, ifacename, concname string) error {
+	obj := pkg.Scope().Lookup(ifacename)
+	if obj == nil {
+		return fmt.Errorf("%s.%s not found", pkg.Path(), ifacename)
+	}
+	if _, ok := obj.(*types.TypeName); !ok {
+		return fmt.Errorf("%v is not a named type", obj)
+	}
+	iface, ok := obj.Type().Underlying().(*types.Interface)
+	if !ok {
+		return fmt.Errorf("type %v is a %T, not an interface",
+			obj, obj.Type().Underlying())
+	}
+	// Use first letter of type name as receiver parameter.
+	if !isValidIdentifier(concname) {
+		return fmt.Errorf("invalid concrete type name: %q", concname)
+	}
+	r, _ := utf8.DecodeRuneInString(concname)
+
+	fmt.Printf("// *%s implements %s.%s.\n", concname, pkg.Path(), ifacename)
+	fmt.Printf("type %s struct{}\n", concname)
+	mset := types.NewMethodSet(iface)
+	for i := 0; i < mset.Len(); i++ {
+		meth := mset.At(i).Obj()
+		sig := types.TypeString(meth.Type(), (*types.Package).Name)
+		fmt.Printf("func (%c *%s) %s%s {\n\tpanic(\"unimplemented\")\n}\n",
+			r, concname, meth.Name(),
+			strings.TrimPrefix(sig, "func"))
+	}
+	return nil
+}
+
+//!-
+
+func isValidIdentifier(id string) bool {
+	for i, r := range id {
+		if !unicode.IsLetter(r) &&
+			!(i > 0 && unicode.IsDigit(r)) {
+			return false
+		}
+	}
+	return id != ""
+}
+
+func main() {
+	if len(os.Args) != 4 {
+		log.Fatal(usage)
+	}
+	pkgpath, ifacename, concname := os.Args[1], os.Args[2], os.Args[3]
+
+	// The loader loads a complete Go program from source code.
+	var conf loader.Config
+	conf.Import(pkgpath)
+	lprog, err := conf.Load()
+	if err != nil {
+		log.Fatal(err) // load error
+	}
+	pkg := lprog.Package(pkgpath).Pkg
+	if err := PrintSkeleton(pkg, ifacename, concname); err != nil {
+		log.Fatal(err)
+	}
+}
+
+/*
+//!+output1
+$ ./skeleton io ReadWriteCloser buffer
+// *buffer implements io.ReadWriteCloser.
+type buffer struct{}
+func (b *buffer) Close() error {
+	panic("unimplemented")
+}
+func (b *buffer) Read(p []byte) (n int, err error) {
+	panic("unimplemented")
+}
+func (b *buffer) Write(p []byte) (n int, err error) {
+	panic("unimplemented")
+}
+//!-output1
+
+//!+output2
+$ ./skeleton net/http Handler myHandler
+// *myHandler implements net/http.Handler.
+type myHandler struct{}
+func (m *myHandler) ServeHTTP(http.ResponseWriter, *http.Request) {
+	panic("unimplemented")
+}
+//!-output2
+*/
diff --git a/gotypes/typeandvalue/main.go b/gotypes/typeandvalue/main.go
new file mode 100644
index 0000000..96b7bf0
--- /dev/null
+++ b/gotypes/typeandvalue/main.go
@@ -0,0 +1,130 @@
+package main
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/importer"
+	"go/parser"
+	"go/token"
+	"go/types"
+	"log"
+)
+
+//!+input
+const input = `
+package main
+
+var m = make(map[string]int)
+
+func main() {
+	v, ok := m["hello, " + "world"]
+	print(rune(v), ok)
+}
+`
+
+//!-input
+
+var fset = token.NewFileSet()
+
+func main() {
+	f, err := parser.ParseFile(fset, "hello.go", input, 0)
+	if err != nil {
+		log.Fatal(err) // parse error
+	}
+
+	conf := types.Config{Importer: importer.Default()}
+	info := &types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
+	if _, err := conf.Check("cmd/hello", fset, []*ast.File{f}, info); err != nil {
+		log.Fatal(err) // type error
+	}
+
+	//!+inspect
+	// f is a parsed, type-checked *ast.File.
+	ast.Inspect(f, func(n ast.Node) bool {
+		if expr, ok := n.(ast.Expr); ok {
+			if tv, ok := info.Types[expr]; ok {
+				fmt.Printf("%-24s\tmode:  %s\n", nodeString(expr), mode(tv))
+				fmt.Printf("\t\t\t\ttype:  %v\n", tv.Type)
+				if tv.Value != nil {
+					fmt.Printf("\t\t\t\tvalue: %v\n", tv.Value)
+				}
+			}
+		}
+		return true
+	})
+	//!-inspect
+}
+
+// nodeString formats a syntax tree in the style of gofmt.
+func nodeString(n ast.Node) string {
+	var buf bytes.Buffer
+	format.Node(&buf, fset, n)
+	return buf.String()
+}
+
+// mode returns a string describing the mode of an expression.
+func mode(tv types.TypeAndValue) string {
+	s := ""
+	if tv.IsVoid() {
+		s += ",void"
+	}
+	if tv.IsType() {
+		s += ",type"
+	}
+	if tv.IsBuiltin() {
+		s += ",builtin"
+	}
+	if tv.IsValue() {
+		s += ",value"
+	}
+	if tv.IsNil() {
+		s += ",nil"
+	}
+	if tv.Addressable() {
+		s += ",addressable"
+	}
+	if tv.Assignable() {
+		s += ",assignable"
+	}
+	if tv.HasOk() {
+		s += ",ok"
+	}
+	return s[1:]
+}
+
+/*
+//!+output
+$ go build github.com/golang/example/gotypes/typeandvalue
+$ ./typeandvalue
+make(map[string]int)            mode:  value
+                                type:  map[string]int
+make                            mode:  builtin
+                                type:  func(map[string]int) map[string]int
+map[string]int                  mode:  type
+                                type:  map[string]int
+m["hello"]                      mode:  value,assignable,ok
+                                type:  (int, bool)
+m                               mode:  value,addressable,assignable
+                                type:  map[string]int
+"hello, " + "world"             mode:  value
+                                type:  string
+                                value: "hello, world"
+"hello, "                       mode:  value
+                                type:  untyped string
+                                value: "hello, "
+"world"                         mode:  value
+                                type:  untyped string
+                                value: "world"
+print(rune(v), ok)              mode:  void
+                                type:  ()
+print                           mode:  builtin
+                                type:  func(rune, bool)
+rune(v)                         mode:  value
+                                type:  rune
+rune                            mode:  type
+                                type:  rune
+...more not shown...
+//!-output
+*/
diff --git a/gotypes/weave.go b/gotypes/weave.go
new file mode 100644
index 0000000..770bda2
--- /dev/null
+++ b/gotypes/weave.go
@@ -0,0 +1,191 @@
+// The weave command is a simple preprocessor for markdown files.
+// It builds a table of contents and processes %include directives.
+//
+// Example usage:
+// 	$ go run weave.go go-types.md > README.md
+package main
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"regexp"
+	"strings"
+)
+
+func main() {
+	log.SetFlags(0)
+	log.SetPrefix("weave: ")
+	if len(os.Args) != 2 {
+		log.Fatal("usage: weave input.md\n")
+	}
+
+	f, err := os.Open(os.Args[1])
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer f.Close()
+
+	fmt.Println("<!-- Autogenerated by weave; DO NOT EDIT -->")
+
+	// Pass 1.
+	var toc []string
+	in := bufio.NewScanner(f)
+	for in.Scan() {
+		line := in.Text()
+		if line == "" || (line[0] != '#' && line[0] != '%') {
+			continue
+		}
+		line = strings.TrimSpace(line)
+		if line == "%toc" {
+			toc = nil
+		} else if strings.HasPrefix(line, "# ") || strings.HasPrefix(line, "## ") {
+			words := strings.Fields(line)
+			depth := len(words[0])
+			words = words[1:]
+			text := strings.Join(words, " ")
+			for i := range words {
+				words[i] = strings.ToLower(words[i])
+			}
+			line = fmt.Sprintf("%s1. [%s](#%s)",
+				strings.Repeat("\t", depth-1), text, strings.Join(words, "-"))
+			toc = append(toc, line)
+		}
+	}
+
+	// Pass 2.
+	if _, err := f.Seek(0, os.SEEK_SET); err != nil {
+		log.Fatalf("can't rewind input: %v", err)
+	}
+	in = bufio.NewScanner(f)
+	for in.Scan() {
+		line := in.Text()
+		switch {
+		case strings.HasPrefix(line, "%toc"): // ToC
+			for _, h := range toc {
+				fmt.Println(h)
+			}
+		case strings.HasPrefix(line, "%include"):
+			words := strings.Fields(line)
+			if len(words) < 2 {
+				log.Fatal(line)
+			}
+			filename := words[1]
+
+			// Show caption unless '-' follows.
+			if len(words) < 4 || words[3] != "-" {
+				fmt.Printf("	// go get github.com/golang/example/gotypes/%s\n\n",
+					filepath.Dir(filename))
+			}
+
+			section := ""
+			if len(words) > 2 {
+				section = words[2]
+			}
+			s, err := include(filename, section)
+			if err != nil {
+				log.Fatal(err)
+			}
+			fmt.Println("```")
+			fmt.Println(cleanListing(s)) // TODO(adonovan): escape /^```/ in s
+			fmt.Println("```")
+		default:
+			fmt.Println(line)
+		}
+
+	}
+}
+
+// include processes an included file, and returns the included text.
+// Only lines between those matching !+tag and !-tag will be returned.
+// This is true even if tag=="".
+func include(file, tag string) (string, error) {
+	f, err := os.Open(file)
+	if err != nil {
+		return "", err
+	}
+	defer f.Close()
+
+	startre, err := regexp.Compile("!\\+" + tag + "$")
+	if err != nil {
+		return "", err
+	}
+	endre, err := regexp.Compile("!\\-" + tag + "$")
+	if err != nil {
+		return "", err
+	}
+
+	var text bytes.Buffer
+	in := bufio.NewScanner(f)
+	var on bool
+	for in.Scan() {
+		line := in.Text()
+		switch {
+		case startre.MatchString(line):
+			on = true
+		case endre.MatchString(line):
+			on = false
+		case on:
+			text.WriteByte('\t')
+			text.WriteString(line)
+			text.WriteByte('\n')
+		}
+	}
+	if text.Len() == 0 {
+		return "", fmt.Errorf("no lines of %s matched tag %q", file, tag)
+	}
+	return text.String(), nil
+}
+
+func isBlank(line string) bool { return strings.TrimSpace(line) == "" }
+
+func indented(line string) bool {
+	return strings.HasPrefix(line, "    ") || strings.HasPrefix(line, "\t")
+}
+
+// cleanListing removes entirely blank leading and trailing lines from
+// text, and removes n leading tabs.
+func cleanListing(text string) string {
+	lines := strings.Split(text, "\n")
+
+	// remove minimum number of leading tabs from all non-blank lines
+	tabs := 999
+	for i, line := range lines {
+		if strings.TrimSpace(line) == "" {
+			lines[i] = ""
+		} else {
+			if n := leadingTabs(line); n < tabs {
+				tabs = n
+			}
+		}
+	}
+	for i, line := range lines {
+		if line != "" {
+			line := line[tabs:]
+			lines[i] = line // remove leading tabs
+		}
+	}
+
+	// remove leading blank lines
+	for len(lines) > 0 && lines[0] == "" {
+		lines = lines[1:]
+	}
+	// remove trailing blank lines
+	for len(lines) > 0 && lines[len(lines)-1] == "" {
+		lines = lines[:len(lines)-1]
+	}
+	return strings.Join(lines, "\n")
+}
+
+func leadingTabs(s string) int {
+	var i int
+	for i = 0; i < len(s); i++ {
+		if s[i] != '\t' {
+			break
+		}
+	}
+	return i
+}