diff options
Diffstat (limited to 'crates/hir_ty/src/method_resolution.rs')
-rw-r--r-- | crates/hir_ty/src/method_resolution.rs | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index ccc12c075..c7055bee5 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs | |||
@@ -9,7 +9,7 @@ use base_db::CrateId; | |||
9 | use chalk_ir::Mutability; | 9 | use chalk_ir::Mutability; |
10 | use hir_def::{ | 10 | use hir_def::{ |
11 | lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, | 11 | lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, |
12 | ImplId, Lookup, ModuleId, TraitId, TypeAliasId, | 12 | ImplId, Lookup, ModuleId, TraitId, |
13 | }; | 13 | }; |
14 | use hir_expand::name::Name; | 14 | use hir_expand::name::Name; |
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 15 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -17,10 +17,11 @@ use rustc_hash::{FxHashMap, FxHashSet}; | |||
17 | use crate::{ | 17 | use crate::{ |
18 | autoderef, | 18 | autoderef, |
19 | db::HirDatabase, | 19 | db::HirDatabase, |
20 | from_foreign_def_id, | ||
20 | primitive::{self, FloatTy, IntTy, UintTy}, | 21 | primitive::{self, FloatTy, IntTy, UintTy}, |
21 | utils::all_super_traits, | 22 | utils::all_super_traits, |
22 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, | 23 | AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner, |
23 | TraitEnvironment, TraitRef, Ty, TypeWalk, | 24 | Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk, |
24 | }; | 25 | }; |
25 | 26 | ||
26 | /// This is used as a key for indexing impls. | 27 | /// This is used as a key for indexing impls. |
@@ -35,7 +36,7 @@ pub enum TyFingerprint { | |||
35 | Adt(hir_def::AdtId), | 36 | Adt(hir_def::AdtId), |
36 | Dyn(TraitId), | 37 | Dyn(TraitId), |
37 | Tuple(usize), | 38 | Tuple(usize), |
38 | ForeignType(TypeAliasId), | 39 | ForeignType(ForeignDefId), |
39 | FnPtr(usize, FnSig), | 40 | FnPtr(usize, FnSig), |
40 | } | 41 | } |
41 | 42 | ||
@@ -44,18 +45,20 @@ impl TyFingerprint { | |||
44 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not | 45 | /// have impls: if we have some `struct S`, we can have an `impl S`, but not |
45 | /// `impl &S`. Hence, this will return `None` for reference types and such. | 46 | /// `impl &S`. Hence, this will return `None` for reference types and such. |
46 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { | 47 | pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { |
47 | let fp = match ty { | 48 | let fp = match *ty.interned(&Interner) { |
48 | &Ty::Str => TyFingerprint::Str, | 49 | TyKind::Str => TyFingerprint::Str, |
49 | &Ty::Never => TyFingerprint::Never, | 50 | TyKind::Never => TyFingerprint::Never, |
50 | &Ty::Slice(..) => TyFingerprint::Slice, | 51 | TyKind::Slice(..) => TyFingerprint::Slice, |
51 | &Ty::Array(..) => TyFingerprint::Array, | 52 | TyKind::Array(..) => TyFingerprint::Array, |
52 | &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), | 53 | TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar), |
53 | &Ty::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), | 54 | TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), |
54 | &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), | 55 | TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), |
55 | &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), | 56 | TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), |
56 | &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), | 57 | TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), |
57 | &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), | 58 | TyKind::Function(FnPointer { num_args, sig, .. }) => { |
58 | Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | 59 | TyFingerprint::FnPtr(num_args, sig) |
60 | } | ||
61 | TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, | ||
59 | _ => return None, | 62 | _ => return None, |
60 | }; | 63 | }; |
61 | Some(fp) | 64 | Some(fp) |
@@ -230,31 +233,33 @@ impl Ty { | |||
230 | 233 | ||
231 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); | 234 | let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); |
232 | 235 | ||
233 | let lang_item_targets = match self { | 236 | let lang_item_targets = match self.interned(&Interner) { |
234 | Ty::Adt(AdtId(def_id), _) => { | 237 | TyKind::Adt(AdtId(def_id), _) => { |
235 | return mod_to_crate_ids(def_id.module(db.upcast())); | 238 | return mod_to_crate_ids(def_id.module(db.upcast())); |
236 | } | 239 | } |
237 | Ty::ForeignType(type_alias_id) => { | 240 | TyKind::ForeignType(id) => { |
238 | return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); | 241 | return mod_to_crate_ids( |
242 | from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()), | ||
243 | ); | ||
239 | } | 244 | } |
240 | Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), | 245 | TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"), |
241 | Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), | 246 | TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"), |
242 | Ty::Scalar(Scalar::Float(f)) => match f { | 247 | TyKind::Scalar(Scalar::Float(f)) => match f { |
243 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) | 248 | // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) |
244 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), | 249 | FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), |
245 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), | 250 | FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), |
246 | }, | 251 | }, |
247 | &Ty::Scalar(Scalar::Int(t)) => { | 252 | &TyKind::Scalar(Scalar::Int(t)) => { |
248 | lang_item_crate!(primitive::int_ty_to_string(t)) | 253 | lang_item_crate!(primitive::int_ty_to_string(t)) |
249 | } | 254 | } |
250 | &Ty::Scalar(Scalar::Uint(t)) => { | 255 | &TyKind::Scalar(Scalar::Uint(t)) => { |
251 | lang_item_crate!(primitive::uint_ty_to_string(t)) | 256 | lang_item_crate!(primitive::uint_ty_to_string(t)) |
252 | } | 257 | } |
253 | Ty::Str => lang_item_crate!("str_alloc", "str"), | 258 | TyKind::Str => lang_item_crate!("str_alloc", "str"), |
254 | Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), | 259 | TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"), |
255 | Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), | 260 | TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), |
256 | Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), | 261 | TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), |
257 | Ty::Dyn(_) => { | 262 | TyKind::Dyn(_) => { |
258 | return self.dyn_trait().and_then(|trait_| { | 263 | return self.dyn_trait().and_then(|trait_| { |
259 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) | 264 | mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) |
260 | }); | 265 | }); |
@@ -430,7 +435,8 @@ fn iterate_method_candidates_with_autoref( | |||
430 | } | 435 | } |
431 | let refed = Canonical { | 436 | let refed = Canonical { |
432 | kinds: deref_chain[0].kinds.clone(), | 437 | kinds: deref_chain[0].kinds.clone(), |
433 | value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), | 438 | value: TyKind::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())) |
439 | .intern(&Interner), | ||
434 | }; | 440 | }; |
435 | if iterate_method_candidates_by_receiver( | 441 | if iterate_method_candidates_by_receiver( |
436 | &refed, | 442 | &refed, |
@@ -446,7 +452,8 @@ fn iterate_method_candidates_with_autoref( | |||
446 | } | 452 | } |
447 | let ref_muted = Canonical { | 453 | let ref_muted = Canonical { |
448 | kinds: deref_chain[0].kinds.clone(), | 454 | kinds: deref_chain[0].kinds.clone(), |
449 | value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), | 455 | value: TyKind::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())) |
456 | .intern(&Interner), | ||
450 | }; | 457 | }; |
451 | if iterate_method_candidates_by_receiver( | 458 | if iterate_method_candidates_by_receiver( |
452 | &ref_muted, | 459 | &ref_muted, |
@@ -526,10 +533,9 @@ fn iterate_trait_method_candidates( | |||
526 | // if ty is `dyn Trait`, the trait doesn't need to be in scope | 533 | // if ty is `dyn Trait`, the trait doesn't need to be in scope |
527 | let inherent_trait = | 534 | let inherent_trait = |
528 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); | 535 | self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); |
529 | let env_traits = if let Ty::Placeholder(_) = self_ty.value { | 536 | let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) { |
530 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope | 537 | // if we have `T: Trait` in the param env, the trait doesn't need to be in scope |
531 | env.trait_predicates_for_self_ty(&self_ty.value) | 538 | env.traits_in_scope_from_clauses(&self_ty.value) |
532 | .map(|tr| tr.trait_) | ||
533 | .flat_map(|t| all_super_traits(db.upcast(), t)) | 539 | .flat_map(|t| all_super_traits(db.upcast(), t)) |
534 | .collect() | 540 | .collect() |
535 | } else { | 541 | } else { |
@@ -680,13 +686,13 @@ pub(crate) fn inherent_impl_substs( | |||
680 | } | 686 | } |
681 | 687 | ||
682 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past | 688 | /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past |
683 | /// num_vars_to_keep) by `Ty::Unknown`. | 689 | /// num_vars_to_keep) by `TyKind::Unknown`. |
684 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { | 690 | fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { |
685 | s.fold_binders( | 691 | s.fold_binders( |
686 | &mut |ty, binders| { | 692 | &mut |ty, binders| { |
687 | if let Ty::BoundVar(bound) = &ty { | 693 | if let TyKind::BoundVar(bound) = ty.interned(&Interner) { |
688 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { | 694 | if bound.index >= num_vars_to_keep && bound.debruijn >= binders { |
689 | Ty::Unknown | 695 | TyKind::Unknown.intern(&Interner) |
690 | } else { | 696 | } else { |
691 | ty | 697 | ty |
692 | } | 698 | } |
@@ -773,9 +779,11 @@ fn autoderef_method_receiver( | |||
773 | ) -> Vec<Canonical<Ty>> { | 779 | ) -> Vec<Canonical<Ty>> { |
774 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); | 780 | let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); |
775 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) | 781 | // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) |
776 | if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { | 782 | if let Some(TyKind::Array(parameters)) = |
783 | deref_chain.last().map(|ty| ty.value.interned(&Interner)) | ||
784 | { | ||
777 | let kinds = deref_chain.last().unwrap().kinds.clone(); | 785 | let kinds = deref_chain.last().unwrap().kinds.clone(); |
778 | let unsized_ty = Ty::Slice(parameters.clone()); | 786 | let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner); |
779 | deref_chain.push(Canonical { value: unsized_ty, kinds }) | 787 | deref_chain.push(Canonical { value: unsized_ty, kinds }) |
780 | } | 788 | } |
781 | deref_chain | 789 | deref_chain |