Skip to content

rustc panicked when reference a moved variable in a closure #129951

Closed

Description

Code

use sqlx::{mysql::MySqlPoolOptions, MySql, QueryBuilder};
use std::fmt::Debug;
use std::{future::Future, sync::Arc};
use tokio::sync::mpsc::UnboundedReceiver;

fn main() {
    let tokio = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .unwrap();

    tokio.block_on(async {
        let logger = Arc::new(Logger(MySqlPoolOptions::new().connect("").await.unwrap()));
        let (tx, rx) = tokio::sync::mpsc::unbounded_channel();

        logger.foo(rx).await;
    })
}

struct Logger(sqlx::Pool<MySql>);

impl Logger {
    pub fn foo(self: Arc<Self>, logs: UnboundedReceiver<Log>) -> impl Future<Output = ()> {
        let mut buf = [0u8; 4]; // This one caused the error.
        let query = "INSERT INTO foo (bar) ";

        self.clone().main(logs, query, move |mut b, l| {
            let bar: &str = l.bar.encode_utf8(&mut buf);

            b.push_bind(bar);
        })
    }

    async fn main<'c, T, F>(
        self: Arc<Self>,
        mut chan: UnboundedReceiver<T>,
        query: &'static str,
        mut append: F,
    ) where
        T: Debug,
        F: for<'a, 'b> FnMut(sqlx::query_builder::Separated<'a, 'b, MySql, &'static str>, &'b T)
            + 'c,
    {
        let mut logs = Vec::new();

        loop {
            // Wait for logs.
            if chan.recv_many(&mut logs, 50).await == 0 {
                break;
            }

            // Append query.
            let mut query = QueryBuilder::new(query);

            query.push_values(&logs, &mut append);

            // Execute.
            if let Err(e) = query.build().execute(&self.0).await {
                eprintln!("Failed to log {:?}: {}.", logs, e);
            }

            // Reset states.
            logs.clear();
        }
    }
}

#[derive(Debug)]
struct Log {
    bar: char,
}

Cargo project for the above code: https://github.com/ultimaweapon/rustc-bug

It working if I remove the let mut buf = [0u8; 4];.

Meta

rustc --version --verbose:

rustc 1.80.1 (3f5fd8dd4 2024-08-06)
binary: rustc
commit-hash: 3f5fd8dd41153bc5fdca9427e9e05be2c767ba23
commit-date: 2024-08-06
host: x86_64-unknown-linux-gnu
release: 1.80.1
LLVM version: 18.1.7

Error output

thread 'rustc' panicked at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/compiler/rustc_type_ir/src/binder.rs:780:9:
expected region for `'c/#0` ('c/#0/0) but found Type(std::sync::Arc<Logger, std::alloc::Global>) when instantiating args=[std::sync::Arc<Logger, std::alloc::Global>, ?3t, Closure(DefId(0:20 ~ rustc_bug[e02e]::{impl#0}::foo::{closure#0}), [i16, Binder(fn((sqlx::query_builder::Separated<ReLateParam(DefId(0:20 ~ rustc_bug[e02e]::{impl#0}::foo::{closure#0}), BrAnon), ReLateParam(DefId(0:20 ~ rustc_bug[e02e]::{impl#0}::foo::{closure#0}), BrAnon), sqlx::MySql, &'{erased} str>, &ReLateParam(DefId(0:20 ~ rustc_bug[e02e]::{impl#0}::foo::{closure#0}), BrAnon) Log)), []), ([u8; 4_usize],)])]
Backtrace

   0: rust_begin_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:72:14
   2: <rustc_type_ir::binder::ArgFolder<rustc_middle::ty::context::TyCtxt>>::region_param_expected
   3: <rustc_middle::ty::predicate::Clause as rustc_type_ir::fold::TypeFoldable<rustc_middle::ty::context::TyCtxt>>::try_fold_with::<rustc_type_ir::binder::ArgFolder<rustc_middle::ty::context::TyCtxt>>
   4: <rustc_middle::ty::generics::GenericPredicates>::instantiate_into
   5: <rustc_middle::ty::generics::GenericPredicates>::instantiate
   6: <rustc_borrowck::MirBorrowckCtxt>::report_general_error
   7: <rustc_borrowck::MirBorrowckCtxt>::report_region_error
   8: rustc_borrowck::do_mir_borrowck
      [... omitted 1 frame ...]
   9: <rustc_borrowck::type_check::TypeChecker>::prove_closure_bounds
  10: <rustc_borrowck::type_check::TypeChecker>::typeck_mir
  11: rustc_borrowck::type_check::type_check
  12: rustc_borrowck::nll::compute_regions
  13: rustc_borrowck::do_mir_borrowck
      [... omitted 1 frame ...]
  14: rustc_hir_analysis::collect::type_of::type_of_opaque
      [... omitted 1 frame ...]
  15: rustc_hir_analysis::collect::type_of::type_of
      [... omitted 1 frame ...]
  16: rustc_hir_analysis::check::wfcheck::check_well_formed
      [... omitted 1 frame ...]
  17: rustc_hir_analysis::check::wfcheck::check_mod_type_wf
      [... omitted 1 frame ...]
  18: rustc_hir_analysis::check_crate
  19: rustc_interface::passes::analysis
      [... omitted 1 frame ...]
  20: rustc_interface::interface::run_compiler::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#1}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions