return s.min <= pos && pos < s.max
}
-// growSpan expands the span for the object to contain the instance represented
-// by the identifier.
-func (pkg *Package) growSpan(ident *ast.Ident, obj types.Object) {
+// growSpan expands the span for the object to contain the source range [pos, end).
+func (pkg *Package) growSpan(obj types.Object, pos, end token.Pos) {
if *strictShadowing {
return // No need
}
- pos := ident.Pos()
- end := ident.End()
span, ok := pkg.spans[obj]
if ok {
if span.min > pos {
// the shadowing identifier.
span, ok := f.pkg.spans[shadowed]
if !ok {
- f.Badf(ident.Pos(), "internal error: no range for %q", ident.Name)
+ f.Badf(shadowed.Pos(), "internal error: no range for %q", shadowed.Name())
return
}
if !span.contains(ident.Pos()) {
func one() int {
return 1
}
+
+// Must not complain with an internal error for the
+// implicitly declared type switch variable v.
+func issue26725(x interface{}) int {
+ switch v := x.(type) {
+ case int, int32:
+ if v, ok := x.(int); ok {
+ return v
+ }
+ case int64:
+ return int(v)
+ }
+ return 0
+}
+
+// Verify that implicitly declared variables from
+// type switches are considered in shadowing analysis.
+func shadowTypeSwitch(a interface{}) {
+ switch t := a.(type) {
+ case int:
+ {
+ t := 0 // ERROR "declaration of .t. shadows declaration at shadow.go:78"
+ _ = t
+ }
+ _ = t
+ case uint:
+ {
+ t := uint(0) // OK because t is not mentioned later in this function
+ _ = t
+ }
+ }
+}
}
pkg.defs = make(map[*ast.Ident]types.Object)
pkg.uses = make(map[*ast.Ident]types.Object)
+ pkg.implicits = make(map[ast.Node]types.Object)
pkg.selectors = make(map[*ast.SelectorExpr]*types.Selection)
pkg.spans = make(map[types.Object]Span)
pkg.types = make(map[ast.Expr]types.TypeAndValue)
Types: pkg.types,
Defs: pkg.defs,
Uses: pkg.uses,
+ Implicits: pkg.implicits,
}
typesPkg, err := config.Check(pkg.path, fs, astFiles, info)
if len(allErrors) == 0 && err != nil {
pkg.typesPkg = typesPkg
// update spans
for id, obj := range pkg.defs {
- pkg.growSpan(id, obj)
+ // Ignore identifiers that don't denote objects
+ // (package names, symbolic variables such as t
+ // in t := x.(type) of type switch headers).
+ if obj != nil {
+ pkg.growSpan(obj, id.Pos(), id.End())
+ }
}
for id, obj := range pkg.uses {
- pkg.growSpan(id, obj)
+ pkg.growSpan(obj, id.Pos(), id.End())
+ }
+ for node, obj := range pkg.implicits {
+ // A type switch with a short variable declaration
+ // such as t := x.(type) doesn't declare the symbolic
+ // variable (t in the example) at the switch header;
+ // instead a new variable t (with specific type) is
+ // declared implicitly for each case. Such variables
+ // are found in the types.Info.Implicits (not Defs)
+ // map. Add them here, assuming they are declared at
+ // the type cases' colon ":".
+ if cc, ok := node.(*ast.CaseClause); ok {
+ pkg.growSpan(obj, cc.Colon, cc.Colon)
+ }
}
return allErrors
}