From 2fcd44d4702f69350ec1b81c99e930bf52048661 Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Sun, 26 May 2024 21:15:36 +0100 Subject: [PATCH] s1009: fix with SelectorExpr Also clarify the docs that this also checks maps and channels. Fixes #1527 --- simple/s1009/s1009.go | 26 +++++++++++++------ .../CheckRedundantNilCheckWithLen/nil-len.go | 18 +++++++++++++ 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/simple/s1009/s1009.go b/simple/s1009/s1009.go index 418968602..d445f19f9 100644 --- a/simple/s1009/s1009.go +++ b/simple/s1009/s1009.go @@ -25,10 +25,10 @@ var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ Requires: []*analysis.Analyzer{inspect.Analyzer, generated.Analyzer}, }, Doc: &lint.Documentation{ - Title: `Omit redundant nil check on slices`, - Text: `The \'len\' function is defined for all slices, even nil ones, which have -a length of zero. It is not necessary to check if a slice is not nil -before checking that its length is not zero.`, + Title: `Omit redundant nil check on slices, maps, and channels`, + Text: `The \'len\' function is defined for all slices, maps, and +channels, even nil ones, which have a length of zero. It is not necessary to +check for nil before checking that its length is not zero.`, Before: `if x != nil && len(x) != 0 {}`, After: `if len(x) != 0 {}`, Since: "2017.1", @@ -81,8 +81,13 @@ func run(pass *analysis.Pass) (interface{}, error) { if !eqNil && x.Op != token.NEQ { return } - xx, ok := x.X.(*ast.Ident) - if !ok { + var xx *ast.Ident + switch s := x.X.(type) { + case *ast.Ident: + xx = s + case *ast.SelectorExpr: + xx = s.Sel + default: return } if !code.IsNil(pass, x.Y) { @@ -104,8 +109,13 @@ func run(pass *analysis.Pass) (interface{}, error) { if !code.IsCallTo(pass, yx, "len") { return } - yxArg, ok := yx.Args[knowledge.Arg("len.v")].(*ast.Ident) - if !ok { + var yxArg *ast.Ident + switch s := yx.Args[knowledge.Arg("len.v")].(type) { + case *ast.Ident: + yxArg = s + case *ast.SelectorExpr: + yxArg = s.Sel + default: return } if yxArg.Name != xx.Name { diff --git a/simple/s1009/testdata/src/example.com/CheckRedundantNilCheckWithLen/nil-len.go b/simple/s1009/testdata/src/example.com/CheckRedundantNilCheckWithLen/nil-len.go index cc5543384..f3ca081dd 100644 --- a/simple/s1009/testdata/src/example.com/CheckRedundantNilCheckWithLen/nil-len.go +++ b/simple/s1009/testdata/src/example.com/CheckRedundantNilCheckWithLen/nil-len.go @@ -73,3 +73,21 @@ func fn3() { if x == nil || len(x) == 0 { } } + +func issue1527() { + var t struct { + pa *[5]int + s []int + m map[uint64]bool + ch chan int + } + + if t.s == nil || len(t.s) == 0 { //@ diag(`should omit nil check`) + } + if t.m == nil || len(t.m) == 0 { //@ diag(`should omit nil check`) + } + if t.ch == nil || len(t.ch) == 0 { //@ diag(`should omit nil check`) + } + if t.pa == nil || len(t.pa) == 0 { // nil check cannot be removed with pointer to an array + } +}