mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 20:43:40 +00:00
compiler: disambiguate function-local named types (#5336)
* compiler: make getTypeCodeName a method on compilerContext * testdata: add regression tests for function-local named types * compiler: disambiguate function-local named types * Some PR feedback
This commit is contained in:
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
module github.com/tinygo-org/tinygo/testdata/localtypes
|
||||
|
||||
go 1.21
|
||||
Vendored
+28
@@ -0,0 +1,28 @@
|
||||
package lib
|
||||
|
||||
type Checker = func(any) bool
|
||||
|
||||
func GenericWithLocals[T any]() (any, any, Checker, Checker) {
|
||||
type UsesT struct{ V T }
|
||||
type NoT struct{ V int }
|
||||
var z T
|
||||
return UsesT{V: z}, NoT{V: 42},
|
||||
func(x any) bool { _, ok := x.(UsesT); return ok },
|
||||
func(x any) bool { _, ok := x.(NoT); return ok }
|
||||
}
|
||||
|
||||
func SiblingClosures() (any, any, Checker, Checker) {
|
||||
var av, bv any
|
||||
var ac, bc Checker
|
||||
func() {
|
||||
type Foo struct{ V int }
|
||||
av = Foo{V: 1}
|
||||
ac = func(x any) bool { _, ok := x.(Foo); return ok }
|
||||
}()
|
||||
func() {
|
||||
type Foo struct{ V int }
|
||||
bv = Foo{V: 2}
|
||||
bc = func(x any) bool { _, ok := x.(Foo); return ok }
|
||||
}()
|
||||
return av, bv, ac, bc
|
||||
}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
package lib2
|
||||
|
||||
import "github.com/tinygo-org/tinygo/testdata/localtypes/lib"
|
||||
|
||||
func IntPair() (any, any, lib.Checker, lib.Checker) { return lib.GenericWithLocals[int]() }
|
||||
Vendored
+40
@@ -0,0 +1,40 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/tinygo-org/tinygo/testdata/localtypes/lib"
|
||||
"github.com/tinygo-org/tinygo/testdata/localtypes/lib2"
|
||||
)
|
||||
|
||||
func expect(name string, ok bool) {
|
||||
if ok {
|
||||
println("ok:", name)
|
||||
} else {
|
||||
println("BUG:", name)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
mainU, mainN, mainUC, mainNC := lib.GenericWithLocals[int]()
|
||||
libU, libN, libUC, libNC := lib2.IntPair()
|
||||
|
||||
// Same instance compiled in two packages: each package's checker
|
||||
// must accept the other package's value.
|
||||
expect("main GenericWithLocals[int].UsesT accepts lib2's value", mainUC(libU))
|
||||
expect("main GenericWithLocals[int].NoT accepts lib2's value", mainNC(libN))
|
||||
expect("lib2 GenericWithLocals[int].UsesT accepts main's value", libUC(mainU))
|
||||
expect("lib2 GenericWithLocals[int].NoT accepts main's value", libNC(mainN))
|
||||
|
||||
// Different instantiations: distinct types.
|
||||
stringU, stringN, stringUC, stringNC := lib.GenericWithLocals[string]()
|
||||
expect("GenericWithLocals[int].UsesT rejects [string].UsesT", !mainUC(stringU))
|
||||
expect("GenericWithLocals[int].NoT rejects [string].NoT", !mainNC(stringN))
|
||||
expect("GenericWithLocals[string].UsesT rejects [int].UsesT", !stringUC(mainU))
|
||||
expect("GenericWithLocals[string].NoT rejects [int].NoT", !stringNC(mainN))
|
||||
|
||||
// Sibling closures inside one function (declared in lib).
|
||||
scA, scB, scAC, scBC := lib.SiblingClosures()
|
||||
expect("lib.SiblingClosures.Foo#1 accepts own", scAC(scA))
|
||||
expect("lib.SiblingClosures.Foo#2 accepts own", scBC(scB))
|
||||
expect("lib.SiblingClosures.Foo#1 rejects Foo#2", !scAC(scB))
|
||||
expect("lib.SiblingClosures.Foo#2 rejects Foo#1", !scBC(scA))
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
ok: main GenericWithLocals[int].UsesT accepts lib2's value
|
||||
ok: main GenericWithLocals[int].NoT accepts lib2's value
|
||||
ok: lib2 GenericWithLocals[int].UsesT accepts main's value
|
||||
ok: lib2 GenericWithLocals[int].NoT accepts main's value
|
||||
ok: GenericWithLocals[int].UsesT rejects [string].UsesT
|
||||
ok: GenericWithLocals[int].NoT rejects [string].NoT
|
||||
ok: GenericWithLocals[string].UsesT rejects [int].UsesT
|
||||
ok: GenericWithLocals[string].NoT rejects [int].NoT
|
||||
ok: lib.SiblingClosures.Foo#1 accepts own
|
||||
ok: lib.SiblingClosures.Foo#2 accepts own
|
||||
ok: lib.SiblingClosures.Foo#1 rejects Foo#2
|
||||
ok: lib.SiblingClosures.Foo#2 rejects Foo#1
|
||||
Reference in New Issue
Block a user