aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-12-07 12:05:05 +0000
committerAleksey Kladov <[email protected]>2019-12-07 12:13:00 +0000
commitd6c2b92409902d9ceca8cd064026cfcc1f357cf6 (patch)
tree8ce9fd29435ef3bf1fe568fd889c3f1ab8307ea6 /crates/ra_hir_ty/src
parent8e9837df21942ca12a5aece0a868ea46eb405742 (diff)
Refactor parameter count tracking
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs2
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs18
-rw-r--r--crates/ra_hir_ty/src/lib.rs10
-rw-r--r--crates/ra_hir_ty/src/lower.rs13
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs2
-rw-r--r--crates/ra_hir_ty/src/utils.rs17
6 files changed, 30 insertions, 32 deletions
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs
index a6db7f623..d557962b4 100644
--- a/crates/ra_hir_ty/src/autoderef.rs
+++ b/crates/ra_hir_ty/src/autoderef.rs
@@ -55,7 +55,7 @@ fn deref_by_trait(
55 let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; 55 let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?;
56 56
57 let generic_params = generics(db, target.into()); 57 let generic_params = generics(db, target.into());
58 if generic_params.count_params_including_parent() != 1 { 58 if generic_params.len() != 1 {
59 // the Target type + Deref trait should only have one generic parameter, 59 // the Target type + Deref trait should only have one generic parameter,
60 // namely Deref's Self type 60 // namely Deref's Self type
61 return None; 61 return None;
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index e52040eb5..2c296987c 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -660,10 +660,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
660 generic_args: Option<&GenericArgs>, 660 generic_args: Option<&GenericArgs>,
661 receiver_ty: &Ty, 661 receiver_ty: &Ty,
662 ) -> Substs { 662 ) -> Substs {
663 let (parent_param_count, param_count) = def_generics 663 let (total_len, _parent_len, child_len) =
664 .as_ref() 664 def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split());
665 .map_or((0, 0), |g| (g.count_parent_params(), g.params.params.len())); 665 let mut substs = Vec::with_capacity(total_len);
666 let mut substs = Vec::with_capacity(parent_param_count + param_count);
667 // Parent arguments are unknown, except for the receiver type 666 // Parent arguments are unknown, except for the receiver type
668 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { 667 if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) {
669 for (_id, param) in parent_generics { 668 for (_id, param) in parent_generics {
@@ -677,7 +676,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
677 // handle provided type arguments 676 // handle provided type arguments
678 if let Some(generic_args) = generic_args { 677 if let Some(generic_args) = generic_args {
679 // if args are provided, it should be all of them, but we can't rely on that 678 // if args are provided, it should be all of them, but we can't rely on that
680 for arg in generic_args.args.iter().take(param_count) { 679 for arg in generic_args.args.iter().take(child_len) {
681 match arg { 680 match arg {
682 GenericArg::Type(type_ref) => { 681 GenericArg::Type(type_ref) => {
683 let ty = self.make_ty(type_ref); 682 let ty = self.make_ty(type_ref);
@@ -687,10 +686,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
687 } 686 }
688 }; 687 };
689 let supplied_params = substs.len(); 688 let supplied_params = substs.len();
690 for _ in supplied_params..parent_param_count + param_count { 689 for _ in supplied_params..total_len {
691 substs.push(Ty::Unknown); 690 substs.push(Ty::Unknown);
692 } 691 }
693 assert_eq!(substs.len(), parent_param_count + param_count); 692 assert_eq!(substs.len(), total_len);
694 Substs(substs.into()) 693 Substs(substs.into())
695 } 694 }
696 695
@@ -709,9 +708,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
709 CallableDef::FunctionId(f) => { 708 CallableDef::FunctionId(f) => {
710 if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { 709 if let ContainerId::TraitId(trait_) = f.lookup(self.db).container {
711 // construct a TraitDef 710 // construct a TraitDef
712 let substs = a_ty.parameters.prefix( 711 let substs =
713 generics(self.db, trait_.into()).count_params_including_parent(), 712 a_ty.parameters.prefix(generics(self.db, trait_.into()).len());
714 );
715 self.obligations.push(Obligation::Trait(TraitRef { 713 self.obligations.push(Obligation::Trait(TraitRef {
716 trait_: trait_.into(), 714 trait_: trait_.into(),
717 substs, 715 substs,
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 99fd7158e..036d3a589 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -167,15 +167,15 @@ impl TypeCtor {
167 => 1, 167 => 1,
168 TypeCtor::Adt(adt) => { 168 TypeCtor::Adt(adt) => {
169 let generic_params = generics(db, AdtId::from(adt).into()); 169 let generic_params = generics(db, AdtId::from(adt).into());
170 generic_params.count_params_including_parent() 170 generic_params.len()
171 } 171 }
172 TypeCtor::FnDef(callable) => { 172 TypeCtor::FnDef(callable) => {
173 let generic_params = generics(db, callable.into()); 173 let generic_params = generics(db, callable.into());
174 generic_params.count_params_including_parent() 174 generic_params.len()
175 } 175 }
176 TypeCtor::AssociatedType(type_alias) => { 176 TypeCtor::AssociatedType(type_alias) => {
177 let generic_params = generics(db, type_alias.into()); 177 let generic_params = generics(db, type_alias.into());
178 generic_params.count_params_including_parent() 178 generic_params.len()
179 } 179 }
180 TypeCtor::FnPtr { num_args } => num_args as usize + 1, 180 TypeCtor::FnPtr { num_args } => num_args as usize + 1,
181 TypeCtor::Tuple { cardinality } => cardinality as usize, 181 TypeCtor::Tuple { cardinality } => cardinality as usize,
@@ -378,12 +378,12 @@ impl Substs {
378 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder { 378 pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
379 let def = def.into(); 379 let def = def.into();
380 let params = generics(db, def); 380 let params = generics(db, def);
381 let param_count = params.count_params_including_parent(); 381 let param_count = params.len();
382 Substs::builder(param_count) 382 Substs::builder(param_count)
383 } 383 }
384 384
385 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder { 385 pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder {
386 Substs::builder(generic_params.count_params_including_parent()) 386 Substs::builder(generic_params.len())
387 } 387 }
388 388
389 pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder { 389 pub fn build_for_type_ctor(db: &impl HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index d31f6a2d2..eab91229e 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -321,9 +321,8 @@ pub(super) fn substs_from_path_segment(
321 let mut substs = Vec::new(); 321 let mut substs = Vec::new();
322 let def_generics = def_generic.map(|def| generics(db, def.into())); 322 let def_generics = def_generic.map(|def| generics(db, def.into()));
323 323
324 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());
325 def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.params.len())); 325 substs.extend(iter::repeat(Ty::Unknown).take(parent_len));
326 substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count));
327 if add_self_param { 326 if add_self_param {
328 // 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
329 // 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
@@ -334,8 +333,8 @@ pub(super) fn substs_from_path_segment(
334 if let Some(generic_args) = &segment.args_and_bindings { 333 if let Some(generic_args) = &segment.args_and_bindings {
335 // 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
336 let self_param_correction = if add_self_param { 1 } else { 0 }; 335 let self_param_correction = if add_self_param { 1 } else { 0 };
337 let param_count = param_count - self_param_correction; 336 let child_len = child_len + self_param_correction;
338 for arg in generic_args.args.iter().take(param_count) { 337 for arg in generic_args.args.iter().take(child_len) {
339 match arg { 338 match arg {
340 GenericArg::Type(type_ref) => { 339 GenericArg::Type(type_ref) => {
341 let ty = Ty::from_hir(db, resolver, type_ref); 340 let ty = Ty::from_hir(db, resolver, type_ref);
@@ -346,10 +345,10 @@ pub(super) fn substs_from_path_segment(
346 } 345 }
347 // add placeholders for args that were not provided 346 // add placeholders for args that were not provided
348 let supplied_params = substs.len(); 347 let supplied_params = substs.len();
349 for _ in supplied_params..parent_param_count + param_count { 348 for _ in supplied_params..total_len {
350 substs.push(Ty::Unknown); 349 substs.push(Ty::Unknown);
351 } 350 }
352 assert_eq!(substs.len(), parent_param_count + param_count); 351 assert_eq!(substs.len(), total_len);
353 352
354 // handle defaults 353 // handle defaults
355 if let Some(def_generic) = def_generic { 354 if let Some(def_generic) = def_generic {
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 1d44320b9..1e7ff93d5 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -557,7 +557,7 @@ pub(crate) fn associated_ty_data_query(
557 trait_id: trait_.to_chalk(db), 557 trait_id: trait_.to_chalk(db),
558 id, 558 id,
559 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), 559 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()),
560 binders: make_binders(bound_data, generic_params.count_params_including_parent()), 560 binders: make_binders(bound_data, generic_params.len()),
561 }; 561 };
562 Arc::new(datum) 562 Arc::new(datum)
563} 563}
diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs
index 2c458867f..936cfe25e 100644
--- a/crates/ra_hir_ty/src/utils.rs
+++ b/crates/ra_hir_ty/src/utils.rs
@@ -117,13 +117,14 @@ impl Generics {
117 .map(|(i, (_local_id, p))| (i as u32, p)) 117 .map(|(i, (_local_id, p))| (i as u32, p))
118 } 118 }
119 119
120 pub(crate) fn count_parent_params(&self) -> usize { 120 pub(crate) fn len(&self) -> usize {
121 self.parent_generics.as_ref().map_or(0, |p| p.count_params_including_parent()) 121 self.len_split().0
122 } 122 }
123 123 /// (total, parents, child)
124 pub(crate) fn count_params_including_parent(&self) -> usize { 124 pub(crate) fn len_split(&self) -> (usize, usize, usize) {
125 let parent_count = self.count_parent_params(); 125 let parent = self.parent_generics.as_ref().map_or(0, |p| p.len());
126 parent_count + self.params.params.len() 126 let child = self.params.params.len();
127 (parent + child, parent, child)
127 } 128 }
128 pub(crate) fn param_idx(&self, param: GenericParamId) -> u32 { 129 pub(crate) fn param_idx(&self, param: GenericParamId) -> u32 {
129 self.find_param(param).0 130 self.find_param(param).0
@@ -140,8 +141,8 @@ impl Generics {
140 .enumerate() 141 .enumerate()
141 .find(|(_, (idx, _))| *idx == param.local_id) 142 .find(|(_, (idx, _))| *idx == param.local_id)
142 .unwrap(); 143 .unwrap();
143 144 let (_total, parent_len, _child) = self.len_split();
144 return ((self.count_parent_params() + idx) as u32, data); 145 return ((parent_len + idx) as u32, data);
145 } 146 }
146 self.parent_generics.as_ref().unwrap().find_param(param) 147 self.parent_generics.as_ref().unwrap().find_param(param)
147 } 148 }