mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
![Dan Scales](/assets/img/avatar_default.png)
In the compiler, we need to distinguish field and method access on a type param. For field access, we avoid the dictionary access (to create an interface bound) and just do the normal transformDot() (which will create the field access on the shape type). This field access works fine for non-pointer types, since the shape type preserves the underlying type of all types in the shape. But we generally merge all pointer types into a single shape, which means the field will not be accessible via the shape type. So, we need to change Shapify() so that a type which is a pointer type is mapped to its underlying type, rather than being merged with other pointers. Because we don't want to change the export format at this point in the release, we need to compute StructuralType() directly in types1, rather than relying on types2. That implementation is in types/type.go, along with the helper specificTypes(). I enabled the compiler-related tests in issue50417.go, added an extra test for unnamed pointer types, and added a bunch more tests for interesting cases involving StructuralType(). I added a test issue50417b.go similar to the original example, but also tests access to an embedded field. I also added a unit test in cmd/compile/internal/types/structuraltype_test.go that tests a bunch of unusual cases directly (some of which have no structural type). Updates #50417 Change-Id: I77c55cbad98a2b95efbd4a02a026c07dfbb46caa Reviewed-on: https://go-review.googlesource.com/c/go/+/376194 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
51 lines
756 B
Go
51 lines
756 B
Go
// run -gcflags=-G=3
|
|
|
|
// 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 "fmt"
|
|
|
|
type MyStruct struct {
|
|
b1, b2 string
|
|
E
|
|
}
|
|
|
|
type E struct {
|
|
val int
|
|
}
|
|
|
|
type C interface {
|
|
~struct {
|
|
b1, b2 string
|
|
E
|
|
}
|
|
}
|
|
|
|
func f[T C]() T {
|
|
var x T = T{
|
|
b1: "a",
|
|
b2: "b",
|
|
}
|
|
|
|
if got, want := x.b2, "b"; got != want {
|
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
|
}
|
|
x.b1 = "y"
|
|
x.val = 5
|
|
|
|
return x
|
|
}
|
|
|
|
func main() {
|
|
x := f[MyStruct]()
|
|
if got, want := x.b1, "y"; got != want {
|
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
|
}
|
|
if got, want := x.val, 5; got != want {
|
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
|
}
|
|
}
|