Expand description
Objectionable storage of ?Sized
types inline inside allocated objects.
See BigBox
and InlineBox
for the crate’s central interface.
§Feature Flags
alloc
(enabled by default) — Enable a dependency onalloc
to allow boxing values on the heap.strict-provenance
— Support sound execution under the the experimental strict provenance memory model. See the section on soundness for more details.
§Soundness & Memory Model
When the strict-provenance
crate feature is enabled,
this crate uses unstable APIs1 for sound execution under the experimental strict provenance memory model
and to support passing the test suite under Miri.
When this feature is disabled, this crate tries to replicate the unstable methods using only those available in stable Rust. This method is reliable enough for compilation in a practical environment, but is considered unsound under the strict provenance memory model. This should not have an effect on typical use cases (as of Rust 1.80), but when interacting with strict provenance, the aforementioned feature is required.
Bear in mind that this project is developped as a hobby, and is not formally verified. There may be undiscovered unsoundness in untested edge cases. Issues and PRs are welcome.
§Examples
// we define the trait object (and impls) which our `BigBox` will contain.
trait Character {
fn personality(&self) -> &'static str;
}
impl Character for u8 {
fn personality(&self) -> &'static str {
"very small"
}
}
impl Character for [u8; 1000] {
fn personality(&self) -> &'static str {
"enormous"
}
}
// implementing the unsafe trait `FromSized` is necessary for creating `BigBox` values,
// but there is thankfully a safe macro for this:
objectionable::impl_from_sized_for_trait_object!(dyn Character);
// to use `BigBox`, we have to configure it with an internal type and maximum inline size:
type MyBox = objectionable::BigBox<dyn Character, 32>;
// if we have a pre-allocated value, we can use `BigBox::new_boxed` to create a `BigBox` value:
let pre_boxed = Box::new(5_u8);
let pre_boxed = MyBox::new_boxed(pre_boxed);
// alternatively, we can use `BigBox::new` which will store the value inline if it is small enough:
let inline = MyBox::new(2_u8);
assert!(inline.is_inline() == true);
// but if the value is too large, it will be allocated on the heap via a standard `Box`:
let boxed = MyBox::new([2u8; 1000]);
assert!(boxed.is_inline() == false);
// accessing values is easy:
assert_eq!(Character::personality(pre_boxed.as_ref()), "very small");
assert_eq!(Character::personality(inline.as_ref()), "very small");
assert_eq!(Character::personality(boxed.as_ref()), "enormous");
Notably, Rust’s
strict_provenance
andptr_metadata
features are enabled. ↩
Macros§
- impl_
from_ sized_ for_ trait_ object - Safely implements
FromSized
for trait objects.
Structs§
- BigBox
- Similar to
Box<T>
, but stores small values inline. - Inline
Box - A box which stores its (small) value inline.
- TooLarge
- An error indicating a value was too large to fit in an
InlineBox
.
Enums§
- BoxCapture
alloc
- Represents the result of a
BigBox::take
operation.
Traits§
- From
Sized - Allows construction of
?Sized
values fromSized
values.