compiler: fix issue with methods on generic structs
Этот коммит содержится в:
родитель
5026047cde
коммит
58072a5167
2 изменённых файлов: 18 добавлений и 6 удалений
|
@ -18,6 +18,7 @@ import (
|
|||
"github.com/tinygo-org/tinygo/compiler/llvmutil"
|
||||
"github.com/tinygo-org/tinygo/loader"
|
||||
"golang.org/x/tools/go/ssa"
|
||||
"golang.org/x/tools/go/types/typeutil"
|
||||
"tinygo.org/x/go-llvm"
|
||||
)
|
||||
|
||||
|
@ -70,7 +71,7 @@ type compilerContext struct {
|
|||
cu llvm.Metadata
|
||||
difiles map[string]llvm.Metadata
|
||||
ditypes map[types.Type]llvm.Metadata
|
||||
llvmTypes map[types.Type]llvm.Type
|
||||
llvmTypes typeutil.Map
|
||||
machine llvm.TargetMachine
|
||||
targetData llvm.TargetData
|
||||
intType llvm.Type
|
||||
|
@ -95,7 +96,6 @@ func newCompilerContext(moduleName string, machine llvm.TargetMachine, config *C
|
|||
DumpSSA: dumpSSA,
|
||||
difiles: make(map[string]llvm.Metadata),
|
||||
ditypes: make(map[types.Type]llvm.Metadata),
|
||||
llvmTypes: make(map[types.Type]llvm.Type),
|
||||
machine: machine,
|
||||
targetData: machine.CreateTargetData(),
|
||||
astComments: map[string]*ast.CommentGroup{},
|
||||
|
@ -329,12 +329,16 @@ func (c *compilerContext) getLLVMRuntimeType(name string) llvm.Type {
|
|||
// important for named struct types (which should only be created once).
|
||||
func (c *compilerContext) getLLVMType(goType types.Type) llvm.Type {
|
||||
// Try to load the LLVM type from the cache.
|
||||
if t, ok := c.llvmTypes[goType]; ok {
|
||||
return t
|
||||
// Note: *types.Named isn't unique when working with generics.
|
||||
// See https://github.com/golang/go/issues/53914
|
||||
// This is the reason for using typeutil.Map to lookup LLVM types for Go types.
|
||||
ival := c.llvmTypes.At(goType)
|
||||
if ival != nil {
|
||||
return ival.(llvm.Type)
|
||||
}
|
||||
// Not already created, so adding this type to the cache.
|
||||
llvmType := c.makeLLVMType(goType)
|
||||
c.llvmTypes[goType] = llvmType
|
||||
c.llvmTypes.Set(goType, llvmType)
|
||||
return llvmType
|
||||
}
|
||||
|
||||
|
@ -391,7 +395,7 @@ func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
|
|||
// self-referencing types such as linked lists.
|
||||
llvmName := typ.Obj().Pkg().Path() + "." + typ.Obj().Name()
|
||||
llvmType := c.ctx.StructCreateNamed(llvmName)
|
||||
c.llvmTypes[goType] = llvmType // avoid infinite recursion
|
||||
c.llvmTypes.Set(goType, llvmType) // avoid infinite recursion
|
||||
underlying := c.getLLVMType(st)
|
||||
llvmType.StructSetBody(underlying.StructElementTypes(), false)
|
||||
return llvmType
|
||||
|
|
8
testdata/generics.go
предоставленный
8
testdata/generics.go
предоставленный
|
@ -3,6 +3,9 @@ package main
|
|||
func main() {
|
||||
println("add:", Add(3, 5))
|
||||
println("add:", Add(int8(3), 5))
|
||||
|
||||
var c C[int]
|
||||
c.F() // issue 2951
|
||||
}
|
||||
|
||||
type Integer interface {
|
||||
|
@ -12,3 +15,8 @@ type Integer interface {
|
|||
func Add[T Integer](a, b T) T {
|
||||
return a + b
|
||||
}
|
||||
|
||||
// Test for https://github.com/tinygo-org/tinygo/issues/2951
|
||||
type C[V any] struct{}
|
||||
|
||||
func (c *C[V]) F() {}
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче