@@ -18,6 +18,7 @@ import (
18
18
"github.com/tinygo-org/tinygo/compiler/llvmutil"
19
19
"github.com/tinygo-org/tinygo/loader"
20
20
"golang.org/x/tools/go/ssa"
21
+ "golang.org/x/tools/go/types/typeutil"
21
22
"tinygo.org/x/go-llvm"
22
23
)
23
24
@@ -70,7 +71,7 @@ type compilerContext struct {
70
71
cu llvm.Metadata
71
72
difiles map [string ]llvm.Metadata
72
73
ditypes map [types.Type ]llvm.Metadata
73
- llvmTypes map [types. Type ]llvm. Type
74
+ llvmTypes typeutil. Map
74
75
machine llvm.TargetMachine
75
76
targetData llvm.TargetData
76
77
intType llvm.Type
@@ -95,7 +96,6 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
95
96
DumpSSA : dumpSSA ,
96
97
difiles : make (map [string ]llvm.Metadata ),
97
98
ditypes : make (map [types.Type ]llvm.Metadata ),
98
- llvmTypes : make (map [types.Type ]llvm.Type ),
99
99
machine : machine ,
100
100
targetData : machine .CreateTargetData (),
101
101
astComments : map [string ]* ast.CommentGroup {},
@@ -329,12 +329,16 @@ func (c *compilerContext) getLLVMRuntimeType(name string) llvm.Type {
329
329
// important for named struct types (which should only be created once).
330
330
func (c * compilerContext ) getLLVMType (goType types.Type ) llvm.Type {
331
331
// Try to load the LLVM type from the cache.
332
- if t , ok := c .llvmTypes [goType ]; ok {
333
- return t
332
+ // Note: *types.Named isn't unique when working with generics.
333
+ // See https://github.com/golang/go/issues/53914
334
+ // This is the reason for using typeutil.Map to lookup LLVM types for Go types.
335
+ ival := c .llvmTypes .At (goType )
336
+ if ival != nil {
337
+ return ival .(llvm.Type )
334
338
}
335
339
// Not already created, so adding this type to the cache.
336
340
llvmType := c .makeLLVMType (goType )
337
- c .llvmTypes [ goType ] = llvmType
341
+ c .llvmTypes . Set ( goType , llvmType )
338
342
return llvmType
339
343
}
340
344
@@ -391,7 +395,7 @@ func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
391
395
// self-referencing types such as linked lists.
392
396
llvmName := typ .Obj ().Pkg ().Path () + "." + typ .Obj ().Name ()
393
397
llvmType := c .ctx .StructCreateNamed (llvmName )
394
- c .llvmTypes [ goType ] = llvmType // avoid infinite recursion
398
+ c .llvmTypes . Set ( goType , llvmType ) // avoid infinite recursion
395
399
underlying := c .getLLVMType (st )
396
400
llvmType .StructSetBody (underlying .StructElementTypes (), false )
397
401
return llvmType
0 commit comments