Closed
Description
Today, we only allow you to use a trait as a type if that trait is object safe, because you cannot sanely instantiate the object unless the trait is object safe.
This is a bit odd, though! We let you implement traits for HashMap<f32, _>
, even though you cannot instantiate a HashMap with f32 keys.
We could limit the object safety check to two cases:
- Instantiations of these types
- Attempts to access items of these types.
trait NotObjectSafe: Sized { }
trait SomeTrait {
fn static_method();
fn non_static_method(&self);
}
impl SomeTrait for NotObjectSafe {
fn static_method() {
println!("There's no object, why isn't this allowed?");
println!("You could totally call this function just fine.");
}
fn non_static_method(&self) {
println!("You could just never instantiate the object.");
println!("So you could never call this method.");
}
}
fn main() {
NotObjectSafe::static_method() // Never instantiated, should be fine.
}
Similarly, we could allow you to omit associated types from the receiver of such impls (e.g. impl for Iterator
, without specifying an item).
I actually have a motivating use case for this: I have types which are parameterized by a trait, which is used solely for static dispatch. The trait is never actually instantiated as an object, and making it object safe is very limiting.