diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs index a6db7f623bc..d557962b4fe 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( let target = db.trait_data(deref_trait).associated_type_by_name(&name::TARGET_TYPE)?; let generic_params = generics(db, target.into()); - if generic_params.count_params_including_parent() != 1 { + if generic_params.len() != 1 { // the Target type + Deref trait should only have one generic parameter, // namely Deref's Self type return None; diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index e52040eb5b8..2c296987c8a 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> { generic_args: Option<&GenericArgs>, receiver_ty: &Ty, ) -> Substs { - let (parent_param_count, param_count) = def_generics - .as_ref() - .map_or((0, 0), |g| (g.count_parent_params(), g.params.params.len())); - let mut substs = Vec::with_capacity(parent_param_count + param_count); + let (total_len, _parent_len, child_len) = + def_generics.as_ref().map_or((0, 0, 0), |g| g.len_split()); + let mut substs = Vec::with_capacity(total_len); // Parent arguments are unknown, except for the receiver type if let Some(parent_generics) = def_generics.as_ref().map(|p| p.iter_parent()) { for (_id, param) in parent_generics { @@ -677,7 +676,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // handle provided type arguments if let Some(generic_args) = generic_args { // if args are provided, it should be all of them, but we can't rely on that - for arg in generic_args.args.iter().take(param_count) { + for arg in generic_args.args.iter().take(child_len) { match arg { GenericArg::Type(type_ref) => { let ty = self.make_ty(type_ref); @@ -687,10 +686,10 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } }; let supplied_params = substs.len(); - for _ in supplied_params..parent_param_count + param_count { + for _ in supplied_params..total_len { substs.push(Ty::Unknown); } - assert_eq!(substs.len(), parent_param_count + param_count); + assert_eq!(substs.len(), total_len); Substs(substs.into()) } @@ -709,9 +708,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { CallableDef::FunctionId(f) => { if let ContainerId::TraitId(trait_) = f.lookup(self.db).container { // construct a TraitDef - let substs = a_ty.parameters.prefix( - generics(self.db, trait_.into()).count_params_including_parent(), - ); + let substs = + a_ty.parameters.prefix(generics(self.db, trait_.into()).len()); self.obligations.push(Obligation::Trait(TraitRef { trait_: trait_.into(), substs, diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 99fd7158ee8..036d3a589a8 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -167,15 +167,15 @@ impl TypeCtor { => 1, TypeCtor::Adt(adt) => { let generic_params = generics(db, AdtId::from(adt).into()); - generic_params.count_params_including_parent() + generic_params.len() } TypeCtor::FnDef(callable) => { let generic_params = generics(db, callable.into()); - generic_params.count_params_including_parent() + generic_params.len() } TypeCtor::AssociatedType(type_alias) => { let generic_params = generics(db, type_alias.into()); - generic_params.count_params_including_parent() + generic_params.len() } TypeCtor::FnPtr { num_args } => num_args as usize + 1, TypeCtor::Tuple { cardinality } => cardinality as usize, @@ -378,12 +378,12 @@ impl Substs { pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { let def = def.into(); let params = generics(db, def); - let param_count = params.count_params_including_parent(); + let param_count = params.len(); Substs::builder(param_count) } pub(crate) fn build_for_generics(generic_params: &Generics) -> SubstsBuilder { - Substs::builder(generic_params.count_params_including_parent()) + Substs::builder(generic_params.len()) } 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 d31f6a2d295..eab91229e3e 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( let mut substs = Vec::new(); let def_generics = def_generic.map(|def| generics(db, def.into())); - let (parent_param_count, param_count) = - def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.params.len())); - substs.extend(iter::repeat(Ty::Unknown).take(parent_param_count)); + let (total_len, parent_len, child_len) = def_generics.map_or((0, 0, 0), |g| g.len_split()); + substs.extend(iter::repeat(Ty::Unknown).take(parent_len)); if add_self_param { // FIXME this add_self_param argument is kind of a hack: Traits have the // Self type as an implicit first type parameter, but it can't be @@ -334,8 +333,8 @@ pub(super) fn substs_from_path_segment( if let Some(generic_args) = &segment.args_and_bindings { // if args are provided, it should be all of them, but we can't rely on that let self_param_correction = if add_self_param { 1 } else { 0 }; - let param_count = param_count - self_param_correction; - for arg in generic_args.args.iter().take(param_count) { + let child_len = child_len + self_param_correction; + for arg in generic_args.args.iter().take(child_len) { match arg { GenericArg::Type(type_ref) => { let ty = Ty::from_hir(db, resolver, type_ref); @@ -346,10 +345,10 @@ pub(super) fn substs_from_path_segment( } // add placeholders for args that were not provided let supplied_params = substs.len(); - for _ in supplied_params..parent_param_count + param_count { + for _ in supplied_params..total_len { substs.push(Ty::Unknown); } - assert_eq!(substs.len(), parent_param_count + param_count); + assert_eq!(substs.len(), total_len); // handle defaults 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 1d44320b944..1e7ff93d596 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( trait_id: trait_.to_chalk(db), id, name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), - binders: make_binders(bound_data, generic_params.count_params_including_parent()), + binders: make_binders(bound_data, generic_params.len()), }; Arc::new(datum) } diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 2c458867ffb..936cfe25e08 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -117,13 +117,14 @@ impl Generics { .map(|(i, (_local_id, p))| (i as u32, p)) } - pub(crate) fn count_parent_params(&self) -> usize { - self.parent_generics.as_ref().map_or(0, |p| p.count_params_including_parent()) + pub(crate) fn len(&self) -> usize { + self.len_split().0 } - - pub(crate) fn count_params_including_parent(&self) -> usize { - let parent_count = self.count_parent_params(); - parent_count + self.params.params.len() + /// (total, parents, child) + pub(crate) fn len_split(&self) -> (usize, usize, usize) { + let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); + let child = self.params.params.len(); + (parent + child, parent, child) } pub(crate) fn param_idx(&self, param: GenericParamId) -> u32 { self.find_param(param).0 @@ -140,8 +141,8 @@ impl Generics { .enumerate() .find(|(_, (idx, _))| *idx == param.local_id) .unwrap(); - - return ((self.count_parent_params() + idx) as u32, data); + let (_total, parent_len, _child) = self.len_split(); + return ((parent_len + idx) as u32, data); } self.parent_generics.as_ref().unwrap().find_param(param) }