Skip to content

Insert dummy values for const generics in subst #11660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/hir/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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) => {
Expand Down Expand Up @@ -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
Expand All @@ -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 &params.types[*id].name() {
WherePredicateTypeTarget::TypeOrConstParam(id) => match &params.tocs[*id].name() {
Some(name) => write!(f, "{}", name),
None => write!(f, "{{unnamed}}"),
},
Expand Down
10 changes: 5 additions & 5 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2007,7 +2007,7 @@ impl_from!(
impl GenericDef {
pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
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),
Expand All @@ -2027,7 +2027,7 @@ impl GenericDef {
pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeOrConstParam> {
let generics = db.generic_params(self.into());
generics
.types
.tocs
.iter()
.map(|(local_id, _)| TypeOrConstParam {
id: TypeOrConstParamId { parent: self.into(), local_id },
Expand Down Expand Up @@ -2349,7 +2349,7 @@ impl ConstParam {

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!();
Expand Down Expand Up @@ -2381,7 +2381,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(),
}
Expand All @@ -2397,7 +2397,7 @@ impl TypeOrConstParam {

pub fn split(self, db: &dyn HirDatabase) -> Either<ConstParam, TypeParam> {
let params = db.generic_params(self.id.parent);
match &params.types[self.id.local_id] {
match &params.tocs[self.id.local_id] {
hir_def::generics::TypeOrConstParamData::TypeParamData(_) => {
Either::Right(TypeParam { id: self.id.into() })
}
Expand Down
35 changes: 24 additions & 11 deletions crates/hir_def/src/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ impl TypeOrConstParamData {
}
}

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) => {
Expand All @@ -92,7 +99,7 @@ impl_from!(TypeParamData, ConstParamData for TypeOrConstParamData);
/// Data about the generic parameters of a function, struct, impl, etc.
#[derive(Clone, PartialEq, Eq, Debug, Default, Hash)]
pub struct GenericParams {
pub types: Arena<TypeOrConstParamData>,
pub tocs: Arena<TypeOrConstParamData>,
pub lifetimes: Arena<LifetimeParamData>,
pub where_predicates: Vec<WherePredicate>,
}
Expand Down Expand Up @@ -131,7 +138,13 @@ impl GenericParams {
pub fn type_iter<'a>(
&'a self,
) -> impl Iterator<Item = (Idx<TypeOrConstParamData>, &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<Item = (Idx<TypeOrConstParamData>, &TypeOrConstParamData)> {
self.tocs.iter()
}

pub(crate) fn generic_params_query(
Expand Down Expand Up @@ -238,7 +251,7 @@ impl GenericParams {
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));
}
Expand All @@ -248,7 +261,7 @@ impl GenericParams {
.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());
}
}
}
Expand Down Expand Up @@ -335,7 +348,7 @@ impl GenericParams {
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),
Expand All @@ -359,27 +372,27 @@ impl GenericParams {
}

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<LocalTypeOrConstParamId> {
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<LocalTypeOrConstParamId> {
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<LocalTypeOrConstParamId> {
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)
Expand Down Expand Up @@ -438,7 +451,7 @@ impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
db: &dyn DefDatabase,
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
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);

Expand Down Expand Up @@ -492,7 +505,7 @@ impl ChildBySource for GenericDefId {
}

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.
Expand Down
2 changes: 1 addition & 1 deletion crates/hir_def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ impl<'a> Ctx<'a> {
}
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,
Expand Down
6 changes: 3 additions & 3 deletions crates/hir_def/src/item_tree/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ impl<'a> Printer<'a> {
}

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;
}

Expand All @@ -639,7 +639,7 @@ impl<'a> Printer<'a> {
first = false;
w!(self, "{}", lt.name);
}
for (idx, x) in params.types.iter() {
for (idx, x) in params.tocs.iter() {
if !first {
w!(self, ", ");
}
Expand Down Expand Up @@ -701,7 +701,7 @@ impl<'a> Printer<'a> {
match target {
WherePredicateTypeTarget::TypeRef(ty) => this.print_type_ref(ty),
WherePredicateTypeTarget::TypeOrConstParam(id) => {
match &params.types[*id].name() {
match &params.tocs[*id].name() {
Some(name) => w!(this, "{}", name),
None => w!(this, "_anon_{}", id.into_raw()),
}
Expand Down
4 changes: 2 additions & 2 deletions crates/hir_def/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,10 +526,10 @@ impl Scope {
}
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) = &param.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 {
Expand Down
2 changes: 1 addition & 1 deletion crates/hir_ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ impl TyExt for Ty {
TyKind::Placeholder(idx) => {
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 => {
Expand Down
8 changes: 4 additions & 4 deletions crates/hir_ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ impl HirDisplay for Const {
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),
Expand Down Expand Up @@ -489,9 +489,9 @@ impl HirDisplay for Ty {
};
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, "<")?;
Expand Down Expand Up @@ -680,7 +680,7 @@ impl HirDisplay for Ty {
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 => {
Expand Down
7 changes: 4 additions & 3 deletions crates/hir_ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1032,10 +1032,10 @@ impl<'a> InferenceContext<'a> {
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() {
Expand All @@ -1044,7 +1044,8 @@ impl<'a> InferenceContext<'a> {
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());
}
}
}
Expand Down
44 changes: 29 additions & 15 deletions crates/hir_ty/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,21 @@ impl<'a> TyLoweringContext<'a> {
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)
}
Expand Down Expand Up @@ -639,9 +644,10 @@ impl<'a> TyLoweringContext<'a> {
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));

Expand Down Expand Up @@ -993,7 +999,7 @@ fn named_associated_type_shorthand_candidates<R>(
// 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();
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
Loading