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

ICE: compiler/rustc_mir_build/src/build/matches/mod.rs None #133063

Closed
matthiaskrgr opened this issue Nov 15, 2024 · 4 comments · Fixed by #135409
Closed

ICE: compiler/rustc_mir_build/src/build/matches/mod.rs None #133063

matthiaskrgr opened this issue Nov 15, 2024 · 4 comments · Fixed by #135409
Assignees
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. F-if_let_guard `#![feature(if_let_guard)]` F-never_patterns `#![feature(never_patterns)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. S-has-bisection Status: a bisection has been found for this issue S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@matthiaskrgr
Copy link
Member

auto-reduced (treereduce-rust):

fn split_last(_: &()) -> Option<(&i32, &i32)> {
    None
}

fn assign_twice() {
    loop {
        match () {
            
            (! | !) if let _ = split_last(&()) => {}
            _ => {}
        }
    }
}

original:

//@ check-pass

#![feature(if_let_guard)]

fn split_last(_: &()) -> Option<(&i32, &i32)> {
    None
}

fn assign_twice() {
    loop {
        match () {
            #[allow(irrefutable_let_patterns)]
            (! | !) if let _ = split_last(&()) => {}
            _ => {}
        }
    }
}

fn main() {}

Version information

rustc 1.84.0-nightly (251dc8ad8 2024-11-15)
binary: rustc
commit-hash: 251dc8ad84492c792a7600d8c5fef2ec868a36a7
commit-date: 2024-11-15
host: x86_64-unknown-linux-gnu
release: 1.84.0-nightly
LLVM version: 19.1.3

Possibly related line of code:

source_info,
);
leaf_candidate.pre_binding_block = Some(new_pre_binding);
if has_guard {
// Falsely branch to `next_candidate_start_block` also if the guard fails.
let new_otherwise = self.cfg.start_new_block();
let old_otherwise = leaf_candidate.otherwise_block.unwrap();
self.false_edges(
new_otherwise,
old_otherwise,
next_candidate_start_block,
source_info,
);

Command:
/home/matthias/.rustup/toolchains/master/bin/rustc

Program output

error[E0658]: `if let` guards are experimental
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:21
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: see issue #51114 <https://github.com/rust-lang/rust/issues/51114> for more information
   = help: add `#![feature(if_let_guard)]` to the crate attributes to enable
   = note: this compiler was built on 2024-11-15; consider upgrading it if it is out of date
   = help: you can write `if matches!(<expr>, <pattern>)` instead of `if let <pattern> = <expr>`

error[E0658]: `!` patterns are experimental
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:14
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |              ^
   |
   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
   = help: add `#![feature(never_patterns)]` to the crate attributes to enable
   = note: this compiler was built on 2024-11-15; consider upgrading it if it is out of date

error[E0658]: `!` patterns are experimental
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:18
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |                  ^
   |
   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
   = help: add `#![feature(never_patterns)]` to the crate attributes to enable
   = note: this compiler was built on 2024-11-15; consider upgrading it if it is out of date

warning: unnecessary parentheses around pattern
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:13
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |             ^     ^
   |
   = note: `#[warn(unused_parens)]` on by default
help: remove these parentheses
   |
13 -             (! | !) if let _ = split_last(&()) => {}
13 +             ! | ! if let _ = split_last(&()) => {}
   |

error: a never pattern is always unreachable
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:51
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |                                                   ^^
   |                                                   |
   |                                                   this will never be executed
   |                                                   help: remove this expression

error[E0601]: `main` function not found in crate `mvce`
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:17:2
   |
17 | }
   |  ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs`

error: mismatched types
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:14
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |              ^ a never pattern must be used on an uninhabited type
   |
   = note: the matched value is of type `()`

error: mismatched types
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:18
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |                  ^ a never pattern must be used on an uninhabited type
   |
   = note: the matched value is of type `()`

warning: irrefutable `if let` guard pattern
  --> /tmp/icemaker_global_tempdir.FVFwJhAXzIYI/rustc_testrunner_tmpdir_reporting.RbOs5qNwMqij/mvce.rs:13:24
   |
13 |             (! | !) if let _ = split_last(&()) => {}
   |                        ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: this pattern will always match, so the guard is useless
   = help: consider removing the guard and adding a `let` inside the match arm
   = note: `#[warn(irrefutable_let_patterns)]` on by default

thread 'rustc' panicked at compiler/rustc_mir_build/src/build/matches/mod.rs:1540:76:
called `Option::unwrap()` on a `None` value
stack backtrace:
   0:     0x79ade605a3ba - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h3e8890c320687803
   1:     0x79ade680414a - core::fmt::write::h8e02e323e721d5d3
   2:     0x79ade7c2cc51 - std::io::Write::write_fmt::hfa5fc2d5ad51eab4
   3:     0x79ade605a212 - std::sys::backtrace::BacktraceLock::print::hef9ddff43c45c466
   4:     0x79ade605c716 - std::panicking::default_hook::{{closure}}::he4ae1ef11715c038
   5:     0x79ade605c560 - std::panicking::default_hook::h4571154760051e3a
   6:     0x79ade50e4281 - std[575dabc3fc23637d]::panicking::update_hook::<alloc[488fcebc54bee2fb]::boxed::Box<rustc_driver_impl[530468506af41d6d]::install_ice_hook::{closure#0}>>::{closure#0}
   7:     0x79ade605ce28 - std::panicking::rust_panic_with_hook::h99e29fee3fbc2974
   8:     0x79ade605cbc6 - std::panicking::begin_panic_handler::{{closure}}::h66e3972102a7eb3e
   9:     0x79ade605a869 - std::sys::backtrace::__rust_end_short_backtrace::ha9860e2cc56614c6
  10:     0x79ade605c8bc - rust_begin_unwind
  11:     0x79ade2adde30 - core::panicking::panic_fmt::h21ce4ecfcb0cf215
  12:     0x79ade2e52c6c - core::panicking::panic::h2175426ea9d4336d
  13:     0x79ade40982f9 - core::option::unwrap_failed::hb947bce75902c03c
  14:     0x79ade6b48ff7 - rustc_mir_build[ce774ae811bc940]::build::matches::traverse_candidate::<&mut rustc_mir_build[ce774ae811bc940]::build::matches::Candidate, (), core[678332cb0ee15b78]::iter::adapters::rev::Rev<core[678332cb0ee15b78]::slice::iter::IterMut<rustc_mir_build[ce774ae811bc940]::build::matches::Candidate>>, <rustc_mir_build[ce774ae811bc940]::build::matches::Candidate>::visit_leaves_rev<<rustc_mir_build[ce774ae811bc940]::build::Builder>::lower_match_tree::{closure#1}>::{closure#0}, <rustc_mir_build[ce774ae811bc940]::build::matches::Candidate>::visit_leaves_rev<<rustc_mir_build[ce774ae811bc940]::build::Builder>::lower_match_tree::{closure#1}>::{closure#1}, <rustc_mir_build[ce774ae811bc940]::build::matches::Candidate>::visit_leaves_rev<<rustc_mir_build[ce774ae811bc940]::build::Builder>::lower_match_tree::{closure#1}>::{closure#2}>
  15:     0x79ade6b485cb - <rustc_mir_build[ce774ae811bc940]::build::Builder>::lower_match_tree
  16:     0x79ade6b26bb2 - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  17:     0x79ade6b2804a - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  18:     0x79ade748d32b - <rustc_mir_build[ce774ae811bc940]::build::Builder>::ast_block_stmts
  19:     0x79ade748c28c - <rustc_mir_build[ce774ae811bc940]::build::Builder>::ast_block
  20:     0x79ade6b25f0e - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  21:     0x79ade6b29dda - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  22:     0x79ade6b1cb49 - <rustc_mir_build[ce774ae811bc940]::build::Builder>::as_temp::{closure#0}
  23:     0x79ade6b27dbd - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  24:     0x79ade6b2804a - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  25:     0x79ade748d32b - <rustc_mir_build[ce774ae811bc940]::build::Builder>::ast_block_stmts
  26:     0x79ade748c28c - <rustc_mir_build[ce774ae811bc940]::build::Builder>::ast_block
  27:     0x79ade6b25f0e - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  28:     0x79ade6b2804a - <rustc_mir_build[ce774ae811bc940]::build::Builder>::expr_into_dest
  29:     0x79ade6b378e9 - rustc_mir_build[ce774ae811bc940]::build::mir_build
  30:     0x79ade6807f04 - rustc_mir_transform[b6a0096f646ee25e]::mir_built
  31:     0x79ade6807ec7 - rustc_query_impl[bf1c9f3baad9eabf]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf1c9f3baad9eabf]::query_impl::mir_built::dynamic_query::{closure#2}::{closure#0}, rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 8usize]>>
  32:     0x79ade6f12001 - rustc_query_system[d5846f7a9cb2c23f]::query::plumbing::try_execute_query::<rustc_query_impl[bf1c9f3baad9eabf]::DynamicConfig<rustc_query_system[d5846f7a9cb2c23f]::query::caches::VecCache<rustc_span[9778d555244491c7]::def_id::LocalDefId, rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 8usize]>>, false, false, false>, rustc_query_impl[bf1c9f3baad9eabf]::plumbing::QueryCtxt, false>
  33:     0x79ade6f11bcd - rustc_query_impl[bf1c9f3baad9eabf]::query_impl::mir_built::get_query_non_incr::__rust_end_short_backtrace
  34:     0x79ade2c7bd71 - rustc_mir_build[ce774ae811bc940]::check_unsafety::check_unsafety
  35:     0x79ade703eafd - rustc_query_impl[bf1c9f3baad9eabf]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf1c9f3baad9eabf]::query_impl::check_unsafety::dynamic_query::{closure#2}::{closure#0}, rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 0usize]>>
  36:     0x79ade703ed9c - rustc_query_system[d5846f7a9cb2c23f]::query::plumbing::try_execute_query::<rustc_query_impl[bf1c9f3baad9eabf]::DynamicConfig<rustc_query_system[d5846f7a9cb2c23f]::query::caches::VecCache<rustc_span[9778d555244491c7]::def_id::LocalDefId, rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[bf1c9f3baad9eabf]::plumbing::QueryCtxt, false>
  37:     0x79ade703ea41 - rustc_query_impl[bf1c9f3baad9eabf]::query_impl::check_unsafety::get_query_non_incr::__rust_end_short_backtrace
  38:     0x79ade6d4562c - rustc_interface[c18496298df4cf52]::passes::run_required_analyses
  39:     0x79ade762961e - rustc_interface[c18496298df4cf52]::passes::analysis
  40:     0x79ade76295ef - rustc_query_impl[bf1c9f3baad9eabf]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[bf1c9f3baad9eabf]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 1usize]>>
  41:     0x79ade77dee6e - rustc_query_system[d5846f7a9cb2c23f]::query::plumbing::try_execute_query::<rustc_query_impl[bf1c9f3baad9eabf]::DynamicConfig<rustc_query_system[d5846f7a9cb2c23f]::query::caches::SingleCache<rustc_middle[c94631e3827a547d]::query::erase::Erased<[u8; 1usize]>>, false, false, false>, rustc_query_impl[bf1c9f3baad9eabf]::plumbing::QueryCtxt, false>
  42:     0x79ade77deb4e - rustc_query_impl[bf1c9f3baad9eabf]::query_impl::analysis::get_query_non_incr::__rust_end_short_backtrace
  43:     0x79ade76d963a - rustc_interface[c18496298df4cf52]::interface::run_compiler::<core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>, rustc_driver_impl[530468506af41d6d]::run_compiler::{closure#0}>::{closure#1}
  44:     0x79ade7732e50 - std[575dabc3fc23637d]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[c18496298df4cf52]::util::run_in_thread_with_globals<rustc_interface[c18496298df4cf52]::util::run_in_thread_pool_with_globals<rustc_interface[c18496298df4cf52]::interface::run_compiler<core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>, rustc_driver_impl[530468506af41d6d]::run_compiler::{closure#0}>::{closure#1}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>::{closure#0}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>
  45:     0x79ade773326b - <<std[575dabc3fc23637d]::thread::Builder>::spawn_unchecked_<rustc_interface[c18496298df4cf52]::util::run_in_thread_with_globals<rustc_interface[c18496298df4cf52]::util::run_in_thread_pool_with_globals<rustc_interface[c18496298df4cf52]::interface::run_compiler<core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>, rustc_driver_impl[530468506af41d6d]::run_compiler::{closure#0}>::{closure#1}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>::{closure#0}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[678332cb0ee15b78]::result::Result<(), rustc_span[9778d555244491c7]::ErrorGuaranteed>>::{closure#1} as core[678332cb0ee15b78]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  46:     0x79ade7733d39 - std::sys::pal::unix::thread::Thread::new::thread_start::h1176f996a4a1b888
  47:     0x79ade908f39d - <unknown>
  48:     0x79ade911449c - <unknown>
  49:                0x0 - <unknown>

error: the compiler unexpectedly panicked. this is a bug.

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.84.0-nightly (251dc8ad8 2024-11-15) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [mir_built] building MIR for `assign_twice`
#1 [check_unsafety] unsafety-checking `assign_twice`
end of query stack
error: aborting due to 7 previous errors; 2 warnings emitted

Some errors have detailed explanations: E0601, E0658.
For more information about an error, try `rustc --explain E0601`.

@rustbot label +F-if_let_guard

@matthiaskrgr matthiaskrgr added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Nov 15, 2024
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. F-if_let_guard `#![feature(if_let_guard)]` labels Nov 15, 2024
@matthiaskrgr matthiaskrgr added the F-never_patterns `#![feature(never_patterns)]` label Nov 15, 2024
@matthiaskrgr
Copy link
Member Author

This bisects to #127159 cc @Nadrieril

@matthiaskrgr
Copy link
Member Author

smaller

fn main() {
	match () {
		(! | !) if let _ = Some(0) => {}
		_ => {}
	}
}

@jieyouxu jieyouxu added S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue S-has-bisection Status: a bisection has been found for this issue A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Nov 15, 2024
@Nadrieril
Copy link
Member

Smaller and type-correct:

fn foo(x: !) {
	match x {
		(! | !) if false => {}
		_ => {}
	}
}

@Nadrieril Nadrieril self-assigned this Nov 15, 2024
@saethlin saethlin added the A-patterns Relating to patterns and pattern matching label Nov 16, 2024
@matthiaskrgr matthiaskrgr added the S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. label Dec 13, 2024
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Jan 22, 2025
…lse-edge-start-block, r=Nadrieril

Fix ICE-133117: multiple never-pattern arm doesn't have false_edge_start_block

Fixes rust-lang#133117 , and close fixes rust-lang#133063 , fixes rust-lang#130779

In order to fix ICE-133117, at first I needed to tackle to ICE-133063 (this fixed 130779 as well).

### ICE-133063 and ICE-130779
This ICE is caused by those steps:
1. An arm has or-pattern, and all of the sub-candidates are never-pattern
2. In that case, all sub-candidates are removed in remove_never_subcandidates(). So the arm (candidate) has no sub-candidate.
3. In the current implementation, if there is no sub-candidate, the function assigns `pre_binding_block` into the candidate ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L2002-L2004)). However, otherwise_block should be assigned to the candidate as well, because the otherwise_block is unwrapped in multiple place (like in lower_match_tree()). As a result, it causes the panic.

I simply added the same block as pre_binding_block into otherwise_block, but I'm wondering if there is a better block to assign to otherwise_block (is it ok to assign the same block into pre_binding and otherwise?)

### ICE-133117
This is caused by those steps:
1. There are two arms, both are or-pattern and each has one match-pair (in the test code, both are `(!|!)`), and the second arm has a guard.
2. In match_candidate() for the first arm, it expands the second arm’s sub-candidates as well ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L1800-L1805)). As a result, the root candidate of the second arm is not evaluated/modified in match_candidate(). So a false_edge_start_block is not assigned to the candidate.
3. merge_trivial_subcandidates() is called against the candidate for the second arm. It just returns immediately because the candidate has a guard. So a flase_edge_start_block is not assigned to the candidate also in this function.
4. remove_never_subcandidates() is called against the candidate. Since all sub-candidates are never-pattern. they are removed.
5. In lower_match_tree(), since there is no sub-candidate for the candidate, the candidate itself is evaluated in visit_leave_rev ([here](https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_build/src/builder/matches/mod.rs#L1532)). Because the candidate has no false_edge_start_block, it causes the panic.

So I modified the order of if blocks in merge_trivial_subcandidates() to assign a false_edge_start_block if the candidate doesn't have.
@bors bors closed this as completed in f875983 Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-MIR Area: Mid-level IR (MIR) - https://blog.rust-lang.org/2016/04/19/MIR.html A-patterns Relating to patterns and pattern matching C-bug Category: This is a bug. F-if_let_guard `#![feature(if_let_guard)]` F-never_patterns `#![feature(never_patterns)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ S-bug-has-test Status: This bug is tracked inside the repo by a `known-bug` test. S-has-bisection Status: a bisection has been found for this issue S-has-mcve Status: A Minimal Complete and Verifiable Example has been found for this issue T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants