Add nilnil linter (#2236)
This commit is contained in:
parent
2ea496f22b
commit
32292622f8
@ -172,10 +172,6 @@ linters-settings:
|
|||||||
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
# minimal code complexity to report, 30 by default (but we recommend 10-20)
|
||||||
min-complexity: 10
|
min-complexity: 10
|
||||||
|
|
||||||
nestif:
|
|
||||||
# minimal complexity of if statements to report, 5 by default
|
|
||||||
min-complexity: 4
|
|
||||||
|
|
||||||
goconst:
|
goconst:
|
||||||
# minimal length of string constant, 3 by default
|
# minimal length of string constant, 3 by default
|
||||||
min-len: 3
|
min-len: 3
|
||||||
@ -497,6 +493,31 @@ linters-settings:
|
|||||||
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
|
||||||
max-func-lines: 30
|
max-func-lines: 30
|
||||||
|
|
||||||
|
nestif:
|
||||||
|
# minimal complexity of if statements to report, 5 by default
|
||||||
|
min-complexity: 4
|
||||||
|
|
||||||
|
nilnil:
|
||||||
|
# By default, nilnil checks all returned types below.
|
||||||
|
checked-types:
|
||||||
|
- ptr
|
||||||
|
- func
|
||||||
|
- iface
|
||||||
|
- map
|
||||||
|
- chan
|
||||||
|
|
||||||
|
nolintlint:
|
||||||
|
# Enable to ensure that nolint directives are all used. Default is true.
|
||||||
|
allow-unused: false
|
||||||
|
# Disable to ensure that nolint directives don't have a leading space. Default is true.
|
||||||
|
allow-leading-space: true
|
||||||
|
# Exclude following linters from requiring an explanation. Default is [].
|
||||||
|
allow-no-explanation: [ ]
|
||||||
|
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
|
||||||
|
require-explanation: true
|
||||||
|
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
|
||||||
|
require-specific: true
|
||||||
|
|
||||||
prealloc:
|
prealloc:
|
||||||
# XXX: we don't recommend using this linter before doing performance profiling.
|
# XXX: we don't recommend using this linter before doing performance profiling.
|
||||||
# For most programs usage of prealloc will be a premature optimization.
|
# For most programs usage of prealloc will be a premature optimization.
|
||||||
@ -528,18 +549,6 @@ linters-settings:
|
|||||||
# include method names and field names (i.e., qualified names) in checks
|
# include method names and field names (i.e., qualified names) in checks
|
||||||
q: false
|
q: false
|
||||||
|
|
||||||
nolintlint:
|
|
||||||
# Enable to ensure that nolint directives are all used. Default is true.
|
|
||||||
allow-unused: false
|
|
||||||
# Disable to ensure that nolint directives don't have a leading space. Default is true.
|
|
||||||
allow-leading-space: true
|
|
||||||
# Exclude following linters from requiring an explanation. Default is [].
|
|
||||||
allow-no-explanation: []
|
|
||||||
# Enable to require an explanation of nonzero length after each nolint directive. Default is false.
|
|
||||||
require-explanation: true
|
|
||||||
# Enable to require nolint directives to mention the specific linter being suppressed. Default is false.
|
|
||||||
require-specific: true
|
|
||||||
|
|
||||||
rowserrcheck:
|
rowserrcheck:
|
||||||
packages:
|
packages:
|
||||||
- github.com/jmoiron/sqlx
|
- github.com/jmoiron/sqlx
|
||||||
|
1
go.mod
1
go.mod
@ -5,6 +5,7 @@ go 1.15
|
|||||||
require (
|
require (
|
||||||
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a
|
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a
|
||||||
github.com/Antonboom/errname v0.1.4
|
github.com/Antonboom/errname v0.1.4
|
||||||
|
github.com/Antonboom/nilnil v0.1.0
|
||||||
github.com/BurntSushi/toml v0.4.1
|
github.com/BurntSushi/toml v0.4.1
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
||||||
github.com/OpenPeeDeeP/depguard v1.0.1
|
github.com/OpenPeeDeeP/depguard v1.0.1
|
||||||
|
4
go.sum
generated
4
go.sum
generated
@ -46,6 +46,10 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EU
|
|||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
github.com/Antonboom/errname v0.1.4 h1:lGSlI42Gm4bI1e+IITtXJXvxFM8N7naWimVFKcb0McY=
|
github.com/Antonboom/errname v0.1.4 h1:lGSlI42Gm4bI1e+IITtXJXvxFM8N7naWimVFKcb0McY=
|
||||||
github.com/Antonboom/errname v0.1.4/go.mod h1:jRXo3m0E0EuCnK3wbsSVH3X55Z4iTDLl6ZfCxwFj4TM=
|
github.com/Antonboom/errname v0.1.4/go.mod h1:jRXo3m0E0EuCnK3wbsSVH3X55Z4iTDLl6ZfCxwFj4TM=
|
||||||
|
github.com/Antonboom/nilnil v0.0.0-20210914182304-d33f75a9101c h1:GZ/bAqfmHdiHy8O0jwbGwLsK0qyw+8iuCaqNbCcV/to=
|
||||||
|
github.com/Antonboom/nilnil v0.0.0-20210914182304-d33f75a9101c/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo=
|
||||||
|
github.com/Antonboom/nilnil v0.1.0 h1:DLDavmg0a6G/F4Lt9t7Enrbgb3Oph6LnDE6YVsmTt74=
|
||||||
|
github.com/Antonboom/nilnil v0.1.0/go.mod h1:PhHLvRPSghY5Y7mX4TW+BHZQYo1A8flE5H20D3IPZBo=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
|
||||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
|
@ -118,6 +118,7 @@ type LintersSettings struct {
|
|||||||
Misspell MisspellSettings
|
Misspell MisspellSettings
|
||||||
Nakedret NakedretSettings
|
Nakedret NakedretSettings
|
||||||
Nestif NestifSettings
|
Nestif NestifSettings
|
||||||
|
NilNil NilNilSettings
|
||||||
NoLintLint NoLintLintSettings
|
NoLintLint NoLintLintSettings
|
||||||
Prealloc PreallocSettings
|
Prealloc PreallocSettings
|
||||||
Predeclared PredeclaredSettings
|
Predeclared PredeclaredSettings
|
||||||
@ -360,6 +361,10 @@ type NestifSettings struct {
|
|||||||
MinComplexity int `mapstructure:"min-complexity"`
|
MinComplexity int `mapstructure:"min-complexity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NilNilSettings struct {
|
||||||
|
CheckedTypes []string `mapstructure:"checked-types"`
|
||||||
|
}
|
||||||
|
|
||||||
type NoLintLintSettings struct {
|
type NoLintLintSettings struct {
|
||||||
RequireExplanation bool `mapstructure:"require-explanation"`
|
RequireExplanation bool `mapstructure:"require-explanation"`
|
||||||
AllowLeadingSpace bool `mapstructure:"allow-leading-space"`
|
AllowLeadingSpace bool `mapstructure:"allow-leading-space"`
|
||||||
|
30
pkg/golinters/nilnil.go
Normal file
30
pkg/golinters/nilnil.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/Antonboom/nilnil/pkg/analyzer"
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
|
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewNilNil(cfg *config.NilNilSettings) *goanalysis.Linter {
|
||||||
|
a := analyzer.New()
|
||||||
|
|
||||||
|
cfgMap := make(map[string]map[string]interface{})
|
||||||
|
if cfg != nil && len(cfg.CheckedTypes) != 0 {
|
||||||
|
cfgMap[a.Name] = map[string]interface{}{
|
||||||
|
"checked-types": strings.Join(cfg.CheckedTypes, ","),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return goanalysis.NewLinter(
|
||||||
|
a.Name,
|
||||||
|
a.Doc,
|
||||||
|
[]*analysis.Analyzer{a},
|
||||||
|
cfgMap,
|
||||||
|
).
|
||||||
|
WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||||
|
}
|
@ -99,46 +99,48 @@ func enableLinterConfigs(lcs []*linter.Config, isEnabled func(lc *linter.Config)
|
|||||||
|
|
||||||
//nolint:funlen
|
//nolint:funlen
|
||||||
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
||||||
var govetCfg *config.GovetSettings
|
var cyclopCfg *config.Cyclop
|
||||||
var testpackageCfg *config.TestpackageSettings
|
var errorlintCfg *config.ErrorLintSettings
|
||||||
var exhaustiveCfg *config.ExhaustiveSettings
|
var exhaustiveCfg *config.ExhaustiveSettings
|
||||||
var exhaustiveStructCfg *config.ExhaustiveStructSettings
|
var exhaustiveStructCfg *config.ExhaustiveStructSettings
|
||||||
var errorlintCfg *config.ErrorLintSettings
|
|
||||||
var thelperCfg *config.ThelperSettings
|
|
||||||
var predeclaredCfg *config.PredeclaredSettings
|
|
||||||
var ifshortCfg *config.IfshortSettings
|
|
||||||
var reviveCfg *config.ReviveSettings
|
|
||||||
var cyclopCfg *config.Cyclop
|
|
||||||
var importAsCfg *config.ImportAsSettings
|
|
||||||
var ireturnCfg *config.IreturnSettings
|
|
||||||
var goModDirectivesCfg *config.GoModDirectivesSettings
|
var goModDirectivesCfg *config.GoModDirectivesSettings
|
||||||
var tagliatelleCfg *config.TagliatelleSettings
|
|
||||||
var gosecCfg *config.GoSecSettings
|
var gosecCfg *config.GoSecSettings
|
||||||
var gosimpleCfg *config.StaticCheckSettings
|
var gosimpleCfg *config.StaticCheckSettings
|
||||||
|
var govetCfg *config.GovetSettings
|
||||||
|
var ifshortCfg *config.IfshortSettings
|
||||||
|
var importAsCfg *config.ImportAsSettings
|
||||||
|
var ireturnCfg *config.IreturnSettings
|
||||||
|
var nilNilCfg *config.NilNilSettings
|
||||||
|
var predeclaredCfg *config.PredeclaredSettings
|
||||||
|
var reviveCfg *config.ReviveSettings
|
||||||
var staticcheckCfg *config.StaticCheckSettings
|
var staticcheckCfg *config.StaticCheckSettings
|
||||||
var stylecheckCfg *config.StaticCheckSettings
|
var stylecheckCfg *config.StaticCheckSettings
|
||||||
|
var tagliatelleCfg *config.TagliatelleSettings
|
||||||
|
var testpackageCfg *config.TestpackageSettings
|
||||||
|
var thelperCfg *config.ThelperSettings
|
||||||
var unusedCfg *config.StaticCheckSettings
|
var unusedCfg *config.StaticCheckSettings
|
||||||
var wrapcheckCfg *config.WrapcheckSettings
|
var wrapcheckCfg *config.WrapcheckSettings
|
||||||
|
|
||||||
if m.cfg != nil {
|
if m.cfg != nil {
|
||||||
govetCfg = &m.cfg.LintersSettings.Govet
|
cyclopCfg = &m.cfg.LintersSettings.Cyclop
|
||||||
testpackageCfg = &m.cfg.LintersSettings.Testpackage
|
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
|
||||||
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
|
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
|
||||||
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
|
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
|
||||||
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
|
|
||||||
thelperCfg = &m.cfg.LintersSettings.Thelper
|
|
||||||
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
|
|
||||||
ifshortCfg = &m.cfg.LintersSettings.Ifshort
|
|
||||||
reviveCfg = &m.cfg.LintersSettings.Revive
|
|
||||||
cyclopCfg = &m.cfg.LintersSettings.Cyclop
|
|
||||||
importAsCfg = &m.cfg.LintersSettings.ImportAs
|
|
||||||
ireturnCfg = &m.cfg.LintersSettings.Ireturn
|
|
||||||
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
|
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
|
||||||
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
|
|
||||||
gosecCfg = &m.cfg.LintersSettings.Gosec
|
gosecCfg = &m.cfg.LintersSettings.Gosec
|
||||||
gosimpleCfg = &m.cfg.LintersSettings.Gosimple
|
gosimpleCfg = &m.cfg.LintersSettings.Gosimple
|
||||||
|
govetCfg = &m.cfg.LintersSettings.Govet
|
||||||
|
ifshortCfg = &m.cfg.LintersSettings.Ifshort
|
||||||
|
importAsCfg = &m.cfg.LintersSettings.ImportAs
|
||||||
|
ireturnCfg = &m.cfg.LintersSettings.Ireturn
|
||||||
|
nilNilCfg = &m.cfg.LintersSettings.NilNil
|
||||||
|
predeclaredCfg = &m.cfg.LintersSettings.Predeclared
|
||||||
|
reviveCfg = &m.cfg.LintersSettings.Revive
|
||||||
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
staticcheckCfg = &m.cfg.LintersSettings.Staticcheck
|
||||||
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
stylecheckCfg = &m.cfg.LintersSettings.Stylecheck
|
||||||
|
tagliatelleCfg = &m.cfg.LintersSettings.Tagliatelle
|
||||||
|
testpackageCfg = &m.cfg.LintersSettings.Testpackage
|
||||||
|
thelperCfg = &m.cfg.LintersSettings.Thelper
|
||||||
unusedCfg = &m.cfg.LintersSettings.Unused
|
unusedCfg = &m.cfg.LintersSettings.Unused
|
||||||
wrapcheckCfg = &m.cfg.LintersSettings.Wrapcheck
|
wrapcheckCfg = &m.cfg.LintersSettings.Wrapcheck
|
||||||
}
|
}
|
||||||
@ -513,6 +515,11 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
WithPresets(linter.PresetStyle).
|
WithPresets(linter.PresetStyle).
|
||||||
WithLoadForGoAnalysis().
|
WithLoadForGoAnalysis().
|
||||||
WithURL("https://github.com/butuzov/ireturn"),
|
WithURL("https://github.com/butuzov/ireturn"),
|
||||||
|
linter.NewConfig(golinters.NewNilNil(nilNilCfg)).
|
||||||
|
WithPresets(linter.PresetStyle).
|
||||||
|
WithLoadForGoAnalysis().
|
||||||
|
WithURL("https://github.com/Antonboom/nilnil").
|
||||||
|
WithSince("v1.43.0"),
|
||||||
|
|
||||||
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
|
// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives
|
||||||
linter.NewConfig(golinters.NewNoLintLint()).
|
linter.NewConfig(golinters.NewNoLintLint()).
|
||||||
|
180
test/testdata/nilnil.go
vendored
Normal file
180
test/testdata/nilnil.go
vendored
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
//args: -Enilnil
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User struct{}
|
||||||
|
|
||||||
|
func primitivePtr() (*int, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func structPtr() (*User, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func emptyStructPtr() (*struct{}, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func anonymousStructPtr() (*struct{ ID string }, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func chBi() (chan int, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func chIn() (chan<- int, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func chOut() (<-chan int, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func fun() (func(), error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func funWithArgsAndResults() (func(a, b, c int) (int, int), error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func iface() (interface{}, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func m1() (map[int]int, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func m2() (map[int]*User, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
type Storage struct{}
|
||||||
|
|
||||||
|
func (s *Storage) GetUser() (*User, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func ifReturn() (*User, error) {
|
||||||
|
var s Storage
|
||||||
|
if _, err := s.GetUser(); err != nil {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
return new(User), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func forReturn() (*User, error) {
|
||||||
|
for {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func multipleReturn() (*User, error) {
|
||||||
|
var s Storage
|
||||||
|
|
||||||
|
if _, err := s.GetUser(); err != nil {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.GetUser(); err != nil {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := s.GetUser(); err != nil {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
return new(User), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func nested() {
|
||||||
|
_ = func() (*User, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
_, _ = func() (*User, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func deeplyNested() {
|
||||||
|
_ = func() {
|
||||||
|
_ = func() int {
|
||||||
|
_ = func() {
|
||||||
|
_ = func() (*User, error) {
|
||||||
|
_ = func() {}
|
||||||
|
_ = func() int { return 0 }
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
StructPtrType *User
|
||||||
|
PrimitivePtrType *int
|
||||||
|
ChannelType chan int
|
||||||
|
FuncType func(int) int
|
||||||
|
Checker interface{ Check() }
|
||||||
|
)
|
||||||
|
|
||||||
|
func structPtrType() (StructPtrType, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func primitivePtrType() (PrimitivePtrType, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func channelType() (ChannelType, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func funcType() (FuncType, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func ifaceType() (Checker, error) {
|
||||||
|
return nil, nil // ERROR "return both the `nil` error and invalid value: use a sentinel error instead"
|
||||||
|
}
|
||||||
|
|
||||||
|
func withoutArgs() {}
|
||||||
|
func withoutError1() *User { return nil }
|
||||||
|
func withoutError2() (*User, *User) { return nil, nil }
|
||||||
|
func withoutError3() (*User, *User, *User) { return nil, nil, nil }
|
||||||
|
func withoutError4() (*User, *User, *User, *User) { return nil, nil, nil, nil }
|
||||||
|
|
||||||
|
// Unsupported.
|
||||||
|
|
||||||
|
func invalidOrder() (error, *User) { return nil, nil }
|
||||||
|
func withError3rd() (*User, bool, error) { return nil, false, nil }
|
||||||
|
func withError4th() (*User, *User, *User, error) { return nil, nil, nil, nil }
|
||||||
|
func unsafePtr() (unsafe.Pointer, error) { return nil, nil }
|
||||||
|
func uintPtr() (uintptr, error) { return 0, nil }
|
||||||
|
func slice() ([]int, error) { return nil, nil }
|
||||||
|
func ifaceExtPkg() (io.Closer, error) { return nil, nil }
|
||||||
|
|
||||||
|
func implicitNil1() (*User, error) {
|
||||||
|
err := (error)(nil)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func implicitNil2() (*User, error) {
|
||||||
|
err := io.EOF
|
||||||
|
err = nil
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func implicitNil3() (*User, error) {
|
||||||
|
return nil, wrap(nil)
|
||||||
|
}
|
||||||
|
func wrap(err error) error { return err }
|
Loading…
x
Reference in New Issue
Block a user