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

go.tools/go/types: no errors for x.(T) where T is an interface

Also: Added Config.Strict flag to enable type checker tests
      beyond the Go 1 specification.

Fixes golang/go#8561.

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/134050043
This commit is contained in:
Robert Griesemer 2014-08-28 14:03:10 -07:00
parent cd5b7ff318
commit 289e96cc26
5 changed files with 26 additions and 3 deletions

View File

@ -79,6 +79,18 @@ 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

View File

@ -20,6 +20,9 @@
// _ = x /* ERROR "not declared" */ + 1
// }
// TODO(gri) Also collect strict mode errors of the form /* STRICT ... */
// and test against strict mode.
package types_test
import (

View File

@ -1406,10 +1406,18 @@ 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)
if method == nil {
return
}
var msg string
if wrongType {
msg = "wrong type for method"

View File

@ -381,7 +381,7 @@ func type_asserts() {
_ = t.(*T)
_ = t /* ERROR "missing method m" */ .(T1)
_ = t /* ERROR "wrong type for method m" */ .(T2)
_ = t /* ERROR "wrong type for method m" */ .(I2)
_ = t /* STRICT "wrong type for method m" */ .(I2) // only an error in strict mode (issue 8561)
// e doesn't statically have an m, but may have one dynamically.
_ = e.(I2)

View File

@ -558,7 +558,7 @@ func typeswitches() {
case T:
case T1 /* ERROR "missing method m" */ :
case T2 /* ERROR "wrong type for method m" */ :
case I2 /* ERROR "wrong type for method m" */ :
case I2 /* STRICT "wrong type for method m" */ : // only an error in strict mode (issue 8561)
}
}
@ -596,7 +596,7 @@ func typeswitch2() {
switch A(nil).(type) {
case A:
case B:
case C /* ERROR "cannot have dynamic type" */:
case C /* STRICT "cannot have dynamic type" */: // only an error in strict mode (issue 8561)
}
}