File tree Expand file tree Collapse file tree 2 files changed +84
-5
lines changed Expand file tree Collapse file tree 2 files changed +84
-5
lines changed Original file line number Diff line number Diff line change
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "time"
6
+ )
7
+
8
+ type TestStruct struct {}
9
+
10
+ func (t TestStruct ) String () string {
11
+ return "hello world"
12
+ }
13
+
14
+ func main () {
15
+ var t interface {}
16
+ t = time .Nanosecond
17
+ s , ok := t .(fmt.Stringer )
18
+ if ! ok {
19
+ fmt .Println ("time.Nanosecond does not implement fmt.Stringer" )
20
+ return
21
+ }
22
+ fmt .Println (s .String ())
23
+
24
+ var tt interface {}
25
+ tt = TestStruct {}
26
+ ss , ok := tt .(fmt.Stringer )
27
+ if ! ok {
28
+ fmt .Println ("TestStuct does not implement fmt.Stringer" )
29
+ return
30
+ }
31
+ fmt .Println (ss .String ())
32
+ }
33
+
34
+ // Output:
35
+ // 1ns
36
+ // hello world
Original file line number Diff line number Diff line change @@ -380,14 +380,54 @@ func typeAssert2(n *node) {
380
380
}
381
381
case isInterface (typ ):
382
382
n .exec = func (f * frame ) bltn {
383
- v := value (f ).Elem ()
384
- ok := v .IsValid () && canAssertTypes (v .Type (), rtype )
385
- if ok {
383
+ var leftType reflect.Type
384
+ v := value (f )
385
+ val , ok := v .Interface ().(valueInterface )
386
+ defer func () {
387
+ assertOk := ok
388
+ if setStatus {
389
+ value1 (f ).SetBool (assertOk )
390
+ }
391
+ }()
392
+ if ok && val .node .typ .cat != valueT {
393
+ m0 := val .node .typ .methods ()
394
+ m1 := typ .methods ()
395
+ if len (m0 ) < len (m1 ) {
396
+ ok = false
397
+ return next
398
+ }
399
+
400
+ for k , meth1 := range m1 {
401
+ var meth0 string
402
+ meth0 , ok = m0 [k ]
403
+ if ! ok {
404
+ return next
405
+ }
406
+ if meth0 != meth1 {
407
+ ok = false
408
+ return next
409
+ }
410
+ }
411
+
412
+ v = genInterfaceWrapper (val .node , rtype )(f )
386
413
value0 (f ).Set (v )
414
+ ok = true
415
+ return next
387
416
}
388
- if setStatus {
389
- value1 (f ).SetBool (ok )
417
+
418
+ if ok {
419
+ v = val .value
420
+ leftType = val .node .typ .rtype
421
+ } else {
422
+ v = v .Elem ()
423
+ leftType = v .Type ()
424
+ ok = true
390
425
}
426
+ ok = v .IsValid () && canAssertTypes (leftType , rtype )
427
+ if ! ok {
428
+ return next
429
+ }
430
+ value0 (f ).Set (v )
391
431
return next
392
432
}
393
433
case n .child [0 ].typ .cat == valueT || n .child [0 ].typ .cat == errorT :
@@ -844,6 +884,9 @@ func genFunctionWrapper(n *node) func(*frame) reflect.Value {
844
884
if src .Type ().Kind () != dest .Type ().Kind () {
845
885
dest .Set (src .Addr ())
846
886
} else {
887
+ if wrappedSrc , ok := src .Interface ().(valueInterface ); ok {
888
+ src = wrappedSrc .value
889
+ }
847
890
dest .Set (src )
848
891
}
849
892
d = d [numRet + 1 :]
You can’t perform that action at this time.
0 commit comments