mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
b98ce3b606
commit
a69c45213d
1 changed files with 18 additions and 12 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
// REVIEW INCOMPLETE
|
|
||||||
// Copyright 2012 The Go Authors. All rights reserved.
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// 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
|
// Typed constants must be representable in
|
||||||
// their type after each constant operation.
|
// their type after each constant operation.
|
||||||
if typ := asBasic(x.typ); typ != nil && isTyped(typ) {
|
if isTyped(x.typ) {
|
||||||
check.representable(x, typ)
|
check.representable(x, asBasic(x.typ))
|
||||||
return
|
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)
|
// nothing to do (and don't cause an error below in the overflow check)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
typ := asBasic(x.typ)
|
|
||||||
var prec uint
|
var prec uint
|
||||||
if isUnsigned(typ) {
|
if isUnsigned(x.typ) {
|
||||||
prec = uint(check.conf.sizeof(typ) * 8)
|
prec = uint(check.conf.sizeof(x.typ) * 8)
|
||||||
}
|
}
|
||||||
x.val = constant.UnaryOp(e.Op, x.val, prec)
|
x.val = constant.UnaryOp(e.Op, x.val, prec)
|
||||||
x.expr = e
|
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
|
// representable checks that a constant operand is representable in the given
|
||||||
// basic type.
|
// basic type.
|
||||||
func (check *Checker) representable(x *operand, typ *Basic) {
|
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)
|
check.invalidConversion(code, x, typ)
|
||||||
x.mode = invalid
|
x.mode = invalid
|
||||||
} else if v != nil {
|
return
|
||||||
|
}
|
||||||
|
assert(v != nil)
|
||||||
x.val = v
|
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) {
|
func (check *Checker) representation(x *operand, typ *Basic) (constant.Value, errorCode) {
|
||||||
assert(x.mode == constant_)
|
assert(x.mode == constant_)
|
||||||
v := x.val
|
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
|
// implicitTypeAndValue returns the implicit type of x when used in a context
|
||||||
// where the target type is expected. If no such implicit conversion is
|
// 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) {
|
func (check *Checker) implicitTypeAndValue(x *operand, target Type) (Type, constant.Value, errorCode) {
|
||||||
target = expand(target)
|
target = expand(target)
|
||||||
if x.mode == invalid || isTyped(x.typ) || target == Typ[Invalid] {
|
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
|
// x.typ is unchanged
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
typ := asBasic(x.typ)
|
|
||||||
// force integer division of integer operands
|
// force integer division of integer operands
|
||||||
if op == token.QUO && isInteger(typ) {
|
if op == token.QUO && isInteger(x.typ) {
|
||||||
op = token.QUO_ASSIGN
|
op = token.QUO_ASSIGN
|
||||||
}
|
}
|
||||||
x.val = constant.BinaryOp(x.val, op, y.val)
|
x.val = constant.BinaryOp(x.val, op, y.val)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue