aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty.rs')
-rw-r--r--crates/ra_hir/src/ty.rs65
1 files changed, 52 insertions, 13 deletions
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index f28a7e731..562ad1f49 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -165,6 +165,17 @@ impl Substs {
165 pub fn empty() -> Substs { 165 pub fn empty() -> Substs {
166 Substs(Arc::new([])) 166 Substs(Arc::new([]))
167 } 167 }
168
169 /// Replaces the end of the substitutions by other ones.
170 pub(crate) fn replace_tail(self, replace_by: Vec<Ty>) -> Substs {
171 // again missing Arc::make_mut_slice...
172 let len = replace_by.len().min(self.0.len());
173 let parent_len = self.0.len() - len;
174 let mut result = Vec::with_capacity(parent_len + len);
175 result.extend(self.0.iter().take(parent_len).cloned());
176 result.extend(replace_by);
177 Substs(result.into())
178 }
168} 179}
169 180
170/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs). 181/// A type. This is based on the `TyKind` enum in rustc (librustc/ty/sty.rs).
@@ -421,7 +432,8 @@ impl Ty {
421 (var.parent_enum(db).generic_params(db), segment) 432 (var.parent_enum(db).generic_params(db), segment)
422 } 433 }
423 }; 434 };
424 // substs_from_path 435 let parent_param_count = def_generics.count_parent_params();
436 substs.extend((0..parent_param_count).map(|_| Ty::Unknown));
425 if let Some(generic_args) = &segment.args_and_bindings { 437 if let Some(generic_args) = &segment.args_and_bindings {
426 // if args are provided, it should be all of them, but we can't rely on that 438 // if args are provided, it should be all of them, but we can't rely on that
427 let param_count = def_generics.params.len(); 439 let param_count = def_generics.params.len();
@@ -436,9 +448,8 @@ impl Ty {
436 } 448 }
437 // add placeholders for args that were not provided 449 // add placeholders for args that were not provided
438 // TODO: handle defaults 450 // TODO: handle defaults
439 let supplied_params = 451 let supplied_params = substs.len();
440 segment.args_and_bindings.as_ref().map(|ga| ga.args.len()).unwrap_or(0); 452 for _ in supplied_params..def_generics.count_params_including_parent() {
441 for _ in supplied_params..def_generics.params.len() {
442 substs.push(Ty::Unknown); 453 substs.push(Ty::Unknown);
443 } 454 }
444 assert_eq!(substs.len(), def_generics.params.len()); 455 assert_eq!(substs.len(), def_generics.params.len());
@@ -666,7 +677,12 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty {
666} 677}
667 678
668fn make_substs(generics: &GenericParams) -> Substs { 679fn make_substs(generics: &GenericParams) -> Substs {
669 Substs(generics.params.iter().map(|_p| Ty::Unknown).collect::<Vec<_>>().into()) 680 Substs(
681 (0..generics.count_params_including_parent())
682 .map(|_p| Ty::Unknown)
683 .collect::<Vec<_>>()
684 .into(),
685 )
670} 686}
671 687
672fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty { 688fn type_for_struct(db: &impl HirDatabase, s: Struct) -> Ty {
@@ -1362,15 +1378,34 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1362 } 1378 }
1363 ret_ty 1379 ret_ty
1364 } 1380 }
1365 Expr::MethodCall { receiver, args, method_name } => { 1381 Expr::MethodCall { receiver, args, method_name, generic_args } => {
1366 let receiver_ty = self.infer_expr(*receiver, &Expectation::none()); 1382 let receiver_ty = self.infer_expr(*receiver, &Expectation::none());
1367 let resolved = receiver_ty.clone().lookup_method(self.db, method_name); 1383 let resolved = receiver_ty.clone().lookup_method(self.db, method_name);
1368 let method_ty = match resolved { 1384 let (derefed_receiver_ty, method_ty, def_generics) = match resolved {
1369 Some(func) => { 1385 Some((ty, func)) => {
1370 self.write_method_resolution(tgt_expr, func); 1386 self.write_method_resolution(tgt_expr, func);
1371 self.db.type_for_def(func.into()) 1387 (ty, self.db.type_for_def(func.into()), Some(func.generic_params(self.db)))
1388 }
1389 None => (Ty::Unknown, receiver_ty, None),
1390 };
1391 // handle provided type arguments
1392 let method_ty = if let Some(generic_args) = generic_args {
1393 // if args are provided, it should be all of them, but we can't rely on that
1394 let param_count = def_generics.map(|g| g.params.len()).unwrap_or(0);
1395 let mut new_substs = Vec::with_capacity(generic_args.args.len());
1396 for arg in generic_args.args.iter().take(param_count) {
1397 match arg {
1398 GenericArg::Type(type_ref) => {
1399 let ty = self.make_ty(type_ref);
1400 new_substs.push(ty);
1401 }
1402 }
1372 } 1403 }
1373 None => Ty::Unknown, 1404 let substs = method_ty.substs().unwrap_or_else(Substs::empty);
1405 let substs = substs.replace_tail(new_substs);
1406 method_ty.apply_substs(substs)
1407 } else {
1408 method_ty
1374 }; 1409 };
1375 let method_ty = self.insert_type_vars(method_ty); 1410 let method_ty = self.insert_type_vars(method_ty);
1376 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty { 1411 let (expected_receiver_ty, param_tys, ret_ty) = match &method_ty {
@@ -1394,9 +1429,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1394 } 1429 }
1395 _ => (Ty::Unknown, Vec::new(), Ty::Unknown), 1430 _ => (Ty::Unknown, Vec::new(), Ty::Unknown),
1396 }; 1431 };
1397 // TODO we would have to apply the autoderef/autoref steps here 1432 // Apply autoref so the below unification works correctly
1398 // to get the correct receiver type to unify... 1433 let actual_receiver_ty = match expected_receiver_ty {
1399 self.unify(&expected_receiver_ty, &receiver_ty); 1434 Ty::Ref(_, mutability) => Ty::Ref(Arc::new(derefed_receiver_ty), mutability),
1435 _ => derefed_receiver_ty,
1436 };
1437 self.unify(&expected_receiver_ty, &actual_receiver_ty);
1438
1400 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown)); 1439 let param_iter = param_tys.into_iter().chain(repeat(Ty::Unknown));
1401 for (arg, param) in args.iter().zip(param_iter) { 1440 for (arg, param) in args.iter().zip(param_iter) {
1402 self.infer_expr(*arg, &Expectation::has_type(param)); 1441 self.infer_expr(*arg, &Expectation::has_type(param));