Skip to content

Commit

Permalink
Introduce a full tutorial for stabby (#63)
Browse files Browse the repository at this point in the history
* start tutorial

* type section done

* start working on traits section

* trait section done

* tutorial for runtime imports

* tutorial ready

* Update TUTORIAL.md

* v4.0.4
  • Loading branch information
p-avital authored Apr 3, 2024
1 parent 9dcbcdf commit 242a781
Show file tree
Hide file tree
Showing 11 changed files with 853 additions and 16 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# 4.0.4
- Introduce a tutorial to help onboard new users.
- Available as `stabby/TUTORIAL.md` in sources.
- Inserted as the documentation to a docs-only `stabby::_tutorial_` module. This ensures that codeblocks in it compile and that links to the doc are checked.
- Allow `stabby::sync::Weak` to function as a pointer-type for fat pointers, allowing the `stabby::dynptr!(Weak<dyn Trait>)` pattern.
- This can be helpful if you're building a plugin that needs to refer to its host weakly to avoid cycles, for example.

# 4.0.3
- Ensure `stabby` compiles on `nightly` by using `core::marker::Freeze` to reassure Rust that a bound that will eventually become required for const static references is respected by v-tables.
- Small documentation pass on internals to make nightly clippy happy
Expand Down
4 changes: 2 additions & 2 deletions stabby-abi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

[package]
name = "stabby-abi"
version = "4.0.3"
version = "4.0.4"
edition = "2021"
authors = { workspace = true }
license = { workspace = true }
Expand All @@ -38,7 +38,7 @@ abi_stable-channels = ["abi_stable", "abi_stable/channels"]
# unsafe_wakers = [] # unsafe_wakers is no longer a feature, but a compile option: you can enable them using `RUST_FLAGS='--cfg unsafe_wakers="true"'`

[dependencies]
stabby-macros = { path = "../stabby-macros/", version = "4.0.3" }
stabby-macros = { path = "../stabby-macros/", version = "4.0.4" }
abi_stable = { workspace = true, optional = true }
libc = { workspace = true, optional = true }
rustversion = { workspace = true }
Expand Down
67 changes: 66 additions & 1 deletion stabby-abi/src/alloc/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
use core::{
fmt::Debug,
hash::Hash,
mem::ManuallyDrop,
ptr::NonNull,
sync::atomic::{AtomicUsize, Ordering},
};

use crate::IntoDyn;
use crate::{vtable::HasDropVt, Dyn, IStable, IntoDyn};

use super::{
vec::{ptr_add, ptr_diff, Vec, VecInner},
Expand Down Expand Up @@ -219,6 +220,11 @@ impl<T, Alloc: IAlloc> Arc<T, Alloc> {
Ok(ret)
}
}

/// Constructs an additional [`Weak`] pointer to `this`.
pub fn downgrade(this: &Self) -> Weak<T, Alloc> {
this.into()
}
}
impl<T, Alloc: IAlloc> Drop for Arc<T, Alloc> {
fn drop(&mut self) {
Expand Down Expand Up @@ -646,3 +652,62 @@ impl<T, Alloc: IAlloc> IntoDyn for Arc<T, Alloc> {
anonymized
}
}

impl<T, Alloc: IAlloc> crate::IPtrOwned for Weak<T, Alloc> {
fn drop(this: &mut core::mem::ManuallyDrop<Self>, drop: unsafe extern "C" fn(&mut ())) {
if unsafe { this.ptr.prefix() }
.strong
.fetch_sub(1, Ordering::Relaxed)
!= 1
{
return;
}
unsafe {
drop(this.ptr.cast().as_mut());
_ = Weak::<T, Alloc>::from_raw(this.ptr);
}
}
}

impl<T, Alloc: IAlloc> crate::IPtrClone for Weak<T, Alloc> {
fn clone(this: &Self) -> Self {
this.clone()
}
}

impl<T, Alloc: IAlloc> IntoDyn for Weak<T, Alloc> {
type Anonymized = Weak<(), Alloc>;
type Target = T;
fn anonimize(self) -> Self::Anonymized {
let original_prefix = self.ptr.prefix_ptr();
let anonymized = unsafe { core::mem::transmute::<_, Self::Anonymized>(self) };
let anonymized_prefix = anonymized.ptr.prefix_ptr();
assert_eq!(anonymized_prefix, original_prefix, "The allocation prefix was lost in anonimization, this is definitely a bug, please report it.");
anonymized
}
}

impl<'a, Vt: HasDropVt, Alloc: IAlloc> From<&'a Dyn<'a, Arc<(), Alloc>, Vt>>
for Dyn<'a, Weak<(), Alloc>, Vt>
{
fn from(value: &'a Dyn<'a, Arc<(), Alloc>, Vt>) -> Self {
Self {
ptr: ManuallyDrop::new(Arc::downgrade(&value.ptr)),
vtable: value.vtable,
unsend: core::marker::PhantomData,
}
}
}
impl<'a, Vt: HasDropVt + IStable, Alloc: IAlloc> Dyn<'a, Weak<(), Alloc>, Vt> {
/// Attempts to upgrade a weak trait object to a strong one.
pub fn upgrade(self) -> crate::option::Option<Dyn<'a, Arc<(), Alloc>, Vt>> {
let Some(ptr) = self.ptr.upgrade() else {
return crate::option::Option::None();
};
crate::option::Option::Some(Dyn {
ptr: ManuallyDrop::new(ptr),
vtable: self.vtable,
unsend: core::marker::PhantomData,
})
}
}
10 changes: 5 additions & 5 deletions stabby-abi/src/fatptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl<T: IPtrMut> IPtrTryAsMut for T {
/// Provides drop support in dynptr for pointers that have at least partial ownership of their pointee.
///
/// `drop` is the drop function of the pointee.
pub trait IPtrOwned: IPtr {
pub trait IPtrOwned {
/// Called instead of `Drop::drop` when the dynptr is dropped.
fn drop(this: &mut core::mem::ManuallyDrop<Self>, drop: unsafe extern "C" fn(&mut ()));
}
Expand Down Expand Up @@ -153,9 +153,9 @@ impl<'a, Vt: Copy + 'a> DynRef<'a, Vt> {
#[stabby::stabby]
/// A stable trait object (or a stable `&mut dyn`)
pub struct Dyn<'a, P: IPtrOwned + 'a, Vt: HasDropVt + 'static> {
ptr: core::mem::ManuallyDrop<P>,
vtable: &'static Vt,
unsend: core::marker::PhantomData<&'a P>,
pub(crate) ptr: core::mem::ManuallyDrop<P>,
pub(crate) vtable: &'static Vt,
pub(crate) unsend: core::marker::PhantomData<&'a P>,
}

/// Allows casting a `dyn A + B` into `dyn A`.
Expand Down Expand Up @@ -207,7 +207,7 @@ impl<'a, P: IPtrOwned + IPtrClone, Vt: HasDropVt + 'a> Clone for Dyn<'a, P, Vt>
}
}
}
impl<'a, P: IPtrOwned, Vt: HasDropVt + 'a> Dyn<'a, P, Vt> {
impl<'a, P: IPtrOwned + IPtr, Vt: HasDropVt + 'a> Dyn<'a, P, Vt> {
/// Access the data pointer immutably.
pub fn ptr(&self) -> &P {
&self.ptr
Expand Down
103 changes: 103 additions & 0 deletions stabby-abi/src/stable_impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,3 +832,106 @@ sliceimpl!(
U101, U102, U103, U104, U105, U106, U107, U108, U109, U110, U111, U112, U113, U114, U115, U116,
U117, U118, U119, U120, U121, U122, U123, U124, U125, U126, U127, U128
);

unsafe impl IStable for core::cmp::Ordering {
type Align = U1;
type Size = U1;
type ForbiddenValues = illegal_values!(
[
[
[
[
[[[U2], [U3, U4]], [[U5, U6], [U7, U8]]],
[[[U9, U10], [U11, U12]], [[U13, U14], [U15, U16]]]
],
[
[[[U17, U18], [U19, U20]], [[U21, U22], [U23, U24]]],
[[[U25, U26], [U27, U28]], [[U29, U30], [U31, U32]]]
]
],
[
[
[[[U33, U34], [U35, U36]], [[U37, U38], [U39, U40]]],
[[[U41, U42], [U43, U44]], [[U45, U46], [U47, U48]]]
],
[
[[[U49, U50], [U51, U52]], [[U53, U54], [U55, U56]]],
[[[U57, U58], [U59, U60]], [[U61, U62], [U63, U64]]]
]
]
],
[
[
[
[[[U65, U66], [U67, U68]], [[U69, U70], [U71, U72]]],
[[[U73, U74], [U75, U76]], [[U77, U78], [U79, U80]]]
],
[
[[[U81, U82], [U83, U84]], [[U85, U86], [U87, U88]]],
[[[U89, U90], [U91, U92]], [[U93, U94], [U95, U96]]]
]
],
[
[
[[[U97, U98], [U99, U100]], [[U101, U102], [U103, U104]]],
[[[U105, U106], [U107, U108]], [[U109, U110], [U111, U112]]]
],
[
[[[U113, U114], [U115, U116]], [[U117, U118], [U119, U120]]],
[[[U121, U122], [U123, U124]], [[U125, U126], [U127, U128]]]
]
]
]
],
[
[
[
[
[[[U129], [U130, U131]], [[U132, U133], [U134, U135]]],
[[[U136, U137], [U138, U139]], [[U140, U141], [U142, U143]]]
],
[
[[[U144, U145], [U146, U147]], [[U148, U149], [U150, U151]]],
[[[U152, U153], [U154, U155]], [[U156, U157], [U158, U159]]]
]
],
[
[
[[[U160, U161], [U162, U163]], [[U164, U165], [U166, U167]]],
[[[U168, U169], [U170, U171]], [[U172, U173], [U174, U175]]]
],
[
[[[U176, U177], [U178, U179]], [[U180, U181], [U182, U183]]],
[[[U184, U185], [U186, U187]], [[U188, U189], [U190, U191]]]
]
]
],
[
[
[
[[[U192, U193], [U194, U195]], [[U196, U197], [U198, U199]]],
[[[U200, U201], [U202, U203]], [[U204, U205], [U206, U207]]]
],
[
[[[U208, U209], [U210, U211]], [[U212, U213], [U214, U215]]],
[[[U216, U217], [U218, U219]], [[U220, U221], [U222, U223]]]
]
],
[
[
[[[U224, U225], [U226, U227]], [[U228, U229], [U230, U231]]],
[[[U232, U233], [U234, U235]], [[U236, U237], [U238, U239]]]
],
[
[[[U240, U241], [U242, U243]], [[U244, U245], [U246, U247]]],
[[[U248, U249], [U250, U251]], [[U252, U253], [U254]]]
]
]
]
]
);
type UnusedBits = End;
type HasExactlyOneNiche = B0;
type ContainsIndirections = B0;
primitive_report!("core::cmp::Ordering");
}
2 changes: 1 addition & 1 deletion stabby-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

[package]
name = "stabby-macros"
version = "4.0.3"
version = "4.0.4"
edition = "2021"
authors = { workspace = true }
license = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion stabby-macros/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ impl<'a> DynTraitDescription<'a> {
}
impl<
#(#trait_lts,)*
StabbyPtrProvider: #st::IPtrOwned,
StabbyPtrProvider: #st::IPtrOwned + #st::IPtr,
StabbyVtProvider: #st::vtable::HasDropVt + Copy + #st::vtable::TransitiveDeref<
#vt_signature,
StabbyTransitiveDerefN
Expand Down
5 changes: 3 additions & 2 deletions stabby/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

[package]
name = "stabby"
version = "4.0.3"
version = "4.0.4"
edition = "2021"
authors = { workspace = true }
license = { workspace = true }
Expand All @@ -30,7 +30,7 @@ libloading = ["dep:libloading", "std"]
libc = ["stabby-abi/libc"]

[dependencies]
stabby-abi = { path = "../stabby-abi/", version = "4.0.3" }
stabby-abi = { path = "../stabby-abi/", version = "4.0.4" }

lazy_static = { workspace = true }
libloading = { workspace = true, optional = true }
Expand All @@ -42,6 +42,7 @@ criterion = { workspace = true }
rand = { workspace = true }

[package.metadata.docs.rs]
all-features = true
rustc-args = ["--cfg", "docsrs"]

[[bench]]
Expand Down
Loading

0 comments on commit 242a781

Please sign in to comment.