diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs index f5eb37f427876..e40c6a63f661d 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/expr.rs @@ -793,11 +793,12 @@ impl InferenceContext<'_> { .trait_data(index_trait) .method_by_name(&Name::new_symbol_root(sym::index.clone())) { - 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 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 assoc = self.resolve_ops_index_output(); let res = self.resolve_associated_type_with_params( @@ -1295,10 +1296,12 @@ 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) - .push(lhs_ty.clone()) - .push(rhs_ty.clone()) - .build(); + 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(); + 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/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs index d83a34298eab0..a15670b3c85d9 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/tests/simple.rs @@ -3686,3 +3686,36 @@ 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 { + 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} + "#]], + ); +}