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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
//! # Rust 核心分配和集合库
//!
//! 该库提供了用于管理堆分配值的智能指针和集合。
//!
//! 这个库和 core 一样,通常不需要直接使用,因为它的内容在 [`std` crate](../std/index.html) 中被重新导出。
//! 但是,使用 `#![no_std]` 属性的 Crates 通常不依赖于 `std`,因此他们会改用此 crate。
//!
//! ## Boxed 值
//!
//! [`Box`] 类型是智能指针类型。[`Box`] 只能有一个所有者,所有者可以决定对内容进行可变的,这些内容存在于堆中。
//!
//! 由于 `Box` 值的大小与指针的大小相同,因此可以在线程之间高效地发送此类型。
//! 由于每个节点通常只有一个所有者,即父节点,因此通常使用 boxes 构建树状数据结构。
//!
//! ## 引用计数指针
//!
//! [`Rc`] 类型是一种非线程安全的引用计数指针类型,旨在共享线程内的内存。
//! [`Rc`] 指针包装类型 `T`,并且仅允许访问共享引用的 `&T`。
//!
//! 当继承的可变性 (例如使用 [`Box`]) 对于应用程序来说过于受限时,此类型很有用,并且通常与 [`Cell`] 或 [`RefCell`] 类型配对以允许进行可变的。
//!
//!
//! ## 原子引用计数指针
//!
//! [`Arc`] 类型与 [`Rc`] 类型等效。它提供 [`Rc`] 的所有相同功能,不同之处在于它要求包含的 `T` 类型是可共享的。
//! 此外,[`Arc<T>`][`Arc`] 本身可发送,而 [`Rc<T>`][`Rc`] 不可发送。
//!
//! 这种类型允许共享访问所包含的数据,并且通常与同步原语 (例如互斥锁) 配对以允许共享资源的可变。
//!
//! ## Collections
//!
//! 该库中定义了最通用的通用数据结构的实现。它们通过 [标准 collections 库](../std/collections/index.html) 重导出。
//!
//! ## 堆接口
//!
//! [`alloc`](alloc/index.html) 模块将默认接口定义为默认分配器。它与 libc 分配器 API 不兼容。
//!
//! [`Arc`]: sync
//! [`Box`]: boxed
//! [`Cell`]: core::cell
//! [`Rc`]: rc
//! [`RefCell`]: core::cell
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!
//!

#![allow(unused_attributes)]
#![stable(feature = "alloc", since = "1.36.0")]
#![doc(
    html_playground_url = "https://play.rust-lang.org/",
    issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
    test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
)]
#![doc(cfg_hide(
    not(test),
    not(any(test, bootstrap)),
    any(not(feature = "miri-test-libstd"), test, doctest),
    no_global_oom_handling,
    not(no_global_oom_handling),
    not(no_rc),
    not(no_sync),
    target_has_atomic = "ptr"
))]
#![no_std]
#![needs_allocator]
// 要在没有 x.py 的情况下运行 alloc 测试而不以两个 alloc 副本结束,Miri 需要能够 "empty" 这个 crate。
// 请参见 <https://github.com/rust-lang/miri-test-libstd/issues/4>。
// rustc 本身从不设置该特性,因此这一行在那里没有影响。
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
//
// Lints:
#![deny(unsafe_op_in_unsafe_fn)]
#![deny(fuzzy_provenance_casts)]
#![warn(deprecated_in_future)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![allow(explicit_outlives_requirements)]
#![warn(multiple_supertrait_upcastable)]
//
// 库特性:
// tidy-alphabetical-start
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_len))]
#![cfg_attr(test, feature(is_sorted))]
#![cfg_attr(test, feature(new_uninit))]
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(array_chunks)]
#![feature(array_into_iter_constructors)]
#![feature(array_methods)]
#![feature(array_windows)]
#![feature(ascii_char)]
#![feature(assert_matches)]
#![feature(async_iterator)]
#![feature(coerce_unsized)]
#![feature(const_align_of_val)]
#![feature(const_box)]
#![feature(const_cow_is_borrowed)]
#![feature(const_eval_select)]
#![feature(const_maybe_uninit_as_mut_ptr)]
#![feature(const_maybe_uninit_write)]
#![feature(const_maybe_uninit_zeroed)]
#![feature(const_pin)]
#![feature(const_refs_to_cell)]
#![feature(const_size_of_val)]
#![feature(const_waker)]
#![feature(core_intrinsics)]
#![feature(core_panic)]
#![feature(dispatch_from_dyn)]
#![feature(error_generic_member_access)]
#![feature(error_in_core)]
#![feature(exact_size_is_empty)]
#![feature(extend_one)]
#![feature(fmt_internals)]
#![feature(fn_traits)]
#![feature(hasher_prefixfree_extras)]
#![feature(inline_const)]
#![feature(inplace_iteration)]
#![feature(iter_advance_by)]
#![feature(iter_next_chunk)]
#![feature(iter_repeat_n)]
#![feature(layout_for_ptr)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(pattern)]
#![feature(pointer_byte_offsets)]
#![feature(provide_any)]
#![feature(ptr_internals)]
#![feature(ptr_metadata)]
#![feature(ptr_sub_ptr)]
#![feature(receiver_trait)]
#![feature(saturating_int_impl)]
#![feature(set_ptr_value)]
#![feature(sized_type_properties)]
#![feature(slice_from_ptr_range)]
#![feature(slice_group_by)]
#![feature(slice_ptr_get)]
#![feature(slice_ptr_len)]
#![feature(slice_range)]
#![feature(std_internals)]
#![feature(str_internals)]
#![feature(strict_provenance)]
#![feature(trusted_len)]
#![feature(trusted_random_access)]
#![feature(try_trait_v2)]
#![feature(tuple_trait)]
#![feature(unchecked_math)]
#![feature(unicode_internals)]
#![feature(unsize)]
#![feature(utf8_chunks)]
// tidy-alphabetical-end
//
// 语言特性:
// tidy-alphabetical-start
#![cfg_attr(not(test), feature(generator_trait))]
#![cfg_attr(test, feature(panic_update_hook))]
#![cfg_attr(test, feature(test))]
#![feature(allocator_internals)]
#![feature(allow_internal_unstable)]
#![feature(associated_type_bounds)]
#![feature(c_unwind)]
#![feature(cfg_sanitize)]
#![feature(const_mut_refs)]
#![feature(const_precise_live_drops)]
#![feature(const_ptr_write)]
#![feature(const_trait_impl)]
#![feature(const_try)]
#![feature(dropck_eyepatch)]
#![feature(exclusive_range_pattern)]
#![feature(fundamental)]
#![feature(hashmap_internals)]
#![feature(lang_items)]
#![feature(min_specialization)]
#![feature(multiple_supertrait_upcastable)]
#![feature(negative_impls)]
#![feature(never_type)]
#![feature(pointer_is_aligned)]
#![feature(rustc_allow_const_fn_unstable)]
#![feature(rustc_attrs)]
#![feature(slice_internals)]
#![feature(staged_api)]
#![feature(stmt_expr_attributes)]
#![feature(unboxed_closures)]
#![feature(unsized_fn_params)]
#![feature(with_negative_coherence)]
// tidy-alphabetical-end
//
// Rustdoc 特性:
#![feature(doc_cfg)]
#![feature(doc_cfg_hide)]
// 从技术上讲,这是 rustdoc 中的一个 bug: rustdoc 看到关于 `#[lang = slice_alloc]` 块的文档是针对 `&[T]` 的,它也有在 `core` 中使用这个特性的文档,并对特性开关未启用感到愤怒。
// 理想情况下,它不会为其他 crates 的文档检查特性开关,但是由于它只能出现在 lang 项上,因此似乎不值得修复。
//
//
#![feature(intra_doc_pointers)]

// 允许测试该库
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(test)]
extern crate test;
#[cfg(test)]
mod testing;

// 具有其他模块使用的内部宏的模块 (需要在其他模块之前包含)。
#[macro_use]
mod macros;

mod raw_vec;

// 为灵活分配策略提供的堆

pub mod alloc;

// 使用上面的堆的原始类型

// 需要在 `boxed.rs` 中有条件地定义 mod,以避免在构建测试 cfg 时重复 lang-Item; 但还需要允许代码具有 `use boxed::Box;` 声明。
//
//
#[cfg(not(test))]
pub mod boxed;
#[cfg(test)]
mod boxed {
    pub use std::boxed::Box;
}
pub mod borrow;
pub mod collections;
#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
pub mod ffi;
pub mod fmt;
#[cfg(not(no_rc))]
pub mod rc;
pub mod slice;
pub mod str;
pub mod string;
#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
pub mod sync;
#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
pub mod task;
#[cfg(test)]
mod tests;
pub mod vec;

#[doc(hidden)]
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
pub mod __export {
    pub use core::format_args;
}

#[cfg(test)]
#[allow(dead_code)] // 未在所有配置中使用
pub(crate) mod test_helpers {
    /// 从 `std::test_helpers::test_rng` 复制,因为这些测试依赖于每个 RNG 调用也不相同的 seed。
    ///
    pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
        use std::hash::{BuildHasher, Hash, Hasher};
        let mut hasher = std::collections::hash_map::RandomState::new().build_hasher();
        std::panic::Location::caller().hash(&mut hasher);
        let hc64 = hasher.finish();
        let seed_vec =
            hc64.to_le_bytes().into_iter().chain(0u8..8).collect::<crate::vec::Vec<u8>>();
        let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap();
        rand::SeedableRng::from_seed(seed)
    }
}