Skip to content

Commit 753dece

Browse files
committed
rust: import upstream alloc crate
This is a subset of the Rust standard library `alloc` crate, version 1.62.0, licensed under "Apache-2.0 OR MIT", from: https://github.com/rust-lang/rust/tree/1.62.0/library/alloc/src The files are copied as-is, with no modifications whatsoever (not even adding the SPDX identifiers). For copyright details, please see: https://github.com/rust-lang/rust/blob/1.62.0/COPYRIGHT The next patch modifies these files as needed for use within the kernel. This patch split allows reviewers to double-check the import and to clearly see the differences introduced. Vendoring `alloc`, at least for the moment, allows us to have fallible allocations support (i.e. the `try_*` versions of methods which return a `Result` instead of panicking) early on. It also gives a bit more freedom to experiment with new interfaces and to iterate quickly. Eventually, the goal is to have everything the kernel needs in upstream `alloc` and drop it from the kernel tree. For a summary of work on `alloc` happening upstream, please see: #408 The following script may be used to verify the contents: for path in $(cd rust/alloc/ && find . -type f -name '*.rs'); do curl --silent --show-error --location \ https://github.com/rust-lang/rust/raw/1.62.0/library/alloc/src/$path \ | diff --unified rust/alloc/$path - && echo $path: OK done Reviewed-by: Kees Cook <keescook@chromium.org> Co-developed-by: Alex Gaynor <alex.gaynor@gmail.com> Signed-off-by: Alex Gaynor <alex.gaynor@gmail.com> Co-developed-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Wedson Almeida Filho <wedsonaf@google.com> Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 12f5772 commit 753dece

13 files changed

+9037
-0
lines changed

rust/alloc/alloc.rs

+438
Large diffs are not rendered by default.

rust/alloc/borrow.rs

+496
Large diffs are not rendered by default.

rust/alloc/boxed.rs

+2,024
Large diffs are not rendered by default.

rust/alloc/collections/mod.rs

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
//! Collection types.
2+
3+
#![stable(feature = "rust1", since = "1.0.0")]
4+
5+
#[cfg(not(no_global_oom_handling))]
6+
pub mod binary_heap;
7+
#[cfg(not(no_global_oom_handling))]
8+
mod btree;
9+
#[cfg(not(no_global_oom_handling))]
10+
pub mod linked_list;
11+
#[cfg(not(no_global_oom_handling))]
12+
pub mod vec_deque;
13+
14+
#[cfg(not(no_global_oom_handling))]
15+
#[stable(feature = "rust1", since = "1.0.0")]
16+
pub mod btree_map {
17+
//! An ordered map based on a B-Tree.
18+
#[stable(feature = "rust1", since = "1.0.0")]
19+
pub use super::btree::map::*;
20+
}
21+
22+
#[cfg(not(no_global_oom_handling))]
23+
#[stable(feature = "rust1", since = "1.0.0")]
24+
pub mod btree_set {
25+
//! An ordered set based on a B-Tree.
26+
#[stable(feature = "rust1", since = "1.0.0")]
27+
pub use super::btree::set::*;
28+
}
29+
30+
#[cfg(not(no_global_oom_handling))]
31+
#[stable(feature = "rust1", since = "1.0.0")]
32+
#[doc(no_inline)]
33+
pub use binary_heap::BinaryHeap;
34+
35+
#[cfg(not(no_global_oom_handling))]
36+
#[stable(feature = "rust1", since = "1.0.0")]
37+
#[doc(no_inline)]
38+
pub use btree_map::BTreeMap;
39+
40+
#[cfg(not(no_global_oom_handling))]
41+
#[stable(feature = "rust1", since = "1.0.0")]
42+
#[doc(no_inline)]
43+
pub use btree_set::BTreeSet;
44+
45+
#[cfg(not(no_global_oom_handling))]
46+
#[stable(feature = "rust1", since = "1.0.0")]
47+
#[doc(no_inline)]
48+
pub use linked_list::LinkedList;
49+
50+
#[cfg(not(no_global_oom_handling))]
51+
#[stable(feature = "rust1", since = "1.0.0")]
52+
#[doc(no_inline)]
53+
pub use vec_deque::VecDeque;
54+
55+
use crate::alloc::{Layout, LayoutError};
56+
use core::fmt::Display;
57+
58+
/// The error type for `try_reserve` methods.
59+
#[derive(Clone, PartialEq, Eq, Debug)]
60+
#[stable(feature = "try_reserve", since = "1.57.0")]
61+
pub struct TryReserveError {
62+
kind: TryReserveErrorKind,
63+
}
64+
65+
impl TryReserveError {
66+
/// Details about the allocation that caused the error
67+
#[inline]
68+
#[must_use]
69+
#[unstable(
70+
feature = "try_reserve_kind",
71+
reason = "Uncertain how much info should be exposed",
72+
issue = "48043"
73+
)]
74+
pub fn kind(&self) -> TryReserveErrorKind {
75+
self.kind.clone()
76+
}
77+
}
78+
79+
/// Details of the allocation that caused a `TryReserveError`
80+
#[derive(Clone, PartialEq, Eq, Debug)]
81+
#[unstable(
82+
feature = "try_reserve_kind",
83+
reason = "Uncertain how much info should be exposed",
84+
issue = "48043"
85+
)]
86+
pub enum TryReserveErrorKind {
87+
/// Error due to the computed capacity exceeding the collection's maximum
88+
/// (usually `isize::MAX` bytes).
89+
CapacityOverflow,
90+
91+
/// The memory allocator returned an error
92+
AllocError {
93+
/// The layout of allocation request that failed
94+
layout: Layout,
95+
96+
#[doc(hidden)]
97+
#[unstable(
98+
feature = "container_error_extra",
99+
issue = "none",
100+
reason = "\
101+
Enable exposing the allocator’s custom error value \
102+
if an associated type is added in the future: \
103+
https://github.com/rust-lang/wg-allocators/issues/23"
104+
)]
105+
non_exhaustive: (),
106+
},
107+
}
108+
109+
#[unstable(
110+
feature = "try_reserve_kind",
111+
reason = "Uncertain how much info should be exposed",
112+
issue = "48043"
113+
)]
114+
impl From<TryReserveErrorKind> for TryReserveError {
115+
#[inline]
116+
fn from(kind: TryReserveErrorKind) -> Self {
117+
Self { kind }
118+
}
119+
}
120+
121+
#[unstable(feature = "try_reserve_kind", reason = "new API", issue = "48043")]
122+
impl From<LayoutError> for TryReserveErrorKind {
123+
/// Always evaluates to [`TryReserveErrorKind::CapacityOverflow`].
124+
#[inline]
125+
fn from(_: LayoutError) -> Self {
126+
TryReserveErrorKind::CapacityOverflow
127+
}
128+
}
129+
130+
#[stable(feature = "try_reserve", since = "1.57.0")]
131+
impl Display for TryReserveError {
132+
fn fmt(
133+
&self,
134+
fmt: &mut core::fmt::Formatter<'_>,
135+
) -> core::result::Result<(), core::fmt::Error> {
136+
fmt.write_str("memory allocation failed")?;
137+
let reason = match self.kind {
138+
TryReserveErrorKind::CapacityOverflow => {
139+
" because the computed capacity exceeded the collection's maximum"
140+
}
141+
TryReserveErrorKind::AllocError { .. } => {
142+
" because the memory allocator returned a error"
143+
}
144+
};
145+
fmt.write_str(reason)
146+
}
147+
}
148+
149+
/// An intermediate trait for specialization of `Extend`.
150+
#[doc(hidden)]
151+
trait SpecExtend<I: IntoIterator> {
152+
/// Extends `self` with the contents of the given iterator.
153+
fn spec_extend(&mut self, iter: I);
154+
}

rust/alloc/lib.rs

+236
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
//! # The Rust core allocation and collections library
2+
//!
3+
//! This library provides smart pointers and collections for managing
4+
//! heap-allocated values.
5+
//!
6+
//! This library, like libcore, normally doesn’t need to be used directly
7+
//! since its contents are re-exported in the [`std` crate](../std/index.html).
8+
//! Crates that use the `#![no_std]` attribute however will typically
9+
//! not depend on `std`, so they’d use this crate instead.
10+
//!
11+
//! ## Boxed values
12+
//!
13+
//! The [`Box`] type is a smart pointer type. There can only be one owner of a
14+
//! [`Box`], and the owner can decide to mutate the contents, which live on the
15+
//! heap.
16+
//!
17+
//! This type can be sent among threads efficiently as the size of a `Box` value
18+
//! is the same as that of a pointer. Tree-like data structures are often built
19+
//! with boxes because each node often has only one owner, the parent.
20+
//!
21+
//! ## Reference counted pointers
22+
//!
23+
//! The [`Rc`] type is a non-threadsafe reference-counted pointer type intended
24+
//! for sharing memory within a thread. An [`Rc`] pointer wraps a type, `T`, and
25+
//! only allows access to `&T`, a shared reference.
26+
//!
27+
//! This type is useful when inherited mutability (such as using [`Box`]) is too
28+
//! constraining for an application, and is often paired with the [`Cell`] or
29+
//! [`RefCell`] types in order to allow mutation.
30+
//!
31+
//! ## Atomically reference counted pointers
32+
//!
33+
//! The [`Arc`] type is the threadsafe equivalent of the [`Rc`] type. It
34+
//! provides all the same functionality of [`Rc`], except it requires that the
35+
//! contained type `T` is shareable. Additionally, [`Arc<T>`][`Arc`] is itself
36+
//! sendable while [`Rc<T>`][`Rc`] is not.
37+
//!
38+
//! This type allows for shared access to the contained data, and is often
39+
//! paired with synchronization primitives such as mutexes to allow mutation of
40+
//! shared resources.
41+
//!
42+
//! ## Collections
43+
//!
44+
//! Implementations of the most common general purpose data structures are
45+
//! defined in this library. They are re-exported through the
46+
//! [standard collections library](../std/collections/index.html).
47+
//!
48+
//! ## Heap interfaces
49+
//!
50+
//! The [`alloc`](alloc/index.html) module defines the low-level interface to the
51+
//! default global allocator. It is not compatible with the libc allocator API.
52+
//!
53+
//! [`Arc`]: sync
54+
//! [`Box`]: boxed
55+
//! [`Cell`]: core::cell
56+
//! [`Rc`]: rc
57+
//! [`RefCell`]: core::cell
58+
59+
// To run liballoc tests without x.py without ending up with two copies of liballoc, Miri needs to be
60+
// able to "empty" this crate. See <https://github.com/rust-lang/miri-test-libstd/issues/4>.
61+
// rustc itself never sets the feature, so this line has no affect there.
62+
#![cfg(any(not(feature = "miri-test-libstd"), test, doctest))]
63+
#![allow(unused_attributes)]
64+
#![stable(feature = "alloc", since = "1.36.0")]
65+
#![doc(
66+
html_playground_url = "https://play.rust-lang.org/",
67+
issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/",
68+
test(no_crate_inject, attr(allow(unused_variables), deny(warnings)))
69+
)]
70+
#![doc(cfg_hide(
71+
not(test),
72+
not(any(test, bootstrap)),
73+
any(not(feature = "miri-test-libstd"), test, doctest),
74+
no_global_oom_handling,
75+
not(no_global_oom_handling),
76+
target_has_atomic = "ptr"
77+
))]
78+
#![no_std]
79+
#![needs_allocator]
80+
//
81+
// Lints:
82+
#![deny(unsafe_op_in_unsafe_fn)]
83+
#![warn(deprecated_in_future)]
84+
#![warn(missing_debug_implementations)]
85+
#![warn(missing_docs)]
86+
#![allow(explicit_outlives_requirements)]
87+
//
88+
// Library features:
89+
#![cfg_attr(not(no_global_oom_handling), feature(alloc_c_string))]
90+
#![feature(alloc_layout_extra)]
91+
#![feature(allocator_api)]
92+
#![feature(array_chunks)]
93+
#![feature(array_methods)]
94+
#![feature(array_windows)]
95+
#![feature(assert_matches)]
96+
#![feature(async_iterator)]
97+
#![feature(coerce_unsized)]
98+
#![cfg_attr(not(no_global_oom_handling), feature(const_alloc_error))]
99+
#![feature(const_box)]
100+
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
101+
#![feature(const_cow_is_borrowed)]
102+
#![feature(const_convert)]
103+
#![feature(const_size_of_val)]
104+
#![feature(const_align_of_val)]
105+
#![feature(const_ptr_read)]
106+
#![feature(const_maybe_uninit_write)]
107+
#![feature(const_maybe_uninit_as_mut_ptr)]
108+
#![feature(const_refs_to_cell)]
109+
#![feature(core_c_str)]
110+
#![feature(core_intrinsics)]
111+
#![feature(core_ffi_c)]
112+
#![feature(const_eval_select)]
113+
#![feature(const_pin)]
114+
#![feature(cstr_from_bytes_until_nul)]
115+
#![feature(dispatch_from_dyn)]
116+
#![feature(exact_size_is_empty)]
117+
#![feature(extend_one)]
118+
#![feature(fmt_internals)]
119+
#![feature(fn_traits)]
120+
#![feature(hasher_prefixfree_extras)]
121+
#![feature(inplace_iteration)]
122+
#![feature(iter_advance_by)]
123+
#![feature(layout_for_ptr)]
124+
#![feature(maybe_uninit_slice)]
125+
#![cfg_attr(test, feature(new_uninit))]
126+
#![feature(nonnull_slice_from_raw_parts)]
127+
#![feature(pattern)]
128+
#![feature(ptr_internals)]
129+
#![feature(ptr_metadata)]
130+
#![feature(ptr_sub_ptr)]
131+
#![feature(receiver_trait)]
132+
#![feature(set_ptr_value)]
133+
#![feature(slice_group_by)]
134+
#![feature(slice_ptr_get)]
135+
#![feature(slice_ptr_len)]
136+
#![feature(slice_range)]
137+
#![feature(str_internals)]
138+
#![feature(strict_provenance)]
139+
#![feature(trusted_len)]
140+
#![feature(trusted_random_access)]
141+
#![feature(try_trait_v2)]
142+
#![feature(unchecked_math)]
143+
#![feature(unicode_internals)]
144+
#![feature(unsize)]
145+
//
146+
// Language features:
147+
#![feature(allocator_internals)]
148+
#![feature(allow_internal_unstable)]
149+
#![feature(associated_type_bounds)]
150+
#![feature(box_syntax)]
151+
#![feature(cfg_sanitize)]
152+
#![feature(const_deref)]
153+
#![feature(const_mut_refs)]
154+
#![feature(const_ptr_write)]
155+
#![feature(const_precise_live_drops)]
156+
#![feature(const_trait_impl)]
157+
#![feature(const_try)]
158+
#![feature(dropck_eyepatch)]
159+
#![feature(exclusive_range_pattern)]
160+
#![feature(fundamental)]
161+
#![cfg_attr(not(test), feature(generator_trait))]
162+
#![feature(hashmap_internals)]
163+
#![feature(lang_items)]
164+
#![feature(let_else)]
165+
#![feature(min_specialization)]
166+
#![feature(negative_impls)]
167+
#![feature(never_type)]
168+
#![feature(nll)] // Not necessary, but here to test the `nll` feature.
169+
#![feature(rustc_allow_const_fn_unstable)]
170+
#![feature(rustc_attrs)]
171+
#![feature(slice_internals)]
172+
#![feature(staged_api)]
173+
#![cfg_attr(test, feature(test))]
174+
#![feature(unboxed_closures)]
175+
#![feature(unsized_fn_params)]
176+
#![feature(c_unwind)]
177+
//
178+
// Rustdoc features:
179+
#![feature(doc_cfg)]
180+
#![feature(doc_cfg_hide)]
181+
// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]`
182+
// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad
183+
// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs
184+
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
185+
#![feature(intra_doc_pointers)]
186+
187+
// Allow testing this library
188+
#[cfg(test)]
189+
#[macro_use]
190+
extern crate std;
191+
#[cfg(test)]
192+
extern crate test;
193+
194+
// Module with internal macros used by other modules (needs to be included before other modules).
195+
#[macro_use]
196+
mod macros;
197+
198+
mod raw_vec;
199+
200+
// Heaps provided for low-level allocation strategies
201+
202+
pub mod alloc;
203+
204+
// Primitive types using the heaps above
205+
206+
// Need to conditionally define the mod from `boxed.rs` to avoid
207+
// duplicating the lang-items when building in test cfg; but also need
208+
// to allow code to have `use boxed::Box;` declarations.
209+
#[cfg(not(test))]
210+
pub mod boxed;
211+
#[cfg(test)]
212+
mod boxed {
213+
pub use std::boxed::Box;
214+
}
215+
pub mod borrow;
216+
pub mod collections;
217+
#[cfg(not(no_global_oom_handling))]
218+
pub mod ffi;
219+
pub mod fmt;
220+
pub mod rc;
221+
pub mod slice;
222+
pub mod str;
223+
pub mod string;
224+
#[cfg(target_has_atomic = "ptr")]
225+
pub mod sync;
226+
#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
227+
pub mod task;
228+
#[cfg(test)]
229+
mod tests;
230+
pub mod vec;
231+
232+
#[doc(hidden)]
233+
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
234+
pub mod __export {
235+
pub use core::format_args;
236+
}

0 commit comments

Comments
 (0)