rust-lang / rust-analyzer

A Rust compiler front-end for IDEs
https://rust-analyzer.github.io/
Apache License 2.0
14.11k stars 1.57k forks source link

Panic in chalk with index out of bounds in fold_free_var_ty #4885

Closed Speedy37 closed 4 years ago

Speedy37 commented 4 years ago

This crash:

    pub fn get<KR, K>(&self, key: &K) -> impl Future<Output = K::ValueType>
    where
        KR: KeyRegion<RootKeyRegion = R>,
        K: Key<KR>,
    {
       ...
    }

This does not:

    pub fn get<KR, K>(&self, key: &K) -> impl Future<Output = <K as PartialKey<KR>>::ValueType>
    where
        KR: KeyRegion<RootKeyRegion = R>,
        K: Key<KR>,
    {
       ...
    }

Key is declared like (this is not the complete definition) :

trait PartialKey<R: KeyRegion>: PrefixKey<R>  {
   type ValueType;
}
trait Key<R: KeyRegion>: PartialKey<R> {}
Backtrace

``` thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 3', fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\subst.rs:60:19 stack backtrace: 0: backtrace::backtrace::dbghelp::trace at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace\dbghelp.rs:88 1: backtrace::backtrace::trace_unsynchronized at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\backtrace-0.3.46\src\backtrace\mod.rs:66 2: std::sys_common::backtrace::_print_fmt at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:78 3: std::sys_common::backtrace::_print::{{impl}}::fmt at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:59 4: core::fmt::write at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\fmt\mod.rs:1069 5: std::io::Write::write_fmt at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\io\mod.rs:1504 6: std::sys_common::backtrace::_print at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:62 7: std::sys_common::backtrace::print at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\sys_common\backtrace.rs:49 8: std::panicking::default_hook::{{closure}} at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:198 9: std::panicking::default_hook at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:218 10: std::panicking::rust_panic_with_hook at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:511 11: std::panicking::begin_panic_handler at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libstd\panicking.rs:419 12: core::panicking::panic_fmt at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\panicking.rs:111 13: core::panicking::panic_bounds_check at /rustc/49cae55760da0a43428eba73abcb659bb70cf2e4\/src\libcore\panicking.rs:69 14: chalk_ir::fold::subst::{{impl}}::fold_free_var_ty at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\subst.rs:60 15: chalk_ir::fold::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:505 16: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_GenericArgData::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\lib.rs:1062 17: chalk_ir::fold::boring_impls::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:128 18: chalk_ir::fold::boring_impls::{{impl}}::fold_with::{{closure}} at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:39 19: core::ops::function::impls::{{impl}}::call_once at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\ops\function.rs:285 20: core::option::Option::map at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\option.rs:456 21: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 22: chalk_ir::cast::{{impl}}::next at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\cast.rs:360 23: core::iter::traits::iterator::Iterator::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:1877 24: core::iter::adapters::{{impl}}::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:1100 25: core::iter::traits::iterator::Iterator::find at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:2212 26: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 27: alloc::vec::{{impl}}::from_iter,core::iter::adapters::ResultShunt>, closure-0>, core::result::Result at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:424 40: chalk_ir::fold::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:505 41: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_GenericArgData::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\lib.rs:1062 42: chalk_ir::fold::boring_impls::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:128 43: chalk_ir::fold::boring_impls::{{impl}}::fold_with::{{closure}} at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:39 44: core::ops::function::impls::{{impl}}::call_once at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\ops\function.rs:285 45: core::option::Option::map at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\option.rs:456 46: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 47: chalk_ir::cast::{{impl}}::next at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\cast.rs:360 48: core::iter::traits::iterator::Iterator::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:1877 49: core::iter::adapters::{{impl}}::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:1100 50: core::iter::traits::iterator::Iterator::find at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:2212 51: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 52: alloc::vec::{{impl}}::from_iter,core::iter::adapters::ResultShunt>, closure-0>, core::result::Result at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:421 64: chalk_ir::fold::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:505 65: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_GenericArgData::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\lib.rs:1062 66: chalk_ir::fold::boring_impls::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:128 67: chalk_ir::fold::boring_impls::{{impl}}::fold_with::{{closure}} at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:39 68: core::ops::function::impls::{{impl}}::call_once at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\ops\function.rs:285 69: core::option::Option::map at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\option.rs:456 70: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 71: chalk_ir::cast::{{impl}}::next at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\cast.rs:360 72: core::iter::traits::iterator::Iterator::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:1877 73: core::iter::adapters::{{impl}}::try_fold at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:1100 74: core::iter::traits::iterator::Iterator::find at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\traits\iterator.rs:2212 75: core::iter::adapters::{{impl}}::next at fake_path\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\src\rust\src\libcore\iter\adapters\mod.rs:805 76: alloc::vec::{{impl}}::from_iter,core::iter::adapters::ResultShunt>, closure-0>, core::result::Result at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:421 88: chalk_ir::fold::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold.rs:564 89: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_AliasEq::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\lib.rs:1467 90: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_WhereClause::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\lib.rs:1193 91: chalk_ir::fold::binder_impls::{{impl}}::fold_with at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\binder_impls.rs:24 92: chalk_ir::fold::boring_impls::{{impl}}::fold_with>,ra_hir_ty::traits::chalk::interner::Interner,ra_hir_ty::traits::chalk::interner::Interner> at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-ir-0.11.0\src\fold\boring_impls.rs:23 93: chalk_solve::clauses::builder::ClauseBuilder::push_binders,closure-0> at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\clauses\builder.rs:137 94: chalk_solve::clauses::program_clauses::{{impl}}::to_program_clauses at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\clauses\program_clauses.rs:133 95: chalk_solve::clauses::program_clauses_for_goal at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\clauses.rs:189 96: chalk_solve::recursive::Solver::solve_goal at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\recursive.rs:168 97: chalk_solve::recursive::Solver::solve_root_goal at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\recursive.rs:110 98: chalk_solve::solve::Solver::solve_limited at fake_path\.cargo\registry\src\github.com-1ecc6299db9ec823\chalk-solve-0.11.0\src\solve.rs:367 99: ra_hir_ty::traits::solve::{{closure}} at .\crates\ra_hir_ty\src\traits.rs:199 100: ra_hir_ty::traits::solve at .\crates\ra_hir_ty\src\traits.rs:206 ```

Speedy37 commented 4 years ago

I had another panic location, and I worked around it the same way (<T as MyTrait>::MyType) the where clause was less complex: (T: MyTrait and other bounds).

Speedy37 commented 4 years ago

I managed to create a reproducer:

trait Future {
    type Output;
}
trait Foo<R> {
    type Bar;
}
fn foo<R, K>(key: &K) -> impl Future<Output = K::Bar>
where
    K: Foo<R>,
{
    bar(key)
}
fn bar<R, K>(key: &K) -> impl Future<Output = K::Bar>
where
    K: Foo<R>,
{
}

Changing

K::Bar

to

<K as Key<R>>::Bar

workaround the issue

flodiebold commented 4 years ago

This is sadly not enough information to reproduce the problem. Is your project available somewhere?

flodiebold commented 4 years ago

You could also retest it after #4950 is merged, although it's probably not the same issue since the trait and supertrait have the same number of parameters.

Speedy37 commented 4 years ago

Just dropping that code in any rust code file makes rust-analyser panic. I wasn't able to write a test in ra_hir_ty that makes it crash tho.

Edit: I just created a new project (cargo init --lib and dropped that code), instant panic.

lnicola commented 4 years ago

I can reproduce it even without bar.

flodiebold commented 4 years ago

Oh, I was looking at an old tab and didn't see your later comment :facepalm:

flodiebold commented 4 years ago

Adding

#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}

makes it crash in a test as well.

flodiebold commented 4 years ago

Ok, it's the same problem as #4800.

Speedy37 commented 4 years ago

I've pull in both #4952 and #4950, it's still crashing :(

  13: ra_hir_ty::Binders<ra_hir_ty::Ty>::subst
             at .\crates\ra_hir_ty\src\lib.rs:553
  14: ra_hir_ty::infer::InferenceContext::resolve_value_path
             at .\crates\ra_hir_ty\src\infer\path.rs:85
  15: ra_hir_ty::infer::InferenceContext::infer_path
             at .\crates\ra_hir_ty\src\infer\path.rs:23
  16: ra_hir_ty::infer::InferenceContext::infer_expr_inner
             at .\crates\ra_hir_ty\src\infer\expr.rs:249
  17: ra_hir_ty::infer::InferenceContext::infer_expr
             at .\crates\ra_hir_ty\src\infer\expr.rs:31
  18: ra_hir_ty::infer::InferenceContext::infer_expr_inner
             at .\crates\ra_hir_ty\src\infer\expr.rs:200
  19: ra_hir_ty::infer::InferenceContext::infer_expr_coerce
             at .\crates\ra_hir_ty\src\infer\expr.rs:49
  20: ra_hir_ty::infer::InferenceContext::infer_block
             at .\crates\ra_hir_ty\src\infer\expr.rs:640
             at .\crates\ra_hir_ty\src\infer\expr.rs:91
  22: ra_hir_ty::infer::InferenceContext::infer_expr_coerce
             at .\crates\ra_hir_ty\src\infer\expr.rs:49
  23: ra_hir_ty::infer::InferenceContext::infer_body
             at .\crates\ra_hir_ty\src\infer.rs:548
  24: ra_hir_ty::infer::infer_query
             at .\crates\ra_hir_ty\src\infer.rs:77

Might not be the same cause, I'm checking the file that cause this in the editor (the stack is from analysis-stats)

Speedy37 commented 4 years ago

Ok #4952 seems to fix this bug. I'm probably gonna open another one.