[dev.typeparams] cmd/compile/internal/types2: resolve decl cycle the same way as in go/types

Minor adjustment to match go/types more closely.

Change-Id: Id79c51f0ecd8cda0f5b68f6e961500f7f22f7115
Reviewed-on: https://go-review.googlesource.com/c/go/+/294270
Reviewed-by: Robert Findley <rfindley@google.com>
Trust: Robert Griesemer <gri@golang.org>
This commit is contained in:
Robert Griesemer 2021-02-19 09:39:01 -08:00
parent dfe0ef961b
commit 6521c7b378
2 changed files with 28 additions and 27 deletions

View file

@ -59,11 +59,16 @@ the type (and constant value, if any) is recorded via Info.Types, if present.
type opPredicates map[syntax.Operator]func(Type) bool type opPredicates map[syntax.Operator]func(Type) bool
var unaryOpPredicates = opPredicates{ var unaryOpPredicates opPredicates
syntax.Add: isNumeric,
syntax.Sub: isNumeric, func init() {
syntax.Xor: isInteger, // Setting unaryOpPredicates in init avoids declaration cycles.
syntax.Not: isBoolean, unaryOpPredicates = opPredicates{
syntax.Add: isNumeric,
syntax.Sub: isNumeric,
syntax.Xor: isInteger,
syntax.Not: isBoolean,
}
} }
func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool { func (check *Checker) op(m opPredicates, x *operand, op syntax.Operator) bool {
@ -896,20 +901,25 @@ func (check *Checker) shift(x, y *operand, e syntax.Expr, op syntax.Operator) {
x.mode = value x.mode = value
} }
var binaryOpPredicates = opPredicates{ var binaryOpPredicates opPredicates
syntax.Add: isNumericOrString,
syntax.Sub: isNumeric,
syntax.Mul: isNumeric,
syntax.Div: isNumeric,
syntax.Rem: isInteger,
syntax.And: isInteger, func init() {
syntax.Or: isInteger, // Setting binaryOpPredicates in init avoids declaration cycles.
syntax.Xor: isInteger, binaryOpPredicates = opPredicates{
syntax.AndNot: isInteger, syntax.Add: isNumericOrString,
syntax.Sub: isNumeric,
syntax.Mul: isNumeric,
syntax.Div: isNumeric,
syntax.Rem: isInteger,
syntax.AndAnd: isBoolean, syntax.And: isInteger,
syntax.OrOr: isBoolean, syntax.Or: isInteger,
syntax.Xor: isInteger,
syntax.AndNot: isInteger,
syntax.AndAnd: isBoolean,
syntax.OrOr: isBoolean,
}
} }
// If e != nil, it must be the binary expression; it may be nil for non-constant expressions // If e != nil, it must be the binary expression; it may be nil for non-constant expressions

View file

@ -881,16 +881,7 @@ func (t *top) String() string { return TypeString(t, nil) }
// If it doesn't exist, the result is Typ[Invalid]. // If it doesn't exist, the result is Typ[Invalid].
// under must only be called when a type is known // under must only be called when a type is known
// to be fully set up. // to be fully set up.
// func under(t Type) Type {
// under is set to underf to avoid an initialization cycle.
// TODO(gri) this doesn't happen in go/types - investigate
var under func(Type) Type
func init() {
under = underf
}
func underf(t Type) Type {
// TODO(gri) is this correct for *Sum? // TODO(gri) is this correct for *Sum?
if n := asNamed(t); n != nil { if n := asNamed(t); n != nil {
return n.under() return n.under()