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

go.tools/go/types: fix interface vs interface type assertion

R=adonovan
CC=golang-dev
https://golang.org/cl/12378043
This commit is contained in:
Robert Griesemer 2013-08-02 14:37:19 -07:00
parent e06b897351
commit 3209d6ad73
4 changed files with 36 additions and 11 deletions

View File

@ -225,22 +225,18 @@ func consolidateMultiples(list []embeddedType) []embeddedType {
// is missing or simply has the wrong type.
//
func MissingMethod(typ Type, T *Interface) (method *Func, wrongType bool) {
// an interface type implements T if it has no methods with conflicting signatures
// Note: This is stronger than the current spec. Should the spec require this?
// fast path for common case
if T.NumMethods() == 0 {
return
}
// An interface type implements T if it has at least the methods of T.
// The dynamic type of a value stored in an interface may implement T,
// but only if all the shared interface methods have matching signatures.
// Note: This is stronger than the current spec. Should the spec require this?
if ityp, _ := typ.Underlying().(*Interface); ityp != nil {
for _, m := range T.methods {
_, obj := lookupMethod(ityp.methods, m.pkg, m.name)
if obj == nil {
return m, false
}
if !IsIdentical(obj.Type(), m.typ) {
if obj != nil && !IsIdentical(obj.Type(), m.typ) {
return m, true
}
}

View File

@ -108,6 +108,7 @@ func TestStdfixed(t *testing.T) {
"bug050.go", "bug088.go", "bug106.go", // TODO(gri) parser loses comments when bailing out early
"bug222.go", "bug282.go", "bug306.go", // TODO(gri) parser loses comments when bailing out early
"bug136.go", "bug179.go", "bug344.go", // TODO(gri) implement missing label checks
"bug251.go", // TODO(gri) incorrect cycle checks for interface types
"bug165.go", // TODO(gri) isComparable not working for incomplete struct type
"bug176.go", // TODO(gri) composite literal array index must be non-negative constant
"bug200.go", // TODO(gri) complete duplicate checking in expr switches

View File

@ -44,12 +44,19 @@ func interface_conversions() {
type I2 interface{
m1()
m2()
m2(x int)
}
type I3 interface{
m1()
m2() int
}
var e E
var i1 I1
var i2 I2
var i3 I3
_ = E(0)
_ = E(nil)
_ = E(e)
@ -59,10 +66,18 @@ func interface_conversions() {
_ = I1 /* ERROR "cannot convert" */ (0)
_ = I1(nil)
_ = I1(i1)
_ = I1 /* ERROR "cannot convert" */ (e)
_ = I1(e)
_ = I1(i2)
_ = I2 /* ERROR "cannot convert" */ (i1)
_ = I2(nil)
_ = I2(i1)
_ = I2(i2)
_ = I2 /* ERROR "cannot convert" */ (i3)
_ = I3(nil)
_ = I3(i1)
_ = I3 /* ERROR "cannot convert" */ (i2)
_ = I3(i3)
// TODO(gri) add more tests, improve error message
}

View File

@ -298,6 +298,19 @@ func typeswitch1() {
}
}
// Test correct typeswitch against interface types.
type A interface { a() }
type B interface { b() }
type C interface { a(int) }
func typeswitch2() {
switch A(nil).(type) {
case A:
case B:
case C /* ERROR "cannot have dynamic type" */:
}
}
func rangeloops() {
var (
x int