diff --git a/src/lib.rs b/src/lib.rs index 211e464..446e2bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -97,6 +97,23 @@ pub struct Z; /// Peano numbers: Increment pub struct S ( PhantomData ); + +trait Pop { + type Head; + type Tail; +} + +impl Pop for (A, B) { + type Head = A; + type Tail = (A, B); +} + +impl, N> Pop> for (A, B) { + type Head = B::Head; + type Tail = B::Tail; +} + + /// End of communication session (epsilon) #[allow(missing_copy_implementations)] pub struct Eps; @@ -312,6 +329,14 @@ impl Chan<(P, E), Var>> { } } +impl, N> Chan> { + /// Pop the environment, restoring the protocol N layers of recursion above us. + #[must_use] + pub fn pop(self) -> Chan { + Chan(self.0, self.1, PhantomData) + } +} + /// Homogeneous select. We have a vector of channels, all obeying the same /// protocol (and in the exact same point of the protocol), wait for one of them /// to receive. Removes the receiving channel from the vector and returns both @@ -370,7 +395,7 @@ pub struct ChanSelect<'c, T> { } -impl<'c, T> ChanSelect<'c, T> { +impl<'c, T: 'c> ChanSelect<'c, T> { pub fn new() -> ChanSelect<'c, T> { ChanSelect { chans: Vec::new() diff --git a/tests/pop.rs b/tests/pop.rs new file mode 100644 index 0000000..c2d1bc7 --- /dev/null +++ b/tests/pop.rs @@ -0,0 +1,15 @@ +extern crate session_types; +use session_types::*; + +fn client(n: u64, mut c: Chan<(), Rec>>>) { + let mut c = c.enter(); + c = c.send(n).pop(); // type should remain the same, test will fail if it cannot compile +} + +fn client2(n: u64, mut c: Chan<(), Rec>>>>>>) { + let mut c = c.enter(); + c = c.send(n).enter().send(n).pop(); // type should remain the same, test will fail if it cannot compile +} + +#[test] +fn main() {} \ No newline at end of file