diff --git a/noinlineerr.go b/noinlineerr.go index 2ecefe3..ecafcd9 100644 --- a/noinlineerr.go +++ b/noinlineerr.go @@ -63,9 +63,11 @@ func inlineErrorInspector(pass *analysis.Pass) func(n ast.Node) { continue } - if len(assignStmt.Lhs) != 1 { - // if there are more than 1 assignment then we can make a shadow conflict with other variables - // so don't do anything beside simple error message + // if there are more than 1 assignment + // or there are any variables with same name + // then we can make a shadow conflict with other variables + // so don't do anything beside simple error message + if len(assignStmt.Lhs) != 1 || shadowVarsExists(ident.Name, pass.TypesInfo.Scopes[ifStmt]) { pass.Reportf(ident.Pos(), errMessage) return } @@ -75,6 +77,7 @@ func inlineErrorInspector(pass *analysis.Pass) func(n ast.Node) { // and we can autofix that var buf bytes.Buffer + _ = printer.Fprint(&buf, pass.Fset, assignStmt) assignText := buf.String() @@ -116,3 +119,16 @@ func isError(obj types.Object) bool { return types.AssignableTo(obj.Type(), errorType) } + +func shadowVarsExists(name string, scope *types.Scope) bool { + if scope == nil { + return false + } + + parentScope := scope.Parent() + if parentScope == nil { + return false + } + + return parentScope.Lookup(name) != nil +} diff --git a/testdata/src/a/main.go b/testdata/src/a/main.go index 2412511..832c02a 100644 --- a/testdata/src/a/main.go +++ b/testdata/src/a/main.go @@ -7,7 +7,7 @@ import ( type MyAliasErr error -type MyCustomError struct {} +type MyCustomError struct{} func (mc *MyCustomError) Error() string { return "error" @@ -84,3 +84,22 @@ func invalid() error { return nil } + +func errShadow() error { + var err error + if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return err + } + fmt.Println(err) + + return nil +} + +func naming() error { + if otherName := doSomething(); otherName != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return otherName + } + + return nil +} + diff --git a/testdata/src/a/main.go.golden b/testdata/src/a/main.go.golden index 254035c..d8a52d1 100644 --- a/testdata/src/a/main.go.golden +++ b/testdata/src/a/main.go.golden @@ -8,7 +8,7 @@ import ( type MyAliasErr error -type MyCustomError struct {} +type MyCustomError struct{} func (mc *MyCustomError) Error() string { return "error" @@ -86,6 +86,25 @@ func invalid() error { if err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" return err } + + return nil +} + +func errShadow() error { + var err error + if err := doSomething(); err != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return err + } + fmt.Println(err) + + return nil +} + +func naming() error { + otherName := doSomething() + if otherName != nil { // want "avoid inline error handling using `if err := ...; err != nil`; use plain assignment `err := ...`" + return otherName + } return nil }