| // +build ignore |
| |
| package main |
| |
| // Test of interface calls. |
| |
| func use(interface{}) |
| |
| type A byte // instantiated but not a reflect type |
| |
| func (A) f() {} // called directly |
| func (A) F() {} // unreachable |
| |
| type B int // a reflect type |
| |
| func (*B) f() {} // reachable via interface invoke |
| func (*B) F() {} // reachable: exported method of reflect type |
| |
| type B2 int // a reflect type, and *B2 also |
| |
| func (B2) f() {} // reachable via interface invoke |
| func (B2) g() {} // reachable: exported method of reflect type |
| |
| type C string // not instantiated |
| |
| func (C) f() {} // unreachable |
| func (C) F() {} // unreachable |
| |
| type D uint // instantiated only in dead code |
| |
| func (D) f() {} // unreachable |
| func (D) F() {} // unreachable |
| |
| func main() { |
| A(0).f() |
| |
| use(new(B)) |
| use(B2(0)) |
| |
| var i interface { |
| f() |
| } |
| i.f() // calls (*B).f, (*B2).f and (B2.f) |
| |
| live() |
| } |
| |
| func live() { |
| var j interface { |
| f() |
| g() |
| } |
| j.f() // calls (B2).f and (*B2).f but not (*B).f (no g method). |
| } |
| |
| func dead() { |
| use(D(0)) |
| } |
| |
| // WANT: |
| // Dynamic calls |
| // live --> (*B2).f |
| // live --> (B2).f |
| // main --> (*B).f |
| // main --> (*B2).f |
| // main --> (B2).f |
| // Reachable functions |
| // (*B).F |
| // (*B).f |
| // (*B2).f |
| // (A).f |
| // (B2).f |
| // live |
| // use |
| // Reflect types |
| // *B |
| // *B2 |
| // B |
| // B2 |