diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go index bc390158465..311c5858b2c 100644 --- a/src/cmd/compile/internal/typecheck/subr.go +++ b/src/cmd/compile/internal/typecheck/subr.go @@ -1532,7 +1532,7 @@ func Shapify(t *types.Type, index int, tparam *types.Type) *types.Type { // Note: pointers to arrays are special because of slice-to-array-pointer // conversions. See issue 49295. if u.Kind() == types.TPTR && u.Elem().Kind() != types.TARRAY && - tparam.Bound().StructuralType() == nil { + tparam.Bound().StructuralType() == nil && !u.Elem().NotInHeap() { u = types.Types[types.TUINT8].PtrTo() } diff --git a/test/typeparam/issue51733.go b/test/typeparam/issue51733.go new file mode 100644 index 00000000000..03624f18655 --- /dev/null +++ b/test/typeparam/issue51733.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 ( + "log" + "unsafe" +) + +//go:notinheap +type S struct{} + +func main() { + p := (*S)(unsafe.Pointer(uintptr(0x8000))) + var v any = p + p2 := v.(*S) + if p != p2 { + log.Fatalf("%p != %p", unsafe.Pointer(p), unsafe.Pointer(p2)) + } + p2 = typeAssert[*S](v) + if p != p2 { + log.Fatalf("%p != %p from typeAssert", unsafe.Pointer(p), unsafe.Pointer(p2)) + } +} + +func typeAssert[T any](v any) T { + return v.(T) +}