aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r--crates/ra_hir_ty/src/lower.rs40
1 files changed, 32 insertions, 8 deletions
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index c68c5852b..6a2aded02 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -14,9 +14,9 @@ use hir_def::{
14 path::{GenericArg, Path, PathSegment, PathSegments}, 14 path::{GenericArg, Path, PathSegment, PathSegments},
15 resolver::{HasResolver, Resolver, TypeNs}, 15 resolver::{HasResolver, Resolver, TypeNs},
16 type_ref::{TypeBound, TypeRef}, 16 type_ref::{TypeBound, TypeRef},
17 AdtId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, 17 AdtId, AssocContainerId, ConstId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule,
18 LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId, 18 ImplId, LocalStructFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
19 VariantId, 19 UnionId, VariantId,
20}; 20};
21use ra_arena::map::ArenaMap; 21use ra_arena::map::ArenaMap;
22use ra_db::CrateId; 22use ra_db::CrateId;
@@ -152,7 +152,7 @@ impl Ty {
152 data.provenance == TypeParamProvenance::ArgumentImplTrait 152 data.provenance == TypeParamProvenance::ArgumentImplTrait
153 }) 153 })
154 .nth(idx as usize) 154 .nth(idx as usize)
155 .map_or(Ty::Unknown, |(id, _)| Ty::Param(id)); 155 .map_or(Ty::Unknown, |(id, _)| Ty::Placeholder(id));
156 param 156 param
157 } else { 157 } else {
158 Ty::Unknown 158 Ty::Unknown
@@ -270,7 +270,7 @@ impl Ty {
270 let generics = 270 let generics =
271 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope")); 271 generics(ctx.db, ctx.resolver.generic_def().expect("generics in scope"));
272 match ctx.type_param_mode { 272 match ctx.type_param_mode {
273 TypeParamLoweringMode::Placeholder => Ty::Param(param_id), 273 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
274 TypeParamLoweringMode::Variable => { 274 TypeParamLoweringMode::Variable => {
275 let idx = generics.param_idx(param_id).expect("matching generics"); 275 let idx = generics.param_idx(param_id).expect("matching generics");
276 Ty::Bound(idx) 276 Ty::Bound(idx)
@@ -339,7 +339,7 @@ impl Ty {
339 None => return Ty::Unknown, // this can't actually happen 339 None => return Ty::Unknown, // this can't actually happen
340 }; 340 };
341 let param_id = match self_ty { 341 let param_id = match self_ty {
342 Ty::Param(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id, 342 Ty::Placeholder(id) if ctx.type_param_mode == TypeParamLoweringMode::Placeholder => id,
343 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => { 343 Ty::Bound(idx) if ctx.type_param_mode == TypeParamLoweringMode::Variable => {
344 let generics = generics(ctx.db, def); 344 let generics = generics(ctx.db, def);
345 let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) { 345 let param_id = if let Some((id, _)) = generics.iter().nth(idx as usize) {
@@ -544,7 +544,7 @@ impl GenericPredicate {
544 let generics = generics(ctx.db, generic_def); 544 let generics = generics(ctx.db, generic_def);
545 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 };
546 match ctx.type_param_mode { 546 match ctx.type_param_mode {
547 TypeParamLoweringMode::Placeholder => Ty::Param(param_id), 547 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
548 TypeParamLoweringMode::Variable => { 548 TypeParamLoweringMode::Variable => {
549 let idx = generics.param_idx(param_id).expect("matching generics"); 549 let idx = generics.param_idx(param_id).expect("matching generics");
550 Ty::Bound(idx) 550 Ty::Bound(idx)
@@ -672,11 +672,35 @@ impl TraitEnvironment {
672 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 672 pub fn lower(db: &impl HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> {
673 let ctx = TyLoweringContext::new(db, &resolver) 673 let ctx = TyLoweringContext::new(db, &resolver)
674 .with_type_param_mode(TypeParamLoweringMode::Placeholder); 674 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
675 let predicates = resolver 675 let mut predicates = resolver
676 .where_predicates_in_scope() 676 .where_predicates_in_scope()
677 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred)) 677 .flat_map(|pred| GenericPredicate::from_where_predicate(&ctx, pred))
678 .collect::<Vec<_>>(); 678 .collect::<Vec<_>>();
679 679
680 if let Some(def) = resolver.generic_def() {
681 let container: Option<AssocContainerId> = match def {
682 // FIXME: is there a function for this?
683 GenericDefId::FunctionId(f) => Some(f.lookup(db).container),
684 GenericDefId::AdtId(_) => None,
685 GenericDefId::TraitId(_) => None,
686 GenericDefId::TypeAliasId(t) => Some(t.lookup(db).container),
687 GenericDefId::ImplId(_) => None,
688 GenericDefId::EnumVariantId(_) => None,
689 GenericDefId::ConstId(c) => Some(c.lookup(db).container),
690 };
691 if let Some(AssocContainerId::TraitId(trait_id)) = container {
692 // add `Self: Trait<T1, T2, ...>` to the environment in trait
693 // function default implementations (and hypothetical code
694 // inside consts or type aliases)
695 test_utils::tested_by!(trait_self_implements_self);
696 let substs = Substs::type_params(db, trait_id);
697 let trait_ref = TraitRef { trait_: trait_id, substs };
698 let pred = GenericPredicate::Implemented(trait_ref);
699
700 predicates.push(pred);
701 }
702 }
703
680 Arc::new(TraitEnvironment { predicates }) 704 Arc::new(TraitEnvironment { predicates })
681 } 705 }
682} 706}