1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Package types declares the data types and implements
6// the algorithms for type-checking of Go packages. Use
7// Config.Check to invoke the type checker for a package.
8// Alternatively, create a new type checker with NewChecker
9// and invoke it incrementally by calling Checker.Files.
10//
11// Type-checking consists of several interdependent phases:
12//
13// Name resolution maps each identifier (syntax.Name) in the program to the
14// language object (Object) it denotes.
15// Use Info.{Defs,Uses,Implicits} for the results of name resolution.
16//
17// Constant folding computes the exact constant value (constant.Value)
18// for every expression (syntax.Expr) that is a compile-time constant.
19// Use Info.Types[expr].Value for the results of constant folding.
20//
21// Type inference computes the type (Type) of every expression (syntax.Expr)
22// and checks for compliance with the language specification.
23// Use Info.Types[expr].Type for the results of type inference.
24//
25package types2
26
27import (
28	"bytes"
29	"cmd/compile/internal/syntax"
30	"fmt"
31	"go/constant"
32)
33
34// An Error describes a type-checking error; it implements the error interface.
35// A "soft" error is an error that still permits a valid interpretation of a
36// package (such as "unused variable"); "hard" errors may lead to unpredictable
37// behavior if ignored.
38type Error struct {
39	Pos  syntax.Pos // error position
40	Msg  string     // default error message, user-friendly
41	Full string     // full error message, for debugging (may contain internal details)
42	Soft bool       // if set, error is "soft"
43}
44
45// Error returns an error string formatted as follows:
46// filename:line:column: message
47func (err Error) Error() string {
48	return fmt.Sprintf("%s: %s", err.Pos, err.Msg)
49}
50
51// FullError returns an error string like Error, buy it may contain
52// type-checker internal details such as subscript indices for type
53// parameters and more. Useful for debugging.
54func (err Error) FullError() string {
55	return fmt.Sprintf("%s: %s", err.Pos, err.Full)
56}
57
58// An ArgumentError holds an error associated with an argument index.
59type ArgumentError struct {
60	Index int
61	Err   error
62}
63
64func (e *ArgumentError) Error() string { return e.Err.Error() }
65func (e *ArgumentError) Unwrap() error { return e.Err }
66
67// An Importer resolves import paths to Packages.
68//
69// CAUTION: This interface does not support the import of locally
70// vendored packages. See https://golang.org/s/go15vendor.
71// If possible, external implementations should implement ImporterFrom.
72type Importer interface {
73	// Import returns the imported package for the given import path.
74	// The semantics is like for ImporterFrom.ImportFrom except that
75	// dir and mode are ignored (since they are not present).
76	Import(path string) (*Package, error)
77}
78
79// ImportMode is reserved for future use.
80type ImportMode int
81
82// An ImporterFrom resolves import paths to packages; it
83// supports vendoring per https://golang.org/s/go15vendor.
84// Use go/importer to obtain an ImporterFrom implementation.
85type ImporterFrom interface {
86	// Importer is present for backward-compatibility. Calling
87	// Import(path) is the same as calling ImportFrom(path, "", 0);
88	// i.e., locally vendored packages may not be found.
89	// The types package does not call Import if an ImporterFrom
90	// is present.
91	Importer
92
93	// ImportFrom returns the imported package for the given import
94	// path when imported by a package file located in dir.
95	// If the import failed, besides returning an error, ImportFrom
96	// is encouraged to cache and return a package anyway, if one
97	// was created. This will reduce package inconsistencies and
98	// follow-on type checker errors due to the missing package.
99	// The mode value must be 0; it is reserved for future use.
100	// Two calls to ImportFrom with the same path and dir must
101	// return the same package.
102	ImportFrom(path, dir string, mode ImportMode) (*Package, error)
103}
104
105// A Config specifies the configuration for type checking.
106// The zero value for Config is a ready-to-use default configuration.
107type Config struct {
108	// Context is the context used for resolving global identifiers. If nil, the
109	// type checker will initialize this field with a newly created context.
110	Context *Context
111
112	// GoVersion describes the accepted Go language version. The string
113	// must follow the format "go%d.%d" (e.g. "go1.12") or ist must be
114	// empty; an empty string indicates the latest language version.
115	// If the format is invalid, invoking the type checker will cause a
116	// panic.
117	GoVersion string
118
119	// If IgnoreFuncBodies is set, function bodies are not
120	// type-checked.
121	IgnoreFuncBodies bool
122
123	// If FakeImportC is set, `import "C"` (for packages requiring Cgo)
124	// declares an empty "C" package and errors are omitted for qualified
125	// identifiers referring to package C (which won't find an object).
126	// This feature is intended for the standard library cmd/api tool.
127	//
128	// Caution: Effects may be unpredictable due to follow-on errors.
129	//          Do not use casually!
130	FakeImportC bool
131
132	// If IgnoreLabels is set, correct label use is not checked.
133	// TODO(gri) Consolidate label checking and remove this flag.
134	IgnoreLabels bool
135
136	// If CompilerErrorMessages is set, errors are reported using
137	// cmd/compile error strings to match $GOROOT/test errors.
138	// TODO(gri) Consolidate error messages and remove this flag.
139	CompilerErrorMessages bool
140
141	// If go115UsesCgo is set, the type checker expects the
142	// _cgo_gotypes.go file generated by running cmd/cgo to be
143	// provided as a package source file. Qualified identifiers
144	// referring to package C will be resolved to cgo-provided
145	// declarations within _cgo_gotypes.go.
146	//
147	// It is an error to set both FakeImportC and go115UsesCgo.
148	go115UsesCgo bool
149
150	// If Trace is set, a debug trace is printed to stdout.
151	Trace bool
152
153	// If Error != nil, it is called with each error found
154	// during type checking; err has dynamic type Error.
155	// Secondary errors (for instance, to enumerate all types
156	// involved in an invalid recursive type declaration) have
157	// error strings that start with a '\t' character.
158	// If Error == nil, type-checking stops with the first
159	// error found.
160	Error func(err error)
161
162	// An importer is used to import packages referred to from
163	// import declarations.
164	// If the installed importer implements ImporterFrom, the type
165	// checker calls ImportFrom instead of Import.
166	// The type checker reports an error if an importer is needed
167	// but none was installed.
168	Importer Importer
169
170	// If Sizes != nil, it provides the sizing functions for package unsafe.
171	// Otherwise SizesFor("gc", "amd64") is used instead.
172	Sizes Sizes
173
174	// If DisableUnusedImportCheck is set, packages are not checked
175	// for unused imports.
176	DisableUnusedImportCheck bool
177}
178
179func srcimporter_setUsesCgo(conf *Config) {
180	conf.go115UsesCgo = true
181}
182
183// Info holds result type information for a type-checked package.
184// Only the information for which a map is provided is collected.
185// If the package has type errors, the collected information may
186// be incomplete.
187type Info struct {
188	// Types maps expressions to their types, and for constant
189	// expressions, also their values. Invalid expressions are
190	// omitted.
191	//
192	// For (possibly parenthesized) identifiers denoting built-in
193	// functions, the recorded signatures are call-site specific:
194	// if the call result is not a constant, the recorded type is
195	// an argument-specific signature. Otherwise, the recorded type
196	// is invalid.
197	//
198	// The Types map does not record the type of every identifier,
199	// only those that appear where an arbitrary expression is
200	// permitted. For instance, the identifier f in a selector
201	// expression x.f is found only in the Selections map, the
202	// identifier z in a variable declaration 'var z int' is found
203	// only in the Defs map, and identifiers denoting packages in
204	// qualified identifiers are collected in the Uses map.
205	//
206	// For binary expressions representing unions in constraint
207	// position or type elements in interfaces, a union type is
208	// recorded for the top-level expression only. For instance,
209	// given the constraint a|b|c, the union type for (a|b)|c
210	// is recorded, but not the union type for a|b.
211	Types map[syntax.Expr]TypeAndValue
212
213	// Instances maps identifiers denoting parameterized types or functions to
214	// their type arguments and instantiated type.
215	//
216	// For example, Instances will map the identifier for 'T' in the type
217	// instantiation T[int, string] to the type arguments [int, string] and
218	// resulting instantiated *Named type. Given a parameterized function
219	// func F[A any](A), Instances will map the identifier for 'F' in the call
220	// expression F(int(1)) to the inferred type arguments [int], and resulting
221	// instantiated *Signature.
222	//
223	// Invariant: Instantiating Uses[id].Type() with Instances[id].TypeArgs
224	// results in an equivalent of Instances[id].Type.
225	Instances map[*syntax.Name]Instance
226
227	// Defs maps identifiers to the objects they define (including
228	// package names, dots "." of dot-imports, and blank "_" identifiers).
229	// For identifiers that do not denote objects (e.g., the package name
230	// in package clauses, or symbolic variables t in t := x.(type) of
231	// type switch headers), the corresponding objects are nil.
232	//
233	// For an embedded field, Defs returns the field *Var it defines.
234	//
235	// Invariant: Defs[id] == nil || Defs[id].Pos() == id.Pos()
236	Defs map[*syntax.Name]Object
237
238	// Uses maps identifiers to the objects they denote.
239	//
240	// For an embedded field, Uses returns the *TypeName it denotes.
241	//
242	// Invariant: Uses[id].Pos() != id.Pos()
243	Uses map[*syntax.Name]Object
244
245	// Implicits maps nodes to their implicitly declared objects, if any.
246	// The following node and object types may appear:
247	//
248	//     node               declared object
249	//
250	//     *syntax.ImportDecl    *PkgName for imports without renames
251	//     *syntax.CaseClause    type-specific *Var for each type switch case clause (incl. default)
252	//     *syntax.Field         anonymous parameter *Var (incl. unnamed results)
253	//
254	Implicits map[syntax.Node]Object
255
256	// Selections maps selector expressions (excluding qualified identifiers)
257	// to their corresponding selections.
258	Selections map[*syntax.SelectorExpr]*Selection
259
260	// Scopes maps syntax.Nodes to the scopes they define. Package scopes are not
261	// associated with a specific node but with all files belonging to a package.
262	// Thus, the package scope can be found in the type-checked Package object.
263	// Scopes nest, with the Universe scope being the outermost scope, enclosing
264	// the package scope, which contains (one or more) files scopes, which enclose
265	// function scopes which in turn enclose statement and function literal scopes.
266	// Note that even though package-level functions are declared in the package
267	// scope, the function scopes are embedded in the file scope of the file
268	// containing the function declaration.
269	//
270	// The following node types may appear in Scopes:
271	//
272	//     *syntax.File
273	//     *syntax.FuncType
274	//     *syntax.BlockStmt
275	//     *syntax.IfStmt
276	//     *syntax.SwitchStmt
277	//     *syntax.CaseClause
278	//     *syntax.CommClause
279	//     *syntax.ForStmt
280	//
281	Scopes map[syntax.Node]*Scope
282
283	// InitOrder is the list of package-level initializers in the order in which
284	// they must be executed. Initializers referring to variables related by an
285	// initialization dependency appear in topological order, the others appear
286	// in source order. Variables without an initialization expression do not
287	// appear in this list.
288	InitOrder []*Initializer
289}
290
291// TypeOf returns the type of expression e, or nil if not found.
292// Precondition: the Types, Uses and Defs maps are populated.
293//
294func (info *Info) TypeOf(e syntax.Expr) Type {
295	if t, ok := info.Types[e]; ok {
296		return t.Type
297	}
298	if id, _ := e.(*syntax.Name); id != nil {
299		if obj := info.ObjectOf(id); obj != nil {
300			return obj.Type()
301		}
302	}
303	return nil
304}
305
306// ObjectOf returns the object denoted by the specified id,
307// or nil if not found.
308//
309// If id is an embedded struct field, ObjectOf returns the field (*Var)
310// it defines, not the type (*TypeName) it uses.
311//
312// Precondition: the Uses and Defs maps are populated.
313//
314func (info *Info) ObjectOf(id *syntax.Name) Object {
315	if obj := info.Defs[id]; obj != nil {
316		return obj
317	}
318	return info.Uses[id]
319}
320
321// TypeAndValue reports the type and value (for constants)
322// of the corresponding expression.
323type TypeAndValue struct {
324	mode  operandMode
325	Type  Type
326	Value constant.Value
327}
328
329// IsVoid reports whether the corresponding expression
330// is a function call without results.
331func (tv TypeAndValue) IsVoid() bool {
332	return tv.mode == novalue
333}
334
335// IsType reports whether the corresponding expression specifies a type.
336func (tv TypeAndValue) IsType() bool {
337	return tv.mode == typexpr
338}
339
340// IsBuiltin reports whether the corresponding expression denotes
341// a (possibly parenthesized) built-in function.
342func (tv TypeAndValue) IsBuiltin() bool {
343	return tv.mode == builtin
344}
345
346// IsValue reports whether the corresponding expression is a value.
347// Builtins are not considered values. Constant values have a non-
348// nil Value.
349func (tv TypeAndValue) IsValue() bool {
350	switch tv.mode {
351	case constant_, variable, mapindex, value, nilvalue, commaok, commaerr:
352		return true
353	}
354	return false
355}
356
357// IsNil reports whether the corresponding expression denotes the
358// predeclared value nil. Depending on context, it may have been
359// given a type different from UntypedNil.
360func (tv TypeAndValue) IsNil() bool {
361	return tv.mode == nilvalue
362}
363
364// Addressable reports whether the corresponding expression
365// is addressable (https://golang.org/ref/spec#Address_operators).
366func (tv TypeAndValue) Addressable() bool {
367	return tv.mode == variable
368}
369
370// Assignable reports whether the corresponding expression
371// is assignable to (provided a value of the right type).
372func (tv TypeAndValue) Assignable() bool {
373	return tv.mode == variable || tv.mode == mapindex
374}
375
376// HasOk reports whether the corresponding expression may be
377// used on the rhs of a comma-ok assignment.
378func (tv TypeAndValue) HasOk() bool {
379	return tv.mode == commaok || tv.mode == mapindex
380}
381
382// Instance reports the type arguments and instantiated type for type and
383// function instantiations. For type instantiations, Type will be of dynamic
384// type *Named. For function instantiations, Type will be of dynamic type
385// *Signature.
386type Instance struct {
387	TypeArgs *TypeList
388	Type     Type
389}
390
391// An Initializer describes a package-level variable, or a list of variables in case
392// of a multi-valued initialization expression, and the corresponding initialization
393// expression.
394type Initializer struct {
395	Lhs []*Var // var Lhs = Rhs
396	Rhs syntax.Expr
397}
398
399func (init *Initializer) String() string {
400	var buf bytes.Buffer
401	for i, lhs := range init.Lhs {
402		if i > 0 {
403			buf.WriteString(", ")
404		}
405		buf.WriteString(lhs.Name())
406	}
407	buf.WriteString(" = ")
408	syntax.Fprint(&buf, init.Rhs, syntax.ShortForm)
409	return buf.String()
410}
411
412// Check type-checks a package and returns the resulting package object and
413// the first error if any. Additionally, if info != nil, Check populates each
414// of the non-nil maps in the Info struct.
415//
416// The package is marked as complete if no errors occurred, otherwise it is
417// incomplete. See Config.Error for controlling behavior in the presence of
418// errors.
419//
420// The package is specified by a list of *syntax.Files and corresponding
421// file set, and the package path the package is identified with.
422// The clean path must not be empty or dot (".").
423func (conf *Config) Check(path string, files []*syntax.File, info *Info) (*Package, error) {
424	pkg := NewPackage(path, "")
425	return pkg, NewChecker(conf, pkg, info).Files(files)
426}
427
428// AssertableTo reports whether a value of type V can be asserted to have type T.
429func AssertableTo(V *Interface, T Type) bool {
430	m, _ := (*Checker)(nil).assertableTo(V, T)
431	return m == nil
432}
433
434// AssignableTo reports whether a value of type V is assignable to a variable of type T.
435func AssignableTo(V, T Type) bool {
436	x := operand{mode: value, typ: V}
437	ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x
438	return ok
439}
440
441// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
442func ConvertibleTo(V, T Type) bool {
443	x := operand{mode: value, typ: V}
444	return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
445}
446
447// Implements reports whether type V implements interface T.
448func Implements(V Type, T *Interface) bool {
449	if T.Empty() {
450		// All types (even Typ[Invalid]) implement the empty interface.
451		return true
452	}
453	// Checker.implements suppresses errors for invalid types, so we need special
454	// handling here.
455	if V.Underlying() == Typ[Invalid] {
456		return false
457	}
458	return (*Checker)(nil).implements(V, T, nil) == nil
459}
460
461// Identical reports whether x and y are identical types.
462// Receivers of Signature types are ignored.
463func Identical(x, y Type) bool {
464	return identical(x, y, true, nil)
465}
466
467// IdenticalIgnoreTags reports whether x and y are identical types if tags are ignored.
468// Receivers of Signature types are ignored.
469func IdenticalIgnoreTags(x, y Type) bool {
470	return identical(x, y, false, nil)
471}
472