From 74f33a8d2739e54c706ea6825f0a5343e3935e2a Mon Sep 17 00:00:00 2001 From: Adrian Keet Date: Wed, 21 May 2025 00:23:36 -0700 Subject: [PATCH] Remove unsafe lifetime transmute in vt::Stream. Meanwhile, make input::Stream an actual Iterator. --- src/input.rs | 11 ++++++----- src/vt.rs | 17 +++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/input.rs b/src/input.rs index 56e16761607c..6082a7cdfbda 100644 --- a/src/input.rs +++ b/src/input.rs @@ -302,16 +302,15 @@ impl Parser { } /// An iterator that parses VT sequences into input events. -/// -/// Can't implement [`Iterator`], because this is a "lending iterator". pub struct Stream<'parser, 'vt, 'input> { parser: &'parser mut Parser, stream: vt::Stream<'vt, 'input>, } -impl<'input> Stream<'_, '_, 'input> { - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option> { +impl<'input> Iterator for Stream<'_, '_, 'input> { + type Item = Input<'input>; + + fn next(&mut self) -> Option> { loop { if self.parser.bracketed_paste { return self.handle_bracketed_paste(); @@ -489,7 +488,9 @@ impl<'input> Stream<'_, '_, 'input> { } } } +} +impl<'input> Stream<'_, '_, 'input> { /// Once we encounter the start of a bracketed paste /// we seek to the end of the paste in this function. /// diff --git a/src/vt.rs b/src/vt.rs index 31701c08728e..c047576f0b81 100644 --- a/src/vt.rs +++ b/src/vt.rs @@ -3,7 +3,7 @@ //! Our VT parser. -use std::{mem, time}; +use std::time; use crate::simd::memchr2; @@ -114,7 +114,7 @@ pub struct Stream<'parser, 'input> { off: usize, } -impl<'parser, 'input> Stream<'parser, 'input> { +impl<'input> Stream<'_, 'input> { /// Returns the input that is being parsed. pub fn input(&self) -> &'input str { self.input @@ -136,11 +136,12 @@ impl<'parser, 'input> Stream<'parser, 'input> { } /// Parses the next VT sequence from the previously given input. - #[allow(clippy::should_implement_trait)] - pub fn next(&mut self) -> Option> { - // I don't know how to tell Rust that `self.parser` and its lifetime - // `'parser` outlives `self`, and at this point I don't care. - let parser = unsafe { mem::transmute::<_, &'parser mut Parser>(&mut *self.parser) }; + #[allow( + clippy::should_implement_trait, + reason = "can't implement Iterator because this is a lending iterator" + )] + pub fn next(&mut self) -> Option> { + let parser = &mut *self.parser; let input = self.input; let bytes = input.as_bytes(); @@ -242,7 +243,7 @@ impl<'parser, 'input> Stream<'parser, 'input> { if parser.csi.param_count != 0 || parser.csi.params[0] != 0 { parser.csi.param_count += 1; } - return Some(Token::Csi(&parser.csi as &'parser Csi)); + return Some(Token::Csi(&parser.csi)); } b';' => parser.csi.param_count += 1, b'<'..=b'?' => parser.csi.private_byte = c as char,