aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/autoderef.rs10
-rw-r--r--crates/hir_ty/src/lib.rs8
-rw-r--r--crates/hir_ty/src/method_resolution.rs106
3 files changed, 61 insertions, 63 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index 80e192a57..f8e9db9ae 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -35,13 +35,21 @@ pub(crate) fn deref(
35 krate: CrateId, 35 krate: CrateId,
36 ty: InEnvironment<&Canonical<Ty>>, 36 ty: InEnvironment<&Canonical<Ty>>,
37) -> Option<Canonical<Ty>> { 37) -> Option<Canonical<Ty>> {
38 if let Some(derefed) = ty.goal.value.builtin_deref() { 38 if let Some(derefed) = builtin_deref(&ty.goal.value) {
39 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) 39 Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
40 } else { 40 } else {
41 deref_by_trait(db, krate, ty) 41 deref_by_trait(db, krate, ty)
42 } 42 }
43} 43}
44 44
45fn builtin_deref(ty: &Ty) -> Option<Ty> {
46 match ty.kind(&Interner) {
47 TyKind::Ref(.., ty) => Some(ty.clone()),
48 TyKind::Raw(.., ty) => Some(ty.clone()),
49 _ => None,
50 }
51}
52
45fn deref_by_trait( 53fn deref_by_trait(
46 db: &dyn HirDatabase, 54 db: &dyn HirDatabase,
47 krate: CrateId, 55 krate: CrateId,
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 5c83a508d..ae3987752 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -199,14 +199,6 @@ impl Ty {
199 } 199 }
200 } 200 }
201 201
202 fn builtin_deref(&self) -> Option<Ty> {
203 match self.kind(&Interner) {
204 TyKind::Ref(.., ty) => Some(ty.clone()),
205 TyKind::Raw(.., ty) => Some(ty.clone()),
206 _ => None,
207 }
208 }
209
210 /// Returns the type parameters of this type if it has some (i.e. is an ADT 202 /// Returns the type parameters of this type if it has some (i.e. is an ADT
211 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 203 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
212 pub fn substs(&self) -> Option<&Substitution> { 204 pub fn substs(&self) -> Option<&Substitution> {
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index f29319f20..c601f2d53 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -239,15 +239,14 @@ impl InherentImpls {
239 } 239 }
240} 240}
241 241
242impl Ty { 242pub fn def_crates(
243 pub fn def_crates( 243 db: &dyn HirDatabase,
244 &self, 244 ty: &Ty,
245 db: &dyn HirDatabase, 245 cur_crate: CrateId,
246 cur_crate: CrateId, 246) -> Option<ArrayVec<CrateId, 2>> {
247 ) -> Option<ArrayVec<CrateId, 2>> { 247 // Types like slice can have inherent impls in several crates, (core and alloc).
248 // Types like slice can have inherent impls in several crates, (core and alloc). 248 // The corresponding impls are marked with lang items, so we can use them to find the required crates.
249 // The corresponding impls are marked with lang items, so we can use them to find the required crates. 249 macro_rules! lang_item_crate {
250 macro_rules! lang_item_crate {
251 ($($name:expr),+ $(,)?) => {{ 250 ($($name:expr),+ $(,)?) => {{
252 let mut v = ArrayVec::<LangItemTarget, 2>::new(); 251 let mut v = ArrayVec::<LangItemTarget, 2>::new();
253 $( 252 $(
@@ -257,51 +256,50 @@ impl Ty {
257 }}; 256 }};
258 } 257 }
259 258
260 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 259 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
261 260
262 let lang_item_targets = match self.kind(&Interner) { 261 let lang_item_targets = match ty.kind(&Interner) {
263 TyKind::Adt(AdtId(def_id), _) => { 262 TyKind::Adt(AdtId(def_id), _) => {
264 return mod_to_crate_ids(def_id.module(db.upcast())); 263 return mod_to_crate_ids(def_id.module(db.upcast()));
265 } 264 }
266 TyKind::Foreign(id) => { 265 TyKind::Foreign(id) => {
267 return mod_to_crate_ids( 266 return mod_to_crate_ids(
268 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), 267 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
269 ); 268 );
270 } 269 }
271 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 270 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
272 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), 271 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
273 TyKind::Scalar(Scalar::Float(f)) => match f { 272 TyKind::Scalar(Scalar::Float(f)) => match f {
274 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 273 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
275 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 274 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
276 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 275 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
277 }, 276 },
278 &TyKind::Scalar(Scalar::Int(t)) => { 277 &TyKind::Scalar(Scalar::Int(t)) => {
279 lang_item_crate!(primitive::int_ty_to_string(t)) 278 lang_item_crate!(primitive::int_ty_to_string(t))
280 } 279 }
281 &TyKind::Scalar(Scalar::Uint(t)) => { 280 &TyKind::Scalar(Scalar::Uint(t)) => {
282 lang_item_crate!(primitive::uint_ty_to_string(t)) 281 lang_item_crate!(primitive::uint_ty_to_string(t))
283 } 282 }
284 TyKind::Str => lang_item_crate!("str_alloc", "str"), 283 TyKind::Str => lang_item_crate!("str_alloc", "str"),
285 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 284 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
286 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 285 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
287 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 286 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
288 TyKind::Dyn(_) => { 287 TyKind::Dyn(_) => {
289 return self.dyn_trait().and_then(|trait_| { 288 return ty.dyn_trait().and_then(|trait_| {
290 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 289 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
291 }); 290 });
292 } 291 }
293 _ => return None, 292 _ => return None,
294 }; 293 };
295 let res = lang_item_targets 294 let res = lang_item_targets
296 .into_iter() 295 .into_iter()
297 .filter_map(|it| match it { 296 .filter_map(|it| match it {
298 LangItemTarget::ImplDefId(it) => Some(it), 297 LangItemTarget::ImplDefId(it) => Some(it),
299 _ => None, 298 _ => None,
300 }) 299 })
301 .map(|it| it.lookup(db.upcast()).container.krate()) 300 .map(|it| it.lookup(db.upcast()).container.krate())
302 .collect(); 301 .collect();
303 Some(res) 302 Some(res)
304 }
305} 303}
306 304
307/// Look up the method with the given name, returning the actual autoderefed 305/// Look up the method with the given name, returning the actual autoderefed
@@ -628,7 +626,7 @@ fn iterate_inherent_methods(
628 visible_from_module: Option<ModuleId>, 626 visible_from_module: Option<ModuleId>,
629 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool, 627 callback: &mut dyn FnMut(&Ty, AssocItemId) -> bool,
630) -> bool { 628) -> bool {
631 let def_crates = match self_ty.value.def_crates(db, krate) { 629 let def_crates = match def_crates(db, &self_ty.value, krate) {
632 Some(k) => k, 630 Some(k) => k,
633 None => return false, 631 None => return false,
634 }; 632 };