Repository: rust-analyzer/rust-analyzer (rust)

Issue:
Panic when trying to rename a local variable
<!--
Troubleshooting guide: https://rust-analyzer.github.io/manual.html#troubleshooting
Forum for questions: https://users.rust-lang.org/c/ide/14

Before submitting, please make sure that you're not running into one of these known issues:

 1. local imports (`use` statements) don't work: #1165
 2. local items don't work: #1559
 3. on-the-fly diagnostics are mostly unimplemented (`cargo check` diagnostics will be shown when saving a file)
 4. some settings are required for procedural macro and build script support (`rust-analyzer.cargo.loadOutDirsFromCheck`, `rust-analyzer.procMacro.enable`): #6448
 5. some platform-specific imports are not resolved: #6038
 6. the official `rust-lang.rust` VS Code extension conflicts with `rust-analyzer`: #6463

Otherwise please try to provide information which will help us to fix the issue faster. Minimal reproducible examples with few dependencies are especially lovely <3.
-->

```
thread '<unnamed>' panicked at 'expected substs of len 1, got Substs([Apply(ApplicationTy { ctor: Adt(EnumId(EnumId(524))), parameters: Substs([]) }), Apply(ApplicationTy { ctor: Adt(StructId(StructId(234))), parameters: Substs([]) })])', crates/hir_ty/src/lib.rs:397:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:475
   1: std::panicking::begin_panic_fmt
             at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:429
   2: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   3: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   4: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   5: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   6: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
   7: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::check_call_arguments
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_method_call
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  15: hir_ty::infer::infer_query
  16: salsa::runtime::Runtime::execute_query_implementation
  17: salsa::derived::slot::Slot<Q,MP>::read_upgrade
  18: salsa::derived::slot::Slot<Q,MP>::read
  19: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::try_fetch
  20: <DB as hir_ty::db::HirDatabase>::infer_query::__shim
  21: hir_ty::db::infer_wait
  22: hir_ty::diagnostics::validate_body
  23: hir::code_model::Module::diagnostics
  24: ide::diagnostics::diagnostics
  25: ide::Analysis::diagnostics
  26: rust_analyzer::handlers::handle_code_action
  27: <F as threadpool::FnBox>::call_box
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Panic context:
> request: rust-analyzer/inlayHints InlayHintsParams {
    text_document: TextDocumentIdentifier {
        uri: "file:///home/joshua/rustc/src/librustdoc/clean/inline.rs",
    },
}

thread '<unnamed>' panicked at 'expected substs of len 1, got Substs([Apply(ApplicationTy { ctor: Adt(EnumId(EnumId(524))), parameters: Substs([]) }), Apply(ApplicationTy { ctor: Adt(StructId(StructId(234))), parameters: Substs([]) })])', crates/hir_ty/src/lib.rs:397:13
stack backtrace:
   0: rust_begin_unwind
             at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:475
   1: std::panicking::begin_panic_fmt
             at /rustc/18bf6b4f01a6feaf7259ba7cdae58031af1b7b39/library/std/src/panicking.rs:429
   2: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   3: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   4: hir_ty::infer::pat::<impl hir_ty::infer::InferenceContext>::infer_pat
   5: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   6: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
   7: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
   8: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
   9: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::check_call_arguments
  10: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_method_call
  11: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  12: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr
  13: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  14: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
  15: hir_ty::infer::infer_query
  16: salsa::runtime::Runtime::execute_query_implementation
  17: salsa::derived::slot::Slot<Q,MP>::read_upgrade
  18: salsa::derived::slot::Slot<Q,MP>::read
  19: <salsa::derived::DerivedStorage<Q,MP> as salsa::plumbing::QueryStorageOps<Q>>::try_fetch
  20: <DB as hir_ty::db::HirDatabase>::infer_query::__shim
  21: hir_ty::db::infer_wait
  22: hir::source_analyzer::SourceAnalyzer::new_for_body
  23: hir::semantics::SemanticsImpl::analyze2
  24: hir::semantics::SemanticsImpl::scope
  25: ide::inlay_hints::inlay_hints
  26: ide::Analysis::inlay_hints
  27: rust_analyzer::handlers::handle_inlay_hints
  28: <F as threadpool::FnBox>::call_box
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
[Error - 1:55:31 PM] Request textDocument/prepareRename failed.
  Message: No references found at position
  Code: -32603 
```

This happened while trying to rename the `inner` variable at https://github.com/jyn514/rust/blob/2d2ba508a2a2c29c3be32b25341ffdf79e31922d/src/librustdoc/clean/mod.rs#L1288. I have not yet tried to reproduce the bug in something smaller.

Pull request:
Fix box pattern inference panic
Fixes #6560

Patch:
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index e3ac37e4c8..44eaeffb9e 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -2068,10 +2068,7 @@ impl Type {
                 match pred {
                     WhereClause::Implemented(trait_ref) => {
                         cb(type_.clone());
-                        // skip the self type. it's likely the type we just got the bounds from
-                        for ty in trait_ref.substitution.iter().skip(1) {
-                            walk_type(db, &type_.derived(ty.clone()), cb);
-                        }
+                        walk_substs(db, type_, &trait_ref.substitution, cb);
                     }
                     _ => (),
                 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 9d3b79be39..3845009ae7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -571,22 +571,13 @@ impl HirDisplay for Ty {
                         write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
                     }
                     TypeParamProvenance::ArgumentImplTrait => {
+                        let bounds = f.db.generic_predicates_for_param(id);
                         let substs = Substitution::type_params_for_generics(f.db, &generics);
-                        let bounds = f
-                            .db
-                            .generic_predicates(id.parent)
-                            .into_iter()
-                            .map(|pred| pred.clone().subst(&substs))
-                            .filter(|wc| match &wc {
-                                WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
-                                WhereClause::AliasEq(AliasEq {
-                                    alias: AliasTy::Projection(proj),
-                                    ty: _,
-                                }) => proj.self_type_parameter() == self,
-                                _ => false,
-                            })
-                            .collect::<Vec<_>>();
-                        write_bounds_like_dyn_trait_with_prefix("impl", &bounds, f)?;
+                        write_bounds_like_dyn_trait_with_prefix(
+                            "impl",
+                            &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
+                            f,
+                        )?;
                     }
                 }
             }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 79bbc5daba..24deff7073 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -513,10 +513,10 @@ impl<'a> InferenceContext<'a> {
                 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
                 if let Some(box_) = self.resolve_boxed_box() {
                     let mut sb =
-                        Substitution::builder(generics(self.db.upcast(), box_.into()).len());
+                        Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
                     sb = sb.push(inner_ty);
-                    match self.db.generic_defaults(box_.into()).as_ref() {
-                        [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
+                    match self.db.generic_defaults(box_.into()).get(1) {
+                        Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
                             sb = sb.push(alloc_ty.value.clone());
                         }
                         _ => (),
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index ec491648fe..474363709b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
 
 use super::{BindingMode, Expectation, InferenceContext};
 use crate::{
-    lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind,
+    lower::lower_to_chalk_mutability,
+    utils::{generics, variant_data},
+    Interner, Substitution, Ty, TyKind,
 };
 
 impl<'a> InferenceContext<'a> {
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
             Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
             Pat::Box { inner } => match self.resolve_boxed_box() {
                 Some(box_adt) => {
-                    let inner_expected = match expected.as_adt() {
-                        Some((adt, substs)) if adt == box_adt => substs.as_single().clone(),
-                        _ => self.result.standard_types.unknown.clone(),
+                    let (inner_ty, alloc_ty) = match expected.as_adt() {
+                        Some((adt, subst)) if adt == box_adt => {
+                            (subst[0].clone(), subst.get(1).cloned())
+                        }
+                        _ => (self.result.standard_types.unknown.clone(), None),
                     };
 
-                    let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm);
-                    Ty::adt_ty(box_adt, Substitution::single(inner_ty))
+                    let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
+                    let mut sb = Substitution::build_for_generics(&generics(
+                        self.db.upcast(),
+                        box_adt.into(),
+                    ));
+                    sb = sb.push(inner_ty);
+                    if sb.remaining() == 1 {
+                        sb = sb.push(match alloc_ty {
+                            Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
+                            _ => match self.db.generic_defaults(box_adt.into()).get(1) {
+                                Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
+                                    alloc_ty.value.clone()
+                                }
+                                _ => self.table.new_type_var(),
+                            },
+                        });
+                    }
+                    Ty::adt_ty(box_adt, sb.build())
                 }
                 None => self.err_ty(),
             },
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index ad908f957b..c46529879d 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -106,10 +106,6 @@ impl ProjectionTy {
         }
     }
 
-    pub fn self_type_parameter(&self) -> &Ty {
-        &self.substitution[0]
-    }
-
     fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
         match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
             AssocContainerId::TraitId(it) => it,
@@ -940,19 +936,10 @@ impl Ty {
                 let param_data = &generic_params.types[id.local_id];
                 match param_data.provenance {
                     hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
-                        let substs = Substitution::type_params(db, id.parent);
                         let predicates = db
-                            .generic_predicates(id.parent)
+                            .generic_predicates_for_param(id)
                             .into_iter()
-                            .map(|pred| pred.clone().subst(&substs))
-                            .filter(|wc| match &wc {
-                                WhereClause::Implemented(tr) => tr.self_type_parameter() == self,
-                                WhereClause::AliasEq(AliasEq {
-                                    alias: AliasTy::Projection(proj),
-                                    ty: _,
-                                }) => proj.self_type_parameter() == self,
-                                _ => false,
-                            })
+                            .map(|pred| pred.value.clone())
                             .collect_vec();
 
                         Some(predicates)
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index fd451a823e..c914a3b8e0 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -189,10 +189,7 @@ impl<'a> TyLoweringContext<'a> {
                 let self_ty =
                     TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
                 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
-                    bounds
-                        .iter()
-                        .flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false))
-                        .collect()
+                    bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
                 });
                 TyKind::Dyn(predicates).intern(&Interner)
             }
@@ -669,7 +666,6 @@ impl<'a> TyLoweringContext<'a> {
     pub(crate) fn lower_where_predicate(
         &'a self,
         where_predicate: &'a WherePredicate,
-        ignore_bindings: bool,
     ) -> impl Iterator<Item = WhereClause> + 'a {
         match where_predicate {
             WherePredicate::ForLifetime { target, bound, .. }
@@ -692,9 +688,7 @@ impl<'a> TyLoweringContext<'a> {
                         .intern(&Interner)
                     }
                 };
-                self.lower_type_bound(bound, self_ty, ignore_bindings)
-                    .collect::<Vec<_>>()
-                    .into_iter()
+                self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter()
             }
             WherePredicate::Lifetime { .. } => vec![].into_iter(),
         }
@@ -704,7 +698,6 @@ impl<'a> TyLoweringContext<'a> {
         &'a self,
         bound: &'a TypeBound,
         self_ty: Ty,
-        ignore_bindings: bool,
     ) -> impl Iterator<Item = WhereClause> + 'a {
         let mut bindings = None;
         let trait_ref = match bound {
@@ -718,7 +711,6 @@ impl<'a> TyLoweringContext<'a> {
         trait_ref.into_iter().chain(
             bindings
                 .into_iter()
-                .filter(move |_| !ignore_bindings)
                 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
         )
     }
@@ -763,7 +755,6 @@ impl<'a> TyLoweringContext<'a> {
                     preds.extend(self.lower_type_bound(
                         bound,
                         TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
-                        false,
                     ));
                 }
                 preds
@@ -775,7 +766,7 @@ impl<'a> TyLoweringContext<'a> {
         let self_ty =
             TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
         let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
-            bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone(), false)).collect()
+            bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
         });
         ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
     }
@@ -905,9 +896,7 @@ pub(crate) fn generic_predicates_for_param_query(
             },
             WherePredicate::Lifetime { .. } => false,
         })
-        .flat_map(|pred| {
-            ctx.lower_where_predicate(pred, true).map(|p| Binders::new(generics.len(), p))
-        })
+        .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
         .collect()
 }
 
@@ -929,7 +918,7 @@ pub(crate) fn trait_environment_query(
     let mut traits_in_scope = Vec::new();
     let mut clauses = Vec::new();
     for pred in resolver.where_predicates_in_scope() {
-        for pred in ctx.lower_where_predicate(pred, false) {
+        for pred in ctx.lower_where_predicate(pred) {
             if let WhereClause::Implemented(tr) = &pred {
                 traits_in_scope.push((tr.self_type_parameter().clone(), tr.hir_trait_id()));
             }
@@ -977,9 +966,7 @@ pub(crate) fn generic_predicates_query(
     let generics = generics(db.upcast(), def);
     resolver
         .where_predicates_in_scope()
-        .flat_map(|pred| {
-            ctx.lower_where_predicate(pred, false).map(|p| Binders::new(generics.len(), p))
-        })
+        .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
         .collect()
 }
 
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 9441456038..734679414b 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -395,7 +395,7 @@ pub(crate) fn associated_ty_data_query(
     let bounds = type_alias_data
         .bounds
         .iter()
-        .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone(), false))
+        .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone()))
         .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
         .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
         .collect();


Test patch:
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs
index ad283c1e04..0a4141e698 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -369,72 +369,3 @@ fn check_infer_with_mismatches(ra_fixture: &str, expect: Expect) {
     actual.push('\n');
     expect.assert_eq(&actual);
 }
-
-#[test]
-fn salsa_bug() {
-    let (mut db, pos) = TestDB::with_position(
-        "
-        //- /lib.rs
-        trait Index {
-            type Output;
-        }
-
-        type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
-
-        pub trait UnificationStoreBase: Index<Output = Key<Self>> {
-            type Key;
-
-            fn len(&self) -> usize;
-        }
-
-        pub trait UnificationStoreMut: UnificationStoreBase {
-            fn push(&mut self, value: Self::Key);
-        }
-
-        fn main() {
-            let x = 1;
-            x.push(1);$0
-        }
-    ",
-    );
-
-    let module = db.module_for_file(pos.file_id);
-    let crate_def_map = module.def_map(&db);
-    visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
-        db.infer(def);
-    });
-
-    let new_text = "
-        //- /lib.rs
-        trait Index {
-            type Output;
-        }
-
-        type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
-
-        pub trait UnificationStoreBase: Index<Output = Key<Self>> {
-            type Key;
-
-            fn len(&self) -> usize;
-        }
-
-        pub trait UnificationStoreMut: UnificationStoreBase {
-            fn push(&mut self, value: Self::Key);
-        }
-
-        fn main() {
-
-            let x = 1;
-            x.push(1);
-        }
-    "
-    .to_string();
-
-    db.set_file_text(pos.file_id, Arc::new(new_text));
-
-    let module = db.module_for_file(pos.file_id);
-    let crate_def_map = module.def_map(&db);
-    visit_module(&db, &crate_def_map, module.local_id, &mut |def| {
-        db.infer(def);
-    });
-}
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 5da19ba5f0..85a28e76b2 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -656,6 +656,28 @@ fn slice_tail_pattern() {
 
 #[test]
 fn box_pattern() {
+    check_infer(
+        r#"
+        pub struct Global;
+        #[lang = "owned_box"]
+        pub struct Box<T, A = Global>(T);
+
+        fn foo(params: Box<i32>) {
+            match params {
+                box integer => {}
+            }
+        }
+        "#,
+        expect![[r#"
+            83..89 'params': Box<i32, Global>
+            101..155 '{     ...   } }': ()
+            107..153 'match ...     }': ()
+            113..119 'params': Box<i32, Global>
+            130..141 'box integer': Box<i32, Global>
+            134..141 'integer': i32
+            145..147 '{}': ()
+        "#]],
+    );
     check_infer(
         r#"
         #[lang = "owned_box"]
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index 37cd04c6f7..8f2bdffc03 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -2271,56 +2271,6 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> {
     );
 }
 
-#[test]
-fn unselected_projection_in_trait_env_cycle_3() {
-    // this is a cycle for rustc; we currently accept it
-    check_types(
-        r#"
-//- /main.rs
-trait Trait {
-    type Item;
-    type OtherItem;
-}
-
-fn test<T>() where T: Trait<OtherItem = T::Item> {
-    let x: T::Item = no_matter;
-}                   //^ Trait::Item<T>
-"#,
-    );
-}
-
-#[test]
-fn unselected_projection_in_trait_env_no_cycle() {
-    // this is not a cycle
-    check_types(
-        r#"
-//- /main.rs
-trait Index {
-    type Output;
-}
-
-type Key<S: UnificationStoreBase> = <S as UnificationStoreBase>::Key;
-
-pub trait UnificationStoreBase: Index<Output = Key<Self>> {
-    type Key;
-
-    fn len(&self) -> usize;
-}
-
-pub trait UnificationStoreMut: UnificationStoreBase {
-    fn push(&mut self, value: Self::Key);
-}
-
-fn test<T>(t: T) where T: UnificationStoreMut {
-    let x;
-    t.push(x);
-    let y: Key<T>;
-    (x, y);
-}      //^ (UnificationStoreBase::Key<T>, UnificationStoreBase::Key<T>)
-"#,
-    );
-}
-
 #[test]
 fn inline_assoc_type_bounds_1() {
     check_types(