diff --git a/tamer/src/asg/graph/object/expr.rs b/tamer/src/asg/graph/object/expr.rs index 683f9ddf..5c79aa1e 100644 --- a/tamer/src/asg/graph/object/expr.rs +++ b/tamer/src/asg/graph/object/expr.rs @@ -28,7 +28,7 @@ //! program. use super::{prelude::*, Doc, Ident, ObjectIndexToTree, Tpl}; -use crate::{f::Map, num::Dim, span::Span}; +use crate::{num::Dim, span::Span}; use std::fmt::Display; #[cfg(doc)] @@ -68,15 +68,8 @@ impl Expr { } } -impl Map for Expr { - fn map(self, f: impl FnOnce(Span) -> Span) -> Self { - match self { - Self { span, .. } => Self { - span: f(span), - ..self - }, - } - } +impl_mono_map! { + Span => Expr { span, .. }, } impl From<&Expr> for Span { diff --git a/tamer/src/f.rs b/tamer/src/f.rs index 06e22db8..04f8f8f3 100644 --- a/tamer/src/f.rs +++ b/tamer/src/f.rs @@ -251,7 +251,43 @@ macro_rules! impl_mono_map { } } )+ - } + }; + + ($($t:ty => $tup:ident{ $field:ident, .. },)+) => { + $( + impl $crate::f::TryMap<$t> for $tup { + fn try_map( + self, + f: impl FnOnce($t) -> Self::FnResult, + ) -> Self::Result { + match self { + Self{ $field: x, .. } => match f(x) { + Ok(y) => Ok(Self{ $field: y, ..self }), + Err((y, e)) => Err(( + Self { $field: y, ..self }, + e, + )), + }, + } + } + } + + impl $crate::f::Map<$t> for $tup { + fn map(self, f: impl FnOnce($t) -> $t) -> Self::Target { + use std::convert::Infallible; + use $crate::f::TryMap; + + // `unwrap()` requires `E: Debug`, + // so this avoids that bound. + match self.try_map::(|x| Ok(f(x))) { + Ok(y) => y, + // Verbosely emphasize unreachability + Err::<_, (_, Infallible)>(_) => unreachable!(), + } + } + } + )+ + }; } /// A nullary [`Fn`] delaying some computation.