diff --git a/tamer/src/asg/graph.rs b/tamer/src/asg/graph.rs index 62bd7c36..c1de4c4f 100644 --- a/tamer/src/asg/graph.rs +++ b/tamer/src/asg/graph.rs @@ -211,8 +211,8 @@ impl Asg { to_oi: ObjectIndex, ctx_span: Option, ) -> Result<(), AsgError> { - from_oi.pre_add_edge(self, to_oi, ctx_span, |asg| { - asg.graph.add_edge( + from_oi.pre_add_edge(self, to_oi, ctx_span).map(|()| { + self.graph.add_edge( from_oi.widen().into(), to_oi.into(), (from_oi.src_rel_ty(), OB::rel_ty(), ctx_span), @@ -511,14 +511,11 @@ pub trait AsgRelMut: ObjectRelatable { /// type for you. fn pre_add_edge( asg: &mut Asg, - _from_oi: ObjectIndex, - _to_oi: ObjectIndex, - _ctx_span: Option, - commit: impl FnOnce(&mut Asg), + rel: ProposedRel, ) -> Result<(), AsgError>; } -impl AsgRelMut for O { +impl AsgRelMut for OA { /// Default edge creation method for all [`ObjectKind`]s. /// /// This takes the place of a default implementation on the trait itself @@ -531,15 +528,21 @@ impl AsgRelMut for O { /// overridden for a particular edge for a particular object /// (see [`object::tpl`] as an example). default fn pre_add_edge( - asg: &mut Asg, - _from_oi: ObjectIndex, - _to_oi: ObjectIndex, - _ctx_span: Option, - commit: impl FnOnce(&mut Asg), + _asg: &mut Asg, + _rel: ProposedRel, ) -> Result<(), AsgError> { - Ok(commit(asg)) + let _ = _rel.ctx_span; // TODO: remove when used (dead_code) + Ok(()) } } +/// The relationship proposed by [`Asg::add_edge`], +/// requiring approval from [`AsgRelMut::pre_add_edge`]. +pub struct ProposedRel { + from_oi: ObjectIndex, + to_oi: ObjectIndex, + ctx_span: Option, +} + #[cfg(test)] mod test; diff --git a/tamer/src/asg/graph/object/rel.rs b/tamer/src/asg/graph/object/rel.rs index 41a7b2a8..de58be0b 100644 --- a/tamer/src/asg/graph/object/rel.rs +++ b/tamer/src/asg/graph/object/rel.rs @@ -27,7 +27,7 @@ use super::{ }; use crate::{ asg::{ - graph::{object::Tpl, AsgRelMut}, + graph::{object::Tpl, AsgRelMut, ProposedRel}, Asg, AsgError, }, f::Map, @@ -864,7 +864,6 @@ pub trait ObjectIndexRelTo: Sized + Clone + Copy { asg: &mut Asg, to_oi: ObjectIndex, ctx_span: Option, - commit: impl FnOnce(&mut Asg), ) -> Result<(), AsgError>; /// Check whether an edge exists from `self` to `to_oi`. @@ -948,14 +947,14 @@ where asg: &mut Asg, to_oi: ObjectIndex, ctx_span: Option, - commit: impl FnOnce(&mut Asg), ) -> Result<(), AsgError> { O::pre_add_edge( asg, - self.widen().must_narrow_into::(), - to_oi, - ctx_span, - commit, + ProposedRel { + from_oi: self.widen().must_narrow_into::(), + to_oi, + ctx_span, + }, ) } } @@ -976,16 +975,16 @@ impl ObjectIndexRelTo for ObjectIndexTo { asg: &mut Asg, to_oi: ObjectIndex, ctx_span: Option, - commit: impl FnOnce(&mut Asg), ) -> Result<(), AsgError> { macro_rules! pre_add_edge { ($ty:ident) => { $ty::pre_add_edge( asg, - self.widen().must_narrow_into::<$ty>(), - to_oi, - ctx_span, - commit, + ProposedRel { + from_oi: self.widen().must_narrow_into::<$ty>(), + to_oi, + ctx_span, + }, ) }; } @@ -1020,10 +1019,9 @@ impl ObjectIndexRelTo for ObjectIndexToTree { asg: &mut Asg, to_oi: ObjectIndex, ctx_span: Option, - commit: impl FnOnce(&mut Asg), ) -> Result<(), AsgError> { match self { - Self(oito) => oito.pre_add_edge(asg, to_oi, ctx_span, commit), + Self(oito) => oito.pre_add_edge(asg, to_oi, ctx_span), } } } diff --git a/tamer/src/asg/graph/object/tpl.rs b/tamer/src/asg/graph/object/tpl.rs index a1870e84..aa3f3f87 100644 --- a/tamer/src/asg/graph/object/tpl.rs +++ b/tamer/src/asg/graph/object/tpl.rs @@ -22,7 +22,7 @@ use std::fmt::Display; use super::{prelude::*, Doc, Expr, Ident}; -use crate::{f::Map, parse::util::SPair, span::Span}; +use crate::{asg::graph::ProposedRel, f::Map, parse::util::SPair, span::Span}; /// Template with associated name. #[derive(Debug, PartialEq, Eq)] @@ -220,20 +220,15 @@ object_rel! { tree Expr { fn pre_add_edge( asg: &mut Asg, - from_oi: ObjectIndex, - to_oi: ObjectIndex, - _ctx_span: Option, - commit: impl FnOnce(&mut Asg), + rel: ProposedRel, ) -> Result<(), AsgError> { - let tpl_name = from_oi.name(asg); - let span = to_oi.resolve(asg).span(); + let tpl_name = rel.from_oi.name(asg); + let span = rel.to_oi.resolve(asg).span(); - from_oi.try_map_obj_inner( + rel.from_oi.try_map_obj_inner( asg, try_adapt_to(TplShape::Expr(span), tpl_name), - )?; - - Ok(commit(asg)) + ).map(|_| ()) } }, @@ -245,23 +240,18 @@ object_rel! { tree Tpl { fn pre_add_edge( asg: &mut Asg, - from_oi: ObjectIndex, - to_oi: ObjectIndex, - _ctx_span: Option, - commit: impl FnOnce(&mut Asg), + rel: ProposedRel, ) -> Result<(), AsgError> { - let tpl_name = from_oi.name(asg); - let apply = to_oi.resolve(asg); + let tpl_name = rel.from_oi.name(asg); + let apply = rel.to_oi.resolve(asg); let apply_shape = apply .shape() .overwrite_span_if_any(apply.span()); - from_oi.try_map_obj_inner( + rel.from_oi.try_map_obj_inner( asg, try_adapt_to(apply_shape, tpl_name), - )?; - - Ok(commit(asg)) + ).map(|_| ()) } },