aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Freeman <mark@golang.org>2026-01-30 14:23:02 -0500
committerRobert Griesemer <gri@google.com>2026-02-02 15:18:11 -0800
commit7fd116f86451d7262f7683629b90c8adc0137f53 (patch)
treee16f90c4bbfda0b4cf2d09c6d9fe5a04904f7a08
parent8ac41b52c4b7a6ab9c41d008abbe254270200b8e (diff)
downloadgo-7fd116f86451d7262f7683629b90c8adc0137f53.tar.xz
go/types, types2: add missing Named.unpack call in Checker.hasVarSize
CL 734980 swapped use of Type.Underlying() in Checker.hasVarSize for traversal of Named.fromRHS. It forgot to call Named.unpack() before inspecting Named.fromRHS, allowing access of unexpanded instantiated types. These unexpanded instantiated types are then mistakenly marked as having fixed size, which fails assertions downstream. This change adds the missing Named.unpack() call and swaps direct access of Named.fromRHS for Named.rhs(), which verifies such access in debug mode. Fixes #77382 Change-Id: I324bbbbf790f8b09e95902ebe67f775483f88417 Reviewed-on: https://go-review.googlesource.com/c/go/+/740620 Reviewed-by: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
-rw-r--r--src/cmd/compile/internal/types2/builtins.go7
-rw-r--r--src/go/types/builtins.go7
-rw-r--r--src/internal/types/testdata/fixedbugs/issue77382.go15
3 files changed, 25 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 5965228585..5fa0e6c6f0 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -1009,7 +1009,8 @@ func sliceElem(x *operand) (Type, *typeError) {
// yet been checked.
func (check *Checker) hasVarSize(t Type) bool {
// Note: We could use Underlying here, but passing through the RHS may yield
- // better error messages.
+ // better error messages and allows us to stash the result on each traversed
+ // Named type.
switch t := Unalias(t).(type) {
case *Named:
if t.stateHas(hasVarSize) {
@@ -1025,7 +1026,9 @@ func (check *Checker) hasVarSize(t Type) bool {
check.push(t.obj)
defer check.pop()
- varSize := check.hasVarSize(t.fromRHS)
+ // Careful, we're inspecting t.fromRHS, so we need to unpack first.
+ t.unpack()
+ varSize := check.hasVarSize(t.rhs())
t.mu.Lock()
defer t.mu.Unlock()
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index aea2997f32..3b8a91a9f7 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -1012,7 +1012,8 @@ func sliceElem(x *operand) (Type, *typeError) {
// yet been checked.
func (check *Checker) hasVarSize(t Type) bool {
// Note: We could use Underlying here, but passing through the RHS may yield
- // better error messages.
+ // better error messages and allows us to stash the result on each traversed
+ // Named type.
switch t := Unalias(t).(type) {
case *Named:
if t.stateHas(hasVarSize) {
@@ -1028,7 +1029,9 @@ func (check *Checker) hasVarSize(t Type) bool {
check.push(t.obj)
defer check.pop()
- varSize := check.hasVarSize(t.fromRHS)
+ // Careful, we're inspecting t.fromRHS, so we need to unpack first.
+ t.unpack()
+ varSize := check.hasVarSize(t.rhs())
t.mu.Lock()
defer t.mu.Unlock()
diff --git a/src/internal/types/testdata/fixedbugs/issue77382.go b/src/internal/types/testdata/fixedbugs/issue77382.go
new file mode 100644
index 0000000000..251d39a438
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue77382.go
@@ -0,0 +1,15 @@
+// Copyright 2026 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
+
+import "unsafe"
+
+type T1[T any] [42]T2[T]
+
+type T2[T any] [42]T
+
+func _[T any]() {
+ _ = unsafe.Sizeof(T1[T]{})
+}