Description
Rust currently has a few built-in traits which all basically mean "does not contain Foo". Freeze
: no &mut
, Cell
, or RefCell
. Send
: no managed or borrowed pointers. 'static
: no non-'static
borrowed pointers. Combined with the proposal to use marker types in #10834, perhaps this could be generalized to user-defined does-not-contain traits, with compiler support.
This would be useful for, for example, preventing cycles in Rc
, in the spirit of #10837 but at a semantic rather than syntactic level. You could write something like:
pub struct ReferenceCounted;
#[does_not_contain(ReferenceCounted)]
pub trait NoRc { }; // an imaginary syntax, others possible
pub struct Rc<T> {
priv val: *mut RcBox<T>,
priv marker: ReferenceCounted
}
impl<T: NoRc> Rc<T> {
pub fn new(val: T) -> Rc<T> { ... }
}
This would solve the problem of existentially quantified types the same way as the built-in traits: any existentially quantified type could only be passed to this new()
if it explicitly had a NoRc
bound (e.g. ~ToStr:NoRc
). This might still be too high a burden, so there would probably be other constructors as well, as now, including a Freeze
-based and an unconstrained one, but this is still finer-grained, at least, than the current situation.
This might also help with #10869, and with another crazy idea I've been thinking about that I'm not ready to post yet.