Skip to content

Commit

Permalink
fix(core): remove TAIT usage to work around false "cycle detected" er…
Browse files Browse the repository at this point in the history
…rors

Work-around for [rust-lang/rust#99793][1].

[1]: rust-lang/rust#99793
  • Loading branch information
yvt committed Aug 9, 2022
1 parent e3c5024 commit 6136058
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 24 deletions.
19 changes: 19 additions & 0 deletions doc/toolchain_limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,25 @@ const _: () = tokenlock::with_branded_token(|token| {
```


### `[tag:rust_99793_tait]` False-positive "cycle detected" in `const fn` with TAIT

*Upstream issue:* [rust-lang/rust#99793](https://github.com/rust-lang/rust/issues/99793) (possibly related)

```rust
#![feature(type_alias_impl_trait)]
type Unit<T> = impl Copy;
fn unit<T>(x: T) -> Unit<T> { core::mem::forget(x) }
```

```rust,compile_fail,E0391
#![feature(type_alias_impl_trait)]
type Unit<T> = impl Copy;
// error[E0391]: cycle detected when computing type of
// `main::_doctest_main_lib_rs_647_0::Unit::{opaque#0}
const fn unit<T>(x: T) -> Unit<T> { core::mem::forget(x) }
```


## Unsized types

### `[tag:unsized_maybe_uninit]` `MaybeUninit<T>` requires `T: Sized`
Expand Down
53 changes: 29 additions & 24 deletions src/r3_core/src/bind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1196,10 +1196,7 @@ macro_rules! impl_fn_bind {
{
type Output = Output;

// This opaque type must be defined outside this trait to
// prevent the unintended capturing of `$BinderI`.
// [ref:opaque_type_extraneous_capture]
type BoundFn = BoundFn<T, Output, $( $RuntimeBinderI, )*>;
type BoundFn = BoundFn<T, $( $RuntimeBinderI, )*>;

fn bind(
self,
Expand All @@ -1209,42 +1206,50 @@ macro_rules! impl_fn_bind {
Binder::register_dependency(&binder, ctx);

let intermediate = Binder::into_runtime_binder(binder);
bind_inner(self, intermediate)
BoundFn {
func: self,
runtime_binders: intermediate,
}
}
}

type BoundFn<T, Output, $( $RuntimeBinderI, )*>
where
$( $RuntimeBinderI: RuntimeBinder, )*
T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*)
-> Output + Copy + Send + 'static,
= impl FnOnce() -> Output + Copy + Send + 'static;

const fn bind_inner<
T,
Output,
$( $RuntimeBinderI, )*
>(
// This opaque type must be defined outside the above `impl` to
// prevent the unintended capturing of `$BinderI`.
// [ref:opaque_type_extraneous_capture]
// type BoundFn<T, Output, $( $RuntimeBinderI, )*>
// where
// $( $RuntimeBinderI: RuntimeBinder, )*
// T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*)
// -> Output + Copy + Send + 'static,
// = impl FnOnce() -> Output + Copy + Send + 'static;

// FIXME: This is supposed to be a TAIT like the one above, but
// [ref:rust_99793_tait] prevents that
#[derive(Copy, Clone)]
pub struct BoundFn<T, $( $RuntimeBinderI, )*> {
func: T,
runtime_binders: ( $( $RuntimeBinderI, )* ),
) -> BoundFn<T, Output, $( $RuntimeBinderI, )*>
runtime_binders: ($( $RuntimeBinderI, )*),
}

impl<T, Output, $( $RuntimeBinderI, )*> FnOnce<()> for BoundFn<T, $( $RuntimeBinderI, )*>
where
$( $RuntimeBinderI: RuntimeBinder, )*
T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*)
-> Output + Copy + Send + 'static,
T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*) -> Output,
{
type Output = Output;

#[inline]
move || {
extern "rust-call" fn call_once(self, (): ()) -> Output {
// Safety: `runtime_binders` was created by the corresponding
// type's `into_runtime_binder` method.
// `CfgBindRegistry::finalize` checks that the borrowing
// rules regarding the materialization output are observed.
// If the check fails, so does the compilation, and this
// runtime code will never be executed.
let ($( $fieldI, )*) = unsafe {
<( $( $RuntimeBinderI, )* ) as RuntimeBinder>::materialize(runtime_binders)
<( $( $RuntimeBinderI, )* ) as RuntimeBinder>::materialize(self.runtime_binders)
};
func($( $fieldI, )*)
(self.func)($( $fieldI, )*)
}
}
}; // const _
Expand Down
2 changes: 2 additions & 0 deletions src/r3_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#![feature(const_nonnull_new)]
#![feature(const_result_drop)]
#![feature(const_slice_index)]
#![feature(unboxed_closures)] // `impl FnOnce`
#![feature(const_option_ext)]
#![feature(const_trait_impl)]
#![feature(const_ptr_write)]
Expand All @@ -48,6 +49,7 @@
#![feature(decl_macro)]
#![feature(never_type)] // `!`
#![feature(const_try)]
#![feature(fn_traits)] // `impl FnOnce`
#![feature(let_else)]
#![feature(doc_cfg)] // `#[doc(cfg(...))]`
#![cfg_attr(test, feature(is_sorted))]
Expand Down

0 comments on commit 6136058

Please sign in to comment.