aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2019-12-03 12:58:44 +0000
committerGitHub <[email protected]>2019-12-03 12:58:44 +0000
commitc5be0cedf3a9d56c17d988ce6354599b85198fb8 (patch)
tree70e3d0e36efa9568fb7f510f44bd65ff675122a2 /crates/ra_hir_ty/src/infer/expr.rs
parent3376c08052a563a5d2db487c458972378edebf44 (diff)
parent18f25acb89304b2eb0a822b7b49b5e66a439ada7 (diff)
Merge #2463
2463: More correct method resolution r=flodiebold a=flodiebold This should fix the order in which candidates for method resolution are considered, i.e. `(&Foo).clone()` should now be of type `Foo` instead of `&Foo`. It also checks for inherent candidates that the self type unifies properly with the self type in the impl (i.e. `impl Foo<u32>` methods will only be considered for `Foo<u32>`). To be able to get the correct receiver type to check in the method resolution, I needed the unification logic, so I extracted it to the `unify.rs` module. Should fix #2435. Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir_ty/src/infer/expr.rs')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs30
1 files changed, 15 insertions, 15 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index 4014f4732..1e78f6efd 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -32,7 +32,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
32 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, 32 TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() },
33 ); 33 );
34 } 34 }
35 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 35 let ty = self.resolve_ty_as_possible(ty);
36 ty 36 ty
37 } 37 }
38 38
@@ -53,7 +53,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
53 expected.ty.clone() 53 expected.ty.clone()
54 }; 54 };
55 55
56 self.resolve_ty_as_possible(&mut vec![], ty) 56 self.resolve_ty_as_possible(ty)
57 } 57 }
58 58
59 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 59 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
@@ -94,7 +94,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
94 94
95 let pat_ty = match self.resolve_into_iter_item() { 95 let pat_ty = match self.resolve_into_iter_item() {
96 Some(into_iter_item_alias) => { 96 Some(into_iter_item_alias) => {
97 let pat_ty = self.new_type_var(); 97 let pat_ty = self.table.new_type_var();
98 let projection = ProjectionPredicate { 98 let projection = ProjectionPredicate {
99 ty: pat_ty.clone(), 99 ty: pat_ty.clone(),
100 projection_ty: ProjectionTy { 100 projection_ty: ProjectionTy {
@@ -103,7 +103,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
103 }, 103 },
104 }; 104 };
105 self.obligations.push(Obligation::Projection(projection)); 105 self.obligations.push(Obligation::Projection(projection));
106 self.resolve_ty_as_possible(&mut vec![], pat_ty) 106 self.resolve_ty_as_possible(pat_ty)
107 } 107 }
108 None => Ty::Unknown, 108 None => Ty::Unknown,
109 }; 109 };
@@ -128,7 +128,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
128 } 128 }
129 129
130 // add return type 130 // add return type
131 let ret_ty = self.new_type_var(); 131 let ret_ty = self.table.new_type_var();
132 sig_tys.push(ret_ty.clone()); 132 sig_tys.push(ret_ty.clone());
133 let sig_ty = Ty::apply( 133 let sig_ty = Ty::apply(
134 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, 134 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 },
@@ -167,7 +167,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
167 Expr::Match { expr, arms } => { 167 Expr::Match { expr, arms } => {
168 let input_ty = self.infer_expr(*expr, &Expectation::none()); 168 let input_ty = self.infer_expr(*expr, &Expectation::none());
169 169
170 let mut result_ty = self.new_maybe_never_type_var(); 170 let mut result_ty = self.table.new_maybe_never_type_var();
171 171
172 for arm in arms { 172 for arm in arms {
173 for &pat in &arm.pats { 173 for &pat in &arm.pats {
@@ -283,7 +283,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
283 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 283 let inner_ty = self.infer_expr(*expr, &Expectation::none());
284 let ty = match self.resolve_future_future_output() { 284 let ty = match self.resolve_future_future_output() {
285 Some(future_future_output_alias) => { 285 Some(future_future_output_alias) => {
286 let ty = self.new_type_var(); 286 let ty = self.table.new_type_var();
287 let projection = ProjectionPredicate { 287 let projection = ProjectionPredicate {
288 ty: ty.clone(), 288 ty: ty.clone(),
289 projection_ty: ProjectionTy { 289 projection_ty: ProjectionTy {
@@ -292,7 +292,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
292 }, 292 },
293 }; 293 };
294 self.obligations.push(Obligation::Projection(projection)); 294 self.obligations.push(Obligation::Projection(projection));
295 self.resolve_ty_as_possible(&mut vec![], ty) 295 self.resolve_ty_as_possible(ty)
296 } 296 }
297 None => Ty::Unknown, 297 None => Ty::Unknown,
298 }; 298 };
@@ -302,7 +302,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
302 let inner_ty = self.infer_expr(*expr, &Expectation::none()); 302 let inner_ty = self.infer_expr(*expr, &Expectation::none());
303 let ty = match self.resolve_ops_try_ok() { 303 let ty = match self.resolve_ops_try_ok() {
304 Some(ops_try_ok_alias) => { 304 Some(ops_try_ok_alias) => {
305 let ty = self.new_type_var(); 305 let ty = self.table.new_type_var();
306 let projection = ProjectionPredicate { 306 let projection = ProjectionPredicate {
307 ty: ty.clone(), 307 ty: ty.clone(),
308 projection_ty: ProjectionTy { 308 projection_ty: ProjectionTy {
@@ -311,7 +311,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
311 }, 311 },
312 }; 312 };
313 self.obligations.push(Obligation::Projection(projection)); 313 self.obligations.push(Obligation::Projection(projection));
314 self.resolve_ty_as_possible(&mut vec![], ty) 314 self.resolve_ty_as_possible(ty)
315 } 315 }
316 None => Ty::Unknown, 316 None => Ty::Unknown,
317 }; 317 };
@@ -465,10 +465,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
465 ty_app!(TypeCtor::Tuple { .. }, st) => st 465 ty_app!(TypeCtor::Tuple { .. }, st) => st
466 .iter() 466 .iter()
467 .cloned() 467 .cloned()
468 .chain(repeat_with(|| self.new_type_var())) 468 .chain(repeat_with(|| self.table.new_type_var()))
469 .take(exprs.len()) 469 .take(exprs.len())
470 .collect::<Vec<_>>(), 470 .collect::<Vec<_>>(),
471 _ => (0..exprs.len()).map(|_| self.new_type_var()).collect(), 471 _ => (0..exprs.len()).map(|_| self.table.new_type_var()).collect(),
472 }; 472 };
473 473
474 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { 474 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
@@ -482,7 +482,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
482 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { 482 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
483 st.as_single().clone() 483 st.as_single().clone()
484 } 484 }
485 _ => self.new_type_var(), 485 _ => self.table.new_type_var(),
486 }; 486 };
487 487
488 match array { 488 match array {
@@ -524,7 +524,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
524 }; 524 };
525 // use a new type variable if we got Ty::Unknown here 525 // use a new type variable if we got Ty::Unknown here
526 let ty = self.insert_type_vars_shallow(ty); 526 let ty = self.insert_type_vars_shallow(ty);
527 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 527 let ty = self.resolve_ty_as_possible(ty);
528 self.write_expr_ty(tgt_expr, ty.clone()); 528 self.write_expr_ty(tgt_expr, ty.clone());
529 ty 529 ty
530 } 530 }
@@ -553,7 +553,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
553 } 553 }
554 } 554 }
555 555
556 let ty = self.resolve_ty_as_possible(&mut vec![], ty); 556 let ty = self.resolve_ty_as_possible(ty);
557 self.infer_pat(*pat, &ty, BindingMode::default()); 557 self.infer_pat(*pat, &ty, BindingMode::default());
558 } 558 }
559 Statement::Expr(expr) => { 559 Statement::Expr(expr) => {