diff options
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r-- | crates/ra_hir/src/ty/method_resolution.rs | 80 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/tests.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir/src/ty/traits/chalk.rs | 6 |
3 files changed, 34 insertions, 69 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index eb5ca6769..9aad2d3fe 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -5,16 +5,14 @@ | |||
5 | use std::sync::Arc; | 5 | use std::sync::Arc; |
6 | 6 | ||
7 | use arrayvec::ArrayVec; | 7 | use arrayvec::ArrayVec; |
8 | use hir_def::CrateModuleId; | ||
9 | use rustc_hash::FxHashMap; | 8 | use rustc_hash::FxHashMap; |
10 | 9 | ||
11 | use crate::{ | 10 | use crate::{ |
12 | db::HirDatabase, | 11 | db::HirDatabase, |
13 | impl_block::{ImplBlock, ImplId}, | ||
14 | resolve::Resolver, | 12 | resolve::Resolver, |
15 | ty::primitive::{FloatBitness, Uncertain}, | 13 | ty::primitive::{FloatBitness, Uncertain}, |
16 | ty::{Ty, TypeCtor}, | 14 | ty::{Ty, TypeCtor}, |
17 | AssocItem, Crate, Function, Module, Mutability, Name, Trait, | 15 | AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, |
18 | }; | 16 | }; |
19 | 17 | ||
20 | use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; | 18 | use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; |
@@ -39,65 +37,46 @@ impl TyFingerprint { | |||
39 | 37 | ||
40 | #[derive(Debug, PartialEq, Eq)] | 38 | #[derive(Debug, PartialEq, Eq)] |
41 | pub struct CrateImplBlocks { | 39 | pub struct CrateImplBlocks { |
42 | /// To make sense of the CrateModuleIds, we need the source root. | 40 | impls: FxHashMap<TyFingerprint, Vec<ImplBlock>>, |
43 | krate: Crate, | 41 | impls_by_trait: FxHashMap<Trait, Vec<ImplBlock>>, |
44 | impls: FxHashMap<TyFingerprint, Vec<(CrateModuleId, ImplId)>>, | ||
45 | impls_by_trait: FxHashMap<Trait, Vec<(CrateModuleId, ImplId)>>, | ||
46 | } | 42 | } |
47 | 43 | ||
48 | impl CrateImplBlocks { | 44 | impl CrateImplBlocks { |
49 | pub fn lookup_impl_blocks<'a>(&'a self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + 'a { | 45 | pub(crate) fn impls_in_crate_query( |
46 | db: &impl HirDatabase, | ||
47 | krate: Crate, | ||
48 | ) -> Arc<CrateImplBlocks> { | ||
49 | let mut crate_impl_blocks = | ||
50 | CrateImplBlocks { impls: FxHashMap::default(), impls_by_trait: FxHashMap::default() }; | ||
51 | if let Some(module) = krate.root_module(db) { | ||
52 | crate_impl_blocks.collect_recursive(db, module); | ||
53 | } | ||
54 | Arc::new(crate_impl_blocks) | ||
55 | } | ||
56 | pub fn lookup_impl_blocks(&self, ty: &Ty) -> impl Iterator<Item = ImplBlock> + '_ { | ||
50 | let fingerprint = TyFingerprint::for_impl(ty); | 57 | let fingerprint = TyFingerprint::for_impl(ty); |
51 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flat_map(|i| i.iter()).map( | 58 | fingerprint.and_then(|f| self.impls.get(&f)).into_iter().flatten().copied() |
52 | move |(module_id, impl_id)| { | ||
53 | let module = Module::new(self.krate, *module_id); | ||
54 | ImplBlock::from_id(module, *impl_id) | ||
55 | }, | ||
56 | ) | ||
57 | } | 59 | } |
58 | 60 | ||
59 | pub fn lookup_impl_blocks_for_trait<'a>( | 61 | pub fn lookup_impl_blocks_for_trait(&self, tr: Trait) -> impl Iterator<Item = ImplBlock> + '_ { |
60 | &'a self, | 62 | self.impls_by_trait.get(&tr).into_iter().flatten().copied() |
61 | tr: Trait, | ||
62 | ) -> impl Iterator<Item = ImplBlock> + 'a { | ||
63 | self.impls_by_trait.get(&tr).into_iter().flat_map(|i| i.iter()).map( | ||
64 | move |(module_id, impl_id)| { | ||
65 | let module = Module::new(self.krate, *module_id); | ||
66 | ImplBlock::from_id(module, *impl_id) | ||
67 | }, | ||
68 | ) | ||
69 | } | 63 | } |
70 | 64 | ||
71 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { | 65 | pub fn all_impls<'a>(&'a self) -> impl Iterator<Item = ImplBlock> + 'a { |
72 | self.impls.values().chain(self.impls_by_trait.values()).flat_map(|i| i.iter()).map( | 66 | self.impls.values().chain(self.impls_by_trait.values()).flatten().copied() |
73 | move |(module_id, impl_id)| { | ||
74 | let module = Module::new(self.krate, *module_id); | ||
75 | ImplBlock::from_id(module, *impl_id) | ||
76 | }, | ||
77 | ) | ||
78 | } | 67 | } |
79 | 68 | ||
80 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { | 69 | fn collect_recursive(&mut self, db: &impl HirDatabase, module: Module) { |
81 | let module_impl_blocks = db.impls_in_module(module); | 70 | for impl_block in module.impl_blocks(db) { |
82 | |||
83 | for (impl_id, _) in module_impl_blocks.impls.iter() { | ||
84 | let impl_block = ImplBlock::from_id(module_impl_blocks.module, impl_id); | ||
85 | |||
86 | let target_ty = impl_block.target_ty(db); | 71 | let target_ty = impl_block.target_ty(db); |
87 | 72 | ||
88 | if impl_block.target_trait(db).is_some() { | 73 | if impl_block.target_trait(db).is_some() { |
89 | if let Some(tr) = impl_block.target_trait_ref(db) { | 74 | if let Some(tr) = impl_block.target_trait_ref(db) { |
90 | self.impls_by_trait | 75 | self.impls_by_trait.entry(tr.trait_).or_default().push(impl_block); |
91 | .entry(tr.trait_) | ||
92 | .or_insert_with(Vec::new) | ||
93 | .push((module.id.module_id, impl_id)); | ||
94 | } | 76 | } |
95 | } else { | 77 | } else { |
96 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { | 78 | if let Some(target_ty_fp) = TyFingerprint::for_impl(&target_ty) { |
97 | self.impls | 79 | self.impls.entry(target_ty_fp).or_default().push(impl_block); |
98 | .entry(target_ty_fp) | ||
99 | .or_insert_with(Vec::new) | ||
100 | .push((module.id.module_id, impl_id)); | ||
101 | } | 80 | } |
102 | } | 81 | } |
103 | } | 82 | } |
@@ -106,21 +85,6 @@ impl CrateImplBlocks { | |||
106 | self.collect_recursive(db, child); | 85 | self.collect_recursive(db, child); |
107 | } | 86 | } |
108 | } | 87 | } |
109 | |||
110 | pub(crate) fn impls_in_crate_query( | ||
111 | db: &impl HirDatabase, | ||
112 | krate: Crate, | ||
113 | ) -> Arc<CrateImplBlocks> { | ||
114 | let mut crate_impl_blocks = CrateImplBlocks { | ||
115 | krate, | ||
116 | impls: FxHashMap::default(), | ||
117 | impls_by_trait: FxHashMap::default(), | ||
118 | }; | ||
119 | if let Some(module) = krate.root_module(db) { | ||
120 | crate_impl_blocks.collect_recursive(db, module); | ||
121 | } | ||
122 | Arc::new(crate_impl_blocks) | ||
123 | } | ||
124 | } | 88 | } |
125 | 89 | ||
126 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { | 90 | fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { |
diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index fe9346c78..9a26e02fa 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs | |||
@@ -1,3 +1,6 @@ | |||
1 | mod never_type; | ||
2 | mod coercion; | ||
3 | |||
1 | use std::fmt::Write; | 4 | use std::fmt::Write; |
2 | use std::sync::Arc; | 5 | use std::sync::Arc; |
3 | 6 | ||
@@ -11,7 +14,7 @@ use ra_syntax::{ | |||
11 | use test_utils::covers; | 14 | use test_utils::covers; |
12 | 15 | ||
13 | use crate::{ | 16 | use crate::{ |
14 | expr::BodySourceMap, test_db::TestDB, ty::display::HirDisplay, ty::InferenceResult, | 17 | expr::BodySourceMap, test_db::TestDB, ty::display::HirDisplay, ty::InferenceResult, Source, |
15 | SourceAnalyzer, | 18 | SourceAnalyzer, |
16 | }; | 19 | }; |
17 | 20 | ||
@@ -19,9 +22,6 @@ use crate::{ | |||
19 | // against snapshots of the expected results using insta. Use cargo-insta to | 22 | // against snapshots of the expected results using insta. Use cargo-insta to |
20 | // update the snapshots. | 23 | // update the snapshots. |
21 | 24 | ||
22 | mod never_type; | ||
23 | mod coercion; | ||
24 | |||
25 | #[test] | 25 | #[test] |
26 | fn cfg_impl_block() { | 26 | fn cfg_impl_block() { |
27 | let (db, pos) = TestDB::with_position( | 27 | let (db, pos) = TestDB::with_position( |
@@ -4609,7 +4609,8 @@ fn test<T, U>() where T: Trait<U::Item>, U: Trait<T::Item> { | |||
4609 | fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { | 4609 | fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { |
4610 | let file = db.parse(pos.file_id).ok().unwrap(); | 4610 | let file = db.parse(pos.file_id).ok().unwrap(); |
4611 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); | 4611 | let expr = algo::find_node_at_offset::<ast::Expr>(file.syntax(), pos.offset).unwrap(); |
4612 | let analyzer = SourceAnalyzer::new(db, pos.file_id, expr.syntax(), Some(pos.offset)); | 4612 | let analyzer = |
4613 | SourceAnalyzer::new(db, Source::new(pos.file_id.into(), expr.syntax()), Some(pos.offset)); | ||
4613 | let ty = analyzer.type_of(db, &expr).unwrap(); | 4614 | let ty = analyzer.type_of(db, &expr).unwrap(); |
4614 | ty.display(db).to_string() | 4615 | ty.display(db).to_string() |
4615 | } | 4616 | } |
@@ -4674,7 +4675,7 @@ fn infer(content: &str) -> String { | |||
4674 | 4675 | ||
4675 | for node in source_file.syntax().descendants() { | 4676 | for node in source_file.syntax().descendants() { |
4676 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { | 4677 | if node.kind() == FN_DEF || node.kind() == CONST_DEF || node.kind() == STATIC_DEF { |
4677 | let analyzer = SourceAnalyzer::new(&db, file_id, &node, None); | 4678 | let analyzer = SourceAnalyzer::new(&db, Source::new(file_id.into(), &node), None); |
4678 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); | 4679 | infer_def(analyzer.inference_result(), analyzer.body_source_map()); |
4679 | } | 4680 | } |
4680 | } | 4681 | } |
@@ -4715,7 +4716,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
4715 | let file = db.parse(pos.file_id).ok().unwrap(); | 4716 | let file = db.parse(pos.file_id).ok().unwrap(); |
4716 | let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); | 4717 | let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); |
4717 | let events = db.log_executed(|| { | 4718 | let events = db.log_executed(|| { |
4718 | SourceAnalyzer::new(&db, pos.file_id, &node, None); | 4719 | SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); |
4719 | }); | 4720 | }); |
4720 | assert!(format!("{:?}", events).contains("infer")) | 4721 | assert!(format!("{:?}", events).contains("infer")) |
4721 | } | 4722 | } |
@@ -4735,7 +4736,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
4735 | let file = db.parse(pos.file_id).ok().unwrap(); | 4736 | let file = db.parse(pos.file_id).ok().unwrap(); |
4736 | let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); | 4737 | let node = file.syntax().token_at_offset(pos.offset).right_biased().unwrap().parent(); |
4737 | let events = db.log_executed(|| { | 4738 | let events = db.log_executed(|| { |
4738 | SourceAnalyzer::new(&db, pos.file_id, &node, None); | 4739 | SourceAnalyzer::new(&db, Source::new(pos.file_id.into(), &node), None); |
4739 | }); | 4740 | }); |
4740 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) | 4741 | assert!(!format!("{:?}", events).contains("infer"), "{:#?}", events) |
4741 | } | 4742 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 75351c17d..68304b950 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -191,11 +191,11 @@ impl ToChalk for Impl { | |||
191 | type Chalk = chalk_ir::ImplId; | 191 | type Chalk = chalk_ir::ImplId; |
192 | 192 | ||
193 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { | 193 | fn to_chalk(self, db: &impl HirDatabase) -> chalk_ir::ImplId { |
194 | db.intern_impl(self).into() | 194 | db.intern_chalk_impl(self).into() |
195 | } | 195 | } |
196 | 196 | ||
197 | fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { | 197 | fn from_chalk(db: &impl HirDatabase, impl_id: chalk_ir::ImplId) -> Impl { |
198 | db.lookup_intern_impl(impl_id.into()) | 198 | db.lookup_intern_chalk_impl(impl_id.into()) |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
@@ -630,7 +630,7 @@ fn impl_block_datum( | |||
630 | .target_trait_ref(db) | 630 | .target_trait_ref(db) |
631 | .expect("FIXME handle unresolved impl block trait ref") | 631 | .expect("FIXME handle unresolved impl block trait ref") |
632 | .subst(&bound_vars); | 632 | .subst(&bound_vars); |
633 | let impl_type = if impl_block.module().krate() == krate { | 633 | let impl_type = if impl_block.krate(db) == krate { |
634 | chalk_rust_ir::ImplType::Local | 634 | chalk_rust_ir::ImplType::Local |
635 | } else { | 635 | } else { |
636 | chalk_rust_ir::ImplType::External | 636 | chalk_rust_ir::ImplType::External |