@@ -18,6 +18,7 @@ import (
1818 "github.com/tinygo-org/tinygo/compiler/llvmutil"
1919 "github.com/tinygo-org/tinygo/loader"
2020 "golang.org/x/tools/go/ssa"
21+ "golang.org/x/tools/go/types/typeutil"
2122 "tinygo.org/x/go-llvm"
2223)
2324
@@ -70,7 +71,7 @@ type compilerContext struct {
7071 cu llvm.Metadata
7172 difiles map [string ]llvm.Metadata
7273 ditypes map [types.Type ]llvm.Metadata
73- llvmTypes map [types. Type ]llvm. Type
74+ llvmTypes typeutil. Map
7475 machine llvm.TargetMachine
7576 targetData llvm.TargetData
7677 intType llvm.Type
@@ -95,7 +96,6 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
9596 DumpSSA : dumpSSA ,
9697 difiles : make (map [string ]llvm.Metadata ),
9798 ditypes : make (map [types.Type ]llvm.Metadata ),
98- llvmTypes : make (map [types.Type ]llvm.Type ),
9999 machine : machine ,
100100 targetData : machine .CreateTargetData (),
101101 astComments : map [string ]* ast.CommentGroup {},
@@ -329,12 +329,16 @@ func (c *compilerContext) getLLVMRuntimeType(name string) llvm.Type {
329329// important for named struct types (which should only be created once).
330330func (c * compilerContext ) getLLVMType (goType types.Type ) llvm.Type {
331331 // 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 )
334338 }
335339 // Not already created, so adding this type to the cache.
336340 llvmType := c .makeLLVMType (goType )
337- c .llvmTypes [ goType ] = llvmType
341+ c .llvmTypes . Set ( goType , llvmType )
338342 return llvmType
339343}
340344
@@ -391,7 +395,7 @@ func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
391395 // self-referencing types such as linked lists.
392396 llvmName := typ .Obj ().Pkg ().Path () + "." + typ .Obj ().Name ()
393397 llvmType := c .ctx .StructCreateNamed (llvmName )
394- c .llvmTypes [ goType ] = llvmType // avoid infinite recursion
398+ c .llvmTypes . Set ( goType , llvmType ) // avoid infinite recursion
395399 underlying := c .getLLVMType (st )
396400 llvmType .StructSetBody (underlying .StructElementTypes (), false )
397401 return llvmType
0 commit comments