Skip to content

This repository showed how to reproduce the compiler unexpected behavior, or issue, bug when embedding a struct that has a field to reference the outer struct by using generic recursively

License

Notifications You must be signed in to change notification settings

nekomeowww/reproduction_recursive_generic_type_issue

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Reproduction for recursive generic type issue of Golang compiler

This repository showed how to reproduce the compiler unexpected behavior, or issue, bug when a struct that has a field to reference the outer struct that has a field to reference the initial struct by using generic in the way recursively: the compiler will complain fatal error: all goroutines are asleep - deadlock! or other behave unexpectedly in all different ways.

Expected

  • Compiler or documentation should address the issue when user attempts to do so.
  • Compiler should have a consistent behavior when user attempts to do so.
  • Compiler should produce the needed assembly codes for the generic recursive types or produces error or warning messages when user attempts to do so.

Behaviors

  • Compiler might complain the fatal error: all goroutines are asleep - deadlock! panics message when running the test by go test -v ./....
  • Compiler might be able to compile the needed assembly codes and run the test successfully when you write the test codes without the _test suffix (exported test).
  • Compiler might complain about the invalid recursive type if you try to move the T2[T any] definition to another file.
  • Compiler might not be able to generate the needed assembly codes for the generic recursive types and produces no error or warning messages silently.
  • Compiler might complain about the redecalred if you try to reload the IDE somehow.

How to reproduce the issue from this repository?

This is the most needed directory structure for reproducing the issue, each cases are well documented with the case, summary, and how-to-reproduce, you may navigate into the directory and run the command I provided in the README.md file to reproduce the issue by yourself on-demand. Or you could use the next section to click the link to the issue and case you want to reproduce by following the instructions.

.
├── minimum_repro
│   ├── deadlock_issue # issue 1: fatal error: all goroutines are asleep - deadlock!
│   │   ├── with_generics # at the case of using generics
│   │   ├── with_generics_with_pointer # at the case of using generics with pointer wrapped
│   │   └── with_generics_without_test_package # at the case of using generics without test package (no _test suffix)
│   ├── unstable_invalid_recursive_issue # issue 2: invalid recursive type
│   │   ├── seperated_files # at the case of seperated files
│   │   └── single_file # at the case of single file
│   └── unstable_redeclare_issue # issue 3: redeclared in this block
│       └── seperated_files # at the case of seperated files
└── original_scenario # the original scenario that I encountered the issue

Issue 1: fatal error: all goroutines are asleep - deadlock!

Issue 2: invalid recursive type

Issue 3: redeclared in this block

How did I encounter?

I was working on an experimental channel wrapper utilities library in nekomeowww/xo/exp, and I tried to discover the possibility of using generics to make the common options assignment easier and more readable by using chained calls pattern in exp/channelx/puller.go. You could see I commented out all the examples in the exp/channelx/example_test.go in commit cf486f5 just because I got stucked by the compiler error fatal error: all goroutines are asleep - deadlock! with the test package (_test suffix) included for examples. I didn't realized that the problem was came from by Golang compiler it self, just because the tests in exp/channelx/puller_test.go can be run successfully and without any problem until now.

How do I think?

TL;DR: It behaves confusingly for users to understand what's going on. At least it jammed me for a while. And I think it should be fixed or addressed by the compiler or documentation.

Even though I could understand the limitations of the current implementation for generics and the "should avoid" with recursive types, but still, I think this is a issue that either Golang team needs to decide whether the compiler or documentation should address when user attempts to do so or Golang team fixes such issue and turns it into the expected way.

Especially it runs successfully without generating the needed assembly codes, and ran successfully when you change the package of main_test.go into recursive_generic_type_issue_reproduction without the _test suffix while developing. Imaging you as being a Golang developer, might only find out what has been wrong after you released the library without the _test test packages test included and caused the compiler issue and complains for all your users, as I stated out in disappeared deadlock error when using generics without test package (_test suffix) case.

Workaround?

Such unexpected behavior could be resolved by GOEXPERIMENT=nounified flag1 and it is rarely reported (or even nobody have mentioned so far and so detailed).

Footnotes

  1. cmd/compile: failed to compile some recursive generic type · Issue #54535 · golang/go

About

This repository showed how to reproduce the compiler unexpected behavior, or issue, bug when embedding a struct that has a field to reference the outer struct by using generic recursively

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages