1 // Copyright 2014 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.
13 func (check
*Checker
) reportAltDecl(obj Object
) {
14 if pos
:= obj
.Pos(); pos
.IsValid() {
15 // We use "other" rather than "previous" here because
16 // the first declaration seen may not be textually
17 // earlier in the source.
18 check
.errorf(pos
, "\tother declaration of %s", obj
.Name()) // secondary error, \t indented
22 func (check
*Checker
) declare(scope
*Scope
, id
*ast
.Ident
, obj Object
, pos token
.Pos
) {
23 // spec: "The blank identifier, represented by the underscore
24 // character _, may be used in a declaration like any other
25 // identifier but the declaration does not introduce a new
27 if obj
.Name() != "_" {
28 if alt
:= scope
.Insert(obj
); alt
!= nil {
29 check
.errorf(obj
.Pos(), "%s redeclared in this block", obj
.Name())
30 check
.reportAltDecl(alt
)
36 check
.recordDef(id
, obj
)
40 // objDecl type-checks the declaration of obj in its respective (file) context.
41 // See check.typ for the details on def and path.
42 func (check
*Checker
) objDecl(obj Object
, def
*Named
, path
[]*TypeName
) {
43 if obj
.Type() != nil {
44 return // already checked - nothing to do
48 check
.trace(obj
.Pos(), "-- declaring %s", obj
.Name())
52 check
.trace(obj
.Pos(), "=> %s", obj
)
56 d
:= check
.objMap
[obj
]
58 check
.dump("%s: %s should have been declared", obj
.Pos(), obj
.Name())
62 // save/restore current context and setup object context
63 defer func(ctxt context
) {
66 check
.context
= context
{
70 // Const and var declarations must not have initialization
71 // cycles. We track them by remembering the current declaration
72 // in check.decl. Initialization expressions depending on other
73 // consts, vars, or functions, add dependencies to the current
75 switch obj
:= obj
.(type) {
77 check
.decl
= d
// new package-level const decl
78 check
.constDecl(obj
, d
.typ
, d
.init
)
80 check
.decl
= d
// new package-level var decl
81 check
.varDecl(obj
, d
.lhs
, d
.typ
, d
.init
)
83 // invalid recursive types are detected via path
84 check
.typeDecl(obj
, d
.typ
, def
, path
, d
.alias
)
86 // functions may be recursive - no need to track dependencies
87 check
.funcDecl(obj
, d
)
93 func (check
*Checker
) constDecl(obj
*Const
, typ
, init ast
.Expr
) {
94 assert(obj
.typ
== nil)
97 obj
.typ
= Typ
[Invalid
]
102 // use the correct value of iota
103 assert(check
.iota == nil)
105 defer func() { check
.iota = nil }()
107 // provide valid constant value under all circumstances
108 obj
.val
= constant
.MakeUnknown()
110 // determine type, if any
114 // don't report an error if the type is an invalid C (defined) type
116 if t
.Underlying() != Typ
[Invalid
] {
117 check
.errorf(typ
.Pos(), "invalid constant type %s", t
)
119 obj
.typ
= Typ
[Invalid
]
125 // check initialization
130 check
.initConst(obj
, &x
)
133 func (check
*Checker
) varDecl(obj
*Var
, lhs
[]*Var
, typ
, init ast
.Expr
) {
134 assert(obj
.typ
== nil)
137 obj
.typ
= Typ
[Invalid
]
142 // var declarations cannot use iota
143 assert(check
.iota == nil)
145 // determine type, if any
147 obj
.typ
= check
.typ(typ
)
148 // We cannot spread the type to all lhs variables if there
149 // are more than one since that would mark them as checked
150 // (see Checker.objDecl) and the assignment of init exprs,
151 // if any, would not be checked.
153 // TODO(gri) If we have no init expr, we should distribute
154 // a given type otherwise we need to re-evalate the type
155 // expr for each lhs variable, leading to duplicate work.
158 // check initialization
161 // error reported before by arityMatch
162 obj
.typ
= Typ
[Invalid
]
167 if lhs
== nil ||
len(lhs
) == 1 {
168 assert(lhs
== nil || lhs
[0] == obj
)
171 check
.initVar(obj
, &x
, "variable declaration")
176 // obj must be one of lhs
178 for _
, lhs
:= range lhs
{
185 panic("inconsistent lhs")
189 // We have multiple variables on the lhs and one init expr.
190 // Make sure all variables have been given the same type if
191 // one was specified, otherwise they assume the type of the
192 // init expression values (was issue #15755).
194 for _
, lhs
:= range lhs
{
199 check
.initVars(lhs
, []ast
.Expr
{init
}, token
.NoPos
)
202 // underlying returns the underlying type of typ; possibly by following
203 // forward chains of named types. Such chains only exist while named types
205 func underlying(typ Type
) Type
{
216 func (n
*Named
) setUnderlying(typ Type
) {
222 func (check
*Checker
) typeDecl(obj
*TypeName
, typ ast
.Expr
, def
*Named
, path
[]*TypeName
, alias
bool) {
223 assert(obj
.typ
== nil)
225 // type declarations cannot use iota
226 assert(check
.iota == nil)
230 obj
.typ
= Typ
[Invalid
]
231 obj
.typ
= check
.typExpr(typ
, nil, append(path
, obj
))
235 named
:= &Named
{obj
: obj
}
236 def
.setUnderlying(named
)
237 obj
.typ
= named
// make sure recursive type declarations terminate
239 // determine underlying type of named
240 check
.typExpr(typ
, named
, append(path
, obj
))
242 // The underlying type of named may be itself a named type that is
251 // The type of C is the (named) type of A which is incomplete,
252 // and which has as its underlying type the named type B.
253 // Determine the (final, unnamed) underlying type by resolving
254 // any forward chain (they always end in an unnamed type).
255 named
.underlying
= underlying(named
.underlying
)
259 // check and add associated methods
260 // TODO(gri) It's easy to create pathological cases where the
261 // current approach is incorrect: In general we need to know
262 // and add all methods _before_ type-checking the type.
263 // See https://play.golang.org/p/WMpE0q2wK8
264 check
.addMethodDecls(obj
)
267 func (check
*Checker
) addMethodDecls(obj
*TypeName
) {
268 // get associated methods
269 methods
:= check
.methods
[obj
.name
]
270 if len(methods
) == 0 {
273 delete(check
.methods
, obj
.name
)
275 // use an objset to check for name conflicts
278 // spec: "If the base type is a struct type, the non-blank method
279 // and field names must be distinct."
280 base
, _
:= obj
.typ
.(*Named
) // nil if receiver base type is type alias
282 if t
, _
:= base
.underlying
.(*Struct
); t
!= nil {
283 for _
, fld
:= range t
.fields
{
285 assert(mset
.insert(fld
) == nil)
290 // Checker.Files may be called multiple times; additional package files
291 // may add methods to already type-checked types. Add pre-existing methods
292 // so that we can detect redeclarations.
293 for _
, m
:= range base
.methods
{
294 assert(m
.name
!= "_")
295 assert(mset
.insert(m
) == nil)
299 // type-check methods
300 for _
, m
:= range methods
{
301 // spec: "For a base type, the non-blank names of methods bound
302 // to it must be unique."
304 if alt
:= mset
.insert(m
); alt
!= nil {
307 check
.errorf(m
.pos
, "field and method with the same name %s", m
.name
)
309 check
.errorf(m
.pos
, "method %s already declared for %s", m
.name
, obj
)
313 check
.reportAltDecl(alt
)
319 check
.objDecl(m
, nil, nil)
321 // methods with blank _ names cannot be found - don't keep them
322 if base
!= nil && m
.name
!= "_" {
323 base
.methods
= append(base
.methods
, m
)
328 func (check
*Checker
) funcDecl(obj
*Func
, decl
*declInfo
) {
329 assert(obj
.typ
== nil)
331 // func declarations cannot use iota
332 assert(check
.iota == nil)
334 sig
:= new(Signature
)
335 obj
.typ
= sig
// guard against cycles
337 check
.funcType(sig
, fdecl
.Recv
, fdecl
.Type
)
338 if sig
.recv
== nil && obj
.name
== "init" && (sig
.params
.Len() > 0 || sig
.results
.Len() > 0) {
339 check
.errorf(fdecl
.Pos(), "func init must have no arguments and no return values")
343 // function body must be type-checked after global declarations
344 // (functions implemented elsewhere have no body)
345 if !check
.conf
.IgnoreFuncBodies
&& fdecl
.Body
!= nil {
346 check
.later(obj
.name
, decl
, sig
, fdecl
.Body
)
350 func (check
*Checker
) declStmt(decl ast
.Decl
) {
353 switch d
:= decl
.(type) {
358 var last
*ast
.ValueSpec
// last ValueSpec with type or init exprs seen
359 for iota, spec
:= range d
.Specs
{
360 switch s
:= spec
.(type) {
364 // determine which init exprs to use
366 case s
.Type
!= nil ||
len(s
.Values
) > 0:
369 last
= new(ast
.ValueSpec
) // make sure last exists
372 // declare all constants
373 lhs
:= make([]*Const
, len(s
.Names
))
374 for i
, name
:= range s
.Names
{
375 obj
:= NewConst(name
.Pos(), pkg
, name
.Name
, nil, constant
.MakeInt64(int64(iota)))
379 if i
< len(last
.Values
) {
380 init
= last
.Values
[i
]
383 check
.constDecl(obj
, last
.Type
, init
)
386 check
.arityMatch(s
, last
)
388 // spec: "The scope of a constant or variable identifier declared
389 // inside a function begins at the end of the ConstSpec or VarSpec
390 // (ShortVarDecl for short variable declarations) and ends at the
391 // end of the innermost containing block."
393 for i
, name
:= range s
.Names
{
394 check
.declare(check
.scope
, name
, lhs
[i
], scopePos
)
398 lhs0
:= make([]*Var
, len(s
.Names
))
399 for i
, name
:= range s
.Names
{
400 lhs0
[i
] = NewVar(name
.Pos(), pkg
, name
.Name
, nil)
403 // initialize all variables
404 for i
, obj
:= range lhs0
{
407 switch len(s
.Values
) {
412 // rhs is expected to be a multi-valued expression
416 if i
< len(s
.Values
) {
420 check
.varDecl(obj
, lhs
, s
.Type
, init
)
421 if len(s
.Values
) == 1 {
422 // If we have a single lhs variable we are done either way.
423 // If we have a single rhs expression, it must be a multi-
424 // valued expression, in which case handling the first lhs
425 // variable will cause all lhs variables to have a type
426 // assigned, and we are done as well.
428 for _
, obj
:= range lhs0
{
429 assert(obj
.typ
!= nil)
436 check
.arityMatch(s
, nil)
438 // declare all variables
439 // (only at this point are the variable scopes (parents) set)
440 scopePos
:= s
.End() // see constant declarations
441 for i
, name
:= range s
.Names
{
442 // see constant declarations
443 check
.declare(check
.scope
, name
, lhs0
[i
], scopePos
)
447 check
.invalidAST(s
.Pos(), "invalid token %s", d
.Tok
)
451 obj
:= NewTypeName(s
.Name
.Pos(), pkg
, s
.Name
.Name
, nil)
452 // spec: "The scope of a type identifier declared inside a function
453 // begins at the identifier in the TypeSpec and ends at the end of
454 // the innermost containing block."
455 scopePos
:= s
.Name
.Pos()
456 check
.declare(check
.scope
, s
.Name
, obj
, scopePos
)
457 check
.typeDecl(obj
, s
.Type
, nil, nil, s
.Assign
.IsValid())
460 check
.invalidAST(s
.Pos(), "const, type, or var declaration expected")
465 check
.invalidAST(d
.Pos(), "unknown ast.Decl node %T", d
)