Skip to content

fix: build with rustc 1.81 (MSRV lock, stable APIs, deflate64 patch) - #4

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:mainfrom
add-uos:fix-rustc-1-81-compat
Sep 16, 2026
Merged

deepin-bot[bot] merged 1 commit into
linuxdeepin:mainfrom
add-uos:fix-rustc-1-81-compat

Conversation

@add-uos

@add-uos add-uos commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

背景 / Background

UOS 各架构构建机(loongarch64 / mips64el / aarch64 / sw_64)使用发行版 rustc/cargo 1.81 工具链,当前代码与依赖图无法在 1.81 下构建,导致 OFD 支持无法在这些架构上打包。

变更 / Changes

  1. 源码等价替换 4 个文件中 1.81 不可用的 API(均为 1.81 之后才稳定的):
    • is_none_ormap_or(true, …)(crates/rofd-core/src/paint.rs、crates/rofd-render/src/cairo_renderer.rs)
    • is_multiple_of% != 0(crates/rofd-core/src/error.rs)
    • repeat_nrepeat().take()(crates/rofd-core/src/reader.rs)
  2. MSRV 声明[workspace.package] 增加 rust-version = "1.81",后续若引入更高 MSRV 的 API/依赖,cargo 会在解析期给出明确报错,防止无意识回归
  3. Cargo.lock 重生成:以 CARGO_RESOLVER_INCOMPATIBLE_RUST_VERSIONS=fallback 在 1.98 下重解析,56 项 >1.81 的依赖降级(toml 1.1.5→1.0.7、time 0.3.55→0.3.44、image 0.25.10→0.25.6 及传递链)。注:原 lock 中 toml 1.1.5 → serde_spanned 1.1.1 使用 edition2024,cargo 1.81 连清单都无法解析,lock 重解析是硬前提
  4. patches/deflate64:deflate64 0.1.12 在 stable <1.87 的 rustc 上编译失败(input_buffer.rs:21 使用 1.87 才稳定的 unbounded_shr)。根包 bin 自带的 zip = "2.2.2"(默认 features)会把 deflate64 拉入构建图,cargo build -p rofd(deb 打包路径)必然编译它。补丁将 (!0u32).unbounded_shr(n) 替换为语义等价的 (!0u32).checked_shr(n).unwrap_or(0),经 [patch.crates-io] 生效

验证 / Verification

架构 rustc 结果
x86_64 1.81 cargo check --release --workspace ✅;dpkg-buildpackage 产出 rofd / librofd-ffi0 / librofd-ffi-dev ✅
loongarch64 1.81(发行版) deb 打包 ✅;OFD GTest 59/59 ✅
mips64el 1.81(发行版) deb 打包 ✅;OFD GTest 59/59 ✅
aarch64 1.81(发行版) deb 打包 ✅

备注

  • deflate64 0.1.0–0.1.12 全系列未声明 rust-version,且 0.1.12 无条件使用 1.87 才稳定的 API,stable <1.87 用户全中招,计划向上游报告
  • 备选方案:根 bin 的 zip = "2.2.2" 改为 zip.workspace = true 可让 deflate64 彻底离开构建图,但会改变 bin 的 zip feature 语义,故采用无语义变化的 patch 方案

Summary by Sourcery

Make the project buildable and packageable with the Rust 1.81 toolchain used by supported distribution build hosts.

Bug Fixes:

  • Restore compatibility with rustc 1.81 by replacing newer-than-MSRV standard-library APIs and pinning dependency resolution to versions that can be parsed and built by the supported toolchain.
  • Prevent builds on older stable compilers from failing through the deflate64 dependency by applying a local compatibility patch.

Enhancements:

  • Declare Rust 1.81 as the workspace minimum supported version so incompatible APIs and dependencies are detected during Cargo resolution.

Build:

  • Regenerate Cargo.lock using Rust-version-aware dependency resolution and downgrade incompatible dependency versions.

Tests:

  • Validate workspace checks and Debian packaging across x86_64, loongarch64, mips64el, and aarch64 with rustc 1.81, including OFD test coverage on supported architectures.

- declare rust-version = 1.81 across workspace, re-resolve lockfile
  (toml 1.0.7+spec, time 0.3.44, image 0.25.6 stay 1.81-compatible)
- replace 1.82+ APIs: is_none_or -> map_or(true, ..) (rofd-core/paint,
  rofd-render/cairo_renderer), is_multiple_of -> % != 0 (rofd-ffi/error),
  iter::repeat_n -> repeat().take() (rofd reader)
- patch deflate64 0.1.12: nightly unbounded_shr -> stable checked_shr
  via [patch.crates-io] path dependency (patches/deflate64)

Verified: cargo +1.81 check --release --workspace; dpkg-buildpackage
on x86_64 (local), loongarch64 (10.8.12.56), mips64el (10.8.12.58).
@sourcery-ai

sourcery-ai Bot commented Sep 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR makes the workspace buildable with rustc/Cargo 1.81 by removing newer standard-library APIs, declaring and lock-resolving against the 1.81 MSRV, and locally patching deflate64 to remove its newer compiler intrinsic while preserving the root binary’s zip feature behavior.

Flow diagram for the MSRV-compatible dependency resolution

flowchart TD
    Start[Build workspace with Rust 1.81]
    Declare[Declare rust-version 1.81]
    Resolve[Cargo resolves dependencies with fallback]
    Downgrade[Select dependency versions compatible with 1.81]
    Patch[Apply crates.io patch for deflate64]
    Build[Compile workspace and Debian targets]
    Success[Build succeeds across supported architectures]

    Start --> Declare --> Resolve --> Downgrade --> Patch --> Build --> Success
Loading

File-Level Changes

Change Details Files
Replaced post-1.81 Rust APIs with equivalent constructs.
  • Rewrote optional-value, alignment, iterator-repeat, and overflow-check expressions using Rust 1.81-compatible APIs.
  • Preserved existing parsing, rendering, FFI validation, and snippet-matching behavior.
crates/rofd-core/src/paint.rs
crates/rofd-core/src/reader.rs
crates/rofd-ffi/src/error.rs
crates/rofd-render/src/cairo_renderer.rs
src/bin/rofd/reader.rs
Declared and enforced Rust 1.81 as the workspace MSRV.
  • Added the workspace rust-version and propagated it to workspace packages.
  • Regenerated the lockfile with incompatible Rust-version fallback, including dependency downgrades needed for Cargo 1.81 manifest parsing.
Cargo.toml
crates/rofd-core/Cargo.toml
crates/rofd-ffi/Cargo.toml
crates/rofd-render/Cargo.toml
Cargo.lock
Vendored a patched deflate64 dependency for stable Rust 1.81 builds.
  • Added a crates.io patch pointing deflate64 to a local 0.1.12 source copy.
  • Replaced the unavailable unbounded_shr call with checked_shr(...).unwrap_or(0), retaining the original shift semantics.
  • Included the vendored crate metadata and source required for Cargo to build the dependency pulled by the root zip binary.
Cargo.toml
patches/deflate64/.cargo-ok
patches/deflate64/.cargo_vcs_info.json
patches/deflate64/.git-blame-ignore-revs
patches/deflate64/.gitignore
patches/deflate64/CHANGELOG.md
patches/deflate64/Cargo.toml
patches/deflate64/Cargo.toml.orig
patches/deflate64/LICENSE
patches/deflate64/README.md
patches/deflate64/benches/inflate.rs
patches/deflate64/src/buffer.rs
patches/deflate64/src/huffman_tree.rs
patches/deflate64/src/inflater_checkpoint.rs
patches/deflate64/src/inflater_managed.rs
patches/deflate64/src/input_buffer.rs
patches/deflate64/src/lib.rs
patches/deflate64/src/output_window.rs
patches/deflate64/src/stream.rs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="crates/rofd-ffi/src/error.rs" line_range="505-506" />
<code_context>
         }
         let start = pointer as usize;
-        if !start.is_multiple_of(alignment) {
+        if start % alignment != 0 {
             return Err(());
         }
         let end = start.checked_add(size).ok_or(())?;
</code_context>
<issue_to_address>
**issue (bug_risk):** `start % alignment` panics when `alignment` is zero, whereas `is_multiple_of(0)` returns false for a nonzero pointer and the previous code returned `Err(())`. `SlotRange::for_region` accepts the alignment value without rejecting zero.

**Triggers:** When an internal caller passes a non-null pointer with `alignment == 0`.

**Suggested fix:** Reject zero alignment before the modulo operation, or preserve the old zero-divisor behavior explicitly.

```suggestion
        if alignment == 0 || start % alignment != 0 {
            return Err(());
```
</issue_to_address>

### Comment 2
<location path="Cargo.toml" line_range="39" />
<code_context>
 resolver = "2"

 [workspace.package]
+rust-version = "1.81"
 edition = "2021"
 license = "LGPL-2.1-or-later"
</code_context>
<issue_to_address>
**nitpick:** The `ofdrw-compat` workspace member does not set `rust-version.workspace = true`, so the declared 1.81 MSRV is not enforced for that package and its dev-dependency resolution. A future API or dependency update in the compatibility tests can therefore bypass the lockfile's intended workspace-wide MSRV guard.

**Triggers:** When the compatibility-test package gains a Rust-1.82-or-newer API or dependency.

**Suggested fix:** Add `rust-version.workspace = true` to `tests/ofdrw-compat/Cargo.toml`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment on lines +505 to 506
if start % alignment != 0 {
return Err(());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): start % alignment panics when alignment is zero, whereas is_multiple_of(0) returns false for a nonzero pointer and the previous code returned Err(()). SlotRange::for_region accepts the alignment value without rejecting zero.

Triggers: When an internal caller passes a non-null pointer with alignment == 0.

Suggested fix: Reject zero alignment before the modulo operation, or preserve the old zero-divisor behavior explicitly.

Suggested change
if start % alignment != 0 {
return Err(());
if alignment == 0 || start % alignment != 0 {
return Err(());

Comment thread Cargo.toml
resolver = "2"

[workspace.package]
rust-version = "1.81"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: The ofdrw-compat workspace member does not set rust-version.workspace = true, so the declared 1.81 MSRV is not enforced for that package and its dev-dependency resolution. A future API or dependency update in the compatibility tests can therefore bypass the lockfile's intended workspace-wide MSRV guard.

Triggers: When the compatibility-test package gains a Rust-1.82-or-newer API or dependency.

Suggested fix: Add rust-version.workspace = true to tests/ofdrw-compat/Cargo.toml.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 99 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 总体评分 99 分,大于 70 分通过阈值。本次 PR 旨在使项目兼容 rustc 1.81 工具链,所有 API 替换均语义等价,无安全漏洞,代码质量优秀。

🔍 详细分析

1. 语法逻辑 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 所有 API 替换均语义正确,无需修改。建议在后续 rustc 版本升级时考虑恢复使用标准 API。


2. 代码质量 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 建议定期关注上游 deflate64 crate 是否修复了 unbounded_shr 兼容性问题,以便移除 vendored patch。


3. 代码性能 ✅

评价: 优秀 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: 无性能问题,所有替换对性能无负面影响。


4. 代码安全 🔒

评价: 优秀 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: 无安全建议,代码安全合规。


💡 改进建议代码示例

// 本次 PR 的所有 API 替换均为语义等价替换,无需额外修复代码示例
// 以下是各替换点的等价性说明:

// 1. is_none_or → map_or(true, ...)
//    Option::is_none_or(f) = match self { None => true, Some(x) => f(x) }
//    Option::map_or(true, f) = match self { None => true, Some(x) => f(x) }
//    完全等价

// 2. is_multiple_of → % != 0
//    x.is_multiple_of(y) = (x % y == 0)
//    !x.is_multiple_of(y) = (x % y != 0)
//    当 y != 0 时完全等价(align_of::<T>() >= 1)

// 3. repeat_n → repeat().take()
//    iter::repeat_n(i, n) 产生 n 个 i
//    iter::repeat(i).take(n) 产生 n 个 i
//    对 extend() 消费行为完全等价

// 4. unbounded_shr → checked_shr().unwrap_or(0)
//    u32::unbounded_shr(n) = if n >= 32 { 0 } else { self >> n }
//    u32::checked_shr(n).unwrap_or(0) = if n >= 32 { 0 } else { self >> n }
//    完全等价

本报告由 AI 代码审查工具自动生成

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: add-uos, lzwind

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@add-uos

add-uos commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot
deepin-bot Bot merged commit 201944e into linuxdeepin:main Sep 16, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants