There's a feature in the works that allows specifying the never type as !
. This is not present in stable Rust, so you need to use a nightly and a feature flag:
#![feature(never_type)]
fn thing<T>() -> Option<T> {
None
}
fn main() {
thing::<!>();
}
However, this doesn't work for your case yet (this is part of the reason that it's unstable):
#![feature(never_type)]
trait NothingImplementsMe {}
fn thing<T>() -> Option<T>
where T: NothingImplementsMe,
{
None
}
fn main() {
thing::<!>();
}
error[E0277]: the trait bound `!: NothingImplementsMe` is not satisfied
--> src/main.rs:12:5
|
12 | thing::<!>();
| ^^^^^^^^^^ the trait `NothingImplementsMe` is not implemented for `!`
|
= note: required by `thing`
The very first unresolved question on the tracking issue is:
What traits should we implement for !
?
Since this feature is both unstable and doesn't do what you want, you may want to consider creating your own bespoke "bottom" type:
trait AlmostNothingImplementsMe {
fn foo();
}
struct Nope;
impl AlmostNothingImplementsMe for Nope {
fn foo() { unimplemented!() }
}
fn thing<T>() -> Option<T>
where T: AlmostNothingImplementsMe,
{
None
}
fn main() {
thing::<Nope>();
}
To improve the UX of this, I'd suggest creating a builder of some type that starts you off with the faux-bottom type:
mod nested {
pub trait AlmostNothingImplementsMe {
fn foo();
}
pub struct Nope;
impl AlmostNothingImplementsMe for Nope {
fn foo() { unimplemented!() }
}
pub fn with_value<T>(t: T) -> Option<T>
where T: AlmostNothingImplementsMe,
{
Some(t)
}
pub fn without_value() -> Option<Nope> {
None
}
}
fn main() {
nested::without_value();
}
You can see this similar pattern in crates like Hyper, although it boxes the concrete type so you don't see it from the outside.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…