aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lower.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2020-01-31 15:52:43 +0000
committerFlorian Diebold <[email protected]>2020-02-07 17:28:10 +0000
commited25cf70d5e0df9c7a33deb503ea14c2d97bd7a7 (patch)
treebc6e8620244d64beed8f1a9ce9059e5dfd2a0fbe /crates/ra_hir_ty/src/lower.rs
parentf8b7b64bce772f21124b4790538ca97418cc23ca (diff)
Change Ty::Param to contain param ID
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r--crates/ra_hir_ty/src/lower.rs108
1 files changed, 59 insertions, 49 deletions
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::{
30 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs, 30 Binders, FnSig, GenericPredicate, PolyFnSig, ProjectionPredicate, ProjectionTy, Substs,
31 TraitEnvironment, TraitRef, Ty, TypeCtor, 31 TraitEnvironment, TraitRef, Ty, TypeCtor,
32}; 32};
33use hir_expand::name::Name; 33use hir_def::TypeParamId;
34 34
35#[derive(Debug)] 35#[derive(Debug)]
36pub struct TyLoweringContext<'a, DB: HirDatabase> { 36pub struct TyLoweringContext<'a, DB: HirDatabase> {
@@ -145,7 +145,16 @@ impl Ty {
145 ImplTraitLoweringMode::Param => { 145 ImplTraitLoweringMode::Param => {
146 let idx = ctx.impl_trait_counter.get(); 146 let idx = ctx.impl_trait_counter.get();
147 ctx.impl_trait_counter.set(idx + 1); 147 ctx.impl_trait_counter.set(idx + 1);
148 Ty::Param { idx: idx as u32, name: Name::missing() } 148 if let Some(def) = ctx.resolver.generic_def() {
149 let generics = generics(ctx.db, def);
150 let param = generics
151 .iter()
152 .nth(idx as usize)
153 .map_or(Ty::Unknown, |(id, _)| Ty::Param(id));
154 param
155 } else {
156 Ty::Unknown
157 }
149 } 158 }
150 ImplTraitLoweringMode::Variable => { 159 ImplTraitLoweringMode::Variable => {
151 let idx = ctx.impl_trait_counter.get(); 160 let idx = ctx.impl_trait_counter.get();
@@ -176,7 +185,7 @@ impl Ty {
176 fn from_hir_only_param( 185 fn from_hir_only_param(
177 ctx: &TyLoweringContext<'_, impl HirDatabase>, 186 ctx: &TyLoweringContext<'_, impl HirDatabase>,
178 type_ref: &TypeRef, 187 type_ref: &TypeRef,
179 ) -> Option<u32> { 188 ) -> Option<TypeParamId> {
180 let path = match type_ref { 189 let path = match type_ref {
181 TypeRef::Path(path) => path, 190 TypeRef::Path(path) => path,
182 _ => return None, 191 _ => return None,
@@ -192,9 +201,7 @@ impl Ty {
192 _ => return None, 201 _ => return None,
193 }; 202 };
194 if let TypeNs::GenericParam(param_id) = resolution { 203 if let TypeNs::GenericParam(param_id) = resolution {
195 let generics = generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); 204 Some(param_id)
196 let idx = generics.param_idx(param_id);
197 Some(idx)
198 } else { 205 } else {
199 None 206 None
200 } 207 }
@@ -256,20 +263,18 @@ impl Ty {
256 TypeNs::GenericParam(param_id) => { 263 TypeNs::GenericParam(param_id) => {
257 let generics = 264 let generics =
258 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); 265 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
259 let idx = generics.param_idx(param_id);
260 match ctx.type_param_mode { 266 match ctx.type_param_mode {
261 TypeParamLoweringMode::Placeholder => { 267 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
262 // FIXME: maybe return name in resolution? 268 TypeParamLoweringMode::Variable => {
263 let name = generics.param_name(param_id); 269 let idx = generics.param_idx(param_id).expect("matching generics");
264 Ty::Param { idx, name } 270 Ty::Bound(idx)
265 } 271 }
266 TypeParamLoweringMode::Variable => Ty::Bound(idx),
267 } 272 }
268 } 273 }
269 TypeNs::SelfType(impl_id) => { 274 TypeNs::SelfType(impl_id) => {
270 let generics = generics(ctx.db, impl_id.into()); 275 let generics = generics(ctx.db, impl_id.into());
271 let substs = match ctx.type_param_mode { 276 let substs = match ctx.type_param_mode {
272 TypeParamLoweringMode::Placeholder => Substs::identity(&generics), 277 TypeParamLoweringMode::Placeholder => Substs::type_params(&generics),
273 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), 278 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
274 }; 279 };
275 ctx.db.impl_self_ty(impl_id).subst(&substs) 280 ctx.db.impl_self_ty(impl_id).subst(&substs)
@@ -277,7 +282,7 @@ impl Ty {
277 TypeNs::AdtSelfType(adt) => { 282 TypeNs::AdtSelfType(adt) => {
278 let generics = generics(ctx.db, adt.into()); 283 let generics = generics(ctx.db, adt.into());
279 let substs = match ctx.type_param_mode { 284 let substs = match ctx.type_param_mode {
280 TypeParamLoweringMode::Placeholder => Substs::identity(&generics), 285 TypeParamLoweringMode::Placeholder => Substs::type_params(&generics),
281 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics), 286 TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
282 }; 287 };
283 ctx.db.ty(adt.into()).subst(&substs) 288 ctx.db.ty(adt.into()).subst(&substs)
@@ -319,20 +324,28 @@ impl Ty {
319 self_ty: Ty, 324 self_ty: Ty,
320 segment: PathSegment<'_>, 325 segment: PathSegment<'_>,
321 ) -> Ty { 326 ) -> Ty {
322 let param_idx = match self_ty {
323 Ty::Param { idx, .. } if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => idx,
324 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => idx,
325 _ => return Ty::Unknown, // Error: Ambiguous associated type
326 };
327 let def = match ctx.resolver.generic_def() { 327 let def = match ctx.resolver.generic_def() {
328 Some(def) => def, 328 Some(def) => def,
329 None => return Ty::Unknown, // this can't actually happen 329 None => return Ty::Unknown, // this can't actually happen
330 }; 330 };
331 let predicates = ctx.db.generic_predicates_for_param(def.into(), param_idx); 331 let param_id = match self_ty {
332 Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id,
333 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => {
334 let generics = generics(ctx.db, def);
335 let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) {
336 id
337 } else {
338 return Ty::Unknown;
339 };
340 param_id
341 },
342 _ => return Ty::Unknown, // Error: Ambiguous associated type
343 };
344 let predicates = ctx.db.generic_predicates_for_param(param_id);
332 let traits_from_env = predicates.iter().filter_map(|pred| match pred { 345 let traits_from_env = predicates.iter().filter_map(|pred| match pred {
333 GenericPredicate::Implemented(tr) => { 346 GenericPredicate::Implemented(tr) => {
334 if let Ty::Param { idx, .. } = tr.self_ty() { 347 if let Ty::Param(id) = tr.self_ty() {
335 if *idx == param_idx { 348 if *id == param_id {
336 return Some(tr.trait_); 349 return Some(tr.trait_);
337 } 350 }
338 } 351 }
@@ -530,13 +543,12 @@ impl GenericPredicate {
530 let generic_def = ctx.resolver.generic_def().expect("generics in scope"); 543 let generic_def = ctx.resolver.generic_def().expect("generics in scope");
531 let generics = generics(ctx.db, generic_def); 544 let generics = generics(ctx.db, generic_def);
532 let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; 545 let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
533 let idx = generics.param_idx(param_id);
534 match ctx.type_param_mode { 546 match ctx.type_param_mode {
535 TypeParamLoweringMode::Placeholder => { 547 TypeParamLoweringMode::Placeholder => Ty::Param(param_id),
536 let name = generics.param_name(param_id); 548 TypeParamLoweringMode::Variable => {
537 Ty::Param { idx, name } 549 let idx = generics.param_idx(param_id).expect("matching generics");
550 Ty::Bound(idx)
538 } 551 }
539 TypeParamLoweringMode::Variable => Ty::Bound(idx),
540 } 552 }
541 } 553 }
542 }; 554 };
@@ -599,17 +611,19 @@ pub fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> PolyFnSig {
599pub(crate) fn field_types_query( 611pub(crate) fn field_types_query(
600 db: &impl HirDatabase, 612 db: &impl HirDatabase,
601 variant_id: VariantId, 613 variant_id: VariantId,
602) -> Arc<ArenaMap<LocalStructFieldId, Ty>> { 614) -> Arc<ArenaMap<LocalStructFieldId, Binders<Ty>>> {
603 let var_data = variant_data(db, variant_id); 615 let var_data = variant_data(db, variant_id);
604 let resolver = match variant_id { 616 let (resolver, def): (_, GenericDefId) = match variant_id {
605 VariantId::StructId(it) => it.resolver(db), 617 VariantId::StructId(it) => (it.resolver(db), it.into()),
606 VariantId::UnionId(it) => it.resolver(db), 618 VariantId::UnionId(it) => (it.resolver(db), it.into()),
607 VariantId::EnumVariantId(it) => it.parent.resolver(db), 619 VariantId::EnumVariantId(it) => (it.parent.resolver(db), it.parent.into()),
608 }; 620 };
621 let generics = generics(db, def);
609 let mut res = ArenaMap::default(); 622 let mut res = ArenaMap::default();
610 let ctx = TyLoweringContext::new(db, &resolver); 623 let ctx = TyLoweringContext::new(db, &resolver)
624 .with_type_param_mode(TypeParamLoweringMode::Variable);
611 for (field_id, field_data) in var_data.fields().iter() { 625 for (field_id, field_data) in var_data.fields().iter() {
612 res.insert(field_id, Ty::from_hir(&ctx, &field_data.type_ref)) 626 res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref)))
613 } 627 }
614 Arc::new(res) 628 Arc::new(res)
615} 629}
@@ -624,23 +638,20 @@ pub(crate) fn field_types_query(
624/// these are fine: `T: Foo<U::Item>, U: Foo<()>`. 638/// these are fine: `T: Foo<U::Item>, U: Foo<()>`.
625pub(crate) fn generic_predicates_for_param_query( 639pub(crate) fn generic_predicates_for_param_query(
626 db: &impl HirDatabase, 640 db: &impl HirDatabase,
627 def: GenericDefId, 641 param_id: TypeParamId,
628 param_idx: u32,
629) -> Arc<[GenericPredicate]> { 642) -> Arc<[GenericPredicate]> {
630 let resolver = def.resolver(db); 643 let resolver = param_id.parent.resolver(db);
631 let ctx = TyLoweringContext::new(db, &resolver); 644 let ctx = TyLoweringContext::new(db, &resolver);
632 let generics = generics(db, def); 645 // let generics = generics(db, def);
633 resolver 646 resolver
634 .where_predicates_in_scope() 647 .where_predicates_in_scope()
635 // we have to filter out all other predicates *first*, before attempting to lower them 648 // we have to filter out all other predicates *first*, before attempting to lower them
636 .filter(|pred| match &pred.target { 649 .filter(|pred| match &pred.target {
637 WherePredicateTarget::TypeRef(type_ref) => { 650 WherePredicateTarget::TypeRef(type_ref) => {
638 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_idx) 651 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
639 } 652 }
640 WherePredicateTarget::TypeParam(local_id) => { 653 WherePredicateTarget::TypeParam(local_id) => {
641 let param_id = hir_def::TypeParamId { parent: def, local_id: *local_id }; 654 *local_id == param_id.local_id
642 let idx = generics.param_idx(param_id);
643 idx == param_idx
644 } 655 }
645 }) 656 })
646 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 657 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
@@ -650,8 +661,7 @@ pub(crate) fn generic_predicates_for_param_query(
650pub(crate) fn generic_predicates_for_param_recover( 661pub(crate) fn generic_predicates_for_param_recover(
651 _db: &impl HirDatabase, 662 _db: &impl HirDatabase,
652 _cycle: &[String], 663 _cycle: &[String],
653 _def: &GenericDefId, 664 _param_id: &TypeParamId,
654 _param_idx: &u32,
655) -> Arc<[GenericPredicate]> { 665) -> Arc<[GenericPredicate]> {
656 Arc::new([]) 666 Arc::new([])
657} 667}
@@ -905,12 +915,12 @@ pub(crate) fn impl_self_ty_recover(
905 Binders::new(generics.len(), Ty::Unknown) 915 Binders::new(generics.len(), Ty::Unknown)
906} 916}
907 917
908pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<TraitRef> { 918pub(crate) fn impl_trait_query(db: &impl HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
909 let impl_data = db.impl_data(impl_id); 919 let impl_data = db.impl_data(impl_id);
910 let resolver = impl_id.resolver(db); 920 let resolver = impl_id.resolver(db);
911 let generics = generics(db, impl_id.into()); 921 let ctx = TyLoweringContext::new(db, &resolver)
912 let ctx = TyLoweringContext::new(db, &resolver); 922 .with_type_param_mode(TypeParamLoweringMode::Variable);
913 let self_ty = db.impl_self_ty(impl_id).subst(&Substs::identity(&generics)); 923 let self_ty = db.impl_self_ty(impl_id);
914 let target_trait = impl_data.target_trait.as_ref()?; 924 let target_trait = impl_data.target_trait.as_ref()?;
915 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.clone())) 925 Some(Binders::new(self_ty.num_binders, TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value.clone()))?))
916} 926}