mirror of
https://github.com/golang/go
synced 2024-11-26 23:31:24 -07:00
go/types, cmd/compile: fix composite literal structural typing
For a composite literal expression like []T{{f: 1}}, we allow T to be a pointer to struct type, so it's consistent to allow T to also be a type parameter whose structural type is a pointer to struct type. Fixes #50833. Change-Id: Ib0781ec4a4f327c875ea25b97740ff2c0c86b916 Reviewed-on: https://go-review.googlesource.com/c/go/+/381075 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Robert Griesemer <gri@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
b7b44b3173
commit
1a2435c95f
@ -332,7 +332,7 @@ func (g *irgen) exprs(exprs []syntax.Expr) []ir.Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
|
func (g *irgen) compLit(typ types2.Type, lit *syntax.CompositeLit) ir.Node {
|
||||||
if ptr, ok := typ.Underlying().(*types2.Pointer); ok {
|
if ptr, ok := types2.StructuralType(typ).(*types2.Pointer); ok {
|
||||||
n := ir.NewAddrExpr(g.pos(lit), g.compLit(ptr.Elem(), lit))
|
n := ir.NewAddrExpr(g.pos(lit), g.compLit(ptr.Elem(), lit))
|
||||||
n.SetOp(ir.OPTRLIT)
|
n.SetOp(ir.OPTRLIT)
|
||||||
return typed(g.typ(typ), n)
|
return typed(g.typ(typ), n)
|
||||||
|
@ -1338,8 +1338,7 @@ func (w *writer) compLit(lit *syntax.CompositeLit) {
|
|||||||
w.typ(tv.Type)
|
w.typ(tv.Type)
|
||||||
|
|
||||||
typ := tv.Type
|
typ := tv.Type
|
||||||
// TODO(mdempsky): Use types2.StructuralType here too? See #50833.
|
if ptr, ok := types2.StructuralType(typ).(*types2.Pointer); ok {
|
||||||
if ptr, ok := typ.Underlying().(*types2.Pointer); ok {
|
|
||||||
typ = ptr.Elem()
|
typ = ptr.Elem()
|
||||||
}
|
}
|
||||||
str, isStruct := types2.StructuralType(typ).(*types2.Struct)
|
str, isStruct := types2.StructuralType(typ).(*types2.Struct)
|
||||||
|
@ -1262,11 +1262,7 @@ func (check *Checker) exprInternal(x *operand, e syntax.Expr, hint Type) exprKin
|
|||||||
case hint != nil:
|
case hint != nil:
|
||||||
// no composite literal type present - use hint (element type of enclosing type)
|
// no composite literal type present - use hint (element type of enclosing type)
|
||||||
typ = hint
|
typ = hint
|
||||||
base = typ
|
base, _ = deref(structuralType(typ)) // *T implies &T{}
|
||||||
if !isTypeParam(typ) {
|
|
||||||
base = under(typ)
|
|
||||||
}
|
|
||||||
base, _ = deref(base) // *T implies &T{}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// TODO(gri) provide better error messages depending on context
|
// TODO(gri) provide better error messages depending on context
|
||||||
|
16
src/cmd/compile/internal/types2/testdata/fixedbugs/issue50833.go2
vendored
Normal file
16
src/cmd/compile/internal/types2/testdata/fixedbugs/issue50833.go2
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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 p
|
||||||
|
|
||||||
|
type (
|
||||||
|
S struct{ f int }
|
||||||
|
PS *S
|
||||||
|
)
|
||||||
|
|
||||||
|
func a() []*S { return []*S{{f: 1}} }
|
||||||
|
func b() []PS { return []PS{{f: 1}} }
|
||||||
|
|
||||||
|
func c[P *S]() []P { return []P{{f: 1}} }
|
||||||
|
func d[P PS]() []P { return []P{{f: 1}} }
|
@ -1241,11 +1241,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
|||||||
case hint != nil:
|
case hint != nil:
|
||||||
// no composite literal type present - use hint (element type of enclosing type)
|
// no composite literal type present - use hint (element type of enclosing type)
|
||||||
typ = hint
|
typ = hint
|
||||||
base = typ
|
base, _ = deref(structuralType(typ)) // *T implies &T{}
|
||||||
if !isTypeParam(typ) {
|
|
||||||
base = under(typ)
|
|
||||||
}
|
|
||||||
base, _ = deref(base) // *T implies &T{}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// TODO(gri) provide better error messages depending on context
|
// TODO(gri) provide better error messages depending on context
|
||||||
|
16
src/go/types/testdata/fixedbugs/issue50833.go2
vendored
Normal file
16
src/go/types/testdata/fixedbugs/issue50833.go2
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// 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 p
|
||||||
|
|
||||||
|
type (
|
||||||
|
S struct{ f int }
|
||||||
|
PS *S
|
||||||
|
)
|
||||||
|
|
||||||
|
func a() []*S { return []*S{{f: 1}} }
|
||||||
|
func b() []PS { return []PS{{f: 1}} }
|
||||||
|
|
||||||
|
func c[P *S]() []P { return []P{{f: 1}} }
|
||||||
|
func d[P PS]() []P { return []P{{f: 1}} }
|
23
test/typeparam/issue50833.go
Normal file
23
test/typeparam/issue50833.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// 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
|
||||||
|
|
||||||
|
type (
|
||||||
|
S struct{ f int }
|
||||||
|
PS *S
|
||||||
|
)
|
||||||
|
|
||||||
|
func a() []*S { return []*S{{f: 1}} }
|
||||||
|
func b() []PS { return []PS{{f: 1}} }
|
||||||
|
|
||||||
|
func c[P *S]() []P { return []P{{f: 1}} }
|
||||||
|
func d[P PS]() []P { return []P{{f: 1}} }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
c[*S]()
|
||||||
|
d[PS]()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user