diff options
author | Rob Findley <rfindley@google.com> | 2021-02-23 16:29:33 -0500 |
---|---|---|
committer | Robert Findley <rfindley@google.com> | 2021-03-01 21:11:10 +0000 |
commit | a69c45213d7fa18a09e59274e0e18db7766bf5c8 (patch) | |
tree | a34ed583205919ada3bb5837c004120790fdd949 | |
parent | b98ce3b606b2bb620c9c62482cd73f068157a32c (diff) | |
download | go-a69c45213d7fa18a09e59274e0e18db7766bf5c8.tar.gz go-a69c45213d7fa18a09e59274e0e18db7766bf5c8.zip |
go/types: review of expr.go
The changes from the (reviewed) dev.regabi copy of expr.go can be seen
by comparing patchset 2 and 7. The actual change is some small
improvements to readability and consistency in untyped conversion,
adding some missing documentation, and removing the "// REVIEW
INCOMPLETE" marker.
Note that expr.go diverges from types2 in its handling of untyped
conversion.
Change-Id: I13a85f6e08f43343e249818245aa857b1f4bf29c
Reviewed-on: https://go-review.googlesource.com/c/go/+/295729
Trust: Robert Findley <rfindley@google.com>
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
-rw-r--r-- | src/go/types/expr.go | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/go/types/expr.go b/src/go/types/expr.go index 77807e3b5b..9b51ce94b7 100644 --- a/src/go/types/expr.go +++ b/src/go/types/expr.go @@ -1,4 +1,3 @@ -// REVIEW INCOMPLETE // Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. @@ -100,8 +99,8 @@ func (check *Checker) overflow(x *operand, op token.Token, opPos token.Pos) { // Typed constants must be representable in // their type after each constant operation. - if typ := asBasic(x.typ); typ != nil && isTyped(typ) { - check.representable(x, typ) + if isTyped(x.typ) { + check.representable(x, asBasic(x.typ)) return } @@ -191,10 +190,9 @@ func (check *Checker) unary(x *operand, e *ast.UnaryExpr) { // nothing to do (and don't cause an error below in the overflow check) return } - typ := asBasic(x.typ) var prec uint - if isUnsigned(typ) { - prec = uint(check.conf.sizeof(typ) * 8) + if isUnsigned(x.typ) { + prec = uint(check.conf.sizeof(x.typ) * 8) } x.val = constant.UnaryOp(e.Op, x.val, prec) x.expr = e @@ -400,14 +398,20 @@ func representableConst(x constant.Value, check *Checker, typ *Basic, rounded *c // representable checks that a constant operand is representable in the given // basic type. func (check *Checker) representable(x *operand, typ *Basic) { - if v, code := check.representation(x, typ); code != 0 { + v, code := check.representation(x, typ) + if code != 0 { check.invalidConversion(code, x, typ) x.mode = invalid - } else if v != nil { - x.val = v + return } + assert(v != nil) + x.val = v } +// representation returns the representation of the constant operand x as the +// basic type typ. +// +// If no such representation is possible, it returns a non-zero error code. func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) { assert(x.mode == constant_) v := x.val @@ -593,7 +597,10 @@ func (check *Checker) convertUntyped(x *operand, target Type) { // implicitTypeAndValue returns the implicit type of x when used in a context // where the target type is expected. If no such implicit conversion is -// possible, it returns a nil Type. +// possible, it returns a nil Type and non-zero error code. +// +// If x is a constant operand, the returned constant.Value will be the +// representation of x in this context. func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) { target = expand(target) if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] { @@ -994,9 +1001,8 @@ func (check *Checker) binary(x *operand, e ast.Expr, lhs, rhs ast.Expr, op token // x.typ is unchanged return } - typ := asBasic(x.typ) // force integer division of integer operands - if op == token.QUO && isInteger(typ) { + if op == token.QUO && isInteger(x.typ) { op = token.QUO_ASSIGN } x.val = constant.BinaryOp(x.val, op, y.val) |