diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index b7ea42236ee..8f80f3a5db6 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs @@ -293,7 +293,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H let params = f.db.generic_params(def); if params.lifetimes.is_empty() && params - .types + .tocs .iter() .filter_map(|x| x.1.type_param()) .all(|param| !matches!(param.provenance, TypeParamProvenance::TypeParamList)) @@ -315,7 +315,7 @@ fn write_generic_params(def: GenericDefId, f: &mut HirFormatter) -> Result<(), H delim(f)?; write!(f, "{}", lifetime.name)?; } - for (_, ty) in params.types.iter() { + for (_, ty) in params.tocs.iter() { if let Some(name) = &ty.name() { match ty { TypeOrConstParamData::TypeParamData(ty) => { @@ -348,7 +348,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir // unnamed type targets are displayed inline with the argument itself, e.g. `f: impl Y`. let is_unnamed_type_target = |target: &WherePredicateTypeTarget| match target { WherePredicateTypeTarget::TypeRef(_) => false, - WherePredicateTypeTarget::TypeOrConstParam(id) => params.types[*id].name().is_none(), + WherePredicateTypeTarget::TypeOrConstParam(id) => params.tocs[*id].name().is_none(), }; let has_displayable_predicate = params @@ -364,7 +364,7 @@ fn write_where_clause(def: GenericDefId, f: &mut HirFormatter) -> Result<(), Hir let write_target = |target: &WherePredicateTypeTarget, f: &mut HirFormatter| match target { WherePredicateTypeTarget::TypeRef(ty) => ty.hir_fmt(f), - WherePredicateTypeTarget::TypeOrConstParam(id) => match ¶ms.types[*id].name() { + WherePredicateTypeTarget::TypeOrConstParam(id) => match ¶ms.tocs[*id].name() { Some(name) => write!(f, "{}", name), None => write!(f, "{{unnamed}}"), }, diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index d38c91ac437..0aabb415d46 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2029,7 +2029,7 @@ pub enum GenericDef { impl GenericDef { pub fn params(self, db: &dyn HirDatabase) -> Vec { let generics = db.generic_params(self.into()); - let ty_params = generics.types.iter().map(|(local_id, _)| { + let ty_params = generics.tocs.iter().map(|(local_id, _)| { let toc = TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id } }; match toc.split(db) { Either::Left(x) => GenericParam::ConstParam(x), @@ -2049,7 +2049,7 @@ pub fn params(self, db: &dyn HirDatabase) -> Vec { pub fn type_params(self, db: &dyn HirDatabase) -> Vec { let generics = db.generic_params(self.into()); generics - .types + .tocs .iter() .map(|(local_id, _)| TypeOrConstParam { id: TypeOrConstParamId { parent: self.into(), local_id }, @@ -2371,7 +2371,7 @@ pub fn merge(self) -> TypeOrConstParam { pub fn name(self, db: &dyn HirDatabase) -> Name { let params = db.generic_params(self.id.parent()); - match params.types[self.id.local_id()].name() { + match params.tocs[self.id.local_id()].name() { Some(x) => x.clone(), None => { never!(); @@ -2403,7 +2403,7 @@ pub struct TypeOrConstParam { impl TypeOrConstParam { pub fn name(self, db: &dyn HirDatabase) -> Name { let params = db.generic_params(self.id.parent); - match params.types[self.id.local_id].name() { + match params.tocs[self.id.local_id].name() { Some(n) => n.clone(), _ => Name::missing(), } @@ -2419,7 +2419,7 @@ pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { pub fn split(self, db: &dyn HirDatabase) -> Either { let params = db.generic_params(self.id.parent); - match ¶ms.types[self.id.local_id] { + match ¶ms.tocs[self.id.local_id] { hir_def::generics::TypeOrConstParamData::TypeParamData(_) => { Either::Right(TypeParam { id: self.id.into() }) } diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index b5a11a1ba55..60d79f1473e 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs @@ -77,6 +77,13 @@ pub fn type_param(&self) -> Option<&TypeParamData> { } } + pub fn const_param(&self) -> Option<&ConstParamData> { + match self { + TypeOrConstParamData::TypeParamData(_) => None, + TypeOrConstParamData::ConstParamData(x) => Some(x), + } + } + pub fn is_trait_self(&self) -> bool { match self { TypeOrConstParamData::TypeParamData(x) => { @@ -92,7 +99,7 @@ pub fn is_trait_self(&self) -> bool { /// Data about the generic parameters of a function, struct, impl, etc. #[derive(Clone, PartialEq, Eq, Debug, Default, Hash)] pub struct GenericParams { - pub types: Arena, + pub tocs: Arena, pub lifetimes: Arena, pub where_predicates: Vec, } @@ -131,7 +138,13 @@ impl GenericParams { pub fn type_iter<'a>( &'a self, ) -> impl Iterator, &TypeParamData)> { - self.types.iter().filter_map(|x| x.1.type_param().map(|y| (x.0, y))) + self.tocs.iter().filter_map(|x| x.1.type_param().map(|y| (x.0, y))) + } + + pub fn toc_iter<'a>( + &'a self, + ) -> impl Iterator, &TypeOrConstParamData)> { + self.tocs.iter() } pub(crate) fn generic_params_query( @@ -238,7 +251,7 @@ fn fill_params(&mut self, lower_ctx: &LowerCtx, params: ast::GenericParamList) { default, provenance: TypeParamProvenance::TypeParamList, }; - self.types.alloc(param.into()); + self.tocs.alloc(param.into()); let type_ref = TypeRef::Path(name.into()); self.fill_bounds(lower_ctx, &type_param, Either::Left(type_ref)); } @@ -248,7 +261,7 @@ fn fill_params(&mut self, lower_ctx: &LowerCtx, params: ast::GenericParamList) { .ty() .map_or(TypeRef::Error, |it| TypeRef::from_ast(lower_ctx, it)); let param = ConstParamData { name, ty: Interned::new(ty) }; - self.types.alloc(param.into()); + self.tocs.alloc(param.into()); } } } @@ -335,7 +348,7 @@ pub(crate) fn fill_implicit_impl_trait_args( default: None, provenance: TypeParamProvenance::ArgumentImplTrait, }; - let param_id = self.types.alloc(param.into()); + let param_id = self.tocs.alloc(param.into()); for bound in bounds { self.where_predicates.push(WherePredicate::TypeBound { target: WherePredicateTypeTarget::TypeOrConstParam(param_id), @@ -359,27 +372,27 @@ pub(crate) fn fill_implicit_impl_trait_args( } pub(crate) fn shrink_to_fit(&mut self) { - let Self { lifetimes, types, where_predicates } = self; + let Self { lifetimes, tocs: types, where_predicates } = self; lifetimes.shrink_to_fit(); types.shrink_to_fit(); where_predicates.shrink_to_fit(); } pub fn find_type_by_name(&self, name: &Name) -> Option { - self.types + self.tocs .iter() .filter(|x| matches!(x.1, TypeOrConstParamData::TypeParamData(_))) .find_map(|(id, p)| if p.name().as_ref() == Some(&name) { Some(id) } else { None }) } pub fn find_type_or_const_by_name(&self, name: &Name) -> Option { - self.types + self.tocs .iter() .find_map(|(id, p)| if p.name().as_ref() == Some(&name) { Some(id) } else { None }) } pub fn find_trait_self_param(&self) -> Option { - self.types.iter().find_map(|(id, p)| { + self.tocs.iter().find_map(|(id, p)| { if let TypeOrConstParamData::TypeParamData(p) = p { if p.provenance == TypeParamProvenance::TraitSelf { Some(id) @@ -438,7 +451,7 @@ fn child_source( db: &dyn DefDatabase, ) -> InFile> { let generic_params = db.generic_params(*self); - let mut idx_iter = generic_params.types.iter().map(|(idx, _)| idx); + let mut idx_iter = generic_params.tocs.iter().map(|(idx, _)| idx); let (file_id, generic_params_list) = file_id_and_params_of(*self, db); @@ -492,7 +505,7 @@ fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: Hi } let generic_params = db.generic_params(*self); - let mut toc_idx_iter = generic_params.types.iter().map(|(idx, _)| idx); + let mut toc_idx_iter = generic_params.tocs.iter().map(|(idx, _)| idx); let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx); // For traits the first type index is `Self`, skip it. diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index d215ce101f0..45b5430a22f 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -582,7 +582,7 @@ fn lower_generic_params( } GenericsOwner::Trait(trait_def) => { // traits get the Self type as an implicit first type parameter - generics.types.alloc( + generics.tocs.alloc( TypeParamData { name: Some(name![Self]), default: None, diff --git a/crates/hir_def/src/item_tree/pretty.rs b/crates/hir_def/src/item_tree/pretty.rs index 5b211a142ab..6fea95a2ac9 100644 --- a/crates/hir_def/src/item_tree/pretty.rs +++ b/crates/hir_def/src/item_tree/pretty.rs @@ -626,7 +626,7 @@ fn print_generic_arg(&mut self, arg: &GenericArg) { } fn print_generic_params(&mut self, params: &GenericParams) { - if params.types.is_empty() && params.lifetimes.is_empty() { + if params.tocs.is_empty() && params.lifetimes.is_empty() { return; } @@ -639,7 +639,7 @@ fn print_generic_params(&mut self, params: &GenericParams) { first = false; w!(self, "{}", lt.name); } - for (idx, x) in params.types.iter() { + for (idx, x) in params.tocs.iter() { if !first { w!(self, ", "); } @@ -701,7 +701,7 @@ fn print_where_clause(&mut self, params: &GenericParams) -> bool { match target { WherePredicateTypeTarget::TypeRef(ty) => this.print_type_ref(ty), WherePredicateTypeTarget::TypeOrConstParam(id) => { - match ¶ms.types[*id].name() { + match ¶ms.tocs[*id].name() { Some(name) => w!(this, "{}", name), None => w!(this, "_anon_{}", id.into_raw()), } diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs index 22f66a0d621..3d47064e4f6 100644 --- a/crates/hir_def/src/resolver.rs +++ b/crates/hir_def/src/resolver.rs @@ -518,10 +518,10 @@ fn process_names(&self, db: &dyn DefDatabase, acc: &mut ScopeNames) { } Scope::GenericParams { params, def: parent } => { let parent = *parent; - for (local_id, param) in params.types.iter() { + for (local_id, param) in params.tocs.iter() { if let Some(name) = ¶m.name() { let id = TypeOrConstParamId { parent, local_id }; - let data = &db.generic_params(parent).types[local_id]; + let data = &db.generic_params(parent).tocs[local_id]; acc.add( name, ScopeDef::GenericParam(match data { diff --git a/crates/hir_ty/src/chalk_ext.rs b/crates/hir_ty/src/chalk_ext.rs index d34257f1184..8758f38bfc9 100644 --- a/crates/hir_ty/src/chalk_ext.rs +++ b/crates/hir_ty/src/chalk_ext.rs @@ -237,7 +237,7 @@ fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option { let id = from_placeholder_idx(db, *idx); let generic_params = db.generic_params(id.parent); - let param_data = &generic_params.types[id.local_id]; + let param_data = &generic_params.tocs[id.local_id]; match param_data { TypeOrConstParamData::TypeParamData(p) => match p.provenance { hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index a2644e74b8d..d81aa348248 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs @@ -320,7 +320,7 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { ConstValue::Placeholder(idx) => { let id = from_placeholder_idx(f.db, idx); let generics = generics(f.db.upcast(), id.parent); - let param_data = &generics.params.types[id.local_id]; + let param_data = &generics.params.tocs[id.local_id]; write!(f, "{}", param_data.name().unwrap()) } ConstValue::Concrete(c) => write!(f, "{}", c.interned), @@ -489,9 +489,9 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { }; if parameters.len(Interner) > 0 { let generics = generics(f.db.upcast(), def.into()); - let (parent_params, self_param, type_params, _impl_trait_params) = + let (parent_params, self_param, type_params, const_params, _impl_trait_params) = generics.provenance_split(); - let total_len = parent_params + self_param + type_params; + let total_len = parent_params + self_param + type_params + const_params; // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? if total_len > 0 { write!(f, "<")?; @@ -680,7 +680,7 @@ fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { TyKind::Placeholder(idx) => { let id = from_placeholder_idx(f.db, *idx); let generics = generics(f.db.upcast(), id.parent); - let param_data = &generics.params.types[id.local_id]; + let param_data = &generics.params.tocs[id.local_id]; match param_data { TypeOrConstParamData::TypeParamData(p) => match p.provenance { TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index c52dd3e8edb..c093f0e4b23 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -1032,10 +1032,10 @@ fn substs_for_method_call( def_generics: Generics, generic_args: Option<&GenericArgs>, ) -> Substitution { - let (parent_params, self_params, type_params, impl_trait_params) = + let (parent_params, self_params, type_params, const_params, impl_trait_params) = def_generics.provenance_split(); assert_eq!(self_params, 0); // method shouldn't have another Self param - let total_len = parent_params + type_params + impl_trait_params; + let total_len = parent_params + type_params + const_params + impl_trait_params; let mut substs = Vec::with_capacity(total_len); // Parent arguments are unknown for (_id, param) in def_generics.iter_parent() { @@ -1044,7 +1044,8 @@ fn substs_for_method_call( substs.push(self.table.new_type_var()); } TypeOrConstParamData::ConstParamData(_) => { - // FIXME: here we should do something + // FIXME: here we should do something else + substs.push(self.table.new_type_var()); } } } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index 3147b6f330b..15f91ce799b 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -286,16 +286,21 @@ pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option) { let idx = self.impl_trait_counter.get(); // FIXME we're probably doing something wrong here self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); - let (parent_params, self_params, list_params, _impl_trait_params) = - if let Some(def) = self.resolver.generic_def() { - let generics = generics(self.db.upcast(), def); - generics.provenance_split() - } else { - (0, 0, 0, 0) - }; + let ( + parent_params, + self_params, + list_params, + const_params, + _impl_trait_params, + ) = if let Some(def) = self.resolver.generic_def() { + let generics = generics(self.db.upcast(), def); + generics.provenance_split() + } else { + (0, 0, 0, 0, 0) + }; TyKind::BoundVar(BoundVar::new( self.in_binders, - idx as usize + parent_params + self_params + list_params, + idx as usize + parent_params + self_params + list_params + const_params, )) .intern(Interner) } @@ -639,9 +644,10 @@ fn substs_from_path_segment( let mut substs = Vec::new(); let def_generics = def_generic.map(|def| generics(self.db.upcast(), def)); - let (parent_params, self_params, type_params, impl_trait_params) = - def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); - let total_len = parent_params + self_params + type_params + impl_trait_params; + let (parent_params, self_params, type_params, const_params, impl_trait_params) = + def_generics.map_or((0, 0, 0, 0, 0), |g| g.provenance_split()); + let total_len = + parent_params + self_params + type_params + const_params + impl_trait_params; substs.extend(iter::repeat(TyKind::Error.intern(Interner)).take(parent_params)); @@ -993,7 +999,7 @@ fn named_associated_type_shorthand_candidates( // Handle `Self::Type` referring to own associated type in trait definitions if let GenericDefId::TraitId(trait_id) = param_id.parent() { let generics = generics(db.upcast(), trait_id.into()); - if generics.params.types[param_id.local_id()].is_trait_self() { + if generics.params.tocs[param_id.local_id()].is_trait_self() { let trait_ref = TyBuilder::trait_ref(db, trait_id) .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) .build(); @@ -1235,9 +1241,17 @@ pub(crate) fn generic_defaults_query( let generic_params = generics(db.upcast(), def); let defaults = generic_params - .type_iter() + .toc_iter() .enumerate() .map(|(idx, (_, p))| { + let p = match p { + TypeOrConstParamData::TypeParamData(p) => p, + TypeOrConstParamData::ConstParamData(_) => { + // FIXME: here we should add const generic parameters + let ty = TyKind::Error.intern(Interner); + return crate::make_only_type_binders(idx, ty); + } + }; let mut ty = p.default.as_ref().map_or(TyKind::Error.intern(Interner), |t| ctx.lower_ty(t)); @@ -1269,7 +1283,7 @@ pub(crate) fn generic_defaults_recover( // we still need one default per parameter let defaults = generic_params - .type_iter() + .toc_iter() .enumerate() .map(|(idx, _)| { let ty = TyKind::Error.intern(Interner); @@ -1502,7 +1516,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde // returns None if def is a type arg pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { let parent_data = db.generic_params(def.parent()); - let data = &parent_data.types[def.local_id()]; + let data = &parent_data.tocs[def.local_id()]; let resolver = def.parent().resolver(db.upcast()); let ctx = TyLoweringContext::new(db, &resolver); match data { diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index b17e517ccb0..020c5da6804 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -1298,3 +1298,71 @@ impl IntoIterator for I { "#, ); } + +#[test] +fn bug_11659() { + check_infer( + r#" +struct LinkArray(LD); +fn f(x: LD) -> LinkArray { + let r = LinkArray::(x); + r +} + +fn test() { + let x = f::<2, i32>(5); + let y = LinkArray::<52, LinkArray<2, i32>>(x); +} + "#, + expect![[r#" + 67..68 'x': LD + 94..138 '{ ... r }': LinkArray<{unknown}, LD> + 104..105 'r': LinkArray<{unknown}, LD> + 108..126 'LinkAr...N, LD>': LinkArray<{unknown}, LD>(LD) -> LinkArray<{unknown}, LD> + 108..129 'LinkAr...LD>(x)': LinkArray<{unknown}, LD> + 127..128 'x': LD + 135..136 'r': LinkArray<{unknown}, LD> + 150..232 '{ ...(x); }': () + 160..161 'x': LinkArray<{unknown}, {unknown}> + 164..175 'f::<2, i32>': fn f(i32) -> LinkArray<{unknown}, {unknown}> + 164..178 'f::<2, i32>(5)': LinkArray<{unknown}, {unknown}> + 176..177 '5': i32 + 188..189 'y': LinkArray, LinkArray<{unknown}, {unknown}>> + 192..226 'LinkAr... i32>>': LinkArray, LinkArray<{unknown}, {unknown}>>(LinkArray<{unknown}, {unknown}>) -> LinkArray, LinkArray<{unknown}, {unknown}>> + 192..229 'LinkAr...2>>(x)': LinkArray, LinkArray<{unknown}, {unknown}>> + 227..228 'x': LinkArray<{unknown}, {unknown}> + "#]], + ); + check_infer( + r#" +struct LinkArray(LD); +fn f(x: LD) -> LinkArray { + let r = LinkArray::(x); + r +} + +fn test() { + let x = f::(5); + let y = LinkArray::, 52>(x); +} + "#, + expect![[r#" + 67..68 'x': LD + 94..138 '{ ... r }': LinkArray + 104..105 'r': LinkArray + 108..126 'LinkAr...LD, N>': LinkArray(LD) -> LinkArray + 108..129 'LinkAr... N>(x)': LinkArray + 127..128 'x': LD + 135..136 'r': LinkArray + 150..232 '{ ...(x); }': () + 160..161 'x': LinkArray + 164..175 'f::': fn f(i32) -> LinkArray + 164..178 'f::(5)': LinkArray + 176..177 '5': i32 + 188..189 'y': LinkArray, {unknown}> + 192..226 'LinkAr...>, 52>': LinkArray, {unknown}>(LinkArray) -> LinkArray, {unknown}> + 192..229 'LinkAr...52>(x)': LinkArray, {unknown}> + 227..228 'x': LinkArray + "#]], + ); +} diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs index cf8e284c627..a6706aa81d5 100644 --- a/crates/hir_ty/src/utils.rs +++ b/crates/hir_ty/src/utils.rs @@ -203,12 +203,30 @@ pub(crate) fn type_iter<'a>( ) } + pub(crate) fn toc_iter<'a>( + &'a self, + ) -> impl Iterator + 'a { + self.parent_generics + .as_ref() + .into_iter() + .flat_map(|it| { + it.params + .toc_iter() + .map(move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p)) + }) + .chain( + self.params.toc_iter().map(move |(local_id, p)| { + (TypeOrConstParamId { parent: self.def, local_id }, p) + }), + ) + } + pub(crate) fn iter_parent<'a>( &'a self, ) -> impl Iterator + 'a { self.parent_generics.as_ref().into_iter().flat_map(|it| { it.params - .types + .tocs .iter() .map(move |(local_id, p)| (TypeOrConstParamId { parent: it.def, local_id }, p)) }) @@ -221,36 +239,36 @@ pub(crate) fn len(&self) -> usize { /// (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()); - // FIXME: we should not filter const generics here, but at now it breaks tests - let child = self.params.types.iter().filter_map(|x| x.1.type_param()).count(); + let child = self.params.tocs.len(); (parent + child, parent, child) } - /// (parent total, self param, type param list, impl trait) - pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize) { + /// (parent total, self param, type param list, const param list, impl trait) + pub(crate) fn provenance_split(&self) -> (usize, usize, usize, usize, usize) { let parent = self.parent_generics.as_ref().map_or(0, |p| p.len()); let self_params = self .params - .types + .tocs .iter() .filter_map(|x| x.1.type_param()) .filter(|p| p.provenance == TypeParamProvenance::TraitSelf) .count(); - let list_params = self + let type_params = self .params - .types + .tocs .iter() .filter_map(|x| x.1.type_param()) .filter(|p| p.provenance == TypeParamProvenance::TypeParamList) .count(); + let const_params = self.params.tocs.iter().filter_map(|x| x.1.const_param()).count(); let impl_trait_params = self .params - .types + .tocs .iter() .filter_map(|x| x.1.type_param()) .filter(|p| p.provenance == TypeParamProvenance::ArgumentImplTrait) .count(); - (parent, self_params, list_params, impl_trait_params) + (parent, self_params, type_params, const_params, impl_trait_params) } pub(crate) fn param_idx(&self, param: TypeOrConstParamId) -> Option { @@ -261,7 +279,7 @@ fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstPa if param.parent == self.def { let (idx, (_local_id, data)) = self .params - .types + .tocs .iter() .enumerate() .find(|(_, (idx, _))| *idx == param.local_id) @@ -277,7 +295,7 @@ fn find_param(&self, param: TypeOrConstParamId) -> Option<(usize, &TypeOrConstPa pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution { Substitution::from_iter( Interner, - self.type_iter() + self.toc_iter() .enumerate() .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(Interner)), ) @@ -287,7 +305,7 @@ pub(crate) fn bound_vars_subst(&self, debruijn: DebruijnIndex) -> Substitution { pub(crate) fn type_params_subst(&self, db: &dyn HirDatabase) -> Substitution { Substitution::from_iter( Interner, - self.type_iter().map(|(id, _)| { + self.toc_iter().map(|(id, _)| { TyKind::Placeholder(crate::to_placeholder_idx(db, id)).intern(Interner) }), )