]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: set correct Pos for T in struct{p.T}
authorAlan Donovan <adonovan@google.com>
Wed, 24 May 2023 18:16:38 +0000 (14:16 -0400)
committerGopher Robot <gobot@golang.org>
Wed, 24 May 2023 23:16:04 +0000 (23:16 +0000)
Previously, the field Var for T created for struct{p.T}
would use the Pos of the ast.Field, which coincides with p.
This change makes it use the Pos of T.

Errors about the field type are still reported at the
position of the ast.Field (e.g. *p.T) not the field T.

Fixes #60372

Change-Id: I06000874f2018d47159493626da3d16e6716f4c8
Reviewed-on: https://go-review.googlesource.com/c/go/+/497882
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Alan Donovan <adonovan@google.com>

src/cmd/compile/internal/types2/struct.go
src/go/types/struct.go
src/internal/types/testdata/check/decls3.go
src/internal/types/testdata/examples/types.go

index 5de3fa8f422c2dae551a38784c1b7a7a212150f6..125e94647b36afb998b973f5f8f4e036279b3472 100644 (file)
@@ -127,7 +127,7 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
                        // spec: "An embedded type must be specified as a type name T or as a
                        // pointer to a non-interface type name *T, and T itself may not be a
                        // pointer type."
-                       pos := syntax.StartPos(f.Type)
+                       pos := syntax.StartPos(f.Type) // position of type, for errors
                        name := embeddedFieldIdent(f.Type)
                        if name == nil {
                                check.errorf(pos, InvalidSyntaxTree, "invalid embedded field type %s", f.Type)
@@ -135,7 +135,7 @@ func (check *Checker) structType(styp *Struct, e *syntax.StructType) {
                                addInvalid(name, pos)
                                continue
                        }
-                       add(name, true, pos)
+                       add(name, true, name.Pos()) // struct{p.T} field has position of T
 
                        // Because we have a name, typ must be of the form T or *T, where T is the name
                        // of a (named or alias) type, and t (= deref(typ)) must be the type of T.
index 89aea02ccadd5b0ab18621158905ce44aab4395f..7247a25719ce5980e607e916eb9c26988f170929 100644 (file)
@@ -122,7 +122,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
                        // spec: "An embedded type must be specified as a type name T or as a
                        // pointer to a non-interface type name *T, and T itself may not be a
                        // pointer type."
-                       pos := f.Type.Pos()
+                       pos := f.Type.Pos() // position of type, for errors
                        name := embeddedFieldIdent(f.Type)
                        if name == nil {
                                check.errorf(f.Type, InvalidSyntaxTree, "embedded field type %s has no name", f.Type)
@@ -131,7 +131,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
                                addInvalid(name, pos)
                                continue
                        }
-                       add(name, true, pos)
+                       add(name, true, name.Pos()) // struct{p.T} field has position of T
 
                        // Because we have a name, typ must be of the form T or *T, where T is the name
                        // of a (named or alias) type, and t (= deref(typ)) must be the type of T.
index fed2f600551ffc99bcfed5356896965211c9553b..3d00a580ab922caa9f29c0c92e9637a758e617b9 100644 (file)
@@ -99,9 +99,9 @@ func _() {
        // unsafe.Pointers are treated like regular pointers when embedded
        type T2 struct {
                unsafe /* ERROR "cannot be unsafe.Pointer" */ .Pointer
-               */* ERROR "cannot be unsafe.Pointer" */ /* ERROR "Pointer redeclared" */ unsafe.Pointer
+               */* ERROR "cannot be unsafe.Pointer" */ unsafe.Pointer /* ERROR "Pointer redeclared" */
                UP /* ERROR "cannot be unsafe.Pointer" */
-               * /* ERROR "cannot be unsafe.Pointer" */  /* ERROR "UP redeclared" */ UP
+               * /* ERROR "cannot be unsafe.Pointer" */ UP /* ERROR "UP redeclared" */
        }
 }
 
index 562080b92805ec351c42683586e20114d2b2a983..67f1534be394792d3d77efef763b4a8ad58db488 100644 (file)
@@ -152,7 +152,7 @@ type _ struct {
        List[int]
 
        int8 /* ERROR "int8 redeclared" */
-       * /* ERROR "int16 redeclared" */ int16
+       *int16 /* ERROR "int16 redeclared" */
        List /* ERROR "List redeclared" */ [int]
 }
 
@@ -166,17 +166,17 @@ type _ struct {
 // func _[T interface{ m(); ~int }]() {
 //     type L T
 //     var x L
-// 
+//
 //     // m is not defined on L (it is not "inherited" from
 //     // its underlying type).
 //     x.m /* ERROR "x.m undefined" */ ()
-// 
+//
 //     // But the properties of T, such that as that it supports
 //     // the operations of the types given by its type bound,
 //     // are also the properties of L.
 //     x++
 //     _ = x - x
-// 
+//
 //     // On the other hand, if we define a local alias for T,
 //     // that alias stands for T as expected.
 //     type A = T