mirror of https://github.com/golang/go.git
go/types, types2: adjust Checker.recordCommaOkTypes signature
By changing the signature to accept a slice rather than an array, we can avoid creating the array in the first place. Functionally, we now also record comma-ok types if the corresponding assignment was incorrect. But this change provides more (not less) information through the API and only so if the program is incorrect in the first place. Change-Id: I0d629441f2f890a37912171fb26ef0e75827ce23 Reviewed-on: https://go-review.googlesource.com/c/go/+/478218 Auto-Submit: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
0ed364a463
commit
bd7b19356f
|
|
@ -373,11 +373,9 @@ func (check *Checker) initVars(lhs []*Var, orig_rhs []syntax.Expr, returnStmt sy
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -412,11 +410,9 @@ func (check *Checker) assignVars(lhs, orig_rhs []syntax.Expr) {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -504,22 +504,27 @@ func (check *Checker) recordBuiltinType(f syntax.Expr, sig *Signature) {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
@ -535,8 +540,8 @@ func (check *Checker) recordCommaOkTypes(x syntax.Expr, a [2]Type) {
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -365,11 +365,9 @@ func (check *Checker) initVars(lhs []*Var, origRHS []ast.Expr, returnStmt ast.St
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -394,11 +392,9 @@ func (check *Checker) assignVars(lhs, origRHS []ast.Expr) {
|
|||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -478,20 +478,24 @@ func (check *Checker) recordBuiltinType(f ast.Expr, sig *Signature) {
|
|||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in New Issue