diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-12-03 12:58:44 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2019-12-03 12:58:44 +0000 |
commit | c5be0cedf3a9d56c17d988ce6354599b85198fb8 (patch) | |
tree | 70e3d0e36efa9568fb7f510f44bd65ff675122a2 /crates/ra_hir_ty/src/infer/expr.rs | |
parent | 3376c08052a563a5d2db487c458972378edebf44 (diff) | |
parent | 18f25acb89304b2eb0a822b7b49b5e66a439ada7 (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.rs | 30 |
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) => { |