From ed25cf70d5e0df9c7a33deb503ea14c2d97bd7a7 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 31 Jan 2020 16:52:43 +0100 Subject: Change Ty::Param to contain param ID --- crates/ra_hir_ty/src/db.rs | 17 ++-- crates/ra_hir_ty/src/infer/coerce.rs | 16 ++-- crates/ra_hir_ty/src/infer/expr.rs | 5 +- crates/ra_hir_ty/src/infer/pat.rs | 7 +- crates/ra_hir_ty/src/lib.rs | 49 ++++++----- crates/ra_hir_ty/src/lower.rs | 108 +++++++++++++----------- crates/ra_hir_ty/src/method_resolution.rs | 2 +- crates/ra_hir_ty/src/tests/method_resolution.rs | 2 +- crates/ra_hir_ty/src/tests/traits.rs | 3 +- crates/ra_hir_ty/src/traits/chalk.rs | 24 +++--- crates/ra_hir_ty/src/utils.rs | 30 +++---- 11 files changed, 136 insertions(+), 127 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs index fea122a8b..7684ade06 100644 --- a/crates/ra_hir_ty/src/db.rs +++ b/crates/ra_hir_ty/src/db.rs @@ -3,10 +3,10 @@ use std::sync::Arc; use hir_def::{ - db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, + db::DefDatabase, DefWithBodyId, GenericDefId, ImplId, LocalStructFieldId, TraitId, VariantId, TypeParamId, }; use ra_arena::map::ArenaMap; -use ra_db::{salsa, CrateId}; +use ra_db::{impl_intern_key, salsa, CrateId}; use ra_prof::profile; use crate::{ @@ -37,10 +37,10 @@ pub trait HirDatabase: DefDatabase { fn impl_self_ty(&self, def: ImplId) -> Binders; #[salsa::invoke(crate::lower::impl_trait_query)] - fn impl_trait(&self, def: ImplId) -> Option; + fn impl_trait(&self, def: ImplId) -> Option>; #[salsa::invoke(crate::lower::field_types_query)] - fn field_types(&self, var: VariantId) -> Arc>; + fn field_types(&self, var: VariantId) -> Arc>>; #[salsa::invoke(crate::callable_item_sig)] fn callable_item_signature(&self, def: CallableDef) -> PolyFnSig; @@ -49,8 +49,7 @@ pub trait HirDatabase: DefDatabase { #[salsa::cycle(crate::lower::generic_predicates_for_param_recover)] fn generic_predicates_for_param( &self, - def: GenericDefId, - param_idx: u32, + param_id: TypeParamId, ) -> Arc<[GenericPredicate]>; #[salsa::invoke(crate::lower::generic_predicates_query)] @@ -77,6 +76,8 @@ pub trait HirDatabase: DefDatabase { #[salsa::interned] fn intern_type_ctor(&self, type_ctor: TypeCtor) -> crate::TypeCtorId; #[salsa::interned] + fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; + #[salsa::interned] fn intern_chalk_impl(&self, impl_: Impl) -> crate::traits::GlobalImplId; #[salsa::interned] 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 { fn hir_database_is_object_safe() { fn _assert_object_safe(_: &dyn HirDatabase) {} } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct GlobalTypeParamId(salsa::InternId); +impl_intern_key!(GlobalTypeParamId); diff --git a/crates/ra_hir_ty/src/infer/coerce.rs b/crates/ra_hir_ty/src/infer/coerce.rs index 83c0c2c3f..2a9567898 100644 --- a/crates/ra_hir_ty/src/infer/coerce.rs +++ b/crates/ra_hir_ty/src/infer/coerce.rs @@ -57,8 +57,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let trait_ref = db.impl_trait(impl_id)?; // `CoerseUnsized` has one generic parameter for the target type. - let cur_from_ty = trait_ref.substs.0.get(0)?; - let cur_to_ty = trait_ref.substs.0.get(1)?; + let cur_from_ty = trait_ref.value.substs.0.get(0)?; + let cur_to_ty = trait_ref.value.substs.0.get(1)?; match (&cur_from_ty, cur_to_ty) { (ty_app!(ctor1, st1), ty_app!(ctor2, st2)) => { @@ -66,8 +66,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // This works for smart-pointer-like coercion, which covers all impls from std. st1.iter().zip(st2.iter()).enumerate().find_map(|(i, (ty1, ty2))| { match (ty1, ty2) { - (Ty::Param { idx: p1, .. }, Ty::Param { idx: p2, .. }) - if p1 != p2 => + (Ty::Bound(idx1), Ty::Bound(idx2)) + if idx1 != idx2 => { Some(((*ctor1, *ctor2), i)) } @@ -256,8 +256,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let unsize_generic_index = { let mut index = None; let mut multiple_param = false; - field_tys[last_field_id].walk(&mut |ty| match ty { - &Ty::Param { idx, .. } => { + field_tys[last_field_id].value.walk(&mut |ty| match ty { + &Ty::Bound(idx) => { if index.is_none() { index = Some(idx); } else if Some(idx) != index { @@ -276,8 +276,8 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { // Check other fields do not involve it. let mut multiple_used = false; fields.for_each(|(field_id, _data)| { - field_tys[field_id].walk(&mut |ty| match ty { - &Ty::Param { idx, .. } if idx == unsize_generic_index => { + field_tys[field_id].value.walk(&mut |ty| match ty { + &Ty::Bound(idx) if idx == unsize_generic_index => { multiple_used = true } _ => {} diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs index e1fdb356d..8b8378499 100644 --- a/crates/ra_hir_ty/src/infer/expr.rs +++ b/crates/ra_hir_ty/src/infer/expr.rs @@ -236,8 +236,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.result.record_field_resolutions.insert(field.expr, field_def); } let field_ty = field_def - .map_or(Ty::Unknown, |it| field_types[it.local_id].clone()) - .subst(&substs); + .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); } if let Some(expr) = spread { @@ -686,7 +685,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { if let TypeCtor::FnDef(def) = a_ty.ctor { let generic_predicates = self.db.generic_predicates(def.into()); for predicate in generic_predicates.iter() { - let predicate = predicate.clone().subst(&a_ty.parameters); + let predicate = predicate.clone().subst_type_params(self.db, def.into(), &a_ty.parameters); if let Some(obligation) = Obligation::from_predicate(predicate) { self.obligations.push(obligation); } diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index a14662884..e7283f24c 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs @@ -12,7 +12,7 @@ use hir_expand::name::Name; use test_utils::tested_by; use super::{BindingMode, InferenceContext}; -use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor, TypeWalk}; +use crate::{db::HirDatabase, utils::variant_data, Substs, Ty, TypeCtor}; impl<'a, D: HirDatabase> InferenceContext<'a, D> { fn infer_tuple_struct_pat( @@ -34,8 +34,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let expected_ty = var_data .as_ref() .and_then(|d| d.field(&Name::new_tuple_field(i))) - .map_or(Ty::Unknown, |field| field_tys[field].clone()) - .subst(&substs); + .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); let expected_ty = self.normalize_associated_types_in(expected_ty); self.infer_pat(subpat, &expected_ty, default_bm); } @@ -65,7 +64,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { for subpat in subpats { let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); let expected_ty = - matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone()).subst(&substs); + matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); let expected_ty = self.normalize_associated_types_in(expected_ty); self.infer_pat(subpat.pat, &expected_ty, default_bm); } diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs index 1f0fd1128..1e162943c 100644 --- a/crates/ra_hir_ty/src/lib.rs +++ b/crates/ra_hir_ty/src/lib.rs @@ -45,10 +45,10 @@ use std::{fmt, iter, mem}; use hir_def::{ expr::ExprId, type_ref::Mutability, AdtId, AssocContainerId, DefWithBodyId, GenericDefId, - HasModule, Lookup, TraitId, TypeAliasId, + HasModule, Lookup, TraitId, TypeAliasId, TypeParamId, generics::TypeParamProvenance, }; -use hir_expand::name::Name; use ra_db::{impl_intern_key, salsa, CrateId}; +use hir_expand::name::Name; use crate::{ db::HirDatabase, @@ -288,14 +288,7 @@ pub enum Ty { Projection(ProjectionTy), /// A type parameter; for example, `T` in `fn f(x: T) {} - Param { - /// The index of the parameter (starting with parameters from the - /// surrounding impl, then the current function). - idx: u32, - /// The name of the parameter, for displaying. - // FIXME get rid of this - name: Name, - }, + Param(TypeParamId), /// A bound type variable. Used during trait resolution to represent Chalk /// variables, and in `Dyn` and `Opaque` bounds to represent the `Self` type. @@ -366,15 +359,15 @@ impl Substs { } /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). - pub(crate) fn identity(generic_params: &Generics) -> Substs { + pub(crate) fn type_params(generic_params: &Generics) -> Substs { Substs( - generic_params.iter().map(|(idx, p)| Ty::Param { idx, name: p.name.clone().unwrap_or_else(Name::missing) }).collect(), + generic_params.iter().map(|(id, _)| Ty::Param(id)).collect(), ) } /// Return Substs that replace each parameter by a bound variable. pub(crate) fn bound_vars(generic_params: &Generics) -> Substs { - Substs(generic_params.iter().map(|(idx, _p)| Ty::Bound(idx)).collect()) + Substs(generic_params.iter().enumerate().map(|(idx, _)| Ty::Bound(idx as u32)).collect()) } pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { @@ -422,11 +415,6 @@ impl SubstsBuilder { self.fill((starting_from..).map(Ty::Bound)) } - pub fn fill_with_params(self) -> Self { - let start = self.vec.len() as u32; - self.fill((start..).map(|idx| Ty::Param { idx, name: Name::missing() })) - } - pub fn fill_with_unknown(self) -> Self { self.fill(iter::repeat(Ty::Unknown)) } @@ -762,13 +750,19 @@ pub trait TypeWalk { /// Replaces type parameters in this type using the given `Substs`. (So e.g. /// if `self` is `&[T]`, where type parameter T has index 0, and the /// `Substs` contain `u32` at index 0, we'll have `&[u32]` afterwards.) - fn subst(self, substs: &Substs) -> Self + // TODO: this should mostly not be used anymore + fn subst_type_params(self, db: &impl HirDatabase, def: GenericDefId, substs: &Substs) -> Self where Self: Sized, { + let generics = generics(db, def); self.fold(&mut |ty| match ty { - Ty::Param { idx, name } => { - substs.get(idx as usize).cloned().unwrap_or(Ty::Param { idx, name }) + Ty::Param(id) => { + if let Some(idx) = generics.param_idx(id) { + substs.get(idx as usize).cloned().unwrap_or(Ty::Param(id)) + } else { + ty + } } ty => ty, }) @@ -1042,7 +1036,18 @@ impl HirDisplay for Ty { match self { Ty::Apply(a_ty) => a_ty.hir_fmt(f)?, Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, - Ty::Param { name, .. } => write!(f, "{}", name)?, + Ty::Param(id) => { + let generic_params = f.db.generic_params(id.parent); + let param_data = &generic_params.types[id.local_id]; + match param_data.provenance { + TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => { + write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? + } + TypeParamProvenance::ArgumentImplTrait => { + write!(f, "impl TODO")? + } + } + }, Ty::Bound(idx) => write!(f, "?{}", idx)?, Ty::Dyn(predicates) | Ty::Opaque(predicates) => { match self { diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs index 88d962b47..d60b59433 100644 --- a/crates/ra_hir_ty/src/lower.rs +++ b/crates/ra_hir_ty/src/lower.rs @@ -30,7 +30,7 @@ use crate::{ Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, }; -use hir_expand::name::Name; +use hir_def::TypeParamId; #[derive(Debug)] pub struct TyLoweringContext<'a, DB: HirDatabase> { @@ -145,7 +145,16 @@ impl Ty { ImplTraitLoweringMode::Param => { let idx = ctx.impl_trait_counter.get(); ctx.impl_trait_counter.set(idx + 1); - Ty::Param { idx: idx as u32, name: Name::missing() } + if let Some(def) = ctx.resolver.generic_def() { + let generics = generics(ctx.db, def); + let param = generics + .iter() + .nth(idx as usize) + .map_or(Ty::Unknown, |(id, _)| Ty::Param(id)); + param + } else { + Ty::Unknown + } } ImplTraitLoweringMode::Variable => { let idx = ctx.impl_trait_counter.get(); @@ -176,7 +185,7 @@ impl Ty { fn from_hir_only_param( ctx: &TyLoweringContext<'_, impl HirDatabase>, type_ref: &TypeRef, - ) -> Option { + ) -> Option { let path = match type_ref { TypeRef::Path(path) => path, _ => return None, @@ -192,9 +201,7 @@ impl Ty { _ => return None, }; if let TypeNs::GenericParam(param_id) = resolution { - let generics = generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); - let idx = generics.param_idx(param_id); - Some(idx) + Some(param_id) } else { None } @@ -256,20 +263,18 @@ impl Ty { TypeNs::GenericParam(param_id) => { let generics = generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); - let idx = generics.param_idx(param_id); match ctx.type_param_mode { - TypeParamLoweringMode::Placeholder => { - // FIXME: maybe return name in resolution? - let name = generics.param_name(param_id); - Ty::Param { idx, name } + TypeParamLoweringMode::Placeholder => Ty::Param(param_id), + TypeParamLoweringMode::Variable => { + let idx = generics.param_idx(param_id).expect("matching generics"); + Ty::Bound(idx) } - TypeParamLoweringMode::Variable => Ty::Bound(idx), } } TypeNs::SelfType(impl_id) => { let generics = generics(ctx.db, impl_id.into()); let substs = match ctx.type_param_mode { - TypeParamLoweringMode::Placeholder => Substs::identity(&generics), + TypeParamLoweringMode::Placeholder => Substs::type_params(&generics), TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), }; ctx.db.impl_self_ty(impl_id).subst(&substs) @@ -277,7 +282,7 @@ impl Ty { TypeNs::AdtSelfType(adt) => { let generics = generics(ctx.db, adt.into()); let substs = match ctx.type_param_mode { - TypeParamLoweringMode::Placeholder => Substs::identity(&generics), + TypeParamLoweringMode::Placeholder => Substs::type_params(&generics), TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), }; ctx.db.ty(adt.into()).subst(&substs) @@ -319,20 +324,28 @@ impl Ty { self_ty: Ty, segment: PathSegment<'_>, ) -> Ty { - let param_idx = match self_ty { - Ty::Param { idx, .. } if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => idx, - Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => idx, - _ => return Ty::Unknown, // Error: Ambiguous associated type - }; let def = match ctx.resolver.generic_def() { Some(def) => def, None => return Ty::Unknown, // this can't actually happen }; - let predicates = ctx.db.generic_predicates_for_param(def.into(), param_idx); + let param_id = match self_ty { + Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id, + Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => { + let generics = generics(ctx.db, def); + let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) { + id + } else { + return Ty::Unknown; + }; + param_id + }, + _ => return Ty::Unknown, // Error: Ambiguous associated type + }; + let predicates = ctx.db.generic_predicates_for_param(param_id); let traits_from_env = predicates.iter().filter_map(|pred| match pred { GenericPredicate::Implemented(tr) => { - if let Ty::Param { idx, .. } = tr.self_ty() { - if *idx == param_idx { + if let Ty::Param(id) = tr.self_ty() { + if *id == param_id { return Some(tr.trait_); } } @@ -530,13 +543,12 @@ impl GenericPredicate { let generic_def = ctx.resolver.generic_def().expect("generics in scope"); let generics = generics(ctx.db, generic_def); let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; - let idx = generics.param_idx(param_id); match ctx.type_param_mode { - TypeParamLoweringMode::Placeholder => { - let name = generics.param_name(param_id); - Ty::Param { idx, name } + TypeParamLoweringMode::Placeholder => Ty::Param(param_id), + TypeParamLoweringMode::Variable => { + let idx = generics.param_idx(param_id).expect("matching generics"); + Ty::Bound(idx) } - TypeParamLoweringMode::Variable => Ty::Bound(idx), } } }; @@ -599,17 +611,19 @@ pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig { pub(crate) fn field_types_query( db: &impl HirDatabase, variant_id: VariantId, -) -> Arc> { +) -> Arc>> { let var_data = variant_data(db, variant_id); - let resolver = match variant_id { - VariantId::StructId(it) => it.resolver(db), - VariantId::UnionId(it) => it.resolver(db), - VariantId::EnumVariantId(it) => it.parent.resolver(db), + let (resolver, def): (_, GenericDefId) = match variant_id { + VariantId::StructId(it) => (it.resolver(db), it.into()), + VariantId::UnionId(it) => (it.resolver(db), it.into()), + VariantId::EnumVariantId(it) => (it.parent.resolver(db), it.parent.into()), }; + let generics = generics(db, def); let mut res = ArenaMap::default(); - let ctx = TyLoweringContext::new(db, &resolver); + let ctx = TyLoweringContext::new(db, &resolver) + .with_type_param_mode(TypeParamLoweringMode::Variable); for (field_id, field_data) in var_data.fields().iter() { - res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) + res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) } Arc::new(res) } @@ -624,23 +638,20 @@ pub(crate) fn field_types_query( /// these are fine: `T: Foo, U: Foo<()>`. pub(crate) fn generic_predicates_for_param_query( db: &impl HirDatabase, - def: GenericDefId, - param_idx: u32, + param_id: TypeParamId, ) -> Arc<[GenericPredicate]> { - let resolver = def.resolver(db); + let resolver = param_id.parent.resolver(db); let ctx = TyLoweringContext::new(db, &resolver); - let generics = generics(db, def); + // let generics = generics(db, def); resolver .where_predicates_in_scope() // we have to filter out all other predicates *first*, before attempting to lower them .filter(|pred| match &pred.target { WherePredicateTarget::TypeRef(type_ref) => { - Ty::from_hir_only_param(&ctx, type_ref) == Some(param_idx) + Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) } WherePredicateTarget::TypeParam(local_id) => { - let param_id = hir_def::TypeParamId { parent: def, local_id: *local_id }; - let idx = generics.param_idx(param_id); - idx == param_idx + *local_id == param_id.local_id } }) .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) @@ -650,8 +661,7 @@ pub(crate) fn generic_predicates_for_param_query( pub(crate) fn generic_predicates_for_param_recover( _db: &impl HirDatabase, _cycle: &[String], - _def: &GenericDefId, - _param_idx: &u32, + _param_id: &TypeParamId, ) -> Arc<[GenericPredicate]> { Arc::new([]) } @@ -905,12 +915,12 @@ pub(crate) fn impl_self_ty_recover( Binders::new(generics.len(), Ty::Unknown) } -pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option { +pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option> { let impl_data = db.impl_data(impl_id); let resolver = impl_id.resolver(db); - let generics = generics(db, impl_id.into()); - let ctx = TyLoweringContext::new(db, &resolver); - let self_ty = db.impl_self_ty(impl_id).subst(&Substs::identity(&generics)); + let ctx = TyLoweringContext::new(db, &resolver) + .with_type_param_mode(TypeParamLoweringMode::Variable); + let self_ty = db.impl_self_ty(impl_id); let target_trait = impl_data.target_trait.as_ref()?; - TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) + Some(Binders::new(self_ty.num_binders, TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?)) } diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs index eab2149dc..5283bff28 100644 --- a/crates/ra_hir_ty/src/method_resolution.rs +++ b/crates/ra_hir_ty/src/method_resolution.rs @@ -61,7 +61,7 @@ impl CrateImplBlocks { for impl_id in module_data.scope.impls() { match db.impl_trait(impl_id) { Some(tr) => { - res.impls_by_trait.entry(tr.trait_).or_default().push(impl_id); + res.impls_by_trait.entry(tr.value.trait_).or_default().push(impl_id); } None => { let self_ty = db.impl_self_ty(impl_id); diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs index 446d12813..1722563aa 100644 --- a/crates/ra_hir_ty/src/tests/method_resolution.rs +++ b/crates/ra_hir_ty/src/tests/method_resolution.rs @@ -697,7 +697,7 @@ fn test>(t: T) { [71; 72) 't': T [77; 96) '{ ...d(); }': () [83; 84) 't': T - [83; 93) 't.method()': [missing name] + [83; 93) 't.method()': U "### ); } diff --git a/crates/ra_hir_ty/src/tests/traits.rs b/crates/ra_hir_ty/src/tests/traits.rs index dc78e83cd..e6f697fa3 100644 --- a/crates/ra_hir_ty/src/tests/traits.rs +++ b/crates/ra_hir_ty/src/tests/traits.rs @@ -822,8 +822,7 @@ fn test() { "#, ); // inside the generic function, the associated type gets normalized to a placeholder `ApplL::Out` [https://rust-lang.github.io/rustc-guide/traits/associated-types.html#placeholder-associated-types]. - // FIXME: fix type parameter names going missing when going through Chalk - assert_eq!(t, "ApplyL::Out<[missing name]>"); + assert_eq!(t, "ApplyL::Out"); } #[test] diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index fe9cb556c..6e97f7dd2 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs @@ -142,8 +142,9 @@ impl ToChalk for Ty { let substitution = proj_ty.parameters.to_chalk(db); chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern() } - Ty::Param { idx, .. } => { - PlaceholderIndex { ui: UniverseIndex::ROOT, idx: idx as usize } + Ty::Param(id) => { + let interned_id = db.intern_type_param_id(id); + PlaceholderIndex { ui: UniverseIndex::ROOT, idx: interned_id.as_intern_id().as_usize() } .to_ty::() } Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), @@ -177,7 +178,8 @@ impl ToChalk for Ty { }, chalk_ir::TyData::Placeholder(idx) => { assert_eq!(idx.ui, UniverseIndex::ROOT); - Ty::Param { idx: idx.idx as u32, name: crate::Name::missing() } + let interned_id = crate::db::GlobalTypeParamId::from_intern_id(crate::salsa::InternId::from(idx.idx)); + Ty::Param(db.lookup_intern_type_param_id(interned_id)) } chalk_ir::TyData::Alias(proj) => { let associated_ty = from_chalk(db, proj.associated_ty_id); @@ -524,7 +526,7 @@ fn convert_where_clauses( // skip errored predicates completely continue; } - result.push(pred.clone().subst(substs).to_chalk(db)); + result.push(pred.clone().subst_type_params(db, def, substs).to_chalk(db)); } result } @@ -709,12 +711,12 @@ fn impl_block_datum( let trait_ref = db .impl_trait(impl_id) // ImplIds for impls where the trait ref can't be resolved should never reach Chalk - .expect("invalid impl passed to Chalk"); + .expect("invalid impl passed to Chalk") + .value; let impl_data = db.impl_data(impl_id); let generic_params = generics(db, impl_id.into()); let bound_vars = Substs::bound_vars(&generic_params); - let trait_ref = trait_ref.subst(&bound_vars); let trait_ = trait_ref.trait_; let impl_type = if impl_id.lookup(db).container.module(db).krate == krate { chalk_rust_ir::ImplType::Local @@ -789,20 +791,18 @@ fn type_alias_associated_ty_value( _ => panic!("assoc ty value should be in impl"), }; - let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist"); // we don't return any assoc ty values if the impl'd trait can't be resolved + let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved let assoc_ty = db .trait_data(trait_ref.trait_) .associated_type_by_name(&type_alias_data.name) .expect("assoc ty value should not exist"); // validated when building the impl data as well - let generic_params = generics(db, impl_id.into()); - let bound_vars = Substs::bound_vars(&generic_params); - let ty = db.ty(type_alias.into()).subst(&bound_vars); - let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; + let ty = db.ty(type_alias.into()); + let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; let value = chalk_rust_ir::AssociatedTyValue { impl_id: Impl::ImplBlock(impl_id.into()).to_chalk(db), associated_ty_id: assoc_ty.to_chalk(db), - value: make_binders(value_bound, bound_vars.len()), + value: make_binders(value_bound, ty.num_binders), }; Arc::new(value) } diff --git a/crates/ra_hir_ty/src/utils.rs b/crates/ra_hir_ty/src/utils.rs index 77b7de729..8fa1838bd 100644 --- a/crates/ra_hir_ty/src/utils.rs +++ b/crates/ra_hir_ty/src/utils.rs @@ -99,23 +99,19 @@ pub(crate) struct Generics { } impl Generics { - pub(crate) fn iter<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn iter<'a>(&'a self) -> impl Iterator + 'a { self.parent_generics .as_ref() .into_iter() - .flat_map(|it| it.params.types.iter()) - .chain(self.params.types.iter()) - .enumerate() - .map(|(i, (_local_id, p))| (i as u32, p)) + .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) + .chain(self.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: self.def, local_id }, p))) } - pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn iter_parent<'a>(&'a self) -> impl Iterator + 'a { self.parent_generics .as_ref() .into_iter() - .flat_map(|it| it.params.types.iter()) - .enumerate() - .map(|(i, (_local_id, p))| (i as u32, p)) + .flat_map(|it| it.params.types.iter().map(move |(local_id, p)| (TypeParamId { parent: it.def, local_id }, p))) } pub(crate) fn len(&self) -> usize { @@ -137,16 +133,11 @@ impl Generics { (self_params, list_params, impl_trait_params) } - pub(crate) fn param_idx(&self, param: TypeParamId) -> u32 { - self.find_param(param).0 + pub(crate) fn param_idx(&self, param: TypeParamId) -> Option { + Some(self.find_param(param)?.0) } - pub(crate) fn param_name(&self, param: TypeParamId) -> Name { - // FIXME make this return Option - self.find_param(param).1.name.clone().unwrap_or_else(Name::missing) - } - - fn find_param(&self, param: TypeParamId) -> (u32, &TypeParamData) { + fn find_param(&self, param: TypeParamId) -> Option<(u32, &TypeParamData)> { if param.parent == self.def { let (idx, (_local_id, data)) = self .params @@ -156,9 +147,10 @@ impl Generics { .find(|(_, (idx, _))| *idx == param.local_id) .unwrap(); let (_total, parent_len, _child) = self.len_split(); - return ((parent_len + idx) as u32, data); + Some(((parent_len + idx) as u32, data)) + } else { + self.parent_generics.as_ref().and_then(|g| g.find_param(param)) } - self.parent_generics.as_ref().unwrap().find_param(param) } } -- cgit v1.2.3