Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) a

## [Unreleased]

### Added

- Add `Version::CRuby4_0` to the Rust bindings. `Version::CRuby3_5` remains available but is deprecated in favor of the new name; both select Ruby 4.0 syntax.

## [2.0.0] - 2026-10-21

### Highlights
Expand Down
38 changes: 35 additions & 3 deletions rust/ruby-prism/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ pub enum Version {
CRuby3_3,
/// The vendored version of prism in `CRuby` 3.4.x.
CRuby3_4,
/// The vendored version of prism in `CRuby` 3.5.x / 4.0.x.
/// The vendored version of prism in `CRuby` 4.0.x, formerly known as 3.5.x.
#[deprecated(note = "Use Version::CRuby4_0 instead")]
CRuby3_5,
/// The vendored version of prism in `CRuby` 4.0.x.
CRuby4_0,
/// The vendored version of prism in `CRuby` 4.1.x.
CRuby4_1,
}
Expand All @@ -63,8 +66,9 @@ impl Version {
Self::CRuby3_4 => {
pm_options_version_set(opts, c"3.4".as_ptr(), 3);
},
Self::CRuby3_5 => {
pm_options_version_set(opts, c"3.5".as_ptr(), 3);
#[allow(deprecated)]
Self::CRuby3_5 | Self::CRuby4_0 => {
pm_options_version_set(opts, c"4.0".as_ptr(), 3);
},
Self::CRuby4_1 => {
pm_options_version_set(opts, c"4.1".as_ptr(), 3);
Expand Down Expand Up @@ -1148,6 +1152,34 @@ end
assert!(result.errors().next().is_none());
}

#[test]
#[allow(deprecated)]
fn parse_with_options_cruby4_0_test() {
use super::{parse_with_options, Options, Version};

let source = b"private def foo = puts 'Hello'";
let newer_source = b"def foo(&nil); end";

for version in [Version::CRuby4_0, Version::CRuby3_5] {
let options = Options::default().version(version).build();
let result = parse_with_options(source, &options);
assert!(result.errors().next().is_none());

let call = result.node().as_program_node().unwrap().statements().body().first().unwrap().as_call_node().unwrap();
assert_eq!(call.name().as_slice(), b"private");
let method = call.arguments().unwrap().arguments().first().unwrap().as_def_node().unwrap();
assert_eq!(method.name().as_slice(), b"foo");

assert!(parse_with_options(newer_source, &options).errors().next().is_some());
}

let earlier_options = Options::default().version(Version::CRuby3_4).build();
assert!(parse_with_options(source, &earlier_options).errors().next().is_some());

let later_options = Options::default().version(Version::CRuby4_1).build();
assert!(parse_with_options(newer_source, &later_options).errors().next().is_none());
}

#[test]
fn parse_with_options_default_line_test() {
use super::{parse_with_options, Options};
Expand Down
Loading