Skip to content

Commit 133a05f

Browse files
committed
ssa: typeAssert check closure equal
1 parent 070d64f commit 133a05f

File tree

7 files changed

+144
-62
lines changed

7 files changed

+144
-62
lines changed

cl/_testgo/reflect/in.go

+10-12
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,11 @@ func callMethod() {
9393
println("method", fn.Kind(), fn.Type().String())
9494
r := fn.Call([]reflect.Value{reflect.ValueOf(100)})
9595
println(r[0].Int())
96-
//TODO type assert
97-
// ifn, ok := fn.Interface().(func(int) int)
98-
// if !ok {
99-
// panic("error")
100-
// }
101-
// ifn(1)
96+
ifn, ok := fn.Interface().(func(int) int)
97+
if !ok {
98+
panic("error")
99+
}
100+
ifn(1)
102101
v2 := reflect.ValueOf(fn.Interface())
103102
r2 := v2.Call([]reflect.Value{reflect.ValueOf(100)})
104103
println(r2[0].Int())
@@ -111,12 +110,11 @@ func callIMethod() {
111110
println("imethod", fn.Kind(), fn.Type().String())
112111
r := fn.Call([]reflect.Value{reflect.ValueOf(100)})
113112
println(r[0].Int())
114-
//TODO type assert
115-
// ifn, ok := fn.Interface().(func(int) int)
116-
// if !ok {
117-
// panic("error")
118-
// }
119-
// ifn(1)
113+
ifn, ok := fn.Interface().(func(int) int)
114+
if !ok {
115+
panic("error")
116+
}
117+
ifn(1)
120118
v2 := reflect.ValueOf(fn.Interface())
121119
r2 := v2.Call([]reflect.Value{reflect.ValueOf(100)})
122120
println(r2[0].Int())

cl/_testgo/reflect/out.ll

+114-42
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ _llgo_0:
127127
%39 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %11)
128128
%40 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %39, 0
129129
%41 = load ptr, ptr @"main.struct$0F5MIVpixVnQ6IoIDrJI9hTk70oCWg1odzb2q0E2rJ0", align 8
130-
%42 = icmp eq ptr %40, %41
130+
%42 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %41, ptr %40)
131131
br i1 %42, label %_llgo_3, label %_llgo_4
132132

133133
_llgo_1: ; preds = %_llgo_5
@@ -223,7 +223,7 @@ _llgo_0:
223223
%32 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %4)
224224
%33 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %32, 0
225225
%34 = load ptr, ptr @"main.struct$0F5MIVpixVnQ6IoIDrJI9hTk70oCWg1odzb2q0E2rJ0", align 8
226-
%35 = icmp eq ptr %33, %34
226+
%35 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %34, ptr %33)
227227
br i1 %35, label %_llgo_3, label %_llgo_4
228228

229229
_llgo_1: ; preds = %_llgo_5
@@ -322,28 +322,63 @@ _llgo_0:
322322
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %41)
323323
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
324324
%42 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %14)
325-
%43 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %42)
326-
%44 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
327-
%45 = getelementptr inbounds %reflect.Value, ptr %44, i64 0
328-
%46 = load ptr, ptr @_llgo_int, align 8
329-
%47 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %46, 0
330-
%48 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %47, ptr inttoptr (i64 100 to ptr), 1
331-
%49 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %48)
332-
store %reflect.Value %49, ptr %45, align 8
333-
%50 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %44, 0
334-
%51 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %50, i64 1, 1
335-
%52 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %51, i64 1, 2
336-
%53 = call %"github.com/goplus/llgo/internal/runtime.Slice" @reflect.Value.Call(%reflect.Value %43, %"github.com/goplus/llgo/internal/runtime.Slice" %52)
337-
%54 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %53, 0
338-
%55 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %53, 1
339-
%56 = icmp sge i64 0, %55
340-
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %56)
341-
%57 = getelementptr inbounds %reflect.Value, ptr %54, i64 0
342-
%58 = load %reflect.Value, ptr %57, align 8
343-
%59 = call i64 @reflect.Value.Int(%reflect.Value %58)
344-
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %59)
325+
%43 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %42, 0
326+
%44 = load ptr, ptr @"main.struct$0F5MIVpixVnQ6IoIDrJI9hTk70oCWg1odzb2q0E2rJ0", align 8
327+
%45 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %44, ptr %43)
328+
br i1 %45, label %_llgo_3, label %_llgo_4
329+
330+
_llgo_1: ; preds = %_llgo_5
331+
%46 = load ptr, ptr @_llgo_string, align 8
332+
%47 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
333+
store %"github.com/goplus/llgo/internal/runtime.String" { ptr @5, i64 5 }, ptr %47, align 8
334+
%48 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %46, 0
335+
%49 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %48, ptr %47, 1
336+
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %49)
337+
unreachable
338+
339+
_llgo_2: ; preds = %_llgo_5
340+
%50 = extractvalue { ptr, ptr } %76, 1
341+
%51 = extractvalue { ptr, ptr } %76, 0
342+
%52 = call i64 %51(ptr %50, i64 1)
343+
%53 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %14)
344+
%54 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %53)
345+
%55 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
346+
%56 = getelementptr inbounds %reflect.Value, ptr %55, i64 0
347+
%57 = load ptr, ptr @_llgo_int, align 8
348+
%58 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %57, 0
349+
%59 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %58, ptr inttoptr (i64 100 to ptr), 1
350+
%60 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %59)
351+
store %reflect.Value %60, ptr %56, align 8
352+
%61 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %55, 0
353+
%62 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %61, i64 1, 1
354+
%63 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %62, i64 1, 2
355+
%64 = call %"github.com/goplus/llgo/internal/runtime.Slice" @reflect.Value.Call(%reflect.Value %54, %"github.com/goplus/llgo/internal/runtime.Slice" %63)
356+
%65 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %64, 0
357+
%66 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %64, 1
358+
%67 = icmp sge i64 0, %66
359+
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %67)
360+
%68 = getelementptr inbounds %reflect.Value, ptr %65, i64 0
361+
%69 = load %reflect.Value, ptr %68, align 8
362+
%70 = call i64 @reflect.Value.Int(%reflect.Value %69)
363+
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %70)
345364
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
346365
ret void
366+
367+
_llgo_3: ; preds = %_llgo_0
368+
%71 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %42, 1
369+
%72 = load { ptr, ptr }, ptr %71, align 8
370+
%73 = insertvalue { { ptr, ptr }, i1 } undef, { ptr, ptr } %72, 0
371+
%74 = insertvalue { { ptr, ptr }, i1 } %73, i1 true, 1
372+
br label %_llgo_5
373+
374+
_llgo_4: ; preds = %_llgo_0
375+
br label %_llgo_5
376+
377+
_llgo_5: ; preds = %_llgo_4, %_llgo_3
378+
%75 = phi { { ptr, ptr }, i1 } [ %74, %_llgo_3 ], [ zeroinitializer, %_llgo_4 ]
379+
%76 = extractvalue { { ptr, ptr }, i1 } %75, 0
380+
%77 = extractvalue { { ptr, ptr }, i1 } %75, 1
381+
br i1 %77, label %_llgo_2, label %_llgo_1
347382
}
348383

349384
define void @main.callMethod() {
@@ -394,28 +429,63 @@ _llgo_0:
394429
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %33)
395430
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
396431
%34 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %6)
397-
%35 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %34)
398-
%36 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
399-
%37 = getelementptr inbounds %reflect.Value, ptr %36, i64 0
400-
%38 = load ptr, ptr @_llgo_int, align 8
401-
%39 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %38, 0
402-
%40 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %39, ptr inttoptr (i64 100 to ptr), 1
403-
%41 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %40)
404-
store %reflect.Value %41, ptr %37, align 8
405-
%42 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %36, 0
406-
%43 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %42, i64 1, 1
407-
%44 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %43, i64 1, 2
408-
%45 = call %"github.com/goplus/llgo/internal/runtime.Slice" @reflect.Value.Call(%reflect.Value %35, %"github.com/goplus/llgo/internal/runtime.Slice" %44)
409-
%46 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %45, 0
410-
%47 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %45, 1
411-
%48 = icmp sge i64 0, %47
412-
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %48)
413-
%49 = getelementptr inbounds %reflect.Value, ptr %46, i64 0
414-
%50 = load %reflect.Value, ptr %49, align 8
415-
%51 = call i64 @reflect.Value.Int(%reflect.Value %50)
416-
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %51)
432+
%35 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %34, 0
433+
%36 = load ptr, ptr @"main.struct$0F5MIVpixVnQ6IoIDrJI9hTk70oCWg1odzb2q0E2rJ0", align 8
434+
%37 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %36, ptr %35)
435+
br i1 %37, label %_llgo_3, label %_llgo_4
436+
437+
_llgo_1: ; preds = %_llgo_5
438+
%38 = load ptr, ptr @_llgo_string, align 8
439+
%39 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocU"(i64 16)
440+
store %"github.com/goplus/llgo/internal/runtime.String" { ptr @5, i64 5 }, ptr %39, align 8
441+
%40 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %38, 0
442+
%41 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %40, ptr %39, 1
443+
call void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface" %41)
444+
unreachable
445+
446+
_llgo_2: ; preds = %_llgo_5
447+
%42 = extractvalue { ptr, ptr } %68, 1
448+
%43 = extractvalue { ptr, ptr } %68, 0
449+
%44 = call i64 %43(ptr %42, i64 1)
450+
%45 = call %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value %6)
451+
%46 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %45)
452+
%47 = call ptr @"github.com/goplus/llgo/internal/runtime.AllocZ"(i64 24)
453+
%48 = getelementptr inbounds %reflect.Value, ptr %47, i64 0
454+
%49 = load ptr, ptr @_llgo_int, align 8
455+
%50 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" undef, ptr %49, 0
456+
%51 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %50, ptr inttoptr (i64 100 to ptr), 1
457+
%52 = call %reflect.Value @reflect.ValueOf(%"github.com/goplus/llgo/internal/runtime.eface" %51)
458+
store %reflect.Value %52, ptr %48, align 8
459+
%53 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" undef, ptr %47, 0
460+
%54 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %53, i64 1, 1
461+
%55 = insertvalue %"github.com/goplus/llgo/internal/runtime.Slice" %54, i64 1, 2
462+
%56 = call %"github.com/goplus/llgo/internal/runtime.Slice" @reflect.Value.Call(%reflect.Value %46, %"github.com/goplus/llgo/internal/runtime.Slice" %55)
463+
%57 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %56, 0
464+
%58 = extractvalue %"github.com/goplus/llgo/internal/runtime.Slice" %56, 1
465+
%59 = icmp sge i64 0, %58
466+
call void @"github.com/goplus/llgo/internal/runtime.AssertIndexRange"(i1 %59)
467+
%60 = getelementptr inbounds %reflect.Value, ptr %57, i64 0
468+
%61 = load %reflect.Value, ptr %60, align 8
469+
%62 = call i64 @reflect.Value.Int(%reflect.Value %61)
470+
call void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64 %62)
417471
call void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8 10)
418472
ret void
473+
474+
_llgo_3: ; preds = %_llgo_0
475+
%63 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %34, 1
476+
%64 = load { ptr, ptr }, ptr %63, align 8
477+
%65 = insertvalue { { ptr, ptr }, i1 } undef, { ptr, ptr } %64, 0
478+
%66 = insertvalue { { ptr, ptr }, i1 } %65, i1 true, 1
479+
br label %_llgo_5
480+
481+
_llgo_4: ; preds = %_llgo_0
482+
br label %_llgo_5
483+
484+
_llgo_5: ; preds = %_llgo_4, %_llgo_3
485+
%67 = phi { { ptr, ptr }, i1 } [ %66, %_llgo_3 ], [ zeroinitializer, %_llgo_4 ]
486+
%68 = extractvalue { { ptr, ptr }, i1 } %67, 0
487+
%69 = extractvalue { { ptr, ptr }, i1 } %67, 1
488+
br i1 %69, label %_llgo_2, label %_llgo_1
419489
}
420490

421491
define void @main.callSlice() {
@@ -1376,6 +1446,8 @@ declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
13761446

13771447
declare %"github.com/goplus/llgo/internal/runtime.eface" @reflect.Value.Interface(%reflect.Value)
13781448

1449+
declare i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr, ptr)
1450+
13791451
declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface")
13801452

13811453
define linkonce i64 @"__llgo_stub.main.callFunc$1"(ptr %0, i64 %1) {

cl/_testrt/closureiface/out.ll

+3-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ _llgo_0:
5656
%12 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %11, ptr %10, 1
5757
%13 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %12, 0
5858
%14 = load ptr, ptr @"main.struct$0F5MIVpixVnQ6IoIDrJI9hTk70oCWg1odzb2q0E2rJ0", align 8
59-
%15 = icmp eq ptr %13, %14
59+
%15 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %14, ptr %13)
6060
br i1 %15, label %_llgo_3, label %_llgo_4
6161

6262
_llgo_1: ; preds = %_llgo_5
@@ -209,6 +209,8 @@ declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/l
209209

210210
declare void @"github.com/goplus/llgo/internal/runtime.SetClosure"(ptr)
211211

212+
declare i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr, ptr)
213+
212214
declare void @"github.com/goplus/llgo/internal/runtime.PrintInt"(i64)
213215

214216
declare void @"github.com/goplus/llgo/internal/runtime.PrintByte"(i8)

cl/_testrt/funcdecl/out.ll

+4-2
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ _llgo_0:
3939
%10 = insertvalue %"github.com/goplus/llgo/internal/runtime.eface" %9, ptr %8, 1
4040
%11 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %6, 0
4141
%12 = load ptr, ptr @"main.struct$MYJJzV_XnHHne2yABOrxrKaJAnHA7CUbHXWeamxO-48", align 8
42-
%13 = icmp eq ptr %11, %12
42+
%13 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %12, ptr %11)
4343
br i1 %13, label %_llgo_1, label %_llgo_2
4444

4545
_llgo_1: ; preds = %_llgo_0
4646
%14 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %6, 1
4747
%15 = load { ptr, ptr }, ptr %14, align 8
4848
%16 = extractvalue %"github.com/goplus/llgo/internal/runtime.eface" %10, 0
4949
%17 = load ptr, ptr @"main.struct$MYJJzV_XnHHne2yABOrxrKaJAnHA7CUbHXWeamxO-48", align 8
50-
%18 = icmp eq ptr %16, %17
50+
%18 = call i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr %17, ptr %16)
5151
br i1 %18, label %_llgo_3, label %_llgo_4
5252

5353
_llgo_2: ; preds = %_llgo_0
@@ -225,6 +225,8 @@ declare %"github.com/goplus/llgo/internal/abi.StructField" @"github.com/goplus/l
225225

226226
declare void @"github.com/goplus/llgo/internal/runtime.SetClosure"(ptr)
227227

228+
declare i1 @"github.com/goplus/llgo/internal/runtime.ClosureEqual"(ptr, ptr)
229+
228230
declare void @"github.com/goplus/llgo/internal/runtime.Panic"(%"github.com/goplus/llgo/internal/runtime.eface")
229231

230232
declare void @"github.com/goplus/llgo/internal/runtime.PrintEface"(%"github.com/goplus/llgo/internal/runtime.eface")

internal/lib/reflect/makefunc.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -129,14 +129,12 @@ func makeMethodValue(op string, v Value) Value {
129129

130130
// v.Type returns the actual type of the method value.
131131
ftyp := (*funcType)(unsafe.Pointer(v.Type().(*rtype)))
132-
ptyp := rtypeOf(unsafe.Pointer(uintptr(0)))
133-
typ := runtime.Struct(v.typ().Uncommon().PkgPath_, 2*unsafe.Sizeof(0), abi.StructField{
132+
typ := runtime.Struct("", 2*unsafe.Sizeof(0), abi.StructField{
134133
Name_: "f",
135134
Typ: &ftyp.Type,
136135
}, abi.StructField{
137-
Name_: "data",
138-
Typ: ptyp,
139-
Offset: unsafe.Sizeof(0),
136+
Name_: "data",
137+
Typ: unsafePointerType,
140138
})
141139
typ.TFlag |= abi.TFlagClosure
142140
_, _, fn := methodReceiver(op, rcvr, int(v.flag)>>flagMethodShift)
@@ -150,6 +148,8 @@ func makeMethodValue(op string, v Value) Value {
150148
return Value{typ, unsafe.Pointer(fv), v.flag&flagRO | flagIndir | flag(Func)}
151149
}
152150

151+
var unsafePointerType = rtypeOf(unsafe.Pointer(nil))
152+
153153
/*
154154
func methodValueCallCodePtr() uintptr {
155155
return abi.FuncPCABI0(methodValueCall)

internal/runtime/z_face.go

+5
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,11 @@ func SetClosure(t *abi.Type) {
490490
t.TFlag |= abi.TFlagClosure
491491
}
492492

493+
func ClosureEqual(c *abi.Type, t *abi.Type) bool {
494+
return c == t || (t.IsClosure() &&
495+
(*abi.StructType)(unsafe.Pointer(c)).Fields[0].Typ == (*abi.StructType)(unsafe.Pointer(t)).Fields[0].Typ)
496+
}
497+
493498
func interfaceStr(ft *abi.InterfaceType) string {
494499
repr := make([]byte, 0, 64)
495500
repr = append(repr, "interface {"...)

ssa/interface.go

+3
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,9 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
245245
if rawIntf, ok := assertedTyp.raw.Type.Underlying().(*types.Interface); ok {
246246
eq = b.InlineCall(b.Pkg.rtFunc("Implements"), tabi, tx)
247247
val = func() Expr { return Expr{b.unsafeInterface(rawIntf, tx, b.faceData(x.impl)), assertedTyp} }
248+
} else if assertedTyp.kind == vkClosure {
249+
eq = b.InlineCall(b.Pkg.rtFunc("ClosureEqual"), tabi, tx)
250+
val = func() Expr { return b.valFromData(assertedTyp, b.faceData(x.impl)) }
248251
} else {
249252
eq = b.BinOp(token.EQL, tx, tabi)
250253
val = func() Expr { return b.valFromData(assertedTyp, b.faceData(x.impl)) }

0 commit comments

Comments
 (0)