aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock23
-rw-r--r--crates/ra_hir/Cargo.toml1
-rw-r--r--crates/ra_hir/src/code_model.rs9
-rw-r--r--crates/ra_hir/src/db.rs4
-rw-r--r--crates/ra_hir/src/ty/lower.rs34
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs101
-rw-r--r--crates/ra_hir/src/ty/primitive.rs159
-rw-r--r--crates/ra_hir/src/ty/traits.rs4
-rw-r--r--crates/ra_hir_ty/Cargo.toml32
-rw-r--r--crates/ra_hir_ty/src/lib.rs4
-rw-r--r--crates/ra_hir_ty/src/primitive.rs193
-rw-r--r--crates/ra_ide_api/src/impls.rs10
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]]
1041name = "ra_hir_ty"
1042version = "0.1.0"
1043dependencies = [
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]]
1040name = "ra_ide_api" 1063name = "ra_ide_api"
1041version = "0.1.0" 1064version = "0.1.0"
1042dependencies = [ 1065dependencies = [
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" }
23tt = { path = "../ra_tt", package = "ra_tt" } 23tt = { path = "../ra_tt", package = "ra_tt" }
24hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" } 24hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
25hir_def = { path = "../ra_hir_def", package = "ra_hir_def" } 25hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
26hir_ty = { path = "../ra_hir_ty", package = "ra_hir_ty" }
26test_utils = { path = "../test_utils" } 27test_utils = { path = "../test_utils" }
27ra_prof = { path = "../ra_prof" } 28ra_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
999impl ImplBlock { 999impl 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 @@
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use ra_arena::map::ArenaMap; 5use ra_arena::map::ArenaMap;
6use ra_db::salsa; 6use ra_db::{salsa, CrateId};
7 7
8use crate::{ 8use 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;
9use std::sync::Arc; 9use std::sync::Arc;
10 10
11use hir_def::{ 11use 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::{
27use crate::{ 27use 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
682impl From<BuiltinInt> for IntTy {
683 fn from(t: BuiltinInt) -> Self {
684 IntTy { signedness: t.signedness, bitness: t.bitness }
685 }
686}
687
688impl From<BuiltinFloat> for FloatTy {
689 fn from(t: BuiltinFloat) -> Self {
690 FloatTy { bitness: t.bitness }
691 }
692}
693
694impl 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
703impl 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
712fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: StructId) -> FnSig { 682fn 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 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver, AstItemDef, HasModule}; 8use hir_def::{
9 lang_item::LangItemTarget, resolver::HasResolver, resolver::Resolver, AssocItemId, AstItemDef,
10 HasModule, ImplId, TraitId,
11};
12use ra_db::CrateId;
13use ra_prof::profile;
9use rustc_hash::FxHashMap; 14use rustc_hash::FxHashMap;
10 15
11use crate::{ 16use 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
18use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 23use super::{autoderef, Canonical, InEnvironment, TraitEnvironment, TraitRef};
@@ -37,54 +42,58 @@ impl TyFingerprint {
37 42
38#[derive(Debug, PartialEq, Eq)] 43#[derive(Debug, PartialEq, Eq)]
39pub struct CrateImplBlocks { 44pub 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
44impl CrateImplBlocks { 49impl 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
90fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { 99fn 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
3use std::fmt; 3pub use hir_ty::primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain};
4
5pub use hir_def::builtin_type::{FloatBitness, IntBitness, Signedness};
6
7#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
8pub enum Uncertain<T> {
9 Unknown,
10 Known(T),
11}
12
13impl From<IntTy> for Uncertain<IntTy> {
14 fn from(ty: IntTy) -> Self {
15 Uncertain::Known(ty)
16 }
17}
18
19impl 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
28impl From<FloatTy> for Uncertain<FloatTy> {
29 fn from(ty: FloatTy) -> Self {
30 Uncertain::Known(ty)
31 }
32}
33
34impl 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)]
44pub struct IntTy {
45 pub signedness: Signedness,
46 pub bitness: IntBitness,
47}
48
49impl fmt::Debug for IntTy {
50 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
51 fmt::Display::fmt(self, f)
52 }
53}
54
55impl fmt::Display for IntTy {
56 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
57 write!(f, "{}", self.ty_to_string())
58 }
59}
60
61impl 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)]
129pub struct FloatTy {
130 pub bitness: FloatBitness,
131}
132
133impl fmt::Debug for FloatTy {
134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135 fmt::Display::fmt(self, f)
136 }
137}
138
139impl fmt::Display for FloatTy {
140 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
141 write!(f, "{}", self.ty_to_string())
142 }
143}
144
145impl 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]
2edition = "2018"
3name = "ra_hir_ty"
4version = "0.1.0"
5authors = ["rust-analyzer developers"]
6
7[lib]
8doctest = false
9
10[dependencies]
11log = "0.4.5"
12rustc-hash = "1.0"
13parking_lot = "0.9.0"
14ena = "0.13"
15
16ra_syntax = { path = "../ra_syntax" }
17ra_arena = { path = "../ra_arena" }
18ra_db = { path = "../ra_db" }
19hir_expand = { path = "../ra_hir_expand", package = "ra_hir_expand" }
20hir_def = { path = "../ra_hir_def", package = "ra_hir_def" }
21test_utils = { path = "../test_utils" }
22ra_prof = { path = "../ra_prof" }
23
24# https://github.com/rust-lang/chalk/pull/294
25chalk-solve = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
26chalk-rust-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
27chalk-ir = { git = "https://github.com/jackh726/chalk.git", rev = "095cd38a4f16337913bba487f2055b9ca0179f30" }
28
29lalrpop-intern = "0.15.1"
30
31[dev-dependencies]
32insta = "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
4pub 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
6use std::fmt;
7
8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness};
9
10#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
11pub enum Uncertain<T> {
12 Unknown,
13 Known(T),
14}
15
16impl From<IntTy> for Uncertain<IntTy> {
17 fn from(ty: IntTy) -> Self {
18 Uncertain::Known(ty)
19 }
20}
21
22impl 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
31impl From<FloatTy> for Uncertain<FloatTy> {
32 fn from(ty: FloatTy) -> Self {
33 Uncertain::Known(ty)
34 }
35}
36
37impl 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)]
47pub struct IntTy {
48 pub signedness: Signedness,
49 pub bitness: IntBitness,
50}
51
52impl fmt::Debug for IntTy {
53 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
54 fmt::Display::fmt(self, f)
55 }
56}
57
58impl fmt::Display for IntTy {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 write!(f, "{}", self.ty_to_string())
61 }
62}
63
64impl 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)]
132pub struct FloatTy {
133 pub bitness: FloatBitness,
134}
135
136impl fmt::Debug for FloatTy {
137 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138 fmt::Display::fmt(self, f)
139 }
140}
141
142impl fmt::Display for FloatTy {
143 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
144 write!(f, "{}", self.ty_to_string())
145 }
146}
147
148impl 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
165impl From<BuiltinInt> for IntTy {
166 fn from(t: BuiltinInt) -> Self {
167 IntTy { signedness: t.signedness, bitness: t.bitness }
168 }
169}
170
171impl From<BuiltinFloat> for FloatTy {
172 fn from(t: BuiltinFloat) -> Self {
173 FloatTy { bitness: t.bitness }
174 }
175}
176
177impl 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
186impl 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
3use hir::{db::HirDatabase, ApplicationTy, FromSource, Ty, TypeCtor}; 3use hir::{ApplicationTy, FromSource, ImplBlock, Ty, TypeCtor};
4use ra_db::SourceDatabase; 4use ra_db::SourceDatabase;
5use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; 5use 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
85fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool { 85fn is_equal_for_find_impls(original_ty: &Ty, impl_ty: &Ty) -> bool {