diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits')
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 28 |
2 files changed, 27 insertions, 21 deletions
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs index 88a422d2c..6d5f2d46a 100644 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ b/crates/ra_hir_ty/src/traits/builtin.rs | |||
@@ -40,7 +40,7 @@ pub(super) fn get_builtin_impls( | |||
40 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { | 40 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { |
41 | for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() | 41 | for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() |
42 | { | 42 | { |
43 | if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { | 43 | if let Some(actual_trait) = fn_trait.get_id(db, krate) { |
44 | if trait_ == actual_trait { | 44 | if trait_ == actual_trait { |
45 | let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; | 45 | let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; |
46 | if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) { | 46 | if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) { |
@@ -128,7 +128,7 @@ fn check_closure_fn_trait_impl_prerequisites( | |||
128 | data: super::ClosureFnTraitImplData, | 128 | data: super::ClosureFnTraitImplData, |
129 | ) -> bool { | 129 | ) -> bool { |
130 | // the respective Fn/FnOnce/FnMut trait needs to exist | 130 | // the respective Fn/FnOnce/FnMut trait needs to exist |
131 | if get_fn_trait(db, krate, data.fn_trait).is_none() { | 131 | if data.fn_trait.get_id(db, krate).is_none() { |
132 | return false; | 132 | return false; |
133 | } | 133 | } |
134 | 134 | ||
@@ -136,7 +136,7 @@ fn check_closure_fn_trait_impl_prerequisites( | |||
136 | // the traits having no type params, FnOnce being a supertrait | 136 | // the traits having no type params, FnOnce being a supertrait |
137 | 137 | ||
138 | // the FnOnce trait needs to exist and have an assoc type named Output | 138 | // the FnOnce trait needs to exist and have an assoc type named Output |
139 | let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) { | 139 | let fn_once_trait = match (super::FnTrait::FnOnce).get_id(db, krate) { |
140 | Some(t) => t, | 140 | Some(t) => t, |
141 | None => return false, | 141 | None => return false, |
142 | }; | 142 | }; |
@@ -151,7 +151,9 @@ fn closure_fn_trait_impl_datum( | |||
151 | // for some closure |X, Y| -> Z: | 151 | // for some closure |X, Y| -> Z: |
152 | // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } | 152 | // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } |
153 | 153 | ||
154 | let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait | 154 | let trait_ = data |
155 | .fn_trait | ||
156 | .get_id(db, krate) // get corresponding fn trait | ||
155 | // the existence of the Fn trait has been checked before | 157 | // the existence of the Fn trait has been checked before |
156 | .expect("fn trait for closure impl missing"); | 158 | .expect("fn trait for closure impl missing"); |
157 | 159 | ||
@@ -211,7 +213,7 @@ fn closure_fn_trait_output_assoc_ty_value( | |||
211 | let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into())); | 213 | let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into())); |
212 | 214 | ||
213 | let fn_once_trait = | 215 | let fn_once_trait = |
214 | get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist"); | 216 | (super::FnTrait::FnOnce).get_id(db, krate).expect("assoc ty value should not exist"); |
215 | 217 | ||
216 | let output_ty_id = db | 218 | let output_ty_id = db |
217 | .trait_data(fn_once_trait) | 219 | .trait_data(fn_once_trait) |
@@ -360,14 +362,6 @@ fn super_trait_object_unsize_impl_datum( | |||
360 | BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() } | 362 | BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() } |
361 | } | 363 | } |
362 | 364 | ||
363 | fn get_fn_trait(db: &dyn HirDatabase, krate: CrateId, fn_trait: super::FnTrait) -> Option<TraitId> { | ||
364 | let target = db.lang_item(krate, fn_trait.lang_item_name().into())?; | ||
365 | match target { | ||
366 | LangItemTarget::TraitId(t) => Some(t), | ||
367 | _ => None, | ||
368 | } | ||
369 | } | ||
370 | |||
371 | fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> { | 365 | fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> { |
372 | let target = db.lang_item(krate, "unsize".into())?; | 366 | let target = db.lang_item(krate, "unsize".into())?; |
373 | match target { | 367 | match target { |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index a72a82f5a..2f35d6d49 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -74,14 +74,26 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
74 | // Note: Since we're using impls_for_trait, only impls where the trait | 74 | // Note: Since we're using impls_for_trait, only impls where the trait |
75 | // can be resolved should ever reach Chalk. `impl_datum` relies on that | 75 | // can be resolved should ever reach Chalk. `impl_datum` relies on that |
76 | // and will panic if the trait can't be resolved. | 76 | // and will panic if the trait can't be resolved. |
77 | let mut result: Vec<_> = self | 77 | let in_deps = self.db.impls_from_deps(self.krate); |
78 | .db | 78 | let in_self = self.db.impls_in_crate(self.krate); |
79 | .impls_for_trait(self.krate, trait_, self_ty_fp) | 79 | let impl_maps = [in_deps, in_self]; |
80 | .iter() | 80 | |
81 | .copied() | 81 | let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); |
82 | .map(Impl::ImplDef) | 82 | |
83 | .map(|impl_| impl_.to_chalk(self.db)) | 83 | let mut result: Vec<_> = match self_ty_fp { |
84 | .collect(); | 84 | Some(fp) => impl_maps |
85 | .iter() | ||
86 | .flat_map(|crate_impl_defs| { | ||
87 | crate_impl_defs.lookup_impl_defs_for_trait_and_ty(trait_, fp).map(id_to_chalk) | ||
88 | }) | ||
89 | .collect(), | ||
90 | None => impl_maps | ||
91 | .iter() | ||
92 | .flat_map(|crate_impl_defs| { | ||
93 | crate_impl_defs.lookup_impl_defs_for_trait(trait_).map(id_to_chalk) | ||
94 | }) | ||
95 | .collect(), | ||
96 | }; | ||
85 | 97 | ||
86 | let arg: Option<Ty> = | 98 | let arg: Option<Ty> = |
87 | parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone())); | 99 | parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone())); |