diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/expr.rs | 247 |
1 files changed, 133 insertions, 114 deletions
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index 2f9ca4bbb..3af05394c 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs | |||
@@ -6,17 +6,21 @@ use std::sync::Arc; | |||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | builtin_type::Signedness, | 7 | builtin_type::Signedness, |
8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, | 8 | expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, |
9 | generics::GenericParams, | ||
10 | path::{GenericArg, GenericArgs}, | 9 | path::{GenericArg, GenericArgs}, |
11 | resolver::resolver_for_expr, | 10 | resolver::resolver_for_expr, |
12 | AdtId, ContainerId, Lookup, StructFieldId, | 11 | AdtId, AssocContainerId, Lookup, StructFieldId, |
13 | }; | 12 | }; |
14 | use hir_expand::name::{self, Name}; | 13 | use hir_expand::name::{name, Name}; |
14 | use ra_syntax::ast::RangeOp; | ||
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
17 | autoderef, db::HirDatabase, method_resolution, op, traits::InEnvironment, utils::variant_data, | 17 | autoderef, |
18 | CallableDef, InferTy, IntTy, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Substs, | 18 | db::HirDatabase, |
19 | TraitRef, Ty, TypeCtor, TypeWalk, Uncertain, | 19 | method_resolution, op, |
20 | traits::InEnvironment, | ||
21 | utils::{generics, variant_data, Generics}, | ||
22 | ApplicationTy, CallableDef, InferTy, IntTy, Mutability, Obligation, Substs, TraitRef, Ty, | ||
23 | TypeCtor, TypeWalk, Uncertain, | ||
20 | }; | 24 | }; |
21 | 25 | ||
22 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; | 26 | use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; |
@@ -31,13 +35,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
31 | TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, | 35 | TypeMismatch { expected: expected.ty.clone(), actual: ty.clone() }, |
32 | ); | 36 | ); |
33 | } | 37 | } |
34 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 38 | let ty = self.resolve_ty_as_possible(ty); |
35 | ty | 39 | ty |
36 | } | 40 | } |
37 | 41 | ||
38 | /// Infer type of expression with possibly implicit coerce to the expected type. | 42 | /// Infer type of expression with possibly implicit coerce to the expected type. |
39 | /// Return the type after possible coercion. | 43 | /// Return the type after possible coercion. |
40 | fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { | 44 | pub(super) fn infer_expr_coerce(&mut self, expr: ExprId, expected: &Expectation) -> Ty { |
41 | let ty = self.infer_expr_inner(expr, &expected); | 45 | let ty = self.infer_expr_inner(expr, &expected); |
42 | let ty = if !self.coerce(&ty, &expected.ty) { | 46 | let ty = if !self.coerce(&ty, &expected.ty) { |
43 | self.result | 47 | self.result |
@@ -52,7 +56,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
52 | expected.ty.clone() | 56 | expected.ty.clone() |
53 | }; | 57 | }; |
54 | 58 | ||
55 | self.resolve_ty_as_possible(&mut vec![], ty) | 59 | self.resolve_ty_as_possible(ty) |
56 | } | 60 | } |
57 | 61 | ||
58 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 62 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
@@ -91,27 +95,14 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
91 | Expr::For { iterable, body, pat } => { | 95 | Expr::For { iterable, body, pat } => { |
92 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); | 96 | let iterable_ty = self.infer_expr(*iterable, &Expectation::none()); |
93 | 97 | ||
94 | let pat_ty = match self.resolve_into_iter_item() { | 98 | let pat_ty = |
95 | Some(into_iter_item_alias) => { | 99 | self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item()); |
96 | let pat_ty = self.new_type_var(); | ||
97 | let projection = ProjectionPredicate { | ||
98 | ty: pat_ty.clone(), | ||
99 | projection_ty: ProjectionTy { | ||
100 | associated_ty: into_iter_item_alias, | ||
101 | parameters: Substs::single(iterable_ty), | ||
102 | }, | ||
103 | }; | ||
104 | self.obligations.push(Obligation::Projection(projection)); | ||
105 | self.resolve_ty_as_possible(&mut vec![], pat_ty) | ||
106 | } | ||
107 | None => Ty::Unknown, | ||
108 | }; | ||
109 | 100 | ||
110 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); | 101 | self.infer_pat(*pat, &pat_ty, BindingMode::default()); |
111 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 102 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
112 | Ty::unit() | 103 | Ty::unit() |
113 | } | 104 | } |
114 | Expr::Lambda { body, args, arg_types } => { | 105 | Expr::Lambda { body, args, ret_type, arg_types } => { |
115 | assert_eq!(args.len(), arg_types.len()); | 106 | assert_eq!(args.len(), arg_types.len()); |
116 | 107 | ||
117 | let mut sig_tys = Vec::new(); | 108 | let mut sig_tys = Vec::new(); |
@@ -127,7 +118,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
127 | } | 118 | } |
128 | 119 | ||
129 | // add return type | 120 | // add return type |
130 | let ret_ty = self.new_type_var(); | 121 | let ret_ty = match ret_type { |
122 | Some(type_ref) => self.make_ty(type_ref), | ||
123 | None => self.table.new_type_var(), | ||
124 | }; | ||
131 | sig_tys.push(ret_ty.clone()); | 125 | sig_tys.push(ret_ty.clone()); |
132 | let sig_ty = Ty::apply( | 126 | let sig_ty = Ty::apply( |
133 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, | 127 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1 }, |
@@ -143,7 +137,12 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
143 | // infer the body. | 137 | // infer the body. |
144 | self.coerce(&closure_ty, &expected.ty); | 138 | self.coerce(&closure_ty, &expected.ty); |
145 | 139 | ||
146 | self.infer_expr(*body, &Expectation::has_type(ret_ty)); | 140 | let prev_ret_ty = std::mem::replace(&mut self.return_ty, ret_ty.clone()); |
141 | |||
142 | self.infer_expr_coerce(*body, &Expectation::has_type(ret_ty)); | ||
143 | |||
144 | self.return_ty = prev_ret_ty; | ||
145 | |||
147 | closure_ty | 146 | closure_ty |
148 | } | 147 | } |
149 | Expr::Call { callee, args } => { | 148 | Expr::Call { callee, args } => { |
@@ -166,7 +165,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
166 | Expr::Match { expr, arms } => { | 165 | Expr::Match { expr, arms } => { |
167 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 166 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
168 | 167 | ||
169 | let mut result_ty = self.new_maybe_never_type_var(); | 168 | let mut result_ty = self.table.new_maybe_never_type_var(); |
170 | 169 | ||
171 | for arm in arms { | 170 | for arm in arms { |
172 | for &pat in &arm.pats { | 171 | for &pat in &arm.pats { |
@@ -200,7 +199,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
200 | } | 199 | } |
201 | Expr::Return { expr } => { | 200 | Expr::Return { expr } => { |
202 | if let Some(expr) = expr { | 201 | if let Some(expr) = expr { |
203 | self.infer_expr(*expr, &Expectation::has_type(self.return_ty.clone())); | 202 | self.infer_expr_coerce(*expr, &Expectation::has_type(self.return_ty.clone())); |
203 | } else { | ||
204 | let unit = Ty::unit(); | ||
205 | self.coerce(&unit, &self.return_ty.clone()); | ||
204 | } | 206 | } |
205 | Ty::simple(TypeCtor::Never) | 207 | Ty::simple(TypeCtor::Never) |
206 | } | 208 | } |
@@ -244,7 +246,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
244 | ty | 246 | ty |
245 | } | 247 | } |
246 | Expr::Field { expr, name } => { | 248 | Expr::Field { expr, name } => { |
247 | let receiver_ty = self.infer_expr(*expr, &Expectation::none()); | 249 | let receiver_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
248 | let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); | 250 | let canonicalized = self.canonicalizer().canonicalize_ty(receiver_ty); |
249 | let ty = autoderef::autoderef( | 251 | let ty = autoderef::autoderef( |
250 | self.db, | 252 | self.db, |
@@ -279,45 +281,18 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
279 | self.normalize_associated_types_in(ty) | 281 | self.normalize_associated_types_in(ty) |
280 | } | 282 | } |
281 | Expr::Await { expr } => { | 283 | Expr::Await { expr } => { |
282 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 284 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
283 | let ty = match self.resolve_future_future_output() { | 285 | let ty = |
284 | Some(future_future_output_alias) => { | 286 | self.resolve_associated_type(inner_ty, self.resolve_future_future_output()); |
285 | let ty = self.new_type_var(); | ||
286 | let projection = ProjectionPredicate { | ||
287 | ty: ty.clone(), | ||
288 | projection_ty: ProjectionTy { | ||
289 | associated_ty: future_future_output_alias, | ||
290 | parameters: Substs::single(inner_ty), | ||
291 | }, | ||
292 | }; | ||
293 | self.obligations.push(Obligation::Projection(projection)); | ||
294 | self.resolve_ty_as_possible(&mut vec![], ty) | ||
295 | } | ||
296 | None => Ty::Unknown, | ||
297 | }; | ||
298 | ty | 287 | ty |
299 | } | 288 | } |
300 | Expr::Try { expr } => { | 289 | Expr::Try { expr } => { |
301 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 290 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
302 | let ty = match self.resolve_ops_try_ok() { | 291 | let ty = self.resolve_associated_type(inner_ty, self.resolve_ops_try_ok()); |
303 | Some(ops_try_ok_alias) => { | ||
304 | let ty = self.new_type_var(); | ||
305 | let projection = ProjectionPredicate { | ||
306 | ty: ty.clone(), | ||
307 | projection_ty: ProjectionTy { | ||
308 | associated_ty: ops_try_ok_alias, | ||
309 | parameters: Substs::single(inner_ty), | ||
310 | }, | ||
311 | }; | ||
312 | self.obligations.push(Obligation::Projection(projection)); | ||
313 | self.resolve_ty_as_possible(&mut vec![], ty) | ||
314 | } | ||
315 | None => Ty::Unknown, | ||
316 | }; | ||
317 | ty | 292 | ty |
318 | } | 293 | } |
319 | Expr::Cast { expr, type_ref } => { | 294 | Expr::Cast { expr, type_ref } => { |
320 | let _inner_ty = self.infer_expr(*expr, &Expectation::none()); | 295 | let _inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
321 | let cast_ty = self.make_ty(type_ref); | 296 | let cast_ty = self.make_ty(type_ref); |
322 | // FIXME check the cast... | 297 | // FIXME check the cast... |
323 | cast_ty | 298 | cast_ty |
@@ -333,12 +308,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
333 | } else { | 308 | } else { |
334 | Expectation::none() | 309 | Expectation::none() |
335 | }; | 310 | }; |
336 | // FIXME reference coercions etc. | 311 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
337 | let inner_ty = self.infer_expr(*expr, &expectation); | ||
338 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) | 312 | Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) |
339 | } | 313 | } |
340 | Expr::Box { expr } => { | 314 | Expr::Box { expr } => { |
341 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 315 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
342 | if let Some(box_) = self.resolve_boxed_box() { | 316 | if let Some(box_) = self.resolve_boxed_box() { |
343 | Ty::apply_one(TypeCtor::Adt(box_), inner_ty) | 317 | Ty::apply_one(TypeCtor::Adt(box_), inner_ty) |
344 | } else { | 318 | } else { |
@@ -346,7 +320,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
346 | } | 320 | } |
347 | } | 321 | } |
348 | Expr::UnaryOp { expr, op } => { | 322 | Expr::UnaryOp { expr, op } => { |
349 | let inner_ty = self.infer_expr(*expr, &Expectation::none()); | 323 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
350 | match op { | 324 | match op { |
351 | UnaryOp::Deref => match self.resolver.krate() { | 325 | UnaryOp::Deref => match self.resolver.krate() { |
352 | Some(krate) => { | 326 | Some(krate) => { |
@@ -369,31 +343,36 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
369 | }, | 343 | }, |
370 | UnaryOp::Neg => { | 344 | UnaryOp::Neg => { |
371 | match &inner_ty { | 345 | match &inner_ty { |
372 | Ty::Apply(a_ty) => match a_ty.ctor { | 346 | // Fast path for builtins |
373 | TypeCtor::Int(Uncertain::Unknown) | 347 | Ty::Apply(ApplicationTy { |
374 | | TypeCtor::Int(Uncertain::Known(IntTy { | 348 | ctor: |
375 | signedness: Signedness::Signed, | 349 | TypeCtor::Int(Uncertain::Known(IntTy { |
376 | .. | 350 | signedness: Signedness::Signed, |
377 | })) | 351 | .. |
378 | | TypeCtor::Float(..) => inner_ty, | 352 | })), |
379 | _ => Ty::Unknown, | 353 | .. |
380 | }, | 354 | }) |
381 | Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => { | 355 | | Ty::Apply(ApplicationTy { |
382 | inner_ty | 356 | ctor: TypeCtor::Int(Uncertain::Unknown), |
383 | } | 357 | .. |
384 | // FIXME: resolve ops::Neg trait | 358 | }) |
385 | _ => Ty::Unknown, | 359 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) |
360 | | Ty::Infer(InferTy::IntVar(..)) | ||
361 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
362 | // Otherwise we resolve via the std::ops::Neg trait | ||
363 | _ => self | ||
364 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | ||
386 | } | 365 | } |
387 | } | 366 | } |
388 | UnaryOp::Not => { | 367 | UnaryOp::Not => { |
389 | match &inner_ty { | 368 | match &inner_ty { |
390 | Ty::Apply(a_ty) => match a_ty.ctor { | 369 | // Fast path for builtins |
391 | TypeCtor::Bool | TypeCtor::Int(_) => inner_ty, | 370 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) |
392 | _ => Ty::Unknown, | 371 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) |
393 | }, | 372 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, |
394 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 373 | // Otherwise we resolve via the std::ops::Not trait |
395 | // FIXME: resolve ops::Not trait for inner_ty | 374 | _ => self |
396 | _ => Ty::Unknown, | 375 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
397 | } | 376 | } |
398 | } | 377 | } |
399 | } | 378 | } |
@@ -415,21 +394,63 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
415 | } | 394 | } |
416 | _ => Ty::Unknown, | 395 | _ => Ty::Unknown, |
417 | }, | 396 | }, |
397 | Expr::Range { lhs, rhs, range_type } => { | ||
398 | let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); | ||
399 | let rhs_expect = lhs_ty | ||
400 | .as_ref() | ||
401 | .map_or_else(Expectation::none, |ty| Expectation::has_type(ty.clone())); | ||
402 | let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); | ||
403 | match (range_type, lhs_ty, rhs_ty) { | ||
404 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | ||
405 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | ||
406 | None => Ty::Unknown, | ||
407 | }, | ||
408 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | ||
409 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
410 | None => Ty::Unknown, | ||
411 | }, | ||
412 | (RangeOp::Inclusive, None, Some(ty)) => { | ||
413 | match self.resolve_range_to_inclusive() { | ||
414 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
415 | None => Ty::Unknown, | ||
416 | } | ||
417 | } | ||
418 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | ||
419 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
420 | None => Ty::Unknown, | ||
421 | }, | ||
422 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | ||
423 | match self.resolve_range_inclusive() { | ||
424 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
425 | None => Ty::Unknown, | ||
426 | } | ||
427 | } | ||
428 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | ||
429 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | ||
430 | None => Ty::Unknown, | ||
431 | }, | ||
432 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | ||
433 | } | ||
434 | } | ||
418 | Expr::Index { base, index } => { | 435 | Expr::Index { base, index } => { |
419 | let _base_ty = self.infer_expr(*base, &Expectation::none()); | 436 | let base_ty = self.infer_expr_inner(*base, &Expectation::none()); |
420 | let _index_ty = self.infer_expr(*index, &Expectation::none()); | 437 | let index_ty = self.infer_expr(*index, &Expectation::none()); |
421 | // FIXME: use `std::ops::Index::Output` to figure out the real return type | 438 | |
422 | Ty::Unknown | 439 | self.resolve_associated_type_with_params( |
440 | base_ty, | ||
441 | self.resolve_ops_index_output(), | ||
442 | &[index_ty], | ||
443 | ) | ||
423 | } | 444 | } |
424 | Expr::Tuple { exprs } => { | 445 | Expr::Tuple { exprs } => { |
425 | let mut tys = match &expected.ty { | 446 | let mut tys = match &expected.ty { |
426 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 447 | ty_app!(TypeCtor::Tuple { .. }, st) => st |
427 | .iter() | 448 | .iter() |
428 | .cloned() | 449 | .cloned() |
429 | .chain(repeat_with(|| self.new_type_var())) | 450 | .chain(repeat_with(|| self.table.new_type_var())) |
430 | .take(exprs.len()) | 451 | .take(exprs.len()) |
431 | .collect::<Vec<_>>(), | 452 | .collect::<Vec<_>>(), |
432 | _ => (0..exprs.len()).map(|_| self.new_type_var()).collect(), | 453 | _ => (0..exprs.len()).map(|_| self.table.new_type_var()).collect(), |
433 | }; | 454 | }; |
434 | 455 | ||
435 | for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { | 456 | for (expr, ty) in exprs.iter().zip(tys.iter_mut()) { |
@@ -443,7 +464,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
443 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | 464 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { |
444 | st.as_single().clone() | 465 | st.as_single().clone() |
445 | } | 466 | } |
446 | _ => self.new_type_var(), | 467 | _ => self.table.new_type_var(), |
447 | }; | 468 | }; |
448 | 469 | ||
449 | match array { | 470 | match array { |
@@ -485,7 +506,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
485 | }; | 506 | }; |
486 | // use a new type variable if we got Ty::Unknown here | 507 | // use a new type variable if we got Ty::Unknown here |
487 | let ty = self.insert_type_vars_shallow(ty); | 508 | let ty = self.insert_type_vars_shallow(ty); |
488 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 509 | let ty = self.resolve_ty_as_possible(ty); |
489 | self.write_expr_ty(tgt_expr, ty.clone()); | 510 | self.write_expr_ty(tgt_expr, ty.clone()); |
490 | ty | 511 | ty |
491 | } | 512 | } |
@@ -514,7 +535,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
514 | } | 535 | } |
515 | } | 536 | } |
516 | 537 | ||
517 | let ty = self.resolve_ty_as_possible(&mut vec![], ty); | 538 | let ty = self.resolve_ty_as_possible(ty); |
518 | self.infer_pat(*pat, &ty, BindingMode::default()); | 539 | self.infer_pat(*pat, &ty, BindingMode::default()); |
519 | } | 540 | } |
520 | Statement::Expr(expr) => { | 541 | Statement::Expr(expr) => { |
@@ -558,7 +579,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
558 | Some((ty, func)) => { | 579 | Some((ty, func)) => { |
559 | let ty = canonicalized_receiver.decanonicalize_ty(ty); | 580 | let ty = canonicalized_receiver.decanonicalize_ty(ty); |
560 | self.write_method_resolution(tgt_expr, func); | 581 | self.write_method_resolution(tgt_expr, func); |
561 | (ty, self.db.value_ty(func.into()), Some(self.db.generic_params(func.into()))) | 582 | (ty, self.db.value_ty(func.into()), Some(generics(self.db, func.into()))) |
562 | } | 583 | } |
563 | None => (receiver_ty, Ty::Unknown, None), | 584 | None => (receiver_ty, Ty::Unknown, None), |
564 | }; | 585 | }; |
@@ -607,6 +628,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
607 | continue; | 628 | continue; |
608 | } | 629 | } |
609 | 630 | ||
631 | let param_ty = self.insert_vars_for_impl_trait(param_ty); | ||
610 | let param_ty = self.normalize_associated_types_in(param_ty); | 632 | let param_ty = self.normalize_associated_types_in(param_ty); |
611 | self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone())); | 633 | self.infer_expr_coerce(arg, &Expectation::has_type(param_ty.clone())); |
612 | } | 634 | } |
@@ -615,17 +637,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
615 | 637 | ||
616 | fn substs_for_method_call( | 638 | fn substs_for_method_call( |
617 | &mut self, | 639 | &mut self, |
618 | def_generics: Option<Arc<GenericParams>>, | 640 | def_generics: Option<Generics>, |
619 | generic_args: Option<&GenericArgs>, | 641 | generic_args: Option<&GenericArgs>, |
620 | receiver_ty: &Ty, | 642 | receiver_ty: &Ty, |
621 | ) -> Substs { | 643 | ) -> Substs { |
622 | let (parent_param_count, param_count) = | 644 | let (total_len, _parent_len, child_len) = |
623 | def_generics.as_ref().map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); | 645 | def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split()); |
624 | let mut substs = Vec::with_capacity(parent_param_count + param_count); | 646 | let mut substs = Vec::with_capacity(total_len); |
625 | // Parent arguments are unknown, except for the receiver type | 647 | // Parent arguments are unknown, except for the receiver type |
626 | if let Some(parent_generics) = def_generics.and_then(|p| p.parent_params.clone()) { | 648 | if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { |
627 | for param in &parent_generics.params { | 649 | for (_id, param) in parent_generics { |
628 | if param.name == name::SELF_TYPE { | 650 | if param.name == name![Self] { |
629 | substs.push(receiver_ty.clone()); | 651 | substs.push(receiver_ty.clone()); |
630 | } else { | 652 | } else { |
631 | substs.push(Ty::Unknown); | 653 | substs.push(Ty::Unknown); |
@@ -635,7 +657,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
635 | // handle provided type arguments | 657 | // handle provided type arguments |
636 | if let Some(generic_args) = generic_args { | 658 | if let Some(generic_args) = generic_args { |
637 | // if args are provided, it should be all of them, but we can't rely on that | 659 | // if args are provided, it should be all of them, but we can't rely on that |
638 | for arg in generic_args.args.iter().take(param_count) { | 660 | for arg in generic_args.args.iter().take(child_len) { |
639 | match arg { | 661 | match arg { |
640 | GenericArg::Type(type_ref) => { | 662 | GenericArg::Type(type_ref) => { |
641 | let ty = self.make_ty(type_ref); | 663 | let ty = self.make_ty(type_ref); |
@@ -645,10 +667,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
645 | } | 667 | } |
646 | }; | 668 | }; |
647 | let supplied_params = substs.len(); | 669 | let supplied_params = substs.len(); |
648 | for _ in supplied_params..parent_param_count + param_count { | 670 | for _ in supplied_params..total_len { |
649 | substs.push(Ty::Unknown); | 671 | substs.push(Ty::Unknown); |
650 | } | 672 | } |
651 | assert_eq!(substs.len(), parent_param_count + param_count); | 673 | assert_eq!(substs.len(), total_len); |
652 | Substs(substs.into()) | 674 | Substs(substs.into()) |
653 | } | 675 | } |
654 | 676 | ||
@@ -665,13 +687,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
665 | // add obligation for trait implementation, if this is a trait method | 687 | // add obligation for trait implementation, if this is a trait method |
666 | match def { | 688 | match def { |
667 | CallableDef::FunctionId(f) => { | 689 | CallableDef::FunctionId(f) => { |
668 | if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { | 690 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db).container { |
669 | // construct a TraitDef | 691 | // construct a TraitDef |
670 | let substs = a_ty.parameters.prefix( | 692 | let substs = |
671 | self.db | 693 | a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); |
672 | .generic_params(trait_.into()) | ||
673 | .count_params_including_parent(), | ||
674 | ); | ||
675 | self.obligations.push(Obligation::Trait(TraitRef { | 694 | self.obligations.push(Obligation::Trait(TraitRef { |
676 | trait_: trait_.into(), | 695 | trait_: trait_.into(), |
677 | substs, | 696 | substs, |