Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lifetime '2 not defined in error message for "lifetime may not live long enough" #76185

Closed
taladar opened this issue Sep 1, 2020 · 2 comments
Labels
C-bug Category: This is a bug.

Comments

@taladar
Copy link

taladar commented Sep 1, 2020

I tried to return an async block using the parameter value of a closure and got a "lifetime may not be long enough" error message with "returning this value requires that '1 must outlive '2 but it never actually mentioned what it named '2

I tried this code (Edition 2018, Dependencies serenity 0.9.0-rc.0 features framework, standard_framework, rustls_backend, collector and tokio 0.2 with features macros)

use std::{
    collections::HashSet, env,
    time::Duration,
};
use serenity::{
    async_trait,
    collector::MessageCollectorBuilder,
    // Collectors are streams, that means we can use `StreamExt` and
    // `TryStreamExt`.
    futures::stream::StreamExt,
    framework::standard::{
        Args, CommandResult, CommandGroup,
        HelpOptions, help_commands, StandardFramework,
        macros::{command, group, help},
    },
    prelude::*,
    http::Http,
    model::prelude::*,
};

#[group("trivia")]
#[commands(start_trivia)]
struct Trivia;

#[help]
async fn my_help(
    context: &Context,
    msg: &Message,
    args: Args,
    help_options: &'static HelpOptions,
    groups: &[&'static CommandGroup],
    owners: HashSet<UserId>
) -> CommandResult {
    let _ = help_commands::with_embeds(context, msg, args, &help_options, groups, owners).await;
    Ok(())
}

struct Handler;

#[async_trait]
impl EventHandler for Handler {
    async fn ready(&self, _: Context, ready: Ready) {
        println!("{} is connected!", ready.user.name);
    }
}

#[tokio::main]
async fn main() {
    // Configure the client with your Discord bot token in the environment.
    let token = env::var("DISCORD_TOKEN").expect(
        "Expected a token in the environment",
    );

    let http = Http::new_with_token(&token);

    // We will fetch your bot's id.
    let bot_id = match http.get_current_application_info().await {
        Ok(info) => {
            info.id
        },
        Err(why) => panic!("Could not access application info: {:?}", why),
    };

    let framework = StandardFramework::new()
        .configure(|c| c
                   .with_whitespace(true)
                   .on_mention(Some(bot_id))
                   .prefix("~")
                   .delimiters(vec![", ", ","]))
        .help(&MY_HELP)
        .group(&TRIVIA_GROUP);

    let mut client = Client::new(&token)
        .event_handler(Handler)
        .framework(framework)
        .await
        .expect("Err creating client");

    if let Err(why) = client.start().await {
        println!("Client error: {:?}", why);
    }
}

#[command]
async fn start_trivia(ctx: &Context, msg: &Message, _: Args) -> CommandResult {
    let _ =  msg.reply(ctx, "What kind of game are we playing here?").await;

    // We can create a collector from scratch too using this builder future.
    let collector = MessageCollectorBuilder::new(&ctx)
        .channel_id(msg.channel_id)
        .timeout(Duration::from_secs(60))
    // Build the collector.
        .await;

    // Let's acquire borrow HTTP to send a message inside the `async move`.
    let http = &ctx.http;

    collector.skip_while(|msg| async move { msg.content != "trivia" }).take(1usize).then(|msg| async move {
        msg.reply(http, "You got the correct answer").await;
    }).collect::<Vec<_>>().await;

    Ok(())
}

I expected to see this happen:

For it to compile or give a readable error message.

Instead, this happened:

error: lifetime may not live long enough
  --> src/main.rs:98:32
   |
98 |     collector.skip_while(|msg| async move { msg.content != "trivia" }).take(1usize).then(|msg| async move {
   |                           ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
   |                           |  |
   |                           |  return type of closure is impl std::future::Future
   |                           has type `&'1 std::sync::Arc<serenity::model::channel::message::Message>`

error: aborting due to previous error

error: could not compile `discord-trivia`.

Note how it never mentions what it named '2 Presumably it is the return type but it would still be nice to have that actually printed somewhere as part of the error message when names are used that are nowhere in my code.

@taladar taladar added the C-bug Category: This is a bug. label Sep 1, 2020
@SNCPlay42
Copy link
Contributor

See #74497.

@jyn514
Copy link
Member

jyn514 commented Sep 1, 2020

Closing as duplicate of #74497

@jyn514 jyn514 closed this as completed Sep 1, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

3 participants