diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 71a9ddf..6bed769 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -50,15 +50,17 @@ var ( } ) -type typeSpecByName map[string]*ast.TypeSpec +type typeSpecByName map[string]typer func (n *nilNil) run(pass *analysis.Pass) (interface{}, error) { insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) - typeSpecs := typeSpecByName{} + typeSpecs := typeSpecByName{ + "any": newTyper(new(ast.InterfaceType)), + } insp.Preorder(types, func(node ast.Node) { t := node.(*ast.TypeSpec) - typeSpecs[t.Name.Name] = t + typeSpecs[t.Name.Name] = newTyper(t.Type) }) var fs funcTypeStack @@ -125,7 +127,7 @@ func (n *nilNil) isDangerNilType(t ast.Expr, typeSpecs typeSpecByName) bool { case *ast.Ident: if t, ok := typeSpecs[v.Name]; ok { - return n.isDangerNilType(t.Type, nil) + return n.isDangerNilType(t.Type(), typeSpecs) } } return false @@ -146,3 +148,11 @@ func isIdent(n ast.Node, name string) bool { } return i.Name == name } + +type typer interface { + Type() ast.Expr +} + +func newTyper(t ast.Expr) typer { return typerImpl{t: t} } // +type typerImpl struct{ t ast.Expr } // +func (ti typerImpl) Type() ast.Expr { return ti.t } diff --git a/pkg/analyzer/testdata/src/examples/positive.go b/pkg/analyzer/testdata/src/examples/positive.go index 9653b13..4114894 100644 --- a/pkg/analyzer/testdata/src/examples/positive.go +++ b/pkg/analyzer/testdata/src/examples/positive.go @@ -42,6 +42,10 @@ func iface() (interface{}, error) { return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" } +func anyType() (any, error) { + return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" +} + func m1() (map[int]int, error) { return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" } @@ -50,6 +54,12 @@ func m2() (map[int]*User, error) { return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" } +type mapAlias = map[int]*User + +func m3() (mapAlias, error) { + return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" +} + type Storage struct{} func (s *Storage) GetUser() (*User, error) { diff --git a/pkg/analyzer/testdata/src/examples/positive_with_types.go b/pkg/analyzer/testdata/src/examples/positive_with_types.go index 25f1d08..f5f996a 100644 --- a/pkg/analyzer/testdata/src/examples/positive_with_types.go +++ b/pkg/analyzer/testdata/src/examples/positive_with_types.go @@ -27,3 +27,9 @@ func funcType() (FuncType, error) { func ifaceType() (Checker, error) { return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" } + +type checkerAlias = Checker + +func ifaceTypeAliased() (checkerAlias, error) { + return nil, nil // want "return both the `nil` error and invalid value: use a sentinel error instead" +}