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

Issue:
Chalk panic accessing associated type with fully qualified syntax
**rust-analyzer version**: rust-analyzer 0.0.0 (18414cdf64 2024-08-12)

**rustc version**: rustc 1.80.1 (3f5fd8dd4 2024-08-06)

**code snippet to reproduce**: 
```rust
trait T {
    type A;
}

type Foo = <S as T>::A; // note that S isn't defined

fn main() {
    Foo {}
}
```
Panic:
```
thread 'main' panicked at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ena-0.14.3/src/snapshot_vec.rs:199:10:
index out of bounds: the len is 1 but the index is 1
stack backtrace:
   0: rust_begin_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_bounds_check
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:274:5
   3: ena::unify::UnificationTable<S>::inlined_probe_value
   4: ena::unify::UnificationTable<S>::probe_value
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ena-0.14.3/src/unify/mod.rs:560:9
   5: chalk_solve::infer::InferenceTable<I>::probe_var
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-solve-0.98.0/src/infer.rs:179:26
   6: <chalk_solve::infer::canonicalize::Canonicalizer<I> as chalk_ir::fold::TypeFolder<I>>::fold_inference_ty
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-solve-0.98.0/src/infer/canonicalize.rs:156:15
   7: <chalk_ir::Ty<I> as chalk_ir::fold::TypeSuperFoldable<I>>::try_super_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold.rs:698:17
   8: chalk_ir::fold::TypeSuperFoldable::super_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold.rs:649:9
   9: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::GenericArgData<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/lib.rs:1524:53
  10: chalk_ir::fold::boring_impls::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::GenericArg<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold/boring_impls.rs:70:20
  11: chalk_ir::fold::boring_impls::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::Substitution<I>>::try_fold_with::{{closure}}
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold/boring_impls.rs:89:22
  12: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ops/function.rs:305:13
  13: core::option::Option<T>::map
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/option.rs:1075:29
  14: <core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::next
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/adapters/map.rs:108:26
  15: <chalk_ir::cast::Casted<IT,U> as core::iter::traits::iterator::Iterator>::next
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/cast.rs:339:9
  16: core::iter::traits::iterator::Iterator::try_fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:2410:29
  17: <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::try_fold
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/adapters/mod.rs:204:9
  18: core::iter::traits::iterator::Iterator::try_for_each
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/traits/iterator.rs:2473:9
  19: <core::iter::adapters::GenericShunt<I,R> as core::iter::traits::iterator::Iterator>::next
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/iter/adapters/mod.rs:187:14
  20: <smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smallvec-1.13.2/src/lib.rs:2071:36
  21: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::AliasTy<I>>::try_fold_with
  22: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::AliasEq<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/lib.rs:2025:38
  23: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::WhereClause<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/lib.rs:1730:38
  24: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::DomainGoal<I>>::try_fold_with
  25: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<I> for chalk_ir::GoalData<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/lib.rs:2563:38
  26: <chalk_ir::Goal<I> as chalk_ir::fold::TypeSuperFoldable<I>>::try_super_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold.rs:903:13
  27: chalk_ir::fold::TypeSuperFoldable::super_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold.rs:649:9
  28: <chalk_ir::Goal<I> as chalk_ir::fold::TypeFoldable<I>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/fold.rs:889:9
  29: chalk_ir::_::<impl chalk_ir::fold::TypeFoldable<_I> for chalk_ir::InEnvironment<G>>::try_fold_with
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-ir-0.98.0/src/lib.rs:202:45
  30: chalk_solve::infer::canonicalize::<impl chalk_solve::infer::InferenceTable<I>>::canonicalize
             at /Users/davidrichey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/chalk-solve-0.98.0/src/infer/canonicalize.rs:43:21
  31: hir_ty::infer::unify::InferenceTable::canonicalize_with_free_vars
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/unify.rs:301:22
  32: hir_ty::infer::unify::InferenceTable::register_obligation_in_env
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/unify.rs:605:29
  33: hir_ty::infer::unify::InferenceTable::register_obligation
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/unify.rs:601:9
  34: hir_ty::infer::unify::InferenceTable::normalize_projection_ty
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/unify.rs:368:9
  35: hir_ty::traits::normalize_projection_query
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/traits.rs:94:14
  36: hir_ty::infer::InferenceContext::resolve_variant_on_alias
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer.rs:1439:17
  37: hir_ty::infer::InferenceContext::resolve_variant
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer.rs:1398:17
  38: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  39: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_coerce
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/expr.rs:76:18
  40: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block::{{closure}}
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/expr.rs:1424:21
  41: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::with_breakable_ctx
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/expr.rs:2136:19
  42: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_block
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/expr.rs:1369:13
  43: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_expr_inner
  44: hir_ty::infer::expr::<impl hir_ty::infer::InferenceContext>::infer_return
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer/expr.rs:1087:30
  45: hir_ty::infer::InferenceContext::infer_body
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer.rs:1057:24
  46: hir_ty::infer::infer_query
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/infer.rs:133:5
  47: <hir_ty::db::InferQuery as salsa::plumbing::QueryFunction>::execute
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/db.rs:34:21
  48: salsa::derived::slot::Slot<Q>::execute::{{closure}}
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/derived/slot.rs:224:43
  49: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panic/unwind_safe.rs:272:9
  50: std::panicking::try::do_call
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:559:40
  51: std::panicking::try
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:523:19
  52: std::panic::catch_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panic.rs:149:14
  53: salsa::Cycle::catch
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/lib.rs:692:15
  54: salsa::derived::slot::Slot<Q>::execute
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/derived/slot.rs:224:27
  55: salsa::derived::slot::Slot<Q>::read_upgrade
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/derived/slot.rs:202:9
  56: salsa::derived::slot::Slot<Q>::read
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/derived/slot.rs:140:9
  57: <salsa::derived::DerivedStorage<Q> as salsa::plumbing::QueryStorageOps<Q>>::fetch
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/derived.rs:108:62
  58: salsa::QueryTable<Q>::get
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/salsa/src/lib.rs:502:9
  59: <DB as hir_ty::db::HirDatabase>::infer::__shim
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/db.rs:32:1
  60: <DB as hir_ty::db::HirDatabase>::infer
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir-ty/src/db.rs:32:1
  61: hir::source_analyzer::SourceAnalyzer::new_for_body
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir/src/source_analyzer.rs:72:57
  62: hir::semantics::SemanticsImpl::analyze_impl
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir/src/semantics.rs:1531:21
  63: hir::semantics::SemanticsImpl::analyze
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir/src/semantics.rs:1501:9
  64: hir::semantics::SemanticsImpl::resolve_path
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/hir/src/semantics.rs:1429:9
  65: ide_db::defs::NameRefClass::classify
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide-db/src/defs.rs:625:20
  66: ide_db::defs::IdentClass::classify_node
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide-db/src/defs.rs:291:43
  67: ide_db::defs::IdentClass::classify_token
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide-db/src/defs.rs:312:9
  68: ide_db::helpers::get_definition
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide-db/src/helpers.rs:122:19
  69: ide::static_index::StaticIndex::add_file
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide/src/static_index.rs:188:29
  70: ide::static_index::StaticIndex::compute
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/ide/src/static_index.rs:257:13
  71: rust_analyzer::cli::scip::<impl rust_analyzer::cli::flags::Scip>::run
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/rust-analyzer/src/cli/scip.rs:66:18
  72: rust_analyzer::actual_main
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/rust-analyzer/src/bin/main.rs:88:46
  73: rust_analyzer::main
             at /Users/davidrichey/Desktop/test/rust-analyzer/crates/rust-analyzer/src/bin/main.rs:39:9
  74: core::ops::function::FnOnce::call_once
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

Pull request description:
fix: Panic while canonicalizing erroneous projection type
Fixes #17866 

The root cause of #17866 is quite horrifyng 😨 

```rust
trait T {
    type A;
}

type Foo = <S as T>::A; // note that S isn't defined

fn main() {
    Foo {}
}
```

While inferencing alias type `Foo = <S as T>::A`;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer.rs#L1388-L1398

the error type `S` in it is substituted by inference var in L1396 above as below;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer/unify.rs#L866-L869

This new inference var's index is `1`, as the type inferecing procedure here previously inserted another inference var into same `InferenceTable`.

But after that, the projection type made from the above then passed to the following function;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/traits.rs#L88-L96

here, a whole new `InferenceTable` is made, without any inference var and in the L94, this table calls;

https://github.com/rust-lang/rust-analyzer/blob/78c2bdce860dbd996a8083224d01a96660dd6a15/crates/hir-ty/src/infer/unify.rs#L364-L370

And while registering `AliasEq` `obligation`, this obligation contains inference var `?1` made from the previous table, but this table has only one inference var `?0` made at L365.
So, the chalk panics when we try to canonicalize that obligation to register it, because the obligation contains an inference var `?1` that the canonicalizing table doesn't have.

Currently, we are calling `InferenceTable::new()` to do some normalizing, unifying or coercing things to some targets that might contain inference var that the new table doesn't have.
I think that this is quite dangerous footgun because the inference var is just an index that does not contain the information which table does it made from, so sometimes this "foreign" index might cause panic like this case, or point at the wrong variable.

This PR mitigates such behaviour simply by inserting sufficient number of inference vars to new table to avoid such problem.
This strategy doesn't harm current r-a's intention because the inference vars that passed into new tables are just "unresolved" variables in current r-a, so this is just making sure that such "unresolved" variables exist in the new table  

Patch:
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 45d423d03c..5a7deab3a4 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -1436,7 +1436,8 @@ impl<'a> InferenceContext<'a> {
         let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
         let ty = match ty.kind(Interner) {
             TyKind::Alias(AliasTy::Projection(proj_ty)) => {
-                self.db.normalize_projection(proj_ty.clone(), self.table.trait_env.clone())
+                let ty = self.table.normalize_projection_ty(proj_ty.clone());
+                self.table.resolve_ty_shallow(&ty)
             }
             _ => ty,
         };
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index e40c6a63f6..f5eb37f427 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -793,12 +793,11 @@ impl InferenceContext<'_> {
                         .trait_data(index_trait)
                         .method_by_name(&Name::new_symbol_root(sym::index.clone()))
                     {
-                        let subst = TyBuilder::subst_for_def(self.db, index_trait, None);
-                        if subst.remaining() != 2 {
-                            return self.err_ty();
-                        }
-                        let subst = subst.push(self_ty.clone()).push(index_ty.clone()).build();
-                        self.write_method_resolution(tgt_expr, func, subst);
+                        let substs = TyBuilder::subst_for_def(self.db, index_trait, None)
+                            .push(self_ty.clone())
+                            .push(index_ty.clone())
+                            .build();
+                        self.write_method_resolution(tgt_expr, func, substs);
                     }
                     let assoc = self.resolve_ops_index_output();
                     let res = self.resolve_associated_type_with_params(
@@ -1296,12 +1295,10 @@ impl InferenceContext<'_> {
 
         // HACK: We can use this substitution for the function because the function itself doesn't
         // have its own generic parameters.
-        let subst = TyBuilder::subst_for_def(self.db, trait_, None);
-        if subst.remaining() != 2 {
-            return Ty::new(Interner, TyKind::Error);
-        }
-        let subst = subst.push(lhs_ty.clone()).push(rhs_ty.clone()).build();
-
+        let subst = TyBuilder::subst_for_def(self.db, trait_, None)
+            .push(lhs_ty.clone())
+            .push(rhs_ty.clone())
+            .build();
         self.write_method_resolution(tgt_expr, func, subst.clone());
 
         let method_ty = self.db.value_ty(func.into()).unwrap().substitute(Interner, &subst);
diff --git a/crates/hir-ty/src/traits.rs b/crates/hir-ty/src/traits.rs
index c46382a0ea..00791c5149 100644
--- a/crates/hir-ty/src/traits.rs
+++ b/crates/hir-ty/src/traits.rs
@@ -14,13 +14,13 @@ use hir_def::{
 };
 use hir_expand::name::Name;
 use intern::sym;
-use stdx::panic_context;
+use stdx::{never, panic_context};
 use triomphe::Arc;
 
 use crate::{
     db::HirDatabase, infer::unify::InferenceTable, utils::UnevaluatedConstEvaluatorFolder, AliasEq,
     AliasTy, Canonical, DomainGoal, Goal, Guidance, InEnvironment, Interner, ProjectionTy,
-    ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, WhereClause,
+    ProjectionTyExt, Solution, TraitRefExt, Ty, TyKind, TypeFlags, WhereClause,
 };
 
 /// This controls how much 'time' we give the Chalk solver before giving up.
@@ -90,6 +90,16 @@ pub(crate) fn normalize_projection_query(
     projection: ProjectionTy,
     env: Arc<TraitEnvironment>,
 ) -> Ty {
+    if projection.substitution.iter(Interner).any(|arg| {
+        arg.ty(Interner)
+            .is_some_and(|ty| ty.data(Interner).flags.intersects(TypeFlags::HAS_TY_INFER))
+    }) {
+        never!(
+            "Invoking `normalize_projection_query` with a projection type containing inference var"
+        );
+        return TyKind::Error.intern(Interner);
+    }
+
     let mut table = InferenceTable::new(db, env);
     let ty = table.normalize_projection_ty(projection);
     table.resolve_completely(ty)
diff --git a/crates/rust-analyzer/src/op_queue.rs b/crates/rust-analyzer/src/op_queue.rs
index eab9733872..99f9e9829c 100644
--- a/crates/rust-analyzer/src/op_queue.rs
+++ b/crates/rust-analyzer/src/op_queue.rs
@@ -3,26 +3,6 @@
 
 pub(crate) type Cause = String;
 
-/// A single-item queue that allows callers to request an operation to
-/// be performed later.
-///
-/// ```
-/// let queue = OpQueue::default();
-///
-/// // Request work to be done.
-/// queue.request_op("user pushed a button", ());
-///
-/// // In a later iteration of the server loop, we start the work.
-/// if let Some((_cause, ())) = queue.should_start_op() {
-///     dbg!("Some slow operation here");
-/// }
-///
-/// // In an even later iteration of the server loop, we can see that the work
-/// // was completed.
-/// if !queue.op_in_progress() {
-///     dbg!("Work has been done!");
-/// }
-/// ```
 #[derive(Debug)]
 pub(crate) struct OpQueue<Args = (), Output = ()> {
     op_requested: Option<(Cause, Args)>,


Test patch:
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 2819838612..26e9243e73 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -2141,3 +2141,24 @@ fn test() {
 }"#,
     );
 }
+
+#[test]
+fn issue_17866() {
+    check_infer(
+        r#"
+trait T {
+    type A;
+}
+
+type Foo = <S as T>::A;
+
+fn main() {
+    Foo {};
+}
+"#,
+        expect![[r#"
+            60..75 '{     Foo {}; }': ()
+            66..72 'Foo {}': {unknown}
+        "#]],
+    );
+}
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index a15670b3c8..d83a34298e 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -3686,36 +3686,3 @@ fn main() {
 "#,
     );
 }
-
-#[test]
-fn infer_bad_lang_item() {
-    check_infer(
-        r#"
-#[lang="eq"]
-pub trait Eq {
-    fn eq(&self, ) -> bool;
-
-}
-
-#[lang="shr"]
-pub trait Shr<RHS,Result> {
-    fn shr(&self, rhs: &RHS) -> Result;
-}
-
-fn test() -> bool {
-    1 >> 1;
-    1 == 1;
-}
-"#,
-        expect![[r#"
-            39..43 'self': &'? Self
-            114..118 'self': &'? Self
-            120..123 'rhs': &'? RHS
-            163..190 '{     ...= 1; }': bool
-            169..170 '1': i32
-            169..175 '1 >> 1': {unknown}
-            181..182 '1': i32
-            181..187 '1 == 1': {unknown}
-        "#]],
-    );
-}