1
0
mirror of https://github.com/golang/go synced 2024-11-18 16:04:44 -07:00

go.tools/go/types: remove Strict mode from API

Also: factor out shared code assertableTo.

LGTM=adonovan
R=adonovan, gordon.klaus
CC=golang-codereviews
https://golang.org/cl/139880043
This commit is contained in:
Robert Griesemer 2014-08-29 09:15:36 -07:00
parent 2b15aa63b7
commit a4d1505cfc
4 changed files with 29 additions and 22 deletions

View File

@ -79,18 +79,6 @@ type Importer func(map[string]*Package, string) (*Package, error)
// A Config specifies the configuration for type checking.
// The zero value for Config is a ready-to-use default configuration.
type Config struct {
// If Strict is set, the type-checker enforces additional
// rules not specified by the Go 1 spec, but which will
// catch guaranteed run-time errors if the respective
// code is executed. In other words, programs passing in
// Strict mode are Go 1 compliant, but not all Go 1 programs
// will pass in Strict mode. The additional rules are:
//
// - A type assertion x.(T) where T is an interface type
// is invalid if any (statically known) method that exists
// for both x and T have different signatures.
Strict bool
// If IgnoreFuncBodies is set, function bodies are not
// type-checked.
IgnoreFuncBodies bool
@ -345,8 +333,8 @@ func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, i
// AssertableTo reports whether a value of type V can be asserted to have type T.
func AssertableTo(V *Interface, T Type) bool {
f, _ := MissingMethod(T, V, false)
return f == nil
m, _ := assertableTo(V, T)
return m == nil
}
// AssignableTo reports whether a value of type V is assignable to a variable of type T.

View File

@ -20,6 +20,19 @@ const (
trace = false // turn on for detailed type resolution traces
)
// If Strict is set, the type-checker enforces additional
// rules not specified by the Go 1 spec, but which will
// catch guaranteed run-time errors if the respective
// code is executed. In other words, programs passing in
// Strict mode are Go 1 compliant, but not all Go 1 programs
// will pass in Strict mode. The additional rules are:
//
// - A type assertion x.(T) where T is an interface type
// is invalid if any (statically known) method that exists
// for both x and T have different signatures.
//
const strict = false
// exprInfo stores information about an untyped expression.
type exprInfo struct {
isLhs bool // expression is lhs operand of a shift with delayed type-check

View File

@ -1406,14 +1406,7 @@ Error:
// typeAssertion checks that x.(T) is legal; xtyp must be the type of x.
func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) {
// no static check is required if T is an interface
// spec: "If T is an interface type, x.(T) asserts that the
// dynamic type of x implements the interface T."
if _, ok := T.Underlying().(*Interface); ok && !check.conf.Strict {
return
}
method, wrongType := MissingMethod(T, xtyp, false)
method, wrongType := assertableTo(xtyp, T)
if method == nil {
return
}

View File

@ -293,6 +293,19 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
return
}
// assertableTo reports whether a value of type V can be asserted to have type T.
// It returns (nil, false) as affirmative answer. Otherwise it returns a missing
// method required by V and whether it is missing or just has the wrong type.
func assertableTo(V *Interface, T Type) (method *Func, wrongType bool) {
// no static check is required if T is an interface
// spec: "If T is an interface type, x.(T) asserts that the
// dynamic type of x implements the interface T."
if _, ok := T.Underlying().(*Interface); ok && !strict {
return
}
return MissingMethod(T, V, false)
}
// deref dereferences typ if it is a *Pointer and returns its base and true.
// Otherwise it returns (typ, false).
func deref(typ Type) (Type, bool) {