poise icon indicating copy to clipboard operation
poise copied to clipboard

the trait bound `poise::serenity_prelude::Context: AsRef<poise::serenity_prelude::Context>` is not satisfied

Open sarahkittyy opened this issue 4 months ago • 9 comments

What is this error? I am trying to use poise::execute_modal_on_component_interaction.

Here is my function:

pub async fn dispatch(ctx: &serenity::Context, mci: &ComponentInteraction) -> Result<(), Error> {
    match mci.data.custom_id.as_str() {
        "birthday.submit" => {
            let data: Option<AgeModal> =
                poise::execute_modal_on_component_interaction(ctx, mci.clone(), None, None).await?;
        }
        _ => (),
    }
    Ok(())
}

And my error is:

error[E0277]: the trait bound `poise::serenity_prelude::Context: AsRef<poise::serenity_prelude::Context>` is not satisfied
   --> src\discord\on_component_interaction.rs:12:63
    |
12  |                 poise::execute_modal_on_component_interaction(ctx, mci.clone(), None, None).await?;
    |                 --------------------------------------------- ^^^ the trait `AsRef<poise::serenity_prelude::Context>` is not implemented for `poise::serenity_prelude::Context`
    |                 |
    |                 required by a bound introduced by this call
    |
    = help: the following other types implement trait `AsRef<T>`:
              <poise::serenity_prelude::Context as AsRef<Arc<Cache>>>
              <poise::serenity_prelude::Context as AsRef<Arc<poise::serenity_prelude::Http>>>
              <poise::serenity_prelude::Context as AsRef<Cache>>
              <poise::serenity_prelude::Context as AsRef<ShardMessenger>>
              <poise::serenity_prelude::Context as AsRef<poise::serenity_prelude::Http>>
    = note: required for `&poise::serenity_prelude::Context` to implement `AsRef<poise::serenity_prelude::Context>`
note: required by a bound in `execute_modal_on_component_interaction`
   --> C:\Users\sarah\.cargo\registry\src\index.crates.io-6f17d22bba15001f\poise-0.6.1\src\modal.rs:123:15
    |
122 | pub async fn execute_modal_on_component_interaction<M: Modal>(
    |              -------------------------------------- required by a bound in this function
123 |     ctx: impl AsRef<serenity::Context>,
    |               ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `execute_modal_on_component_interaction`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `girlpound-bot` (bin "girlpound-bot") due to 1 previous error

What is happening? I know in general there is no blanket impl AsRef<T> for &T in Rust because of some sort of conflict, but what do I do in this case? I feel like I am missing something obvious.

sarahkittyy avatar Mar 01 '24 07:03 sarahkittyy

It's possible your Cargo.toml contains a different serenity version than the one poise uses, which means the two mismatching serenity Context types only mismatch because they're of two different versions.. Poise 0.6 needs Serenity 0.12. Is that the case in your Cargo.toml?

kangalio avatar Mar 01 '24 07:03 kangalio

There is no serenity in my Cargo.toml. I am using the one that comes in the poise crate. The types are the same. Rust does not have a blanket impl AsRef<T> for &T. To solve this I had to implement execute_model_generic myself.

sarahkittyy avatar Mar 01 '24 09:03 sarahkittyy

@kangalio See https://doc.rust-lang.org/std/convert/trait.AsRef.html#reflexivity

sarahkittyy avatar Mar 01 '24 09:03 sarahkittyy

Please attach your Cargo.lock file, so we can see if you have duplicate dependencies.

GnomedDev avatar Mar 01 '24 10:03 GnomedDev

Here. Poise 0.6.1 and Serenity 0.12.1. Cargo.lock.txt

The problem is not duplicate dependencies. The types are the same. AsRef<poise::serenity_prelude::Context> is NOT implemented for poise::serenity_prelude::Context. This is a known quirk of the rust language.

See https://doc.rust-lang.org/std/convert/trait.AsRef.html#reflexivity Also see this minimal example

To fix this I copied the existing but private execute_modal_generic here into my own code.

sarahkittyy avatar Mar 01 '24 10:03 sarahkittyy

I'm not a Rust pro but maybe this should be impl Into<> or Deref<> or Borrow<> instead? Or maybe impl CacheHttp.

sarahkittyy avatar Mar 01 '24 10:03 sarahkittyy

It shouldn't be AsRef in the first place, it should just be &serenity::Context, I'll make that change now. Anyway, for now can't you just pass &serenity::Context?

GnomedDev avatar Mar 01 '24 10:03 GnomedDev

No! You cannot pass &serenity::Context to a parameter of type impl AsRef<serenity::Context> because as per my last comments, &T does not implement the trait AsRef<T>. You would think it would, but it doesn't. See https://doc.rust-lang.org/std/convert/trait.AsRef.html#reflexivity.

Changing execute_modal_on_component_interaction's first argument to &serenity::Context instead of impl AsRef<serenity::Context> will fix this issue. Thanks ^^

sarahkittyy avatar Mar 01 '24 10:03 sarahkittyy

That is so weird.

GnomedDev avatar Mar 01 '24 10:03 GnomedDev