From: Emilie Burgun Date: Mon, 3 Feb 2025 13:26:33 +0000 (+0100) Subject: Fix realiased streams causing close/1 to leave a dangling stream X-Git-Tag: v0.10.0~74^2~3 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=949d316773906807c1d9a07891411f66d72c62e5;p=scryer-prolog.git Fix realiased streams causing close/1 to leave a dangling stream --- diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 3432fadc..ca348a0e 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -640,7 +640,7 @@ impl Stream { } } - pub fn options_mut(&mut self) -> &mut StreamOptions { + pub(super) fn options_mut(&mut self) -> &mut StreamOptions { match self { Stream::Byte(ref mut ptr) => &mut ptr.options, Stream::InputFile(ref mut ptr) => &mut ptr.options, @@ -1946,4 +1946,24 @@ mod test { assert_eq!(results.len(), 1); assert!(results[0].is_ok()); } + + #[test] + #[cfg_attr(miri, ignore)] + fn close_realiased_stream() { + let mut machine = MachineBuilder::new().build(); + + let results = machine + .run_query(r#" + \+ \+ ( + open("README.md", read, S, [alias(readme)]), + open(stream(S), read, _, [alias(another_alias)]), + close(S) + ), + open("README.md", read, _, [alias(readme)]). + "#) + .collect::>(); + + assert_eq!(results.len(), 1); + assert!(results[0].is_ok()); + } } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 2b05b8f0..50c28549 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -5162,7 +5162,7 @@ impl Machine { #[inline(always)] pub(crate) fn set_stream_options(&mut self) -> CallResult { - let mut stream = self.machine_st.get_stream_or_alias( + let stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, atom!("open"), @@ -5174,10 +5174,12 @@ impl Machine { let reposition = self.machine_st.registers[4]; let stream_type = self.machine_st.registers[5]; - let options = + let new_options = self.machine_st .get_stream_options(alias, eof_action, reposition, stream_type); - *stream.options_mut() = options; + self.indices.update_stream_options(stream, |options| { + *options = new_options; + }); Ok(()) }