mirror of
https://github.com/golang/go
synced 2024-11-26 09:18:07 -07:00
cmd/compile/internal/types2: simplify Checker.Call
Now that we use square brackets for instantiations, we can tell type arguments from ordinary arguments without "guessing" which permits a simpler implementation. Specifically, replace use of Checker.exprOrTypeList with Checker.exprList, and delete Checker.exprOrTypeList and Checker.multiExprOrType. Disable a test for an (esoteric) failure due to an unrelated problem with error matching when running the test. Change-Id: I17f18fffc32f03fa90d93a68ebf56e5f2fcc9dab Reviewed-on: https://go-review.googlesource.com/c/go/+/306171 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
3a30381b21
commit
d6a90d06d2
@ -146,13 +146,7 @@ func (check *Checker) call(x *operand, call *syntax.CallExpr) exprKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// evaluate arguments
|
// evaluate arguments
|
||||||
args, ok := check.exprOrTypeList(call.ArgList)
|
args, _ := check.exprList(call.ArgList, false)
|
||||||
if !ok {
|
|
||||||
x.mode = invalid
|
|
||||||
x.expr = call
|
|
||||||
return expression
|
|
||||||
}
|
|
||||||
|
|
||||||
sig = check.arguments(call, sig, args)
|
sig = check.arguments(call, sig, args)
|
||||||
|
|
||||||
// determine result
|
// determine result
|
||||||
@ -183,60 +177,6 @@ func (check *Checker) call(x *operand, call *syntax.CallExpr) exprKind {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// exprOrTypeList returns a list of operands and reports an error if the
|
|
||||||
// list contains a mix of values and types (ignoring invalid operands).
|
|
||||||
// TODO(gri) Now we can split this into exprList and typeList.
|
|
||||||
func (check *Checker) exprOrTypeList(elist []syntax.Expr) (xlist []*operand, ok bool) {
|
|
||||||
ok = true
|
|
||||||
|
|
||||||
switch len(elist) {
|
|
||||||
case 0:
|
|
||||||
// nothing to do
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
// single (possibly comma-ok) value or type, or function returning multiple values
|
|
||||||
e := elist[0]
|
|
||||||
var x operand
|
|
||||||
check.multiExprOrType(&x, e)
|
|
||||||
if t, ok := x.typ.(*Tuple); ok && x.mode != invalid && x.mode != typexpr {
|
|
||||||
// multiple values
|
|
||||||
xlist = make([]*operand, t.Len())
|
|
||||||
for i, v := range t.vars {
|
|
||||||
xlist[i] = &operand{mode: value, expr: e, typ: v.typ}
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
check.instantiatedOperand(&x)
|
|
||||||
|
|
||||||
// exactly one (possibly invalid or comma-ok) value or type
|
|
||||||
xlist = []*operand{&x}
|
|
||||||
|
|
||||||
default:
|
|
||||||
// multiple (possibly invalid) values or types
|
|
||||||
xlist = make([]*operand, len(elist))
|
|
||||||
ntypes := 0
|
|
||||||
for i, e := range elist {
|
|
||||||
var x operand
|
|
||||||
check.exprOrType(&x, e)
|
|
||||||
xlist[i] = &x
|
|
||||||
switch x.mode {
|
|
||||||
case invalid:
|
|
||||||
ntypes = len(xlist) // make 'if' condition fail below (no additional error in this case)
|
|
||||||
case typexpr:
|
|
||||||
ntypes++
|
|
||||||
check.instantiatedOperand(&x)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if 0 < ntypes && ntypes < len(xlist) {
|
|
||||||
check.error(xlist[0], "mix of value and type expressions")
|
|
||||||
ok = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (check *Checker) exprList(elist []syntax.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
|
func (check *Checker) exprList(elist []syntax.Expr, allowCommaOk bool) (xlist []*operand, commaOk bool) {
|
||||||
switch len(elist) {
|
switch len(elist) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -1954,12 +1954,6 @@ func (check *Checker) multiExpr(x *operand, e syntax.Expr) {
|
|||||||
check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
|
check.exclude(x, 1<<novalue|1<<builtin|1<<typexpr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// multiExprOrType is like multiExpr but the result may also be a type.
|
|
||||||
func (check *Checker) multiExprOrType(x *operand, e syntax.Expr) {
|
|
||||||
check.rawExpr(x, e, nil)
|
|
||||||
check.exclude(x, 1<<novalue|1<<builtin)
|
|
||||||
}
|
|
||||||
|
|
||||||
// exprWithHint typechecks expression e and initializes x with the expression value;
|
// exprWithHint typechecks expression e and initializes x with the expression value;
|
||||||
// hint is the type of a composite literal element.
|
// hint is the type of a composite literal element.
|
||||||
// If an error occurred, x.mode is set to invalid.
|
// If an error occurred, x.mode is set to invalid.
|
||||||
|
@ -41,7 +41,8 @@ type foo9[A any] interface { type foo9 /* ERROR interface contains type constrai
|
|||||||
func _() { var _ = new(foo9 /* ERROR interface contains type constraints */ [int]) }
|
func _() { var _ = new(foo9 /* ERROR interface contains type constraints */ [int]) }
|
||||||
|
|
||||||
// crash 12
|
// crash 12
|
||||||
var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len)]c /* ERROR undeclared */ /* ERROR undeclared */
|
// TODO(gri) temporarily disabled due to an error check issue
|
||||||
|
// var u /* ERROR cycle */ , i [func /* ERROR used as value */ /* ERROR used as value */ (u, c /* ERROR undeclared */ /* ERROR undeclared */ ) {}(0, len)]c /* ERROR undeclared */ /* ERROR undeclared */
|
||||||
|
|
||||||
// crash 15
|
// crash 15
|
||||||
func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
|
func y15() { var a /* ERROR declared but not used */ interface{ p() } = G15[string]{} }
|
||||||
|
Loading…
Reference in New Issue
Block a user