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

"index out of bounds" with incorrect match #15883

Closed
SludgePhD opened this issue Nov 12, 2023 · 6 comments · Fixed by #16533
Closed

"index out of bounds" with incorrect match #15883

SludgePhD opened this issue Nov 12, 2023 · 6 comments · Fixed by #16533
Labels
A-pattern pattern handling related things C-bug Category: bug I-panic

Comments

@SludgePhD
Copy link

rust-analyzer version: 0.3.1722-standalone

rustc version: rustc 1.73.0 (cc66ad468 2023-10-03)

relevant settings: none that should affect this

This code causes a panic inside rust-analyzer:

fn main() {
    match Some((true, false)) {
        Some(true) | Some(false) => {}
        None => {}
    }
}

Panic backtrace:

thread 'Worker' panicked at crates/hir-ty/src/diagnostics/match_check/usefulness.rs:371:18:
index out of bounds: the len is 0 but the index is 0
stack backtrace:
   0: rust_begin_unwind
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/std/src/panicking.rs:595:5
   1: core::panicking::panic_fmt
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_bounds_check
             at /rustc/cc66ad468955717ab92600c770da8c1601a4ff33/library/core/src/panicking.rs:162:5
   3: <alloc::vec::Vec<T,A> as alloc::vec::spec_extend::SpecExtend<T,I>>::spec_extend
   4: hir_ty::diagnostics::match_check::deconstruct_pat::Constructor::split
   5: <core::iter::adapters::flatten::FlattenCompat<I,U> as core::iter::traits::iterator::Iterator>::next
   6: hir_ty::diagnostics::match_check::deconstruct_pat::SplitWildcard::split
   7: hir_ty::diagnostics::match_check::deconstruct_pat::Constructor::split
   8: hir_ty::diagnostics::match_check::usefulness::is_useful
   9: hir_ty::diagnostics::match_check::usefulness::is_useful
  10: hir_ty::diagnostics::match_check::usefulness::is_useful
  11: hir_ty::diagnostics::match_check::usefulness::compute_match_usefulness
  12: hir_ty::diagnostics::expr::BodyValidationDiagnostic::collect
  13: hir::DefWithBody::diagnostics
  14: hir::ModuleDef::diagnostics
  15: hir::Module::diagnostics
  16: ide_diagnostics::diagnostics
  17: std::panicking::try
  18: ide::Analysis::assists_with_fixes
  19: rust_analyzer::handlers::request::handle_code_action
  20: core::ops::function::FnOnce::call_once{{vtable.shim}}
@roife
Copy link
Member

roife commented Dec 31, 2023

I investigated this issue and found that it is due to the validate_match function in hir-ty/src/diagnostics/expr.rs. Because of pattern type inference, the function assumes that pat_ty == scrut_ty, meaning it considers the pattern type of Some(true) to be the same as the scrut_ty (of Some((true, false))). This leads to triggering the error trying to compare incompatible constructors during subsequent matrix construction and specialization calculations.

However, according to the algorithm, if the constructors of the two are different, they should just return false. I'm not sure why this error is being triggered in this case. (In fact, when I set it up this way, the error did indeed disappear, and it passed all tests successfully.)

@Nadrieril
Copy link
Member

The error is being triggered because this algorithm was taken from rustc, where detecting such type errors early is important. For rust-analyzer it does make sense to ignore those, we should do that

@roife
Copy link
Member

roife commented Jan 23, 2024

So, should we remove never! in https://github.com/rust-lang/rust-analyzer/blob/master/crates/hir-ty/src/diagnostics/match_check/deconstruct_pat.rs#L481 and return false? (as which described in the algorithm)

@Nadrieril
Copy link
Member

Nadrieril commented Jan 23, 2024

That risks false positives, for example the match being errored as "non exhaustive". The correct fix is to use the recently added Err path, which we will get after #16420. We'll have to do the chance on the rustc side

@iDawer
Copy link
Contributor

iDawer commented Jan 24, 2024

The OP's example was supposed to cause this function

fn types_of_subpatterns_do_match(pat: PatId, body: &Body, infer: &InferenceResult) -> bool {

to return false and prevent from being checked for exhaustiveness. But the example seems sneaking through RA's typecheck. Or perhaps that function is buggy.

@Nadrieril Nadrieril added the A-pattern pattern handling related things label Jan 24, 2024
@Nadrieril
Copy link
Member

Nadrieril commented Jan 24, 2024

rust-lang/rust#120313 should fix this (and #15808) once it makes its way to rust-analyzer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-pattern pattern handling related things C-bug Category: bug I-panic
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants