diff options
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 32569ac66..eab91229e 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs | |||
@@ -24,7 +24,7 @@ use crate::{ | |||
24 | db::HirDatabase, | 24 | db::HirDatabase, |
25 | primitive::{FloatTy, IntTy}, | 25 | primitive::{FloatTy, IntTy}, |
26 | utils::{ | 26 | utils::{ |
27 | all_super_traits, associated_type_by_name_including_super_traits, make_mut_slice, | 27 | all_super_traits, associated_type_by_name_including_super_traits, generics, make_mut_slice, |
28 | variant_data, | 28 | variant_data, |
29 | }, | 29 | }, |
30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, | 30 | FnSig, GenericPredicate, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, |
@@ -111,7 +111,9 @@ impl Ty { | |||
111 | Some((it, None)) => it, | 111 | Some((it, None)) => it, |
112 | _ => return None, | 112 | _ => return None, |
113 | }; | 113 | }; |
114 | if let TypeNs::GenericParam(idx) = resolution { | 114 | if let TypeNs::GenericParam(param_id) = resolution { |
115 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | ||
116 | let idx = generics.param_idx(param_id); | ||
115 | Some(idx) | 117 | Some(idx) |
116 | } else { | 118 | } else { |
117 | None | 119 | None |
@@ -174,9 +176,11 @@ impl Ty { | |||
174 | Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) | 176 | Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) |
175 | }; | 177 | }; |
176 | } | 178 | } |
177 | TypeNs::GenericParam(idx) => { | 179 | TypeNs::GenericParam(param_id) => { |
180 | let generics = generics(db, resolver.generic_def().expect("generics in scope")); | ||
181 | let idx = generics.param_idx(param_id); | ||
178 | // FIXME: maybe return name in resolution? | 182 | // FIXME: maybe return name in resolution? |
179 | let name = resolved_segment.name.clone(); | 183 | let name = generics.param_name(param_id); |
180 | Ty::Param { idx, name } | 184 | Ty::Param { idx, name } |
181 | } | 185 | } |
182 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), | 186 | TypeNs::SelfType(impl_id) => db.impl_self_ty(impl_id).clone(), |
@@ -315,11 +319,10 @@ pub(super) fn substs_from_path_segment( | |||
315 | add_self_param: bool, | 319 | add_self_param: bool, |
316 | ) -> Substs { | 320 | ) -> Substs { |
317 | let mut substs = Vec::new(); | 321 | let mut substs = Vec::new(); |
318 | let def_generics = def_generic.map(|def| db.generic_params(def.into())); | 322 | let def_generics = def_generic.map(|def| generics(db, def.into())); |
319 | 323 | ||
320 | let (parent_param_count, param_count) = | 324 | let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); |
321 | def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); | 325 | substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); |
322 | substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count)); | ||
323 | if add_self_param { | 326 | if add_self_param { |
324 | // FIXME this add_self_param argument is kind of a hack: Traits have the | 327 | // FIXME this add_self_param argument is kind of a hack: Traits have the |
325 | // Self type as an implicit first type parameter, but it can't be | 328 | // Self type as an implicit first type parameter, but it can't be |
@@ -330,8 +333,8 @@ pub(super) fn substs_from_path_segment( | |||
330 | if let Some(generic_args) = &segment.args_and_bindings { | 333 | if let Some(generic_args) = &segment.args_and_bindings { |
331 | // if args are provided, it should be all of them, but we can't rely on that | 334 | // if args are provided, it should be all of them, but we can't rely on that |
332 | let self_param_correction = if add_self_param { 1 } else { 0 }; | 335 | let self_param_correction = if add_self_param { 1 } else { 0 }; |
333 | let param_count = param_count - self_param_correction; | 336 | let child_len = child_len + self_param_correction; |
334 | for arg in generic_args.args.iter().take(param_count) { | 337 | for arg in generic_args.args.iter().take(child_len) { |
335 | match arg { | 338 | match arg { |
336 | GenericArg::Type(type_ref) => { | 339 | GenericArg::Type(type_ref) => { |
337 | let ty = Ty::from_hir(db, resolver, type_ref); | 340 | let ty = Ty::from_hir(db, resolver, type_ref); |
@@ -342,10 +345,10 @@ pub(super) fn substs_from_path_segment( | |||
342 | } | 345 | } |
343 | // add placeholders for args that were not provided | 346 | // add placeholders for args that were not provided |
344 | let supplied_params = substs.len(); | 347 | let supplied_params = substs.len(); |
345 | for _ in supplied_params..parent_param_count + param_count { | 348 | for _ in supplied_params..total_len { |
346 | substs.push(Ty::Unknown); | 349 | substs.push(Ty::Unknown); |
347 | } | 350 | } |
348 | assert_eq!(substs.len(), parent_param_count + param_count); | 351 | assert_eq!(substs.len(), total_len); |
349 | 352 | ||
350 | // handle defaults | 353 | // handle defaults |
351 | if let Some(def_generic) = def_generic { | 354 | if let Some(def_generic) = def_generic { |
@@ -567,12 +570,11 @@ pub(crate) fn generic_predicates_query( | |||
567 | /// Resolve the default type params from generics | 570 | /// Resolve the default type params from generics |
568 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { | 571 | pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDefId) -> Substs { |
569 | let resolver = def.resolver(db); | 572 | let resolver = def.resolver(db); |
570 | let generic_params = db.generic_params(def.into()); | 573 | let generic_params = generics(db, def.into()); |
571 | 574 | ||
572 | let defaults = generic_params | 575 | let defaults = generic_params |
573 | .params_including_parent() | 576 | .iter() |
574 | .into_iter() | 577 | .map(|(_idx, p)| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) |
575 | .map(|p| p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(db, &resolver, t))) | ||
576 | .collect(); | 578 | .collect(); |
577 | 579 | ||
578 | Substs(defaults) | 580 | Substs(defaults) |
@@ -589,7 +591,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: FunctionId) -> FnSig { | |||
589 | /// Build the declared type of a function. This should not need to look at the | 591 | /// Build the declared type of a function. This should not need to look at the |
590 | /// function body. | 592 | /// function body. |
591 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { | 593 | fn type_for_fn(db: &impl HirDatabase, def: FunctionId) -> Ty { |
592 | let generics = db.generic_params(def.into()); | 594 | let generics = generics(db, def.into()); |
593 | let substs = Substs::identity(&generics); | 595 | let substs = Substs::identity(&generics); |
594 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 596 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
595 | } | 597 | } |
@@ -639,7 +641,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> Ty { | |||
639 | if struct_data.variant_data.is_unit() { | 641 | if struct_data.variant_data.is_unit() { |
640 | return type_for_adt(db, def.into()); // Unit struct | 642 | return type_for_adt(db, def.into()); // Unit struct |
641 | } | 643 | } |
642 | let generics = db.generic_params(def.into()); | 644 | let generics = generics(db, def.into()); |
643 | let substs = Substs::identity(&generics); | 645 | let substs = Substs::identity(&generics); |
644 | Ty::apply(TypeCtor::FnDef(def.into()), substs) | 646 | Ty::apply(TypeCtor::FnDef(def.into()), substs) |
645 | } | 647 | } |
@@ -653,7 +655,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId | |||
653 | .iter() | 655 | .iter() |
654 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) | 656 | .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) |
655 | .collect::<Vec<_>>(); | 657 | .collect::<Vec<_>>(); |
656 | let generics = db.generic_params(def.parent.into()); | 658 | let generics = generics(db, def.parent.into()); |
657 | let substs = Substs::identity(&generics); | 659 | let substs = Substs::identity(&generics); |
658 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); | 660 | let ret = type_for_adt(db, def.parent.into()).subst(&substs); |
659 | FnSig::from_params_and_return(params, ret) | 661 | FnSig::from_params_and_return(params, ret) |
@@ -666,18 +668,18 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariantId) | |||
666 | if var_data.is_unit() { | 668 | if var_data.is_unit() { |
667 | return type_for_adt(db, def.parent.into()); // Unit variant | 669 | return type_for_adt(db, def.parent.into()); // Unit variant |
668 | } | 670 | } |
669 | let generics = db.generic_params(def.parent.into()); | 671 | let generics = generics(db, def.parent.into()); |
670 | let substs = Substs::identity(&generics); | 672 | let substs = Substs::identity(&generics); |
671 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) | 673 | Ty::apply(TypeCtor::FnDef(EnumVariantId::from(def).into()), substs) |
672 | } | 674 | } |
673 | 675 | ||
674 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { | 676 | fn type_for_adt(db: &impl HirDatabase, adt: AdtId) -> Ty { |
675 | let generics = db.generic_params(adt.into()); | 677 | let generics = generics(db, adt.into()); |
676 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) | 678 | Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) |
677 | } | 679 | } |
678 | 680 | ||
679 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { | 681 | fn type_for_type_alias(db: &impl HirDatabase, t: TypeAliasId) -> Ty { |
680 | let generics = db.generic_params(t.into()); | 682 | let generics = generics(db, t.into()); |
681 | let resolver = t.resolver(db); | 683 | let resolver = t.resolver(db); |
682 | let type_ref = &db.type_alias_data(t).type_ref; | 684 | let type_ref = &db.type_alias_data(t).type_ref; |
683 | let substs = Substs::identity(&generics); | 685 | let substs = Substs::identity(&generics); |