diff options
author | Aleksey Kladov <[email protected]> | 2019-11-21 09:21:46 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-21 10:25:03 +0000 |
commit | 0102fb41337ac0442e689d410bb424d215e9a7bd (patch) | |
tree | c77bf501427adc77c0fc92fe75fd9f314087b120 /crates/ra_hir/src/ty | |
parent | 612a72fc4ea4376920f2a7da7b3c334227c1716c (diff) |
Decouple Resolver
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 23 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/infer/path.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 4 |
4 files changed, 35 insertions, 27 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7f9e81d64..684d66946 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -24,6 +24,7 @@ use rustc_hash::FxHashMap; | |||
24 | use hir_def::{ | 24 | use hir_def::{ |
25 | path::known, | 25 | path::known, |
26 | type_ref::{Mutability, TypeRef}, | 26 | type_ref::{Mutability, TypeRef}, |
27 | AdtId, | ||
27 | }; | 28 | }; |
28 | use hir_expand::{diagnostics::DiagnosticSink, name}; | 29 | use hir_expand::{diagnostics::DiagnosticSink, name}; |
29 | use ra_arena::map::ArenaMap; | 30 | use ra_arena::map::ArenaMap; |
@@ -43,7 +44,7 @@ use crate::{ | |||
43 | resolve::{HasResolver, Resolver, TypeNs}, | 44 | resolve::{HasResolver, Resolver, TypeNs}, |
44 | ty::infer::diagnostics::InferenceDiagnostic, | 45 | ty::infer::diagnostics::InferenceDiagnostic, |
45 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, | 46 | Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, |
46 | StructField, VariantDef, | 47 | StructField, Trait, VariantDef, |
47 | }; | 48 | }; |
48 | 49 | ||
49 | macro_rules! ty_app { | 50 | macro_rules! ty_app { |
@@ -518,17 +519,17 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
518 | // FIXME: this should resolve assoc items as well, see this example: | 519 | // FIXME: this should resolve assoc items as well, see this example: |
519 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 | 520 | // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 |
520 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { | 521 | match resolver.resolve_path_in_type_ns_fully(self.db, &path) { |
521 | Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), | 522 | Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), |
522 | Some(TypeNs::Adt(Adt::Union(it))) => it.into(), | 523 | Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), |
523 | Some(TypeNs::AdtSelfType(adt)) => adt.into(), | 524 | Some(TypeNs::AdtSelfType(adt)) => adt.into(), |
524 | Some(TypeNs::EnumVariant(it)) => it.into(), | 525 | Some(TypeNs::EnumVariantId(it)) => it.into(), |
525 | Some(TypeNs::TypeAlias(it)) => it.into(), | 526 | Some(TypeNs::TypeAliasId(it)) => it.into(), |
526 | 527 | ||
527 | Some(TypeNs::SelfType(_)) | | 528 | Some(TypeNs::SelfType(_)) | |
528 | Some(TypeNs::GenericParam(_)) | | 529 | Some(TypeNs::GenericParam(_)) | |
529 | Some(TypeNs::BuiltinType(_)) | | 530 | Some(TypeNs::BuiltinType(_)) | |
530 | Some(TypeNs::Trait(_)) | | 531 | Some(TypeNs::TraitId(_)) | |
531 | Some(TypeNs::Adt(Adt::Enum(_))) | | 532 | Some(TypeNs::AdtId(AdtId::EnumId(_))) | |
532 | None => { | 533 | None => { |
533 | return (Ty::Unknown, None) | 534 | return (Ty::Unknown, None) |
534 | } | 535 | } |
@@ -576,26 +577,26 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
576 | 577 | ||
577 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { | 578 | fn resolve_into_iter_item(&self) -> Option<TypeAlias> { |
578 | let path = known::std_iter_into_iterator(); | 579 | let path = known::std_iter_into_iterator(); |
579 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 580 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
580 | trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) | 581 | trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) |
581 | } | 582 | } |
582 | 583 | ||
583 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { | 584 | fn resolve_ops_try_ok(&self) -> Option<TypeAlias> { |
584 | let path = known::std_ops_try(); | 585 | let path = known::std_ops_try(); |
585 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 586 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
586 | trait_.associated_type_by_name(self.db, &name::OK_TYPE) | 587 | trait_.associated_type_by_name(self.db, &name::OK_TYPE) |
587 | } | 588 | } |
588 | 589 | ||
589 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { | 590 | fn resolve_future_future_output(&self) -> Option<TypeAlias> { |
590 | let path = known::std_future_future(); | 591 | let path = known::std_future_future(); |
591 | let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; | 592 | let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); |
592 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) | 593 | trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) |
593 | } | 594 | } |
594 | 595 | ||
595 | fn resolve_boxed_box(&self) -> Option<Adt> { | 596 | fn resolve_boxed_box(&self) -> Option<Adt> { |
596 | let path = known::std_boxed_box(); | 597 | let path = known::std_boxed_box(); |
597 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; | 598 | let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; |
598 | Some(Adt::Struct(struct_)) | 599 | Some(Adt::Struct(struct_.into())) |
599 | } | 600 | } |
600 | } | 601 | } |
601 | 602 | ||
diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 31ca675aa..f36a27929 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs | |||
@@ -94,13 +94,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
94 | let is_before_last = remaining_segments.len() == 1; | 94 | let is_before_last = remaining_segments.len() == 1; |
95 | 95 | ||
96 | match (def, is_before_last) { | 96 | match (def, is_before_last) { |
97 | (TypeNs::Trait(trait_), true) => { | 97 | (TypeNs::TraitId(trait_), true) => { |
98 | let segment = | 98 | let segment = |
99 | remaining_segments.last().expect("there should be at least one segment here"); | 99 | remaining_segments.last().expect("there should be at least one segment here"); |
100 | let trait_ref = TraitRef::from_resolved_path( | 100 | let trait_ref = TraitRef::from_resolved_path( |
101 | self.db, | 101 | self.db, |
102 | &self.resolver, | 102 | &self.resolver, |
103 | trait_, | 103 | trait_.into(), |
104 | resolved_segment, | 104 | resolved_segment, |
105 | None, | 105 | None, |
106 | ); | 106 | ); |
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 397ee7d5f..d4fbddac0 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -28,8 +28,8 @@ use crate::{ | |||
28 | Adt, | 28 | Adt, |
29 | }, | 29 | }, |
30 | util::make_mut_slice, | 30 | util::make_mut_slice, |
31 | Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, | 31 | Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, |
32 | TypeAlias, Union, VariantDef, | 32 | Trait, TypeAlias, Union, VariantDef, |
33 | }; | 33 | }; |
34 | 34 | ||
35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of | 35 | // FIXME: this is only really used in `type_for_def`, which contains a bunch of |
@@ -156,9 +156,14 @@ impl Ty { | |||
156 | remaining_segments: &[PathSegment], | 156 | remaining_segments: &[PathSegment], |
157 | ) -> Ty { | 157 | ) -> Ty { |
158 | let ty = match resolution { | 158 | let ty = match resolution { |
159 | TypeNs::Trait(trait_) => { | 159 | TypeNs::TraitId(trait_) => { |
160 | let trait_ref = | 160 | let trait_ref = TraitRef::from_resolved_path( |
161 | TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); | 161 | db, |
162 | resolver, | ||
163 | trait_.into(), | ||
164 | resolved_segment, | ||
165 | None, | ||
166 | ); | ||
162 | return if remaining_segments.len() == 1 { | 167 | return if remaining_segments.len() == 1 { |
163 | let segment = &remaining_segments[0]; | 168 | let segment = &remaining_segments[0]; |
164 | match trait_ref | 169 | match trait_ref |
@@ -189,18 +194,18 @@ impl Ty { | |||
189 | let name = resolved_segment.name.clone(); | 194 | let name = resolved_segment.name.clone(); |
190 | Ty::Param { idx, name } | 195 | Ty::Param { idx, name } |
191 | } | 196 | } |
192 | TypeNs::SelfType(impl_block) => impl_block.target_ty(db), | 197 | TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), |
193 | TypeNs::AdtSelfType(adt) => adt.ty(db), | 198 | TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db), |
194 | 199 | ||
195 | TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), | 200 | TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), |
196 | TypeNs::BuiltinType(it) => { | 201 | TypeNs::BuiltinType(it) => { |
197 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | 202 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) |
198 | } | 203 | } |
199 | TypeNs::TypeAlias(it) => { | 204 | TypeNs::TypeAliasId(it) => { |
200 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) | 205 | Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) |
201 | } | 206 | } |
202 | // FIXME: report error | 207 | // FIXME: report error |
203 | TypeNs::EnumVariant(_) => return Ty::Unknown, | 208 | TypeNs::EnumVariantId(_) => return Ty::Unknown, |
204 | }; | 209 | }; |
205 | 210 | ||
206 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) | 211 | Ty::from_type_relative_path(db, resolver, ty, remaining_segments) |
@@ -247,7 +252,7 @@ impl Ty { | |||
247 | Some(def) => def, | 252 | Some(def) => def, |
248 | None => return Ty::Unknown, // this can't actually happen | 253 | None => return Ty::Unknown, // this can't actually happen |
249 | }; | 254 | }; |
250 | let predicates = db.generic_predicates_for_param(def, param_idx); | 255 | let predicates = db.generic_predicates_for_param(def.into(), param_idx); |
251 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { | 256 | let traits_from_env = predicates.iter().filter_map(|pred| match pred { |
252 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), | 257 | GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), |
253 | _ => None, | 258 | _ => None, |
@@ -391,11 +396,11 @@ impl TraitRef { | |||
391 | explicit_self_ty: Option<Ty>, | 396 | explicit_self_ty: Option<Ty>, |
392 | ) -> Option<Self> { | 397 | ) -> Option<Self> { |
393 | let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { | 398 | let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { |
394 | TypeNs::Trait(tr) => tr, | 399 | TypeNs::TraitId(tr) => tr, |
395 | _ => return None, | 400 | _ => return None, |
396 | }; | 401 | }; |
397 | let segment = path.segments.last().expect("path should have at least one segment"); | 402 | let segment = path.segments.last().expect("path should have at least one segment"); |
398 | Some(TraitRef::from_resolved_path(db, resolver, resolved, segment, explicit_self_ty)) | 403 | Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) |
399 | } | 404 | } |
400 | 405 | ||
401 | pub(super) fn from_resolved_path( | 406 | pub(super) fn from_resolved_path( |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index f377fca48..26dd06171 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -224,7 +224,9 @@ fn iterate_trait_method_candidates<T>( | |||
224 | .trait_predicates_for_self_ty(&ty.value) | 224 | .trait_predicates_for_self_ty(&ty.value) |
225 | .map(|tr| tr.trait_) | 225 | .map(|tr| tr.trait_) |
226 | .flat_map(|t| t.all_super_traits(db)); | 226 | .flat_map(|t| t.all_super_traits(db)); |
227 | let traits = inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db)); | 227 | let traits = inherent_trait |
228 | .chain(traits_from_env) | ||
229 | .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); | ||
228 | 'traits: for t in traits { | 230 | 'traits: for t in traits { |
229 | let data = t.trait_data(db); | 231 | let data = t.trait_data(db); |
230 | 232 | ||