4 个稳定版本

1.2.1 2020 年 5 月 13 日
1.2.0 2020 年 4 月 25 日
1.1.1 2020 年 4 月 11 日
1.1.0 2020 年 2 月 22 日
1.0.0 2020 年 1 月 31 日

#4 in #type-erasure

Download history 6613/week @ 2023-11-24 8439/week @ 2023-12-01 8235/week @ 2023-12-08 6169/week @ 2023-12-15 6471/week @ 2023-12-22 6209/week @ 2023-12-29 8662/week @ 2024-01-05 9935/week @ 2024-01-12 11042/week @ 2024-01-19 11230/week @ 2024-01-26 9806/week @ 2024-02-02 10939/week @ 2024-02-09 10205/week @ 2024-02-16 9565/week @ 2024-02-23 7961/week @ 2024-03-01 4542/week @ 2024-03-08

34,299 每月下载量
71 crate 中使用 (直接使用 8 个)

MIT/Apache

32KB
425

擦除具有具体类型的指针并存储类型擦除的指针。

这大致相当于 C 中的 void*,但它不使用 libc::c_void

在 Rust 中类型擦除指针有两个主要的有用原因

  • 从内部实现细节中移除病毒式泛型。如果内部实现确实不关心存储的类型,将其作为不可知处理可以减少作者和编译器的单态化成本。
  • 指向 ?Sized 类型的瘦指针。如果未指定类型存储其元数据内联,则它可以实现 Erasable 并在类型擦除指针后使用。类型擦除的指针不必携带元数据,而胖指针可以从内联元数据中恢复。我们提供了 Thin 包装类型以提供瘦指针类型。

变更列表

1.2.0

新增

  • impl ErasablePtr for Thin<P>:明显的实现;Thin 在内部被擦除
  • Thin::ptr_eq:轻松比较两个瘦指针的指针相等性

1.1.0

破坏性更改

不幸的是,在 Erasable::unerase 对实现者的要求中发现了一个微妙的问题,并且需要在本次版本中纠正。

始终的意图是,任何来源的指针都应该通过 Erasable::erase/unerase 进行往返,而不影响任何指针的来源有效性。不幸的是,在 1.0.0 版本中,Eraseable::unerase 的实现中明确建议使用临时共享引用(&_),这并不符合期望的语义。以下是 Eraseable::unerase 的新文档的引用

不应创建对指针指向对象的任何引用,因为它们的存在本身可能会影响其他指向同一位置的指针的有效性和可追溯性。

表面上创建共享引用看起来应该是可以的。毕竟,你有一个指向你类型的已知有效指针,你可以从被擦除的任何指针那里借用。然而,面对具有共享可变来源的原始指针,这会带来问题。如果写入指针指向的位置与任何 unerase 调用发生竞争,并且它创建了一个对位置的引用,那么在共享引用后面进行写入将产生未定义的行为。

根本问题是可能存在外部同步,这种实现无法知晓。此特质的实现必须只读取重新类型化指针所需的最小数据量,并且必须使用原始指针读取,或者,如果存在已知的 UnsafeCell 指针(例如原子),则必须引用该 UnsafeCell 指针和该 UnsafeCell 指针的安全 API。

有关此问题的发现更多信息,请参阅 此 Twitter 线程

为了使此更新更容易,我们还添加了 const Erasable::ACK_1_1_0: bool。此值默认为 false,但 必须Erasable 的新实现中将它覆盖为 true,以明确承认新的要求。为了找到没有这样做的方法,可以将 ERASABLE_ENFORCE_1_1_0_SEMANTICS 环境变量设置为删除默认实现,明确破坏未覆盖其值的任何实现者。

如果你有使用 unerase 的用例,如果 unerase 创建共享引用,就会变得不安全,那么建议断言 ACK_1_1_0 的值,以防止创建共享引用的旧实现。此外,请告诉我它是如何使用的,因为我无法构造出一个合理的示例,该示例会受到这个漏洞的影响,而只是一个理论上的攻击向量。同样,如果你能证明这不是必需的,请与我联系。如果最终发现这根本不是必需的,我很乐意删除这个修补程序(但我认为我有信心排除这种可能性)。

  • ptr-union: 指针大小为指针的指针联合。
  • rc-borrow: RcArc 的借用形式。
  • rc-box: 已知的 RcArc 的唯一形式。
  • slice-dst: 支持自定义基于切片的 DST。

支持的最小 Rust 版本

我们需要的最小 Rust 版本是 1.41.0。这是为了调整局部特质的实现检查。

由于依赖关系的处理方式,仅保证使用最小版本解析时(-Z 最小-versions/--minimal-versions)的最小版本支持。Rust的最小版本将仅随着小版本号的提升而增加,而不是补丁版本号的提升,并且在变更说明中会明确指出。

许可证

根据您的选择,许可协议为以下之一

如果您是任何一家将利润置于人之上、重视利润的公司的高薪工作者,您仍然可以使用这个crate。我只是希望您会联合起来,抵制您所在工作场所对增长的痴迷、对控制的追求和对权力的滥用。请站起来反对他们强加给您的低薪同事的恶劣工作条件,以及他们对那些他们声称要为之奋斗的人权的普遍不尊重。

贡献

除非您明确声明,否则您根据Apache-2.0许可证定义的任何有意提交以包含在作品中的贡献,都应如上所述的双重许可,不附加任何额外条款或条件。

依赖项

~18KB