diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
index 53c2912..10b7c82 100644
--- a/src/cmd/compile/internal/typecheck/expr.go
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -312,6 +312,19 @@
return ir.NewStructKeyExpr(kv.Pos(), f, kv.Value)
}
+ var f *types.Field
+ if p, ambig := dotpath(sym, typ, &f, false); p != nil {
+ if ambig {
+ base.Errorf("ambiguous promoted field '%v' in struct literal of type %v", sym, typ)
+ return nil
+ }
+ if f.IsMethod() {
+ base.Errorf("cannot use method '%v' in struct literal of type %v", sym, typ)
+ return nil
+ }
+ return ir.NewStructKeyExpr(kv.Pos(), f, kv.Value)
+ }
+
if ci := Lookdot1(nil, sym, typ, typ.Fields(), 2); ci != nil { // Case-insensitive lookup.
if visible(ci.Sym) {
base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", sym, typ, ci.Sym)
@@ -323,7 +336,6 @@
return nil
}
- var f *types.Field
p, _ := dotpath(sym, typ, &f, true)
if p == nil || f.IsMethod() {
base.Errorf("unknown field '%v' in struct literal of type %v", sym, typ)
@@ -335,8 +347,8 @@
for ei := len(p) - 1; ei >= 0; ei-- {
ep = append(ep, p[ei].field.Sym.Name)
}
- ep = append(ep, sym.Name)
- base.Errorf("cannot use promoted field %v in struct literal of type %v", strings.Join(ep, "."), typ)
+ ep = append(ep, f.Sym.Name)
+ base.Errorf("unknown field '%v' in struct literal of type %v (but does have %v)", sym, typ, strings.Join(ep, "."))
return nil
}
diff --git a/src/cmd/compile/internal/walk/complit.go b/src/cmd/compile/internal/walk/complit.go
index 1bc4d42..6f04a37 100644
--- a/src/cmd/compile/internal/walk/complit.go
+++ b/src/cmd/compile/internal/walk/complit.go
@@ -220,7 +220,7 @@
return ir.BlankNode, r.Value
}
ir.SetPos(r)
- return ir.NewSelectorExpr(base.Pos, ir.ODOT, var_, r.Sym()), r.Value
+ return ir.NewSelectorExpr(base.Pos, ir.OXDOT, var_, r.Sym()), r.Value
}
default:
base.Fatalf("fixedlit bad op: %v", n.Op())
diff --git a/test/complit2.go b/test/complit2.go
new file mode 100644
index 0000000..43b23c0
--- /dev/null
+++ b/test/complit2.go
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2026 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.
+
+// Verify that composite literals using selectors for
+// embedded fields are assembled correctly.
+
+package main
+
+import "fmt"
+
+type A struct {
+ a int
+ B
+}
+
+type B struct {
+ b string
+ C
+}
+
+type C struct {
+ c any
+}
+
+func main() {
+ eq(A{1, B{b: "foo"}}, A{a: 1, b: "foo"})
+ eq(A{B: B{C: C{c: "foo"}}}, A{c: "foo"})
+}
+
+func eq(x, y any) {
+ if x != y {
+ panic(fmt.Sprintf("%v != %v", x, y))
+ }
+}