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

New weekly build crashs reproducily #4053

Closed weiznich closed 4 years ago

weiznich commented 4 years ago

I've doing some work on diesel. Pointing with the cursor to this line reproducibly crashes rust-analyzer with the attached backtrace.

Version: rust-analyzer 90f8378 OS: Ubuntu 20.04 IDE: Emacs

Backtrace: 
thread '<unnamed>' panicked at 'index out of bounds: the len is 1 but the index is 7', /home/runner/.cargo/git/checkouts/chalk-7b02fa8caa2cec94/28cef6f/chalk-ir/src/fold/subst.rs:56:19
stack backtrace:
   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: <unknown>
  16: <unknown>
  17: <unknown>
  18: <unknown>
  19: <unknown>
  20: <unknown>
  21: <unknown>
  22: <unknown>
  23: <unknown>
  24: <unknown>
  25: <unknown>
  26: <unknown>
  27: <unknown>
  28: <unknown>
  29: <unknown>
  30: <unknown>
  31: <unknown>
  32: <unknown>
  33: <unknown>
  34: <unknown>
  35: <unknown>
  36: <unknown>
  37: <unknown>
  38: <unknown>
  39: <unknown>
  40: <unknown>
  41: <unknown>
  42: <unknown>
  43: <unknown>
  44: <unknown>
  45: <unknown>
  46: <unknown>
  47: <unknown>
  48: <unknown>
  49: <unknown>
  50: <unknown>
  51: <unknown>
  52: <unknown>
  53: <unknown>
  54: <unknown>
  55: <unknown>
  56: <unknown>
  57: <unknown>
  58: <unknown>
  59: <unknown>
  60: <unknown>
  61: <unknown>
  62: <unknown>
  63: <unknown>
  64: <unknown>
  65: <unknown>
  66: <unknown>
  67: <unknown>
  68: <unknown>
  69: <unknown>
  70: <unknown>
  71: <unknown>
  72: <unknown>
  73: <unknown>
  74: <unknown>
  75: <unknown>
  76: <unknown>
  77: <unknown>
  78: <unknown>
  79: <unknown>
  80: <unknown>
  81: <unknown>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
bjorn3 commented 4 years ago

Probably duplicate of #4050.

Edit: Panic message is different.

flodiebold commented 4 years ago

Yeah, that's a different one. The backtrace isn't very helpful though.

weiznich commented 4 years ago

I know that the backtrace isn't that helpful. I will trying to get another one. Is there any way to get a complete backtrace without rebuilding the binary manually?

lnicola commented 4 years ago

I suggest enabling debug = 2 in Cargo.toml and building from source.

@matklad I recall you mentioning that the release binaries are stripped, but I can't find that in the workflows. What would you say about enabling debug info for nightly builds?

matklad commented 4 years ago

but I can't find that in the workflows.

That's in dist.rs

What would you say about enabling debug info for nightly builds?

Yes :)

lnicola commented 4 years ago
        if !nightly {
            run!("strip ./target/x86_64-unknown-linux-musl/release/rust-analyzer")?;
        }

Oh, right.

@weiznich maybe you could try the nightly version?

weiznich commented 4 years ago

Using the latest nightly build prints the following backtrace:

$ rust-analyzer-linux analysis-bench --goto-def diesel/diesel/src/query_builder/select_statement/dsl_impls.rs:359:1
…
from scratch:   thread 'main' panicked at 'index out of bounds: the len is 1 but the index is 8', /home/runner/.cargo/git/checkouts/chalk-7b02fa8caa2cec94/28cef6f/chalk-ir/src/fold/subst.rs:56:19
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:77
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1052
   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:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:204
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:224
  10: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:472
  11: rust_begin_unwind
             at src/libstd/panicking.rs:380
  12: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
  13: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:63
  14: <chalk_ir::fold::subst::Subst<I> as chalk_ir::fold::Folder<I>>::fold_free_var_ty
  15: <chalk_ir::Ty<I> as chalk_ir::fold::SuperFold<I,TI>>::super_fold_with
  16: chalk_ir::fold::boring_impls::<impl chalk_ir::fold::Fold<I,TI> for chalk_ir::Parameter<I>>::fold_with
  17: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
  18: core::iter::adapters::process_results
  19: chalk_ir::_DERIVE_chalk_ir_fold_Fold_I_TI_FOR_WhereClause::<impl chalk_ir::fold::Fold<I,_TI> for chalk_ir::WhereClause<I>>::fold_with
  20: chalk_ir::fold::binder_impls::<impl chalk_ir::fold::Fold<I,TI> for chalk_ir::Binders<T>>::fold_with
  21: <core::iter::adapters::ResultShunt<I,E> as core::iter::traits::iterator::Iterator>::next
  22: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
  23: chalk_ir::fold::boring_impls::<impl chalk_ir::fold::Fold<I,TI> for chalk_ir::QuantifiedWhereClauses<I>>::fold_with
  24: chalk_solve::infer::instantiate::<impl chalk_solve::infer::InferenceTable<I>>::instantiate_binders_universally
  25: <chalk_solve::infer::unify::Unifier<I> as chalk_ir::zip::Zipper<I>>::zip_binders
  26: chalk_solve::infer::unify::Unifier<I>::unify_ty_ty
  27: <chalk_ir::Substitution<I> as chalk_ir::zip::Zip<I>>::zip_with
  28: chalk_solve::infer::unify::Unifier<I>::unify_ty_ty
  29: <chalk_ir::Substitution<I> as chalk_ir::zip::Zip<I>>::zip_with
  30: chalk_solve::infer::unify::Unifier<I>::unify_ty_ty
  31: <chalk_ir::DomainGoal<I> as chalk_ir::zip::Zip<I>>::zip_with
  32: chalk_solve::infer::unify::Unifier<I>::unify
  33: chalk_solve::infer::unify::<impl chalk_solve::infer::InferenceTable<I>>::unify
  34: chalk_solve::recursive::Solver<I>::solve_via_implication
  35: chalk_solve::recursive::Solver<I>::solve_goal
  36: chalk_solve::recursive::fulfill::Fulfill<I>::prove
  37: chalk_solve::recursive::fulfill::Fulfill<I>::solve
  38: chalk_solve::recursive::Solver<I>::solve_via_implication
  39: chalk_solve::recursive::Solver<I>::solve_goal
  40: chalk_solve::recursive::fulfill::Fulfill<I>::prove
  41: chalk_solve::recursive::fulfill::Fulfill<I>::solve
  42: chalk_solve::recursive::Solver<I>::solve_via_implication
  43: chalk_solve::recursive::Solver<I>::solve_goal
  44: chalk_solve::recursive::fulfill::Fulfill<I>::prove
  45: chalk_solve::recursive::fulfill::Fulfill<I>::solve
  46: chalk_solve::recursive::Solver<I>::solve_via_implication
  47: chalk_solve::recursive::Solver<I>::solve_goal
  48: chalk_solve::recursive::Solver<I>::solve_root_goal
  49: ra_hir_ty::traits::trait_solve_query
  50: salsa::runtime::Runtime<DB>::execute_query_implementation
  51: salsa::derived::slot::Slot<DB,Q,MP>::read_upgrade
  52: salsa::derived::slot::Slot<DB,Q,MP>::read
  53: <salsa::derived::DerivedStorage<DB,Q,MP> as salsa::plumbing::QueryStorageOps<DB,Q>>::try_fetch
  54: salsa::QueryTable<DB,Q>::get
  55: <T as ra_hir_ty::db::HirDatabase>::trait_solve
  56: ra_hir_ty::infer::InferenceContext::resolve_ty_as_possible
  57: ra_hir_ty::infer::path::<impl ra_hir_ty::infer::InferenceContext>::infer_path
  58: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  59: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr
  60: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  61: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  62: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_block
  63: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_inner
  64: ra_hir_ty::infer::expr::<impl ra_hir_ty::infer::InferenceContext>::infer_expr_coerce
  65: ra_hir_ty::infer::infer_query
  66: salsa::runtime::Runtime<DB>::execute_query_implementation
  67: salsa::derived::slot::Slot<DB,Q,MP>::read_upgrade
  68: salsa::derived::slot::Slot<DB,Q,MP>::read
  69: <salsa::derived::DerivedStorage<DB,Q,MP> as salsa::plumbing::QueryStorageOps<DB,Q>>::try_fetch
  70: <T as ra_hir_ty::db::HirDatabase>::infer_query
  71: ra_hir_ty::db::infer_wait
  72: ra_hir::source_analyzer::SourceAnalyzer::new_for_body
  73: ra_hir::semantics::Semantics<DB>::analyze2
  74: ra_hir::semantics::Semantics<DB>::descend_into_macros
  75: ra_ide::goto_definition::goto_definition
  76: std::panicking::try::do_call
  77: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:86
  78: ra_ide::Analysis::goto_definition
  79: rust_analyzer::cli::analysis_bench::analysis_bench
  80: rust_analyzer::main
  81: std::rt::lang_start::{{closure}}
  82: std::rt::lang_start_internal::{{closure}}
             at src/libstd/rt.rs:52
  83: std::panicking::try::do_call
             at src/libstd/panicking.rs:305
  84: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:86
  85: std::panicking::try
             at src/libstd/panicking.rs:281
  86: std::panic::catch_unwind
             at src/libstd/panic.rs:394
  87: std::rt::lang_start_internal
             at src/libstd/rt.rs:51
  88: main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
matklad commented 4 years ago

if !nightly {

Ah, so that wasn't a Deja vu :)

flodiebold commented 4 years ago

So another crash related to binders in dyn Trait... I really thought #4023 would be the last one :grimacing:

(Also, wow, those where clauses...)

Diggsey commented 4 years ago

I'm seeing this too:

thread '<unnamed>' panicked at 'index out of bounds: the len is 1 but the index is 8', C:\Users\runneradmin\.cargo\git\checkouts\chalk-7b02fa8caa2cec94\28cef6f\chalk-ir\src\fold\subst.rs:56:19
flodiebold commented 4 years ago

I think we need more people trying out the nightlies, or to check analysis-stats on nightlies on more projects :grimacing:

eminence commented 4 years ago

to check analysis-stats on nightlies on more projects

What's the easiest way for me to run stable/weekly RA in vs-code, but run also run nightly "analysis-stats" if i notice problems? Is this just a matter of cloning the latest RA source, building, and then cargo runing something?

flodiebold commented 4 years ago

Yeah, either cargo build --release from source (you really need the release build), or download a nightly build from our releases.

JoshMcguigan commented 4 years ago

or to check analysis-stats on nightlies on more projects

+1 to this

I'd really like to see the nightly CI job gate the release on a succesful run against some representative projects.

matklad commented 4 years ago

I'd really like to see the nightly CI job gate the release on a succesful run against some representative projects

A helpful first step would be to find a specific less-than-huge project which causes the currently weekly to die. I think setting up the actual CI process would be on me, but I'd love to have one project to start with :)

matklad commented 4 years ago

Actually, diesel would be a good example. I'll add it to CI, once we stop crashing on it.

Hm, actually, why re-invent the wheel? We should just re-use https://github.com/rust-lang/rustc-perf/tree/master/collector/benchmarks

flodiebold commented 4 years ago

That's where @edwin0cheng's page gets its test cases from, IIRC :smile:

matklad commented 4 years ago

The only problem so far it seems like we don't crash on those crates (though it looks like we are doing something exponential in servo's crates) =/ We do crash on diesel at the moment though.

matklad commented 4 years ago

Another, more time-consuming, but probably better option, is to learn to run analys-stats on rustc's test suite. This should be both faster and give us better coverage than analyzing full projects.

flodiebold commented 4 years ago

Oh, that's indeed an interesting idea :thinking:

I always had plans to someday test the type inference on rustc's test suite, but only once we're mostly complete. But just checking that it doesn't crash would be possible right now, of course...

matklad commented 4 years ago

Wait, no, we do in fact crash with this error on https://github.com/rust-lang/rustc-perf/tree/master/collector/benchmarks/hyper-2, which might be better (or worse) than diesel.

matklad commented 4 years ago

Did a first stab at the idea at https://github.com/rust-analyzer/rust-analyzer/pull/4104

At the moment, it does just a single-file analysis, without stdlib. it only found a couple of problems with macro expansion :(

flodiebold commented 4 years ago

Small guide to minimizing the reproducer for such a crash, in case someone is interested:

In the end I ended up with:

trait BoxedDsl<DB> {
    type Output;
    fn internal_into_boxed(self) -> Self::Output;
}

struct SelectStatement<From, Select, Distinct, Where, Order, LimitOffset, GroupBy, Locking> {
    order: Order,
}

trait QueryFragment<DB: Backend> {}

trait Into<T> { fn into(self) -> T; }

impl<F, S, D, W, O, LOf, DB> BoxedDsl<DB>
    for SelectStatement<F, S, D, W, O, LOf, G>
where
    O: Into<dyn QueryFragment<DB>>,
{
    type Output = XXX;

    fn internal_into_boxed(self) -> Self::Output {
        self.order.into();
    }
}

and copied that to a test, where it indeed still crashed. With that, finding and fixing the bug was just a matter of some print debugging :wink: