diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/lower.rs | 34 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 101 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/primitive.rs | 159 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits.rs | 4 |
4 files changed, 60 insertions, 238 deletions
diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 485871e69..2d23890a5 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs | |||
@@ -9,7 +9,7 @@ use std::iter; | |||
9 | use std::sync::Arc; | 9 | use std::sync::Arc; |
10 | 10 | ||
11 | use hir_def::{ | 11 | use hir_def::{ |
12 | builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, | 12 | builtin_type::BuiltinType, |
13 | generics::WherePredicate, | 13 | generics::WherePredicate, |
14 | path::{GenericArg, PathSegment}, | 14 | path::{GenericArg, PathSegment}, |
15 | resolver::{HasResolver, Resolver, TypeNs}, | 15 | resolver::{HasResolver, Resolver, TypeNs}, |
@@ -27,7 +27,7 @@ use super::{ | |||
27 | use crate::{ | 27 | use crate::{ |
28 | db::HirDatabase, | 28 | db::HirDatabase, |
29 | ty::{ | 29 | ty::{ |
30 | primitive::{FloatTy, IntTy, Uncertain}, | 30 | primitive::{FloatTy, IntTy}, |
31 | Adt, | 31 | Adt, |
32 | }, | 32 | }, |
33 | util::make_mut_slice, | 33 | util::make_mut_slice, |
@@ -679,36 +679,6 @@ fn type_for_builtin(def: BuiltinType) -> Ty { | |||
679 | }) | 679 | }) |
680 | } | 680 | } |
681 | 681 | ||
682 | impl From<BuiltinInt> for IntTy { | ||
683 | fn from(t: BuiltinInt) -> Self { | ||
684 | IntTy { signedness: t.signedness, bitness: t.bitness } | ||
685 | } | ||
686 | } | ||
687 | |||
688 | impl From<BuiltinFloat> for FloatTy { | ||
689 | fn from(t: BuiltinFloat) -> Self { | ||
690 | FloatTy { bitness: t.bitness } | ||
691 | } | ||
692 | } | ||
693 | |||
694 | impl From<Option<BuiltinInt>> for Uncertain<IntTy> { | ||
695 | fn from(t: Option<BuiltinInt>) -> Self { | ||
696 | match t { | ||
697 | None => Uncertain::Unknown, | ||
698 | Some(t) => Uncertain::Known(t.into()), | ||
699 | } | ||
700 | } | ||
701 | } | ||
702 | |||
703 | impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | ||
704 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
705 | match t { | ||
706 | None => Uncertain::Unknown, | ||
707 | Some(t) => Uncertain::Known(t.into()), | ||
708 | } | ||
709 | } | ||
710 | } | ||
711 | |||
712 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { | 682 | fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { |
713 | let struct_data = db.struct_data(def.into()); | 683 | let struct_data = db.struct_data(def.into()); |
714 | let fields = struct_data.variant_data.fields(); | 684 | let fields = struct_data.variant_data.fields(); |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 7f0ff2e8c..489fcd64b 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,14 +5,19 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef, | ||
10 | HasModule, ImplId, TraitId, | ||
11 | }; | ||
12 | use ra_db::CrateId; | ||
13 | use ra_prof::profile; | ||
9 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
10 | 15 | ||
11 | use crate::{ | 16 | use crate::{ |
12 | db::HirDatabase, | 17 | db::HirDatabase, |
13 | ty::primitive::{FloatBitness, Uncertain}, | 18 | ty::primitive::{FloatBitness, Uncertain}, |
14 | ty::{Ty, TypeCtor}, | 19 | ty::{Ty, TypeCtor}, |
15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, | 20 | AssocItem, Crate, Function, Mutability, Name, Trait, |
16 | }; | 21 | }; |
17 | 22 | ||
18 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 23 | use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -37,54 +42,58 @@ impl TyFingerprint { | |||
37 | 42 | ||
38 | #[derive(Debug, PartialEq, Eq)] | 43 | #[derive(Debug, PartialEq, Eq)] |
39 | pub struct CrateImplBlocks { | 44 | pub struct CrateImplBlocks { |
40 | impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>, | 45 | impls: FxHashMap<TyFingerprint, Vec<ImplId>>, |
41 | impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>, | 46 | impls_by_trait: FxHashMap<TraitId, Vec<ImplId>>, |
42 | } | 47 | } |
43 | 48 | ||
44 | impl CrateImplBlocks { | 49 | impl CrateImplBlocks { |
45 | pub(crate) fn impls_in_crate_query( | 50 | pub(crate) fn impls_in_crate_query( |
46 | db: &impl HirDatabase, | 51 | db: &impl HirDatabase, |
47 | krate: Crate, | 52 | krate: CrateId, |
48 | ) -> Arc<CrateImplBlocks> { | 53 | ) -> Arc<CrateImplBlocks> { |
49 | let mut crate_impl_blocks = | 54 | let _p = profile("impls_in_crate_query"); |
55 | let mut res = | ||
50 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; | 56 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; |
51 | if let Some(module) = krate.root_module(db) { | 57 | |
52 | crate_impl_blocks.collect_recursive(db, module); | 58 | let crate_def_map = db.crate_def_map(krate); |
59 | for (_module_id, module_data) in crate_def_map.modules.iter() { | ||
60 | for &impl_id in module_data.impls.iter() { | ||
61 | let impl_data = db.impl_data(impl_id); | ||
62 | let resolver = impl_id.resolver(db); | ||
63 | |||
64 | let target_ty = { Ty::from_hir(db, &resolver, &impl_data.target_type) }; | ||
65 | |||
66 | match &impl_data.target_trait { | ||
67 | Some(trait_ref) => { | ||
68 | if let Some(tr) = | ||
69 | TraitRef::from_hir(db, &resolver, &trait_ref, Some(target_ty)) | ||
70 | { | ||
71 | res.impls_by_trait.entry(tr.trait_.id).or_default().push(impl_id); | ||
72 | } | ||
73 | } | ||
74 | None => { | ||
75 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
76 | res.impls.entry(target_ty_fp).or_default().push(impl_id); | ||
77 | } | ||
78 | } | ||
79 | } | ||
80 | } | ||
53 | } | 81 | } |
54 | Arc::new(crate_impl_blocks) | 82 | |
83 | Arc::new(res) | ||
55 | } | 84 | } |
56 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ { | 85 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplId> + '_ { |
57 | let fingerprint = TyFingerprint::for_impl(ty); | 86 | let fingerprint = TyFingerprint::for_impl(ty); |
58 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() | 87 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() |
59 | } | 88 | } |
60 | 89 | ||
61 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ { | 90 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplId> + '_ { |
62 | self.impls_by_trait.get(&tr).into_iter().flatten().copied() | 91 | self.impls_by_trait.get(&tr.id).into_iter().flatten().copied() |
63 | } | 92 | } |
64 | 93 | ||
65 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { | 94 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplId> + 'a { |
66 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() | 95 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() |
67 | } | 96 | } |
68 | |||
69 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { | ||
70 | for impl_block in module.impl_blocks(db) { | ||
71 | let target_ty = impl_block.target_ty(db); | ||
72 | |||
73 | if impl_block.target_trait(db).is_some() { | ||
74 | if let Some(tr) = impl_block.target_trait_ref(db) { | ||
75 | self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); | ||
76 | } | ||
77 | } else { | ||
78 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | ||
79 | self.impls.entry(target_ty_fp).or_default().push(impl_block); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | |||
84 | for child in module.children(db) { | ||
85 | self.collect_recursive(db, child); | ||
86 | } | ||
87 | } | ||
88 | } | 97 | } |
89 | 98 | ||
90 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { | 99 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { |
@@ -279,14 +288,14 @@ fn iterate_inherent_methods<T>( | |||
279 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, | 288 | mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, |
280 | ) -> Option<T> { | 289 | ) -> Option<T> { |
281 | for krate in def_crates(db, krate, &ty.value)? { | 290 | for krate in def_crates(db, krate, &ty.value)? { |
282 | let impls = db.impls_in_crate(krate); | 291 | let impls = db.impls_in_crate(krate.crate_id); |
283 | 292 | ||
284 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 293 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
285 | for item in impl_block.items(db) { | 294 | for &item in db.impl_data(impl_block).items.iter() { |
286 | if !is_valid_candidate(db, name, mode, item) { | 295 | if !is_valid_candidate(db, name, mode, item) { |
287 | continue; | 296 | continue; |
288 | } | 297 | } |
289 | if let Some(result) = callback(&ty.value, item) { | 298 | if let Some(result) = callback(&ty.value, item.into()) { |
290 | return Some(result); | 299 | return Some(result); |
291 | } | 300 | } |
292 | } | 301 | } |
@@ -299,17 +308,17 @@ fn is_valid_candidate( | |||
299 | db: &impl HirDatabase, | 308 | db: &impl HirDatabase, |
300 | name: Option<&Name>, | 309 | name: Option<&Name>, |
301 | mode: LookupMode, | 310 | mode: LookupMode, |
302 | item: AssocItem, | 311 | item: AssocItemId, |
303 | ) -> bool { | 312 | ) -> bool { |
304 | match item { | 313 | match item { |
305 | AssocItem::Function(m) => { | 314 | AssocItemId::FunctionId(m) => { |
306 | let data = db.function_data(m.id); | 315 | let data = db.function_data(m); |
307 | name.map_or(true, |name| data.name == *name) | 316 | name.map_or(true, |name| &data.name == name) |
308 | && (data.has_self_param || mode == LookupMode::Path) | 317 | && (data.has_self_param || mode == LookupMode::Path) |
309 | } | 318 | } |
310 | AssocItem::Const(c) => { | 319 | AssocItemId::ConstId(c) => { |
311 | name.map_or(true, |name| Some(name) == c.name(db).as_ref()) | 320 | let data = db.const_data(c); |
312 | && (mode == LookupMode::Path) | 321 | name.map_or(true, |name| data.name.as_ref() == Some(name)) && (mode == LookupMode::Path) |
313 | } | 322 | } |
314 | _ => false, | 323 | _ => false, |
315 | } | 324 | } |
@@ -344,11 +353,11 @@ impl Ty { | |||
344 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 353 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
345 | ) -> Option<T> { | 354 | ) -> Option<T> { |
346 | for krate in def_crates(db, krate, &self)? { | 355 | for krate in def_crates(db, krate, &self)? { |
347 | let impls = db.impls_in_crate(krate); | 356 | let impls = db.impls_in_crate(krate.crate_id); |
348 | 357 | ||
349 | for impl_block in impls.lookup_impl_blocks(&self) { | 358 | for impl_block in impls.lookup_impl_blocks(&self) { |
350 | for item in impl_block.items(db) { | 359 | for &item in db.impl_data(impl_block).items.iter() { |
351 | if let Some(result) = callback(item) { | 360 | if let Some(result) = callback(item.into()) { |
352 | return Some(result); | 361 | return Some(result); |
353 | } | 362 | } |
354 | } | 363 | } |
diff --git a/crates/ra_hir/src/ty/primitive.rs b/crates/ra_hir/src/ty/primitive.rs index 47789db87..12dc96572 100644 --- a/crates/ra_hir/src/ty/primitive.rs +++ b/crates/ra_hir/src/ty/primitive.rs | |||
@@ -1,160 +1,3 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::fmt; | 3 | pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}; |
4 | |||
5 | pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness}; | ||
6 | |||
7 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
8 | pub enum Uncertain<T> { | ||
9 | Unknown, | ||
10 | Known(T), | ||
11 | } | ||
12 | |||
13 | impl From<IntTy> for Uncertain<IntTy> { | ||
14 | fn from(ty: IntTy) -> Self { | ||
15 | Uncertain::Known(ty) | ||
16 | } | ||
17 | } | ||
18 | |||
19 | impl fmt::Display for Uncertain<IntTy> { | ||
20 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
21 | match *self { | ||
22 | Uncertain::Unknown => write!(f, "{{integer}}"), | ||
23 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
24 | } | ||
25 | } | ||
26 | } | ||
27 | |||
28 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
29 | fn from(ty: FloatTy) -> Self { | ||
30 | Uncertain::Known(ty) | ||
31 | } | ||
32 | } | ||
33 | |||
34 | impl fmt::Display for Uncertain<FloatTy> { | ||
35 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
36 | match *self { | ||
37 | Uncertain::Unknown => write!(f, "{{float}}"), | ||
38 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
39 | } | ||
40 | } | ||
41 | } | ||
42 | |||
43 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | ||
44 | pub struct IntTy { | ||
45 | pub signedness: Signedness, | ||
46 | pub bitness: IntBitness, | ||
47 | } | ||
48 | |||
49 | impl fmt::Debug for IntTy { | ||
50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
51 | fmt::Display::fmt(self, f) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl fmt::Display for IntTy { | ||
56 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
57 | write!(f, "{}", self.ty_to_string()) | ||
58 | } | ||
59 | } | ||
60 | |||
61 | impl IntTy { | ||
62 | pub fn isize() -> IntTy { | ||
63 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } | ||
64 | } | ||
65 | |||
66 | pub fn i8() -> IntTy { | ||
67 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } | ||
68 | } | ||
69 | |||
70 | pub fn i16() -> IntTy { | ||
71 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } | ||
72 | } | ||
73 | |||
74 | pub fn i32() -> IntTy { | ||
75 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } | ||
76 | } | ||
77 | |||
78 | pub fn i64() -> IntTy { | ||
79 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } | ||
80 | } | ||
81 | |||
82 | pub fn i128() -> IntTy { | ||
83 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } | ||
84 | } | ||
85 | |||
86 | pub fn usize() -> IntTy { | ||
87 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } | ||
88 | } | ||
89 | |||
90 | pub fn u8() -> IntTy { | ||
91 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } | ||
92 | } | ||
93 | |||
94 | pub fn u16() -> IntTy { | ||
95 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } | ||
96 | } | ||
97 | |||
98 | pub fn u32() -> IntTy { | ||
99 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } | ||
100 | } | ||
101 | |||
102 | pub fn u64() -> IntTy { | ||
103 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } | ||
104 | } | ||
105 | |||
106 | pub fn u128() -> IntTy { | ||
107 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } | ||
108 | } | ||
109 | |||
110 | pub(crate) fn ty_to_string(self) -> &'static str { | ||
111 | match (self.signedness, self.bitness) { | ||
112 | (Signedness::Signed, IntBitness::Xsize) => "isize", | ||
113 | (Signedness::Signed, IntBitness::X8) => "i8", | ||
114 | (Signedness::Signed, IntBitness::X16) => "i16", | ||
115 | (Signedness::Signed, IntBitness::X32) => "i32", | ||
116 | (Signedness::Signed, IntBitness::X64) => "i64", | ||
117 | (Signedness::Signed, IntBitness::X128) => "i128", | ||
118 | (Signedness::Unsigned, IntBitness::Xsize) => "usize", | ||
119 | (Signedness::Unsigned, IntBitness::X8) => "u8", | ||
120 | (Signedness::Unsigned, IntBitness::X16) => "u16", | ||
121 | (Signedness::Unsigned, IntBitness::X32) => "u32", | ||
122 | (Signedness::Unsigned, IntBitness::X64) => "u64", | ||
123 | (Signedness::Unsigned, IntBitness::X128) => "u128", | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | |||
128 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||
129 | pub struct FloatTy { | ||
130 | pub bitness: FloatBitness, | ||
131 | } | ||
132 | |||
133 | impl fmt::Debug for FloatTy { | ||
134 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
135 | fmt::Display::fmt(self, f) | ||
136 | } | ||
137 | } | ||
138 | |||
139 | impl fmt::Display for FloatTy { | ||
140 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
141 | write!(f, "{}", self.ty_to_string()) | ||
142 | } | ||
143 | } | ||
144 | |||
145 | impl FloatTy { | ||
146 | pub fn f32() -> FloatTy { | ||
147 | FloatTy { bitness: FloatBitness::X32 } | ||
148 | } | ||
149 | |||
150 | pub fn f64() -> FloatTy { | ||
151 | FloatTy { bitness: FloatBitness::X64 } | ||
152 | } | ||
153 | |||
154 | pub(crate) fn ty_to_string(self) -> &'static str { | ||
155 | match self.bitness { | ||
156 | FloatBitness::X32 => "f32", | ||
157 | FloatBitness::X64 => "f64", | ||
158 | } | ||
159 | } | ||
160 | } | ||
diff --git a/crates/ra_hir/src/ty/traits.rs b/crates/ra_hir/src/ty/traits.rs index b9a5d651f..2eeb03099 100644 --- a/crates/ra_hir/src/ty/traits.rs +++ b/crates/ra_hir/src/ty/traits.rs | |||
@@ -88,8 +88,8 @@ pub(crate) fn impls_for_trait_query( | |||
88 | for dep in krate.dependencies(db) { | 88 | for dep in krate.dependencies(db) { |
89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); | 89 | impls.extend(db.impls_for_trait(dep.krate, trait_).iter()); |
90 | } | 90 | } |
91 | let crate_impl_blocks = db.impls_in_crate(krate); | 91 | let crate_impl_blocks = db.impls_in_crate(krate.crate_id); |
92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_)); | 92 | impls.extend(crate_impl_blocks.lookup_impl_blocks_for_trait(trait_).map(ImplBlock::from)); |
93 | impls.into_iter().collect() | 93 | impls.into_iter().collect() |
94 | } | 94 | } |
95 | 95 | ||