go.tools/go/types: export IsAssignableTo
Tested implictly since its simply calling the internal isAssignableTo which is used in every assignment when testing the std library. R=adonovan CC=golang-dev https://golang.org/cl/11189043
This commit is contained in:
parent
424b1fda00
commit
5ec27f6da9
|
|
@ -35,7 +35,7 @@ package types
|
|||
//
|
||||
// BUG(gri): Conversions of constants only change the type, not the value (e.g., int(1.1) is wrong).
|
||||
// BUG(gri): Some built-ins don't check parameters fully, yet (e.g. append).
|
||||
// BUG(gri): Use of labels is not checked.
|
||||
// BUG(gri): Use of labels is only partially checked.
|
||||
// BUG(gri): Unused variables and imports are not reported.
|
||||
// BUG(gri): Interface vs non-interface comparisons are not correctly implemented.
|
||||
// BUG(gri): Switch statements don't check correct use of 'fallthrough'.
|
||||
|
|
@ -150,3 +150,10 @@ func Check(path string, fset *token.FileSet, files ...*ast.File) (*Package, erro
|
|||
var ctxt Context
|
||||
return ctxt.Check(path, fset, files...)
|
||||
}
|
||||
|
||||
// IsAssignableTo reports whether a value of type V
|
||||
// is assignable to a variable of type T.
|
||||
func IsAssignableTo(V, T Type) bool {
|
||||
x := operand{mode: value, typ: V}
|
||||
return x.isAssignableTo(nil, T) // context not needed for non-constant x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (check *checker) assignment(x *operand, to Type) bool {
|
|||
|
||||
check.convertUntyped(x, to)
|
||||
|
||||
return x.mode != invalid && x.isAssignable(check.ctxt, to)
|
||||
return x.mode != invalid && x.isAssignableTo(check.ctxt, to)
|
||||
}
|
||||
|
||||
func (check *checker) initConst(lhs *Const, x *operand) {
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, bin *Builtin) {
|
|||
if x.mode == invalid {
|
||||
goto Error
|
||||
}
|
||||
if !x.isAssignable(check.ctxt, m.key) {
|
||||
if !x.isAssignableTo(check.ctxt, m.key) {
|
||||
check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
|
||||
goto Error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ Error:
|
|||
|
||||
func (x *operand) isConvertible(ctxt *Context, T Type) bool {
|
||||
// "x is assignable to T"
|
||||
if x.isAssignable(ctxt, T) {
|
||||
if x.isAssignableTo(ctxt, T) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -471,7 +471,7 @@ func (check *checker) comparison(x, y *operand, op token.Token) {
|
|||
// TODO(gri) deal with interface vs non-interface comparison
|
||||
|
||||
valid := false
|
||||
if x.isAssignable(check.ctxt, y.typ) || y.isAssignable(check.ctxt, x.typ) {
|
||||
if x.isAssignableTo(check.ctxt, y.typ) || y.isAssignableTo(check.ctxt, x.typ) {
|
||||
switch op {
|
||||
case token.EQL, token.NEQ:
|
||||
valid = isComparable(x.typ) ||
|
||||
|
|
|
|||
|
|
@ -122,12 +122,12 @@ func (x *operand) isNil() bool {
|
|||
return x.mode == constant && x.val.Kind() == exact.Nil
|
||||
}
|
||||
|
||||
// TODO(gri) The functions operand.isAssignable, checker.convertUntyped,
|
||||
// TODO(gri) The functions operand.isAssignableTo, checker.convertUntyped,
|
||||
// checker.isRepresentable, and checker.assignOperand are
|
||||
// overlapping in functionality. Need to simplify and clean up.
|
||||
|
||||
// isAssignable reports whether x is assignable to a variable of type T.
|
||||
func (x *operand) isAssignable(ctxt *Context, T Type) bool {
|
||||
// isAssignableTo reports whether x is assignable to a variable of type T.
|
||||
func (x *operand) isAssignableTo(ctxt *Context, T Type) bool {
|
||||
if x.mode == invalid || T == Typ[Invalid] {
|
||||
return true // avoid spurious errors
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue