rosefromthedead / effing-mad

Algebraic effects for Rust
579 stars 19 forks source link

Cannot use more than 1 `EffectGroup` in `effectful` attribute macro? #12

Closed teohhanhui closed 3 months ago

teohhanhui commented 3 months ago
#![feature(coroutines)]
#![feature(coroutine_trait)]

use std::borrow::Cow;

use effing_mad::{effectful, handle_group, handler};
use steamctl::cli_options::{options, Options};

effing_mad::effects! {
    Console<'a> {
        fn print(s: Cow<'a, str>) -> ();
    }
}

effing_mad::effects! {
    CliOptions {
        fn read() -> Options;
    }
}

fn main() {
    let console_handler = handler!(Console {
        print(s, _) => println!("{s}"),
    });
    let with_console = handle_group(do_command(), console_handler);
    let cli_options_handler = handler!(CliOptions {
        read() => options().run(),
    });
    let with_cli_options = handle_group(with_console, cli_options_handler);

    effing_mad::run(with_cli_options);
}

#[effectful(CliOptions, Console<'a>)]
fn do_command<'a>() {
    let options = yield CliOptions::read();
    yield Console::print(format!("{options:?}").into());
}

cargo clippy -- --verbose &> clippy.log:

clippy.log

``` Checking steamctl v0.1.0 (/home/teohhanhui/Projects/teohhanhui/steamctl-rs) error[E0277]: the trait bound `Console<'a>: effing_mad::Effect` is not satisfied --> src/bin/steamctl.rs:34:1 | 34 | #[effectful(CliOptions, Console<'a>)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `effing_mad::Effect` is not implemented for `Console<'a>`, which is required by `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>: effing_mad::injection::EffectList` | = help: the following other types implement trait `effing_mad::Effect`: print<'a> effing_mad::effects::future::Await effing_mad::effects::future::GetContext read = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>` to implement `effing_mad::injection::EffectList` error[E0277]: the trait bound `effing_mad::frunk::coproduct::CNil: effing_mad::frunk::coproduct::CoprodUninjector>, _>` is not satisfied --> src/bin/steamctl.rs:34:1 | 34 | #[effectful(CliOptions, Console<'a>)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `effing_mad::frunk::coproduct::CoprodUninjector>, _>` is not implemented for `effing_mad::frunk::coproduct::CNil`, which is required by `effing_mad::frunk::Coproduct, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>: effing_mad::frunk::coproduct::CoprodUninjector>, _>` | = help: the following other types implement trait `effing_mad::frunk::coproduct::CoprodUninjector`: as effing_mad::frunk::coproduct::CoprodUninjector> as effing_mad::frunk::coproduct::CoprodUninjector>> = note: required for `effing_mad::frunk::Coproduct` to implement `effing_mad::frunk::coproduct::CoprodUninjector>, effing_mad::frunk::indices::There<_>>` = note: 2 redundant requirements hidden = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>` to implement `effing_mad::frunk::coproduct::CoprodUninjector>, effing_mad::frunk::indices::There>>>` note: required by a bound in `effing_mad::macro_impl::get_inj` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/macro_impl.rs:30:11 | 27 | pub fn get_inj(injs: Injs, _marker: PhantomData) -> Option | ------- required by a bound in this function ... 30 | Injs: CoprodUninjector, Index>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `get_inj` = note: this error originates in the attribute macro `effectful` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `effing_mad::frunk::coproduct::CNil: effing_mad::frunk::coproduct::CoprodInjector, _>` is not satisfied --> src/bin/steamctl.rs:34:1 | 34 | #[effectful(CliOptions, Console<'a>)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `effing_mad::frunk::coproduct::CoprodInjector, _>` is not implemented for `effing_mad::frunk::coproduct::CNil`, which is required by `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>>: effing_mad::frunk::coproduct::CoprodInjector, _>` | = help: the following other types implement trait `effing_mad::frunk::coproduct::CoprodInjector`: as effing_mad::frunk::coproduct::CoprodInjector>> as effing_mad::frunk::coproduct::CoprodInjector> = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>` to implement `effing_mad::frunk::coproduct::CoprodInjector, effing_mad::frunk::indices::There<_>>` = note: 1 redundant requirement hidden = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>>` to implement `effing_mad::frunk::coproduct::CoprodInjector, effing_mad::frunk::indices::There>>` note: required by a bound in `effing_mad::frunk::Coproduct::::inject` --> /home/teohhanhui/.cargo/registry/src/index.crates.io-6f17d22bba15001f/frunk_core-0.4.2/src/coproduct.rs:166:15 | 164 | pub fn inject(to_insert: T) -> Self | ------ required by a bound in this associated function 165 | where 166 | Self: CoprodInjector, | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Coproduct::::inject` = note: this error originates in the attribute macro `effectful` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: the trait bound `Console<'_>: effing_mad::Effect` is not satisfied --> src/bin/steamctl.rs:25:37 | 25 | let with_console = handle_group(do_command(), console_handler); | ------------ ^^^^^^^^^^^^ the trait `effing_mad::Effect` is not implemented for `Console<'_>`, which is required by `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>: effing_mad::injection::EffectList` | | | required by a bound introduced by this call | = help: the following other types implement trait `effing_mad::Effect`: print<'a> effing_mad::effects::future::Await effing_mad::effects::future::GetContext read = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>` to implement `effing_mad::injection::EffectList` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:208:8 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 208 | G: Coroutine, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0277]: the trait bound `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield: effing_mad::injection::EffectList` is not satisfied --> src/bin/steamctl.rs:25:24 | 25 | let with_console = handle_group(do_command(), console_handler); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `effing_mad::injection::EffectList` is not implemented for `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` | = help: the following other types implement trait `effing_mad::injection::EffectList`: effing_mad::frunk::Coproduct effing_mad::frunk::coproduct::CNil note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:204:12 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 204 | PreEs: EffectList + CoproductSubsetter, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:25:51 | 22 | let console_handler = handler!(Console { | ___________________________- 23 | | print(s, _) => println!("{s}"), 24 | | }); | |______- found signature defined here 25 | let with_console = handle_group(do_command(), console_handler); | ------------ ^^^^^^^^^^^^^^^ expected due to this | | | required by a bound introduced by this call | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` help: consider wrapping the function in a closure | 25 | let with_console = handle_group(do_command(), |arg0: effing_mad::frunk::coproduct::CNil| console_handler(/* effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil> */)); | ++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:25:24 | 22 | let console_handler = handler!(Console { | ___________________________- 23 | | print(s, _) => println!("{s}"), 24 | | }); | |______- found signature defined here 25 | let with_console = handle_group(do_command(), console_handler); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0277]: the trait bound `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield: effing_mad::injection::EffectList` is not satisfied --> src/bin/steamctl.rs:29:28 | 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^ the trait `effing_mad::injection::EffectList` is not implemented for `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` | = help: the following other types implement trait `effing_mad::injection::EffectList`: effing_mad::frunk::Coproduct effing_mad::frunk::coproduct::CNil note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:204:12 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 204 | PreEs: EffectList + CoproductSubsetter, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0277]: the trait bound `Console<'_>: effing_mad::Effect` is not satisfied --> src/bin/steamctl.rs:29:28 | 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^ the trait `effing_mad::Effect` is not implemented for `Console<'_>`, which is required by `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>: effing_mad::injection::EffectList` | = help: the following other types implement trait `effing_mad::Effect`: print<'a> effing_mad::effects::future::Await effing_mad::effects::future::GetContext read = note: required for `effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>` to implement `effing_mad::injection::EffectList` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:208:8 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 208 | G: Coroutine, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:29:28 | 22 | let console_handler = handler!(Console { | ___________________________- 23 | | print(s, _) => println!("{s}"), 24 | | }); | |______- found signature defined here ... 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0277]: the trait bound `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield: effing_mad::injection::EffectList` is not satisfied --> src/bin/steamctl.rs:29:28 | 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `effing_mad::injection::EffectList` is not implemented for `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` | = help: the following other types implement trait `effing_mad::injection::EffectList`: effing_mad::frunk::Coproduct effing_mad::frunk::coproduct::CNil note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:204:12 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 204 | PreEs: EffectList + CoproductSubsetter, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:29:55 | 26 | let cli_options_handler = handler!(CliOptions { | _______________________________- 27 | | read() => options().run(), 28 | | }); | |______- found signature defined here 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ------------ ^^^^^^^^^^^^^^^^^^^ expected due to this | | | required by a bound introduced by this call | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` help: consider wrapping the function in a closure | 29 | let with_cli_options = handle_group(with_console, |arg0: effing_mad::frunk::coproduct::CNil| cli_options_handler(/* effing_mad::frunk::Coproduct */)); | ++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:29:28 | 26 | let cli_options_handler = handler!(CliOptions { | _______________________________- 27 | | read() => options().run(), 28 | | }); | |______- found signature defined here 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:29:28 | 22 | let console_handler = handler!(Console { | ___________________________- 23 | | print(s, _) => println!("{s}"), 24 | | }); | |______- found signature defined here ... 29 | let with_cli_options = handle_group(with_console, cli_options_handler); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0271]: type mismatch resolving `, Yield = > as FlattenEffects>::Out as EffectList>::Injections, Yield = ..., Return = ...> as Coroutine<...>>::Yield> as Coroutine<...>>::Yield == CNil` --> src/bin/steamctl.rs:31:21 | 31 | effing_mad::run(with_cli_options); | --------------- ^^^^^^^^^^^^^^^^ expected `CNil`, found associated type | | | required by a bound introduced by this call ... 34 | #[effectful(CliOptions, Console<'a>)] | ------------------------------------- the found opaque type | = note: expected enum `effing_mad::frunk::coproduct::CNil` found associated type `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` note: required by a bound in `effing_mad::run` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:77:42 | 75 | pub fn run(mut f: F) -> R | --- required by a bound in this function 76 | where 77 | F: Coroutine, Yield = CNil, Return = R>, | ^^^^^^^^^^^^ required by this bound in `run` help: consider constraining the associated type `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` to `effing_mad::frunk::coproduct::CNil` | 34 | #[effectful(CliOptions, Console<'a>)] | ++++++++++++++++++++++++++++++++++++++++++++ error[E0277]: the trait bound `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield: effing_mad::injection::EffectList` is not satisfied --> src/bin/steamctl.rs:31:5 | 31 | effing_mad::run(with_cli_options); | ^^^^^^^^^^^^^^^ the trait `effing_mad::injection::EffectList` is not implemented for `, effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out as effing_mad::injection::EffectList>::Injections, Yield = , effing_mad::frunk::coproduct::CNil>> as effing_mad::macro_impl::FlattenEffects>::Out, Return = ()> as std::ops::Coroutine, effing_mad::frunk::Coproduct>, effing_mad::frunk::Coproduct>>>>::Yield` | = help: the following other types implement trait `effing_mad::injection::EffectList`: effing_mad::frunk::Coproduct effing_mad::frunk::coproduct::CNil note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:204:12 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 204 | PreEs: EffectList + CoproductSubsetter, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:31:5 | 26 | let cli_options_handler = handler!(CliOptions { | _______________________________- 27 | | read() => options().run(), 28 | | }); | |______- found signature defined here ... 31 | effing_mad::run(with_cli_options); | ^^^^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` error[E0631]: type mismatch in closure arguments --> src/bin/steamctl.rs:31:5 | 22 | let console_handler = handler!(Console { | ___________________________- 23 | | print(s, _) => println!("{s}"), 24 | | }); | |______- found signature defined here ... 31 | effing_mad::run(with_cli_options); | ^^^^^^^^^^^^^^^ expected due to this | = note: expected closure signature `fn(effing_mad::frunk::coproduct::CNil) -> _` found closure signature `fn(effing_mad::frunk::Coproduct, effing_mad::frunk::coproduct::CNil>) -> _` note: required by a bound in `effing_mad::handle_group` --> /home/teohhanhui/.cargo/git/checkouts/effing-mad-e103e8f2d0b7efef/770c85e/src/lib.rs:199:36 | 184 | pub fn handle_group< | ------------ required by a bound in this function ... 199 | mut handler: impl FnMut(Es) -> ControlFlow, | ^^^^^^^^^^^^^^^^^^ required by this bound in `handle_group` Some errors have detailed explanations: E0271, E0277, E0631. For more information about an error, try `rustc --explain E0271`. error: could not compile `steamctl` (bin "steamctl") due to 18 previous errors ```

Using 1 EffectGroup + 1 Effect works though...

rosefromthedead commented 3 months ago

Can reproduce. Could you try with the latest commit? 6da8bf5c1fd4f305cb70f44ac7ac35e98007e878 should fix it.

teohhanhui commented 3 months ago

That works. Thank you!

I have another question:

    let console_handler = handler!(Console {
        print(s, _) => println!("{s}"),
    });

Is the PhantomData<Console<'_>> here useful in the effect handler? I thought it's only for tagging as a marker...

EDIT: Oh, I think I understand now. This is just a consequence of pattern matching... Haha.

Indeed the macro gets expanded as:

|effs: <Console as ::effing_mad::EffectGroup> ::Effects|{
    let __effing_inj = match effs.uninject(){
        Ok(print(s,_)) => {
            let __effing_inj = {
                $crate::io::_print(builtin #format_args("{s}"));
            };
            #[allow(unreachable_code)]
            ::effing_mad::frunk::Coproduct::inject(::effing_mad::injection::Tagged:: <_,print> ::new(__effing_inj))
        },
        Err(effs) => match effs{}
        ,

        };
    #[allow(unreachable_code)]
    ::core::ops::ControlFlow:: <_,_> ::Continue(__effing_inj)
}

Hmm... But here we already push the PhantomData to the end of the tuple struct elements?

https://github.com/rosefromthedead/effing-mad/blob/f0022807465b577842aacbde44a52ef33b28f454/effing-macros/src/lib.rs#L489

Maybe it's just a parsing error then...

rosefromthedead commented 3 months ago

That part of the macro only runs if the effect name has angle brackets in it, so since you're eliding the lifetime on Console the PhantomData isn't handled for you. This isn't intentional (and I didn't see it coming), but I don't think there's much the macro can do about it. Maybe if all effects had a PhantomData inserted, and non-generic ones just had PhantomData<()>, we could unconditionally insert the field initialiser...

teohhanhui commented 3 months ago

That part of the macro only runs if the effect name has angle brackets in it, so since you're eliding the lifetime on Console the PhantomData isn't handled for you.

FWIW, this works fine:

    let console_handler = handler!(Console<'_> {
        print(s) => println!("{s}"),
    });

Maybe if all effects had a PhantomData inserted, and non-generic ones just had PhantomData<()>, we could unconditionally insert the field initialiser...

This is actually not a sensible solution, as it'd be an unexpected surprise when trying to use handler! with hand-rolled effect types...