diff --git a/src/cmd/compile/internal/typecheck/const.go b/src/cmd/compile/internal/typecheck/const.go index 22fa9e7d95..6109850c24 100644 --- a/src/cmd/compile/internal/typecheck/const.go +++ b/src/cmd/compile/internal/typecheck/const.go @@ -805,6 +805,18 @@ func evalunsafe(n ir.Node) int64 { sel.X = Expr(sel.X) sbase := sel.X + // Implicit dot may already be resolved for instantiating generic function. So we + // need to remove any implicit dot until we reach the first non-implicit one, it's + // the right base selector. See issue #53137. + var clobberBase func(n ir.Node) ir.Node + clobberBase = func(n ir.Node) ir.Node { + if sel, ok := n.(*ir.SelectorExpr); ok && sel.Implicit() { + return clobberBase(sel.X) + } + return n + } + sbase = clobberBase(sbase) + tsel := Expr(sel) n.X = tsel if tsel.Type() == nil { diff --git a/test/fixedbugs/issue53137.go b/test/fixedbugs/issue53137.go new file mode 100644 index 0000000000..a0e67211ce --- /dev/null +++ b/test/fixedbugs/issue53137.go @@ -0,0 +1,32 @@ +// run + +// Copyright 2022 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 main + +import ( + "unsafe" +) + +type Embedded struct { + B int +} + +type S[K any] struct { + A K + Embedded +} + +func showOffsets[K any](d *S[K]) { + o1 := unsafe.Offsetof(d.B) + o2 := unsafe.Offsetof(d.Embedded) + if o1 != o2 { + panic("offset mismatch") + } +} + +func main() { + showOffsets(new(S[int])) +}