1. Have a constraint on T that lets you return some sort of placeholder. For example, if you've got an array of u8, maybe every read past the end of the array returns 0.
fn bar<T: Default>() -> T {
if let Some(t) = foo() {
t
} else {
eprintln!("programmer error, foo() returned None!");
Default::default()
}
}
2. Return a `Option<T>` from bar, as you describe.3. Return a `Result<T, BarError>`, where `BarError` is a struct or enum describing possible error conditions.
#[non_exhaustive]
enum BarError {
FooIsNone,
}
fn bar<T>() -> Result<T, BarError> {
if let Some(t) = foo() {
Ok(t)
} else {
eprintln!("programmer error, foo() returned None!");
Err(BarError::FooIsNone)
}
}