lambdaclass / lambdaclass/libssz

Building without the `alloc` feature fails: `alloc` is load-bearing but presented as optional

Open
#30 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
10
Forks
4
PR merge metrics
No merged PRs in 30d

Description

--no-default-features (without alloc) does not compile, but the feature set advertises it as a valid configuration.

Reproduction

On main (verified at f4d682b):

$ cargo build -p libssz --no-default-features
error[E0425]: cannot find type `Vec` in this scope
...
error: could not compile `libssz` (lib) due to 23 previous errors

All three crates fail the same way, 24 errors each for the other two:

Crate --no-default-features --no-default-features --features alloc
libssz 23 errors ok
libssz-types 24 errors ok
libssz-merkle 24 errors ok

Cause

Vec is imported only under the alloc feature:

// crates/ssz/src/encode.rs:1
#[cfg(feature = "alloc")]
use alloc::vec::Vec;

but the core trait methods use it unconditionally:

// crates/ssz/src/encode.rs:20
fn ssz_append(&self, buf: &mut Vec<u8>);

Same shape in decode.rs. alloc is not really optional: it is load-bearing for the trait surface, so std = ["alloc"] and alloc = [] being separable features misrepresents what builds.

Why it went unnoticed

CI never builds without alloc. The matrix in .github/workflows/ci.yml covers default and alloc-only (--no-default-features --features alloc), and the embedded-target checks at lines 128-129 also pass --features alloc. The README documents only --no-default-features --features alloc for no_std, so the documented paths are all fine; it is the undocumented-but-expressible combination that breaks.

Options

  1. Make alloc mandatory. Move extern crate alloc and the Vec imports out from behind the feature gate, drop the alloc feature (or keep it as a no-op alias for backwards compatibility). Honest about the requirement, no new maintenance burden.
  2. Fail fast. Keep the feature but add compile_error!("libssz requires the alloc feature") in lib.rs when neither alloc nor std is enabled. Cheap, gives a readable message instead of 23 type errors.
  3. Actually support alloc-free use. Gate the Vec-taking trait methods and add a sink abstraction so encoding can target a caller-provided buffer. Real work, only worth it if there is demand from embedded users.

Option 1 or 2 seems right unless alloc-free support is a goal. Either way, adding a --no-default-features job to the CI matrix would keep the claim and the reality in sync.

Found while addressing review comments on #20; unrelated to that PR's changes.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the no-default-features build for libssz, libssz-types, and libssz-merkle, then inspect crates/ssz/src/encode.rs, decode.rs, lib.rs, and the feature matrix in .github/workflows/ci.yml. Compare the available handling options and ensure the selected behavior is consistent across all three crates, with CI covering the intended feature combinations.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.