n.Y = o.safeMapRHS(n.Y)
}
o.out = append(o.out, n)
-
- case ir.OAS2, ir.OAS2DOTTYPE, ir.OAS2MAPR, ir.OAS2FUNC:
- n := n.(*ir.AssignListStmt)
- o.out = append(o.out, n)
}
}
t := o.markTemp()
o.exprList(n.Lhs)
o.exprList(n.Rhs)
- o.mapAssign(n)
+ o.out = append(o.out, n)
o.cleanTemp(t)
// Special: avoid copy of func call n.Right
o.exprList(n.Lhs)
o.init(n.Rhs[0])
o.call(n.Rhs[0])
- o.as2(n)
+ o.as2func(n)
o.cleanTemp(t)
// Special: use temporary variables to hold result,
base.Fatalf("order.stmt: %v", r.Op())
}
- o.okAs2(n)
+ o.as2ok(n)
o.cleanTemp(t)
// Special: does not save n onto out.
// No return - type-assertions above. Each case must return for itself.
}
-// as2 orders OAS2XXXX nodes. It creates temporaries to ensure left-to-right assignment.
-// The caller should order the right-hand side of the assignment before calling order.as2.
+// as2func orders OAS2FUNC nodes. It creates temporaries to ensure left-to-right assignment.
+// The caller should order the right-hand side of the assignment before calling order.as2func.
// It rewrites,
-// a, b, a = ...
+// a, b, a = ...
// as
// tmp1, tmp2, tmp3 = ...
-// a, b, a = tmp1, tmp2, tmp3
+// a, b, a = tmp1, tmp2, tmp3
// This is necessary to ensure left to right assignment order.
-func (o *orderState) as2(n *ir.AssignListStmt) {
- tmplist := []ir.Node{}
- left := []ir.Node{}
- for ni, l := range n.Lhs {
- if !ir.IsBlank(l) {
- tmp := o.newTemp(l.Type(), l.Type().HasPointers())
- n.Lhs[ni] = tmp
- tmplist = append(tmplist, tmp)
- left = append(left, l)
+func (o *orderState) as2func(n *ir.AssignListStmt) {
+ results := n.Rhs[0].Type()
+ as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
+ for i, nl := range n.Lhs {
+ if !ir.IsBlank(nl) {
+ typ := results.Field(i).Type
+ tmp := o.newTemp(typ, typ.HasPointers())
+ n.Lhs[i] = tmp
+ as.Lhs = append(as.Lhs, nl)
+ as.Rhs = append(as.Rhs, tmp)
}
}
o.out = append(o.out, n)
-
- as := ir.NewAssignListStmt(base.Pos, ir.OAS2, nil, nil)
- as.Lhs = left
- as.Rhs = tmplist
o.stmt(typecheck.Stmt(as))
}
-// okAs2 orders OAS2XXX with ok.
-// Just like as2, this also adds temporaries to ensure left-to-right assignment.
-func (o *orderState) okAs2(n *ir.AssignListStmt) {
- var tmp1, tmp2 ir.Node
- if !ir.IsBlank(n.Lhs[0]) {
- typ := n.Rhs[0].Type()
- tmp1 = o.newTemp(typ, typ.HasPointers())
+// as2ok orders OAS2XXX with ok.
+// Just like as2func, this also adds temporaries to ensure left-to-right assignment.
+func (o *orderState) as2ok(n *ir.AssignListStmt) {
+ as := ir.NewAssignListStmt(n.Pos(), ir.OAS2, nil, nil)
+
+ do := func(i int, typ *types.Type) {
+ if nl := n.Lhs[i]; !ir.IsBlank(nl) {
+ var tmp ir.Node = o.newTemp(typ, typ.HasPointers())
+ n.Lhs[i] = tmp
+ as.Lhs = append(as.Lhs, nl)
+ if i == 1 {
+ // The "ok" result is an untyped boolean according to the Go
+ // spec. We need to explicitly convert it to the LHS type in
+ // case the latter is a defined boolean type (#8475).
+ tmp = typecheck.Conv(tmp, nl.Type())
+ }
+ as.Rhs = append(as.Rhs, tmp)
+ }
}
- if !ir.IsBlank(n.Lhs[1]) {
- tmp2 = o.newTemp(types.Types[types.TBOOL], false)
- }
+ do(0, n.Rhs[0].Type())
+ do(1, types.Types[types.TBOOL])
o.out = append(o.out, n)
-
- if tmp1 != nil {
- r := ir.NewAssignStmt(base.Pos, n.Lhs[0], tmp1)
- o.mapAssign(typecheck.Stmt(r))
- n.Lhs[0] = tmp1
- }
- if tmp2 != nil {
- r := ir.NewAssignStmt(base.Pos, n.Lhs[1], typecheck.Conv(tmp2, n.Lhs[1].Type()))
- o.mapAssign(typecheck.Stmt(r))
- n.Lhs[1] = tmp2
- }
+ o.stmt(typecheck.Stmt(as))
}