Skip to content

Commit 04348c6

Browse files
committed
refactor(core): remove the work-around for [ref:opaque_type_extraneous_capture] and [ref:rust_99793_tait]
`[ref:opaque_type_extraneous_capture]` has been resolved by [rust-lang/rust#95474][1]. TAIT in associated types seems unaffected by `[ref:rust_99793_tait]` (although it might not be so in the general case). [1]: rust-lang/rust#95474
1 parent 67972c7 commit 04348c6

File tree

2 files changed

+16
-133
lines changed

2 files changed

+16
-133
lines changed

doc/toolchain_limitations.md

-52
Original file line numberDiff line numberDiff line change
@@ -554,25 +554,6 @@ const _: () = tokenlock::with_branded_token(|token| {
554554
```
555555

556556

557-
### `[tag:rust_99793_tait]` False-positive "cycle detected" in `const fn` with TAIT
558-
559-
*Upstream issue:* [rust-lang/rust#99793](https://github.com/rust-lang/rust/issues/99793) (possibly related)
560-
561-
```rust
562-
#![feature(type_alias_impl_trait)]
563-
type Unit<T> = impl Copy;
564-
fn unit<T>(x: T) -> Unit<T> { core::mem::forget(x) }
565-
```
566-
567-
```rust,compile_fail,E0391
568-
#![feature(type_alias_impl_trait)]
569-
type Unit<T> = impl Copy;
570-
// error[E0391]: cycle detected when computing type of
571-
// `main::_doctest_main_lib_rs_647_0::Unit::{opaque#0}
572-
const fn unit<T>(x: T) -> Unit<T> { core::mem::forget(x) }
573-
```
574-
575-
576557
## Unsized types
577558

578559
### `[tag:unsized_maybe_uninit]` `MaybeUninit<T>` requires `T: Sized`
@@ -591,39 +572,6 @@ fn foo(_: &core::mem::MaybeUninit<[u8]>) {}
591572
### `[tag:missing_interior_mutability_trait]` Missing trait for representing the lack of interior mutability
592573

593574
*Upstream RFC:* [rust-lang/rfcs#2944](https://github.com/rust-lang/rfcs/pull/2944) (closed)
594-
\
595-
596-
## Existential types
597-
598-
### `[tag:opaque_type_extraneous_capture]` An opaque type captures unused generic type parameters
599-
600-
It may be possible that it's an intended behavior.
601-
602-
```rust
603-
#![feature(type_alias_impl_trait)]
604-
trait Trait {
605-
type Projection: 'static + Send;
606-
fn get(self) -> Self::Projection;
607-
}
608-
type Projection<U: 'static + Send> = impl 'static + Send;
609-
impl<T, U: 'static + Send> Trait for (T, U) {
610-
type Projection = Projection<U>;
611-
fn get(self) -> Self::Projection { self.1 }
612-
}
613-
```
614-
615-
```rust,compile_fail,E0310
616-
#![feature(type_alias_impl_trait)]
617-
trait Trait {
618-
type Projection: 'static + Send;
619-
fn get(self) -> Self::Projection;
620-
}
621-
impl<T, U: 'static + Send> Trait for (T, U) {
622-
// error[E0310]: the parameter type `T` may not live long enough
623-
type Projection = impl 'static + Send;
624-
fn get(self) -> Self::Projection { self.1 }
625-
}
626-
```
627575

628576

629577
## Macros

src/r3_core/src/bind.rs

+16-81
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ macro_rules! impl_fn_bind {
11991199
{
12001200
type Output = Output;
12011201

1202-
type BoundFn = BoundFn<T, $( $RuntimeBinderI, )*>;
1202+
type BoundFn = impl FnOnce() -> Output + Copy + Send + 'static;
12031203

12041204
fn bind(
12051205
self,
@@ -1209,52 +1209,20 @@ macro_rules! impl_fn_bind {
12091209
Binder::register_dependency(&binder, ctx);
12101210

12111211
let intermediate = Binder::into_runtime_binder(binder);
1212-
BoundFn {
1213-
func: self,
1214-
runtime_binders: intermediate,
1212+
move || {
1213+
// Safety: `runtime_binders` was created by the corresponding
1214+
// type's `into_runtime_binder` method.
1215+
// `CfgBindRegistry::finalize` checks that the borrowing
1216+
// rules regarding the materialization output are observed.
1217+
// If the check fails, so does the compilation, and this
1218+
// runtime code will never be executed.
1219+
let ($( $fieldI, )*) = unsafe {
1220+
<( $( $RuntimeBinderI, )* ) as RuntimeBinder>::materialize(intermediate)
1221+
};
1222+
self($( $fieldI, )*)
12151223
}
12161224
}
1217-
}
1218-
1219-
// This opaque type must be defined outside the above `impl` to
1220-
// prevent the unintended capturing of `$BinderI`.
1221-
// [ref:opaque_type_extraneous_capture]
1222-
// type BoundFn<T, Output, $( $RuntimeBinderI, )*>
1223-
// where
1224-
// $( $RuntimeBinderI: RuntimeBinder, )*
1225-
// T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*)
1226-
// -> Output + Copy + Send + 'static,
1227-
// = impl FnOnce() -> Output + Copy + Send + 'static;
1228-
1229-
// FIXME: This is supposed to be a TAIT like the one above, but
1230-
// [ref:rust_99793_tait] prevents that
1231-
#[derive(Copy, Clone)]
1232-
pub struct BoundFn<T, $( $RuntimeBinderI, )*> {
1233-
func: T,
1234-
runtime_binders: ($( $RuntimeBinderI, )*),
1235-
}
1236-
1237-
impl<T, Output, $( $RuntimeBinderI, )*> FnOnce<()> for BoundFn<T, $( $RuntimeBinderI, )*>
1238-
where
1239-
$( $RuntimeBinderI: RuntimeBinder, )*
1240-
T: for<'call> FnOnce($( $RuntimeBinderI::Target<'call>, )*) -> Output,
1241-
{
1242-
type Output = Output;
1243-
1244-
#[inline]
1245-
extern "rust-call" fn call_once(self, (): ()) -> Output {
1246-
// Safety: `runtime_binders` was created by the corresponding
1247-
// type's `into_runtime_binder` method.
1248-
// `CfgBindRegistry::finalize` checks that the borrowing
1249-
// rules regarding the materialization output are observed.
1250-
// If the check fails, so does the compilation, and this
1251-
// runtime code will never be executed.
1252-
let ($( $fieldI, )*) = unsafe {
1253-
<( $( $RuntimeBinderI, )* ) as RuntimeBinder>::materialize(self.runtime_binders)
1254-
};
1255-
(self.func)($( $fieldI, )*)
1256-
}
1257-
}
1225+
} // impl
12581226
}; // const _
12591227
}; // end of macro arm
12601228

@@ -1342,44 +1310,11 @@ where
13421310
{
13431311
type Output = NewOutput;
13441312

1345-
type BoundFn = MappedBoundFn<InnerBoundFn, Mapper>;
1313+
type BoundFn = impl FnOnce() -> NewOutput + Copy + Send + 'static;
13461314

13471315
fn bind(self, binder: Binder, ctx: &mut CfgBindCtx<'_>) -> Self::BoundFn {
1348-
MappedBoundFn {
1349-
inner_bound_fn: self.inner.bind(binder, ctx),
1350-
mapper: self.mapper,
1351-
}
1352-
}
1353-
}
1354-
1355-
// // This opaque type must be defined outside this trait to
1356-
// // prevent the unintended capturing of `Binder`.
1357-
// // [ref:opaque_type_extraneous_capture]
1358-
// type MappedBoundFn<InnerBoundFn, Output, Mapper, NewOutput>
1359-
// where
1360-
// InnerBoundFn: FnOnce() -> Output + Copy + Send + 'static,
1361-
// Mapper: FnOnce(Output) -> NewOutput + Copy + Send + 'static,
1362-
// = impl FnOnce() -> NewOutput + Copy + Send + 'static;
1363-
1364-
// FIXME: This is supposed to be a TAIT like the one above, but
1365-
// [ref:rust_99793_tait] prevents that
1366-
#[doc(hidden)]
1367-
#[derive(Copy, Clone)]
1368-
pub struct MappedBoundFn<InnerBoundFn, Mapper> {
1369-
inner_bound_fn: InnerBoundFn,
1370-
mapper: Mapper,
1371-
}
1372-
1373-
impl<InnerBoundFn, Output, Mapper, NewOutput> FnOnce<()> for MappedBoundFn<InnerBoundFn, Mapper>
1374-
where
1375-
InnerBoundFn: FnOnce() -> Output + Copy + Send + 'static,
1376-
Mapper: FnOnce(Output) -> NewOutput + Copy + Send + 'static,
1377-
{
1378-
type Output = NewOutput;
1379-
1380-
#[inline]
1381-
extern "rust-call" fn call_once(self, (): ()) -> Self::Output {
1382-
(self.mapper)((self.inner_bound_fn)())
1316+
let inner_bound_fn = self.inner.bind(binder, ctx);
1317+
move || (self.mapper)(inner_bound_fn())
13831318
}
13841319
}
13851320

0 commit comments

Comments
 (0)