I've been working on what is essentially this proposal, which I came up with independently (and other people have come up with very similar things too). My early version of it is in this blog post. There's certainly room for improvement for the syntax (my placeholder syntax there is pretty ugly and probably a more ergonomic syntax should be selected before stablising it), but getting the semantics right is hard enough as it is.
I do think that something like this is extremely important; basically every Rust program I've ever written would benefit from it (and the lack of this sort of feature in Rust is actually making me seriously consider changing to a different language). In particular, Rust would greatly benefit from the ability to statically prove that programs cannot panic (as this would guarantee the absence of certain types of bugs, just like the memory safety does), but there are lots of situations where you need a type system feature like this to prove the absence of panics. As you mention, allocators are also a significant use case (programs are most efficient if they use special-purpose local allocators for just about everything, but you need a feature like this to be able to write code using such allocators without memory bloat and without unsafe).
There are a few significant obstacles. As you mentioned in your post (and I mentioned in mine), one of them is dyn. There are some subtle requirements for mixing dyn with this sort of generic to even be sound. (Notably, the variable has to be Sync (assuming that the type of the dyn references it rather than copying a value); this is because existing unsafe code, including in the standard library, assumes that it is sound to send a lifetime from one thread to another, in the sense of "if you have a reference to a Sync value with lifetime 'a on thread 1 you can reborrow it as a reference to a Sync value with lifetime 'a on thread 2", but this would not be true if you could create a non-Sync generic variable.) Actually implementing such a dyn is also nontrivial, because the dyn metadata ends up changing in size as you add more of these generics into it; there is a fairly simple solution by allocating memory, and a much more complicated solution that involves a whole-program analysis, neither of which is really ideal. (All this said, I consider this feature important enough that I would rather use a Rust without dyn rather than a Rust without this feature.)
Another problem is related to how the type captures the variable (which I don't think you mentioned in your proposal?). Capturing it by shared reference is by far the simplest case: it gives you useful guarantees (that the captured variable won't change in ways other than would be possible through a shared reference), it doesn't put a significant burden on the type checker because shared references are Copy, and it is powerful enough to do a lot of useful things. There have been various suggestions by other people to capture it in other ways (e.g. I was experimenting with allowing captures by mutable reference), but they're both harder to type-check than they look and less useful than they look. (In particular, if you have a mutable reference to something you can swap that thing out, so you end up with no useful guarantees from the type system. You end up being able to implement Cell in safe code, but it isn't useful for implementing anything other than cells.) As such, I would definitely recommend sticking with shared-reference capture, at least initially.
I'm also interested in the theoretical basis, and relationship to other features. Lifetimes are a special case of this feature (a lifetime 'a is equivalent to a variable of type () captured in a generic, except that lifetimes support variance, and for simplicity, variables captured in generics are generally taken not to). It's been commonly proposed to let people pass in their own trait implementations to generic functions (i.e. calling a fn foo<T: Trait>(&T) with a T that doesn't actually implement Trait, by providing an implementation of Trait for T in a generic-like way); I currently believe that that is equivalent to this feature (by providing an implementation that captures a variable as though it were an associated constant), and it can also be used to implement lifetimes (which would make sense if it's equivalent to this feature).
Some existing work, for people interested in reading more (and as a list of references that may be useful for any eventual RFC):
For Rust:
Prior art in other languages:
Other related posts: