aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r--crates/hir_ty/src/traits/chalk.rs77
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs435
2 files changed, 44 insertions, 468 deletions
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index f03b92422..b8c390b2e 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -17,16 +17,14 @@ use super::ChalkContext;
17use crate::{ 17use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id, 20 from_assoc_type_id, make_only_type_binders,
21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id, to_chalk_trait_id, 22 to_assoc_type_id, to_chalk_trait_id,
23 utils::generics, 23 utils::generics,
24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution, 24 AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
25 TraitRef, Ty, TyBuilder, TyExt, TyKind, WhereClause, 25 TraitRef, TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
26};
27use mapping::{
28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
29}; 26};
27use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, TypeAliasAsValue};
30 28
31pub use self::interner::Interner; 29pub use self::interner::Interner;
32pub(crate) use self::interner::*; 30pub(crate) use self::interner::*;
@@ -86,7 +84,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
86 debug!("impls_for_trait {:?}", trait_id); 84 debug!("impls_for_trait {:?}", trait_id);
87 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id); 85 let trait_: hir_def::TraitId = from_chalk(self.db, trait_id);
88 86
89 let ty: Ty = from_chalk(self.db, parameters[0].assert_ty_ref(&Interner).clone()); 87 let ty: Ty = parameters[0].assert_ty_ref(&Interner).clone();
90 88
91 fn binder_kind( 89 fn binder_kind(
92 ty: &Ty, 90 ty: &Ty,
@@ -187,16 +185,11 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
187 let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders(); 185 let (datas, binders) = (*datas).as_ref().into_value_and_skipped_binders();
188 let data = &datas.impl_traits[idx as usize]; 186 let data = &datas.impl_traits[idx as usize];
189 let bound = OpaqueTyDatumBound { 187 let bound = OpaqueTyDatumBound {
190 bounds: make_binders( 188 bounds: make_only_type_binders(
191 data.bounds
192 .skip_binders()
193 .iter()
194 .cloned()
195 .map(|b| b.to_chalk(self.db))
196 .collect(),
197 1, 189 1,
190 data.bounds.skip_binders().iter().cloned().collect(),
198 ), 191 ),
199 where_clauses: make_binders(vec![], 0), 192 where_clauses: make_only_type_binders(0, vec![]),
200 }; 193 };
201 chalk_ir::Binders::new(binders, bound) 194 chalk_ir::Binders::new(binders, bound)
202 } 195 }
@@ -244,25 +237,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
244 .intern(&Interner), 237 .intern(&Interner),
245 }); 238 });
246 let bound = OpaqueTyDatumBound { 239 let bound = OpaqueTyDatumBound {
247 bounds: make_binders( 240 bounds: make_only_type_binders(
241 1,
248 vec![ 242 vec![
249 crate::wrap_empty_binders(impl_bound).to_chalk(self.db), 243 crate::wrap_empty_binders(impl_bound),
250 crate::wrap_empty_binders(proj_bound).to_chalk(self.db), 244 crate::wrap_empty_binders(proj_bound),
251 ], 245 ],
252 1,
253 ), 246 ),
254 where_clauses: make_binders(vec![], 0), 247 where_clauses: make_only_type_binders(0, vec![]),
255 }; 248 };
256 // The opaque type has 1 parameter. 249 // The opaque type has 1 parameter.
257 make_binders(bound, 1) 250 make_only_type_binders(1, bound)
258 } else { 251 } else {
259 // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback. 252 // If failed to find Symbol’s value as variable is void: Future::Output, return empty bounds as fallback.
260 let bound = OpaqueTyDatumBound { 253 let bound = OpaqueTyDatumBound {
261 bounds: make_binders(vec![], 0), 254 bounds: make_only_type_binders(0, vec![]),
262 where_clauses: make_binders(vec![], 0), 255 where_clauses: make_only_type_binders(0, vec![]),
263 }; 256 };
264 // The opaque type has 1 parameter. 257 // The opaque type has 1 parameter.
265 make_binders(bound, 1) 258 make_only_type_binders(1, bound)
266 } 259 }
267 } 260 }
268 }; 261 };
@@ -272,7 +265,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
272 265
273 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 266 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
274 // FIXME: actually provide the hidden type; it is relevant for auto traits 267 // FIXME: actually provide the hidden type; it is relevant for auto traits
275 TyKind::Error.intern(&Interner).to_chalk(self.db) 268 TyKind::Error.intern(&Interner)
276 } 269 }
277 270
278 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { 271 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
@@ -293,29 +286,28 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
293 _closure_id: chalk_ir::ClosureId<Interner>, 286 _closure_id: chalk_ir::ClosureId<Interner>,
294 substs: &chalk_ir::Substitution<Interner>, 287 substs: &chalk_ir::Substitution<Interner>,
295 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 288 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
296 let sig_ty: Ty = 289 let sig_ty = substs.at(&Interner, 0).assert_ty_ref(&Interner).clone();
297 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
298 let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr"); 290 let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
299 let io = rust_ir::FnDefInputsAndOutputDatum { 291 let io = rust_ir::FnDefInputsAndOutputDatum {
300 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), 292 argument_types: sig.params().iter().cloned().collect(),
301 return_type: sig.ret().clone().to_chalk(self.db), 293 return_type: sig.ret().clone(),
302 }; 294 };
303 make_binders(io.shifted_in(&Interner), 0) 295 make_only_type_binders(0, io.shifted_in(&Interner))
304 } 296 }
305 fn closure_upvars( 297 fn closure_upvars(
306 &self, 298 &self,
307 _closure_id: chalk_ir::ClosureId<Interner>, 299 _closure_id: chalk_ir::ClosureId<Interner>,
308 _substs: &chalk_ir::Substitution<Interner>, 300 _substs: &chalk_ir::Substitution<Interner>,
309 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> { 301 ) -> chalk_ir::Binders<chalk_ir::Ty<Interner>> {
310 let ty = TyBuilder::unit().to_chalk(self.db); 302 let ty = TyBuilder::unit();
311 make_binders(ty, 0) 303 make_only_type_binders(0, ty)
312 } 304 }
313 fn closure_fn_substitution( 305 fn closure_fn_substitution(
314 &self, 306 &self,
315 _closure_id: chalk_ir::ClosureId<Interner>, 307 _closure_id: chalk_ir::ClosureId<Interner>,
316 _substs: &chalk_ir::Substitution<Interner>, 308 _substs: &chalk_ir::Substitution<Interner>,
317 ) -> chalk_ir::Substitution<Interner> { 309 ) -> chalk_ir::Substitution<Interner> {
318 Substitution::empty(&Interner).to_chalk(self.db) 310 Substitution::empty(&Interner)
319 } 311 }
320 312
321 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String { 313 fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -410,10 +402,10 @@ pub(crate) fn associated_ty_data_query(
410 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars); 402 let where_clauses = convert_where_clauses(db, type_alias.into(), &bound_vars);
411 let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses }; 403 let bound_data = rust_ir::AssociatedTyDatumBound { bounds, where_clauses };
412 let datum = AssociatedTyDatum { 404 let datum = AssociatedTyDatum {
413 trait_id: trait_.to_chalk(db), 405 trait_id: to_chalk_trait_id(trait_),
414 id, 406 id,
415 name: type_alias, 407 name: type_alias,
416 binders: make_binders(bound_data, generic_params.len()), 408 binders: make_only_type_binders(generic_params.len(), bound_data),
417 }; 409 };
418 Arc::new(datum) 410 Arc::new(datum)
419} 411}
@@ -446,7 +438,7 @@ pub(crate) fn trait_datum_query(
446 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 438 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
447 let trait_datum = TraitDatum { 439 let trait_datum = TraitDatum {
448 id: trait_id, 440 id: trait_id,
449 binders: make_binders(trait_datum_bound, bound_vars.len(&Interner)), 441 binders: make_only_type_binders(bound_vars.len(&Interner), trait_datum_bound),
450 flags, 442 flags,
451 associated_ty_ids, 443 associated_ty_ids,
452 well_known, 444 well_known,
@@ -515,7 +507,7 @@ pub(crate) fn struct_datum_query(
515 // FIXME set ADT kind 507 // FIXME set ADT kind
516 kind: rust_ir::AdtKind::Struct, 508 kind: rust_ir::AdtKind::Struct,
517 id: struct_id, 509 id: struct_id,
518 binders: make_binders(struct_datum_bound, num_params), 510 binders: make_only_type_binders(num_params, struct_datum_bound),
519 flags, 511 flags,
520 }; 512 };
521 Arc::new(struct_datum) 513 Arc::new(struct_datum)
@@ -563,7 +555,6 @@ fn impl_def_datum(
563 trait_ref.display(db), 555 trait_ref.display(db),
564 where_clauses 556 where_clauses
565 ); 557 );
566 let trait_ref = trait_ref.to_chalk(db);
567 558
568 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive }; 559 let polarity = if negative { rust_ir::Polarity::Negative } else { rust_ir::Polarity::Positive };
569 560
@@ -585,7 +576,7 @@ fn impl_def_datum(
585 .collect(); 576 .collect();
586 debug!("impl_datum: {:?}", impl_datum_bound); 577 debug!("impl_datum: {:?}", impl_datum_bound);
587 let impl_datum = ImplDatum { 578 let impl_datum = ImplDatum {
588 binders: make_binders(impl_datum_bound, bound_vars.len(&Interner)), 579 binders: make_only_type_binders(bound_vars.len(&Interner), impl_datum_bound),
589 impl_type, 580 impl_type,
590 polarity, 581 polarity,
591 associated_ty_value_ids, 582 associated_ty_value_ids,
@@ -624,7 +615,7 @@ fn type_alias_associated_ty_value(
624 .associated_type_by_name(&type_alias_data.name) 615 .associated_type_by_name(&type_alias_data.name)
625 .expect("assoc ty value should not exist"); // validated when building the impl data as well 616 .expect("assoc ty value should not exist"); // validated when building the impl data as well
626 let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders(); 617 let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders();
627 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; 618 let value_bound = rust_ir::AssociatedTyValueBound { ty };
628 let value = rust_ir::AssociatedTyValue { 619 let value = rust_ir::AssociatedTyValue {
629 impl_id: impl_id.to_chalk(db), 620 impl_id: impl_id.to_chalk(db),
630 associated_ty_id: to_assoc_type_id(assoc_ty), 621 associated_ty_id: to_assoc_type_id(assoc_ty),
@@ -645,13 +636,13 @@ pub(crate) fn fn_def_datum_query(
645 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars); 636 let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
646 let bound = rust_ir::FnDefDatumBound { 637 let bound = rust_ir::FnDefDatumBound {
647 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway 638 // Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
648 inputs_and_output: make_binders( 639 inputs_and_output: make_only_type_binders(
640 0,
649 rust_ir::FnDefInputsAndOutputDatum { 641 rust_ir::FnDefInputsAndOutputDatum {
650 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(), 642 argument_types: sig.params().iter().cloned().collect(),
651 return_type: sig.ret().clone().to_chalk(db), 643 return_type: sig.ret().clone(),
652 } 644 }
653 .shifted_in(&Interner), 645 .shifted_in(&Interner),
654 0,
655 ), 646 ),
656 where_clauses, 647 where_clauses,
657 }; 648 };
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 84abd99b2..7818f6387 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -3,233 +3,20 @@
3//! Chalk (in both directions); plus some helper functions for more specialized 3//! Chalk (in both directions); plus some helper functions for more specialized
4//! conversions. 4//! conversions.
5 5
6use chalk_ir::{cast::Cast, interner::HasInterner}; 6use chalk_ir::cast::Cast;
7use chalk_solve::rust_ir; 7use chalk_solve::rust_ir;
8 8
9use base_db::salsa::InternKey; 9use base_db::salsa::InternKey;
10use hir_def::{GenericDefId, TypeAliasId}; 10use hir_def::{GenericDefId, TypeAliasId};
11 11
12use crate::{ 12use crate::{
13 chalk_ext::ProjectionTyExt, db::HirDatabase, static_lifetime, AliasTy, CallableDefId, 13 db::HirDatabase, AliasTy, CallableDefId, ProjectionTyExt, QuantifiedWhereClause, Substitution,
14 Canonical, ConstrainedSubst, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, 14 Ty, WhereClause,
15 ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
16}; 15};
17 16
18use super::interner::*; 17use super::interner::*;
19use super::*; 18use super::*;
20 19
21impl ToChalk for Ty {
22 type Chalk = chalk_ir::Ty<Interner>;
23 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
24 match self.into_inner() {
25 TyKind::Ref(m, lt, ty) => {
26 chalk_ir::TyKind::Ref(m, lt, ty.to_chalk(db)).intern(&Interner)
27 }
28 TyKind::Array(ty, size) => {
29 chalk_ir::TyKind::Array(ty.to_chalk(db), size).intern(&Interner)
30 }
31 TyKind::Function(FnPointer { sig, substitution: substs, num_binders }) => {
32 let substitution = chalk_ir::FnSubst(substs.0.to_chalk(db));
33 chalk_ir::TyKind::Function(chalk_ir::FnPointer { num_binders, sig, substitution })
34 .intern(&Interner)
35 }
36 TyKind::AssociatedType(assoc_type_id, substs) => {
37 let substitution = substs.to_chalk(db);
38 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
39 }
40
41 TyKind::OpaqueType(id, substs) => {
42 let substitution = substs.to_chalk(db);
43 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
44 }
45
46 TyKind::Foreign(id) => chalk_ir::TyKind::Foreign(id).intern(&Interner),
47
48 TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
49
50 TyKind::Tuple(cardinality, substs) => {
51 let substitution = substs.to_chalk(db);
52 chalk_ir::TyKind::Tuple(cardinality, substitution).intern(&Interner)
53 }
54 TyKind::Raw(mutability, ty) => {
55 let ty = ty.to_chalk(db);
56 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner)
57 }
58 TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner),
59 TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner),
60 TyKind::FnDef(id, substs) => {
61 let substitution = substs.to_chalk(db);
62 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
63 }
64 TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner),
65
66 TyKind::Closure(closure_id, substs) => {
67 let substitution = substs.to_chalk(db);
68 chalk_ir::TyKind::Closure(closure_id, substitution).intern(&Interner)
69 }
70
71 TyKind::Adt(adt_id, substs) => {
72 let substitution = substs.to_chalk(db);
73 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner)
74 }
75 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
76 chalk_ir::AliasTy::Projection(proj_ty.to_chalk(db))
77 .cast(&Interner)
78 .intern(&Interner)
79 }
80 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
81 chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)).cast(&Interner).intern(&Interner)
82 }
83 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
84 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
85 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
86 TyKind::Dyn(dyn_ty) => {
87 let (bounds, binders) = dyn_ty.bounds.into_value_and_skipped_binders();
88 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
89 &Interner,
90 bounds.interned().iter().cloned().map(|p| p.to_chalk(db)),
91 );
92 let bounded_ty = chalk_ir::DynTy {
93 bounds: chalk_ir::Binders::new(binders, where_clauses),
94 lifetime: dyn_ty.lifetime,
95 };
96 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
97 }
98 TyKind::Error => chalk_ir::TyKind::Error.intern(&Interner),
99 }
100 }
101 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
102 match chalk.data(&Interner).kind.clone() {
103 chalk_ir::TyKind::Error => TyKind::Error,
104 chalk_ir::TyKind::Array(ty, size) => TyKind::Array(from_chalk(db, ty), size),
105 chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
106 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
107 TyKind::Alias(AliasTy::Projection(from_chalk(db, proj)))
108 }
109 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
110 TyKind::Alias(AliasTy::Opaque(from_chalk(db, opaque_ty)))
111 }
112 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
113 num_binders,
114 sig,
115 substitution,
116 ..
117 }) => {
118 assert_eq!(num_binders, 0);
119 let substs = crate::FnSubst(from_chalk(db, substitution.0));
120 TyKind::Function(FnPointer { num_binders, sig, substitution: substs })
121 }
122 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
123 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Error,
124 chalk_ir::TyKind::Dyn(dyn_ty) => {
125 assert_eq!(dyn_ty.bounds.binders.len(&Interner), 1);
126 let (bounds, binders) = dyn_ty.bounds.into_value_and_skipped_binders();
127 let where_clauses = crate::QuantifiedWhereClauses::from_iter(
128 &Interner,
129 bounds.interned().iter().cloned().map(|p| from_chalk(db, p)),
130 );
131 TyKind::Dyn(crate::DynTy {
132 bounds: crate::Binders::new(binders, where_clauses),
133 // HACK: we sometimes get lifetime variables back in solutions
134 // from Chalk, and don't have the infrastructure to substitute
135 // them yet. So for now we just turn them into 'static right
136 // when we get them
137 lifetime: static_lifetime(),
138 })
139 }
140
141 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
142 chalk_ir::TyKind::AssociatedType(type_id, subst) => {
143 TyKind::AssociatedType(type_id, from_chalk(db, subst))
144 }
145
146 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
147 TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst))
148 }
149
150 chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar),
151 chalk_ir::TyKind::Tuple(cardinality, subst) => {
152 TyKind::Tuple(cardinality, from_chalk(db, subst))
153 }
154 chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)),
155 chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)),
156 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
157 // HACK: we sometimes get lifetime variables back in solutions
158 // from Chalk, and don't have the infrastructure to substitute
159 // them yet. So for now we just turn them into 'static right
160 // when we get them
161 TyKind::Ref(mutability, static_lifetime(), from_chalk(db, ty))
162 }
163 chalk_ir::TyKind::Str => TyKind::Str,
164 chalk_ir::TyKind::Never => TyKind::Never,
165
166 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
167 TyKind::FnDef(fn_def_id, from_chalk(db, subst))
168 }
169
170 chalk_ir::TyKind::Closure(id, subst) => TyKind::Closure(id, from_chalk(db, subst)),
171
172 chalk_ir::TyKind::Foreign(foreign_def_id) => TyKind::Foreign(foreign_def_id),
173 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
174 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
175 }
176 .intern(&Interner)
177 }
178}
179
180impl ToChalk for GenericArg {
181 type Chalk = chalk_ir::GenericArg<Interner>;
182
183 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
184 match self.interned() {
185 crate::GenericArgData::Ty(ty) => ty.clone().to_chalk(db).cast(&Interner),
186 }
187 }
188
189 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
190 match chalk.interned() {
191 chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
192 chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
193 chalk_ir::GenericArgData::Const(_) => unimplemented!(),
194 }
195 }
196}
197
198impl ToChalk for Substitution {
199 type Chalk = chalk_ir::Substitution<Interner>;
200
201 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
202 chalk_ir::Substitution::from_iter(
203 &Interner,
204 self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
205 )
206 }
207
208 fn from_chalk(
209 db: &dyn HirDatabase,
210 parameters: chalk_ir::Substitution<Interner>,
211 ) -> Substitution {
212 let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
213 Substitution::intern(tys)
214 }
215}
216
217impl ToChalk for TraitRef {
218 type Chalk = chalk_ir::TraitRef<Interner>;
219
220 fn to_chalk(self: TraitRef, db: &dyn HirDatabase) -> chalk_ir::TraitRef<Interner> {
221 let trait_id = self.trait_id;
222 let substitution = self.substitution.to_chalk(db);
223 chalk_ir::TraitRef { trait_id, substitution }
224 }
225
226 fn from_chalk(db: &dyn HirDatabase, trait_ref: chalk_ir::TraitRef<Interner>) -> Self {
227 let trait_id = trait_ref.trait_id;
228 let substs = from_chalk(db, trait_ref.substitution);
229 TraitRef { trait_id, substitution: substs }
230 }
231}
232
233impl ToChalk for hir_def::TraitId { 20impl ToChalk for hir_def::TraitId {
234 type Chalk = TraitId; 21 type Chalk = TraitId;
235 22
@@ -283,208 +70,6 @@ impl ToChalk for TypeAliasAsValue {
283 } 70 }
284} 71}
285 72
286impl ToChalk for WhereClause {
287 type Chalk = chalk_ir::WhereClause<Interner>;
288
289 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::WhereClause<Interner> {
290 match self {
291 WhereClause::Implemented(trait_ref) => {
292 chalk_ir::WhereClause::Implemented(trait_ref.to_chalk(db))
293 }
294 WhereClause::AliasEq(alias_eq) => chalk_ir::WhereClause::AliasEq(alias_eq.to_chalk(db)),
295 }
296 }
297
298 fn from_chalk(
299 db: &dyn HirDatabase,
300 where_clause: chalk_ir::WhereClause<Interner>,
301 ) -> WhereClause {
302 match where_clause {
303 chalk_ir::WhereClause::Implemented(tr) => WhereClause::Implemented(from_chalk(db, tr)),
304 chalk_ir::WhereClause::AliasEq(alias_eq) => {
305 WhereClause::AliasEq(from_chalk(db, alias_eq))
306 }
307
308 chalk_ir::WhereClause::LifetimeOutlives(_) => {
309 // we shouldn't get these from Chalk
310 panic!("encountered LifetimeOutlives from Chalk")
311 }
312
313 chalk_ir::WhereClause::TypeOutlives(_) => {
314 // we shouldn't get these from Chalk
315 panic!("encountered TypeOutlives from Chalk")
316 }
317 }
318 }
319}
320
321impl ToChalk for ProjectionTy {
322 type Chalk = chalk_ir::ProjectionTy<Interner>;
323
324 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
325 chalk_ir::ProjectionTy {
326 associated_ty_id: self.associated_ty_id,
327 substitution: self.substitution.to_chalk(db),
328 }
329 }
330
331 fn from_chalk(
332 db: &dyn HirDatabase,
333 projection_ty: chalk_ir::ProjectionTy<Interner>,
334 ) -> ProjectionTy {
335 ProjectionTy {
336 associated_ty_id: projection_ty.associated_ty_id,
337 substitution: from_chalk(db, projection_ty.substitution),
338 }
339 }
340}
341impl ToChalk for OpaqueTy {
342 type Chalk = chalk_ir::OpaqueTy<Interner>;
343
344 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
345 chalk_ir::OpaqueTy {
346 opaque_ty_id: self.opaque_ty_id,
347 substitution: self.substitution.to_chalk(db),
348 }
349 }
350
351 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
352 OpaqueTy {
353 opaque_ty_id: chalk.opaque_ty_id,
354 substitution: from_chalk(db, chalk.substitution),
355 }
356 }
357}
358
359impl ToChalk for AliasTy {
360 type Chalk = chalk_ir::AliasTy<Interner>;
361
362 fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
363 match self {
364 AliasTy::Projection(projection_ty) => {
365 chalk_ir::AliasTy::Projection(projection_ty.to_chalk(db))
366 }
367 AliasTy::Opaque(opaque_ty) => chalk_ir::AliasTy::Opaque(opaque_ty.to_chalk(db)),
368 }
369 }
370
371 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
372 match chalk {
373 chalk_ir::AliasTy::Projection(projection_ty) => {
374 AliasTy::Projection(from_chalk(db, projection_ty))
375 }
376 chalk_ir::AliasTy::Opaque(opaque_ty) => AliasTy::Opaque(from_chalk(db, opaque_ty)),
377 }
378 }
379}
380
381impl ToChalk for AliasEq {
382 type Chalk = chalk_ir::AliasEq<Interner>;
383
384 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
385 chalk_ir::AliasEq { alias: self.alias.to_chalk(db), ty: self.ty.to_chalk(db) }
386 }
387
388 fn from_chalk(db: &dyn HirDatabase, alias_eq: chalk_ir::AliasEq<Interner>) -> Self {
389 AliasEq { alias: from_chalk(db, alias_eq.alias), ty: from_chalk(db, alias_eq.ty) }
390 }
391}
392
393impl ToChalk for DomainGoal {
394 type Chalk = chalk_ir::DomainGoal<Interner>;
395
396 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::DomainGoal<Interner> {
397 match self {
398 DomainGoal::Holds(WhereClause::Implemented(tr)) => tr.to_chalk(db).cast(&Interner),
399 DomainGoal::Holds(WhereClause::AliasEq(alias_eq)) => {
400 alias_eq.to_chalk(db).cast(&Interner)
401 }
402 }
403 }
404
405 fn from_chalk(_db: &dyn HirDatabase, _goal: chalk_ir::DomainGoal<Interner>) -> Self {
406 unimplemented!()
407 }
408}
409
410impl<T> ToChalk for Canonical<T>
411where
412 T: ToChalk,
413 T::Chalk: HasInterner<Interner = Interner>,
414{
415 type Chalk = chalk_ir::Canonical<T::Chalk>;
416
417 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
418 let value = self.value.to_chalk(db);
419 chalk_ir::Canonical { value, binders: self.binders }
420 }
421
422 fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
423 Canonical { binders: canonical.binders, value: from_chalk(db, canonical.value) }
424 }
425}
426
427impl<T: ToChalk> ToChalk for InEnvironment<T>
428where
429 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
430{
431 type Chalk = chalk_ir::InEnvironment<T::Chalk>;
432
433 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
434 chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
435 }
436
437 fn from_chalk(
438 _db: &dyn HirDatabase,
439 _in_env: chalk_ir::InEnvironment<T::Chalk>,
440 ) -> InEnvironment<T> {
441 unimplemented!()
442 }
443}
444
445impl<T: ToChalk> ToChalk for crate::Binders<T>
446where
447 T::Chalk: chalk_ir::interner::HasInterner<Interner = Interner>,
448{
449 type Chalk = chalk_ir::Binders<T::Chalk>;
450
451 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
452 let (value, binders) = self.into_value_and_skipped_binders();
453 chalk_ir::Binders::new(binders, value.to_chalk(db))
454 }
455
456 fn from_chalk(db: &dyn HirDatabase, binders: chalk_ir::Binders<T::Chalk>) -> crate::Binders<T> {
457 let (v, b) = binders.into_value_and_skipped_binders();
458 crate::Binders::new(b, from_chalk(db, v))
459 }
460}
461
462impl ToChalk for crate::ConstrainedSubst {
463 type Chalk = chalk_ir::ConstrainedSubst<Interner>;
464
465 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {
466 unimplemented!()
467 }
468
469 fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
470 ConstrainedSubst { subst: from_chalk(db, chalk.subst) }
471 }
472}
473
474pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
475where
476 T: HasInterner<Interner = Interner>,
477{
478 chalk_ir::Binders::new(
479 chalk_ir::VariableKinds::from_iter(
480 &Interner,
481 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
482 .take(num_vars),
483 ),
484 value,
485 )
486}
487
488pub(super) fn convert_where_clauses( 73pub(super) fn convert_where_clauses(
489 db: &dyn HirDatabase, 74 db: &dyn HirDatabase,
490 def: GenericDefId, 75 def: GenericDefId,
@@ -493,7 +78,7 @@ pub(super) fn convert_where_clauses(
493 let generic_predicates = db.generic_predicates(def); 78 let generic_predicates = db.generic_predicates(def);
494 let mut result = Vec::with_capacity(generic_predicates.len()); 79 let mut result = Vec::with_capacity(generic_predicates.len());
495 for pred in generic_predicates.iter() { 80 for pred in generic_predicates.iter() {
496 result.push(pred.clone().substitute(&Interner, substs).to_chalk(db)); 81 result.push(pred.clone().substitute(&Interner, substs));
497 } 82 }
498 result 83 result
499} 84}
@@ -505,33 +90,33 @@ pub(super) fn generic_predicate_to_inline_bound(
505) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> { 90) -> Option<chalk_ir::Binders<rust_ir::InlineBound<Interner>>> {
506 // An InlineBound is like a GenericPredicate, except the self type is left out. 91 // An InlineBound is like a GenericPredicate, except the self type is left out.
507 // We don't have a special type for this, but Chalk does. 92 // We don't have a special type for this, but Chalk does.
508 let self_ty_shifted_in = self_ty.clone().shifted_in_from(DebruijnIndex::ONE); 93 let self_ty_shifted_in = self_ty.clone().shifted_in_from(&Interner, DebruijnIndex::ONE);
509 let (pred, binders) = pred.as_ref().into_value_and_skipped_binders(); 94 let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
510 match pred { 95 match pred {
511 WhereClause::Implemented(trait_ref) => { 96 WhereClause::Implemented(trait_ref) => {
512 if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in { 97 if trait_ref.self_type_parameter(&Interner) != self_ty_shifted_in {
513 // we can only convert predicates back to type bounds if they 98 // we can only convert predicates back to type bounds if they
514 // have the expected self type 99 // have the expected self type
515 return None; 100 return None;
516 } 101 }
517 let args_no_self = trait_ref.substitution.interned()[1..] 102 let args_no_self = trait_ref.substitution.interned()[1..]
518 .iter() 103 .iter()
519 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 104 .map(|ty| ty.clone().cast(&Interner))
520 .collect(); 105 .collect();
521 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self }; 106 let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
522 Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound))) 107 Some(chalk_ir::Binders::new(binders, rust_ir::InlineBound::TraitBound(trait_bound)))
523 } 108 }
524 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => { 109 WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
525 if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in { 110 if projection_ty.self_type_parameter(&Interner) != self_ty_shifted_in {
526 return None; 111 return None;
527 } 112 }
528 let trait_ = projection_ty.trait_(db); 113 let trait_ = projection_ty.trait_(db);
529 let args_no_self = projection_ty.substitution.interned()[1..] 114 let args_no_self = projection_ty.substitution.interned()[1..]
530 .iter() 115 .iter()
531 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 116 .map(|ty| ty.clone().cast(&Interner))
532 .collect(); 117 .collect();
533 let alias_eq_bound = rust_ir::AliasEqBound { 118 let alias_eq_bound = rust_ir::AliasEqBound {
534 value: ty.clone().to_chalk(db), 119 value: ty.clone(),
535 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, 120 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
536 associated_ty_id: projection_ty.associated_ty_id, 121 associated_ty_id: projection_ty.associated_ty_id,
537 parameters: Vec::new(), // FIXME we don't support generic associated types yet 122 parameters: Vec::new(), // FIXME we don't support generic associated types yet