This will simplify the generation of go/types files from types2 files.
Change-Id: Ie9c8061346cff098cb884908c7eb569267886594
Reviewed-on: https://go-review.googlesource.com/c/go/+/461082
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
. "cmd/compile/internal/types2"
)
+// nopos indicates an unknown position
+var nopos syntax.Pos
+
func parse(path, src string) (*syntax.File, error) {
errh := func(error) {} // dummy error handler so that parsing continues in presence of errors
return syntax.Parse(syntax.NewFileBase(path), strings.NewReader(src), errh, nil, 0)
}
}
-var nopos syntax.Pos
-
// newDefined creates a new defined type named T with the given underlying type.
func newDefined(underlying Type) *Named {
tname := NewTypeName(nopos, nil, "T", nil)
. "internal/types/errors"
)
+// nopos indicates an unknown position
var nopos syntax.Pos
// debugging/development support
. "go/types"
)
+// nopos indicates an unknown position
+var nopos token.Pos
+
func parse(fset *token.FileSet, filename, src string) (*ast.File, error) {
return parser.ParseFile(fset, filename, src, 0)
}
// newDefined creates a new defined type named T with the given underlying type.
// Helper function for use with TestIncompleteInterfaces only.
func newDefined(underlying Type) *Named {
- tname := NewTypeName(token.NoPos, nil, "T", nil)
+ tname := NewTypeName(nopos, nil, "T", nil)
return NewNamed(tname, underlying, nil)
}
}
func TestIdenticalUnions(t *testing.T) {
- tname := NewTypeName(token.NoPos, nil, "myInt", nil)
+ tname := NewTypeName(nopos, nil, "myInt", nil)
myInt := NewNamed(tname, Typ[Int], nil)
tmap := map[string]*Term{
"int": NewTerm(false, Typ[Int]),
import (
"fmt"
"go/ast"
- "go/token"
. "internal/types/errors"
"strings"
)
at = rhs[len(rhs)-1].expr // report at last value
}
err := newErrorf(at, WrongResultCount, "%s return values", qualifier)
- err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(rhs), false))
- err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(lhs), false))
+ err.errorf(nopos, "have %s", check.typesSummary(operandTypes(rhs), false))
+ err.errorf(nopos, "want %s", check.typesSummary(varTypes(lhs), false))
check.report(err)
return
}
// Construct a suitable new type parameter for the result type.
// The type parameter is placed in the current package so export/import
// works as expected.
- tpar := NewTypeName(token.NoPos, check.pkg, tp.obj.name, nil)
+ tpar := NewTypeName(nopos, check.pkg, tp.obj.name, nil)
ptyp := check.newTypeParam(tpar, NewInterfaceType(nil, []Type{NewUnion(terms)})) // assigns type to tpar as a side-effect
ptyp.index = tp.index
func makeSig(res Type, args ...Type) *Signature {
list := make([]*Var, len(args))
for i, param := range args {
- list[i] = NewVar(token.NoPos, nil, "", Default(param))
+ list[i] = NewVar(nopos, nil, "", Default(param))
}
params := NewTuple(list...)
var result *Tuple
if res != nil {
assert(!isUntyped(res))
- result = NewTuple(NewVar(token.NoPos, nil, "", res))
+ result = NewTuple(NewVar(nopos, nil, "", res))
}
return &Signature{params: params, results: result}
}
params = sig.params.vars
}
err := newErrorf(at, WrongArgCount, "%s arguments in call to %s", qualifier, call.Fun)
- err.errorf(token.NoPos, "have %s", check.typesSummary(operandTypes(args), false))
- err.errorf(token.NoPos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
+ err.errorf(nopos, "have %s", check.typesSummary(operandTypes(args), false))
+ err.errorf(nopos, "want %s", check.typesSummary(varTypes(params), sig.variadic))
check.report(err)
return
}
if ident.Name == "_" {
continue
}
- if _, obj := check.scope.LookupParent(ident.Name, token.NoPos); obj != nil {
+ if _, obj := check.scope.LookupParent(ident.Name, nopos); obj != nil {
// It's ok to mark non-local variables, but ignore variables
// from other packages to avoid potential race conditions with
// dot-imported variables.
. "internal/types/errors"
)
+// nopos indicates an unknown position
+var nopos token.Pos
+
// debugging/development support
const debug = false // leave on during development
if a.desc != nil {
check.trace(a.desc.pos.Pos(), "-- "+a.desc.format, a.desc.args...)
} else {
- check.trace(token.NoPos, "-- delayed %p", a.f)
+ check.trace(nopos, "-- delayed %p", a.f)
}
}
a.f() // may append to check.delayed
package types
import (
- "go/token"
"testing"
)
var nullaryP, nullaryQ, unaryP Type
{
// type nullaryP = func[P any]()
- tparam := NewTypeParam(NewTypeName(token.NoPos, nil, "P", nil), &emptyInterface)
+ tparam := NewTypeParam(NewTypeName(nopos, nil, "P", nil), &emptyInterface)
nullaryP = NewSignatureType(nil, nil, []*TypeParam{tparam}, nil, nil, false)
}
{
// type nullaryQ = func[Q any]()
- tparam := NewTypeParam(NewTypeName(token.NoPos, nil, "Q", nil), &emptyInterface)
+ tparam := NewTypeParam(NewTypeName(nopos, nil, "Q", nil), &emptyInterface)
nullaryQ = NewSignatureType(nil, nil, []*TypeParam{tparam}, nil, nil, false)
}
{
// type unaryP = func[P any](_ P)
- tparam := NewTypeParam(NewTypeName(token.NoPos, nil, "P", nil), &emptyInterface)
- params := NewTuple(NewVar(token.NoPos, nil, "_", tparam))
+ tparam := NewTypeParam(NewTypeName(nopos, nil, "P", nil), &emptyInterface)
+ params := NewTuple(NewVar(nopos, nil, "_", tparam))
unaryP = NewSignatureType(nil, nil, []*TypeParam{tparam}, params, nil, false)
}
func (err *error_) pos() token.Pos {
if err.empty() {
- return token.NoPos
+ return nopos
}
return err.desc[0].posn.Pos()
}
pos := x.Pos()
return posSpan{pos, pos, x.expr.End()}
}
- return posSpan{token.NoPos, token.NoPos, token.NoPos}
+ return posSpan{nopos, nopos, nopos}
default:
pos := at.Pos()
return posSpan{pos, pos, pos}
package types
import (
- "go/token"
"testing"
)
}
want = "0: foo 42"
- err.errorf(token.NoPos, "foo %d", 42)
+ err.errorf(nopos, "foo %d", 42)
if got := err.String(); got != want {
t.Errorf("simple error: got %q, want %q", got, want)
}
want = "0: foo 42\n\tbar 43"
- err.errorf(token.NoPos, "bar %d", 43)
+ err.errorf(nopos, "bar %d", 43)
if got := err.String(); got != want {
t.Errorf("simple error: got %q, want %q", got, want)
}
var scope *Scope
if pkg == nil {
scope = Universe
- pos = token.NoPos
+ pos = nopos
} else if !pos.IsValid() {
scope = pkg.scope
} else {
func TestEvalBasic(t *testing.T) {
fset := token.NewFileSet()
for _, typ := range Typ[Bool : String+1] {
- testEval(t, fset, nil, token.NoPos, typ.Name(), typ, "", "")
+ testEval(t, fset, nil, nopos, typ.Name(), typ, "", "")
}
}
func TestEvalComposite(t *testing.T) {
fset := token.NewFileSet()
for _, test := range independentTestTypes {
- testEval(t, fset, nil, token.NoPos, test.src, nil, test.str, "")
+ testEval(t, fset, nil, nopos, test.src, nil, test.str, "")
}
}
}
fset := token.NewFileSet()
for _, test := range tests {
- testEval(t, fset, nil, token.NoPos, test, Typ[UntypedBool], "", "true")
+ testEval(t, fset, nil, nopos, test, Typ[UntypedBool], "", "true")
}
}
import (
"fmt"
- "go/token"
. "internal/types/errors"
"strings"
)
// but that doesn't impact the isParameterized check for now).
if params.Len() > 0 {
smap := makeSubstMap(tparams, targs)
- params = check.subst(token.NoPos, params, smap, nil, check.context()).(*Tuple)
+ params = check.subst(nopos, params, smap, nil, check.context()).(*Tuple)
}
// Unify parameter and argument types for generic parameters with typed arguments
n := 0
for _, index := range dirty {
t0 := types[index]
- if t1 := check.subst(token.NoPos, t0, smap, nil, check.context()); t1 != t0 {
+ if t1 := check.subst(nopos, t0, smap, nil, check.context()); t1 != t0 {
types[index] = t1
dirty[n] = index
n++
if len(targs) != len(tparams) {
return nil, fmt.Errorf("got %d type arguments but %s has %d type parameters", len(targs), orig, len(tparams))
}
- if i, err := (*Checker)(nil).verify(token.NoPos, tparams, targs, ctxt); err != nil {
+ if i, err := (*Checker)(nil).verify(nopos, tparams, targs, ctxt); err != nil {
return nil, &ArgumentError{i, err}
}
}
- inst := (*Checker)(nil).instance(token.NoPos, orig, targs, nil, ctxt)
+ inst := (*Checker)(nil).instance(nopos, orig, targs, nil, ctxt)
return inst, nil
}
package types_test
import (
- "go/token"
. "go/types"
"strings"
"testing"
// interface{interface{...}} is equivalent to interface{...}
"package equivalentinterfaces; type T[P any] int",
"T", []Type{
- NewInterfaceType([]*Func{NewFunc(token.NoPos, nil, "M", emptySignature)}, nil),
+ NewInterfaceType([]*Func{NewFunc(nopos, nil, "M", emptySignature)}, nil),
},
"T", []Type{
NewInterfaceType(
nil,
[]Type{
- NewInterfaceType([]*Func{NewFunc(token.NoPos, nil, "M", emptySignature)}, nil),
+ NewInterfaceType([]*Func{NewFunc(nopos, nil, "M", emptySignature)}, nil),
},
),
},
}
// typeSet returns the type set for interface t.
-func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, token.NoPos, t) }
+func (t *Interface) typeSet() *_TypeSet { return computeInterfaceTypeSet(t.check, nopos, t) }
// emptyInterface represents the empty (completed) interface
var emptyInterface = Interface{complete: true, tset: &topTypeSet}
// _ T2
// }
// }
- n1 := NewTypeName(token.NoPos, nil, "T1", nil)
+ n1 := NewTypeName(nopos, nil, "T1", nil)
T1 := NewNamed(n1, nil, nil)
- n2 := NewTypeName(token.NoPos, nil, "T2", nil)
+ n2 := NewTypeName(nopos, nil, "T2", nil)
T2 := NewNamed(n2, nil, nil)
- s1 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", T2, false)}, nil)
+ s1 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
T1.SetUnderlying(s1)
- s2 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", T2, false)}, nil)
- s3 := NewStruct([]*Var{NewField(token.NoPos, nil, "_", s2, false)}, nil)
+ s2 := NewStruct([]*Var{NewField(nopos, nil, "_", T2, false)}, nil)
+ s3 := NewStruct([]*Var{NewField(nopos, nil, "_", s2, false)}, nil)
T2.SetUnderlying(s3)
// These calls must terminate (no endless recursion).
func TestIssue55030(t *testing.T) {
// makeSig makes the signature func(typ...)
makeSig := func(typ Type) {
- par := NewVar(token.NoPos, nil, "", typ)
+ par := NewVar(nopos, nil, "", typ)
params := NewTuple(par)
NewSignatureType(nil, nil, nil, params, nil, true)
}
// P where P's core type is string
{
- P := NewTypeName(token.NoPos, nil, "P", nil) // [P string]
+ P := NewTypeName(nopos, nil, "P", nil) // [P string]
makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{Typ[String]})))
}
// P where P's core type is an (unnamed) slice
{
- P := NewTypeName(token.NoPos, nil, "P", nil) // [P []int]
+ P := NewTypeName(nopos, nil, "P", nil) // [P []int]
makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{NewSlice(Typ[Int])})))
}
// P where P's core type is bytestring (i.e., string or []byte)
{
- t1 := NewTerm(true, Typ[String]) // ~string
- t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
- u := NewUnion([]*Term{t1, t2}) // ~string | []byte
- P := NewTypeName(token.NoPos, nil, "P", nil) // [P ~string | []byte]
+ t1 := NewTerm(true, Typ[String]) // ~string
+ t2 := NewTerm(false, NewSlice(Typ[Byte])) // []byte
+ u := NewUnion([]*Term{t1, t2}) // ~string | []byte
+ P := NewTypeName(nopos, nil, "P", nil) // [P ~string | []byte]
makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
}
}
// NewPkgName returns a new PkgName object representing an imported package.
// The remaining arguments set the attributes found with all Objects.
func NewPkgName(pos token.Pos, pkg *Package, name string, imported *Package) *PkgName {
- return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, token.NoPos}, imported, false}
+ return &PkgName{object{nil, pos, pkg, name, Typ[Invalid], 0, black, nopos}, imported, false}
}
// Imported returns the package that was imported.
// NewConst returns a new constant with value val.
// The remaining arguments set the attributes found with all Objects.
func NewConst(pos token.Pos, pkg *Package, name string, typ Type, val constant.Value) *Const {
- return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, val}
+ return &Const{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, val}
}
// Val returns the constant's value.
// argument for NewNamed, which will set the TypeName's type as a side-
// effect.
func NewTypeName(pos token.Pos, pkg *Package, name string, typ Type) *TypeName {
- return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
+ return &TypeName{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
}
// _NewTypeNameLazy returns a new defined type like NewTypeName, but it
// NewVar returns a new variable.
// The arguments set the attributes found with all Objects.
func NewVar(pos token.Pos, pkg *Package, name string, typ Type) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}}
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}}
}
// NewParam returns a new variable representing a function parameter.
func NewParam(pos token.Pos, pkg *Package, name string, typ Type) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, used: true} // parameters are always 'used'
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, used: true} // parameters are always 'used'
}
// NewField returns a new variable representing a struct field.
// For embedded fields, the name is the unqualified type name
// under which the field is accessible.
func NewField(pos token.Pos, pkg *Package, name string, typ Type, embedded bool) *Var {
- return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, embedded: embedded, isField: true}
+ return &Var{object: object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, embedded: embedded, isField: true}
}
// Anonymous reports whether the variable is an embedded field.
if sig != nil {
typ = sig
}
- return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), token.NoPos}, false, nil}
+ return &Func{object{nil, pos, pkg, name, typ, 0, colorFor(typ), nopos}, false, nil}
}
// FullName returns the package- or receiver-type-qualified name of
t.Errorf("%s: invalid object path %s", test.src, test.obj)
continue
}
- _, obj := pkg.Scope().LookupParent(names[0], token.NoPos)
+ _, obj := pkg.Scope().LookupParent(names[0], nopos)
if obj == nil {
t.Errorf("%s: %s not found", test.src, names[0])
continue
}
// Pos returns the position of the expression corresponding to x.
-// If x is invalid the position is token.NoPos.
+// If x is invalid the position is nopos.
func (x *operand) Pos() token.Pos {
// x.expr may not be set if x is invalid
if x.expr == nil {
- return token.NoPos
+ return nopos
}
return x.expr.Pos()
}
import (
"fmt"
- "go/token"
)
// A Package describes a Go package.
// NewPackage returns a new Package for the given package path and name.
// The package is not complete and contains no explicit imports.
func NewPackage(path, name string) *Package {
- scope := NewScope(Universe, token.NoPos, token.NoPos, fmt.Sprintf("package %q", path))
+ scope := NewScope(Universe, nopos, nopos, fmt.Sprintf("package %q", path))
return &Package{path: path, name: name, scope: scope}
}
package types
-import "go/token"
-
// The isX predicates below report whether t is an X.
// If t is a type parameter the result is false; i.e.,
// these predicates don't look inside a type parameter.
// Constraints must be pair-wise identical, after substitution.
for i, xtparam := range xtparams {
- ybound := check.subst(token.NoPos, ytparams[i].bound, smap, nil, ctxt)
+ ybound := check.subst(nopos, ytparams[i].bound, smap, nil, ctxt)
if !identical(xtparam.bound, ybound, cmpTags, p) {
return false
}
}
- yparams = check.subst(token.NoPos, y.params, smap, nil, ctxt).(*Tuple)
- yresults = check.subst(token.NoPos, y.results, smap, nil, ctxt).(*Tuple)
+ yparams = check.subst(nopos, y.params, smap, nil, ctxt).(*Tuple)
+ yresults = check.subst(nopos, y.results, smap, nil, ctxt).(*Tuple)
}
return x.variadic == y.variadic &&
// TODO(rfindley): can this be reached during type checking? If so,
// consider passing a type set map.
unionSets := make(map[*Union]*_TypeSet)
- xset := computeUnionTypeSet(nil, unionSets, token.NoPos, x)
- yset := computeUnionTypeSet(nil, unionSets, token.NoPos, y)
+ xset := computeUnionTypeSet(nil, unionSets, nopos, x)
+ yset := computeUnionTypeSet(nil, unionSets, nopos, y)
return xset.terms.equal(yset.terms)
}
return
}
- check.declare(check.pkg.scope, ident, obj, token.NoPos)
+ check.declare(check.pkg.scope, ident, obj, nopos)
check.objMap[obj] = d
obj.setOrder(uint32(len(check.objMap)))
}
} else {
// declare imported package object in file scope
// (no need to provide s.Name since we called check.recordDef earlier)
- check.declare(fileScope, nil, pkgName, token.NoPos)
+ check.declare(fileScope, nil, pkgName, nopos)
}
case constDecl:
// declare all constants
check.softErrorf(obj, MissingInitBody, "missing function body")
}
} else {
- check.declare(pkg.scope, d.decl.Name, obj, token.NoPos)
+ check.declare(pkg.scope, d.decl.Name, obj, nopos)
}
} else {
// method
import (
"fmt"
"go/ast"
- "go/token"
. "internal/types/errors"
)
// Value (non-type) parameters' scope starts in the function body. Use a temporary scope for their
// declarations and then squash that scope into the parent scope (and report any redeclarations at
// that time).
- scope := NewScope(check.scope, token.NoPos, token.NoPos, "function body (temp. scope)")
+ scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
recvList, _ := check.collectParams(scope, recvPar, false)
params, variadic := check.collectParams(scope, ftyp.Params, true)
results, _ := check.collectParams(scope, ftyp.Results, false)
switch len(recvList) {
case 0:
// error reported by resolver
- recv = NewParam(token.NoPos, nil, "", Typ[Invalid]) // ignore recv below
+ recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
default:
// more than one receiver
check.error(recvList[len(recvList)-1], InvalidRecv, "method has multiple receivers")
package types
import (
- "go/token"
"strings"
"testing"
)
var myInt = func() Type {
- tname := NewTypeName(token.NoPos, nil, "myInt", nil)
+ tname := NewTypeName(nopos, nil, "myInt", nil)
return NewNamed(tname, Typ[Int], nil)
}()
import (
"go/constant"
- "go/token"
"strings"
)
func defPredeclaredTypes() {
for _, t := range Typ {
- def(NewTypeName(token.NoPos, nil, t.name, t))
+ def(NewTypeName(nopos, nil, t.name, t))
}
for _, t := range aliases {
- def(NewTypeName(token.NoPos, nil, t.name, t))
+ def(NewTypeName(nopos, nil, t.name, t))
}
// type any = interface{}
// Note: don't use &emptyInterface for the type of any. Using a unique
// pointer allows us to detect any and format it as "any" rather than
// interface{}, which clarifies user-facing error messages significantly.
- def(NewTypeName(token.NoPos, nil, "any", &Interface{complete: true, tset: &topTypeSet}))
+ def(NewTypeName(nopos, nil, "any", &Interface{complete: true, tset: &topTypeSet}))
// type error interface{ Error() string }
{
- obj := NewTypeName(token.NoPos, nil, "error", nil)
+ obj := NewTypeName(nopos, nil, "error", nil)
obj.setColor(black)
typ := NewNamed(obj, nil, nil)
// error.Error() string
- recv := NewVar(token.NoPos, nil, "", typ)
- res := NewVar(token.NoPos, nil, "", Typ[String])
+ recv := NewVar(nopos, nil, "", typ)
+ res := NewVar(nopos, nil, "", Typ[String])
sig := NewSignatureType(recv, nil, nil, nil, NewTuple(res), false)
- err := NewFunc(token.NoPos, nil, "Error", sig)
+ err := NewFunc(nopos, nil, "Error", sig)
// interface{ Error() string }
ityp := &Interface{methods: []*Func{err}, complete: true}
- computeInterfaceTypeSet(nil, token.NoPos, ityp) // prevent races due to lazy computation of tset
+ computeInterfaceTypeSet(nil, nopos, ityp) // prevent races due to lazy computation of tset
typ.SetUnderlying(ityp)
def(obj)
// type comparable interface{} // marked as comparable
{
- obj := NewTypeName(token.NoPos, nil, "comparable", nil)
+ obj := NewTypeName(nopos, nil, "comparable", nil)
obj.setColor(black)
typ := NewNamed(obj, nil, nil)
func defPredeclaredConsts() {
for _, c := range predeclaredConsts {
- def(NewConst(token.NoPos, nil, c.name, Typ[c.kind], c.val))
+ def(NewConst(nopos, nil, c.name, Typ[c.kind], c.val))
}
}
}
func init() {
- Universe = NewScope(nil, token.NoPos, token.NoPos, "universe")
+ Universe = NewScope(nil, nopos, nopos, "universe")
Unsafe = NewPackage("unsafe", "unsafe")
Unsafe.complete = true