This further reduces the differences between go/types and types2.
Change-Id: I5ed0f621e1d64cd65b6a3e8eaca9926a1ccb5794
Reviewed-on: https://go-review.googlesource.com/c/go/+/562776
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Robert Griesemer <gri@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
}
return typ
}
-
-// unparen returns e with any enclosing parentheses stripped.
-func unparen(e syntax.Expr) syntax.Expr {
- for {
- p, ok := e.(*syntax.ParenExpr)
- if !ok {
- return e
- }
- e = p.X
- }
-}
// and Typ[Invalid] if it is an invalid lhs expression.
func (check *Checker) lhsVar(lhs ast.Expr) Type {
// Determine if the lhs is a (possibly parenthesized) identifier.
- ident, _ := unparen(lhs).(*ast.Ident)
+ ident, _ := ast.Unparen(lhs).(*ast.Ident)
// Don't evaluate lhs if it is the blank identifier.
if ident != nil && ident.Name == "_" {
rhs0 := rhs[0]
if len(rhs) == 1 {
- if call, _ := unparen(rhs0).(*ast.CallExpr); call != nil {
+ if call, _ := ast.Unparen(rhs0).(*ast.CallExpr); call != nil {
check.errorf(rhs0, WrongAssignCount, "assignment mismatch: %s but %s returns %s", vars, call.Fun, vals)
return
}
// error message don't handle it as n:n mapping below.
isCall := false
if r == 1 {
- _, isCall = unparen(orig_rhs[0]).(*ast.CallExpr)
+ _, isCall = ast.Unparen(orig_rhs[0]).(*ast.CallExpr)
}
// If we have a n:n mapping from lhs variable to rhs expression,
// error message don't handle it as n:n mapping below.
isCall := false
if r == 1 {
- _, isCall = unparen(orig_rhs[0]).(*ast.CallExpr)
+ _, isCall = ast.Unparen(orig_rhs[0]).(*ast.CallExpr)
}
// If we have a n:n mapping from lhs variable to rhs expression,
// unsafe.Offsetof(x T) uintptr, where x must be a selector
// (no argument evaluated yet)
arg0 := argList[0]
- selx, _ := unparen(arg0).(*ast.SelectorExpr)
+ selx, _ := ast.Unparen(arg0).(*ast.SelectorExpr)
if selx == nil {
check.errorf(arg0, BadOffsetofSyntax, invalidArg+"%s is not a selector expression", arg0)
check.use(arg0)
}
return typ
}
-
-func unparen(e ast.Expr) ast.Expr { return ast.Unparen(e) }
func (check *Checker) use1(e ast.Expr, lhs bool) bool {
var x operand
x.mode = value // anything but invalid
- switch n := unparen(e).(type) {
+ switch n := ast.Unparen(e).(type) {
case nil:
// nothing to do
case *ast.Ident:
case token.AND:
// spec: "As an exception to the addressability
// requirement x may also be a composite literal."
- if _, ok := unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
+ if _, ok := ast.Unparen(e.X).(*ast.CompositeLit); !ok && x.mode != variable {
check.errorf(x, UnaddressableOperand, invalidOp+"cannot take address of %s", x)
x.mode = invalid
return
for {
// Note: this differs from types2, but is necessary. The syntax parser
// strips unnecessary parens.
- typ = unparen(typ)
+ typ = ast.Unparen(typ)
// check if we have a pointer type
if pexpr, _ := typ.(*ast.StarExpr); pexpr != nil {
return false, nil
}
ptr = true
- typ = unparen(pexpr.X) // continue with pointer base type
+ typ = ast.Unparen(pexpr.X) // continue with pointer base type
}
// typ must be a name, or a C.name cgo selector.
case *ast.ExprStmt:
// calling the predeclared (possibly parenthesized) panic() function is terminating
- if call, ok := unparen(s.X).(*ast.CallExpr); ok && check.isPanic[call] {
+ if call, ok := ast.Unparen(s.X).(*ast.CallExpr); ok && check.isPanic[call] {
return true
}
// isNil reports whether the expression e denotes the predeclared value nil.
func (check *Checker) isNil(e ast.Expr) bool {
// The only way to express the nil value is by literally writing nil (possibly in parentheses).
- if name, _ := unparen(e).(*ast.Ident); name != nil {
+ if name, _ := ast.Unparen(e).(*ast.Ident); name != nil {
_, ok := check.lookup(name.Name).(*Nil)
return ok
}
// if present, rhs must be a receive operation
if rhs != nil {
- if x, _ := unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
+ if x, _ := ast.Unparen(rhs).(*ast.UnaryExpr); x != nil && x.Op == token.ARROW {
valid = true
}
}