diff options
Diffstat (limited to 'crates/ra_hir_ty/src/lower.rs')
-rw-r--r-- | crates/ra_hir_ty/src/lower.rs | 40 |
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 | }; |
21 | use ra_arena::map::ArenaMap; | 21 | use ra_arena::map::ArenaMap; |
22 | use ra_db::CrateId; | 22 | use 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 | } |