aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorRobert Findley <rfindley@google.com>2023-01-11 14:41:03 -0500
committerGopher Robot <gobot@golang.org>2023-01-11 22:29:34 +0000
commit245e95dfabd77f337373bf2d6bb47cd353ad8d74 (patch)
tree051d706f3319c8ee7bd1680505d26c5bde357c82 /src/internal
parent18625d9becc559e65ab5b39aa5d27ae6eb7b00aa (diff)
downloadgo-245e95dfabd77f337373bf2d6bb47cd353ad8d74.tar.xz
go/types, types2: don't look up fields or methods when expecting a type
As we have seen many times, the type checker must be careful to avoid accessing named type information before the type is fully set up. We need a more systematic solution to this problem, but for now avoid one case that causes a crash: checking a selector expression on an incomplete type when a type expression is expected. For golang/go#57522 Change-Id: I7ed31b859cca263276e3a0647d1f1b49670023a9 Reviewed-on: https://go-review.googlesource.com/c/go/+/461577 Run-TryBot: Robert Findley <rfindley@google.com> Auto-Submit: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/internal')
-rw-r--r--src/internal/types/testdata/check/cycles0.go2
-rw-r--r--src/internal/types/testdata/check/decls0.go10
-rw-r--r--src/internal/types/testdata/check/issues0.go2
-rw-r--r--src/internal/types/testdata/fixedbugs/issue39634.go2
-rw-r--r--src/internal/types/testdata/fixedbugs/issue57522.go24
5 files changed, 32 insertions, 8 deletions
diff --git a/src/internal/types/testdata/check/cycles0.go b/src/internal/types/testdata/check/cycles0.go
index d4e7e60f83..7c00c7d625 100644
--- a/src/internal/types/testdata/check/cycles0.go
+++ b/src/internal/types/testdata/check/cycles0.go
@@ -45,7 +45,7 @@ type (
// pointers
P0 *P0
- PP *struct{ PP.f /* ERROR no field or method f */ }
+ PP *struct{ PP.f /* ERROR PP.f is not a type */ }
// functions
F0 func(F0)
diff --git a/src/internal/types/testdata/check/decls0.go b/src/internal/types/testdata/check/decls0.go
index 6002a9e8a7..868b318a70 100644
--- a/src/internal/types/testdata/check/decls0.go
+++ b/src/internal/types/testdata/check/decls0.go
@@ -63,7 +63,7 @@ type (
type (
- p1 pi.foo /* ERROR "no field or method foo" */
+ p1 pi.foo /* ERROR "pi.foo is not a type" */
p2 unsafe.Pointer
)
@@ -189,10 +189,10 @@ func f4() (x *f4 /* ERROR "not a type" */ ) { return }
// TODO(#43215) this should be detected as a cycle error
func f5([unsafe.Sizeof(f5)]int) {}
-func (S0) m1 (x S0 /* ERROR illegal cycle in method declaration */ .m1) {}
-func (S0) m2 (x *S0 /* ERROR illegal cycle in method declaration */ .m2) {}
-func (S0) m3 () (x S0 /* ERROR illegal cycle in method declaration */ .m3) { return }
-func (S0) m4 () (x *S0 /* ERROR illegal cycle in method declaration */ .m4) { return }
+func (S0) m1 (x S0.m1 /* ERROR S0.m1 is not a type */ ) {}
+func (S0) m2 (x *S0.m2 /* ERROR S0.m2 is not a type */ ) {}
+func (S0) m3 () (x S0.m3 /* ERROR S0.m3 is not a type */ ) { return }
+func (S0) m4 () (x *S0.m4 /* ERROR S0.m4 is not a type */ ) { return }
// interfaces may not have any blank methods
type BlankI interface {
diff --git a/src/internal/types/testdata/check/issues0.go b/src/internal/types/testdata/check/issues0.go
index 0cea36c01f..4a66641369 100644
--- a/src/internal/types/testdata/check/issues0.go
+++ b/src/internal/types/testdata/check/issues0.go
@@ -97,7 +97,7 @@ func issue10979() {
nosuchpkg /* ERROR undefined: nosuchpkg */ .Nosuchtype
}
type I interface {
- I.m /* ERROR no field or method m */
+ I.m /* ERROR I.m is not a type */
m()
}
}
diff --git a/src/internal/types/testdata/fixedbugs/issue39634.go b/src/internal/types/testdata/fixedbugs/issue39634.go
index 7b458f22f2..6ee15489c5 100644
--- a/src/internal/types/testdata/fixedbugs/issue39634.go
+++ b/src/internal/types/testdata/fixedbugs/issue39634.go
@@ -19,7 +19,7 @@ func(*ph1[e,e /* ERROR redeclared */ ])h(d /* ERROR undefined */ )
// func t2[T Numeric2](s[]T){0 /* ERROR not a type */ []{s /* ERROR cannot index */ [0][0]}}
// crash 3
-type t3 *interface{ t3.p /* ERROR no field or method p */ }
+type t3 *interface{ t3.p /* ERROR t3.p is not a type */ }
// crash 4
type Numeric4 interface{t4 /* ERROR not a type */ }
diff --git a/src/internal/types/testdata/fixedbugs/issue57522.go b/src/internal/types/testdata/fixedbugs/issue57522.go
new file mode 100644
index 0000000000..d83e5b2443
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue57522.go
@@ -0,0 +1,24 @@
+// Copyright 2023 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.
+
+package p
+
+// A simplified version of the code in the original report.
+type S[T any] struct{}
+var V = S[any]{}
+func (fs *S[T]) M(V.M /* ERROR "V.M is not a type" */) {}
+
+// Other minimal reproducers.
+type S1[T any] V1.M /* ERROR "V1.M is not a type" */
+type V1 = S1[any]
+
+type S2[T any] struct{}
+type V2 = S2[any]
+func (fs *S2[T]) M(x V2.M /* ERROR "V2.M is not a type" */ ) {}
+
+// The following still panics, as the selector is reached from check.expr
+// rather than check.typexpr. TODO(rfindley): fix this.
+// type X[T any] int
+// func (X[T]) M(x [X[int].M]int) {}
+