1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::marker::Unsize;

/// 一个 trait,指示这是一个指针或一个包装器,其中可以对指针调整大小。
///
/// 有关更多详细信息,请参见 [DST 强制 RFC][dst-coerce] 和 [关于强制的 nomicon 入口][nomicon-coerce]。
///
/// 对于内置指针类型,如果 `T: Unsize<U>` 通过从精简指针转换为胖指针,则指向 `T` 的指针将强制指向指向 `U` 的指针。
///
/// 对于自定义类型,这里的强制通过将 `Foo<T>` 强制为 `Foo<U>` 来工作 (如果存在 `CoerceUnsized<Foo<U>> for Foo<T>` 的实现)。
/// 仅当 `Foo<T>` 仅具有涉及 `T` 的单个非虚拟数据字段时,才可以写这样的 impl。
/// 如果该字段的类型为 `Bar<T>`,则必须存在 `CoerceUnsized<Bar<U>> for Bar<T>` 的实现。
/// coercion 将通过将 `Bar<T>` 字段强制转换为 `Bar<U>` 并填充 `Foo<T>` 的其余字段以创建 `Foo<U>` 来起作用。
/// 这将有效地向下钻取指针字段并将其强制。
///
/// 通常,对于智能指针,您将实现 `CoerceUnsized<Ptr<U>> for Ptr<T> where T: Unsize<U>, U: ?Sized`,并在 `T` 本身上绑定了可选的 `?Sized`。
/// 对于直接嵌入 `T` 的包装器类型 (例如 `Cell<T>` 和 `RefCell<T>`),您可以直接实现 `CoerceUnsized<Wrap<U>> for Wrap<T> where T: CoerceUnsized<U>`。
///
/// 这将使像 `Cell<Box<T>>` 这样的强制类型起作用。
///
/// [`Unsize`][unsize] 用于标记在指针后面可以强制转换为 DST 的类型。它由编译器自动实现。
///
/// [dst-coerce]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
/// [unsize]: crate::marker::Unsize
/// [nomicon-coerce]: ../../nomicon/coercions.html
///
///
///
///
///
///
///
///
///
#[unstable(feature = "coerce_unsized", issue = "18598")]
#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T: ?Sized> {
    // Empty.
}

// &mut T -> &mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
// &mut T -> &U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b mut T {}
// &mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for &'a mut T {}
// &mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a mut T {}

// &T -> &U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
// &T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for &'a T {}

// *mut T -> *mut U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
// *mut T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *mut T {}

// *const T -> *const U
#[unstable(feature = "coerce_unsized", issue = "18598")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}

/// `DispatchFromDyn` 用于对象安全检查的实现 (特别允许任意 self 类型),以保证可以调度方法的接收者类型。
///
/// Note: `DispatchFromDyn` 被简称为 `CoerceSized` (并有略微不同的解释)。
///
/// 想象一下,我们有一个类型为 `&dyn Tr` 的 trait 对象 `t`,其中 `Tr` 是一些 trait,其方法 `m` 定义为 `fn m(&self);`。当调用 `t.m()` 时,接收者 `t` 是一个宽指针,但 `m` 的实现将期望一个 narrow 指针为 `&self` (对具体类型的引用)。
/// 编译器必须生成从 trait object 或 wide 指针到具体 reference 或 narrow 指针的隐式转换。
/// 实现 `DispatchFromDyn` 表示允许这种转换,因此实现 `DispatchFromDyn` 的类型可以安全地用作对象安全方法中的 self 类型。
/// (在上面的例子中,编译器将要求为 `&'a U` 实现 `DispatchFromDyn`)。
///
/// `DispatchFromDyn` 没有指定从 wide 指针到 narrow 指针的转换; 转换被硬连接到编译器中。
/// 为使转换工作,以下属性必须保持 (即,只有对具有这些属性的类型实现 `DispatchFromDyn` 才是安全的,编译器也会检查这些属性) :
///
/// * `Self` 和 `T` 要么都是引用,要么都是裸指针; 无论是哪种情况,都具有相同的可变性。
/// * 或者,以下所有条件都成立
///   - `Self` 和 `T` 必须具有相同的类型构造函数,仅在单个类型参数形式上有所不同 (*coerced 类型 *,例如 `impl DispatchFromDyn<Rc<T>> for Rc<U>` 可以,单个类型参数 (用 `T` 或 `U` 实例化) 是强制类型,`impl DispatchFromDyn<Arc<T>> for Rc<U>` 不是行)。
///
///   - `Self` 的定义必须是结构体。
///   - `Self` 的定义不能是 `#[repr(packed)]` 或 `#[repr(C)]`。
///   - 除了一对齐的零大小字段,`Self` 的定义必须只有一个字段,并且该字段的类型必须是强制类型。此外,`Self` 的字段类型必须实现 `DispatchFromDyn<F>`,其中 `F` 是 `T` 的字段类型的类型。
///
/// trait 的一个示例实现:
///
/// ```
/// # #![feature(dispatch_from_dyn, unsize)]
/// # use std::{ops::DispatchFromDyn, marker::Unsize};
/// # struct Rc<T: ?Sized>(std::rc::Rc<T>);
/// impl<T: ?Sized, U: ?Sized> DispatchFromDyn<Rc<U>> for Rc<T>
/// where
///     T: Unsize<U>,
/// {}
/// ```
///
///
///
///
///
///
///
///
///
///
///
///
///
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
#[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {
    // Empty.
}

// &T -> &U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
// &mut T -> &mut U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
// *const T -> *const U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
// *mut T -> *mut U
#[unstable(feature = "dispatch_from_dyn", issue = "none")]
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}