small refactor of InterpResult
- don't need type alias to default type argument - `Residual` impl allows to use more std APIs (like `<[T; N]>::try_map`)
This commit is contained in:
@@ -57,6 +57,7 @@
|
||||
#![feature(sized_hierarchy)]
|
||||
#![feature(try_blocks)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![feature(try_trait_v2_residual)]
|
||||
#![feature(try_trait_v2_yeet)]
|
||||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(yeet_expr)]
|
||||
|
||||
@@ -793,36 +793,37 @@ impl Drop for Guard {
|
||||
/// We also make things panic if this type is ever implicitly dropped.
|
||||
#[derive(Debug)]
|
||||
#[must_use]
|
||||
pub struct InterpResult_<'tcx, T> {
|
||||
pub struct InterpResult<'tcx, T = ()> {
|
||||
res: Result<T, InterpErrorInfo<'tcx>>,
|
||||
guard: Guard,
|
||||
}
|
||||
|
||||
// Type alias to be able to set a default type argument.
|
||||
pub type InterpResult<'tcx, T = ()> = InterpResult_<'tcx, T>;
|
||||
|
||||
impl<'tcx, T> ops::Try for InterpResult_<'tcx, T> {
|
||||
impl<'tcx, T> ops::Try for InterpResult<'tcx, T> {
|
||||
type Output = T;
|
||||
type Residual = InterpResult_<'tcx, convert::Infallible>;
|
||||
type Residual = InterpResult<'tcx, convert::Infallible>;
|
||||
|
||||
#[inline]
|
||||
fn from_output(output: Self::Output) -> Self {
|
||||
InterpResult_::new(Ok(output))
|
||||
InterpResult::new(Ok(output))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn branch(self) -> ops::ControlFlow<Self::Residual, Self::Output> {
|
||||
match self.disarm() {
|
||||
Ok(v) => ops::ControlFlow::Continue(v),
|
||||
Err(e) => ops::ControlFlow::Break(InterpResult_::new(Err(e))),
|
||||
Err(e) => ops::ControlFlow::Break(InterpResult::new(Err(e))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> ops::FromResidual for InterpResult_<'tcx, T> {
|
||||
impl<'tcx, T> ops::Residual<T> for InterpResult<'tcx, convert::Infallible> {
|
||||
type TryType = InterpResult<'tcx, T>;
|
||||
}
|
||||
|
||||
impl<'tcx, T> ops::FromResidual for InterpResult<'tcx, T> {
|
||||
#[inline]
|
||||
#[track_caller]
|
||||
fn from_residual(residual: InterpResult_<'tcx, convert::Infallible>) -> Self {
|
||||
fn from_residual(residual: InterpResult<'tcx, convert::Infallible>) -> Self {
|
||||
match residual.disarm() {
|
||||
Err(e) => Self::new(Err(e)),
|
||||
}
|
||||
@@ -830,7 +831,7 @@ impl<'tcx, T> ops::FromResidual for InterpResult_<'tcx, T> {
|
||||
}
|
||||
|
||||
// Allow `yeet`ing `InterpError` in functions returning `InterpResult_`.
|
||||
impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult_<'tcx, T> {
|
||||
impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResult<'tcx, T> {
|
||||
#[inline]
|
||||
fn from_residual(ops::Yeet(e): ops::Yeet<InterpErrorKind<'tcx>>) -> Self {
|
||||
Self::new(Err(e.into()))
|
||||
@@ -840,7 +841,7 @@ impl<'tcx, T> ops::FromResidual<ops::Yeet<InterpErrorKind<'tcx>>> for InterpResu
|
||||
// Allow `?` on `Result<_, InterpError>` in functions returning `InterpResult_`.
|
||||
// This is useful e.g. for `option.ok_or_else(|| err_ub!(...))`.
|
||||
impl<'tcx, T, E: Into<InterpErrorInfo<'tcx>>> ops::FromResidual<Result<convert::Infallible, E>>
|
||||
for InterpResult_<'tcx, T>
|
||||
for InterpResult<'tcx, T>
|
||||
{
|
||||
#[inline]
|
||||
fn from_residual(residual: Result<convert::Infallible, E>) -> Self {
|
||||
@@ -863,7 +864,7 @@ impl<'tcx, T, V: FromIterator<T>> FromIterator<InterpResult<'tcx, T>> for Interp
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
impl<'tcx, T> InterpResult<'tcx, T> {
|
||||
#[inline(always)]
|
||||
fn new(res: Result<T, InterpErrorInfo<'tcx>>) -> Self {
|
||||
Self { res, guard: Guard }
|
||||
@@ -890,7 +891,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
|
||||
#[inline]
|
||||
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> InterpResult<'tcx, U> {
|
||||
InterpResult_::new(self.disarm().map(f))
|
||||
InterpResult::new(self.disarm().map(f))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -898,7 +899,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
self,
|
||||
f: impl FnOnce(InterpErrorInfo<'tcx>) -> InterpErrorInfo<'tcx>,
|
||||
) -> InterpResult<'tcx, T> {
|
||||
InterpResult_::new(self.disarm().map_err(f))
|
||||
InterpResult::new(self.disarm().map_err(f))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -906,7 +907,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
self,
|
||||
f: impl FnOnce(InterpErrorKind<'tcx>) -> InterpErrorKind<'tcx>,
|
||||
) -> InterpResult<'tcx, T> {
|
||||
InterpResult_::new(self.disarm().map_err(|mut e| {
|
||||
InterpResult::new(self.disarm().map_err(|mut e| {
|
||||
e.0.kind = f(e.0.kind);
|
||||
e
|
||||
}))
|
||||
@@ -914,7 +915,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
|
||||
#[inline]
|
||||
pub fn inspect_err_kind(self, f: impl FnOnce(&InterpErrorKind<'tcx>)) -> InterpResult<'tcx, T> {
|
||||
InterpResult_::new(self.disarm().inspect_err(|e| f(&e.0.kind)))
|
||||
InterpResult::new(self.disarm().inspect_err(|e| f(&e.0.kind)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -937,7 +938,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
|
||||
#[inline]
|
||||
pub fn and_then<U>(self, f: impl FnOnce(T) -> InterpResult<'tcx, U>) -> InterpResult<'tcx, U> {
|
||||
InterpResult_::new(self.disarm().and_then(|t| f(t).disarm()))
|
||||
InterpResult::new(self.disarm().and_then(|t| f(t).disarm()))
|
||||
}
|
||||
|
||||
/// Returns success if both `self` and `other` succeed, while ensuring we don't
|
||||
@@ -952,7 +953,7 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
// Discard the other error.
|
||||
drop(other.disarm());
|
||||
// Return `self`.
|
||||
InterpResult_::new(Err(e))
|
||||
InterpResult::new(Err(e))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -960,5 +961,5 @@ impl<'tcx, T> InterpResult_<'tcx, T> {
|
||||
|
||||
#[inline(always)]
|
||||
pub fn interp_ok<'tcx, T>(x: T) -> InterpResult<'tcx, T> {
|
||||
InterpResult_::new(Ok(x))
|
||||
InterpResult::new(Ok(x))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user