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:
parent
2b15aa63b7
commit
a4d1505cfc
|
@ -79,18 +79,6 @@ type Importer func(map[string]*Package, string) (*Package, error)
|
||||||
// A Config specifies the configuration for type checking.
|
// A Config specifies the configuration for type checking.
|
||||||
// The zero value for Config is a ready-to-use default configuration.
|
// The zero value for Config is a ready-to-use default configuration.
|
||||||
type Config struct {
|
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
|
// If IgnoreFuncBodies is set, function bodies are not
|
||||||
// type-checked.
|
// type-checked.
|
||||||
IgnoreFuncBodies bool
|
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.
|
// AssertableTo reports whether a value of type V can be asserted to have type T.
|
||||||
func AssertableTo(V *Interface, T Type) bool {
|
func AssertableTo(V *Interface, T Type) bool {
|
||||||
f, _ := MissingMethod(T, V, false)
|
m, _ := assertableTo(V, T)
|
||||||
return f == nil
|
return m == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AssignableTo reports whether a value of type V is assignable to a variable of type T.
|
// AssignableTo reports whether a value of type V is assignable to a variable of type T.
|
||||||
|
|
|
@ -20,6 +20,19 @@ const (
|
||||||
trace = false // turn on for detailed type resolution traces
|
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.
|
// exprInfo stores information about an untyped expression.
|
||||||
type exprInfo struct {
|
type exprInfo struct {
|
||||||
isLhs bool // expression is lhs operand of a shift with delayed type-check
|
isLhs bool // expression is lhs operand of a shift with delayed type-check
|
||||||
|
|
|
@ -1406,14 +1406,7 @@ Error:
|
||||||
|
|
||||||
// typeAssertion checks that x.(T) is legal; xtyp must be the type of x.
|
// 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) {
|
func (check *Checker) typeAssertion(pos token.Pos, x *operand, xtyp *Interface, T Type) {
|
||||||
// no static check is required if T is an interface
|
method, wrongType := assertableTo(xtyp, T)
|
||||||
// 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)
|
|
||||||
if method == nil {
|
if method == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,6 +293,19 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
|
||||||
return
|
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.
|
// deref dereferences typ if it is a *Pointer and returns its base and true.
|
||||||
// Otherwise it returns (typ, false).
|
// Otherwise it returns (typ, false).
|
||||||
func deref(typ Type) (Type, bool) {
|
func deref(typ Type) (Type, bool) {
|
||||||
|
|
Loading…
Reference in New Issue