diff options
author | Yureka <tvl@yuka.dev> | 2024-07-21T11·23+0200 |
---|---|---|
committer | yuka <tvl@yuka.dev> | 2024-07-21T13·20+0000 |
commit | a805a80b48a0ae9c275e2ce26d4a22d89a94155c (patch) | |
tree | eb9ac5c90b3749c3ef1390484ce3c7adfe14b56d | |
parent | ba38883a4fd27cb28820997f464c2289905bd5a5 (diff) |
fix(tvix/composition): include typeid in recursion check r/8388
Change-Id: Icc279d41a4980d4b57acbb4243bbd509039b753f Reviewed-on: https://cl.tvl.fyi/c/depot/+/12000 Reviewed-by: flokli <flokli@flokli.de> Tested-by: BuildkiteCI
-rw-r--r-- | tvix/castore/src/composition.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/tvix/castore/src/composition.rs b/tvix/castore/src/composition.rs index daa8a5008a04..1ff7e1b5bed8 100644 --- a/tvix/castore/src/composition.rs +++ b/tvix/castore/src/composition.rs @@ -274,7 +274,7 @@ pub fn add_default_services(reg: &mut Registry) { } pub struct CompositionContext<'a> { - stack: Vec<String>, + stack: Vec<(TypeId, String)>, composition: Option<&'a Composition>, } @@ -291,8 +291,14 @@ impl<'a> CompositionContext<'a> { entrypoint: String, ) -> Result<Arc<T>, Box<dyn std::error::Error + Send + Sync + 'static>> { // disallow recursion - if self.stack.contains(&entrypoint) { - return Err(CompositionError::Recursion(self.stack.clone()).into()); + if self + .stack + .contains(&(TypeId::of::<T>(), entrypoint.clone())) + { + return Err(CompositionError::Recursion( + self.stack.iter().map(|(_, n)| n.clone()).collect(), + ) + .into()); } match self.composition { Some(comp) => Ok(comp.build_internal(self.stack.clone(), entrypoint).await?), @@ -390,7 +396,7 @@ impl Composition { fn build_internal<T: ?Sized + Send + Sync + 'static>( &self, - stack: Vec<String>, + stack: Vec<(TypeId, String)>, entrypoint: String, ) -> BoxFuture<'_, Result<Arc<T>, CompositionError>> { let mut stores = self.stores.lock().unwrap(); @@ -422,7 +428,9 @@ impl Composition { stack: stack.clone(), composition: Some(self), }; - new_context.stack.push(entrypoint.clone()); + new_context + .stack + .push((TypeId::of::<T>(), entrypoint.clone())); let res = config .build(&entrypoint, &new_context) .await |