Skip to content

Commit 0500fd4

Browse files
Antonboomtimothy-king
authored andcommitted
go/ssa: use core type in address
The type of an address is now the element type of a type whose core type is a pointer type. Previously this was the element type of a type whose underlying type was a pointer type. emitStore now uses the core type as well. func f[M any, P *M](p P) { var m M *p = m } is emitted as: func f[M any, P *M](p P): 0: *p = *new(M):M return Related to golang/go#57272 Fixes golang/go#58633 Change-Id: I35d4345a9b3f69bcd28cf8342f7fec550329eba4 Reviewed-on: https://go-review.googlesource.com/c/tools/+/492598 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Tim King <[email protected]> Reviewed-by: Alan Donovan <[email protected]>
1 parent 8e9b185 commit 0500fd4

File tree

4 files changed

+55
-4
lines changed

4 files changed

+55
-4
lines changed

go/ssa/builder_generic_test.go

+41-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ func TestGenericBodies(t *testing.T) {
340340
func d[T interface{ map[int]int64 }](x T) int64 {
341341
print(x, x[2], x[3]) //@ types(T, int64, int64)
342342
x[2] = 43
343-
return x[3]
343+
return x[3]
344344
}
345345
func e[T ~string](t T) {
346346
print(t, t[0]) //@ types(T, uint8)
@@ -413,6 +413,7 @@ func TestGenericBodies(t *testing.T) {
413413
`,
414414
},
415415
{
416+
// TODO(59983): investigate why writing g.c panics in (*FieldAddr).String.
416417
pkg: "g",
417418
contents: `package g
418419
type S struct{ f int }
@@ -458,6 +459,45 @@ func TestGenericBodies(t *testing.T) {
458459
}
459460
`,
460461
},
462+
{
463+
pkg: "k",
464+
contents: `
465+
package k
466+
467+
func f[M any, PM *M](p PM) {
468+
var m M
469+
*p = m
470+
print(m) /*@ types(M)*/
471+
print(p) /*@ types(PM)*/
472+
}
473+
`,
474+
},
475+
{
476+
pkg: "l",
477+
contents: `
478+
package l
479+
480+
type A struct{int}
481+
func (*A) Marker() {}
482+
483+
type B struct{string}
484+
func (*B) Marker() {}
485+
486+
type C struct{float32}
487+
func (*C) Marker() {}
488+
489+
func process[T interface {
490+
*A
491+
*B
492+
*C
493+
Marker()
494+
}](v T) {
495+
v.Marker()
496+
a := *(any(v).(*A)); print(a) /*@ types("l.A")*/
497+
b := *(any(v).(*B)); print(b) /*@ types("l.B")*/
498+
c := *(any(v).(*C)); print(c) /*@ types("l.C")*/
499+
}`,
500+
},
461501
} {
462502
test := test
463503
t.Run(test.pkg, func(t *testing.T) {

go/ssa/emit.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,10 @@ func emitTypeCoercion(f *Function, v Value, typ types.Type) Value {
372372
// emitStore emits to f an instruction to store value val at location
373373
// addr, applying implicit conversions as required by assignability rules.
374374
func emitStore(f *Function, addr, val Value, pos token.Pos) *Store {
375+
typ := mustDeref(addr.Type())
375376
s := &Store{
376377
Addr: addr,
377-
Val: emitConv(f, val, deref(addr.Type())),
378+
Val: emitConv(f, val, typ),
378379
pos: pos,
379380
}
380381
f.emit(s)

go/ssa/lvalue.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type lvalue interface {
2525

2626
// An address is an lvalue represented by a true pointer.
2727
type address struct {
28-
addr Value
28+
addr Value // must have a pointer core type.
2929
pos token.Pos // source position
3030
expr ast.Expr // source syntax of the value (not address) [debug mode]
3131
}
@@ -52,7 +52,7 @@ func (a *address) address(fn *Function) Value {
5252
}
5353

5454
func (a *address) typ() types.Type {
55-
return deref(a.addr.Type())
55+
return mustDeref(a.addr.Type())
5656
}
5757

5858
// An element is an lvalue represented by m[k], the location of an

go/ssa/util.go

+10
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,16 @@ func deref(typ types.Type) types.Type {
108108
return typ
109109
}
110110

111+
// mustDeref returns the element type of a type with a pointer core type.
112+
// Panics on failure.
113+
func mustDeref(typ types.Type) types.Type {
114+
// TODO(taking): Replace deref with mustDeref when possible.
115+
if p, ok := typeparams.CoreType(typ).(*types.Pointer); ok {
116+
return p.Elem()
117+
}
118+
panic("cannot dereference type " + typ.String())
119+
}
120+
111121
// recvType returns the receiver type of method obj.
112122
func recvType(obj *types.Func) types.Type {
113123
return obj.Type().(*types.Signature).Recv().Type()

0 commit comments

Comments
 (0)