From fc2e860eda39f6bcbe1fecac7b92a50598d1fab9 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Thu, 1 Oct 2026 22:18:19 +0800 Subject: [PATCH 1/3] go/ir: avoid canonicalizing function signatures --- go/ir/instantiate.go | 5 ++++- internal/passes/buildir/buildir_test.go | 6 ++++++ .../testdata/src/issue1749/issue1749.go | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 internal/passes/buildir/testdata/src/issue1749/issue1749.go diff --git a/go/ir/instantiate.go b/go/ir/instantiate.go index bcb6d9a89..cfdf16e01 100644 --- a/go/ir/instantiate.go +++ b/go/ir/instantiate.go @@ -97,7 +97,10 @@ func createInstance(fn *Function, rtargs, targs []types.Type) *Function { panic("Instantiate of a Signature returned a non-signature") } obj = fn.object // instantiation does not exist yet - sig = prog.canon.Type(instance).(*types.Signature) + // Do not canonicalize signatures here. Receiver types are not part of + // signature identity, so a function signature may otherwise reuse a + // previously canonicalized method signature with a receiver. + sig = instance } // Choose strategy (instance or wrapper). diff --git a/internal/passes/buildir/buildir_test.go b/internal/passes/buildir/buildir_test.go index fe78b3af3..358104ff7 100644 --- a/internal/passes/buildir/buildir_test.go +++ b/internal/passes/buildir/buildir_test.go @@ -11,6 +11,7 @@ import ( "golang.org/x/tools/go/analysis/analysistest" "honnef.co/go/tools/internal/passes/buildir" + "honnef.co/go/tools/internal/xtools-internal/testenv" ) func Test(t *testing.T) { @@ -26,3 +27,8 @@ func Test(t *testing.T) { } } } + +func TestGenericMethodValueWithGenericFunction(t *testing.T) { + testenv.NeedsGoCommand1Point(t, 27) + analysistest.Run(t, analysistest.TestData(), buildir.Analyzer, "issue1749") +} diff --git a/internal/passes/buildir/testdata/src/issue1749/issue1749.go b/internal/passes/buildir/testdata/src/issue1749/issue1749.go new file mode 100644 index 000000000..03f424749 --- /dev/null +++ b/internal/passes/buildir/testdata/src/issue1749/issue1749.go @@ -0,0 +1,18 @@ +package issue1749 + +type T struct{} + +func (T) M[P any]() P { + var zero P + return zero +} + +func G[P any]() P { + var zero P + return zero +} + +func F(t T) string { + f := t.M[string] + return f() + G[string]() +} From 470bb917456f0806591fe1e809defc8fe269af58 Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 2 Oct 2026 00:47:05 +0800 Subject: [PATCH 2/3] Validate XML chardata field types --- staticcheck/fakexml/marshal.go | 1 - .../CheckUnsupportedMarshal.go | 13 +++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/staticcheck/fakexml/marshal.go b/staticcheck/fakexml/marshal.go index 9c71e8632..7c481e2c6 100644 --- a/staticcheck/fakexml/marshal.go +++ b/staticcheck/fakexml/marshal.go @@ -340,7 +340,6 @@ func (e *Encoder) marshalStruct(tinfo *typeInfo, val fakereflect.TypeAndCanAddr, continue } } - continue case fComment: vf = indirect(vf) diff --git a/staticcheck/sa1026/testdata/go1.0/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go b/staticcheck/sa1026/testdata/go1.0/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go index 2ae94692c..4d0cbb23c 100644 --- a/staticcheck/sa1026/testdata/go1.0/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go +++ b/staticcheck/sa1026/testdata/go1.0/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go @@ -57,6 +57,14 @@ type Recursive struct { Field *Recursive } +type UnsupportedCharData struct { + Field chan int `xml:",chardata"` +} + +type UnsupportedCDATA struct { + Field func() `xml:",cdata"` +} + type ValueMarshaler chan int func (ValueMarshaler) MarshalText() ([]byte, error) { return nil, nil } @@ -316,6 +324,11 @@ func cyclicPointer() { xml.Marshal(s) //@ diag(`cyclic type P, via x.Foo.Bar`) } +func unsupportedTextFields() { + xml.Marshal(UnsupportedCharData{}) //@ diag(`unsupported type chan int`) + xml.Marshal(UnsupportedCDATA{}) //@ diag(`unsupported type func()`) +} + func functionAsArgument(arg T1) { // https://staticcheck.io/issues/1660 From 29b8ba07be3ec04126693cb1c66b67518cae7ddf Mon Sep 17 00:00:00 2001 From: dajiaohuang Date: Fri, 2 Oct 2026 14:16:05 +0800 Subject: [PATCH 3/3] Keep fix independent of generic IR change --- go/ir/instantiate.go | 5 +---- internal/passes/buildir/buildir_test.go | 6 ------ .../testdata/src/issue1749/issue1749.go | 18 ------------------ 3 files changed, 1 insertion(+), 28 deletions(-) delete mode 100644 internal/passes/buildir/testdata/src/issue1749/issue1749.go diff --git a/go/ir/instantiate.go b/go/ir/instantiate.go index cfdf16e01..bcb6d9a89 100644 --- a/go/ir/instantiate.go +++ b/go/ir/instantiate.go @@ -97,10 +97,7 @@ func createInstance(fn *Function, rtargs, targs []types.Type) *Function { panic("Instantiate of a Signature returned a non-signature") } obj = fn.object // instantiation does not exist yet - // Do not canonicalize signatures here. Receiver types are not part of - // signature identity, so a function signature may otherwise reuse a - // previously canonicalized method signature with a receiver. - sig = instance + sig = prog.canon.Type(instance).(*types.Signature) } // Choose strategy (instance or wrapper). diff --git a/internal/passes/buildir/buildir_test.go b/internal/passes/buildir/buildir_test.go index 358104ff7..fe78b3af3 100644 --- a/internal/passes/buildir/buildir_test.go +++ b/internal/passes/buildir/buildir_test.go @@ -11,7 +11,6 @@ import ( "golang.org/x/tools/go/analysis/analysistest" "honnef.co/go/tools/internal/passes/buildir" - "honnef.co/go/tools/internal/xtools-internal/testenv" ) func Test(t *testing.T) { @@ -27,8 +26,3 @@ func Test(t *testing.T) { } } } - -func TestGenericMethodValueWithGenericFunction(t *testing.T) { - testenv.NeedsGoCommand1Point(t, 27) - analysistest.Run(t, analysistest.TestData(), buildir.Analyzer, "issue1749") -} diff --git a/internal/passes/buildir/testdata/src/issue1749/issue1749.go b/internal/passes/buildir/testdata/src/issue1749/issue1749.go deleted file mode 100644 index 03f424749..000000000 --- a/internal/passes/buildir/testdata/src/issue1749/issue1749.go +++ /dev/null @@ -1,18 +0,0 @@ -package issue1749 - -type T struct{} - -func (T) M[P any]() P { - var zero P - return zero -} - -func G[P any]() P { - var zero P - return zero -} - -func F(t T) string { - f := t.M[string] - return f() + G[string]() -}