Skip to content

Commit

Permalink
go/analysis/passes/unusedresult: update and add test for typeparams
Browse files Browse the repository at this point in the history
This CL implements  support for setting unused generic funcs via flags.
A test for unused results with generics is added.

Updates golang/go#48704
  • Loading branch information
Jack You committed Oct 28, 2021
1 parent c8ad2e1 commit 1c6db19
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//go:build go1.18

package typeparams

import (
"bytes"
"errors"
"fmt"
"typeparams/userdefs"
)

func _[T any]() {
fmt.Errorf("") // want "result of fmt.Errorf call not used"
_ = fmt.Errorf("")

errors.New("") // want "result of errors.New call not used"

err := errors.New("")
err.Error() // want `result of \(error\).Error call not used`

var buf bytes.Buffer
buf.String() // want `result of \(bytes.Buffer\).String call not used`

fmt.Sprint("") // want "result of fmt.Sprint call not used"
fmt.Sprintf("") // want "result of fmt.Sprintf call not used"

userdefs.MustUse[int](1) // want "result of typeparams/userdefs.MustUse call not used"
_ = userdefs.MustUse[int](2)

s := userdefs.SingleTypeParam[int]{X: 1}
s.String() // want `result of \(typeparams/userdefs.SingleTypeParam\[int\]\).String call not used`
_ = s.String()

m := userdefs.MultiTypeParam[int, string]{X: 1, Y: "one"}
m.String() // want `result of \(typeparams/userdefs.MultiTypeParam\[int, string\]\).String call not used`
_ = m.String()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//go:build go1.18

package userdefs

func MustUse[T interface{ ~int }](v T) T {
return v + 1
}

type SingleTypeParam[T any] struct {
X T
}

func (_ *SingleTypeParam[T]) String() string {
return "SingleTypeParam"
}

type MultiTypeParam[T any, U any] struct {
X T
Y U
}

func (_ *MultiTypeParam[T, U]) String() string {
return "MultiTypeParam"
}
6 changes: 6 additions & 0 deletions go/analysis/passes/unusedresult/unusedresult.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
"golang.org/x/tools/go/ast/inspector"
"golang.org/x/tools/internal/typeparams"
)

// TODO(adonovan): make this analysis modular: export a mustUseResult
Expand Down Expand Up @@ -70,6 +71,11 @@ func run(pass *analysis.Pass) (interface{}, error) {
return // a conversion, not a call
}

index := typeparams.GetIndexExprData(fun)
if index != nil {
fun = index.X // If this is generic function or method call, skip the instantiation arguments
}

selector, ok := fun.(*ast.SelectorExpr)
if !ok {
return // neither a method call nor a qualified ident
Expand Down
9 changes: 8 additions & 1 deletion go/analysis/passes/unusedresult/unusedresult_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,16 @@ import (

"golang.org/x/tools/go/analysis/analysistest"
"golang.org/x/tools/go/analysis/passes/unusedresult"
"golang.org/x/tools/internal/typeparams"
)

func Test(t *testing.T) {
testdata := analysistest.TestData()
analysistest.Run(t, testdata, unusedresult.Analyzer, "a")
funcs := "typeparams/userdefs.MustUse,errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint"
unusedresult.Analyzer.Flags.Set("funcs", funcs)
tests := []string{"a"}
if typeparams.Enabled {
tests = append(tests, "typeparams")
}
analysistest.Run(t, testdata, unusedresult.Analyzer, tests...)
}

0 comments on commit 1c6db19

Please sign in to comment.