From 24b3523414190c41576c4a9d83ee4a2023768e19 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Tue, 13 Oct 2026 19:40:07 -0400 Subject: [PATCH] Make Diagnostic::message in Rust return slice --- CHANGELOG.md | 9 ++++++++- rust/ruby-prism/src/lib.rs | 11 +++++++++++ rust/ruby-prism/src/parse_result/diagnostics.rs | 10 +++++----- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9cab65f65..c0fac11a7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,7 +57,7 @@ Note that for this major version, almost every change listed below is breaking. - Comments now live on the source. `Prism::Source#comments` returns them and `Result#comments` delegates to it, so `ParseResult.new`, `LexResult.new`, and `ParseLexResult.new` no longer take a `comments` argument. - Comment attachment now happens during parsing with the `attach_comments` option instead of afterward with `ParseResult#attach_comments!`, which was removed. `Node#comments` now returns the comments attached to the node by that option. `Location#comments`, `Location#leading_comments`, `Location#trailing_comments`, `Node#leading_comments`, `Node#trailing_comments`, and the comment fields of `Prism::Relocation` were removed. -#### C/Rust +#### C - Most structs are now opaque (except for nodes), and many internal functions have been hidden. - Locations are now represented using slices (pairs of 32-bit integers for start offset and length). @@ -65,6 +65,13 @@ Note that for this major version, almost every change listed below is breaking. - You may now build side tables of comment attachments through the `attach_comments` option. - `newline_list` was renamed to `list_offset_list`. +#### Rust + +- Locations are now represented using slices (pairs of 32-bit integers for start offset and length). +- Most allocations are now performed through an arena. +- `newline_list` was renamed to `list_offset_list`. +- `Diagnostic::message` now returns `&[u8]` instead of `&str`. + #### JavaScript - The parse method now only accepts `Uint8Array`, instead of forcing a transcoding to UTF-16. diff --git a/rust/ruby-prism/src/lib.rs b/rust/ruby-prism/src/lib.rs index 3ae8e70437..071e35d25a 100644 --- a/rust/ruby-prism/src/lib.rs +++ b/rust/ruby-prism/src/lib.rs @@ -1160,6 +1160,17 @@ end assert!(stmt.as_local_variable_read_node().is_some()); } + #[test] + fn diagnostic_message_test() { + let source = b"# encoding: shift_jis\nx = <<~\x82\xA0\n"; + let result = parse(source); + let error = result.errors().next().unwrap(); + + let message = error.message(); + assert!(std::str::from_utf8(message).is_err()); + assert!(message.windows(2).any(|window| window == b"\x82\xA0")); + } + #[test] fn malformed_shebang() { let source = "#!\x00"; diff --git a/rust/ruby-prism/src/parse_result/diagnostics.rs b/rust/ruby-prism/src/parse_result/diagnostics.rs index ba231fabb2..799a7c6513 100644 --- a/rust/ruby-prism/src/parse_result/diagnostics.rs +++ b/rust/ruby-prism/src/parse_result/diagnostics.rs @@ -18,14 +18,14 @@ pub struct Diagnostic<'pr> { impl<'pr> Diagnostic<'pr> { /// Returns the message associated with the diagnostic. /// - /// # Panics - /// - /// Panics if the message is not valid UTF-8. + /// The message is in the encoding of the source, because some messages + /// quote the source directly. It is therefore not guaranteed to be valid + /// UTF-8. #[must_use] - pub fn message(&self) -> &str { + pub fn message(&self) -> &[u8] { unsafe { let message = pm_diagnostic_message(self.raw); - CStr::from_ptr(message).to_str().expect("prism allows only UTF-8 for diagnostics.") + CStr::from_ptr(message).to_bytes() } }