Skip to content

Commit b6eca18

Browse files
luoliwoshangclaude
andcommitted
test: regression test for #1389
Add a minimal test case that reproduces the conditional variable reuse bug in type initialization. The test demonstrates: - A named type (MyType) that is initialized early - An interface (MyInterface) with a method returning MyType - The compiler incorrectly reuses the parent type's null check condition to control method type initialization In the generated IR (out.ll): - Line 163-164: Defines %9 = (MyType == null) - Line 182: Reuses the same %9 to control InitNamed call - When MyType already exists, method initialization is skipped This is the same bug pattern as io/fs.FileMode in the reported issue, but in a much simpler form for easier understanding and testing. Related: #1389 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 2363d28 commit b6eca18

File tree

2 files changed

+425
-0
lines changed

2 files changed

+425
-0
lines changed

cl/_testgo/methodinit1389/in.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package main
2+
3+
// This test case reproduces the issue where method type initialization
4+
// is incorrectly skipped when the parent type is already initialized.
5+
//
6+
// The problem occurs when:
7+
// 1. A named type (MyType) is initialized first (via init or usage)
8+
// 2. Then an interface (MyInterface) with a method returning MyType needs initialization
9+
// 3. The compiler incorrectly reuses the null check condition from the parent type
10+
// to control method type initialization, causing func() MyType to never be created
11+
12+
// Named type (like io/fs.FileMode)
13+
type MyType uint32
14+
15+
// Interface with method returning MyType (like io/fs.DirEntry)
16+
type MyInterface interface {
17+
Name() string
18+
GetType() MyType // Method returning the named type
19+
}
20+
21+
// Implementation of MyInterface
22+
type MyImpl struct {
23+
name string
24+
myType MyType
25+
}
26+
27+
func (m *MyImpl) Name() string {
28+
return m.name
29+
}
30+
31+
func (m *MyImpl) GetType() MyType {
32+
return m.myType
33+
}
34+
35+
// Prematurely initialize MyType by using it in init
36+
// (simulates the effect of init$after running before dependencies are initialized)
37+
func init() {
38+
_ = MyType(0) // Force MyType to be initialized early
39+
}
40+
41+
func main() {
42+
// Type assertion forces interface type initialization at runtime
43+
var i interface{} = &MyImpl{name: "test", myType: 42}
44+
45+
// This type assertion requires MyInterface type to be fully initialized
46+
// including the method type func() MyType
47+
if mi, ok := i.(MyInterface); ok {
48+
println(mi.Name())
49+
println(uint32(mi.GetType()))
50+
}
51+
52+
println("Test passed")
53+
}

0 commit comments

Comments
 (0)