Skip to content
This repository was archived by the owner on May 23, 2024. It is now read-only.

ices/62529-01.rs: fixed with errors #908

Closed
wants to merge 1 commit into from

Conversation

github-actions[bot]
Copy link
Contributor

Issue: rust-lang/rust#62529

// FamilyType (GAT workaround)
pub trait FamilyLt<'a> {
    type Out;
}

struct RefMutFamily<T>(std::marker::PhantomData<T>, ());
impl<'a, T: 'a> FamilyLt<'a> for RefMutFamily<T> {
    type Out = &'a mut T;
}

pub trait Execute {
    type E: Inject;
    fn execute(self, value: <<Self::E as Inject>::I as FamilyLt>::Out);
}

pub trait Inject
where
    Self: Sized,
{
    type I: for<'a> FamilyLt<'a>;
    fn inject(_: &()) -> <Self::I as FamilyLt>::Out;
}

impl<T: 'static> Inject for RefMutFamily<T> {
    type I = Self;
    fn inject(_: &()) -> <Self::I as FamilyLt>::Out {
        unimplemented!()
    }
}

// This struct is only used to give a hint to the compiler about the type `Q`
struct Annotate<Q>(std::marker::PhantomData<Q>);
impl<Q> Annotate<Q> {
    fn new() -> Self {
        Self(std::marker::PhantomData)
    }
}

// This function annotate a closure so it can have Higher-Rank Lifetime Bounds
//
// See 'annotate' workaround: https://github.com/rust-lang/rust/issues/58052
fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
where
    F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
    Q: Inject + 'static,
{
    let wrapper: Wrapper<Q, F> = Wrapper(std::marker::PhantomData, func);
    wrapper
}

struct Wrapper<Q, F>(std::marker::PhantomData<Q>, F);
impl<Q, F> Execute for Wrapper<Q, F>
    where
        Q: Inject,
        F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out),
{
    type E = Q;

    fn execute(self, value: <<Self::E as Inject>::I as FamilyLt>::Out) {
        (self.1)(value)
    }
}

struct Task {
    _processor: Box<dyn FnOnce()>,
}

// This function consume the closure
fn task<P>(processor: P) -> Task
where P: Execute + 'static {
    Task {
        _processor: Box::new(move || {
            let q = P::E::inject(&());
            processor.execute(q);
        })
    }
}

fn main() {
    task(annotate(
        Annotate::<RefMutFamily<usize>>::new(),
        |value: &mut usize| {
            *value = 2;
        }
    ));
}
=== stdout ===
=== stderr ===
error[E0631]: type mismatch in closure arguments
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |     task(annotate(
   |          ^^^^^^^^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
81 |         Annotate::<RefMutFamily<usize>>::new(),
82 |         |value: &mut usize| {
   |         ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
   |
note: required by a bound in `annotate`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:44:8
   |
42 | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
   |    -------- required by a bound in this
43 | where
44 |     F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`

error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |       task(annotate(
   |  __________^
81 | |         Annotate::<RefMutFamily<usize>>::new(),
82 | |         |value: &mut usize| {
83 | |             *value = 2;
84 | |         }
85 | |     ));
   | |_____^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `impl Execute`
note: required by a bound in `task`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:69:9
   |
69 | fn task<P>(processor: P) -> Task
   |         ^ required by this bound in `task`
help: consider relaxing the implicit `Sized` restriction
   |
69 | fn task<P: ?Sized>(processor: P) -> Task
   |          ++++++++

error[E0277]: the trait bound `impl Execute: Execute` is not satisfied
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |       task(annotate(
   |  __________^
81 | |         Annotate::<RefMutFamily<usize>>::new(),
82 | |         |value: &mut usize| {
83 | |             *value = 2;
84 | |         }
85 | |     ));
   | |_____^ the trait `Execute` is not implemented for `impl Execute`
   |
note: required by a bound in `task`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:70:10
   |
69 | fn task<P>(processor: P) -> Task
   |    ---- required by a bound in this
70 | where P: Execute + 'static {
   |          ^^^^^^^ required by this bound in `task`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0277, E0631.
For more information about an error, try `rustc --explain E0277`.
==============

=== stdout ===
=== stderr ===
error[E0631]: type mismatch in closure arguments
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |     task(annotate(
   |          ^^^^^^^^ expected signature of `for<'r> fn(<RefMutFamily<usize> as FamilyLt<'r>>::Out) -> _`
81 |         Annotate::<RefMutFamily<usize>>::new(),
82 |         |value: &mut usize| {
   |         ------------------- found signature of `for<'r> fn(&'r mut usize) -> _`
   |
note: required by a bound in `annotate`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:44:8
   |
42 | fn annotate<F, Q>(_q: Annotate<Q>, func: F) -> impl Execute + 'static
   |    -------- required by a bound in this
43 | where
44 |     F: for<'r> FnOnce(<<Q as Inject>::I as FamilyLt<'r>>::Out) + 'static,
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `annotate`

error[E0277]: the size for values of type `impl Execute` cannot be known at compilation time
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |       task(annotate(
   |  __________^
81 | |         Annotate::<RefMutFamily<usize>>::new(),
82 | |         |value: &mut usize| {
83 | |             *value = 2;
84 | |         }
85 | |     ));
   | |_____^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `impl Execute`
note: required by a bound in `task`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:69:9
   |
69 | fn task<P>(processor: P) -> Task
   |         ^ required by this bound in `task`
help: consider relaxing the implicit `Sized` restriction
   |
69 | fn task<P: ?Sized>(processor: P) -> Task
   |          ++++++++

error[E0277]: the trait bound `impl Execute: Execute` is not satisfied
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:80:10
   |
80 |       task(annotate(
   |  __________^
81 | |         Annotate::<RefMutFamily<usize>>::new(),
82 | |         |value: &mut usize| {
83 | |             *value = 2;
84 | |         }
85 | |     ));
   | |_____^ the trait `Execute` is not implemented for `impl Execute`
   |
note: required by a bound in `task`
  --> /home/runner/work/glacier/glacier/ices/62529-01.rs:70:10
   |
69 | fn task<P>(processor: P) -> Task
   |    ---- required by a bound in this
70 | where P: Execute + 'static {
   |          ^^^^^^^ required by this bound in `task`

error: aborting due to 3 previous errors

Some errors have detailed explanations: E0277, E0631.
For more information about an error, try `rustc --explain E0277`.
==============
@Alexendoo Alexendoo closed this Aug 26, 2021
@Alexendoo Alexendoo deleted the autofix/ices/62529-01.rs branch August 29, 2021 12:49
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants