aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/traits')
-rw-r--r--crates/ra_hir_ty/src/traits/builtin.rs377
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs294
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/interner.rs32
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/mapping.rs286
-rw-r--r--crates/ra_hir_ty/src/traits/chalk/tls.rs33
5 files changed, 436 insertions, 586 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 88a422d2c..000000000
--- a/crates/ra_hir_ty/src/traits/builtin.rs
+++ /dev/null
@@ -1,377 +0,0 @@
1//! This module provides the built-in trait implementations, e.g. to make
2//! closures implement `Fn`.
3use hir_def::{expr::Expr, lang_item::LangItemTarget, TraitId, TypeAliasId};
4use hir_expand::name::name;
5use ra_db::CrateId;
6
7use super::{AssocTyValue, Impl, UnsizeToSuperTraitObjectData};
8use crate::{
9 db::HirDatabase,
10 utils::{all_super_traits, generics},
11 ApplicationTy, Binders, BoundVar, DebruijnIndex, GenericPredicate, Substs, TraitRef, Ty,
12 TypeCtor, TypeWalk,
13};
14
15pub(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
22pub(super) struct BuiltinImplAssocTyValueData {
23 pub impl_: Impl,
24 pub assoc_ty_id: TypeAliasId,
25 pub num_vars: usize,
26 pub value: Ty,
27}
28
29pub(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) = get_fn_trait(db, krate, fn_trait) {
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
62fn 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
98pub(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
110pub(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
125fn 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 get_fn_trait(db, krate, data.fn_trait).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 get_fn_trait(db, krate, super::FnTrait::FnOnce) {
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
146fn 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_ = get_fn_trait(db, krate, data.fn_trait) // get corresponding fn trait
155 // the existence of the Fn trait has been checked before
156 .expect("fn trait for closure impl missing");
157
158 let num_args: u16 = match &db.body(data.def)[data.expr] {
159 Expr::Lambda { args, .. } => args.len() as u16,
160 _ => {
161 log::warn!("closure for closure type {:?} not found", data);
162 0
163 }
164 };
165
166 let arg_ty = Ty::apply(
167 TypeCtor::Tuple { cardinality: num_args },
168 Substs::builder(num_args as usize)
169 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
170 .build(),
171 );
172 let sig_ty = Ty::apply(
173 TypeCtor::FnPtr { num_args },
174 Substs::builder(num_args as usize + 1)
175 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
176 .build(),
177 );
178
179 let self_ty = Ty::apply_one(TypeCtor::Closure { def: data.def, expr: data.expr }, sig_ty);
180
181 let trait_ref = TraitRef {
182 trait_,
183 substs: Substs::build_for_def(db, trait_).push(self_ty).push(arg_ty).build(),
184 };
185
186 let output_ty_id = AssocTyValue::ClosureFnTraitImplOutput(data);
187
188 BuiltinImplData {
189 num_vars: num_args as usize + 1,
190 trait_ref,
191 where_clauses: Vec::new(),
192 assoc_ty_values: vec![output_ty_id],
193 }
194}
195
196fn closure_fn_trait_output_assoc_ty_value(
197 db: &dyn HirDatabase,
198 krate: CrateId,
199 data: super::ClosureFnTraitImplData,
200) -> BuiltinImplAssocTyValueData {
201 let impl_ = Impl::ClosureFnTraitImpl(data);
202
203 let num_args: u16 = match &db.body(data.def)[data.expr] {
204 Expr::Lambda { args, .. } => args.len() as u16,
205 _ => {
206 log::warn!("closure for closure type {:?} not found", data);
207 0
208 }
209 };
210
211 let output_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, num_args.into()));
212
213 let fn_once_trait =
214 get_fn_trait(db, krate, super::FnTrait::FnOnce).expect("assoc ty value should not exist");
215
216 let output_ty_id = db
217 .trait_data(fn_once_trait)
218 .associated_type_by_name(&name![Output])
219 .expect("assoc ty value should not exist");
220
221 BuiltinImplAssocTyValueData {
222 impl_,
223 assoc_ty_id: output_ty_id,
224 num_vars: num_args as usize + 1,
225 value: output_ty,
226 }
227}
228
229// Array unsizing
230
231fn check_unsize_impl_prerequisites(db: &dyn HirDatabase, krate: CrateId) -> bool {
232 // the Unsize trait needs to exist and have two type parameters (Self and T)
233 let unsize_trait = match get_unsize_trait(db, krate) {
234 Some(t) => t,
235 None => return false,
236 };
237 let generic_params = generics(db.upcast(), unsize_trait.into());
238 generic_params.len() == 2
239}
240
241fn array_unsize_impl_datum(db: &dyn HirDatabase, krate: CrateId) -> BuiltinImplData {
242 // impl<T> Unsize<[T]> for [T; _]
243 // (this can be a single impl because we don't distinguish array sizes currently)
244
245 let trait_ = get_unsize_trait(db, krate) // get unsize trait
246 // the existence of the Unsize trait has been checked before
247 .expect("Unsize trait missing");
248
249 let var = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
250 let substs = Substs::builder(2)
251 .push(Ty::apply_one(TypeCtor::Array, var.clone()))
252 .push(Ty::apply_one(TypeCtor::Slice, var))
253 .build();
254
255 let trait_ref = TraitRef { trait_, substs };
256
257 BuiltinImplData {
258 num_vars: 1,
259 trait_ref,
260 where_clauses: Vec::new(),
261 assoc_ty_values: Vec::new(),
262 }
263}
264
265// Trait object unsizing
266
267fn trait_object_unsize_impl_datum(
268 db: &dyn HirDatabase,
269 krate: CrateId,
270 trait_: TraitId,
271) -> BuiltinImplData {
272 // impl<T, T1, ...> Unsize<dyn Trait<T1, ...>> for T where T: Trait<T1, ...>
273
274 let unsize_trait = get_unsize_trait(db, krate) // get unsize trait
275 // the existence of the Unsize trait has been checked before
276 .expect("Unsize trait missing");
277
278 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
279
280 let target_substs = Substs::build_for_def(db, trait_)
281 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
282 .fill_with_bound_vars(DebruijnIndex::ONE, 1)
283 .build();
284 let num_vars = target_substs.len();
285 let target_trait_ref = TraitRef { trait_, substs: target_substs };
286 let target_bounds = vec![GenericPredicate::Implemented(target_trait_ref)];
287
288 let self_substs =
289 Substs::build_for_def(db, trait_).fill_with_bound_vars(DebruijnIndex::INNERMOST, 0).build();
290 let self_trait_ref = TraitRef { trait_, substs: self_substs };
291 let where_clauses = vec![GenericPredicate::Implemented(self_trait_ref)];
292
293 let impl_substs = Substs::builder(2).push(self_ty).push(Ty::Dyn(target_bounds.into())).build();
294
295 let trait_ref = TraitRef { trait_: unsize_trait, substs: impl_substs };
296
297 BuiltinImplData { num_vars, trait_ref, where_clauses, assoc_ty_values: Vec::new() }
298}
299
300fn super_trait_object_unsize_impl_datum(
301 db: &dyn HirDatabase,
302 krate: CrateId,
303 data: UnsizeToSuperTraitObjectData,
304) -> BuiltinImplData {
305 // impl<T1, ...> Unsize<dyn SuperTrait> for dyn Trait<T1, ...>
306
307 let unsize_trait = get_unsize_trait(db, krate) // get unsize trait
308 // the existence of the Unsize trait has been checked before
309 .expect("Unsize trait missing");
310
311 let self_substs = Substs::build_for_def(db, data.trait_)
312 .fill_with_bound_vars(DebruijnIndex::INNERMOST, 0)
313 .build();
314 let self_trait_ref = TraitRef { trait_: data.trait_, substs: self_substs.clone() };
315
316 let num_vars = self_substs.len() - 1;
317
318 // we need to go from our trait to the super trait, substituting type parameters
319 let path = crate::utils::find_super_trait_path(db.upcast(), data.trait_, data.super_trait);
320
321 let mut current_trait_ref = self_trait_ref.clone();
322 for t in path.into_iter().skip(1) {
323 let bounds = db.generic_predicates(current_trait_ref.trait_.into());
324 let super_trait_ref = bounds
325 .iter()
326 .find_map(|b| match &b.value {
327 GenericPredicate::Implemented(tr)
328 if tr.trait_ == t
329 && tr.substs[0]
330 == Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)) =>
331 {
332 Some(Binders { value: tr, num_binders: b.num_binders })
333 }
334 _ => None,
335 })
336 .expect("trait bound for known super trait not found");
337 current_trait_ref = super_trait_ref.cloned().subst(&current_trait_ref.substs);
338 }
339
340 // We need to renumber the variables a bit now: from ^0.0, ^0.1, ^0.2, ...
341 // to ^0.0, ^1.0, ^1.1. The reason for this is that the first variable comes
342 // from the dyn Trait binder, while the other variables come from the impl.
343 let new_substs = Substs::builder(num_vars + 1)
344 .push(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
345 .fill_with_bound_vars(DebruijnIndex::ONE, 0)
346 .build();
347
348 let self_bounds =
349 vec![GenericPredicate::Implemented(self_trait_ref.subst_bound_vars(&new_substs))];
350 let super_bounds =
351 vec![GenericPredicate::Implemented(current_trait_ref.subst_bound_vars(&new_substs))];
352
353 let substs = Substs::builder(2)
354 .push(Ty::Dyn(self_bounds.into()))
355 .push(Ty::Dyn(super_bounds.into()))
356 .build();
357
358 let trait_ref = TraitRef { trait_: unsize_trait, substs };
359
360 BuiltinImplData { num_vars, trait_ref, where_clauses: Vec::new(), assoc_ty_values: Vec::new() }
361}
362
363fn 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
371fn get_unsize_trait(db: &dyn HirDatabase, krate: CrateId) -> Option<TraitId> {
372 let target = db.lang_item(krate, "unsize".into())?;
373 match target {
374 LangItemTarget::TraitId(t) => Some(t),
375 _ => None,
376 }
377}
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 61de3cc30..78d0bc43b 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -3,8 +3,8 @@ use std::sync::Arc;
3 3
4use log::debug; 4use log::debug;
5 5
6use chalk_ir::{fold::shift::Shift, GenericArg, TypeName}; 6use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg, TypeName};
7use chalk_solve::rust_ir::{self, WellKnownTrait}; 7use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
8 8
9use hir_def::{ 9use hir_def::{
10 lang_item::{lang_attr, LangItemTarget}, 10 lang_item::{lang_attr, LangItemTarget},
@@ -12,12 +12,17 @@ use hir_def::{
12}; 12};
13use ra_db::{salsa::InternKey, CrateId}; 13use ra_db::{salsa::InternKey, CrateId};
14 14
15use super::{builtin, AssocTyValue, ChalkContext, Impl}; 15use super::ChalkContext;
16use crate::{ 16use 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};
23use mapping::{
24 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
19}; 25};
20use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, make_binders};
21 26
22pub use self::interner::*; 27pub use self::interner::*;
23 28
@@ -48,6 +53,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
48 fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> { 53 fn adt_datum(&self, struct_id: AdtId) -> Arc<StructDatum> {
49 self.db.struct_datum(self.krate, struct_id) 54 self.db.struct_datum(self.krate, struct_id)
50 } 55 }
56 fn adt_repr(&self, _struct_id: AdtId) -> rust_ir::AdtRepr {
57 unreachable!()
58 }
51 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> { 59 fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
52 self.db.impl_datum(self.krate, impl_id) 60 self.db.impl_datum(self.krate, impl_id)
53 } 61 }
@@ -63,32 +71,57 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
63 &self, 71 &self,
64 trait_id: TraitId, 72 trait_id: TraitId,
65 parameters: &[GenericArg<Interner>], 73 parameters: &[GenericArg<Interner>],
74 binders: &CanonicalVarKinds<Interner>,
66 ) -> Vec<ImplId> { 75 ) -> Vec<ImplId> {
67 debug!("impls_for_trait {:?}", trait_id); 76 debug!("impls_for_trait {:?}", trait_id);
68 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 77 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
69 78
70 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());
71 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
72 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 };
73 99
74 // 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
75 // 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
76 // and will panic if the trait can't be resolved. 102 // and will panic if the trait can't be resolved.
77 let mut result: Vec<_> = self 103 let in_deps = self.db.trait_impls_in_deps(self.krate);
78 .db 104 let in_self = self.db.trait_impls_in_crate(self.krate);
79 .impls_for_trait(self.krate, trait_, self_ty_fp) 105 let impl_maps = [in_deps, in_self];
80 .iter() 106
81 .copied() 107 let id_to_chalk = |id: hir_def::ImplId| id.to_chalk(self.db);
82 .map(Impl::ImplDef) 108
83 .map(|impl_| impl_.to_chalk(self.db)) 109 let result: Vec<_> = if fps.is_empty() {
84 .collect(); 110 debug!("Unrestricted search for {:?} impls...", trait_);
85 111 impl_maps
86 let arg: Option<Ty> = 112 .iter()
87 parameters.get(1).map(|p| from_chalk(self.db, p.assert_ty_ref(&Interner).clone())); 113 .flat_map(|crate_impl_defs| crate_impl_defs.for_trait(trait_).map(id_to_chalk))
88 114 .collect()
89 builtin::get_builtin_impls(self.db, self.krate, &ty, &arg, trait_, |i| { 115 } else {
90 result.push(i.to_chalk(self.db)) 116 impl_maps
91 }); 117 .iter()
118 .flat_map(|crate_impl_defs| {
119 fps.iter().flat_map(move |fp| {
120 crate_impl_defs.for_trait_and_self_ty(trait_, *fp).map(id_to_chalk)
121 })
122 })
123 .collect()
124 };
92 125
93 debug!("impls_for_trait returned {} impls", result.len()); 126 debug!("impls_for_trait returned {} impls", result.len());
94 result 127 result
@@ -100,6 +133,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
100 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> { 133 fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc<AssociatedTyValue> {
101 self.db.associated_ty_value(self.krate, id) 134 self.db.associated_ty_value(self.krate, id)
102 } 135 }
136
103 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> { 137 fn custom_clauses(&self) -> Vec<chalk_ir::ProgramClause<Interner>> {
104 vec![] 138 vec![]
105 } 139 }
@@ -115,8 +149,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
115 well_known_trait: rust_ir::WellKnownTrait, 149 well_known_trait: rust_ir::WellKnownTrait,
116 ) -> Option<chalk_ir::TraitId<Interner>> { 150 ) -> Option<chalk_ir::TraitId<Interner>> {
117 let lang_attr = lang_attr_from_well_known_trait(well_known_trait); 151 let lang_attr = lang_attr_from_well_known_trait(well_known_trait);
118 let lang_items = self.db.crate_lang_items(self.krate); 152 let trait_ = match self.db.lang_item(self.krate, lang_attr.into()) {
119 let trait_ = match lang_items.target(lang_attr) {
120 Some(LangItemTarget::TraitId(trait_)) => trait_, 153 Some(LangItemTarget::TraitId(trait_)) => trait_,
121 _ => return None, 154 _ => return None,
122 }; 155 };
@@ -130,11 +163,34 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
130 self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) 163 self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
131 } 164 }
132 165
133 fn opaque_ty_data( 166 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
134 &self, 167 let interned_id = crate::db::InternedOpaqueTyId::from(id);
135 _id: chalk_ir::OpaqueTyId<Interner>, 168 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
136 ) -> Arc<rust_ir::OpaqueTyDatum<Interner>> { 169 let (func, idx) = match full_id {
137 unimplemented!() 170 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => (func, idx),
171 };
172 let datas =
173 self.db.return_type_impl_traits(func).expect("impl trait id without impl traits");
174 let data = &datas.value.impl_traits[idx as usize];
175 let bound = OpaqueTyDatumBound {
176 bounds: make_binders(
177 data.bounds
178 .value
179 .iter()
180 .cloned()
181 .filter(|b| !b.is_error())
182 .map(|b| b.to_chalk(self.db))
183 .collect(),
184 1,
185 ),
186 };
187 let num_vars = datas.num_binders;
188 Arc::new(OpaqueTyDatum { opaque_ty_id: id, bound: make_binders(bound, num_vars) })
189 }
190
191 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
192 // FIXME: actually provide the hidden type; it is relevant for auto traits
193 Ty::Unknown.to_chalk(self.db)
138 } 194 }
139 195
140 fn force_impl_for( 196 fn force_impl_for(
@@ -151,8 +207,61 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
151 true 207 true
152 } 208 }
153 209
154 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 210 fn closure_kind(
155 Ty::Unknown.to_chalk(self.db) 211 &self,
212 _closure_id: chalk_ir::ClosureId<Interner>,
213 _substs: &chalk_ir::Substitution<Interner>,
214 ) -> rust_ir::ClosureKind {
215 // Fn is the closure kind that implements all three traits
216 rust_ir::ClosureKind::Fn
217 }
218 fn closure_inputs_and_output(
219 &self,
220 _closure_id: chalk_ir::ClosureId<Interner>,
221 substs: &chalk_ir::Substitution<Interner>,
222 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
223 let sig_ty: Ty =
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)
234 }
235 fn closure_upvars(
236 &self,
237 _closure_id: chalk_ir::ClosureId<Interner>,
238 _substs: &chalk_ir::Substitution<Interner>,
239 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
240 let ty = Ty::unit().to_chalk(self.db);
241 make_binders(ty, 0)
242 }
243 fn closure_fn_substitution(
244 &self,
245 _closure_id: chalk_ir::ClosureId<Interner>,
246 _substs: &chalk_ir::Substitution<Interner>,
247 ) -> chalk_ir::Substitution<Interner> {
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 {
264 unimplemented!()
156 } 265 }
157} 266}
158 267
@@ -218,7 +327,7 @@ pub(crate) fn trait_datum_query(
218 upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate, 327 upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate,
219 non_enumerable: true, 328 non_enumerable: true,
220 coinductive: false, // only relevant for Chalk testing 329 coinductive: false, // only relevant for Chalk testing
221 // FIXME set these flags correctly 330 // FIXME: set these flags correctly
222 marker: false, 331 marker: false,
223 fundamental: false, 332 fundamental: false,
224 }; 333 };
@@ -240,20 +349,28 @@ pub(crate) fn trait_datum_query(
240 349
241fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> { 350fn well_known_trait_from_lang_attr(name: &str) -> Option<WellKnownTrait> {
242 Some(match name { 351 Some(match name {
243 "sized" => WellKnownTrait::SizedTrait, 352 "sized" => WellKnownTrait::Sized,
244 "copy" => WellKnownTrait::CopyTrait, 353 "copy" => WellKnownTrait::Copy,
245 "clone" => WellKnownTrait::CloneTrait, 354 "clone" => WellKnownTrait::Clone,
246 "drop" => WellKnownTrait::DropTrait, 355 "drop" => WellKnownTrait::Drop,
356 "fn_once" => WellKnownTrait::FnOnce,
357 "fn_mut" => WellKnownTrait::FnMut,
358 "fn" => WellKnownTrait::Fn,
359 "unsize" => WellKnownTrait::Unsize,
247 _ => return None, 360 _ => return None,
248 }) 361 })
249} 362}
250 363
251fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str { 364fn lang_attr_from_well_known_trait(attr: WellKnownTrait) -> &'static str {
252 match attr { 365 match attr {
253 WellKnownTrait::SizedTrait => "sized", 366 WellKnownTrait::Sized => "sized",
254 WellKnownTrait::CopyTrait => "copy", 367 WellKnownTrait::Copy => "copy",
255 WellKnownTrait::CloneTrait => "clone", 368 WellKnownTrait::Clone => "clone",
256 WellKnownTrait::DropTrait => "drop", 369 WellKnownTrait::Drop => "drop",
370 WellKnownTrait::FnOnce => "fn_once",
371 WellKnownTrait::FnMut => "fn_mut",
372 WellKnownTrait::Fn => "fn",
373 WellKnownTrait::Unsize => "unsize",
257 } 374 }
258} 375}
259 376
@@ -277,15 +394,22 @@ pub(crate) fn struct_datum_query(
277 .unwrap_or_else(Vec::new); 394 .unwrap_or_else(Vec::new);
278 let flags = rust_ir::AdtFlags { 395 let flags = rust_ir::AdtFlags {
279 upstream, 396 upstream,
280 // FIXME set fundamental flag correctly 397 // FIXME set fundamental and phantom_data flags correctly
281 fundamental: false, 398 fundamental: false,
399 phantom_data: false,
282 }; 400 };
283 let struct_datum_bound = rust_ir::AdtDatumBound { 401 // FIXME provide enum variants properly (for auto traits)
284 fields: Vec::new(), // FIXME add fields (only relevant for auto traits) 402 let variant = rust_ir::AdtVariantDatum {
285 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,
286 }; 412 };
287 let struct_datum =
288 StructDatum { id: struct_id, binders: make_binders(struct_datum_bound, num_params), flags };
289 Arc::new(struct_datum) 413 Arc::new(struct_datum)
290} 414}
291 415
@@ -296,11 +420,8 @@ pub(crate) fn impl_datum_query(
296) -> Arc<ImplDatum> { 420) -> Arc<ImplDatum> {
297 let _p = ra_prof::profile("impl_datum"); 421 let _p = ra_prof::profile("impl_datum");
298 debug!("impl_datum {:?}", impl_id); 422 debug!("impl_datum {:?}", impl_id);
299 let impl_: Impl = from_chalk(db, impl_id); 423 let impl_: hir_def::ImplId = from_chalk(db, impl_id);
300 match impl_ { 424 impl_def_datum(db, krate, impl_id, impl_)
301 Impl::ImplDef(impl_def) => impl_def_datum(db, krate, impl_id, impl_def),
302 _ => Arc::new(builtin::impl_datum(db, krate, impl_).to_chalk(db)),
303 }
304} 425}
305 426
306fn impl_def_datum( 427fn impl_def_datum(
@@ -351,7 +472,7 @@ fn impl_def_datum(
351 let name = &db.type_alias_data(type_alias).name; 472 let name = &db.type_alias_data(type_alias).name;
352 trait_data.associated_type_by_name(name).is_some() 473 trait_data.associated_type_by_name(name).is_some()
353 }) 474 })
354 .map(|type_alias| AssocTyValue::TypeAlias(type_alias).to_chalk(db)) 475 .map(|type_alias| TypeAliasAsValue(type_alias).to_chalk(db))
355 .collect(); 476 .collect();
356 debug!("impl_datum: {:?}", impl_datum_bound); 477 debug!("impl_datum: {:?}", impl_datum_bound);
357 let impl_datum = ImplDatum { 478 let impl_datum = ImplDatum {
@@ -368,13 +489,8 @@ pub(crate) fn associated_ty_value_query(
368 krate: CrateId, 489 krate: CrateId,
369 id: AssociatedTyValueId, 490 id: AssociatedTyValueId,
370) -> Arc<AssociatedTyValue> { 491) -> Arc<AssociatedTyValue> {
371 let data: AssocTyValue = from_chalk(db, id); 492 let type_alias: TypeAliasAsValue = from_chalk(db, id);
372 match data { 493 type_alias_associated_ty_value(db, krate, type_alias.0)
373 AssocTyValue::TypeAlias(type_alias) => {
374 type_alias_associated_ty_value(db, krate, type_alias)
375 }
376 _ => Arc::new(builtin::associated_ty_value(db, krate, data).to_chalk(db)),
377 }
378} 494}
379 495
380fn type_alias_associated_ty_value( 496fn type_alias_associated_ty_value(
@@ -397,7 +513,7 @@ fn type_alias_associated_ty_value(
397 let ty = db.ty(type_alias.into()); 513 let ty = db.ty(type_alias.into());
398 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) };
399 let value = rust_ir::AssociatedTyValue { 515 let value = rust_ir::AssociatedTyValue {
400 impl_id: Impl::ImplDef(impl_id).to_chalk(db), 516 impl_id: impl_id.to_chalk(db),
401 associated_ty_id: assoc_ty.to_chalk(db), 517 associated_ty_id: assoc_ty.to_chalk(db),
402 value: make_binders(value_bound, ty.num_binders), 518 value: make_binders(value_bound, ty.num_binders),
403 }; 519 };
@@ -409,65 +525,65 @@ pub(crate) fn fn_def_datum_query(
409 _krate: CrateId, 525 _krate: CrateId,
410 fn_def_id: FnDefId, 526 fn_def_id: FnDefId,
411) -> Arc<FnDefDatum> { 527) -> Arc<FnDefDatum> {
412 let callable_def: CallableDef = from_chalk(db, fn_def_id); 528 let callable_def: CallableDefId = from_chalk(db, fn_def_id);
413 let generic_params = generics(db.upcast(), callable_def.into()); 529 let generic_params = generics(db.upcast(), callable_def.into());
414 let sig = db.callable_item_signature(callable_def); 530 let sig = db.callable_item_signature(callable_def);
415 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 531 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
416 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); 532 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
417 let bound = rust_ir::FnDefDatumBound { 533 let bound = rust_ir::FnDefDatumBound {
418 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway 534 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
419 argument_types: sig.value.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(), 535 inputs_and_output: make_binders(
420 return_type: sig.value.ret().clone().to_chalk(db), 536 rust_ir::FnDefInputsAndOutputDatum {
537 argument_types: sig
538 .value
539 .params()
540 .iter()
541 .map(|ty| ty.clone().to_chalk(db))
542 .collect(),
543 return_type: sig.value.ret().clone().to_chalk(db),
544 }
545 .shifted_in(&Interner),
546 0,
547 ),
421 where_clauses, 548 where_clauses,
422 }; 549 };
423 let datum = FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders) }; 550 let datum =
551 FnDefDatum { id: fn_def_id, binders: make_binders(bound, sig.num_binders), abi: () };
424 Arc::new(datum) 552 Arc::new(datum)
425} 553}
426 554
427impl From<AdtId> for crate::TypeCtorId { 555impl From<FnDefId> for crate::db::InternedCallableDefId {
428 fn from(struct_id: AdtId) -> Self {
429 struct_id.0
430 }
431}
432
433impl From<crate::TypeCtorId> for AdtId {
434 fn from(type_ctor_id: crate::TypeCtorId) -> Self {
435 chalk_ir::AdtId(type_ctor_id)
436 }
437}
438
439impl From<FnDefId> for crate::CallableDefId {
440 fn from(fn_def_id: FnDefId) -> Self { 556 fn from(fn_def_id: FnDefId) -> Self {
441 InternKey::from_intern_id(fn_def_id.0) 557 InternKey::from_intern_id(fn_def_id.0)
442 } 558 }
443} 559}
444 560
445impl From<crate::CallableDefId> for FnDefId { 561impl From<crate::db::InternedCallableDefId> for FnDefId {
446 fn from(callable_def_id: crate::CallableDefId) -> Self { 562 fn from(callable_def_id: crate::db::InternedCallableDefId) -> Self {
447 chalk_ir::FnDefId(callable_def_id.as_intern_id()) 563 chalk_ir::FnDefId(callable_def_id.as_intern_id())
448 } 564 }
449} 565}
450 566
451impl From<ImplId> for crate::traits::GlobalImplId { 567impl From<OpaqueTyId> for crate::db::InternedOpaqueTyId {
452 fn from(impl_id: ImplId) -> Self { 568 fn from(id: OpaqueTyId) -> Self {
453 InternKey::from_intern_id(impl_id.0) 569 InternKey::from_intern_id(id.0)
454 } 570 }
455} 571}
456 572
457impl From<crate::traits::GlobalImplId> for ImplId { 573impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
458 fn from(impl_id: crate::traits::GlobalImplId) -> Self { 574 fn from(id: crate::db::InternedOpaqueTyId) -> Self {
459 chalk_ir::ImplId(impl_id.as_intern_id()) 575 chalk_ir::OpaqueTyId(id.as_intern_id())
460 } 576 }
461} 577}
462 578
463impl From<rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId { 579impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId {
464 fn from(id: rust_ir::AssociatedTyValueId<Interner>) -> Self { 580 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
465 Self::from_intern_id(id.0) 581 Self::from_intern_id(id.0)
466 } 582 }
467} 583}
468 584
469impl From<crate::traits::AssocTyValueId> for rust_ir::AssociatedTyValueId<Interner> { 585impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> {
470 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { 586 fn from(id: crate::db::ClosureId) -> Self {
471 rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id()) 587 chalk_ir::ClosureId(id.as_intern_id())
472 } 588 }
473} 589}
diff --git a/crates/ra_hir_ty/src/traits/chalk/interner.rs b/crates/ra_hir_ty/src/traits/chalk/interner.rs
index e27074ba6..8d4c51a8f 100644
--- a/crates/ra_hir_ty/src/traits/chalk/interner.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/interner.rs
@@ -22,6 +22,8 @@ pub type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interne
22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 22pub type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
23pub type FnDefId = chalk_ir::FnDefId<Interner>; 23pub type FnDefId = chalk_ir::FnDefId<Interner>;
24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 24pub type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
25pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
26pub type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
25 27
26impl chalk_ir::interner::Interner for Interner { 28impl chalk_ir::interner::Interner for Interner {
27 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc? 29 type InternedType = Box<chalk_ir::TyData<Self>>; // FIXME use Arc?
@@ -37,9 +39,11 @@ impl chalk_ir::interner::Interner for Interner {
37 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 39 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
38 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>; 40 type InternedVariableKinds = Vec<chalk_ir::VariableKind<Self>>;
39 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>>>;
40 type DefId = InternId; 43 type DefId = InternId;
41 type InternedAdtId = crate::TypeCtorId; 44 type InternedAdtId = hir_def::AdtId;
42 type Identifier = TypeAliasId; 45 type Identifier = TypeAliasId;
46 type FnAbi = ();
43 47
44 fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { 48 fn debug_adt_id(type_kind_id: AdtId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
45 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt))) 49 tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
@@ -346,6 +350,32 @@ impl chalk_ir::interner::Interner for Interner {
346 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] { 350 ) -> &'a [chalk_ir::CanonicalVarKind<Self>] {
347 &canonical_var_kinds 351 &canonical_var_kinds
348 } 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 }
349} 379}
350 380
351impl chalk_ir::interner::HasInterner for Interner { 381impl 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 5f6daf842..09d8347ca 100644
--- a/crates/ra_hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/mapping.rs
@@ -14,10 +14,10 @@ use ra_db::salsa::InternKey;
14 14
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness, Uncertain}, 17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness},
18 traits::{builtin, AssocTyValue, Canonical, Impl, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDef, GenericPredicate, InEnvironment, ProjectionPredicate, ProjectionTy, 19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, 20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -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,14 +63,26 @@ 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 { bounds: make_binders(where_clauses, 1) }; 70 let bounded_ty = chalk_ir::DynTy {
71 bounds: make_binders(where_clauses, 1),
72 lifetime: FAKE_PLACEHOLDER.to_lifetime(&Interner),
73 };
69 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner) 74 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
70 } 75 }
71 Ty::Opaque(_) | Ty::Unknown => { 76 Ty::Opaque(opaque_ty) => {
77 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
78 let substitution = opaque_ty.parameters.to_chalk(db);
79 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
80 opaque_ty_id,
81 substitution,
82 }))
83 .intern(&Interner)
84 }
85 Ty::Unknown => {
72 let substitution = chalk_ir::Substitution::empty(&Interner); 86 let substitution = chalk_ir::Substitution::empty(&Interner);
73 let name = TypeName::Error; 87 let name = TypeName::Error;
74 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner) 88 chalk_ir::ApplicationTy { name, substitution }.cast(&Interner).intern(&Interner)
@@ -80,6 +94,7 @@ impl ToChalk for Ty {
80 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name { 94 chalk_ir::TyData::Apply(apply_ty) => match apply_ty.name {
81 TypeName::Error => Ty::Unknown, 95 TypeName::Error => Ty::Unknown,
82 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),
83 _ => { 98 _ => {
84 let ctor = from_chalk(db, apply_ty.name); 99 let ctor = from_chalk(db, apply_ty.name);
85 let parameters = from_chalk(db, apply_ty.substitution); 100 let parameters = from_chalk(db, apply_ty.substitution);
@@ -98,11 +113,22 @@ impl ToChalk for Ty {
98 let parameters = from_chalk(db, proj.substitution); 113 let parameters = from_chalk(db, proj.substitution);
99 Ty::Projection(ProjectionTy { associated_ty, parameters }) 114 Ty::Projection(ProjectionTy { associated_ty, parameters })
100 } 115 }
101 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), 116 chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
102 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders: _, substitution }) => { 117 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
103 let parameters: Substs = from_chalk(db, substitution); 118 let parameters = from_chalk(db, opaque_ty.substitution);
119 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })
120 }
121 chalk_ir::TyData::Function(chalk_ir::Fn { num_binders, 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 );
104 Ty::Apply(ApplicationTy { 127 Ty::Apply(ApplicationTy {
105 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 },
106 parameters, 132 parameters,
107 }) 133 })
108 } 134 }
@@ -122,7 +148,7 @@ impl ToChalk for Ty {
122 } 148 }
123} 149}
124 150
125const LIFETIME_PLACEHOLDER: PlaceholderIndex = 151const FAKE_PLACEHOLDER: PlaceholderIndex =
126 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX }; 152 PlaceholderIndex { ui: UniverseIndex::ROOT, idx: usize::MAX };
127 153
128/// 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
@@ -133,10 +159,10 @@ fn ref_to_chalk(
133 subst: Substs, 159 subst: Substs,
134) -> chalk_ir::Ty<Interner> { 160) -> chalk_ir::Ty<Interner> {
135 let arg = subst[0].clone().to_chalk(db); 161 let arg = subst[0].clone().to_chalk(db);
136 let lifetime = LIFETIME_PLACEHOLDER.to_lifetime(&Interner); 162 let lifetime = FAKE_PLACEHOLDER.to_lifetime(&Interner);
137 chalk_ir::ApplicationTy { 163 chalk_ir::ApplicationTy {
138 name: TypeName::Ref(mutability.to_chalk(db)), 164 name: TypeName::Ref(mutability.to_chalk(db)),
139 substitution: chalk_ir::Substitution::from( 165 substitution: chalk_ir::Substitution::from_iter(
140 &Interner, 166 &Interner,
141 vec![lifetime.cast(&Interner), arg.cast(&Interner)], 167 vec![lifetime.cast(&Interner), arg.cast(&Interner)],
142 ), 168 ),
@@ -157,11 +183,40 @@ fn ref_from_chalk(
157 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys)) 183 Ty::apply(TypeCtor::Ref(from_chalk(db, mutability)), Substs(tys))
158} 184}
159 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.
188fn 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.
207fn 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
160impl ToChalk for Substs { 215impl ToChalk for Substs {
161 type Chalk = chalk_ir::Substitution<Interner>; 216 type Chalk = chalk_ir::Substitution<Interner>;
162 217
163 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> { 218 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
164 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)))
165 } 220 }
166 221
167 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 {
@@ -204,6 +259,21 @@ impl ToChalk for hir_def::TraitId {
204 } 259 }
205} 260}
206 261
262impl ToChalk for OpaqueTyId {
263 type Chalk = chalk_ir::OpaqueTyId<Interner>;
264
265 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
266 db.intern_impl_trait_id(self).into()
267 }
268
269 fn from_chalk(
270 db: &dyn HirDatabase,
271 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
272 ) -> OpaqueTyId {
273 db.lookup_intern_impl_trait_id(opaque_ty_id.into())
274 }
275}
276
207impl ToChalk for TypeCtor { 277impl ToChalk for TypeCtor {
208 type Chalk = TypeName<Interner>; 278 type Chalk = TypeName<Interner>;
209 279
@@ -214,19 +284,25 @@ impl ToChalk for TypeCtor {
214 TypeName::AssociatedType(type_id) 284 TypeName::AssociatedType(type_id)
215 } 285 }
216 286
287 TypeCtor::OpaqueType(impl_trait_id) => {
288 let id = impl_trait_id.to_chalk(db);
289 TypeName::OpaqueType(id)
290 }
291
217 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool), 292 TypeCtor::Bool => TypeName::Scalar(Scalar::Bool),
218 TypeCtor::Char => TypeName::Scalar(Scalar::Char), 293 TypeCtor::Char => TypeName::Scalar(Scalar::Char),
219 TypeCtor::Int(Uncertain::Known(int_ty)) => TypeName::Scalar(int_ty_to_chalk(int_ty)), 294 TypeCtor::Int(int_ty) => TypeName::Scalar(int_ty_to_chalk(int_ty)),
220 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) => { 295 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
221 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) 296 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
222 } 297 }
223 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) => { 298 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
224 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) 299 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
225 } 300 }
226 301
227 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()), 302 TypeCtor::Tuple { cardinality } => TypeName::Tuple(cardinality.into()),
228 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)), 303 TypeCtor::RawPtr(mutability) => TypeName::Raw(mutability.to_chalk(db)),
229 TypeCtor::Slice => TypeName::Slice, 304 TypeCtor::Slice => TypeName::Slice,
305 TypeCtor::Array => TypeName::Array,
230 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)), 306 TypeCtor::Ref(mutability) => TypeName::Ref(mutability.to_chalk(db)),
231 TypeCtor::Str => TypeName::Str, 307 TypeCtor::Str => TypeName::Str,
232 TypeCtor::FnDef(callable_def) => { 308 TypeCtor::FnDef(callable_def) => {
@@ -235,40 +311,44 @@ impl ToChalk for TypeCtor {
235 } 311 }
236 TypeCtor::Never => TypeName::Never, 312 TypeCtor::Never => TypeName::Never,
237 313
238 TypeCtor::Int(Uncertain::Unknown) 314 TypeCtor::Closure { def, expr } => {
239 | TypeCtor::Float(Uncertain::Unknown) 315 let closure_id = db.intern_closure((def, expr));
240 | TypeCtor::Adt(_) 316 TypeName::Closure(closure_id.into())
241 | TypeCtor::Array 317 }
242 | TypeCtor::FnPtr { .. } 318
243 | TypeCtor::Closure { .. } => { 319 TypeCtor::Adt(adt_id) => TypeName::Adt(chalk_ir::AdtId(adt_id)),
244 // other TypeCtors get interned and turned into a chalk StructId 320
245 let struct_id = db.intern_type_ctor(self).into(); 321 TypeCtor::FnPtr { .. } => {
246 TypeName::Adt(struct_id) 322 // This should not be reached, since Chalk doesn't represent
323 // function pointers with TypeName
324 unreachable!()
247 } 325 }
248 } 326 }
249 } 327 }
250 328
251 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor { 329 fn from_chalk(db: &dyn HirDatabase, type_name: TypeName<Interner>) -> TypeCtor {
252 match type_name { 330 match type_name {
253 TypeName::Adt(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), 331 TypeName::Adt(struct_id) => TypeCtor::Adt(struct_id.0),
254 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), 332 TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
255 TypeName::OpaqueType(_) => unreachable!(), 333 TypeName::OpaqueType(opaque_type_id) => {
334 TypeCtor::OpaqueType(from_chalk(db, opaque_type_id))
335 }
256 336
257 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool, 337 TypeName::Scalar(Scalar::Bool) => TypeCtor::Bool,
258 TypeName::Scalar(Scalar::Char) => TypeCtor::Char, 338 TypeName::Scalar(Scalar::Char) => TypeCtor::Char,
259 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 339 TypeName::Scalar(Scalar::Int(int_ty)) => TypeCtor::Int(IntTy {
260 signedness: Signedness::Signed, 340 signedness: Signedness::Signed,
261 bitness: bitness_from_chalk_int(int_ty), 341 bitness: bitness_from_chalk_int(int_ty),
262 })), 342 }),
263 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(Uncertain::Known(IntTy { 343 TypeName::Scalar(Scalar::Uint(uint_ty)) => TypeCtor::Int(IntTy {
264 signedness: Signedness::Unsigned, 344 signedness: Signedness::Unsigned,
265 bitness: bitness_from_chalk_uint(uint_ty), 345 bitness: bitness_from_chalk_uint(uint_ty),
266 })), 346 }),
267 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => { 347 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
268 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X32 })) 348 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })
269 } 349 }
270 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => { 350 TypeName::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
271 TypeCtor::Float(Uncertain::Known(FloatTy { bitness: FloatBitness::X64 })) 351 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })
272 } 352 }
273 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 }, 353 TypeName::Tuple(cardinality) => TypeCtor::Tuple { cardinality: cardinality as u16 },
274 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)), 354 TypeName::Raw(mutability) => TypeCtor::RawPtr(from_chalk(db, mutability)),
@@ -281,8 +361,15 @@ impl ToChalk for TypeCtor {
281 let callable_def = from_chalk(db, fn_def_id); 361 let callable_def = from_chalk(db, fn_def_id);
282 TypeCtor::FnDef(callable_def) 362 TypeCtor::FnDef(callable_def)
283 } 363 }
364 TypeName::Array => TypeCtor::Array,
284 365
285 TypeName::Array | TypeName::Error => { 366 TypeName::Closure(id) => {
367 let id: crate::db::ClosureId = id.into();
368 let (def, expr) = db.lookup_intern_closure(id);
369 TypeCtor::Closure { def, expr }
370 }
371
372 TypeName::Error => {
286 // this should not be reached, since we don't represent TypeName::Error with TypeCtor 373 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
287 unreachable!() 374 unreachable!()
288 } 375 }
@@ -355,26 +442,26 @@ impl ToChalk for Mutability {
355 } 442 }
356} 443}
357 444
358impl ToChalk for Impl { 445impl ToChalk for hir_def::ImplId {
359 type Chalk = ImplId; 446 type Chalk = ImplId;
360 447
361 fn to_chalk(self, db: &dyn HirDatabase) -> ImplId { 448 fn to_chalk(self, _db: &dyn HirDatabase) -> ImplId {
362 db.intern_chalk_impl(self).into() 449 chalk_ir::ImplId(self.as_intern_id())
363 } 450 }
364 451
365 fn from_chalk(db: &dyn HirDatabase, impl_id: ImplId) -> Impl { 452 fn from_chalk(_db: &dyn HirDatabase, impl_id: ImplId) -> hir_def::ImplId {
366 db.lookup_intern_chalk_impl(impl_id.into()) 453 InternKey::from_intern_id(impl_id.0)
367 } 454 }
368} 455}
369 456
370impl ToChalk for CallableDef { 457impl ToChalk for CallableDefId {
371 type Chalk = FnDefId; 458 type Chalk = FnDefId;
372 459
373 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId { 460 fn to_chalk(self, db: &dyn HirDatabase) -> FnDefId {
374 db.intern_callable_def(self).into() 461 db.intern_callable_def(self).into()
375 } 462 }
376 463
377 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDef { 464 fn from_chalk(db: &dyn HirDatabase, fn_def_id: FnDefId) -> CallableDefId {
378 db.lookup_intern_callable_def(fn_def_id.into()) 465 db.lookup_intern_callable_def(fn_def_id.into())
379 } 466 }
380} 467}
@@ -391,15 +478,20 @@ impl ToChalk for TypeAliasId {
391 } 478 }
392} 479}
393 480
394impl ToChalk for AssocTyValue { 481pub struct TypeAliasAsValue(pub TypeAliasId);
482
483impl ToChalk for TypeAliasAsValue {
395 type Chalk = AssociatedTyValueId; 484 type Chalk = AssociatedTyValueId;
396 485
397 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValueId { 486 fn to_chalk(self, _db: &dyn HirDatabase) -> AssociatedTyValueId {
398 db.intern_assoc_ty_value(self).into() 487 rust_ir::AssociatedTyValueId(self.0.as_intern_id())
399 } 488 }
400 489
401 fn from_chalk(db: &dyn HirDatabase, assoc_ty_value_id: AssociatedTyValueId) -> AssocTyValue { 490 fn from_chalk(
402 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))
403 } 495 }
404} 496}
405 497
@@ -447,6 +539,16 @@ impl ToChalk for GenericPredicate {
447 let ty = from_chalk(db, projection_eq.ty); 539 let ty = from_chalk(db, projection_eq.ty);
448 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty }) 540 GenericPredicate::Projection(ProjectionPredicate { projection_ty, ty })
449 } 541 }
542
543 chalk_ir::WhereClause::LifetimeOutlives(_) => {
544 // we shouldn't get these from Chalk
545 panic!("encountered LifetimeOutlives from Chalk")
546 }
547
548 chalk_ir::WhereClause::TypeOutlives(_) => {
549 // we shouldn't get these from Chalk
550 panic!("encountered TypeOutlives from Chalk")
551 }
450 } 552 }
451 } 553 }
452} 554}
@@ -510,22 +612,42 @@ where
510 type Chalk = chalk_ir::Canonical<T::Chalk>; 612 type Chalk = chalk_ir::Canonical<T::Chalk>;
511 613
512 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 614 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
513 let parameter = chalk_ir::CanonicalVarKind::new( 615 let kinds = self
514 chalk_ir::VariableKind::Ty(chalk_ir::TyKind::General), 616 .kinds
515 chalk_ir::UniverseIndex::ROOT, 617 .iter()
516 ); 618 .map(|k| match k {
619 TyKind::General => chalk_ir::TyKind::General,
620 TyKind::Integer => chalk_ir::TyKind::Integer,
621 TyKind::Float => chalk_ir::TyKind::Float,
622 })
623 .map(|tk| {
624 chalk_ir::CanonicalVarKind::new(
625 chalk_ir::VariableKind::Ty(tk),
626 chalk_ir::UniverseIndex::ROOT,
627 )
628 });
517 let value = self.value.to_chalk(db); 629 let value = self.value.to_chalk(db);
518 chalk_ir::Canonical { 630 chalk_ir::Canonical {
519 value, 631 value,
520 binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]), 632 binders: chalk_ir::CanonicalVarKinds::from_iter(&Interner, kinds),
521 } 633 }
522 } 634 }
523 635
524 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> {
525 Canonical { 637 let kinds = canonical
526 num_vars: canonical.binders.len(&Interner), 638 .binders
527 value: from_chalk(db, canonical.value), 639 .iter(&Interner)
528 } 640 .map(|k| match k.kind {
641 chalk_ir::VariableKind::Ty(tk) => match tk {
642 chalk_ir::TyKind::General => TyKind::General,
643 chalk_ir::TyKind::Integer => TyKind::Integer,
644 chalk_ir::TyKind::Float => TyKind::Float,
645 },
646 chalk_ir::VariableKind::Lifetime => panic!("unexpected lifetime from Chalk"),
647 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
648 })
649 .collect();
650 Canonical { kinds, value: from_chalk(db, canonical.value) }
529 } 651 }
530} 652}
531 653
@@ -578,58 +700,12 @@ where
578 } 700 }
579} 701}
580 702
581impl ToChalk for builtin::BuiltinImplData {
582 type Chalk = ImplDatum;
583
584 fn to_chalk(self, db: &dyn HirDatabase) -> ImplDatum {
585 let impl_type = rust_ir::ImplType::External;
586 let where_clauses = self.where_clauses.into_iter().map(|w| w.to_chalk(db)).collect();
587
588 let impl_datum_bound =
589 rust_ir::ImplDatumBound { trait_ref: self.trait_ref.to_chalk(db), where_clauses };
590 let associated_ty_value_ids =
591 self.assoc_ty_values.into_iter().map(|v| v.to_chalk(db)).collect();
592 rust_ir::ImplDatum {
593 binders: make_binders(impl_datum_bound, self.num_vars),
594 impl_type,
595 polarity: rust_ir::Polarity::Positive,
596 associated_ty_value_ids,
597 }
598 }
599
600 fn from_chalk(_db: &dyn HirDatabase, _data: ImplDatum) -> Self {
601 unimplemented!()
602 }
603}
604
605impl ToChalk for builtin::BuiltinImplAssocTyValueData {
606 type Chalk = AssociatedTyValue;
607
608 fn to_chalk(self, db: &dyn HirDatabase) -> AssociatedTyValue {
609 let ty = self.value.to_chalk(db);
610 let value_bound = rust_ir::AssociatedTyValueBound { ty };
611
612 rust_ir::AssociatedTyValue {
613 associated_ty_id: self.assoc_ty_id.to_chalk(db),
614 impl_id: self.impl_.to_chalk(db),
615 value: make_binders(value_bound, self.num_vars),
616 }
617 }
618
619 fn from_chalk(
620 _db: &dyn HirDatabase,
621 _data: AssociatedTyValue,
622 ) -> builtin::BuiltinImplAssocTyValueData {
623 unimplemented!()
624 }
625}
626
627pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> 703pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
628where 704where
629 T: HasInterner<Interner = Interner>, 705 T: HasInterner<Interner = Interner>,
630{ 706{
631 chalk_ir::Binders::new( 707 chalk_ir::Binders::new(
632 chalk_ir::VariableKinds::from( 708 chalk_ir::VariableKinds::from_iter(
633 &Interner, 709 &Interner,
634 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),
635 ), 711 ),
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index d88828c7c..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
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner}; 7use super::{from_chalk, Interner};
8use crate::{db::HirDatabase, CallableDef, TypeCtor}; 8use crate::{db::HirDatabase, CallableDefId, TypeCtor};
9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, DefWithBodyId, Lookup, TypeAliasId};
10 10
11pub use unsafe_tls::{set_current_program, with_current_program}; 11pub use unsafe_tls::{set_current_program, with_current_program};
12 12
13pub struct DebugContext<'a>(&'a (dyn HirDatabase + 'a)); 13pub struct DebugContext<'a>(&'a dyn HirDatabase);
14 14
15impl DebugContext<'_> { 15impl 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 }
@@ -69,6 +69,11 @@ impl DebugContext<'_> {
69 let name = self.0.type_alias_data(type_alias).name.clone(); 69 let name = self.0.type_alias_data(type_alias).name.clone();
70 write!(f, "{}::{}", trait_name, name)?; 70 write!(f, "{}::{}", trait_name, name)?;
71 } 71 }
72 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
73 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
74 write!(f, "{{impl trait {} of {:?}}}", idx, func)?;
75 }
76 },
72 TypeCtor::Closure { def, expr } => { 77 TypeCtor::Closure { def, expr } => {
73 write!(f, "{{closure {:?} in ", expr.into_raw())?; 78 write!(f, "{{closure {:?} in ", expr.into_raw())?;
74 match def { 79 match def {
@@ -152,7 +157,7 @@ impl DebugContext<'_> {
152 _ => panic!("associated type not in trait"), 157 _ => panic!("associated type not in trait"),
153 }; 158 };
154 let trait_data = self.0.trait_data(trait_); 159 let trait_data = self.0.trait_data(trait_);
155 let params = projection_ty.substitution.parameters(&Interner); 160 let params = projection_ty.substitution.as_slice(&Interner);
156 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?; 161 write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
157 if params.len() > 1 { 162 if params.len() > 1 {
158 write!( 163 write!(
@@ -250,18 +255,18 @@ impl DebugContext<'_> {
250 fn_def_id: chalk_ir::FnDefId<Interner>, 255 fn_def_id: chalk_ir::FnDefId<Interner>,
251 fmt: &mut fmt::Formatter<'_>, 256 fmt: &mut fmt::Formatter<'_>,
252 ) -> Result<(), fmt::Error> { 257 ) -> Result<(), fmt::Error> {
253 let def: CallableDef = from_chalk(self.0, fn_def_id); 258 let def: CallableDefId = from_chalk(self.0, fn_def_id);
254 let name = match def { 259 let name = match def {
255 CallableDef::FunctionId(ff) => self.0.function_data(ff).name.clone(), 260 CallableDefId::FunctionId(ff) => self.0.function_data(ff).name.clone(),
256 CallableDef::StructId(s) => self.0.struct_data(s).name.clone(), 261 CallableDefId::StructId(s) => self.0.struct_data(s).name.clone(),
257 CallableDef::EnumVariantId(e) => { 262 CallableDefId::EnumVariantId(e) => {
258 let enum_data = self.0.enum_data(e.parent); 263 let enum_data = self.0.enum_data(e.parent);
259 enum_data.variants[e.local_id].name.clone() 264 enum_data.variants[e.local_id].name.clone()
260 } 265 }
261 }; 266 };
262 match def { 267 match def {
263 CallableDef::FunctionId(_) => write!(fmt, "{{fn {}}}", name), 268 CallableDefId::FunctionId(_) => write!(fmt, "{{fn {}}}", name),
264 CallableDef::StructId(_) | CallableDef::EnumVariantId(_) => { 269 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {
265 write!(fmt, "{{ctor {}}}", name) 270 write!(fmt, "{{ctor {}}}", name)
266 } 271 }
267 } 272 }