Skip to content

Commit ed25cf7

Browse files
committed
Change Ty::Param to contain param ID
1 parent f8b7b64 commit ed25cf7

File tree

11 files changed

+136
-127
lines changed

11 files changed

+136
-127
lines changed

crates/ra_hir_ty/src/db.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
use std::sync::Arc;
44

55
use hir_def::{
6-
db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId,
6+
db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, TypeParamId,
77
};
88
use ra_arena::map::ArenaMap;
9-
use ra_db::{salsa, CrateId};
9+
use ra_db::{impl_intern_key, salsa, CrateId};
1010
use ra_prof::profile;
1111

1212
use crate::{
@@ -37,10 +37,10 @@ pub trait HirDatabase: DefDatabase {
3737
fn impl_self_ty(&self, def: ImplId) -> Binders<Ty>;
3838

3939
#[salsa::invoke(crate::lower::impl_trait_query)]
40-
fn impl_trait(&self, def: ImplId) -> Option<TraitRef>;
40+
fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
4141

4242
#[salsa::invoke(crate::lower::field_types_query)]
43-
fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Ty>>;
43+
fn field_types(&self, var: VariantId) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>>;
4444

4545
#[salsa::invoke(crate::callable_item_sig)]
4646
fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig;
@@ -49,8 +49,7 @@ pub trait HirDatabase: DefDatabase {
4949
#[salsa::cycle(crate::lower::generic_predicates_for_param_recover)]
5050
fn generic_predicates_for_param(
5151
&self,
52-
def: GenericDefId,
53-
param_idx: u32,
52+
param_id: TypeParamId,
5453
) -> Arc<[GenericPredicate]>;
5554

5655
#[salsa::invoke(crate::lower::generic_predicates_query)]
@@ -77,6 +76,8 @@ pub trait HirDatabase: DefDatabase {
7776
#[salsa::interned]
7877
fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId;
7978
#[salsa::interned]
79+
fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId;
80+
#[salsa::interned]
8081
fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId;
8182
#[salsa::interned]
8283
fn intern_assoc_ty_value(&self, assoc_ty_value: AssocTyValue) -> crate::traits::AssocTyValueId;
@@ -117,3 +118,7 @@ fn infer(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
117118
fn hir_database_is_object_safe() {
118119
fn _assert_object_safe(_: &dyn HirDatabase) {}
119120
}
121+
122+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
123+
pub struct GlobalTypeParamId(salsa::InternId);
124+
impl_intern_key!(GlobalTypeParamId);

crates/ra_hir_ty/src/infer/coerce.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
5757
let trait_ref = db.impl_trait(impl_id)?;
5858

5959
// `CoerseUnsized` has one generic parameter for the target type.
60-
let cur_from_ty = trait_ref.substs.0.get(0)?;
61-
let cur_to_ty = trait_ref.substs.0.get(1)?;
60+
let cur_from_ty = trait_ref.value.substs.0.get(0)?;
61+
let cur_to_ty = trait_ref.value.substs.0.get(1)?;
6262

6363
match (&cur_from_ty, cur_to_ty) {
6464
(ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => {
6565
// FIXME: We return the first non-equal bound as the type parameter to coerce to unsized type.
6666
// This works for smart-pointer-like coercion, which covers all impls from std.
6767
st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| {
6868
match (ty1, ty2) {
69-
(Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. })
70-
if p1 != p2 =>
69+
(Ty::Bound(idx1), Ty::Bound(idx2))
70+
if idx1 != idx2 =>
7171
{
7272
Some(((*ctor1, *ctor2), i))
7373
}
@@ -256,8 +256,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
256256
let unsize_generic_index = {
257257
let mut index = None;
258258
let mut multiple_param = false;
259-
field_tys[last_field_id].walk(&mut |ty| match ty {
260-
&Ty::Param { idx, .. } => {
259+
field_tys[last_field_id].value.walk(&mut |ty| match ty {
260+
&Ty::Bound(idx) => {
261261
if index.is_none() {
262262
index = Some(idx);
263263
} else if Some(idx) != index {
@@ -276,8 +276,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
276276
// Check other fields do not involve it.
277277
let mut multiple_used = false;
278278
fields.for_each(|(field_id, _data)| {
279-
field_tys[field_id].walk(&mut |ty| match ty {
280-
&Ty::Param { idx, .. } if idx == unsize_generic_index => {
279+
field_tys[field_id].value.walk(&mut |ty| match ty {
280+
&Ty::Bound(idx) if idx == unsize_generic_index => {
281281
multiple_used = true
282282
}
283283
_ => {}

crates/ra_hir_ty/src/infer/expr.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
236236
self.result.record_field_resolutions.insert(field.expr, field_def);
237237
}
238238
let field_ty = field_def
239-
.map_or(Ty::Unknown, |it| field_types[it.local_id].clone())
240-
.subst(&substs);
239+
.map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs));
241240
self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
242241
}
243242
if let Some(expr) = spread {
@@ -686,7 +685,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
686685
if let TypeCtor::FnDef(def) = a_ty.ctor {
687686
let generic_predicates = self.db.generic_predicates(def.into());
688687
for predicate in generic_predicates.iter() {
689-
let predicate = predicate.clone().subst(&a_ty.parameters);
688+
let predicate = predicate.clone().subst_type_params(self.db, def.into(), &a_ty.parameters);
690689
if let Some(obligation) = Obligation::from_predicate(predicate) {
691690
self.obligations.push(obligation);
692691
}

crates/ra_hir_ty/src/infer/pat.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use hir_expand::name::Name;
1212
use test_utils::tested_by;
1313

1414
use super::{BindingMode, InferenceContext};
15-
use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk};
15+
use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor};
1616

1717
impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1818
fn infer_tuple_struct_pat(
@@ -34,8 +34,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
3434
let expected_ty = var_data
3535
.as_ref()
3636
.and_then(|d| d.field(&Name::new_tuple_field(i)))
37-
.map_or(Ty::Unknown, |field| field_tys[field].clone())
38-
.subst(&substs);
37+
.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
3938
let expected_ty = self.normalize_associated_types_in(expected_ty);
4039
self.infer_pat(subpat, &expected_ty, default_bm);
4140
}
@@ -65,7 +64,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
6564
for subpat in subpats {
6665
let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name));
6766
let expected_ty =
68-
matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs);
67+
matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs));
6968
let expected_ty = self.normalize_associated_types_in(expected_ty);
7069
self.infer_pat(subpat.pat, &expected_ty, default_bm);
7170
}

crates/ra_hir_ty/src/lib.rs

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ use std::{fmt, iter, mem};
4545

4646
use hir_def::{
4747
expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId,
48-
HasModule, Lookup, TraitId, TypeAliasId,
48+
HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance,
4949
};
50-
use hir_expand::name::Name;
5150
use ra_db::{impl_intern_key, salsa, CrateId};
51+
use hir_expand::name::Name;
5252

5353
use crate::{
5454
db::HirDatabase,
@@ -288,14 +288,7 @@ pub enum Ty {
288288
Projection(ProjectionTy),
289289

290290
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}
291-
Param {
292-
/// The index of the parameter (starting with parameters from the
293-
/// surrounding impl, then the current function).
294-
idx: u32,
295-
/// The name of the parameter, for displaying.
296-
// FIXME get rid of this
297-
name: Name,
298-
},
291+
Param(TypeParamId),
299292

300293
/// A bound type variable. Used during trait resolution to represent Chalk
301294
/// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type.
@@ -366,15 +359,15 @@ impl Substs {
366359
}
367360

368361
/// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
369-
pub(crate) fn identity(generic_params: &Generics) -> Substs {
362+
pub(crate) fn type_params(generic_params: &Generics) -> Substs {
370363
Substs(
371-
generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone().unwrap_or_else(Name::missing) }).collect(),
364+
generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(),
372365
)
373366
}
374367

375368
/// Return Substs that replace each parameter by a bound variable.
376369
pub(crate) fn bound_vars(generic_params: &Generics) -> Substs {
377-
Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect())
370+
Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect())
378371
}
379372

380373
pub fn build_for_def(db: &impl HirDatabase, def: impl Into<GenericDefId>) -> SubstsBuilder {
@@ -422,11 +415,6 @@ impl SubstsBuilder {
422415
self.fill((starting_from..).map(Ty::Bound))
423416
}
424417

425-
pub fn fill_with_params(self) -> Self {
426-
let start = self.vec.len() as u32;
427-
self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() }))
428-
}
429-
430418
pub fn fill_with_unknown(self) -> Self {
431419
self.fill(iter::repeat(Ty::Unknown))
432420
}
@@ -762,13 +750,19 @@ pub trait TypeWalk {
762750
/// Replaces type parameters in this type using the given `Substs`. (So e.g.
763751
/// if `self` is `&[T]`, where type parameter T has index 0, and the
764752
/// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.)
765-
fn subst(self, substs: &Substs) -> Self
753+
// TODO: this should mostly not be used anymore
754+
fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self
766755
where
767756
Self: Sized,
768757
{
758+
let generics = generics(db, def);
769759
self.fold(&mut |ty| match ty {
770-
Ty::Param { idx, name } => {
771-
substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name })
760+
Ty::Param(id) => {
761+
if let Some(idx) = generics.param_idx(id) {
762+
substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id))
763+
} else {
764+
ty
765+
}
772766
}
773767
ty => ty,
774768
})
@@ -1042,7 +1036,18 @@ impl HirDisplay for Ty {
10421036
match self {
10431037
Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
10441038
Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
1045-
Ty::Param { name, .. } => write!(f, "{}", name)?,
1039+
Ty::Param(id) => {
1040+
let generic_params = f.db.generic_params(id.parent);
1041+
let param_data = &generic_params.types[id.local_id];
1042+
match param_data.provenance {
1043+
TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
1044+
write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
1045+
}
1046+
TypeParamProvenance::ArgumentImplTrait => {
1047+
write!(f, "impl TODO")?
1048+
}
1049+
}
1050+
},
10461051
Ty::Bound(idx) => write!(f, "?{}", idx)?,
10471052
Ty::Dyn(predicates) | Ty::Opaque(predicates) => {
10481053
match self {

0 commit comments

Comments
 (0)