// can only appear in qualified identifiers which are mapped to
// selector expressions.
if ident, ok := e.X.(*ast.Ident); ok {
- _, obj := check.scope.LookupParent(ident.Name, check.pos)
+ obj := check.lookup(ident.Name)
if pname, _ := obj.(*PkgName); pname != nil {
assert(pname.pkg == check.pkg)
check.recordUse(ident, pname)
type context struct {
decl *declInfo // package-level declaration whose init expression/function body is checked
scope *Scope // top-most scope for lookups
+ pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
iota constant.Value // value of iota in a constant declaration; nil otherwise
sig *Signature // function signature if inside a function; nil otherwise
hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
}
+// lookup looks up name in the current context and returns the matching object, or nil.
+func (ctxt *context) lookup(name string) Object {
+ _, obj := ctxt.scope.LookupParent(name, ctxt.pos)
+ return obj
+}
+
// An importKey identifies an imported package by import path and source directory
// (directory containing the file containing the import). In practice, the directory
// may always be the same, or may not matter. Given an (import path, directory), an
// context within which the current object is type-checked
// (valid only for the duration of type-checking a specific object)
context
- pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
// debugging
indent int // indentation for tracing
typenameLoop:
// name must be a type name denoting a type whose underlying type is an interface
- _, obj := check.scope.LookupParent(name.Name, check.pos /* use Eval position, if any */)
+ obj := check.lookup(name.Name)
if obj == nil {
return nil
}
if name == nil {
return nil
}
- _, obj1 := check.scope.LookupParent(name.Name, check.pos /* use Eval position, if any */)
+ obj1 := check.lookup(name.Name)
if obj1 == nil {
return nil
}
// list in a "return" statement if a different entity (constant, type, or variable)
// with the same name as a result parameter is in scope at the place of the return."
for _, obj := range res.vars {
- if _, alt := check.scope.LookupParent(obj.name, check.pos); alt != nil && alt != obj {
+ if alt := check.lookup(obj.name); alt != nil && alt != obj {
check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name)
check.errorf(alt.Pos(), "\tinner declaration of %s", obj)
// ok to continue
x.mode = invalid
x.expr = e
+ // Note that we cannot use check.lookup here because the returned scope
+ // may be different from obj.Parent(). See also Scope.LookupParent doc.
scope, obj := check.scope.LookupParent(e.Name, check.pos)
if obj == nil {
if e.Name == "_" {