v0.12.0: Rust 2024 edition migration

- edition = "2024" bump.
- FFI block in src/scsi/macos.rs wrapped in `unsafe extern "C" { }`.
- vtable_fn body gets an explicit unsafe block (unsafe_op_in_unsafe_fn).
- Match-ergonomics cleanup in mux/meta.rs, mkvstream.rs, network.rs,
  stdio.rs — removed redundant `ref` / `ref mut` bindings.

MSRV unchanged at 1.86. 226 tests pass. No behavior change.
This commit is contained in:
MattJackson
2026-04-24 12:07:05 -07:00
parent bd5b7795bd
commit 84f6baba38
7 changed files with 33 additions and 12 deletions
+12
View File
@@ -1,5 +1,17 @@
# Changelog # Changelog
## 0.12.0 (2026-04-24)
### Rust 2024 edition migration
- Bumped `edition = "2024"`. Required code changes:
- FFI declarations in `src/scsi/macos.rs` wrapped in `unsafe extern "C" { … }` per the 2024 FFI safety rules.
- `unsafe_op_in_unsafe_fn` lint: `vtable_fn()` body now has an explicit `unsafe { … }` block rather than relying on implicit unsafe of the containing `unsafe fn`.
- Match-ergonomics: removed redundant `ref`/`ref mut` bindings in `mux/meta.rs`, `mux/mkvstream.rs`, `mux/network.rs`, `mux/stdio.rs` — 2024 tightens "cannot explicitly borrow within an implicitly-borrowing pattern."
- No behavior change. MSRV stays at 1.86.
### Minor / version sync
- Part of the 0.12.0 ecosystem release. The autorip-side fixes (progress regressions, UI redesign, regression-guard tests) drove the minor bump.
## 0.11.22 (2026-04-24) ## 0.11.22 (2026-04-24)
### Version sync — no functional changes ### Version sync — no functional changes
+2 -2
View File
@@ -1,7 +1,7 @@
[package] [package]
name = "libfreemkv" name = "libfreemkv"
version = "0.11.22" version = "0.12.0"
edition = "2021" edition = "2024"
rust-version = "1.86" rust-version = "1.86"
license = "AGPL-3.0-only" license = "AGPL-3.0-only"
description = "Open source raw disc access library for optical drives" description = "Open source raw disc access library for optical drives"
+1 -1
View File
@@ -211,7 +211,7 @@ impl M2tsMeta {
.iter() .iter()
.map(|s| { .map(|s| {
if let MetaStream::Video { if let MetaStream::Video {
codec_private: Some(ref b64), codec_private: Some(b64),
.. ..
} = s } = s
{ {
+3 -3
View File
@@ -150,9 +150,9 @@ impl crate::pes::Stream for MkvStream {
fn write(&mut self, frame: &crate::pes::PesFrame) -> io::Result<()> { fn write(&mut self, frame: &crate::pes::PesFrame) -> io::Result<()> {
match &mut self.mode { match &mut self.mode {
Mode::Write { Mode::Write { muxer: Some(m) } => {
muxer: Some(ref mut m), m.write_frame(frame.track, frame.pts, frame.keyframe, &frame.data)
} => m.write_frame(frame.track, frame.pts, frame.keyframe, &frame.data), }
Mode::Write { muxer: None } => Ok(()), Mode::Write { muxer: None } => Ok(()),
Mode::Read(_) => Err(crate::error::Error::StreamReadOnly.into()), Mode::Read(_) => Err(crate::error::Error::StreamReadOnly.into()),
} }
+1 -1
View File
@@ -81,7 +81,7 @@ impl crate::pes::Stream for NetworkStream {
match &mut self.mode { match &mut self.mode {
Mode::Write { Mode::Write {
writer, writer,
ref mut header_written, header_written,
.. ..
} => { } => {
if !*header_written { if !*header_written {
+1 -1
View File
@@ -70,7 +70,7 @@ impl crate::pes::Stream for StdioStream {
} }
fn write(&mut self, frame: &crate::pes::PesFrame) -> io::Result<()> { fn write(&mut self, frame: &crate::pes::PesFrame) -> io::Result<()> {
match &mut self.writer { match &mut self.writer {
Some(ref mut w) => { Some(w) => {
if !self.header_written { if !self.header_written {
if !self.disc_title.streams.is_empty() { if !self.disc_title.streams.is_empty() {
let m = meta::M2tsMeta::from_title(&self.disc_title); let m = meta::M2tsMeta::from_title(&self.disc_title);
+13 -4
View File
@@ -63,7 +63,8 @@ struct SCSITaskSGElement {
// ── External IOKit / CoreFoundation functions ─────────────────────────────── // ── External IOKit / CoreFoundation functions ───────────────────────────────
extern "C" { // Rust 2024: FFI blocks declaring extern fns must be `unsafe extern`.
unsafe extern "C" {
fn IOMasterPort(bootstrap: u32, master: *mut MachPort) -> IOReturn; fn IOMasterPort(bootstrap: u32, master: *mut MachPort) -> IOReturn;
fn IOBSDNameMatching( fn IOBSDNameMatching(
master: MachPort, master: MachPort,
@@ -97,10 +98,18 @@ extern "C" {
// IOSCSIArchitectureModelFamily/UserClientLib/SCSITaskLib.h // IOSCSIArchitectureModelFamily/UserClientLib/SCSITaskLib.h
/// Read a function pointer from a COM vtable at the given index. /// Read a function pointer from a COM vtable at the given index.
///
/// # Safety
/// `iface` must be a valid COM interface pointer (*mut *mut c_void), and
/// `index` must be a valid vtable slot for the target type `T`.
unsafe fn vtable_fn<T>(iface: ComRef, index: usize) -> T { unsafe fn vtable_fn<T>(iface: ComRef, index: usize) -> T {
let vtable = *iface as *const *const std::ffi::c_void; // Rust 2024: `unsafe fn` bodies are no longer implicitly unsafe.
let fn_ptr = *vtable.add(index); // Each unsafe op needs its own `unsafe { }` block.
std::mem::transmute_copy(&fn_ptr) unsafe {
let vtable = *iface as *const *const std::ffi::c_void;
let fn_ptr = *vtable.add(index);
std::mem::transmute_copy(&fn_ptr)
}
} }
/// Call Release (vtable index 3) on any COM interface. /// Call Release (vtable index 3) on any COM interface.