diff options
author | Florian Diebold <[email protected]> | 2019-12-21 14:00:44 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-12-22 23:08:03 +0000 |
commit | 4053fcfca0e33f133c53fa755c1b1bcc0b4c11bb (patch) | |
tree | 6a77ae7692757830e4c0f5966824b6cd6979d4a2 /crates/ra_hir_ty/src/traits/builtin.rs | |
parent | 6b5efe5bdab160278469417734f4bb619c7bac61 (diff) |
Introduce our own Chalk TypeFamily, instead of using ChalkIr
It's not very different, except we can directly use Salsa IDs instead of casting
them. This means we need to refactor the handling of errors to get rid of
UNKNOWN_TRAIT though.
Diffstat (limited to 'crates/ra_hir_ty/src/traits/builtin.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs index cd587a338..dd41176f0 100644 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ b/crates/ra_hir_ty/src/traits/builtin.rs | |||
@@ -28,24 +28,24 @@ pub(super) fn get_builtin_impls( | |||
28 | trait_: TraitId, | 28 | trait_: TraitId, |
29 | mut callback: impl FnMut(Impl), | 29 | mut callback: impl FnMut(Impl), |
30 | ) { | 30 | ) { |
31 | // Note: since impl_datum needs to be infallible, we need to make sure here | ||
32 | // that we have all prerequisites to build the respective impls. | ||
31 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { | 33 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { def, expr }, .. }) = ty { |
32 | for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() | 34 | for &fn_trait in [super::FnTrait::FnOnce, super::FnTrait::FnMut, super::FnTrait::Fn].iter() |
33 | { | 35 | { |
34 | if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { | 36 | if let Some(actual_trait) = get_fn_trait(db, krate, fn_trait) { |
35 | if trait_ == actual_trait { | 37 | if trait_ == actual_trait { |
36 | let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; | 38 | let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; |
37 | callback(Impl::ClosureFnTraitImpl(impl_)); | 39 | if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) { |
40 | callback(Impl::ClosureFnTraitImpl(impl_)); | ||
41 | } | ||
38 | } | 42 | } |
39 | } | 43 | } |
40 | } | 44 | } |
41 | } | 45 | } |
42 | } | 46 | } |
43 | 47 | ||
44 | pub(super) fn impl_datum( | 48 | pub(super) fn impl_datum(db: &impl HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData { |
45 | db: &impl HirDatabase, | ||
46 | krate: CrateId, | ||
47 | impl_: Impl, | ||
48 | ) -> Option<BuiltinImplData> { | ||
49 | match impl_ { | 49 | match impl_ { |
50 | Impl::ImplBlock(_) => unreachable!(), | 50 | Impl::ImplBlock(_) => unreachable!(), |
51 | Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), | 51 | Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), |
@@ -65,21 +65,38 @@ pub(super) fn associated_ty_value( | |||
65 | } | 65 | } |
66 | } | 66 | } |
67 | 67 | ||
68 | fn check_closure_fn_trait_impl_prerequisites( | ||
69 | db: &impl HirDatabase, | ||
70 | krate: CrateId, | ||
71 | data: super::ClosureFnTraitImplData, | ||
72 | ) -> bool { | ||
73 | // the respective Fn/FnOnce/FnMut trait needs to exist | ||
74 | if get_fn_trait(db, krate, data.fn_trait).is_none() { | ||
75 | return false; | ||
76 | } | ||
77 | |||
78 | // FIXME: there are more assumptions that we should probably check here: | ||
79 | // the traits having no type params, FnOnce being a supertrait | ||
80 | |||
81 | // the FnOnce trait needs to exist and have an assoc type named Output | ||
82 | let fn_once_trait = match get_fn_trait(db, krate, super::FnTrait::FnOnce) { | ||
83 | Some(t) => t, | ||
84 | None => return false, | ||
85 | }; | ||
86 | db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some() | ||
87 | } | ||
88 | |||
68 | fn closure_fn_trait_impl_datum( | 89 | fn closure_fn_trait_impl_datum( |
69 | db: &impl HirDatabase, | 90 | db: &impl HirDatabase, |
70 | krate: CrateId, | 91 | krate: CrateId, |
71 | data: super::ClosureFnTraitImplData, | 92 | data: super::ClosureFnTraitImplData, |
72 | ) -> Option<BuiltinImplData> { | 93 | ) -> BuiltinImplData { |
73 | // for some closure |X, Y| -> Z: | 94 | // for some closure |X, Y| -> Z: |
74 | // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } | 95 | // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } |
75 | 96 | ||
76 | let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait | 97 | let trait_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait |
77 | 98 | // the existence of the Fn trait has been checked before | |
78 | // validate FnOnce trait, since we need it in the assoc ty value definition | 99 | .expect("fn trait for closure impl missing"); |
79 | // and don't want to return a valid value only to find out later that FnOnce | ||
80 | // is broken | ||
81 | let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?; | ||
82 | let _output = db.trait_data(fn_once_trait).associated_type_by_name(&name![Output])?; | ||
83 | 100 | ||
84 | let num_args: u16 = match &db.body(data.def.into())[data.expr] { | 101 | let num_args: u16 = match &db.body(data.def.into())[data.expr] { |
85 | Expr::Lambda { args, .. } => args.len() as u16, | 102 | Expr::Lambda { args, .. } => args.len() as u16, |
@@ -107,12 +124,12 @@ fn closure_fn_trait_impl_datum( | |||
107 | 124 | ||
108 | let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()); | 125 | let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data.clone()); |
109 | 126 | ||
110 | Some(BuiltinImplData { | 127 | BuiltinImplData { |
111 | num_vars: num_args as usize + 1, | 128 | num_vars: num_args as usize + 1, |
112 | trait_ref, | 129 | trait_ref, |
113 | where_clauses: Vec::new(), | 130 | where_clauses: Vec::new(), |
114 | assoc_ty_values: vec![output_ty_id], | 131 | assoc_ty_values: vec![output_ty_id], |
115 | }) | 132 | } |
116 | } | 133 | } |
117 | 134 | ||
118 | fn closure_fn_trait_output_assoc_ty_value( | 135 | fn closure_fn_trait_output_assoc_ty_value( |