fixed code gen mostly
Konnor Andrews 2024-02-12
parent de99999 · commit 75495bb
-rw-r--r--src/any/static_wrapper.rs5
-rw-r--r--src/build.rs4
-rw-r--r--src/build/builders/core/array.rs77
-rw-r--r--src/build/builders/core/bool.rs13
-rw-r--r--src/protocol.rs55
-rw-r--r--src/walk/walkers/core/array.rs52
-rw-r--r--src/walk/walkers/core/bool.rs6
-rw-r--r--tests/demo.rs32
8 files changed, 105 insertions, 139 deletions
diff --git a/src/any/static_wrapper.rs b/src/any/static_wrapper.rs
index ce26fdd..d167257 100644
--- a/src/any/static_wrapper.rs
+++ b/src/any/static_wrapper.rs
@@ -3,6 +3,7 @@
use super::*;
/// Impl of [`TypeNameable`] for `'static` types that are owned (`T`).
+#[repr(transparent)]
pub struct OwnedStatic<T: ?Sized>(pub T);
nameable! {
@@ -12,6 +13,7 @@ nameable! {
}
/// Impl of [`TypeNameable`] for `'static` types that are borrowed (`&'lt T`).
+#[repr(transparent)]
pub struct BorrowedStatic<'lt, T: ?Sized>(pub &'lt T);
nameable! {
@@ -21,6 +23,7 @@ nameable! {
}
/// Impl of [`TypeNameable`] for `'static` types that are temporarily borrowed (`&'a T`).
+#[repr(transparent)]
pub struct TempBorrowedStatic<'a, T: ?Sized>(pub &'a T);
nameable! {
@@ -30,6 +33,7 @@ nameable! {
}
/// Impl of [`TypeNameable`] for `'static` types that are borrowed mutably (`&'lt mut T`).
+#[repr(transparent)]
pub struct BorrowedMutStatic<'lt, T: ?Sized>(pub &'lt mut T);
nameable! {
@@ -39,6 +43,7 @@ nameable! {
}
/// Impl of [`TypeNameable`] for `'static` types that are temporarily borrowed mutably (`&'a mut T`).
+#[repr(transparent)]
pub struct TempBorrowedMutStatic<'a, T: ?Sized>(pub &'a mut T);
nameable! {
diff --git a/src/build.rs b/src/build.rs
index 87c0fc8..f0bb597 100644
--- a/src/build.rs
+++ b/src/build.rs
@@ -55,7 +55,7 @@ pub fn build<'ctx, T: Build<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>(
) -> Result<T, BuildError<<<T as Build<'ctx>>::Builder as Builder<'ctx>>::Error, W::Error>> {
let mut builder = T::Builder::default();
- if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()).into_inner() {
+ if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()) {
return Err(BuildError::Walker(err));
}
@@ -67,7 +67,7 @@ pub fn build_with<'ctx, B: Builder<'ctx>, W: Walker<'ctx, Effect = SyncEffect>>(
) -> Result<B::Value, BuildError<B::Error, W::Error>> {
let mut builder = B::default();
- if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()).into_inner() {
+ if let core::ops::ControlFlow::Break(err) = walker.walk(builder.as_visitor()) {
return Err(BuildError::Walker(err));
}
diff --git a/src/build/builders/core/array.rs b/src/build/builders/core/array.rs
index 2b8edb3..f3311e5 100644
--- a/src/build/builders/core/array.rs
+++ b/src/build/builders/core/array.rs
@@ -4,7 +4,7 @@ use crate::{
any_trait,
protocol::{
visitor::{Sequence, SequenceScope, Status},
- ControlFlowFor, Effect, Ready,
+ ControlFlowFor, Effect,
},
};
@@ -80,49 +80,56 @@ any_trait! {
];
}
-impl<'ctx, B: crate::Builder<'ctx>, const N: usize, E: Effect> Sequence<'ctx, E>
+impl<'ctx, B: crate::Builder<'ctx>, const N: usize> Sequence<'ctx>
for Builder<'ctx, B, N>
{
#[inline]
- fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx, E>) -> ControlFlowFor<'a, E> {
- E::wrap(async {
- loop {
- // Check if the array is full.
- if self.index >= N {
+ fn visit<'a>(&'a mut self, scope: &'a mut dyn SequenceScope<'ctx>) -> ControlFlowFor<'a> {
+ loop {
+ // Check if the array is full.
+ if self.index >= N {
+ return ControlFlow::Continue(());
+ }
+
+ // Try to build the next value.
+ let mut builder = B::default();
+ match scope.next(builder.as_visitor()) {
+ ControlFlow::Continue(Status::Done) => {
+ // The sequence is done so the builder wasn't given a value.
+ // We just throw away the empty builder.
return ControlFlow::Continue(());
}
-
- // Try to build the next value.
- let mut builder = B::default();
- match scope.next(builder.as_visitor()).await {
- ControlFlow::Continue(Status::Done) => {
- // The sequence is done so the builder wasn't given a value.
- // We just throw away the empty builder.
- return ControlFlow::Continue(());
- }
- ControlFlow::Continue(Status::Continue) => match builder.build() {
- Ok(value) => {
- // Put the value in the array, and move to the next one.
- unsafe { maybe_uninit_array(&mut self.array).get_unchecked_mut(self.index).write(value) };
- self.index += 1;
- }
- Err(err) => {
- // Record the item error and return a stop signal.
- self.item_err = Some((self.index, err));
- return ControlFlow::Break(());
+ ControlFlow::Continue(Status::Continue) => match builder.build() {
+ Ok(value) => {
+ // Put the value in the array, and move to the next one.
+ // unsafe {
+ // maybe_uninit_array(&mut self.array)
+ // .get_unchecked_mut(self.index)
+ // .write(value)
+ // };
+ unsafe {
+ let ptr = (self.array.as_mut_ptr() as *mut B::Value).offset(self.index as _);
+ core::ptr::write(ptr, value);
}
- },
- ControlFlow::Break(()) => {
+ // std::ptr::write(&mut self.array
+ self.index += 1;
+ }
+ Err(err) => {
+ // Record the item error and return a stop signal.
+ self.item_err = Some((self.index, err));
return ControlFlow::Break(());
}
+ },
+ ControlFlow::Break(()) => {
+ return ControlFlow::Break(());
}
}
- })
+ }
}
}
-
-fn maybe_uninit_array<T, const N: usize>(
- array: &mut MaybeUninit<[T; N]>,
-) -> &mut [MaybeUninit<T>; N] {
- unsafe { &mut *(array as *mut _ as *mut [MaybeUninit<T>; N]) }
-}
+//
+// fn maybe_uninit_array<T, const N: usize>(
+// array: &mut MaybeUninit<[T; N]>,
+// ) -> &mut [MaybeUninit<T>; N] {
+// unsafe { &mut *(array as *mut _ as *mut [MaybeUninit<T>; N]) }
+// }
diff --git a/src/build/builders/core/bool.rs b/src/build/builders/core/bool.rs
index dd98d0e..ebf628c 100644
--- a/src/build/builders/core/bool.rs
+++ b/src/build/builders/core/bool.rs
@@ -3,7 +3,7 @@ use core::ops::ControlFlow;
use crate::{
any::static_wrapper::OwnedStatic,
any_trait,
- protocol::{visitor::Value, ControlFlowFor, Effect},
+ protocol::{visitor::Value, ControlFlowFor, Effect, SyncEffect},
};
impl<'ctx> crate::Build<'ctx> for bool {
@@ -32,6 +32,7 @@ impl<'ctx> crate::Builder<'ctx> for Builder {
self
}
+ #[inline]
fn build(self) -> Result<Self::Value, Self::Error> {
self.0.ok_or(Error::Incomplete)
}
@@ -43,12 +44,10 @@ any_trait! {
];
}
-impl<'a, E: Effect> Value<'a, OwnedStatic<bool>, E> for Builder {
+impl<'a> Value<'a, OwnedStatic<bool>> for Builder {
#[inline]
- fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a, E> {
- E::wrap(async move {
- self.0 = Some(value);
- ControlFlow::Continue(())
- })
+ fn visit(&'a mut self, OwnedStatic(value): OwnedStatic<bool>) -> ControlFlowFor<'a> {
+ self.0 = Some(value);
+ ControlFlow::Continue(())
}
}
diff --git a/src/protocol.rs b/src/protocol.rs
index 37bcee7..c763730 100644
--- a/src/protocol.rs
+++ b/src/protocol.rs
@@ -52,11 +52,7 @@ pub type Visitor<'a, 'ctx> = dyn AnyTrait<'ctx> + 'a;
pub type Walker<'a, 'ctx> = dyn AnyTrait<'ctx> + 'a;
pub trait Effect: 'static {
- type ControlFlow<'a, C, B>: Future<Output = core::ops::ControlFlow<B, C>>;
-
- fn wrap<'a, C, B, F: Future<Output = core::ops::ControlFlow<B, C>> + 'a>(
- future: F,
- ) -> Self::ControlFlow<'a, C, B>;
+ type ControlFlow<'a, C, B>;
}
pub type ControlFlowFor<'a, E = SyncEffect, C = (), B = ()> = <E as Effect>::ControlFlow<'a, C, B>;
@@ -64,20 +60,7 @@ pub type ControlFlowFor<'a, E = SyncEffect, C = (), B = ()> = <E as Effect>::Con
pub enum SyncEffect {}
impl Effect for SyncEffect {
- type ControlFlow<'a, C, B> = Ready<core::ops::ControlFlow<B, C>>;
-
- fn wrap<'a, C, B, F: Future<Output = core::ops::ControlFlow<B, C>> + 'a>(
- future: F,
- ) -> Self::ControlFlow<'a, C, B> {
- let pinned_future = pin!(future);
-
- let waker = noop();
- let mut cx = Context::<'_>::from_waker(&waker);
- match pinned_future.poll(&mut cx) {
- Poll::Ready(value) => Ready::new(value),
- Poll::Pending => panic!("expected future to be ready"),
- }
- }
+ type ControlFlow<'a, C, B> = core::ops::ControlFlow<B, C>;
}
fn noop() -> Waker {
@@ -94,38 +77,4 @@ pub enum AsyncEffect {}
impl Effect for AsyncEffect {
type ControlFlow<'a, C, B> =
core::pin::Pin<Box<dyn core::future::Future<Output = core::ops::ControlFlow<B, C>> + 'a>>;
-
- fn wrap<'a, C, B, F: Future<Output = core::ops::ControlFlow<B, C>> + 'a>(
- future: F,
- ) -> Self::ControlFlow<'a, C, B> {
- Box::pin(future)
- }
-}
-
-#[must_use]
-pub struct Ready<T>(Option<T>);
-
-impl<T> Unpin for Ready<T> {}
-
-impl<T> Future for Ready<T> {
- type Output = T;
-
- #[inline]
- fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
- unsafe {
- Poll::Ready(self.0.take().unwrap_unchecked())
- }
- }
-}
-
-impl<T> Ready<T> {
- pub fn new(value: T) -> Self {
- Self(Some(value))
- }
-
- #[must_use]
- pub fn into_inner(self) -> T {
- unsafe { self.0.unwrap_unchecked() }
- // .expect("Called `into_inner()` on `Ready` after completion")
- }
}
diff --git a/src/walk/walkers/core/array.rs b/src/walk/walkers/core/array.rs
index 73777d0..2709135 100644
--- a/src/walk/walkers/core/array.rs
+++ b/src/walk/walkers/core/array.rs
@@ -10,7 +10,10 @@ use crate::{
},
};
-impl<'ctx, T: crate::Walk<'ctx>, const N: usize> crate::Walk<'ctx> for [T; N] {
+impl<'ctx, T: crate::Walk<'ctx>, const N: usize> crate::Walk<'ctx> for [T; N]
+where
+ <T as crate::Walk<'ctx>>::Walker: crate::Walker<'ctx, Effect = SyncEffect>
+{
type Walker = Walker<'ctx, T, N, T::Walker>;
}
@@ -38,7 +41,7 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> From<[T; N]>
}
}
-impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> crate::Walker<'ctx>
+impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>> crate::Walker<'ctx>
for Walker<'ctx, T, N, W>
{
type Effect = SyncEffect;
@@ -52,21 +55,19 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> crate::Walker<'c
mut self,
visitor: &'a mut Visitor<'a, 'ctx>,
) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error> {
- SyncEffect::wrap(async {
- if let Some(object) = visitor.upcast_mut::<dyn Sequence<'ctx, W::Effect> + '_>() {
- object.visit(&mut self).await;
- }
+ if let Some(object) = visitor.upcast_mut::<dyn Sequence<'ctx, W::Effect> + '_>() {
+ object.visit(&mut self);
+ }
- if let Some((index, error)) = self.item_err {
- ControlFlow::Break(WalkerError { index, error })
- } else {
- ControlFlow::Continue(())
- }
- })
+ if let Some((index, error)) = self.item_err {
+ ControlFlow::Break(WalkerError { index, error })
+ } else {
+ ControlFlow::Continue(())
+ }
}
}
-impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> SequenceScope<'ctx, W::Effect>
+impl<'ctx, T, const N: usize, W: crate::Walker<'ctx, Effect = SyncEffect> + From<T>> SequenceScope<'ctx>
for Walker<'ctx, T, N, W>
{
#[inline]
@@ -74,22 +75,21 @@ impl<'ctx, T, const N: usize, W: crate::Walker<'ctx> + From<T>> SequenceScope<'c
&'a mut self,
visitor: &'a mut Visitor<'a, 'ctx>,
) -> ControlFlowFor<'a, W::Effect, Status> {
- W::Effect::wrap(async {
- if let Some(Some(value)) = self.array.get_mut(self.index).map(Option::take) {
- self.index += 1;
+ if self.index >= N {
+ return ControlFlow::Continue(Status::Done);
+ }
- let walker = W::from(value);
+ let value = unsafe { self.array.get_unchecked_mut(self.index).take().unwrap_unchecked() };
+ self.index += 1;
- match walker.walk(visitor).await {
- ControlFlow::Continue(_) => ControlFlow::Continue(Status::Continue),
- ControlFlow::Break(err) => {
- self.item_err = Some((self.index, err));
- ControlFlow::Continue(Status::Done)
- }
- }
- } else {
+ let walker = W::from(value);
+
+ match walker.walk(visitor) {
+ ControlFlow::Continue(_) => ControlFlow::Continue(Status::Continue),
+ ControlFlow::Break(err) => {
+ self.item_err = Some((self.index, err));
ControlFlow::Continue(Status::Done)
}
- })
+ }
}
}
diff --git a/src/walk/walkers/core/bool.rs b/src/walk/walkers/core/bool.rs
index caa79d2..7d1aca3 100644
--- a/src/walk/walkers/core/bool.rs
+++ b/src/walk/walkers/core/bool.rs
@@ -37,12 +37,12 @@ impl<'ctx> crate::Walker<'ctx> for Walker {
self,
visitor: &'a mut Visitor<'a, 'ctx>,
) -> ControlFlowFor<'a, Self::Effect, Self::Output, Self::Error> {
- SyncEffect::wrap(async {
+ {
if let Some(object) = visitor.upcast_mut::<dyn Value<'_, OwnedStatic<bool>> + '_>() {
- object.visit(OwnedStatic(self.0)).await;
+ object.visit(OwnedStatic(self.0));
}
ControlFlow::Continue(())
- })
+ }
}
}
diff --git a/tests/demo.rs b/tests/demo.rs
index 0f0e190..6db1559 100644
--- a/tests/demo.rs
+++ b/tests/demo.rs
@@ -6,7 +6,7 @@ use treaty::{
into_walker,
protocol::{
visitor::{Sequence, SequenceScope, Value},
- ControlFlowFor, Ready, SyncEffect, Visitor,
+ ControlFlowFor, SyncEffect, Visitor,
},
Builder, Walk, Walker,
};
@@ -19,7 +19,8 @@ fn demo() {
Data::Bool(false),
]);
- // dbg!(array_to_array([true, false, true]));
+ dbg!(array_to_array2([true, false]));
+ dbg!(array_to_array([true, true]));
let s = build_with::<array::Builder<'_, JsonLike, 3>, _>(into_walker(&a)).unwrap();
dbg!(s);
@@ -30,9 +31,14 @@ fn demo() {
// assert_eq!(s, "[true,[false,true,],false,]");
}
-#[no_mangle]
-pub fn array_to_array(x: [bool; 1]) -> [bool; 1] {
- unsafe { build(into_walker(x)).unwrap_unchecked() }
+#[inline(never)]
+pub fn array_to_array(x: [bool; 2]) -> [bool; 2] {
+ build(into_walker(x)).unwrap()
+}
+
+#[inline(never)]
+pub fn array_to_array2(x: [bool; 2]) -> [bool; 2] {
+ array_to_array(x)
}
#[derive(Debug)]
@@ -69,7 +75,7 @@ const _: () = {
Data::Bool(value) => walk_bool(*value, visitor),
Data::Sequence(value) => walk_vec(value, visitor),
}
- Ready::new(core::ops::ControlFlow::Continue(()))
+ core::ops::ControlFlow::Continue(())
}
}
};
@@ -92,13 +98,13 @@ fn walk_vec<'a, 'ctx>(value: &'ctx [Data], visitor: &'a mut Visitor<'a, 'ctx>) {
if let Some(value) = self.0.pop_front() {
into_walker(value).walk(visitor);
- Ready::new(ControlFlow::Continue(
+ ControlFlow::Continue(
treaty::protocol::visitor::Status::Continue,
- ))
+ )
} else {
- Ready::new(ControlFlow::Continue(
+ ControlFlow::Continue(
treaty::protocol::visitor::Status::Done,
- ))
+ )
}
}
}
@@ -138,7 +144,7 @@ any_trait! {
impl Value<'_, OwnedStatic<bool>> for JsonLike {
fn visit(&mut self, value: OwnedStatic<bool>) -> ControlFlowFor<'_> {
self.0.push_str(&format!("{}", value.0));
- Ready::new(ControlFlow::Continue(()))
+ ControlFlow::Continue(())
}
}
@@ -149,11 +155,11 @@ impl<'ctx> Sequence<'ctx> for JsonLike {
) -> ControlFlowFor<'a, SyncEffect> {
self.0.push_str("[");
while let ControlFlow::Continue(treaty::protocol::visitor::Status::Continue) =
- scope.next(self).into_inner()
+ scope.next(self)
{
self.0.push_str(",");
}
self.0.push_str("]");
- Ready::new(ControlFlow::Continue(()))
+ ControlFlow::Continue(())
}
}