Skip to content

Commit ad47e0c

Browse files
committed
Make Slab::new const on Rust 1.39+
1 parent 0732ab6 commit ad47e0c

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,13 @@ exclude = ["/.*"]
2121
std = []
2222
default = ["std"]
2323

24+
[build-dependencies]
25+
autocfg = "1"
26+
2427
[dependencies]
2528
serde = { version = "1.0.95", optional = true, default-features = false, features = ["alloc"] }
2629

2730
[dev-dependencies]
31+
rustversion = "1"
2832
serde = { version = "1", features = ["derive"] }
2933
serde_test = "1"

build.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
fn main() {
2+
let cfg = match autocfg::AutoCfg::new() {
3+
Ok(cfg) => cfg,
4+
Err(e) => {
5+
// If we couldn't detect the compiler version and features, just
6+
// print a warning. This isn't a fatal error: we can still build
7+
// Tokio, we just can't enable cfgs automatically.
8+
println!(
9+
"cargo:warning=slab: failed to detect compiler features: {}",
10+
e
11+
);
12+
return;
13+
}
14+
};
15+
// Note that this is `no_`*, not `has_*`. This allows treating as the latest
16+
// stable rustc is used when the build script doesn't run. This is useful
17+
// for non-cargo build systems that don't run the build script.
18+
if !cfg.probe_rustc_version(1, 39) {
19+
println!("cargo:rustc-cfg=slab_no_const_vec_new");
20+
}
21+
}

src/lib.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,35 @@ impl<T> Slab<T> {
219219
/// The function does not allocate and the returned slab will have no
220220
/// capacity until `insert` is called or capacity is explicitly reserved.
221221
///
222+
/// This is `const fn` on Rust 1.39+.
223+
///
222224
/// # Examples
223225
///
224226
/// ```
225227
/// # use slab::*;
226228
/// let slab: Slab<i32> = Slab::new();
227229
/// ```
228-
pub fn new() -> Slab<T> {
229-
Slab::with_capacity(0)
230+
#[cfg(not(slab_no_const_vec_new))]
231+
pub const fn new() -> Self {
232+
Self {
233+
entries: Vec::new(),
234+
next: 0,
235+
len: 0,
236+
}
237+
}
238+
/// Construct a new, empty `Slab`.
239+
///
240+
/// The function does not allocate and the returned slab will have no
241+
/// capacity until `insert` is called or capacity is explicitly reserved.
242+
///
243+
/// This is `const fn` on Rust 1.39+.
244+
#[cfg(slab_no_const_vec_new)]
245+
pub fn new() -> Self {
246+
Self {
247+
entries: Vec::new(),
248+
next: 0,
249+
len: 0,
250+
}
230251
}
231252

232253
/// Construct a new, empty `Slab` with the specified capacity.

tests/slab.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,3 +696,9 @@ fn try_remove() {
696696
assert_eq!(slab.try_remove(key), None);
697697
assert_eq!(slab.get(key), None);
698698
}
699+
700+
#[rustversion::since(1.39)]
701+
#[test]
702+
fn const_new() {
703+
static _SLAB: Slab<()> = Slab::new();
704+
}

0 commit comments

Comments
 (0)