Skip to content

Commit

Permalink
fix(core): remove another TAIT usage to work around false "cycle dete…
Browse files Browse the repository at this point in the history
…cted" errors

Work-around for [rust-lang/rust#99793][1]. For some reason this one
didn't cause an error in nightly-2022-06-26.

[1]: rust-lang/rust#99793
  • Loading branch information
yvt committed Aug 9, 2022
1 parent 26e7ba7 commit 8cddcae
Showing 1 changed file with 27 additions and 13 deletions.
40 changes: 27 additions & 13 deletions src/r3_core/src/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1339,31 +1339,45 @@ where
{
type Output = NewOutput;

// This opaque type must be defined outside this trait to
// prevent the unintended capturing of `Binder`.
// [ref:opaque_type_extraneous_capture]
type BoundFn = MappedBoundFn<InnerBoundFn, Output, Mapper, NewOutput>;
type BoundFn = MappedBoundFn<InnerBoundFn, Mapper>;

fn bind(self, binder: Binder, ctx: &mut CfgBindCtx<'_>) -> Self::BoundFn {
map_bind_inner(self.inner.bind(binder, ctx), self.mapper)
MappedBoundFn {
inner_bound_fn: self.inner.bind(binder, ctx),
mapper: self.mapper,
}
}
}

type MappedBoundFn<InnerBoundFn, Output, Mapper, NewOutput>
where
InnerBoundFn: FnOnce() -> Output + Copy + Send + 'static,
Mapper: FnOnce(Output) -> NewOutput + Copy + Send + 'static,
= impl FnOnce() -> NewOutput + Copy + Send + 'static;
// // This opaque type must be defined outside this trait to
// // prevent the unintended capturing of `Binder`.
// // [ref:opaque_type_extraneous_capture]
// type MappedBoundFn<InnerBoundFn, Output, Mapper, NewOutput>
// where
// InnerBoundFn: FnOnce() -> Output + Copy + Send + 'static,
// Mapper: FnOnce(Output) -> NewOutput + Copy + Send + 'static,
// = impl FnOnce() -> NewOutput + Copy + Send + 'static;

const fn map_bind_inner<InnerBoundFn, Output, Mapper, NewOutput>(
// FIXME: This is supposed to be a TAIT like the one above, but
// [ref:rust_99793_tait] prevents that
#[doc(hidden)]
#[derive(Copy, Clone)]
pub struct MappedBoundFn<InnerBoundFn, Mapper> {
inner_bound_fn: InnerBoundFn,
mapper: Mapper,
) -> MappedBoundFn<InnerBoundFn, Output, Mapper, NewOutput>
}

impl<InnerBoundFn, Output, Mapper, NewOutput> FnOnce<()> for MappedBoundFn<InnerBoundFn, Mapper>
where
InnerBoundFn: FnOnce() -> Output + Copy + Send + 'static,
Mapper: FnOnce(Output) -> NewOutput + Copy + Send + 'static,
{
move || (mapper)(inner_bound_fn())
type Output = NewOutput;

#[inline]
extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
(self.mapper)((self.inner_bound_fn)())
}
}

// Binder traits
Expand Down

0 comments on commit 8cddcae

Please sign in to comment.