aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer/expr.rs')
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs247
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;
6use hir_def::{ 6use 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};
14use hir_expand::name::{self, Name}; 13use hir_expand::name::{name, Name};
14use ra_syntax::ast::RangeOp;
15 15
16use crate::{ 16use 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
22use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; 26use 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,