rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
98.05k stars 12.69k forks source link

ICE: unhandled type `unhandled type: &'{erased} mut Closure` #129127

Open matthiaskrgr opened 2 months ago

matthiaskrgr commented 2 months ago

auto-reduced (treereduce-rust):

pub struct Statement;

pub struct Rows<'stmt>(&'stmt Statement);

impl<'stmt> Iterator for Rows<'stmt> {
    type Item = String;

    fn next() -> Option<Self::Item> {
        let stmt = Statement;
        let rows = Rows(&stmt);
        rows.map(|row| row).next()

        // x
        //
    }
}

fn get_names() -> Option<String> {
    let stmt = Statement;
    let rows = Rows(&stmt);
    rows.map(|row| row).next()

    // x
    //
}
original code

original: ````rust // This is a reduction of a concrete test illustrating a case that was // annoying to Rust developer stephaneyfx (see issue #46413). // With resolving issue #54556, pnkfelix hopes that the new diagnostic // With resolving issue #54556, pnkfelix hopes that the new diagnostic // output produced by NLL helps to *explain* the semantic significance // of temp drop order, and thus why storing the result in `x` and then // returning `x` works. pub struct Statement; pub struct Rows<'stmt>(&'stmt Statement); impl<'stmt> Drop for Option { fn drop(&mut self) {} } impl<'stmt> Iterator for Rows<'stmt> { type Item = String; fn next() -> Option { let stmt = Statement; let rows = Rows(&stmt); //~ ERROR does not live long enough rows.map(|row| row).next() // let x = rows.map(|row| row).next(); // x // // Removing the map works too as does removing the Drop impl. } } fn drop(&mut self) {} fn get_names() -> Option { let stmt = Statement; let rows = Rows(&stmt); //~ ERROR does not live long enough rows.map(|row| row).next() // let x = rows.map(|row| row).next(); // x // // Removing the map works too as does removing the Drop impl. } ````

Version information

rustc 1.82.0-nightly (3139ff09e 2024-08-15)
binary: rustc
commit-hash: 3139ff09e9d07f7700f8d15ed25a231e29c43627
commit-date: 2024-08-15
host: x86_64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0

Command: /home/matthias/.rustup/toolchains/master/bin/rustc -Zmir-opt-level=5 -Zvalidate-mir -Zcross-crate-inline-threshold=always

Program output

``` error[E0601]: `main` function not found in crate `mvce` --> /tmp/icemaker_global_tempdir.NrtTvI7Be5z2/rustc_testrunner_tmpdir_reporting.g9SosB3OsY2q/mvce.rs:25:2 | 25 | } | ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.NrtTvI7Be5z2/rustc_testrunner_tmpdir_reporting.g9SosB3OsY2q/mvce.rs` error[E0186]: method `next` has a `&mut self` declaration in the trait, but not in the impl --> /tmp/icemaker_global_tempdir.NrtTvI7Be5z2/rustc_testrunner_tmpdir_reporting.g9SosB3OsY2q/mvce.rs:8:5 | 8 | fn next() -> Option { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&mut self` in impl | = note: `next` from trait: `fn(&mut Self) -> Option<::Item>` error: internal compiler error: compiler/rustc_mir_transform/src/validate.rs:1491:30: unhandled type: &'{erased} mut Closure(DefId(0:13 ~ mvce[127c]::{impl#0}::next::{closure#0}), ['{erased}, i16, Binder { value: extern "RustCall" fn((std::string::String,)) -> std::string::String, bound_vars: [] }, ()]) thread 'rustc' panicked at compiler/rustc_mir_transform/src/validate.rs:1491:30: Box stack backtrace: 0: 0x72956f1cb7fd - ::fmt::hbd75d7a8055bf739 1: 0x72956fa04059 - core::fmt::write::h5f25313cecccceeb 2: 0x7295709aa9d1 - std::io::Write::write_fmt::h17a84ab5b179ddb5 3: 0x72956f1cdedb - std::panicking::default_hook::{{closure}}::h49f53d56c8f7e527 4: 0x72956f1cdb4e - std::panicking::default_hook::h00ed981b528c65ea 5: 0x72956e354309 - std[e33d86a7a723a6e1]::panicking::update_hook::>::{closure#0} 6: 0x72956f1ce7f7 - std::panicking::rust_panic_with_hook::h3d0aa5d214fe032a 7: 0x72956e38e671 - std[e33d86a7a723a6e1]::panicking::begin_panic::::{closure#0} 8: 0x72956e3816b6 - std[e33d86a7a723a6e1]::sys::backtrace::__rust_end_short_backtrace::::{closure#0}, !> 9: 0x72956e381436 - std[e33d86a7a723a6e1]::panicking::begin_panic:: 10: 0x72956e397651 - ::emit_producing_guarantee 11: 0x72956e95abe4 - rustc_middle[110fa1e98ae6b18b]::util::bug::opt_span_bug_fmt::::{closure#0} 12: 0x72956e9407fa - rustc_middle[110fa1e98ae6b18b]::ty::context::tls::with_opt::::{closure#0}, !>::{closure#0} 13: 0x72956e94068b - rustc_middle[110fa1e98ae6b18b]::ty::context::tls::with_context_opt::::{closure#0}, !>::{closure#0}, !> 14: 0x72956c438250 - rustc_middle[110fa1e98ae6b18b]::util::bug::bug_fmt 15: 0x72956cf744bc - rustc_mir_transform[741e50beaeca447e]::validate::validate_types 16: 0x72956cf5642e - ::run_pass 17: 0x72956dc7e930 - rustc_mir_transform[741e50beaeca447e]::pass_manager::validate_body 18: 0x72956fa02693 - rustc_mir_transform[741e50beaeca447e]::pass_manager::run_passes_inner 19: 0x7295703d47f7 - rustc_mir_transform[741e50beaeca447e]::optimized_mir 20: 0x7295703c1c5d - rustc_query_impl[2d64fd05a0316b8c]::plumbing::__rust_begin_short_backtrace::> 21: 0x72956fa281a7 - rustc_query_system[63eaae8e4727c3d2]::query::plumbing::try_execute_query::>, false, false, false>, rustc_query_impl[2d64fd05a0316b8c]::plumbing::QueryCtxt, false> 22: 0x72956fa2775f - rustc_query_impl[2d64fd05a0316b8c]::query_impl::optimized_mir::get_query_non_incr::__rust_end_short_backtrace 23: 0x72956c537429 - ::instance_mir 24: 0x729570486506 - rustc_interface[5dc7c791b1753136]::passes::run_required_analyses 25: 0x72957054369e - rustc_interface[5dc7c791b1753136]::passes::analysis 26: 0x729570543671 - rustc_query_impl[2d64fd05a0316b8c]::plumbing::__rust_begin_short_backtrace::> 27: 0x72957096a62e - rustc_query_system[63eaae8e4727c3d2]::query::plumbing::try_execute_query::>, false, false, false>, rustc_query_impl[2d64fd05a0316b8c]::plumbing::QueryCtxt, false> 28: 0x72957096a38f - rustc_query_impl[2d64fd05a0316b8c]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace 29: 0x7295707dd0e9 - rustc_interface[5dc7c791b1753136]::interface::run_compiler::, rustc_driver_impl[58349887e35c8b09]::run_compiler::{closure#0}>::{closure#1} 30: 0x7295707c6610 - std[e33d86a7a723a6e1]::sys::backtrace::__rust_begin_short_backtrace::, rustc_driver_impl[58349887e35c8b09]::run_compiler::{closure#0}>::{closure#1}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>>::{closure#0}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>> 31: 0x7295707c6c7a - <::spawn_unchecked_, rustc_driver_impl[58349887e35c8b09]::run_compiler::{closure#0}>::{closure#1}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>>::{closure#0}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[3fe3910426b5ab0e]::result::Result<(), rustc_span[179c096983d138e1]::ErrorGuaranteed>>::{closure#1} as core[3fe3910426b5ab0e]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} 32: 0x7295707c6feb - std::sys::pal::unix::thread::Thread::new::thread_start::h2aa5d6e6e369f96b 33: 0x729571f6639d - 34: 0x729571feb49c - 35: 0x0 - note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md note: please make sure that you have updated to the latest nightly note: rustc 1.82.0-nightly (3139ff09e 2024-08-15) running on x86_64-unknown-linux-gnu note: compiler flags: -Z mir-opt-level=5 -Z validate-mir -Z cross-crate-inline-threshold=always -Z dump-mir-dir=dir query stack during panic: #0 [optimized_mir] optimizing MIR for `get_names` #1 [analysis] running analysis passes on this crate end of query stack error: aborting due to 3 previous errors Some errors have detailed explanations: E0186, E0601. For more information about an error, try `rustc --explain E0186`. ```

matthiaskrgr commented 2 months ago

smaller

//  -Zmir-opt-level=5 -Zvalidate-mir -Zcross-crate-inline-threshold=always
pub struct Rows<'a>();

impl<'a> Iterator for Rows<'a> {
    type Item = ();

    fn next() -> Option<Self::Item> {
        let mut rows = Rows();
        rows.map(|row| row).next()
    }
}

fn main() {
    let mut rows = Rows();
    rows.next();
}