Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build(deps): bump github.com/golangci/unconvert to HEAD #4473

Merged
merged 2 commits into from Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions .golangci.reference.yml
Expand Up @@ -2293,6 +2293,14 @@ linters-settings:
# Default: false
syslog-priority: true

unconvert:
# Remove conversions that force intermediate rounding.
# Default: false
fast-math: true
# Be more conservative (experimental).
# Default: false
safe: true

unparam:
# Inspect exported functions.
#
Expand Down
3 changes: 1 addition & 2 deletions go.mod
Expand Up @@ -45,7 +45,7 @@ require (
github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e
github.com/golangci/misspell v0.4.1
github.com/golangci/revgrep v0.5.2
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4
github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed
github.com/gordonklaus/ineffassign v0.1.0
github.com/gostaticanalysis/forcetypeassert v0.1.0
github.com/gostaticanalysis/nilerr v0.1.1
Expand Down Expand Up @@ -151,7 +151,6 @@ require (
github.com/gostaticanalysis/comment v1.4.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kisielk/gotool v1.0.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
Expand Down
5 changes: 2 additions & 3 deletions go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions pkg/config/linters_settings.go
Expand Up @@ -268,6 +268,7 @@ type LintersSettings struct {
Testifylint TestifylintSettings
Testpackage TestpackageSettings
Thelper ThelperSettings
Unconvert UnconvertSettings
Unparam UnparamSettings
Unused UnusedSettings
UseStdlibVars UseStdlibVarsSettings
Expand Down Expand Up @@ -882,6 +883,11 @@ type UseStdlibVarsSettings struct {
SyslogPriority bool `mapstructure:"syslog-priority"`
}

type UnconvertSettings struct {
FastMath bool `mapstructure:"fast-math"`
Safe bool `mapstructure:"safe"`
}

type UnparamSettings struct {
CheckExported bool `mapstructure:"check-exported"`
Algo string
Expand Down
41 changes: 0 additions & 41 deletions pkg/golinters/goanalysis/adapters.go

This file was deleted.

23 changes: 10 additions & 13 deletions pkg/golinters/unconvert.go
Expand Up @@ -3,25 +3,27 @@ package golinters
import (
"sync"

unconvertAPI "github.com/golangci/unconvert"
"github.com/golangci/unconvert"
"golang.org/x/tools/go/analysis"

"github.com/golangci/golangci-lint/pkg/config"
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
"github.com/golangci/golangci-lint/pkg/lint/linter"
"github.com/golangci/golangci-lint/pkg/result"
)

const unconvertName = "unconvert"

func NewUnconvert() *goanalysis.Linter {
//nolint:dupl // This is not a duplicate of dogsled.
func NewUnconvert(settings *config.UnconvertSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []goanalysis.Issue

analyzer := &analysis.Analyzer{
Name: unconvertName,
Doc: goanalysis.TheOnlyanalyzerDoc,
Run: func(pass *analysis.Pass) (any, error) {
issues := runUnconvert(pass)
issues := runUnconvert(pass, settings)

if len(issues) == 0 {
return nil, nil
Expand All @@ -45,18 +47,13 @@ func NewUnconvert() *goanalysis.Linter {
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
}

func runUnconvert(pass *analysis.Pass) []goanalysis.Issue {
prog := goanalysis.MakeFakeLoaderProgram(pass)
func runUnconvert(pass *analysis.Pass, settings *config.UnconvertSettings) []goanalysis.Issue {
positions := unconvert.Run(pass, settings.FastMath, settings.Safe)

positions := unconvertAPI.Run(prog)
if len(positions) == 0 {
return nil
}

issues := make([]goanalysis.Issue, 0, len(positions))
for _, pos := range positions {
var issues []goanalysis.Issue
for _, position := range positions {
issues = append(issues, goanalysis.NewIssue(&result.Issue{
Pos: pos,
Pos: position,
Text: "unnecessary conversion",
FromLinter: unconvertName,
}, pass))
Expand Down
2 changes: 1 addition & 1 deletion pkg/lint/lintersdb/builder_linter.go
Expand Up @@ -633,7 +633,7 @@ func (b LinterBuilder) Build(cfg *config.Config) []*linter.Config {
WithPresets(linter.PresetBugs).
WithURL(""),

linter.NewConfig(golinters.NewUnconvert()).
linter.NewConfig(golinters.NewUnconvert(&cfg.LintersSettings.Unconvert)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetStyle).
Expand Down
1 change: 1 addition & 0 deletions test/linters_test.go
Expand Up @@ -88,6 +88,7 @@ func testOneSource(t *testing.T, log *logutils.StderrLog, binPath, sourcePath st
"--disable-all",
"--out-format=json",
"--max-same-issues=100",
"--max-issues-per-linter=100",
}

for _, addArg := range []string{"", "-Etypecheck"} {
Expand Down
183 changes: 178 additions & 5 deletions test/testdata/unconvert.go
@@ -1,10 +1,183 @@
//golangcitest:args -Eunconvert
package testdata

import "log"
import "io"

func Unconvert() {
a := 1
b := int(a) // want "unnecessary conversion"
log.Print(b)
// Various explicit conversions of untyped constants
// that cannot be removed.
func _() {
const (
_ = byte(0)
_ = int((real)(0i))
_ = complex64(complex(1, 2))
_ = (bool)(true || false)

PtrSize = 4 << (^uintptr(0) >> 63)
c0 = uintptr(PtrSize)
c1 = uintptr((8-PtrSize)/4*2860486313 + (PtrSize-4)/4*33054211828000289)
)

i := int64(0)
_ = i
}

// Make sure we distinguish function calls from
// conversion to function type.
func _() {
type F func(F) int
var f F

_ = F(F(nil)) // want "unnecessary conversion"
_ = f(F(nil))
}

// Make sure we don't remove explicit conversions that
// prevent fusing floating-point operation.
func _() {
var f1, f2, f3, ftmp float64
_ = f1 + float64(f2*f3)
ftmp = float64(f2 * f3)
_ = f1 + ftmp
ftmp = f2 * f3
_ = f1 + float64(ftmp)

var c1, c2, c3, ctmp complex128
_ = c1 + complex128(c2*c3)
ctmp = complex128(c2 * c3)
_ = c1 + ctmp
ctmp = c2 * c3
_ = c1 + complex128(ctmp)
}

// Basic contains conversion errors for builtin data types
func Basic() {
var vbool bool
var vbyte byte
var vcomplex128 complex128
var vcomplex64 complex64
var verror error
var vfloat32 float32
var vfloat64 float64
var vint int
var vint16 int16
var vint32 int32
var vint64 int64
var vint8 int8
var vrune rune
var vstring string
var vuint uint
var vuint16 uint16
var vuint32 uint32
var vuint64 uint64
var vuint8 uint8
var vuintptr uintptr

_ = bool(vbool) // want "unnecessary conversion"
_ = byte(vbyte) // want "unnecessary conversion"
_ = error(verror) // want "unnecessary conversion"
_ = int(vint) // want "unnecessary conversion"
_ = int16(vint16) // want "unnecessary conversion"
_ = int32(vint32) // want "unnecessary conversion"
_ = int64(vint64) // want "unnecessary conversion"
_ = int8(vint8) // want "unnecessary conversion"
_ = rune(vrune) // want "unnecessary conversion"
_ = string(vstring) // want "unnecessary conversion"
_ = uint(vuint) // want "unnecessary conversion"
_ = uint16(vuint16) // want "unnecessary conversion"
_ = uint32(vuint32) // want "unnecessary conversion"
_ = uint64(vuint64) // want "unnecessary conversion"
_ = uint8(vuint8) // want "unnecessary conversion"
_ = uintptr(vuintptr) // want "unnecessary conversion"

_ = float32(vfloat32)
_ = float64(vfloat64)
_ = complex128(vcomplex128)
_ = complex64(vcomplex64)

// Pointers
_ = (*bool)(&vbool) // want "unnecessary conversion"
_ = (*byte)(&vbyte) // want "unnecessary conversion"
_ = (*complex128)(&vcomplex128) // want "unnecessary conversion"
_ = (*complex64)(&vcomplex64) // want "unnecessary conversion"
_ = (*error)(&verror) // want "unnecessary conversion"
_ = (*float32)(&vfloat32) // want "unnecessary conversion"
_ = (*float64)(&vfloat64) // want "unnecessary conversion"
_ = (*int)(&vint) // want "unnecessary conversion"
_ = (*int16)(&vint16) // want "unnecessary conversion"
_ = (*int32)(&vint32) // want "unnecessary conversion"
_ = (*int64)(&vint64) // want "unnecessary conversion"
_ = (*int8)(&vint8) // want "unnecessary conversion"
_ = (*rune)(&vrune) // want "unnecessary conversion"
_ = (*string)(&vstring) // want "unnecessary conversion"
_ = (*uint)(&vuint) // want "unnecessary conversion"
_ = (*uint16)(&vuint16) // want "unnecessary conversion"
_ = (*uint32)(&vuint32) // want "unnecessary conversion"
_ = (*uint64)(&vuint64) // want "unnecessary conversion"
_ = (*uint8)(&vuint8) // want "unnecessary conversion"
_ = (*uintptr)(&vuintptr) // want "unnecessary conversion"
}

// Counter is an int64
type Counter int64

// ID is a typed identifier
type ID string

// Metric is a struct
type Metric struct {
ID ID
Counter Counter
}

// Custom contains conversion errors for builtin data types
func Custom() {
type Local struct{ id ID }

var counter Counter
var id ID
var m Metric
var local Local
var x struct{ id ID }

_ = Counter(counter) // want "unnecessary conversion"
_ = ID(id) // want "unnecessary conversion"
_ = Metric(m) // want "unnecessary conversion"
_ = Local(local) // want "unnecessary conversion"
_ = (struct{ id ID })(x) // want "unnecessary conversion"

// Pointers
_ = (*Counter)(&counter) // want "unnecessary conversion"
_ = (*ID)(&id) // want "unnecessary conversion"
_ = (*Metric)(&m) // want "unnecessary conversion"
_ = (*Local)(&local) // want "unnecessary conversion"
_ = (*struct{ id ID })(&x) // want "unnecessary conversion"
}

// Interfaces contains conversion errors for interfaces
func Interfaces() {
var writer io.Writer

_ = (io.Writer)(writer) // want "unnecessary conversion"
_ = (*io.Writer)(&writer) // want "unnecessary conversion"
}

// Constructor is a func type
type Constructor func() ID

// Funcs contains conversion errors for func types
func Funcs() {
type Local func(ID)
type Recursive func(Recursive)

var ctor Constructor
var local Local
var recursive Recursive

_ = Constructor(ctor) // want "unnecessary conversion"
_ = Local(local) // want "unnecessary conversion"
_ = Recursive(recursive) // want "unnecessary conversion"

_ = (*Constructor)(&ctor) // want "unnecessary conversion"
_ = (*Local)(&local) // want "unnecessary conversion"
_ = (*Recursive)(&recursive) // want "unnecessary conversion"
}