Skip to content

Commit fd2bfb7

Browse files
committed
go/analysis/passes/stdmethods: recognize any as alias for interface{}, for errors.As check
Now that any is an alias for interface{}, we need to recognize both func (T) As(any) bool func (T) As(interface{}) bool as satisfying errors.As. For golang/go#33232. Change-Id: Ie5a992c37da8020e80367528bc23370227a70f75 Reviewed-on: https://go-review.googlesource.com/c/tools/+/369954 Trust: Russ Cox <[email protected]> Run-TryBot: Russ Cox <[email protected]> gopls-CI: kokoro <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent 68cbf41 commit fd2bfb7

File tree

4 files changed

+24
-6
lines changed

4 files changed

+24
-6
lines changed

go/analysis/passes/stdmethods/stdmethods.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ var Analyzer = &analysis.Analyzer{
6161
// we let it go. But if it does have a fmt.ScanState, then the
6262
// rest has to match.
6363
var canonicalMethods = map[string]struct{ args, results []string }{
64-
"As": {[]string{"interface{}"}, []string{"bool"}}, // errors.As
64+
"As": {[]string{"any"}, []string{"bool"}}, // errors.As
6565
// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
6666
"Format": {[]string{"=fmt.State", "rune"}, []string{}}, // fmt.Formatter
6767
"GobDecode": {[]string{"[]byte"}, []string{"error"}}, // gob.GobDecoder
@@ -194,7 +194,9 @@ func matchParams(pass *analysis.Pass, expect []string, actual *types.Tuple, pref
194194
func matchParamType(expect string, actual types.Type) bool {
195195
expect = strings.TrimPrefix(expect, "=")
196196
// Overkill but easy.
197-
return typeString(actual) == expect
197+
t := typeString(actual)
198+
return t == expect ||
199+
(t == "any" || t == "interface{}") && (expect == "any" || expect == "interface{}")
198200
}
199201

200202
var errorType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)

go/analysis/passes/stdmethods/testdata/src/a/a.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,18 @@ type E int
4747

4848
func (E) Error() string { return "" } // E implements error.
4949

50-
func (E) As() {} // want `method As\(\) should have signature As\(interface{}\) bool`
50+
func (E) As() {} // want `method As\(\) should have signature As\((any|interface\{\})\) bool`
5151
func (E) Is() {} // want `method Is\(\) should have signature Is\(error\) bool`
5252
func (E) Unwrap() {} // want `method Unwrap\(\) should have signature Unwrap\(\) error`
5353

5454
type F int
5555

5656
func (F) Error() string { return "" } // Both F and *F implement error.
5757

58-
func (*F) As() {} // want `method As\(\) should have signature As\(interface{}\) bool`
58+
func (*F) As() {} // want `method As\(\) should have signature As\((any|interface\{\})\) bool`
5959
func (*F) Is() {} // want `method Is\(\) should have signature Is\(error\) bool`
6060
func (*F) Unwrap() {} // want `method Unwrap\(\) should have signature Unwrap\(\) error`
61+
62+
type G int
63+
64+
func (G) As(interface{}) bool // ok
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build go1.18
6+
// +build go1.18
7+
8+
package a
9+
10+
type H int
11+
12+
func (H) As(any) bool // ok

go/analysis/passes/stdmethods/testdata/src/typeparams/typeparams.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ type E[P any] int
2828

2929
func (E[_]) Error() string { return "" } // E implements error.
3030

31-
func (E[P]) As() {} // want `method As\(\) should have signature As\(interface{}\) bool`
31+
func (E[P]) As() {} // want `method As\(\) should have signature As\((any|interface\{\})\) bool`
3232
func (E[_]) Is() {} // want `method Is\(\) should have signature Is\(error\) bool`
3333
func (E[_]) Unwrap() {} // want `method Unwrap\(\) should have signature Unwrap\(\) error`
3434

3535
type F[P any] int
3636

3737
func (F[_]) Error() string { return "" } // Both F and *F implement error.
3838

39-
func (*F[_]) As() {} // want `method As\(\) should have signature As\(interface{}\) bool`
39+
func (*F[_]) As() {} // want `method As\(\) should have signature As\((any|interface\{\})\) bool`
4040
func (*F[_]) Is() {} // want `method Is\(\) should have signature Is\(error\) bool`
4141
func (*F[_]) Unwrap() {} // want `method Unwrap\(\) should have signature Unwrap\(\) error`

0 commit comments

Comments
 (0)