Tipos lineares e lógica de separação são ótimos, mas podem exigir um pouco de esforço do programador. Escrever uma lista vinculada segura no Rust pode ser bastante difícil, por exemplo.
Mas há uma alternativa que requer muito menos esforço do programador, embora com garantias menos rigorosas. Um fluxo de trabalho (bastante antigo) é garantir a segurança da memória usando (geralmente uma pilha de) regiões. Usando a inferência de região, um compilador pode decidir estaticamente em qual região um dado de alocação deve entrar e desalocar a região quando ficar fora do escopo.
A inferência de região é comprovadamente segura (não pode desalocar memória acessível) e requer interferência mínima do programador, mas não é "total" (ou seja, ainda pode vazar memória, embora definitivamente seja muito melhor do que "não fazer nada"), por isso geralmente é combinada com GC na prática. oMLtonO compilador do ML Kit usa regiões para eliminar a maioria das chamadas de GC, mas ainda tem um GC, porque ainda assim vazaria memória. De acordo com alguns dos pioneiros em regiões, a inferência de região não foi realmente inventada para esse fim (foi para paralelização automática, eu acho); mas acabou que também poderia ser usado para gerenciamento de memória.
Como ponto de partida, eu diria que vá para o artigo "Implementação do cálculo λ de chamada por valor digitado usando uma pilha de regiões", de Mads Tofte e Jean-Pierre Talpin. Para mais artigos sobre inferência regional, procure outros trabalhos de M. Tofte e J.-P. Talpin, parte do trabalho de Pierre Jouvelot, bem como a série de artigos de Greg Morrisett, Mike Hicks e Dan Grossman sobre o Cyclone.