diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits')
-rw-r--r-- | crates/ra_hir_ty/src/traits/builtin.rs | 371 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 182 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/interner.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/mapping.rs | 184 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk/tls.rs | 28 |
5 files changed, 241 insertions, 553 deletions
diff --git a/crates/ra_hir_ty/src/traits/builtin.rs b/crates/ra_hir_ty/src/traits/builtin.rs deleted file mode 100644 index 6d5f2d46a..000000000 --- a/crates/ra_hir_ty/src/traits/builtin.rs +++ /dev/null | |||
@@ -1,371 +0,0 @@ | |||
1 | //! This module provides the built-in trait implementations, e.g. to make | ||
2 | //! closures implement `Fn`. | ||
3 | use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId}; | ||
4 | use hir_expand::name::name; | ||
5 | use ra_db::CrateId; | ||
6 | |||
7 | use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData}; | ||
8 | use crate::{ | ||
9 | db::HirDatabase, | ||
10 | utils::{all_super_traits, generics}, | ||
11 | ApplicationTy, Binders, BoundVar, DebruijnIndex, GenericPredicate, Substs, TraitRef, Ty, | ||
12 | TypeCtor, TypeWalk, | ||
13 | }; | ||
14 | |||
15 | pub(super) struct BuiltinImplData { | ||
16 | pub num_vars: usize, | ||
17 | pub trait_ref: TraitRef, | ||
18 | pub where_clauses: Vec<super::GenericPredicate>, | ||
19 | pub assoc_ty_values: Vec<AssocTyValue>, | ||
20 | } | ||
21 | |||
22 | pub(super) struct BuiltinImplAssocTyValueData { | ||
23 | pub impl_: Impl, | ||
24 | pub assoc_ty_id: TypeAliasId, | ||
25 | pub num_vars: usize, | ||
26 | pub value: Ty, | ||
27 | } | ||
28 | |||
29 | pub(super) fn get_builtin_impls( | ||
30 | db: &dyn HirDatabase, | ||
31 | krate: CrateId, | ||
32 | ty: &Ty, | ||
33 | // The first argument for the trait, if present | ||
34 | arg: &Option<Ty>, | ||
35 | trait_: TraitId, | ||
36 | mut callback: impl FnMut(Impl), | ||
37 | ) { | ||
38 | // Note: since impl_datum needs to be infallible, we need to make sure here | ||
39 | // that we have all prerequisites to build the respective impls. | ||
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() | ||
42 | { | ||
43 | if let Some(actual_trait) = fn_trait.get_id(db, krate) { | ||
44 | if trait_ == actual_trait { | ||
45 | let impl_ = super::ClosureFnTraitImplData { def: *def, expr: *expr, fn_trait }; | ||
46 | if check_closure_fn_trait_impl_prerequisites(db, krate, impl_) { | ||
47 | callback(Impl::ClosureFnTraitImpl(impl_)); | ||
48 | } | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | let unsize_trait = get_unsize_trait(db, krate); | ||
55 | if let Some(actual_trait) = unsize_trait { | ||
56 | if trait_ == actual_trait { | ||
57 | get_builtin_unsize_impls(db, krate, ty, arg, callback); | ||
58 | } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | fn get_builtin_unsize_impls( | ||
63 | db: &dyn HirDatabase, | ||
64 | krate: CrateId, | ||
65 | ty: &Ty, | ||
66 | // The first argument for the trait, if present | ||
67 | arg: &Option<Ty>, | ||
68 | mut callback: impl FnMut(Impl), | ||
69 | ) { | ||
70 | if !check_unsize_impl_prerequisites(db, krate) { | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, .. }) = ty { | ||
75 | callback(Impl::UnsizeArray); | ||
76 | return; // array is unsized, the rest of the impls shouldn't apply | ||
77 | } | ||
78 | |||
79 | if let Some(target_trait) = arg.as_ref().and_then(|t| t.dyn_trait_ref()) { | ||
80 | // FIXME what about more complicated dyn tys with marker traits? | ||
81 | if let Some(trait_ref) = ty.dyn_trait_ref() { | ||
82 | if trait_ref.trait_ != target_trait.trait_ { | ||
83 | let super_traits = all_super_traits(db.upcast(), trait_ref.trait_); | ||
84 | if super_traits.contains(&target_trait.trait_) { | ||
85 | callback(Impl::UnsizeToSuperTraitObject(UnsizeToSuperTraitObjectData { | ||
86 | trait_: trait_ref.trait_, | ||
87 | super_trait: target_trait.trait_, | ||
88 | })); | ||
89 | } | ||
90 | } | ||
91 | } else { | ||
92 | // FIXME only for sized types | ||
93 | callback(Impl::UnsizeToTraitObject(target_trait.trait_)); | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | |||
98 | pub(super) fn impl_datum(db: &dyn HirDatabase, krate: CrateId, impl_: Impl) -> BuiltinImplData { | ||
99 | match impl_ { | ||
100 | Impl::ImplDef(_) => unreachable!(), | ||
101 | Impl::ClosureFnTraitImpl(data) => closure_fn_trait_impl_datum(db, krate, data), | ||
102 | Impl::UnsizeArray => array_unsize_impl_datum(db, krate), | ||
103 | Impl::UnsizeToTraitObject(trait_) => trait_object_unsize_impl_datum(db, krate, trait_), | ||
104 | Impl::UnsizeToSuperTraitObject(data) => { | ||
105 | super_trait_object_unsize_impl_datum(db, krate, data) | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | pub(super) fn associated_ty_value( | ||
111 | db: &dyn HirDatabase, | ||
112 | krate: CrateId, | ||
113 | data: AssocTyValue, | ||
114 | ) -> BuiltinImplAssocTyValueData { | ||
115 | match data { | ||
116 | AssocTyValue::TypeAlias(_) => unreachable!(), | ||
117 | AssocTyValue::ClosureFnTraitImplOutput(data) => { | ||
118 | closure_fn_trait_output_assoc_ty_value(db, krate, data) | ||
119 | } | ||
120 | } | ||
121 | } | ||
122 | |||
123 | // Closure Fn trait impls | ||
124 | |||
125 | fn check_closure_fn_trait_impl_prerequisites( | ||
126 | db: &dyn HirDatabase, | ||
127 | krate: CrateId, | ||
128 | data: super::ClosureFnTraitImplData, | ||
129 | ) -> bool { | ||
130 | // the respective Fn/FnOnce/FnMut trait needs to exist | ||
131 | if data.fn_trait.get_id(db, krate).is_none() { | ||
132 | return false; | ||
133 | } | ||
134 | |||
135 | // FIXME: there are more assumptions that we should probably check here: | ||
136 | // the traits having no type params, FnOnce being a supertrait | ||
137 | |||
138 | // the FnOnce trait needs to exist and have an assoc type named Output | ||
139 | let fn_once_trait = match (super::FnTrait::FnOnce).get_id(db, krate) { | ||
140 | Some(t) => t, | ||
141 | None => return false, | ||
142 | }; | ||
143 | db.trait_data(fn_once_trait).associated_type_by_name(&name![Output]).is_some() | ||
144 | } | ||
145 | |||
146 | fn closure_fn_trait_impl_datum( | ||
147 | db: &dyn HirDatabase, | ||
148 | krate: CrateId, | ||
149 | data: super::ClosureFnTraitImplData, | ||
150 | ) -> BuiltinImplData { | ||
151 | // for some closure |X, Y| -> Z: | ||
152 | // impl<T, U, V> Fn<(T, U)> for closure<fn(T, U) -> V> { Output = V } | ||
153 | |||
154 | let trait_ = data | ||
155 | .fn_trait | ||
156 | .get_id(db, krate) // get corresponding fn trait | ||
157 | // the existence of the Fn trait has been checked before | ||
158 | .expect("fn trait for closure impl missing"); | ||
159 | |||
160 | let num_args: u16 = match &db.body(data.def)[data.expr] { | ||
161 | Expr::Lambda { args, .. } => args.len() as u16, | ||
162 | _ => { | ||
163 | log::warn!("closure for closure type {:?} not found", data); | ||
164 | 0 | ||
165 | } | ||
166 | }; | ||
167 | |||
168 | let arg_ty = Ty::apply( | ||
169 | TypeCtor::Tuple { cardinality: num_args }, | ||
170 | Substs::builder(num_args as usize) | ||
171 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) | ||
172 | .build(), | ||
173 | ); | ||
174 | let sig_ty = Ty::apply( | ||
175 | TypeCtor::FnPtr { num_args }, | ||
176 | Substs::builder(num_args as usize + 1) | ||
177 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) | ||
178 | .build(), | ||
179 | ); | ||
180 | |||
181 | let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty); | ||
182 | |||
183 | let trait_ref = TraitRef { | ||
184 | trait_, | ||
185 | substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(), | ||
186 | }; | ||
187 | |||
188 | let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data); | ||
189 | |||
190 | BuiltinImplData { | ||
191 | num_vars: num_args as usize + 1, | ||
192 | trait_ref, | ||
193 | where_clauses: Vec::new(), | ||
194 | assoc_ty_values: vec![output_ty_id], | ||
195 | } | ||
196 | } | ||
197 | |||
198 | fn closure_fn_trait_output_assoc_ty_value( | ||
199 | db: &dyn HirDatabase, | ||
200 | krate: CrateId, | ||
201 | data: super::ClosureFnTraitImplData, | ||
202 | ) -> BuiltinImplAssocTyValueData { | ||
203 | let impl_ = Impl::ClosureFnTraitImpl(data); | ||
204 | |||
205 | let num_args: u16 = match &db.body(data.def)[data.expr] { | ||
206 | Expr::Lambda { args, .. } => args.len() as u16, | ||
207 | _ => { | ||
208 | log::warn!("closure for closure type {:?} not found", data); | ||
209 | 0 | ||
210 | } | ||
211 | }; | ||
212 | |||
213 | let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into())); | ||
214 | |||
215 | let fn_once_trait = | ||
216 | (super::FnTrait::FnOnce).get_id(db, krate).expect("assoc ty value should not exist"); | ||
217 | |||
218 | let output_ty_id = db | ||
219 | .trait_data(fn_once_trait) | ||
220 | .associated_type_by_name(&name![Output]) | ||
221 | .expect("assoc ty value should not exist"); | ||
222 | |||
223 | BuiltinImplAssocTyValueData { | ||
224 | impl_, | ||
225 | assoc_ty_id: output_ty_id, | ||
226 | num_vars: num_args as usize + 1, | ||
227 | value: output_ty, | ||
228 | } | ||
229 | } | ||
230 | |||
231 | // Array unsizing | ||
232 | |||
233 | fn check_unsize_impl_prerequisites(db: &dyn HirDatabase, krate: CrateId) -> bool { | ||
234 | // the Unsize trait needs to exist and have two type parameters (Self and T) | ||
235 | let unsize_trait = match get_unsize_trait(db, krate) { | ||
236 | Some(t) => t, | ||
237 | None => return false, | ||
238 | }; | ||
239 | let generic_params = generics(db.upcast(), unsize_trait.into()); | ||
240 | generic_params.len() == 2 | ||
241 | } | ||
242 | |||
243 | fn array_unsize_impl_datum(db: &dyn HirDatabase, krate: CrateId) -> BuiltinImplData { | ||
244 | // impl<T> Unsize<[T]> for [T; _] | ||
245 | // (this can be a single impl because we don't distinguish array sizes currently) | ||
246 | |||
247 | let trait_ = get_unsize_trait(db, krate) // get unsize trait | ||
248 | // the existence of the Unsize trait has been checked before | ||
249 | .expect("Unsize trait missing"); | ||
250 | |||
251 | let var = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | ||
252 | let substs = Substs::builder(2) | ||
253 | .push(Ty::apply_one(TypeCtor::Array, var.clone())) | ||
254 | .push(Ty::apply_one(TypeCtor::Slice, var)) | ||
255 | .build(); | ||
256 | |||
257 | let trait_ref = TraitRef { trait_, substs }; | ||
258 | |||
259 | BuiltinImplData { | ||
260 | num_vars: 1, | ||
261 | trait_ref, | ||
262 | where_clauses: Vec::new(), | ||
263 | assoc_ty_values: Vec::new(), | ||
264 | } | ||
265 | } | ||
266 | |||
267 | // Trait object unsizing | ||
268 | |||
269 | fn trait_object_unsize_impl_datum( | ||
270 | db: &dyn HirDatabase, | ||
271 | krate: CrateId, | ||
272 | trait_: TraitId, | ||
273 | ) -> BuiltinImplData { | ||
274 | // impl<T, T1, ...> Unsize<dyn Trait<T1, ...>> for T where T: Trait<T1, ...> | ||
275 | |||
276 | let unsize_trait = get_unsize_trait(db, krate) // get unsize trait | ||
277 | // the existence of the Unsize trait has been checked before | ||
278 | .expect("Unsize trait missing"); | ||
279 | |||
280 | let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); | ||
281 | |||
282 | let target_substs = Substs::build_for_def(db, trait_) | ||
283 | .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0))) | ||
284 | .fill_with_bound_vars(DebruijnIndex::ONE, 1) | ||
285 | .build(); | ||
286 | let num_vars = target_substs.len(); | ||
287 | let target_trait_ref = TraitRef { trait_, substs: target_substs }; | ||
288 | let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)]; | ||
289 | |||
290 | let self_substs = | ||
291 | Substs::build_for_def(db, trait_).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build(); | ||
292 | let self_trait_ref = TraitRef { trait_, substs: self_substs }; | ||
293 | let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)]; | ||
294 | |||
295 | let impl_substs = Substs::builder(2).push(self_ty).push(Ty::Dyn(target_bounds.into())).build(); | ||
296 | |||
297 | let trait_ref = TraitRef { trait_: unsize_trait, substs: impl_substs }; | ||
298 | |||
299 | BuiltinImplData { num_vars, trait_ref, where_clauses, assoc_ty_values: Vec::new() } | ||
300 | } | ||
301 | |||
302 | fn super_trait_object_unsize_impl_datum( | ||
303 | db: &dyn HirDatabase, | ||
304 | krate: CrateId, | ||
305 | data: UnsizeToSuperTraitObjectData, | ||
306 | ) -> BuiltinImplData { | ||
307 | // impl<T1, ...> Unsize<dyn SuperTrait> for dyn Trait<T1, ...> | ||
308 | |||
309 | let unsize_trait = get_unsize_trait(db, krate) // get unsize trait | ||
310 | // the existence of the Unsize trait has been checked before | ||
311 | .expect("Unsize trait missing"); | ||
312 | |||
313 | let self_substs = Substs::build_for_def(db, data.trait_) | ||
314 | .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0) | ||
315 | .build(); | ||
316 | let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() }; | ||
317 | |||
318 | let num_vars = self_substs.len() - 1; | ||
319 | |||
320 | // we need to go from our trait to the super trait, substituting type parameters | ||
321 | let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait); | ||
322 | |||
323 | let mut current_trait_ref = self_trait_ref.clone(); | ||
324 | for t in path.into_iter().skip(1) { | ||
325 | let bounds = db.generic_predicates(current_trait_ref.trait_.into()); | ||
326 | let super_trait_ref = bounds | ||
327 | .iter() | ||
328 | .find_map(|b| match &b.value { | ||
329 | GenericPredicate::Implemented(tr) | ||
330 | if tr.trait_ == t | ||
331 | && tr.substs[0] | ||
332 | == Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)) => | ||
333 | { | ||
334 | Some(Binders { value: tr, num_binders: b.num_binders }) | ||
335 | } | ||
336 | _ => None, | ||
337 | }) | ||
338 | .expect("trait bound for known super trait not found"); | ||
339 | current_trait_ref = super_trait_ref.cloned().subst(¤t_trait_ref.substs); | ||
340 | } | ||
341 | |||
342 | // We need to renumber the variables a bit now: from ^0.0, ^0.1, ^0.2, ... | ||
343 | // to ^0.0, ^1.0, ^1.1. The reason for this is that the first variable comes | ||
344 | // from the dyn Trait binder, while the other variables come from the impl. | ||
345 | let new_substs = Substs::builder(num_vars + 1) | ||
346 | .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0))) | ||
347 | .fill_with_bound_vars(DebruijnIndex::ONE, 0) | ||
348 | .build(); | ||
349 | |||
350 | let self_bounds = | ||
351 | vec![GenericPredicate::Implemented(self_trait_ref.subst_bound_vars(&new_substs))]; | ||
352 | let super_bounds = | ||
353 | vec![GenericPredicate::Implemented(current_trait_ref.subst_bound_vars(&new_substs))]; | ||
354 | |||
355 | let substs = Substs::builder(2) | ||
356 | .push(Ty::Dyn(self_bounds.into())) | ||
357 | .push(Ty::Dyn(super_bounds.into())) | ||
358 | .build(); | ||
359 | |||
360 | let trait_ref = TraitRef { trait_: unsize_trait, substs }; | ||
361 | |||
362 | BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() } | ||
363 | } | ||
364 | |||
365 | fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> { | ||
366 | let target = db.lang_item(krate, "unsize".into())?; | ||
367 | match target { | ||
368 | LangItemTarget::TraitId(t) => Some(t), | ||
369 | _ => None, | ||
370 | } | ||
371 | } | ||
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index c97b81d57..5298dbecf 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -3,7 +3,7 @@ use std::sync::Arc; | |||
3 | 3 | ||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; | 6 | use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName}; |
7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; | 7 | use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait}; |
8 | 8 | ||
9 | use hir_def::{ | 9 | use hir_def::{ |
@@ -12,12 +12,17 @@ use hir_def::{ | |||
12 | }; | 12 | }; |
13 | use ra_db::{salsa::InternKey, CrateId}; | 13 | use ra_db::{salsa::InternKey, CrateId}; |
14 | 14 | ||
15 | use super::{builtin, AssocTyValue, ChalkContext, Impl}; | 15 | use super::ChalkContext; |
16 | use crate::{ | 16 | use crate::{ |
17 | db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics, | 17 | db::HirDatabase, |
18 | CallableDef, DebruijnIndex, GenericPredicate, Substs, Ty, TypeCtor, | 18 | display::HirDisplay, |
19 | method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, | ||
20 | utils::generics, | ||
21 | CallableDefId, DebruijnIndex, FnSig, GenericPredicate, Substs, Ty, TypeCtor, | ||
22 | }; | ||
23 | use mapping::{ | ||
24 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | ||
19 | }; | 25 | }; |
20 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders}; | ||
21 | 26 | ||
22 | pub use self::interner::*; | 27 | pub use self::interner::*; |
23 | 28 | ||
@@ -49,7 +54,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
49 | self.db.struct_datum(self.krate, struct_id) | 54 | self.db.struct_datum(self.krate, struct_id) |
50 | } | 55 | } |
51 | fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr { | 56 | fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr { |
52 | unreachable!() | 57 | rust_ir::AdtRepr { repr_c: false, repr_packed: false } |
53 | } | 58 | } |
54 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { | 59 | fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { |
55 | self.db.impl_datum(self.krate, impl_id) | 60 | self.db.impl_datum(self.krate, impl_id) |
@@ -66,13 +71,31 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
66 | &self, | 71 | &self, |
67 | trait_id: TraitId, | 72 | trait_id: TraitId, |
68 | parameters: &[GenericArg<Interner>], | 73 | parameters: &[GenericArg<Interner>], |
74 | binders: &CanonicalVarKinds<Interner>, | ||
69 | ) -> Vec<ImplId> { | 75 | ) -> Vec<ImplId> { |
70 | debug!("impls_for_trait {:?}", trait_id); | 76 | debug!("impls_for_trait {:?}", trait_id); |
71 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); | 77 | let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); |
72 | 78 | ||
73 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); | 79 | let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); |
74 | 80 | ||
81 | fn binder_kind(ty: &Ty, binders: &CanonicalVarKinds<Interner>) -> Option<chalk_ir::TyKind> { | ||
82 | if let Ty::Bound(bv) = ty { | ||
83 | let binders = binders.as_slice(&Interner); | ||
84 | if bv.debruijn == DebruijnIndex::INNERMOST { | ||
85 | if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { | ||
86 | return Some(tk); | ||
87 | } | ||
88 | } | ||
89 | } | ||
90 | None | ||
91 | } | ||
92 | |||
75 | let self_ty_fp = TyFingerprint::for_impl(&ty); | 93 | let self_ty_fp = TyFingerprint::for_impl(&ty); |
94 | let fps: &[TyFingerprint] = match binder_kind(&ty, binders) { | ||
95 | Some(chalk_ir::TyKind::Integer) => &ALL_INT_FPS, | ||
96 | Some(chalk_ir::TyKind::Float) => &ALL_FLOAT_FPS, | ||
97 | _ => self_ty_fp.as_ref().map(std::slice::from_ref).unwrap_or(&[]), | ||
98 | }; | ||
76 | 99 | ||
77 | // Note: Since we're using impls_for_trait, only impls where the trait | 100 | // Note: Since we're using impls_for_trait, only impls where the trait |
78 | // can be resolved should ever reach Chalk. `impl_datum` relies on that | 101 | // can be resolved should ever reach Chalk. `impl_datum` relies on that |
@@ -81,28 +104,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
81 | let in_self = self.db.trait_impls_in_crate(self.krate); | 104 | let in_self = self.db.trait_impls_in_crate(self.krate); |
82 | let impl_maps = [in_deps, in_self]; | 105 | let impl_maps = [in_deps, in_self]; |
83 | 106 | ||
84 | let id_to_chalk = |id: hir_def::ImplId| Impl::ImplDef(id).to_chalk(self.db); | 107 | let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db); |
85 | 108 | ||
86 | let mut result: Vec<_> = match self_ty_fp { | 109 | let result: Vec<_> = if fps.is_empty() { |
87 | Some(fp) => impl_maps | 110 | debug!("Unrestricted search for {:?} impls...", trait_); |
111 | impl_maps | ||
112 | .iter() | ||
113 | .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) | ||
114 | .collect() | ||
115 | } else { | ||
116 | impl_maps | ||
88 | .iter() | 117 | .iter() |
89 | .flat_map(|crate_impl_defs| { | 118 | .flat_map(|crate_impl_defs| { |
90 | crate_impl_defs.for_trait_and_self_ty(trait_, fp).map(id_to_chalk) | 119 | fps.iter().flat_map(move |fp| { |
120 | crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk) | ||
121 | }) | ||
91 | }) | 122 | }) |
92 | .collect(), | 123 | .collect() |
93 | None => impl_maps | ||
94 | .iter() | ||
95 | .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk)) | ||
96 | .collect(), | ||
97 | }; | 124 | }; |
98 | 125 | ||
99 | let arg: Option<Ty> = | ||
100 | parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone())); | ||
101 | |||
102 | builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| { | ||
103 | result.push(i.to_chalk(self.db)) | ||
104 | }); | ||
105 | |||
106 | debug!("impls_for_trait returned {} impls", result.len()); | 126 | debug!("impls_for_trait returned {} impls", result.len()); |
107 | result | 127 | result |
108 | } | 128 | } |
@@ -192,31 +212,55 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
192 | _closure_id: chalk_ir::ClosureId<Interner>, | 212 | _closure_id: chalk_ir::ClosureId<Interner>, |
193 | _substs: &chalk_ir::Substitution<Interner>, | 213 | _substs: &chalk_ir::Substitution<Interner>, |
194 | ) -> rust_ir::ClosureKind { | 214 | ) -> rust_ir::ClosureKind { |
195 | // FIXME: implement closure support | 215 | // Fn is the closure kind that implements all three traits |
196 | unimplemented!() | 216 | rust_ir::ClosureKind::Fn |
197 | } | 217 | } |
198 | fn closure_inputs_and_output( | 218 | fn closure_inputs_and_output( |
199 | &self, | 219 | &self, |
200 | _closure_id: chalk_ir::ClosureId<Interner>, | 220 | _closure_id: chalk_ir::ClosureId<Interner>, |
201 | _substs: &chalk_ir::Substitution<Interner>, | 221 | substs: &chalk_ir::Substitution<Interner>, |
202 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { | 222 | ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { |
203 | // FIXME: implement closure support | 223 | let sig_ty: Ty = |
204 | unimplemented!() | 224 | from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); |
225 | let sig = FnSig::from_fn_ptr_substs( | ||
226 | &sig_ty.substs().expect("first closure param should be fn ptr"), | ||
227 | false, | ||
228 | ); | ||
229 | let io = rust_ir::FnDefInputsAndOutputDatum { | ||
230 | argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), | ||
231 | return_type: sig.ret().clone().to_chalk(self.db), | ||
232 | }; | ||
233 | make_binders(io.shifted_in(&Interner), 0) | ||
205 | } | 234 | } |
206 | fn closure_upvars( | 235 | fn closure_upvars( |
207 | &self, | 236 | &self, |
208 | _closure_id: chalk_ir::ClosureId<Interner>, | 237 | _closure_id: chalk_ir::ClosureId<Interner>, |
209 | _substs: &chalk_ir::Substitution<Interner>, | 238 | _substs: &chalk_ir::Substitution<Interner>, |
210 | ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { | 239 | ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { |
211 | // FIXME: implement closure support | 240 | let ty = Ty::unit().to_chalk(self.db); |
212 | unimplemented!() | 241 | make_binders(ty, 0) |
213 | } | 242 | } |
214 | fn closure_fn_substitution( | 243 | fn closure_fn_substitution( |
215 | &self, | 244 | &self, |
216 | _closure_id: chalk_ir::ClosureId<Interner>, | 245 | _closure_id: chalk_ir::ClosureId<Interner>, |
217 | _substs: &chalk_ir::Substitution<Interner>, | 246 | _substs: &chalk_ir::Substitution<Interner>, |
218 | ) -> chalk_ir::Substitution<Interner> { | 247 | ) -> chalk_ir::Substitution<Interner> { |
219 | // FIXME: implement closure support | 248 | Substs::empty().to_chalk(self.db) |
249 | } | ||
250 | |||
251 | fn trait_name(&self, _trait_id: chalk_ir::TraitId<Interner>) -> String { | ||
252 | unimplemented!() | ||
253 | } | ||
254 | fn adt_name(&self, _struct_id: chalk_ir::AdtId<Interner>) -> String { | ||
255 | unimplemented!() | ||
256 | } | ||
257 | fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId<Interner>) -> String { | ||
258 | unimplemented!() | ||
259 | } | ||
260 | fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId<Interner>) -> String { | ||
261 | unimplemented!() | ||
262 | } | ||
263 | fn fn_def_name(&self, _fn_def_id: chalk_ir::FnDefId<Interner>) -> String { | ||
220 | unimplemented!() | 264 | unimplemented!() |
221 | } | 265 | } |
222 | } | 266 | } |
@@ -354,12 +398,18 @@ pub(crate) fn struct_datum_query( | |||
354 | fundamental: false, | 398 | fundamental: false, |
355 | phantom_data: false, | 399 | phantom_data: false, |
356 | }; | 400 | }; |
357 | let struct_datum_bound = rust_ir::AdtDatumBound { | 401 | // FIXME provide enum variants properly (for auto traits) |
358 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits) | 402 | let variant = rust_ir::AdtVariantDatum { |
359 | where_clauses, | 403 | fields: Vec::new(), // FIXME add fields (only relevant for auto traits), |
404 | }; | ||
405 | let struct_datum_bound = rust_ir::AdtDatumBound { variants: vec![variant], where_clauses }; | ||
406 | let struct_datum = StructDatum { | ||
407 | // FIXME set ADT kind | ||
408 | kind: rust_ir::AdtKind::Struct, | ||
409 | id: struct_id, | ||
410 | binders: make_binders(struct_datum_bound, num_params), | ||
411 | flags, | ||
360 | }; | 412 | }; |
361 | let struct_datum = | ||
362 | StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags }; | ||
363 | Arc::new(struct_datum) | 413 | Arc::new(struct_datum) |
364 | } | 414 | } |
365 | 415 | ||
@@ -370,11 +420,8 @@ pub(crate) fn impl_datum_query( | |||
370 | ) -> Arc<ImplDatum> { | 420 | ) -> Arc<ImplDatum> { |
371 | let _p = ra_prof::profile("impl_datum"); | 421 | let _p = ra_prof::profile("impl_datum"); |
372 | debug!("impl_datum {:?}", impl_id); | 422 | debug!("impl_datum {:?}", impl_id); |
373 | let impl_: Impl = from_chalk(db, impl_id); | 423 | let impl_: hir_def::ImplId = from_chalk(db, impl_id); |
374 | match impl_ { | 424 | impl_def_datum(db, krate, impl_id, impl_) |
375 | Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def), | ||
376 | _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)), | ||
377 | } | ||
378 | } | 425 | } |
379 | 426 | ||
380 | fn impl_def_datum( | 427 | fn impl_def_datum( |
@@ -425,7 +472,7 @@ fn impl_def_datum( | |||
425 | let name = &db.type_alias_data(type_alias).name; | 472 | let name = &db.type_alias_data(type_alias).name; |
426 | trait_data.associated_type_by_name(name).is_some() | 473 | trait_data.associated_type_by_name(name).is_some() |
427 | }) | 474 | }) |
428 | .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) | 475 | .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db)) |
429 | .collect(); | 476 | .collect(); |
430 | debug!("impl_datum: {:?}", impl_datum_bound); | 477 | debug!("impl_datum: {:?}", impl_datum_bound); |
431 | let impl_datum = ImplDatum { | 478 | let impl_datum = ImplDatum { |
@@ -442,13 +489,8 @@ pub(crate) fn associated_ty_value_query( | |||
442 | krate: CrateId, | 489 | krate: CrateId, |
443 | id: AssociatedTyValueId, | 490 | id: AssociatedTyValueId, |
444 | ) -> Arc<AssociatedTyValue> { | 491 | ) -> Arc<AssociatedTyValue> { |
445 | let data: AssocTyValue = from_chalk(db, id); | 492 | let type_alias: TypeAliasAsValue = from_chalk(db, id); |
446 | match data { | 493 | type_alias_associated_ty_value(db, krate, type_alias.0) |
447 | AssocTyValue::TypeAlias(type_alias) => { | ||
448 | type_alias_associated_ty_value(db, krate, type_alias) | ||
449 | } | ||
450 | _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)), | ||
451 | } | ||
452 | } | 494 | } |
453 | 495 | ||
454 | fn type_alias_associated_ty_value( | 496 | fn type_alias_associated_ty_value( |
@@ -471,7 +513,7 @@ fn type_alias_associated_ty_value( | |||
471 | let ty = db.ty(type_alias.into()); | 513 | let ty = db.ty(type_alias.into()); |
472 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; | 514 | let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; |
473 | let value = rust_ir::AssociatedTyValue { | 515 | let value = rust_ir::AssociatedTyValue { |
474 | impl_id: Impl::ImplDef(impl_id).to_chalk(db), | 516 | impl_id: impl_id.to_chalk(db), |
475 | associated_ty_id: assoc_ty.to_chalk(db), | 517 | associated_ty_id: assoc_ty.to_chalk(db), |
476 | value: make_binders(value_bound, ty.num_binders), | 518 | value: make_binders(value_bound, ty.num_binders), |
477 | }; | 519 | }; |
@@ -483,7 +525,7 @@ pub(crate) fn fn_def_datum_query( | |||
483 | _krate: CrateId, | 525 | _krate: CrateId, |
484 | fn_def_id: FnDefId, | 526 | fn_def_id: FnDefId, |
485 | ) -> Arc<FnDefDatum> { | 527 | ) -> Arc<FnDefDatum> { |
486 | let callable_def: CallableDef = from_chalk(db, fn_def_id); | 528 | let callable_def: CallableDefId = from_chalk(db, fn_def_id); |
487 | let generic_params = generics(db.upcast(), callable_def.into()); | 529 | let generic_params = generics(db.upcast(), callable_def.into()); |
488 | let sig = db.callable_item_signature(callable_def); | 530 | let sig = db.callable_item_signature(callable_def); |
489 | let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); | 531 | let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); |
@@ -510,42 +552,18 @@ pub(crate) fn fn_def_datum_query( | |||
510 | Arc::new(datum) | 552 | Arc::new(datum) |
511 | } | 553 | } |
512 | 554 | ||
513 | impl From<AdtId> for crate::TypeCtorId { | 555 | impl From<FnDefId> for crate::db::InternedCallableDefId { |
514 | fn from(struct_id: AdtId) -> Self { | ||
515 | struct_id.0 | ||
516 | } | ||
517 | } | ||
518 | |||
519 | impl From<crate::TypeCtorId> for AdtId { | ||
520 | fn from(type_ctor_id: crate::TypeCtorId) -> Self { | ||
521 | chalk_ir::AdtId(type_ctor_id) | ||
522 | } | ||
523 | } | ||
524 | |||
525 | impl From<FnDefId> for crate::CallableDefId { | ||
526 | fn from(fn_def_id: FnDefId) -> Self { | 556 | fn from(fn_def_id: FnDefId) -> Self { |
527 | InternKey::from_intern_id(fn_def_id.0) | 557 | InternKey::from_intern_id(fn_def_id.0) |
528 | } | 558 | } |
529 | } | 559 | } |
530 | 560 | ||
531 | impl From<crate::CallableDefId> for FnDefId { | 561 | impl From<crate::db::InternedCallableDefId> for FnDefId { |
532 | fn from(callable_def_id: crate::CallableDefId) -> Self { | 562 | fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self { |
533 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) | 563 | chalk_ir::FnDefId(callable_def_id.as_intern_id()) |
534 | } | 564 | } |
535 | } | 565 | } |
536 | 566 | ||
537 | impl From<ImplId> for crate::traits::GlobalImplId { | ||
538 | fn from(impl_id: ImplId) -> Self { | ||
539 | InternKey::from_intern_id(impl_id.0) | ||
540 | } | ||
541 | } | ||
542 | |||
543 | impl From<crate::traits::GlobalImplId> for ImplId { | ||
544 | fn from(impl_id: crate::traits::GlobalImplId) -> Self { | ||
545 | chalk_ir::ImplId(impl_id.as_intern_id()) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { | 567 | impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId { |
550 | fn from(id: OpaqueTyId) -> Self { | 568 | fn from(id: OpaqueTyId) -> Self { |
551 | InternKey::from_intern_id(id.0) | 569 | InternKey::from_intern_id(id.0) |
@@ -558,14 +576,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId { | |||
558 | } | 576 | } |
559 | } | 577 | } |
560 | 578 | ||
561 | impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { | 579 | impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId { |
562 | fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { | 580 | fn from(id: chalk_ir::ClosureId<Interner>) -> Self { |
563 | Self::from_intern_id(id.0) | 581 | Self::from_intern_id(id.0) |
564 | } | 582 | } |
565 | } | 583 | } |
566 | 584 | ||
567 | impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { | 585 | impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> { |
568 | fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { | 586 | fn from(id: crate::db::ClosureId) -> Self { |
569 | rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) | 587 | chalk_ir::ClosureId(id.as_intern_id()) |
570 | } | 588 | } |
571 | } | 589 | } |
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs index 15426b022..8d4c51a8f 100644 --- a/crates/ra_hir_ty/src/traits/chalk/interner.rs +++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs | |||
@@ -39,8 +39,9 @@ impl chalk_ir::interner::Interner for Interner { | |||
39 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; | 39 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; |
40 | type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; | 40 | type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; |
41 | type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; | 41 | type InternedCanonicalVarKinds = Vec<chalk_ir::CanonicalVarKind<Self>>; |
42 | type InternedConstraints = Vec<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>>; | ||
42 | type DefId = InternId; | 43 | type DefId = InternId; |
43 | type InternedAdtId = crate::TypeCtorId; | 44 | type InternedAdtId = hir_def::AdtId; |
44 | type Identifier = TypeAliasId; | 45 | type Identifier = TypeAliasId; |
45 | type FnAbi = (); | 46 | type FnAbi = (); |
46 | 47 | ||
@@ -349,6 +350,32 @@ impl chalk_ir::interner::Interner for Interner { | |||
349 | ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { | 350 | ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { |
350 | &canonical_var_kinds | 351 | &canonical_var_kinds |
351 | } | 352 | } |
353 | |||
354 | fn intern_constraints<E>( | ||
355 | &self, | ||
356 | data: impl IntoIterator<Item = Result<chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>, E>>, | ||
357 | ) -> Result<Self::InternedConstraints, E> { | ||
358 | data.into_iter().collect() | ||
359 | } | ||
360 | |||
361 | fn constraints_data<'a>( | ||
362 | &self, | ||
363 | constraints: &'a Self::InternedConstraints, | ||
364 | ) -> &'a [chalk_ir::InEnvironment<chalk_ir::Constraint<Self>>] { | ||
365 | constraints | ||
366 | } | ||
367 | fn debug_closure_id( | ||
368 | _fn_def_id: chalk_ir::ClosureId<Self>, | ||
369 | _fmt: &mut fmt::Formatter<'_>, | ||
370 | ) -> Option<fmt::Result> { | ||
371 | None | ||
372 | } | ||
373 | fn debug_constraints( | ||
374 | _clauses: &chalk_ir::Constraints<Self>, | ||
375 | _fmt: &mut fmt::Formatter<'_>, | ||
376 | ) -> Option<fmt::Result> { | ||
377 | None | ||
378 | } | ||
352 | } | 379 | } |
353 | 380 | ||
354 | impl chalk_ir::interner::HasInterner for Interner { | 381 | impl chalk_ir::interner::HasInterner for Interner { |
diff --git a/crates/ra_hir_ty/src/traits/chalk/mapping.rs b/crates/ra_hir_ty/src/traits/chalk/mapping.rs index 433d6aa03..09d8347ca 100644 --- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs +++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs | |||
@@ -15,8 +15,8 @@ use ra_db::salsa::InternKey; | |||
15 | use crate::{ | 15 | use crate::{ |
16 | db::HirDatabase, | 16 | db::HirDatabase, |
17 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, | 17 | primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, |
18 | traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, | 18 | traits::{Canonical, Obligation}, |
19 | ApplicationTy, CallableDef, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, | 19 | ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, |
20 | ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, | 20 | ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, |
21 | }; | 21 | }; |
22 | 22 | ||
@@ -29,7 +29,9 @@ impl ToChalk for Ty { | |||
29 | match self { | 29 | match self { |
30 | Ty::Apply(apply_ty) => match apply_ty.ctor { | 30 | Ty::Apply(apply_ty) => match apply_ty.ctor { |
31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), | 31 | TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), |
32 | TypeCtor::FnPtr { num_args: _ } => { | 32 | TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), |
33 | TypeCtor::FnPtr { num_args: _, is_varargs: _ } => { | ||
34 | // FIXME: handle is_varargs | ||
33 | let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); | 35 | let substitution = apply_ty.parameters.to_chalk(db).shifted_in(&Interner); |
34 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) | 36 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: 0, substitution }) |
35 | .intern(&Interner) | 37 | .intern(&Interner) |
@@ -61,13 +63,13 @@ impl ToChalk for Ty { | |||
61 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), | 63 | Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx).intern(&Interner), |
62 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), | 64 | Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), |
63 | Ty::Dyn(predicates) => { | 65 | Ty::Dyn(predicates) => { |
64 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from( | 66 | let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( |
65 | &Interner, | 67 | &Interner, |
66 | predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), | 68 | predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), |
67 | ); | 69 | ); |
68 | let bounded_ty = chalk_ir::DynTy { | 70 | let bounded_ty = chalk_ir::DynTy { |
69 | bounds: make_binders(where_clauses, 1), | 71 | bounds: make_binders(where_clauses, 1), |
70 | lifetime: LIFETIME_PLACEHOLDER.to_lifetime(&Interner), | 72 | lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner), |
71 | }; | 73 | }; |
72 | chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) | 74 | chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) |
73 | } | 75 | } |
@@ -92,6 +94,7 @@ impl ToChalk for Ty { | |||
92 | chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { | 94 | chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { |
93 | TypeName::Error => Ty::Unknown, | 95 | TypeName::Error => Ty::Unknown, |
94 | TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), | 96 | TypeName::Ref(m) => ref_from_chalk(db, m, apply_ty.substitution), |
97 | TypeName::Array => array_from_chalk(db, apply_ty.substitution), | ||
95 | _ => { | 98 | _ => { |
96 | let ctor = from_chalk(db, apply_ty.name); | 99 | let ctor = from_chalk(db, apply_ty.name); |
97 | let parameters = from_chalk(db, apply_ty.substitution); | 100 | let parameters = from_chalk(db, apply_ty.substitution); |
@@ -115,10 +118,17 @@ impl ToChalk for Ty { | |||
115 | let parameters = from_chalk(db, opaque_ty.substitution); | 118 | let parameters = from_chalk(db, opaque_ty.substitution); |
116 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) | 119 | Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) |
117 | } | 120 | } |
118 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { | 121 | chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, substitution }) => { |
119 | let parameters: Substs = from_chalk(db, substitution); | 122 | assert_eq!(num_binders, 0); |
123 | let parameters: Substs = from_chalk( | ||
124 | db, | ||
125 | substitution.shifted_out(&Interner).expect("fn ptr should have no binders"), | ||
126 | ); | ||
120 | Ty::Apply(ApplicationTy { | 127 | Ty::Apply(ApplicationTy { |
121 | ctor: TypeCtor::FnPtr { num_args: (parameters.len() - 1) as u16 }, | 128 | ctor: TypeCtor::FnPtr { |
129 | num_args: (parameters.len() - 1) as u16, | ||
130 | is_varargs: false, | ||
131 | }, | ||
122 | parameters, | 132 | parameters, |
123 | }) | 133 | }) |
124 | } | 134 | } |
@@ -138,7 +148,7 @@ impl ToChalk for Ty { | |||
138 | } | 148 | } |
139 | } | 149 | } |
140 | 150 | ||
141 | const LIFETIME_PLACEHOLDER: PlaceholderIndex = | 151 | const FAKE_PLACEHOLDER: PlaceholderIndex = |
142 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; | 152 | PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; |
143 | 153 | ||
144 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a | 154 | /// We currently don't model lifetimes, but Chalk does. So, we have to insert a |
@@ -149,10 +159,10 @@ fn ref_to_chalk( | |||
149 | subst: Substs, | 159 | subst: Substs, |
150 | ) -> chalk_ir::Ty<Interner> { | 160 | ) -> chalk_ir::Ty<Interner> { |
151 | let arg = subst[0].clone().to_chalk(db); | 161 | let arg = subst[0].clone().to_chalk(db); |
152 | let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); | 162 | let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner); |
153 | chalk_ir::ApplicationTy { | 163 | chalk_ir::ApplicationTy { |
154 | name: TypeName::Ref(mutability.to_chalk(db)), | 164 | name: TypeName::Ref(mutability.to_chalk(db)), |
155 | substitution: chalk_ir::Substitution::from( | 165 | substitution: chalk_ir::Substitution::from_iter( |
156 | &Interner, | 166 | &Interner, |
157 | vec![lifetime.cast(&Interner), arg.cast(&Interner)], | 167 | vec![lifetime.cast(&Interner), arg.cast(&Interner)], |
158 | ), | 168 | ), |
@@ -173,11 +183,40 @@ fn ref_from_chalk( | |||
173 | Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) | 183 | Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) |
174 | } | 184 | } |
175 | 185 | ||
186 | /// We currently don't model constants, but Chalk does. So, we have to insert a | ||
187 | /// fake constant here, because Chalks built-in logic may expect it to be there. | ||
188 | fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { | ||
189 | let arg = subst[0].clone().to_chalk(db); | ||
190 | let usize_ty = chalk_ir::ApplicationTy { | ||
191 | name: TypeName::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)), | ||
192 | substitution: chalk_ir::Substitution::empty(&Interner), | ||
193 | } | ||
194 | .intern(&Interner); | ||
195 | let const_ = FAKE_PLACEHOLDER.to_const(&Interner, usize_ty); | ||
196 | chalk_ir::ApplicationTy { | ||
197 | name: TypeName::Array, | ||
198 | substitution: chalk_ir::Substitution::from_iter( | ||
199 | &Interner, | ||
200 | vec![arg.cast(&Interner), const_.cast(&Interner)], | ||
201 | ), | ||
202 | } | ||
203 | .intern(&Interner) | ||
204 | } | ||
205 | |||
206 | /// Here we remove the const from the type we got from Chalk. | ||
207 | fn array_from_chalk(db: &dyn HirDatabase, subst: chalk_ir::Substitution<Interner>) -> Ty { | ||
208 | let tys = subst | ||
209 | .iter(&Interner) | ||
210 | .filter_map(|p| Some(from_chalk(db, p.ty(&Interner)?.clone()))) | ||
211 | .collect(); | ||
212 | Ty::apply(TypeCtor::Array, Substs(tys)) | ||
213 | } | ||
214 | |||
176 | impl ToChalk for Substs { | 215 | impl ToChalk for Substs { |
177 | type Chalk = chalk_ir::Substitution<Interner>; | 216 | type Chalk = chalk_ir::Substitution<Interner>; |
178 | 217 | ||
179 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { | 218 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { |
180 | chalk_ir::Substitution::from(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) | 219 | chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db))) |
181 | } | 220 | } |
182 | 221 | ||
183 | fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { | 222 | fn from_chalk(db: &dyn HirDatabase, parameters: chalk_ir::Substitution<Interner>) -> Substs { |
@@ -263,6 +302,7 @@ impl ToChalk for TypeCtor { | |||
263 | TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), | 302 | TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), |
264 | TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), | 303 | TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), |
265 | TypeCtor::Slice => TypeName::Slice, | 304 | TypeCtor::Slice => TypeName::Slice, |
305 | TypeCtor::Array => TypeName::Array, | ||
266 | TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), | 306 | TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), |
267 | TypeCtor::Str => TypeName::Str, | 307 | TypeCtor::Str => TypeName::Str, |
268 | TypeCtor::FnDef(callable_def) => { | 308 | TypeCtor::FnDef(callable_def) => { |
@@ -271,20 +311,24 @@ impl ToChalk for TypeCtor { | |||
271 | } | 311 | } |
272 | TypeCtor::Never => TypeName::Never, | 312 | TypeCtor::Never => TypeName::Never, |
273 | 313 | ||
274 | TypeCtor::Adt(_) | 314 | TypeCtor::Closure { def, expr } => { |
275 | | TypeCtor::Array | 315 | let closure_id = db.intern_closure((def, expr)); |
276 | | TypeCtor::FnPtr { .. } | 316 | TypeName::Closure(closure_id.into()) |
277 | | TypeCtor::Closure { .. } => { | 317 | } |
278 | // other TypeCtors get interned and turned into a chalk StructId | 318 | |
279 | let struct_id = db.intern_type_ctor(self).into(); | 319 | TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)), |
280 | TypeName::Adt(struct_id) | 320 | |
321 | TypeCtor::FnPtr { .. } => { | ||
322 | // This should not be reached, since Chalk doesn't represent | ||
323 | // function pointers with TypeName | ||
324 | unreachable!() | ||
281 | } | 325 | } |
282 | } | 326 | } |
283 | } | 327 | } |
284 | 328 | ||
285 | fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { | 329 | fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { |
286 | match type_name { | 330 | match type_name { |
287 | TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), | 331 | TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0), |
288 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), | 332 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), |
289 | TypeName::OpaqueType(opaque_type_id) => { | 333 | TypeName::OpaqueType(opaque_type_id) => { |
290 | TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) | 334 | TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)) |
@@ -317,13 +361,16 @@ impl ToChalk for TypeCtor { | |||
317 | let callable_def = from_chalk(db, fn_def_id); | 361 | let callable_def = from_chalk(db, fn_def_id); |
318 | TypeCtor::FnDef(callable_def) | 362 | TypeCtor::FnDef(callable_def) |
319 | } | 363 | } |
364 | TypeName::Array => TypeCtor::Array, | ||
320 | 365 | ||
321 | TypeName::Array | TypeName::Error => { | 366 | TypeName::Closure(id) => { |
322 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | 367 | let id: crate::db::ClosureId = id.into(); |
323 | unreachable!() | 368 | let (def, expr) = db.lookup_intern_closure(id); |
369 | TypeCtor::Closure { def, expr } | ||
324 | } | 370 | } |
325 | TypeName::Closure(_) => { | 371 | |
326 | // FIXME: implement closure support | 372 | TypeName::Error => { |
373 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | ||
327 | unreachable!() | 374 | unreachable!() |
328 | } | 375 | } |
329 | } | 376 | } |
@@ -395,26 +442,26 @@ impl ToChalk for Mutability { | |||
395 | } | 442 | } |
396 | } | 443 | } |
397 | 444 | ||
398 | impl ToChalk for Impl { | 445 | impl ToChalk for hir_def::ImplId { |
399 | type Chalk = ImplId; | 446 | type Chalk = ImplId; |
400 | 447 | ||
401 | fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { | 448 | fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId { |
402 | db.intern_chalk_impl(self).into() | 449 | chalk_ir::ImplId(self.as_intern_id()) |
403 | } | 450 | } |
404 | 451 | ||
405 | fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { | 452 | fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId { |
406 | db.lookup_intern_chalk_impl(impl_id.into()) | 453 | InternKey::from_intern_id(impl_id.0) |
407 | } | 454 | } |
408 | } | 455 | } |
409 | 456 | ||
410 | impl ToChalk for CallableDef { | 457 | impl ToChalk for CallableDefId { |
411 | type Chalk = FnDefId; | 458 | type Chalk = FnDefId; |
412 | 459 | ||
413 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { | 460 | fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { |
414 | db.intern_callable_def(self).into() | 461 | db.intern_callable_def(self).into() |
415 | } | 462 | } |
416 | 463 | ||
417 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { | 464 | fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId { |
418 | db.lookup_intern_callable_def(fn_def_id.into()) | 465 | db.lookup_intern_callable_def(fn_def_id.into()) |
419 | } | 466 | } |
420 | } | 467 | } |
@@ -431,15 +478,20 @@ impl ToChalk for TypeAliasId { | |||
431 | } | 478 | } |
432 | } | 479 | } |
433 | 480 | ||
434 | impl ToChalk for AssocTyValue { | 481 | pub struct TypeAliasAsValue(pub TypeAliasId); |
482 | |||
483 | impl ToChalk for TypeAliasAsValue { | ||
435 | type Chalk = AssociatedTyValueId; | 484 | type Chalk = AssociatedTyValueId; |
436 | 485 | ||
437 | fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { | 486 | fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId { |
438 | db.intern_assoc_ty_value(self).into() | 487 | rust_ir::AssociatedTyValueId(self.0.as_intern_id()) |
439 | } | 488 | } |
440 | 489 | ||
441 | fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { | 490 | fn from_chalk( |
442 | db.lookup_intern_assoc_ty_value(assoc_ty_value_id.into()) | 491 | _db: &dyn HirDatabase, |
492 | assoc_ty_value_id: AssociatedTyValueId, | ||
493 | ) -> TypeAliasAsValue { | ||
494 | TypeAliasAsValue(TypeAliasId::from_intern_id(assoc_ty_value_id.0)) | ||
443 | } | 495 | } |
444 | } | 496 | } |
445 | 497 | ||
@@ -492,6 +544,11 @@ impl ToChalk for GenericPredicate { | |||
492 | // we shouldn't get these from Chalk | 544 | // we shouldn't get these from Chalk |
493 | panic!("encountered LifetimeOutlives from Chalk") | 545 | panic!("encountered LifetimeOutlives from Chalk") |
494 | } | 546 | } |
547 | |||
548 | chalk_ir::WhereClause::TypeOutlives(_) => { | ||
549 | // we shouldn't get these from Chalk | ||
550 | panic!("encountered TypeOutlives from Chalk") | ||
551 | } | ||
495 | } | 552 | } |
496 | } | 553 | } |
497 | } | 554 | } |
@@ -570,7 +627,10 @@ where | |||
570 | ) | 627 | ) |
571 | }); | 628 | }); |
572 | let value = self.value.to_chalk(db); | 629 | let value = self.value.to_chalk(db); |
573 | chalk_ir::Canonical { value, binders: chalk_ir::CanonicalVarKinds::from(&Interner, kinds) } | 630 | chalk_ir::Canonical { |
631 | value, | ||
632 | binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds), | ||
633 | } | ||
574 | } | 634 | } |
575 | 635 | ||
576 | fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { | 636 | fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { |
@@ -640,58 +700,12 @@ where | |||
640 | } | 700 | } |
641 | } | 701 | } |
642 | 702 | ||
643 | impl ToChalk for builtin::BuiltinImplData { | ||
644 | type Chalk = ImplDatum; | ||
645 | |||
646 | fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum { | ||
647 | let impl_type = rust_ir::ImplType::External; | ||
648 | let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect(); | ||
649 | |||
650 | let impl_datum_bound = | ||
651 | rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses }; | ||
652 | let associated_ty_value_ids = | ||
653 | self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect(); | ||
654 | rust_ir::ImplDatum { | ||
655 | binders: make_binders(impl_datum_bound, self.num_vars), | ||
656 | impl_type, | ||
657 | polarity: rust_ir::Polarity::Positive, | ||
658 | associated_ty_value_ids, | ||
659 | } | ||
660 | } | ||
661 | |||
662 | fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self { | ||
663 | unimplemented!() | ||
664 | } | ||
665 | } | ||
666 | |||
667 | impl ToChalk for builtin::BuiltinImplAssocTyValueData { | ||
668 | type Chalk = AssociatedTyValue; | ||
669 | |||
670 | fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue { | ||
671 | let ty = self.value.to_chalk(db); | ||
672 | let value_bound = rust_ir::AssociatedTyValueBound { ty }; | ||
673 | |||
674 | rust_ir::AssociatedTyValue { | ||
675 | associated_ty_id: self.assoc_ty_id.to_chalk(db), | ||
676 | impl_id: self.impl_.to_chalk(db), | ||
677 | value: make_binders(value_bound, self.num_vars), | ||
678 | } | ||
679 | } | ||
680 | |||
681 | fn from_chalk( | ||
682 | _db: &dyn HirDatabase, | ||
683 | _data: AssociatedTyValue, | ||
684 | ) -> builtin::BuiltinImplAssocTyValueData { | ||
685 | unimplemented!() | ||
686 | } | ||
687 | } | ||
688 | |||
689 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> | 703 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> |
690 | where | 704 | where |
691 | T: HasInterner<Interner = Interner>, | 705 | T: HasInterner<Interner = Interner>, |
692 | { | 706 | { |
693 | chalk_ir::Binders::new( | 707 | chalk_ir::Binders::new( |
694 | chalk_ir::VariableKinds::from( | 708 | chalk_ir::VariableKinds::from_iter( |
695 | &Interner, | 709 | &Interner, |
696 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), | 710 | std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General)).take(num_vars), |
697 | ), | 711 | ), |
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs index 556af7098..db915625c 100644 --- a/crates/ra_hir_ty/src/traits/chalk/tls.rs +++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs | |||
@@ -5,12 +5,12 @@ use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplicat | |||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | 6 | ||
7 | use super::{from_chalk, Interner}; | 7 | use super::{from_chalk, Interner}; |
8 | use crate::{db::HirDatabase, CallableDef, TypeCtor}; | 8 | use crate::{db::HirDatabase, CallableDefId, TypeCtor}; |
9 | use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; | 9 | use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; |
10 | 10 | ||
11 | pub use unsafe_tls::{set_current_program, with_current_program}; | 11 | pub use unsafe_tls::{set_current_program, with_current_program}; |
12 | 12 | ||
13 | pub struct DebugContext<'a>(&'a (dyn HirDatabase + 'a)); | 13 | pub struct DebugContext<'a>(&'a dyn HirDatabase); |
14 | 14 | ||
15 | impl DebugContext<'_> { | 15 | impl DebugContext<'_> { |
16 | pub fn debug_struct_id( | 16 | pub fn debug_struct_id( |
@@ -38,16 +38,16 @@ impl DebugContext<'_> { | |||
38 | } | 38 | } |
39 | TypeCtor::FnDef(def) => { | 39 | TypeCtor::FnDef(def) => { |
40 | let name = match def { | 40 | let name = match def { |
41 | CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), | 41 | CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(), |
42 | CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), | 42 | CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(), |
43 | CallableDef::EnumVariantId(e) => { | 43 | CallableDefId::EnumVariantId(e) => { |
44 | let enum_data = self.0.enum_data(e.parent); | 44 | let enum_data = self.0.enum_data(e.parent); |
45 | enum_data.variants[e.local_id].name.clone() | 45 | enum_data.variants[e.local_id].name.clone() |
46 | } | 46 | } |
47 | }; | 47 | }; |
48 | match def { | 48 | match def { |
49 | CallableDef::FunctionId(_) => write!(f, "{{fn {}}}", name)?, | 49 | CallableDefId::FunctionId(_) => write!(f, "{{fn {}}}", name)?, |
50 | CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { | 50 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => { |
51 | write!(f, "{{ctor {}}}", name)? | 51 | write!(f, "{{ctor {}}}", name)? |
52 | } | 52 | } |
53 | } | 53 | } |
@@ -157,7 +157,7 @@ impl DebugContext<'_> { | |||
157 | _ => panic!("associated type not in trait"), | 157 | _ => panic!("associated type not in trait"), |
158 | }; | 158 | }; |
159 | let trait_data = self.0.trait_data(trait_); | 159 | let trait_data = self.0.trait_data(trait_); |
160 | let params = projection_ty.substitution.parameters(&Interner); | 160 | let params = projection_ty.substitution.as_slice(&Interner); |
161 | write!(fmt, "<{:?} as {}", ¶ms[0], trait_data.name,)?; | 161 | write!(fmt, "<{:?} as {}", ¶ms[0], trait_data.name,)?; |
162 | if params.len() > 1 { | 162 | if params.len() > 1 { |
163 | write!( | 163 | write!( |
@@ -255,18 +255,18 @@ impl DebugContext<'_> { | |||
255 | fn_def_id: chalk_ir::FnDefId<Interner>, | 255 | fn_def_id: chalk_ir::FnDefId<Interner>, |
256 | fmt: &mut fmt::Formatter<'_>, | 256 | fmt: &mut fmt::Formatter<'_>, |
257 | ) -> Result<(), fmt::Error> { | 257 | ) -> Result<(), fmt::Error> { |
258 | let def: CallableDef = from_chalk(self.0, fn_def_id); | 258 | let def: CallableDefId = from_chalk(self.0, fn_def_id); |
259 | let name = match def { | 259 | let name = match def { |
260 | CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), | 260 | CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(), |
261 | CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), | 261 | CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(), |
262 | CallableDef::EnumVariantId(e) => { | 262 | CallableDefId::EnumVariantId(e) => { |
263 | let enum_data = self.0.enum_data(e.parent); | 263 | let enum_data = self.0.enum_data(e.parent); |
264 | enum_data.variants[e.local_id].name.clone() | 264 | enum_data.variants[e.local_id].name.clone() |
265 | } | 265 | } |
266 | }; | 266 | }; |
267 | match def { | 267 | match def { |
268 | CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name), | 268 | CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name), |
269 | CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { | 269 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => { |
270 | write!(fmt, "{{ctor {}}}", name) | 270 | write!(fmt, "{{ctor {}}}", name) |
271 | } | 271 | } |
272 | } | 272 | } |