diff options
author | Florian Diebold <[email protected]> | 2020-02-21 18:05:27 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-02-22 10:09:21 +0000 |
commit | 0dfbbaf03b03618dcb7ba203ddc453533bb8d1b4 (patch) | |
tree | ef862c881d191030007f6b6ef40ce2250d45c916 /crates/ra_hir_ty/src/traits | |
parent | de39d221a15c0a146ed8adbdb1616692180948bb (diff) |
Implement dyn Trait unsizing as well
Diffstat (limited to 'crates/ra_hir_ty/src/traits')
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 112 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 4 |
2 files changed, 108 insertions, 8 deletions
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs index 394232fd9..3c8dd4af8 100644 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ b/crates/ra_hir_ty/src/traits/builtin.rs | |||
@@ -4,8 +4,12 @@ use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId}; | |||
4 | use hir_expand::name::name; | 4 | use hir_expand::name::name; |
5 | use ra_db::CrateId; | 5 | use ra_db::CrateId; |
6 | 6 | ||
7 | use super::{AssocTyValue, Impl}; | 7 | use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData}; |
8 | use crate::{db::HirDatabase, utils::generics, ApplicationTy, Substs, TraitRef, Ty, TypeCtor}; | 8 | use crate::{ |
9 | db::HirDatabase, | ||
10 | utils::{all_super_traits, generics}, | ||
11 | ApplicationTy, GenericPredicate, Substs, TraitRef, Ty, TypeCtor, | ||
12 | }; | ||
9 | 13 | ||
10 | pub(super) struct BuiltinImplData { | 14 | pub(super) struct BuiltinImplData { |
11 | pub num_vars: usize, | 15 | pub num_vars: usize, |
@@ -25,6 +29,8 @@ pub(super) fn get_builtin_impls( | |||
25 | db: &impl HirDatabase, | 29 | db: &impl HirDatabase, |
26 | krate: CrateId, | 30 | krate: CrateId, |
27 | ty: &Ty, | 31 | ty: &Ty, |
32 | // The first argument for the trait, if present | ||
33 | arg: &Option<Ty>, | ||
28 | trait_: TraitId, | 34 | trait_: TraitId, |
29 | mut callback: impl FnMut(Impl), | 35 | mut callback: impl FnMut(Impl), |
30 | ) { | 36 | ) { |
@@ -43,14 +49,43 @@ pub(super) fn get_builtin_impls( | |||
43 | } | 49 | } |
44 | } | 50 | } |
45 | } | 51 | } |
52 | |||
53 | let unsize_trait = get_unsize_trait(db, krate); | ||
54 | if let Some(actual_trait) = unsize_trait { | ||
55 | if trait_ == actual_trait { | ||
56 | get_builtin_unsize_impls(db, krate, ty, arg, callback); | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | |||
61 | fn get_builtin_unsize_impls( | ||
62 | db: &impl HirDatabase, | ||
63 | krate: CrateId, | ||
64 | ty: &Ty, | ||
65 | // The first argument for the trait, if present | ||
66 | arg: &Option<Ty>, | ||
67 | mut callback: impl FnMut(Impl), | ||
68 | ) { | ||
69 | if !check_unsize_impl_prerequisites(db, krate) { | ||
70 | return; | ||
71 | } | ||
72 | |||
46 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, .. }) = ty { | 73 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, .. }) = ty { |
47 | if let Some(actual_trait) = get_unsize_trait(db, krate) { | 74 | callback(Impl::UnsizeArray); |
48 | if trait_ == actual_trait { | 75 | } |
49 | if check_unsize_impl_prerequisites(db, krate) { | 76 | |
50 | callback(Impl::UnsizeArray); | 77 | if let Some(target_trait) = arg.as_ref().and_then(|t| t.dyn_trait_ref()) { |
51 | } | 78 | if let Some(trait_ref) = ty.dyn_trait_ref() { |
79 | let super_traits = all_super_traits(db, trait_ref.trait_); | ||
80 | if super_traits.contains(&target_trait.trait_) { | ||
81 | // callback(Impl::UnsizeToSuperTraitObject(UnsizeToSuperTraitObjectData { | ||
82 | // trait_: trait_ref.trait_, | ||
83 | // super_trait: target_trait.trait_, | ||
84 | // })); | ||
52 | } | 85 | } |
53 | } | 86 | } |
87 | |||
88 | callback(Impl::UnsizeToTraitObject(target_trait.trait_)); | ||
54 | } | 89 | } |
55 | } | 90 | } |
56 | 91 | ||
@@ -59,6 +94,10 @@ pub(super) fn impl_datum(db: &impl HirDatabase, krate: CrateId, impl_: Impl) -> | |||
59 | Impl::ImplBlock(_) => unreachable!(), | 94 | Impl::ImplBlock(_) => unreachable!(), |
60 | Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), | 95 | Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), |
61 | Impl::UnsizeArray => array_unsize_impl_datum(db, krate), | 96 | Impl::UnsizeArray => array_unsize_impl_datum(db, krate), |
97 | Impl::UnsizeToTraitObject(trait_) => trait_object_unsize_impl_datum(db, krate, trait_), | ||
98 | Impl::UnsizeToSuperTraitObject(data) => { | ||
99 | super_trait_object_unsize_impl_datum(db, krate, data) | ||
100 | } | ||
62 | } | 101 | } |
63 | } | 102 | } |
64 | 103 | ||
@@ -216,6 +255,65 @@ fn array_unsize_impl_datum(db: &impl HirDatabase, krate: CrateId) -> BuiltinImpl | |||
216 | } | 255 | } |
217 | } | 256 | } |
218 | 257 | ||
258 | // Trait object unsizing | ||
259 | |||
260 | fn trait_object_unsize_impl_datum( | ||
261 | db: &impl HirDatabase, | ||
262 | krate: CrateId, | ||
263 | trait_: TraitId, | ||
264 | ) -> BuiltinImplData { | ||
265 | // impl<T, T1, ...> Unsize<dyn Trait<T1, ...>> for T where T: Trait<T1, ...> | ||
266 | |||
267 | let unsize_trait = get_unsize_trait(db, krate) // get unsize trait | ||
268 | // the existence of the Unsize trait has been checked before | ||
269 | .expect("Unsize trait missing"); | ||
270 | |||
271 | let self_ty = Ty::Bound(0); | ||
272 | |||
273 | let substs = Substs::build_for_def(db, trait_) | ||
274 | // this fits together nicely: $0 is our self type, and the rest are the type | ||
275 | // args for the trait | ||
276 | .fill_with_bound_vars(0) | ||
277 | .build(); | ||
278 | let trait_ref = TraitRef { trait_, substs }; | ||
279 | // This is both the bound for the `dyn` type, *and* the bound for the impl! | ||
280 | // This works because the self type for `dyn` is always Ty::Bound(0), which | ||
281 | // we've also made the parameter for our impl self type. | ||
282 | let bounds = vec![GenericPredicate::Implemented(trait_ref)]; | ||
283 | |||
284 | let impl_substs = Substs::builder(2).push(self_ty).push(Ty::Dyn(bounds.clone().into())).build(); | ||
285 | |||
286 | let trait_ref = TraitRef { trait_: unsize_trait, substs: impl_substs }; | ||
287 | |||
288 | BuiltinImplData { num_vars: 1, trait_ref, where_clauses: bounds, assoc_ty_values: Vec::new() } | ||
289 | } | ||
290 | |||
291 | fn super_trait_object_unsize_impl_datum( | ||
292 | db: &impl HirDatabase, | ||
293 | krate: CrateId, | ||
294 | _data: UnsizeToSuperTraitObjectData, | ||
295 | ) -> BuiltinImplData { | ||
296 | // impl Unsize<dyn SuperTrait> for dyn Trait | ||
297 | |||
298 | let unsize_trait = get_unsize_trait(db, krate) // get unsize trait | ||
299 | // the existence of the Unsize trait has been checked before | ||
300 | .expect("Unsize trait missing"); | ||
301 | |||
302 | let substs = Substs::builder(2) | ||
303 | // .push(Ty::Dyn(todo!())) | ||
304 | // .push(Ty::Dyn(todo!())) | ||
305 | .build(); | ||
306 | |||
307 | let trait_ref = TraitRef { trait_: unsize_trait, substs }; | ||
308 | |||
309 | BuiltinImplData { | ||
310 | num_vars: 1, | ||
311 | trait_ref, | ||
312 | where_clauses: Vec::new(), | ||
313 | assoc_ty_values: Vec::new(), | ||
314 | } | ||
315 | } | ||
316 | |||
219 | fn get_fn_trait( | 317 | fn get_fn_trait( |
220 | db: &impl HirDatabase, | 318 | db: &impl HirDatabase, |
221 | krate: CrateId, | 319 | krate: CrateId, |
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index 1bdf13e48..e1e430aeb 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -572,8 +572,10 @@ where | |||
572 | .collect(); | 572 | .collect(); |
573 | 573 | ||
574 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref().clone()); | 574 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref().clone()); |
575 | let arg: Option<Ty> = | ||
576 | parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref().clone())); | ||
575 | 577 | ||
576 | builtin::get_builtin_impls(self.db, self.krate, &ty, trait_, |i| { | 578 | builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| { |
577 | result.push(i.to_chalk(self.db)) | 579 | result.push(i.to_chalk(self.db)) |
578 | }); | 580 | }); |
579 | 581 | ||