async closure

unsafe in edition 2024

目前来看,Rust edition 2024 将在 unsafe Rust 相关代码上产生重大变化 (看板: https://github.com/orgs/rust-lang/projects/43 ):

  • Make unsafe_op_in_unsafe_fn warn-by-default: https://github.com/rust-lang/rust/issues/123916
  • RFC 3484: Unsafe Extern Blocks: https://github.com/rust-lang/rust/issues/123743
  • RFC 3325: unsafe attributes:https://github.com/rust-lang/rust/issues/123757
  • Disallow references to static mut:https://github.com/rust-lang/rust/issues/114447
    • static_mut_refs: Should the lint cover hidden references? https://github.com/rust-lang/rust/issues/123060

self-referential

The Inconceivable Types of Rust: How to Make Self-Borrows Safe

  • 围绕剖析 async fn 的状态机,从类型系统的角度,站在非常高级的视角审视 Rust 在自引用问题上面临的种种问题,并提出解决方案。
  • 我认为,该文章至少可以回答以下一些问题:
    • async fn 的 Future 状态机之下、跨 await 点上的各种幽暗细节是什么?
    • 从一个假想的、完整的 Rust 类型系统视角,在自引用问题上 partial move、生命周期和 Drop 的交互是什么样的?
    • 当我们在 safe Rust 中,支持零成本手写 Future 状态机的类型系统将会是什么样?
    • 是什么阻止我们以安全的方式,零成本实现自引用?
    • 如何维持 Rust 核心设计来深度拓展自引用?
  • 社区其他人对此的讨论

Ergonomic Self-Referential Types For Rust

  • 由 Rust 异步工作组成员 Yoshua Wuyts 所写 (在一定程度上表明 async Rust 的发展方向)
  • 我认为这个文章提出的设计是采用更务实(即更有可能落地)的方式支持自引用(典型应用为以安全的方式手写 Future 状态机),具体的设计(几乎每条罗列的设计都不是第一次提出,但却是第一次作为连贯的整体方案完整呈现)
    • 'self 生命周期标注,这使得表达自引用生命周期成为可能
    • super let 和 -> super Type 安全地支持 out-pointers / in-place construction
    • 新的 Move auto trait,用于管理(不)可移动操作 (包括 Move/?Move/!Move bounds) - 替换 Pin
    • 基于视图类型 (view type) 的分阶段初始化 (phased initialization,即部分初始化) - 摆脱 Option 来进行初始化

Further Simplifying Self-referential Types For Rust

  • TODO

miscellaneous

Box Is a Unique Type

Box Is a Unique Type by nilstrieb

use aliasable::boxed::AliasableBox;

fn main() {
    let b = Box::new(0);
    let b = AliasableBox::from_unique(b);
    let ptr: *const u8 = &*b;

    takes_box_and_ptr_to_it(b, ptr);
}

fn takes_box_and_ptr_to_it(mut b: AliasableBox<u8>, ptr: *const u8) { // no UB
    let value = unsafe { *ptr };
    *b = 5;
    let value2 = unsafe { *b };
    assert_ne!(value, value2);
}
fn main() {
    let b = Box::new(0);
    let ptr: *const u8 = &*b;

    takes_box_and_ptr_to_it(b, ptr);
}

fn takes_box_and_ptr_to_it(mut b: Box<u8>, ptr: *const u8) { // UB
    let value = unsafe { *ptr };
    *b = 5;
    let value2 = unsafe { *b };
    assert_ne!(value, value2);
}

error: Undefined Behavior: attempting a read access using <2248> at alloc1032[0x0], but that tag does not exist in the borrow stack for this location
  --> src/main.rs:13:26
   |
13 |     let value = unsafe { *ptr };
   |                          ^^^^
   |                          |
   |                          attempting a read access using <2248> at alloc1032[0x0], but that tag does not exist in the borrow stack for this location
   |                          this error occurs as part of an access at alloc1032[0x0..0x1]
   |
   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <2248> was created by a SharedReadOnly retag at offsets [0x0..0x1]
  --> src/main.rs:6:26
   |
6  |     let ptr: *const u8 = &*b;
   |                          ^^^
help: <2248> was later invalidated at offsets [0x0..0x1] by a Unique retag
  --> src/main.rs:8:29
   |
8  |     takes_box_and_ptr_to_it(b, ptr);
   |                             ^
   = note: BACKTRACE (of the first span):
   = note: inside `takes_box_and_ptr_to_it` at src/main.rs:13:26: 13:30
note: inside `main`
  --> src/main.rs:8:5
   |
8  |     takes_box_and_ptr_to_it(b, ptr);
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

TODO

https://blog.shrirambalaji.com/posts/resolving-rust-symbols/:解析 ELF 中的 Rust 符号

https://blog.yoshuawuyts.com/self-referential-types/