I managed to reduce gc insafety in my codebase to few things only: * [scram](https://nimble.directory/pkg/scram), client package (shown above) but it is actually gcsafe becaue when threads are enabled the global variable is replaced by a thread local variable * [scram](https://nimble.directory/pkg/scram), server package where no thread variable exists with multithreading. The global variable is a speg parser * [nre](https://nimble.directory/pkg/nre), regular expression in pure nim where [some procs like escapeReare not gcsafe](https://github.com/flaviut/nre/issues/25) because it uses a global regular expression * [npeg](https://nimble.directory/pkg/npeg), PEG in pure nim [generates code that is not gcsafe because it is calling callbacks without the annotation](https://github.com/zevv/npeg/issues/28)
I see two main things there: * things like regular expressions or pegs that are compiled once and reused everywhere else are subject to gc insafety because the regular expression is a global variable. In theory, the variable is allocated once at startup and will never be freed. using `const` might help but it may not be always possible at in some cases it causes the compilation to fail. * callbacks are a problem too. If a library provides an API with callbacks. The API may be gcsafe in itself but the resulting code may not be gcsafe depending on the safety of the callbacks. If the API requires callbacks to be gcsafe, some users might complain that their GC unsafe code is no longer working. If the API does not requires gcsafe on callbacks, it is impossible to use it in a gcsafe context. While the code is actually compatible with both scenarios.
