diff options
-rw-r--r-- | Cargo.lock | 23 | ||||
-rw-r--r-- | crates/ra_hir/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-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 | ||||
-rw-r--r-- | crates/ra_hir_ty/Cargo.toml | 32 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/primitive.rs | 193 | ||||
-rw-r--r-- | crates/ra_ide_api/src/impls.rs | 10 |
12 files changed, 329 insertions, 245 deletions
diff --git a/Cargo.lock b/Cargo.lock index 12da410d0..5c87cf8e5 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -995,6 +995,7 @@ dependencies = [ | |||
995 | "ra_db 0.1.0", | 995 | "ra_db 0.1.0", |
996 | "ra_hir_def 0.1.0", | 996 | "ra_hir_def 0.1.0", |
997 | "ra_hir_expand 0.1.0", | 997 | "ra_hir_expand 0.1.0", |
998 | "ra_hir_ty 0.1.0", | ||
998 | "ra_mbe 0.1.0", | 999 | "ra_mbe 0.1.0", |
999 | "ra_prof 0.1.0", | 1000 | "ra_prof 0.1.0", |
1000 | "ra_syntax 0.1.0", | 1001 | "ra_syntax 0.1.0", |
@@ -1037,6 +1038,28 @@ dependencies = [ | |||
1037 | ] | 1038 | ] |
1038 | 1039 | ||
1039 | [[package]] | 1040 | [[package]] |
1041 | name = "ra_hir_ty" | ||
1042 | version = "0.1.0" | ||
1043 | dependencies = [ | ||
1044 | "chalk-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", | ||
1045 | "chalk-rust-ir 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", | ||
1046 | "chalk-solve 0.1.0 (git+https://github.com/jackh726/chalk.git?rev=095cd38a4f16337913bba487f2055b9ca0179f30)", | ||
1047 | "ena 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1048 | "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1049 | "lalrpop-intern 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1050 | "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1051 | "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1052 | "ra_arena 0.1.0", | ||
1053 | "ra_db 0.1.0", | ||
1054 | "ra_hir_def 0.1.0", | ||
1055 | "ra_hir_expand 0.1.0", | ||
1056 | "ra_prof 0.1.0", | ||
1057 | "ra_syntax 0.1.0", | ||
1058 | "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||
1059 | "test_utils 0.1.0", | ||
1060 | ] | ||
1061 | |||
1062 | [[package]] | ||
1040 | name = "ra_ide_api" | 1063 | name = "ra_ide_api" |
1041 | version = "0.1.0" | 1064 | version = "0.1.0" |
1042 | dependencies = [ | 1065 | dependencies = [ |
diff --git a/crates/ra_hir/Cargo.toml b/crates/ra_hir/Cargo.toml index 16bd4bafc..caba85a4f 100644 --- a/crates/ra_hir/Cargo.toml +++ b/crates/ra_hir/Cargo.toml | |||
@@ -23,6 +23,7 @@ mbe = { path = "../ra_mbe", package = "ra_mbe" } | |||
23 | tt = { path = "../ra_tt", package = "ra_tt" } | 23 | tt = { path = "../ra_tt", package = "ra_tt" } |
24 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | 24 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } |
25 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | 25 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } |
26 | hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" } | ||
26 | test_utils = { path = "../test_utils" } | 27 | test_utils = { path = "../test_utils" } |
27 | ra_prof = { path = "../ra_prof" } | 28 | ra_prof = { path = "../ra_prof" } |
28 | 29 | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index bb1596bed..821f919d4 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -997,6 +997,15 @@ pub struct ImplBlock { | |||
997 | } | 997 | } |
998 | 998 | ||
999 | impl ImplBlock { | 999 | impl ImplBlock { |
1000 | pub fn all_in_crate(db: &impl HirDatabase, krate: Crate) -> Vec<ImplBlock> { | ||
1001 | let impls = db.impls_in_crate(krate.crate_id); | ||
1002 | impls.all_impls().map(Self::from).collect() | ||
1003 | } | ||
1004 | pub fn for_trait(db: &impl HirDatabase, krate: Crate, trait_: Trait) -> Vec<ImplBlock> { | ||
1005 | let impls = db.impls_in_crate(krate.crate_id); | ||
1006 | impls.lookup_impl_blocks_for_trait(trait_).map(Self::from).collect() | ||
1007 | } | ||
1008 | |||
1000 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { | 1009 | pub fn target_trait(&self, db: &impl DefDatabase) -> Option<TypeRef> { |
1001 | db.impl_data(self.id).target_trait.clone() | 1010 | db.impl_data(self.id).target_trait.clone() |
1002 | } | 1011 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index b034d4e44..32f05a4d8 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_arena::map::ArenaMap; | 5 | use ra_arena::map::ArenaMap; |
6 | use ra_db::salsa; | 6 | use ra_db::{salsa, CrateId}; |
7 | 7 | ||
8 | use crate::{ | 8 | use crate::{ |
9 | ty::{ | 9 | ty::{ |
@@ -60,7 +60,7 @@ pub trait HirDatabase: DefDatabase { | |||
60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; | 60 | fn generic_defaults(&self, def: GenericDefId) -> Substs; |
61 | 61 | ||
62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 62 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
63 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 63 | fn impls_in_crate(&self, krate: CrateId) -> Arc<CrateImplBlocks>; |
64 | 64 | ||
65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] | 65 | #[salsa::invoke(crate::ty::traits::impls_for_trait_query)] |
66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; | 66 | fn impls_for_trait(&self, krate: Crate, trait_: Trait) -> Arc<[ImplBlock]>; |
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 | ||
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml new file mode 100644 index 000000000..70216ab24 --- /dev/null +++ b/crates/ra_hir_ty/Cargo.toml | |||
@@ -0,0 +1,32 @@ | |||
1 | [package] | ||
2 | edition = "2018" | ||
3 | name = "ra_hir_ty" | ||
4 | version = "0.1.0" | ||
5 | authors = ["rust-analyzer developers"] | ||
6 | |||
7 | [lib] | ||
8 | doctest = false | ||
9 | |||
10 | [dependencies] | ||
11 | log = "0.4.5" | ||
12 | rustc-hash = "1.0" | ||
13 | parking_lot = "0.9.0" | ||
14 | ena = "0.13" | ||
15 | |||
16 | ra_syntax = { path = "../ra_syntax" } | ||
17 | ra_arena = { path = "../ra_arena" } | ||
18 | ra_db = { path = "../ra_db" } | ||
19 | hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } | ||
20 | hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } | ||
21 | test_utils = { path = "../test_utils" } | ||
22 | ra_prof = { path = "../ra_prof" } | ||
23 | |||
24 | # https://github.com/rust-lang/chalk/pull/294 | ||
25 | chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
26 | chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
27 | chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" } | ||
28 | |||
29 | lalrpop-intern = "0.15.1" | ||
30 | |||
31 | [dev-dependencies] | ||
32 | insta = "0.12.0" | ||
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs new file mode 100644 index 000000000..28859ba63 --- /dev/null +++ b/crates/ra_hir_ty/src/lib.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | //! Work in Progress: everything related to types, type inference and trait | ||
2 | //! solving. | ||
3 | |||
4 | pub mod primitive; | ||
diff --git a/crates/ra_hir_ty/src/primitive.rs b/crates/ra_hir_ty/src/primitive.rs new file mode 100644 index 000000000..02a8179d9 --- /dev/null +++ b/crates/ra_hir_ty/src/primitive.rs | |||
@@ -0,0 +1,193 @@ | |||
1 | //! Defines primitive types, which have a couple of peculiarities: | ||
2 | //! | ||
3 | //! * during type inference, they can be uncertain (ie, `let x = 92;`) | ||
4 | //! * they don't belong to any particular crate. | ||
5 | |||
6 | use std::fmt; | ||
7 | |||
8 | pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; | ||
9 | |||
10 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] | ||
11 | pub enum Uncertain<T> { | ||
12 | Unknown, | ||
13 | Known(T), | ||
14 | } | ||
15 | |||
16 | impl From<IntTy> for Uncertain<IntTy> { | ||
17 | fn from(ty: IntTy) -> Self { | ||
18 | Uncertain::Known(ty) | ||
19 | } | ||
20 | } | ||
21 | |||
22 | impl fmt::Display for Uncertain<IntTy> { | ||
23 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
24 | match *self { | ||
25 | Uncertain::Unknown => write!(f, "{{integer}}"), | ||
26 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl From<FloatTy> for Uncertain<FloatTy> { | ||
32 | fn from(ty: FloatTy) -> Self { | ||
33 | Uncertain::Known(ty) | ||
34 | } | ||
35 | } | ||
36 | |||
37 | impl fmt::Display for Uncertain<FloatTy> { | ||
38 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
39 | match *self { | ||
40 | Uncertain::Unknown => write!(f, "{{float}}"), | ||
41 | Uncertain::Known(ty) => write!(f, "{}", ty), | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | #[derive(Copy, Clone, Eq, PartialEq, Hash)] | ||
47 | pub struct IntTy { | ||
48 | pub signedness: Signedness, | ||
49 | pub bitness: IntBitness, | ||
50 | } | ||
51 | |||
52 | impl fmt::Debug for IntTy { | ||
53 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
54 | fmt::Display::fmt(self, f) | ||
55 | } | ||
56 | } | ||
57 | |||
58 | impl fmt::Display for IntTy { | ||
59 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
60 | write!(f, "{}", self.ty_to_string()) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | impl IntTy { | ||
65 | pub fn isize() -> IntTy { | ||
66 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize } | ||
67 | } | ||
68 | |||
69 | pub fn i8() -> IntTy { | ||
70 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 } | ||
71 | } | ||
72 | |||
73 | pub fn i16() -> IntTy { | ||
74 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 } | ||
75 | } | ||
76 | |||
77 | pub fn i32() -> IntTy { | ||
78 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 } | ||
79 | } | ||
80 | |||
81 | pub fn i64() -> IntTy { | ||
82 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 } | ||
83 | } | ||
84 | |||
85 | pub fn i128() -> IntTy { | ||
86 | IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 } | ||
87 | } | ||
88 | |||
89 | pub fn usize() -> IntTy { | ||
90 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize } | ||
91 | } | ||
92 | |||
93 | pub fn u8() -> IntTy { | ||
94 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 } | ||
95 | } | ||
96 | |||
97 | pub fn u16() -> IntTy { | ||
98 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 } | ||
99 | } | ||
100 | |||
101 | pub fn u32() -> IntTy { | ||
102 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 } | ||
103 | } | ||
104 | |||
105 | pub fn u64() -> IntTy { | ||
106 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 } | ||
107 | } | ||
108 | |||
109 | pub fn u128() -> IntTy { | ||
110 | IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 } | ||
111 | } | ||
112 | |||
113 | pub fn ty_to_string(self) -> &'static str { | ||
114 | match (self.signedness, self.bitness) { | ||
115 | (Signedness::Signed, IntBitness::Xsize) => "isize", | ||
116 | (Signedness::Signed, IntBitness::X8) => "i8", | ||
117 | (Signedness::Signed, IntBitness::X16) => "i16", | ||
118 | (Signedness::Signed, IntBitness::X32) => "i32", | ||
119 | (Signedness::Signed, IntBitness::X64) => "i64", | ||
120 | (Signedness::Signed, IntBitness::X128) => "i128", | ||
121 | (Signedness::Unsigned, IntBitness::Xsize) => "usize", | ||
122 | (Signedness::Unsigned, IntBitness::X8) => "u8", | ||
123 | (Signedness::Unsigned, IntBitness::X16) => "u16", | ||
124 | (Signedness::Unsigned, IntBitness::X32) => "u32", | ||
125 | (Signedness::Unsigned, IntBitness::X64) => "u64", | ||
126 | (Signedness::Unsigned, IntBitness::X128) => "u128", | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | #[derive(Copy, Clone, PartialEq, Eq, Hash)] | ||
132 | pub struct FloatTy { | ||
133 | pub bitness: FloatBitness, | ||
134 | } | ||
135 | |||
136 | impl fmt::Debug for FloatTy { | ||
137 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
138 | fmt::Display::fmt(self, f) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl fmt::Display for FloatTy { | ||
143 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
144 | write!(f, "{}", self.ty_to_string()) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | impl FloatTy { | ||
149 | pub fn f32() -> FloatTy { | ||
150 | FloatTy { bitness: FloatBitness::X32 } | ||
151 | } | ||
152 | |||
153 | pub fn f64() -> FloatTy { | ||
154 | FloatTy { bitness: FloatBitness::X64 } | ||
155 | } | ||
156 | |||
157 | pub fn ty_to_string(self) -> &'static str { | ||
158 | match self.bitness { | ||
159 | FloatBitness::X32 => "f32", | ||
160 | FloatBitness::X64 => "f64", | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
165 | impl From<BuiltinInt> for IntTy { | ||
166 | fn from(t: BuiltinInt) -> Self { | ||
167 | IntTy { signedness: t.signedness, bitness: t.bitness } | ||
168 | } | ||
169 | } | ||
170 | |||
171 | impl From<BuiltinFloat> for FloatTy { | ||
172 | fn from(t: BuiltinFloat) -> Self { | ||
173 | FloatTy { bitness: t.bitness } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | impl From<Option<BuiltinInt>> for Uncertain<IntTy> { | ||
178 | fn from(t: Option<BuiltinInt>) -> Self { | ||
179 | match t { | ||
180 | None => Uncertain::Unknown, | ||
181 | Some(t) => Uncertain::Known(t.into()), | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | impl From<Option<BuiltinFloat>> for Uncertain<FloatTy> { | ||
187 | fn from(t: Option<BuiltinFloat>) -> Self { | ||
188 | match t { | ||
189 | None => Uncertain::Unknown, | ||
190 | Some(t) => Uncertain::Known(t.into()), | ||
191 | } | ||
192 | } | ||
193 | } | ||
diff --git a/crates/ra_ide_api/src/impls.rs b/crates/ra_ide_api/src/impls.rs index 2b3100fc3..b3ebd9145 100644 --- a/crates/ra_ide_api/src/impls.rs +++ b/crates/ra_ide_api/src/impls.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; | 3 | use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor}; |
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; |
6 | 6 | ||
@@ -56,11 +56,11 @@ fn impls_for_def( | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | let krate = module.krate(); | 58 | let krate = module.krate(); |
59 | let impls = db.impls_in_crate(krate); | 59 | let impls = ImplBlock::all_in_crate(db, krate); |
60 | 60 | ||
61 | Some( | 61 | Some( |
62 | impls | 62 | impls |
63 | .all_impls() | 63 | .into_iter() |
64 | .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) | 64 | .filter(|impl_block| is_equal_for_find_impls(&ty, &impl_block.target_ty(db))) |
65 | .map(|imp| imp.to_nav(db)) | 65 | .map(|imp| imp.to_nav(db)) |
66 | .collect(), | 66 | .collect(), |
@@ -77,9 +77,9 @@ fn impls_for_trait( | |||
77 | let tr = hir::Trait::from_source(db, src)?; | 77 | let tr = hir::Trait::from_source(db, src)?; |
78 | 78 | ||
79 | let krate = module.krate(); | 79 | let krate = module.krate(); |
80 | let impls = db.impls_in_crate(krate); | 80 | let impls = ImplBlock::for_trait(db, krate, tr); |
81 | 81 | ||
82 | Some(impls.lookup_impl_blocks_for_trait(tr).map(|imp| imp.to_nav(db)).collect()) | 82 | Some(impls.into_iter().map(|imp| imp.to_nav(db)).collect()) |
83 | } | 83 | } |
84 | 84 | ||
85 | fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { | 85 | fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { |