Skip to content

Commit 2e043c7

Browse files
aykevldeadprogram
authored andcommitted
compiler: add support for GODEBUG=gotypesalias=1
Since we now require Go 1.22, this became a lot simpler (since we can now refer to `types.Alias` and `types.Unalias`).
1 parent 3f4f4e0 commit 2e043c7

File tree

4 files changed

+27
-9
lines changed

4 files changed

+27
-9
lines changed

compiler/compiler.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ func (c *compilerContext) getLLVMType(goType types.Type) llvm.Type {
389389
// makeLLVMType creates a LLVM type for a Go type. Don't call this, use
390390
// getLLVMType instead.
391391
func (c *compilerContext) makeLLVMType(goType types.Type) llvm.Type {
392-
switch typ := goType.(type) {
392+
switch typ := types.Unalias(goType).(type) {
393393
case *types.Array:
394394
elemType := c.getLLVMType(typ.Elem())
395395
return llvm.ArrayType(elemType, int(typ.Len()))
@@ -497,6 +497,21 @@ func (c *compilerContext) createDIType(typ types.Type) llvm.Metadata {
497497
llvmType := c.getLLVMType(typ)
498498
sizeInBytes := c.targetData.TypeAllocSize(llvmType)
499499
switch typ := typ.(type) {
500+
case *types.Alias:
501+
// Implement types.Alias just like types.Named: by treating them like a
502+
// C typedef.
503+
temporaryMDNode := c.dibuilder.CreateReplaceableCompositeType(llvm.Metadata{}, llvm.DIReplaceableCompositeType{
504+
Tag: dwarf.TagTypedef,
505+
SizeInBits: sizeInBytes * 8,
506+
AlignInBits: uint32(c.targetData.ABITypeAlignment(llvmType)) * 8,
507+
})
508+
c.ditypes[typ] = temporaryMDNode
509+
md := c.dibuilder.CreateTypedef(llvm.DITypedef{
510+
Type: c.getDIType(types.Unalias(typ)), // TODO: use typ.Rhs in Go 1.23
511+
Name: typ.String(),
512+
})
513+
temporaryMDNode.ReplaceAllUsesWith(md)
514+
return md
500515
case *types.Array:
501516
return c.dibuilder.CreateArrayType(llvm.DIArrayType{
502517
SizeInBits: sizeInBytes * 8,
@@ -859,6 +874,11 @@ func (c *compilerContext) createPackage(irbuilder llvm.Builder, pkg *ssa.Package
859874
// Interfaces don't have concrete methods.
860875
continue
861876
}
877+
if _, isalias := member.Type().(*types.Alias); isalias {
878+
// Aliases don't need to be redefined, since they just refer to
879+
// an already existing type whose methods will be defined.
880+
continue
881+
}
862882

863883
// Named type. We should make sure all methods are created.
864884
// This includes both functions with pointer receivers and those

compiler/interface.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ func (c *compilerContext) pkgPathPtr(pkgpath string) llvm.Value {
122122
// This function returns a pointer to the 'kind' field (which might not be the
123123
// first field in the struct).
124124
func (c *compilerContext) getTypeCode(typ types.Type) llvm.Value {
125+
// Resolve alias types: alias types are resolved at compile time.
126+
typ = types.Unalias(typ)
127+
125128
ms := c.program.MethodSets.MethodSet(typ)
126129
hasMethodSet := ms.Len() != 0
127130
_, isInterface := typ.Underlying().(*types.Interface)
@@ -512,7 +515,7 @@ var basicTypeNames = [...]string{
512515
// interface lowering pass to assign type codes as expected by the reflect
513516
// package. See getTypeCodeNum.
514517
func getTypeCodeName(t types.Type) (string, bool) {
515-
switch t := t.(type) {
518+
switch t := types.Unalias(t).(type) {
516519
case *types.Named:
517520
if t.Obj().Parent() != t.Obj().Pkg().Scope() {
518521
return "named:" + t.String() + "$local", true
@@ -942,7 +945,7 @@ func signature(sig *types.Signature) string {
942945
// normalization around `byte` vs `uint8` for example.
943946
func typestring(t types.Type) string {
944947
// See: https://github.com/golang/go/blob/master/src/go/types/typestring.go
945-
switch t := t.(type) {
948+
switch t := types.Unalias(t).(type) {
946949
case *types.Array:
947950
return "[" + strconv.FormatInt(t.Len(), 10) + "]" + typestring(t.Elem())
948951
case *types.Basic:

compiler/map.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ func (b *builder) createMapIteratorNext(rangeVal ssa.Value, llvmRangeVal, it llv
248248
// can be compared with runtime.memequal. Note that padding bytes are undef
249249
// and can alter two "equal" structs being equal when compared with memequal.
250250
func hashmapIsBinaryKey(keyType types.Type) bool {
251-
switch keyType := keyType.(type) {
251+
switch keyType := keyType.Underlying().(type) {
252252
case *types.Basic:
253253
return keyType.Info()&(types.IsBoolean|types.IsInteger) != 0
254254
case *types.Pointer:
@@ -263,8 +263,6 @@ func hashmapIsBinaryKey(keyType types.Type) bool {
263263
return true
264264
case *types.Array:
265265
return hashmapIsBinaryKey(keyType.Elem())
266-
case *types.Named:
267-
return hashmapIsBinaryKey(keyType.Underlying())
268266
default:
269267
return false
270268
}

flake.nix

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,6 @@
6767
# has `md5sum`).
6868
export MD5SUM=md5sum
6969
70-
# Work around #4819, missing support for generic type aliases.
71-
export GODEBUG=gotypesalias=0
72-
7370
# Ugly hack to make the Clang resources directory available.
7471
export GOFLAGS="\"-ldflags=-X github.com/tinygo-org/tinygo/goenv.clangResourceDir=${llvmPackages_20.clang.cc.lib}/lib/clang/20\" -tags=llvm20"
7572
'';

0 commit comments

Comments
 (0)