aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ty')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs80
-rw-r--r--crates/ra_hir/src/ty/tests.rs17
-rw-r--r--crates/ra_hir/src/ty/traits/chalk.rs6
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 @@
5use std::sync::Arc; 5use std::sync::Arc;
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use hir_def::CrateModuleId;
9use rustc_hash::FxHashMap; 8use rustc_hash::FxHashMap;
10 9
11use crate::{ 10use 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
20use super::{autoderef, lower, Canonical, InEnvironment, TraitEnvironment, TraitRef}; 18use 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)]
41pub struct CrateImplBlocks { 39pub 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
48impl CrateImplBlocks { 44impl 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
126fn def_crates(db: &impl HirDatabase, cur_crate: Crate, ty: &Ty) -> Option<ArrayVec<[Crate; 2]>> { 90fn 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 @@
1mod never_type;
2mod coercion;
3
1use std::fmt::Write; 4use std::fmt::Write;
2use std::sync::Arc; 5use std::sync::Arc;
3 6
@@ -11,7 +14,7 @@ use ra_syntax::{
11use test_utils::covers; 14use test_utils::covers;
12 15
13use crate::{ 16use 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
22mod never_type;
23mod coercion;
24
25#[test] 25#[test]
26fn cfg_impl_block() { 26fn 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> {
4609fn type_at_pos(db: &TestDB, pos: FilePosition) -> String { 4609fn 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