diff options
Diffstat (limited to 'crates/hir_ty/src/traits')
-rw-r--r-- | crates/hir_ty/src/traits/chalk.rs | 77 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 435 |
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; | |||
17 | use crate::{ | 17 | use 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 | }; | ||
27 | use mapping::{ | ||
28 | convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue, | ||
29 | }; | 26 | }; |
27 | use mapping::{convert_where_clauses, generic_predicate_to_inline_bound, TypeAliasAsValue}; | ||
30 | 28 | ||
31 | pub use self::interner::Interner; | 29 | pub use self::interner::Interner; |
32 | pub(crate) use self::interner::*; | 30 | pub(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 | ||
6 | use chalk_ir::{cast::Cast, interner::HasInterner}; | 6 | use chalk_ir::cast::Cast; |
7 | use chalk_solve::rust_ir; | 7 | use chalk_solve::rust_ir; |
8 | 8 | ||
9 | use base_db::salsa::InternKey; | 9 | use base_db::salsa::InternKey; |
10 | use hir_def::{GenericDefId, TypeAliasId}; | 10 | use hir_def::{GenericDefId, TypeAliasId}; |
11 | 11 | ||
12 | use crate::{ | 12 | use 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 | ||
18 | use super::interner::*; | 17 | use super::interner::*; |
19 | use super::*; | 18 | use super::*; |
20 | 19 | ||
21 | impl 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 | |||
180 | impl 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 | |||
198 | impl 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 | |||
217 | impl 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 | |||
233 | impl ToChalk for hir_def::TraitId { | 20 | impl 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 | ||
286 | impl 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 | |||
321 | impl 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 | } | ||
341 | impl 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 | |||
359 | impl 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 | |||
381 | impl 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 | |||
393 | impl 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 | |||
410 | impl<T> ToChalk for Canonical<T> | ||
411 | where | ||
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 | |||
427 | impl<T: ToChalk> ToChalk for InEnvironment<T> | ||
428 | where | ||
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 | |||
445 | impl<T: ToChalk> ToChalk for crate::Binders<T> | ||
446 | where | ||
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 | |||
462 | impl 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 | |||
474 | pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> | ||
475 | where | ||
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 | |||
488 | pub(super) fn convert_where_clauses( | 73 | pub(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 |