diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-03-05 13:05:57 +0100 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-03-11 10:02:03 +0100 |
| commit | c679482d7effad2ed9e18c24cdb96e6baefeb02c (patch) | |
| tree | 9704d9b133c34618f9ab44ef3fbb8d10c548731f | |
| parent | d21f88883bd2dec2ab77ad760c9f19bf2f6839ff (diff) | |
| download | rust-c679482d7effad2ed9e18c24cdb96e6baefeb02c.tar.gz rust-c679482d7effad2ed9e18c24cdb96e6baefeb02c.zip | |
Add method resolution deref inference var test
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 14 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/unify.rs | 17 | ||||
| -rw-r--r-- | crates/hir-ty/src/tests/method_resolution.rs | 15 |
3 files changed, 30 insertions, 16 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs index 231eea041be..a3dab1fd9d5 100644 --- a/crates/hir-ty/src/infer/expr.rs +++ b/crates/hir-ty/src/infer/expr.rs @@ -312,15 +312,13 @@ impl InferenceContext<'_> { Expr::Call { callee, args, .. } => { let callee_ty = self.infer_expr(*callee, &Expectation::none()); let mut derefs = Autoderef::new(&mut self.table, callee_ty.clone(), false); - let (res, derefed_callee) = 'b: { - // manual loop to be able to access `derefs.table` - while let Some((callee_deref_ty, _)) = derefs.next() { - let res = derefs.table.callable_sig(&callee_deref_ty, args.len()); - if res.is_some() { - break 'b (res, callee_deref_ty); - } + let (res, derefed_callee) = loop { + let Some((callee_deref_ty, _)) = derefs.next() else { + break (None, callee_ty.clone()); + }; + if let Some(res) = derefs.table.callable_sig(&callee_deref_ty, args.len()) { + break (Some(res), callee_deref_ty); } - (None, callee_ty.clone()) }; // if the function is unresolved, we use is_varargs=true to // suppress the arg count diagnostic here diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs index c3614e44527..18029adbaf2 100644 --- a/crates/hir-ty/src/infer/unify.rs +++ b/crates/hir-ty/src/infer/unify.rs @@ -289,14 +289,14 @@ impl<'a> InferenceTable<'a> { } fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { + let is_diverging = self + .type_variable_table + .get(iv.index() as usize) + .map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING)); + if is_diverging { + return TyKind::Never.intern(Interner); + } match kind { - _ if self - .type_variable_table - .get(iv.index() as usize) - .map_or(false, |data| data.contains(TypeVariableFlags::DIVERGING)) => - { - TyKind::Never - } TyVariableKind::General => TyKind::Error, TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)), TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)), @@ -438,6 +438,7 @@ impl<'a> InferenceTable<'a> { where T: HasInterner<Interner = Interner> + TypeFoldable<Interner>, { + // TODO check this vec here self.resolve_with_fallback_inner(&mut Vec::new(), t, &fallback) } @@ -798,7 +799,7 @@ impl<'a> InferenceTable<'a> { let trait_data = self.db.trait_data(fn_once_trait); let output_assoc_type = trait_data.associated_type_by_name(&name![Output])?; - let mut arg_tys = vec![]; + let mut arg_tys = Vec::with_capacity(num_args); let arg_ty = TyBuilder::tuple(num_args) .fill(|it| { let arg = match it { diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs index c837fae3fef..049941a94f7 100644 --- a/crates/hir-ty/src/tests/method_resolution.rs +++ b/crates/hir-ty/src/tests/method_resolution.rs @@ -1796,6 +1796,21 @@ fn test() { } #[test] +fn deref_into_inference_var() { + check_types( + r#" +//- minicore:deref +struct A<T>(T); +impl core::ops::Deref for A<u32> {} +impl A<i32> { fn foo(&self) {} } +fn main() { + A(0).foo(); + //^^^^^^^^^^ () +} +"#, + ); +} +#[test] fn receiver_adjustment_autoref() { check( r#" |
