aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ty/method_resolution.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-26 19:56:07 +0000
committerAleksey Kladov <[email protected]>2019-11-26 19:56:07 +0000
commitbed6869865ccfc6e72be26cb2041d83ab5cdbe3c (patch)
tree94929e320d14ae8829f807ff83824fb94f44c375 /crates/ra_hir/src/ty/method_resolution.rs
parentcace49e9a79a5fe44cda63964412c5bdce7ee90d (diff)
Cleanup
Diffstat (limited to 'crates/ra_hir/src/ty/method_resolution.rs')
-rw-r--r--crates/ra_hir/src/ty/method_resolution.rs101
1 files changed, 39 insertions, 62 deletions
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs
index fdc87a28d..92645e2a5 100644
--- a/crates/ra_hir/src/ty/method_resolution.rs
+++ b/crates/ra_hir/src/ty/method_resolution.rs
@@ -97,14 +97,15 @@ impl CrateImplBlocks {
97 } 97 }
98} 98}
99 99
100fn def_crates( 100impl Ty {
101 db: &impl HirDatabase, 101 pub(crate) fn def_crates(
102 cur_crate: CrateId, 102 &self,
103 ty: &Ty, 103 db: &impl HirDatabase,
104) -> Option<ArrayVec<[CrateId; 2]>> { 104 cur_crate: CrateId,
105 // Types like slice can have inherent impls in several crates, (core and alloc). 105 ) -> Option<ArrayVec<[CrateId; 2]>> {
106 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 106 // Types like slice can have inherent impls in several crates, (core and alloc).
107 macro_rules! lang_item_crate { 107 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
108 macro_rules! lang_item_crate {
108 ($($name:expr),+ $(,)?) => {{ 109 ($($name:expr),+ $(,)?) => {{
109 let mut v = ArrayVec::<[LangItemTarget; 2]>::new(); 110 let mut v = ArrayVec::<[LangItemTarget; 2]>::new();
110 $( 111 $(
@@ -114,38 +115,38 @@ fn def_crates(
114 }}; 115 }};
115 } 116 }
116 117
117 let lang_item_targets = match ty { 118 let lang_item_targets = match self {
118 Ty::Apply(a_ty) => match a_ty.ctor { 119 Ty::Apply(a_ty) => match a_ty.ctor {
119 TypeCtor::Adt(def_id) => { 120 TypeCtor::Adt(def_id) => {
120 return Some(std::iter::once(def_id.module(db).krate).collect()) 121 return Some(std::iter::once(def_id.module(db).krate).collect())
121 } 122 }
122 TypeCtor::Bool => lang_item_crate!("bool"), 123 TypeCtor::Bool => lang_item_crate!("bool"),
123 TypeCtor::Char => lang_item_crate!("char"), 124 TypeCtor::Char => lang_item_crate!("char"),
124 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness { 125 TypeCtor::Float(Uncertain::Known(f)) => match f.bitness {
125 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 126 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
126 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 127 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"),
127 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"), 128 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
129 },
130 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
131 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
132 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
133 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
134 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
135 _ => return None,
128 }, 136 },
129 TypeCtor::Int(Uncertain::Known(i)) => lang_item_crate!(i.ty_to_string()),
130 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
131 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
132 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
133 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
134 _ => return None, 137 _ => return None,
135 }, 138 };
136 _ => return None, 139 let res = lang_item_targets
137 }; 140 .into_iter()
138 let res = lang_item_targets 141 .filter_map(|it| match it {
139 .into_iter() 142 LangItemTarget::ImplBlockId(it) => Some(it),
140 .filter_map(|it| match it { 143 _ => None,
141 LangItemTarget::ImplBlockId(it) => Some(it), 144 })
142 _ => None, 145 .map(|it| it.module(db).krate)
143 }) 146 .collect();
144 .map(|it| it.module(db).krate) 147 Some(res)
145 .collect(); 148 }
146 Some(res)
147} 149}
148
149/// Look up the method with the given name, returning the actual autoderefed 150/// Look up the method with the given name, returning the actual autoderefed
150/// receiver type (but without autoref applied yet). 151/// receiver type (but without autoref applied yet).
151pub(crate) fn lookup_method( 152pub(crate) fn lookup_method(
@@ -286,7 +287,7 @@ fn iterate_inherent_methods<T>(
286 krate: CrateId, 287 krate: CrateId,
287 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>, 288 mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
288) -> Option<T> { 289) -> Option<T> {
289 for krate in def_crates(db, krate, &ty.value)? { 290 for krate in ty.value.def_crates(db, krate)? {
290 let impls = db.impls_in_crate(krate); 291 let impls = db.impls_in_crate(krate);
291 292
292 for impl_block in impls.lookup_impl_blocks(&ty.value) { 293 for impl_block in impls.lookup_impl_blocks(&ty.value) {
@@ -342,30 +343,6 @@ pub(crate) fn implements_trait(
342 solution.is_some() 343 solution.is_some()
343} 344}
344 345
345impl Ty {
346 // This would be nicer if it just returned an iterator, but that runs into
347 // lifetime problems, because we need to borrow temp `CrateImplBlocks`.
348 pub fn iterate_impl_items<T>(
349 self,
350 db: &impl HirDatabase,
351 krate: CrateId,
352 mut callback: impl FnMut(AssocItem) -> Option<T>,
353 ) -> Option<T> {
354 for krate in def_crates(db, krate, &self)? {
355 let impls = db.impls_in_crate(krate);
356
357 for impl_block in impls.lookup_impl_blocks(&self) {
358 for &item in db.impl_data(impl_block).items.iter() {
359 if let Some(result) = callback(item.into()) {
360 return Some(result);
361 }
362 }
363 }
364 }
365 None
366 }
367}
368
369/// This creates Substs for a trait with the given Self type and type variables 346/// This creates Substs for a trait with the given Self type and type variables
370/// for all other parameters, to query Chalk with it. 347/// for all other parameters, to query Chalk with it.
371fn generic_implements_goal( 348fn generic_implements_goal(