case *syntax.Operation:
if expr.Y == nil {
- return Unary(pos, g.typ(typ), g.op(expr.Op, unOps[:]), g.expr(expr.X))
+ n := Unary(pos, g.typ(typ), g.op(expr.Op, unOps[:]), g.expr(expr.X))
+ if n.Op() == ir.OADDR && !g.delayTransform() {
+ transformAddr(n.(*ir.AddrExpr))
+ }
+ return n
}
switch op := g.op(expr.Op, binOps[:]); op {
case ir.OEQ, ir.ONE, ir.OLT, ir.OLE, ir.OGT, ir.OGE:
key = g.expr(elem.Key)
}
value := wrapname(g.pos(elem.Value), g.expr(elem.Value))
+ if value.Op() == ir.OPAREN {
+ // Make sure any PAREN node added by wrapper has a type
+ typed(value.(*ir.ParenExpr).X.Type(), value)
+ }
exprs[i] = ir.NewKeyExpr(g.pos(elem), key, value)
default:
exprs[i] = wrapname(g.pos(elem), g.expr(elem))
+ if exprs[i].Op() == ir.OPAREN {
+ // Make sure any PAREN node added by wrapper has a type
+ typed(exprs[i].(*ir.ParenExpr).X.Type(), exprs[i])
+ }
}
}
n := ir.NewCompLitExpr(g.pos(lit), ir.OCOMPLIT, nil, exprs)
typed(g.typ(typ), n)
- return transformCompLit(n)
+ var r ir.Node = n
+ if !g.delayTransform() {
+ r = transformCompLit(n)
+ }
+ return r
}
func (g *irgen) funcLit(typ2 types2.Type, expr *syntax.FuncLit) ir.Node {
func Addr(pos src.XPos, x ir.Node) *ir.AddrExpr {
n := typecheck.NodAddrAt(pos, x)
- switch x.Op() {
- case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
- n.SetOp(ir.OPTRLIT)
- }
typed(types.NewPtr(x.Type()), n)
return n
}
case ir.OSELECT:
transformSelect(m.(*ir.SelectStmt))
+ case ir.OCOMPLIT:
+ transformCompLit(m.(*ir.CompLitExpr))
+
+ case ir.OADDR:
+ transformAddr(m.(*ir.AddrExpr))
+
}
}
// transformCompLit transforms n to an OARRAYLIT, OSLICELIT, OMAPLIT, or
// OSTRUCTLIT node, with any needed conversions. Corresponds to
-// typecheck.tcCompLit.
+// typecheck.tcCompLit (and includes parts corresponding to tcStructLitKey).
func transformCompLit(n *ir.CompLitExpr) (res ir.Node) {
assert(n.Type() != nil && n.Typecheck() == 1)
lno := base.Pos
if id, ok := key.(*ir.Ident); ok && typecheck.DotImportRefs[id] != nil {
s = typecheck.Lookup(s.Name)
}
+ if types.IsExported(s.Name) && s.Pkg != types.LocalPkg {
+ // Exported field names should always have
+ // local pkg. We only need to do this
+ // adjustment for generic functions that are
+ // being transformed after being imported
+ // from another package.
+ s = typecheck.Lookup(s.Name)
+ }
// An OXDOT uses the Sym field to hold
// the field to the right of the dot,
// so s will be non-nil, but an OXDOT
// is never a valid struct literal key.
- assert(!(s == nil || s.Pkg != types.LocalPkg || key.Op() == ir.OXDOT || s.IsBlank()))
+ assert(!(s == nil || key.Op() == ir.OXDOT || s.IsBlank()))
f := typecheck.Lookdot1(nil, s, t, t.Fields(), 0)
l := ir.NewStructKeyExpr(l.Pos(), f, kv.Value)
return n
}
+
+// transformAddr corresponds to typecheck.tcAddr.
+func transformAddr(n *ir.AddrExpr) {
+ switch n.X.Op() {
+ case ir.OARRAYLIT, ir.OMAPLIT, ir.OSLICELIT, ir.OSTRUCTLIT:
+ n.SetOp(ir.OPTRLIT)
+ }
+}
}
w.localName(n)
- // case OPACK, ONONAME:
+ case ir.ONONAME:
+ w.op(ir.ONONAME)
+ // This should only be for OKEY nodes in generic functions
+ s := n.Sym()
+ w.string(s.Name)
+ w.pkg(s.Pkg)
+ if go117ExportTypes {
+ w.typ(n.Type())
+ }
+
+ // case OPACK:
// should have been resolved by typechecking - handled by default case
case ir.OTYPE:
w.typ(n.Type())
w.fieldList(n.List) // special handling of field names
- case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
+ case ir.OCOMPLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
n := n.(*ir.CompLitExpr)
if go117ExportTypes {
w.op(n.Op())
return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.fieldList())
case ir.OCOMPLIT:
- return ir.NewCompLitExpr(r.pos(), ir.OCOMPLIT, ir.TypeNode(r.typ()), r.exprList())
+ pos := r.pos()
+ t := r.typ()
+ n := ir.NewCompLitExpr(pos, ir.OCOMPLIT, ir.TypeNode(t), r.exprList())
+ n.SetType(t)
+ return n
case ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
if !go117ExportTypes {
--- /dev/null
+// compile -G=3
+
+// Copyright 2021 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
+
+func main() {
+}
+
+type C interface {
+ map[int]string
+}
+
+func f[A C]() A {
+ return A{
+ 1: "a",
+ 2: "b",
+ }
+}