rust-lang / rust-lang/rust

Custom MIR: ICE on assigning to reference in enum variant

Open
#119,940 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

-Zvalidate-mir A-MIR C-bug I-ICE requires-internal-features S-bug-has-test T-compiler
Dominant language
Rust
Stars
119k
Forks
16.2k
PR merge metrics
PR metrics pending

Description

#![feature(custom_mir, core_intrinsics)]
extern crate core;
use core::intrinsics::mir::*;

pub enum E {
    V0 { fld0: &'static u64 },
}

#[custom_mir(dialect = "runtime", phase = "initial")]
pub fn fn0() {
    mir! {
    let e: E;
    let n: u64;
    {
        n = 0;
        place!(Field::<&u64>(Variant(e, 0), 0)) = &n;
        Return()
    }

    }
}
pub fn main() {
    fn0();
}

Only ICE with -Zmir-opt-level=0. Not sure if this is a real bug or not. Maybe certain MIR passes is required for correctness?

% rustc -Zmir-opt-level=0 repro.rs
...
    error: internal compiler error: broken MIR in Item(DefId(0:8 ~ repro[d2aa]::fn0)) (after phase change to runtime-optimized) at bb0[0]:
                                    Free regions in optimized runtime-optimized MIR
      --> /Users/andy/Code/rustlantis/repro.rs:15:9
       |
    15 |         n = 0;
       |         ^^^^^
       |
    note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:91:33
             0: std::backtrace::Backtrace::create
             1: <rustc_errors::DiagCtxtInner>::emit_diagnostic
             2: <rustc_errors::DiagCtxt>::emit_diagnostic
             3: <rustc_errors::diagnostic_builder::DiagnosticBuilder>::emit_producing_error_guaranteed
             4: <rustc_const_eval::transform::validate::CfgChecker>::fail::<alloc::string::String>
             5: <rustc_const_eval::transform::validate::Validator as rustc_middle::mir::MirPass>::run_pass
             6: rustc_mir_transform::pass_manager::run_passes_inner
             7: rustc_mir_transform::optimized_mir
             8: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::optimized_mir::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
             9: <rustc_query_impl::query_impl::optimized_mir::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, rustc_span::def_id::DefId)>>::call_once
            10: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 8]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            11: rustc_query_impl::query_impl::optimized_mir::get_query_non_incr::__rust_end_short_backtrace
            12: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 8]>>>
            13: rustc_mir_transform::cross_crate_inline::cross_crate_inlinable
            14: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::cross_crate_inlinable::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 1]>>
            15: <rustc_query_impl::query_impl::cross_crate_inlinable::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, rustc_span::def_id::DefId)>>::call_once
            16: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 1]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            17: rustc_query_impl::query_impl::cross_crate_inlinable::get_query_non_incr::__rust_end_short_backtrace
            18: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 1]>>>
            19: rustc_passes::reachable::reachable_set
            20: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::reachable_set::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
            21: <rustc_query_impl::query_impl::reachable_set::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, ())>>::call_once
            22: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 8]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            23: rustc_query_impl::query_impl::reachable_set::get_query_non_incr::__rust_end_short_backtrace
            24: rustc_codegen_ssa::back::symbol_export::reachable_non_generics_provider
            25: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::reachable_non_generics::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 8]>>
            26: <rustc_query_impl::query_impl::reachable_non_generics::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, rustc_span::def_id::CrateNum)>>::call_once
            27: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::VecCache<rustc_span::def_id::CrateNum, rustc_middle::query::erase::Erased<[u8; 8]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            28: rustc_query_impl::query_impl::reachable_non_generics::get_query_non_incr::__rust_end_short_backtrace
            29: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::VecCache<rustc_span::def_id::CrateNum, rustc_middle::query::erase::Erased<[u8; 8]>>>
            30: rustc_codegen_ssa::back::symbol_export::is_reachable_non_generic_provider_local
            31: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::is_reachable_non_generic::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 1]>>
            32: <rustc_query_impl::query_impl::is_reachable_non_generic::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, rustc_span::def_id::DefId)>>::call_once
            33: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 1]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            34: rustc_query_impl::query_impl::is_reachable_non_generic::get_query_non_incr::__rust_end_short_backtrace
            35: rustc_middle::query::plumbing::query_get_at::<rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::DefId, rustc_middle::query::erase::Erased<[u8; 1]>>>
            36: <rustc_monomorphize::collector::RootCollector>::push_if_root
            37: rustc_monomorphize::collector::collect_roots
            38: <rustc_session::session::Session>::time::<alloc::vec::Vec<rustc_middle::mir::mono::MonoItem>, rustc_monomorphize::collector::collect_crate_mono_items::{closure#0}>
            39: rustc_monomorphize::collector::collect_crate_mono_items
            40: rustc_monomorphize::partitioning::collect_and_partition_mono_items
            41: rustc_query_impl::plumbing::__rust_begin_short_backtrace::<rustc_query_impl::query_impl::collect_and_partition_mono_items::dynamic_query::{closure#2}::{closure#0}, rustc_middle::query::erase::Erased<[u8; 24]>>
            42: <rustc_query_impl::query_impl::collect_and_partition_mono_items::dynamic_query::{closure#2} as core::ops::function::FnOnce<(rustc_middle::ty::context::TyCtxt, ())>>::call_once
            43: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::DynamicConfig<rustc_query_system::query::caches::SingleCache<rustc_middle::query::erase::Erased<[u8; 24]>>, false, false, false>, rustc_query_impl::plumbing::QueryCtxt, false>
            44: rustc_query_impl::query_impl::collect_and_partition_mono_items::get_query_non_incr::__rust_end_short_backtrace
            45: rustc_codegen_ssa::base::codegen_crate::<rustc_codegen_llvm::LlvmCodegenBackend>
            46: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
            47: <rustc_session::session::Session>::time::<alloc::boxed::Box<dyn core::any::Any>, rustc_interface::passes::start_codegen::{closure#0}>
            48: rustc_interface::passes::start_codegen
            49: <rustc_middle::ty::context::GlobalCtxt>::enter::<<rustc_interface::queries::Queries>::codegen_and_build_linker::{closure#0}, core::result::Result<rustc_interface::queries::Linker, rustc_span::ErrorGuaranteed>>
            50: <rustc_interface::queries::Queries>::codegen_and_build_linker
            51: <rustc_interface::interface::Compiler>::enter::<rustc_driver_impl::run_compiler::{closure#0}::{closure#0}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_span::ErrorGuaranteed>>
            52: rustc_span::set_source_map::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}::{closure#0}>
            53: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
            54: rustc_span::create_session_globals_then::<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}>
            55: std::sys_common::backtrace::__rust_begin_short_backtrace::<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>
            56: <<std::thread::Builder>::spawn_unchecked_<rustc_interface::util::run_in_thread_with_globals<rustc_interface::util::run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_span::ErrorGuaranteed>, rustc_driver_impl::run_compiler::{closure#0}>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_span::ErrorGuaranteed>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
            57: std::sys::unix::thread::Thread::new::thread_start
            58: __pthread_joiner_wake
      --> /Users/andy/Code/rustlantis/repro.rs:15:9
       |
    15 |         n = 0;
       |         ^^^^^

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Save the issue's reproducer as repro.rs and rerun rustc -Zmir-opt-level=0; the failure points to compiler/rustc_const_eval/src/transform/validate.rs:91:33 and the MIR validator. Trace how the custom MIR assignment to the enum-variant reference reaches that validator, and consider it resolved when the reproducer no longer ICEs at MIR opt level 0.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.