6 releases
0.3.1 | Aug 23, 2024 |
---|---|
0.3.0 | Aug 23, 2024 |
0.2.4 |
|
0.1.0 |
|
#1258 in Rust patterns
31KB
415 lines
objectionable storage of ?Sized
types inline inside allocated objects.
See the documentation for usage and examples.
License
Everything in this repository is dual-licensed under either:
- MIT License (LICENSE-MIT or http://opensource.org/licenses/MIT)
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
at your option, unless explicitly stated otherwise.
lib.rs
:
Objectionable storage of ?Sized
types inline inside allocated objects.
See BigBox
and InlineBox
for the crate's central interface.
Soundness & Memory Model
When the strict-provenance
crate feature is enabled,
this crate uses unstable APIs[^1] 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.
[^1]: Notably, Rust's
strict_provenance
and
ptr_metadata
features are enabled.
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");
Dependencies
~175KB