}
if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.initVar(lhs[i], rhs[i], context)
- }
- check.recordCommaOkTypes(orig_rhs[0], a)
+ check.initVar(lhs[0], rhs[0], context)
+ check.initVar(lhs[1], rhs[1], context)
+ check.recordCommaOkTypes(orig_rhs[0], rhs)
return
}
}
if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.assignVar(lhs[i], rhs[i])
- }
- check.recordCommaOkTypes(orig_rhs[0], a)
+ check.assignVar(lhs[0], rhs[0])
+ check.assignVar(lhs[1], rhs[1])
+ check.recordCommaOkTypes(orig_rhs[0], rhs)
return
}
}
}
-func (check *Checker) recordCommaOkTypes(x syntax.Expr, a [2]Type) {
+// recordCommaOkTypes updates recorded types to reflect that x is used in a commaOk context
+// (and therefore has tuple type).
+func (check *Checker) recordCommaOkTypes(x syntax.Expr, a []*operand) {
assert(x != nil)
- if a[0] == nil || a[1] == nil {
+ assert(len(a) == 2)
+ if a[0].mode == invalid {
return
}
- assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError))
+ t0, t1 := a[0].typ, a[1].typ
+ assert(isTyped(t0) && isTyped(t1) && (isBoolean(t1) || t1 == universeError))
if m := check.Types; m != nil {
for {
tv := m[x]
assert(tv.Type != nil) // should have been recorded already
pos := x.Pos()
tv.Type = NewTuple(
- NewVar(pos, check.pkg, "", a[0]),
- NewVar(pos, check.pkg, "", a[1]),
+ NewVar(pos, check.pkg, "", t0),
+ NewVar(pos, check.pkg, "", t1),
)
m[x] = tv
+ // if x is a parenthesized expression (p.X), update p.X
p, _ := x.(*syntax.ParenExpr)
if p == nil {
break
assert(tv.Type != nil) // should have been recorded already
pos := x.Pos()
tv.Type = NewTuple(
- NewVar(pos, check.pkg, "", a[0]),
- NewVar(pos, check.pkg, "", a[1]),
+ NewVar(pos, check.pkg, "", t0),
+ NewVar(pos, check.pkg, "", t1),
)
x.SetTypeInfo(tv)
p, _ := x.(*syntax.ParenExpr)
}
if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.initVar(lhs[i], rhs[i], context)
- }
- check.recordCommaOkTypes(origRHS[0], a)
+ check.initVar(lhs[0], rhs[0], context)
+ check.initVar(lhs[1], rhs[1], context)
+ check.recordCommaOkTypes(origRHS[0], rhs)
return
}
}
if commaOk {
- var a [2]Type
- for i := range a {
- a[i] = check.assignVar(lhs[i], rhs[i])
- }
- check.recordCommaOkTypes(origRHS[0], a)
+ check.assignVar(lhs[0], rhs[0])
+ check.assignVar(lhs[1], rhs[1])
+ check.recordCommaOkTypes(origRHS[0], rhs)
return
}
}
}
-func (check *Checker) recordCommaOkTypes(x ast.Expr, a [2]Type) {
+// recordCommaOkTypes updates recorded types to reflect that x is used in a commaOk context
+// (and therefore has tuple type).
+func (check *Checker) recordCommaOkTypes(x ast.Expr, a []*operand) {
assert(x != nil)
- if a[0] == nil || a[1] == nil {
+ assert(len(a) == 2)
+ if a[0].mode == invalid {
return
}
- assert(isTyped(a[0]) && isTyped(a[1]) && (isBoolean(a[1]) || a[1] == universeError))
+ t0, t1 := a[0].typ, a[1].typ
+ assert(isTyped(t0) && isTyped(t1) && (isBoolean(t1) || t1 == universeError))
if m := check.Types; m != nil {
for {
tv := m[x]
assert(tv.Type != nil) // should have been recorded already
pos := x.Pos()
tv.Type = NewTuple(
- NewVar(pos, check.pkg, "", a[0]),
- NewVar(pos, check.pkg, "", a[1]),
+ NewVar(pos, check.pkg, "", t0),
+ NewVar(pos, check.pkg, "", t1),
)
m[x] = tv
// if x is a parenthesized expression (p.X), update p.X