diff options
Diffstat (limited to 'crates/ra_hir_ty/src/traits/chalk.rs')
-rw-r--r-- | crates/ra_hir_ty/src/traits/chalk.rs | 145 |
1 files changed, 123 insertions, 22 deletions
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs index e00a82db2..1ccb7c3b4 100644 --- a/crates/ra_hir_ty/src/traits/chalk.rs +++ b/crates/ra_hir_ty/src/traits/chalk.rs | |||
@@ -4,8 +4,8 @@ use std::{fmt, sync::Arc}; | |||
4 | use log::debug; | 4 | use log::debug; |
5 | 5 | ||
6 | use chalk_ir::{ | 6 | use chalk_ir::{ |
7 | cast::Cast, fold::shift::Shift, Goal, GoalData, Parameter, PlaceholderIndex, TypeName, | 7 | cast::Cast, fold::shift::Shift, interner::HasInterner, Goal, GoalData, Parameter, |
8 | UniverseIndex, | 8 | PlaceholderIndex, TypeName, UniverseIndex, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; | 11 | use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId}; |
@@ -33,8 +33,10 @@ impl chalk_ir::interner::Interner for Interner { | |||
33 | type InternedGoals = Vec<Goal<Self>>; | 33 | type InternedGoals = Vec<Goal<Self>>; |
34 | type InternedSubstitution = Vec<Parameter<Self>>; | 34 | type InternedSubstitution = Vec<Parameter<Self>>; |
35 | type InternedProgramClause = chalk_ir::ProgramClauseData<Self>; | 35 | type InternedProgramClause = chalk_ir::ProgramClauseData<Self>; |
36 | type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>; | 36 | type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; |
37 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; | 37 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; |
38 | type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>; | ||
39 | type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<UniverseIndex>>; | ||
38 | type Identifier = TypeAliasId; | 40 | type Identifier = TypeAliasId; |
39 | type DefId = InternId; | 41 | type DefId = InternId; |
40 | 42 | ||
@@ -60,6 +62,27 @@ impl chalk_ir::interner::Interner for Interner { | |||
60 | tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt))) | 62 | tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt))) |
61 | } | 63 | } |
62 | 64 | ||
65 | fn debug_projection_ty( | ||
66 | proj: &chalk_ir::ProjectionTy<Interner>, | ||
67 | fmt: &mut fmt::Formatter<'_>, | ||
68 | ) -> Option<fmt::Result> { | ||
69 | tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt))) | ||
70 | } | ||
71 | |||
72 | fn debug_opaque_ty( | ||
73 | opaque_ty: &chalk_ir::OpaqueTy<Interner>, | ||
74 | fmt: &mut fmt::Formatter<'_>, | ||
75 | ) -> Option<fmt::Result> { | ||
76 | tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt))) | ||
77 | } | ||
78 | |||
79 | fn debug_opaque_ty_id( | ||
80 | opaque_ty_id: chalk_ir::OpaqueTyId<Self>, | ||
81 | fmt: &mut fmt::Formatter<'_>, | ||
82 | ) -> Option<fmt::Result> { | ||
83 | tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt))) | ||
84 | } | ||
85 | |||
63 | fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { | 86 | fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> { |
64 | tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt))) | 87 | tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt))) |
65 | } | 88 | } |
@@ -202,15 +225,15 @@ impl chalk_ir::interner::Interner for Interner { | |||
202 | fn intern_program_clauses( | 225 | fn intern_program_clauses( |
203 | &self, | 226 | &self, |
204 | data: impl IntoIterator<Item = chalk_ir::ProgramClause<Self>>, | 227 | data: impl IntoIterator<Item = chalk_ir::ProgramClause<Self>>, |
205 | ) -> Vec<chalk_ir::ProgramClause<Self>> { | 228 | ) -> Arc<[chalk_ir::ProgramClause<Self>]> { |
206 | data.into_iter().collect() | 229 | data.into_iter().collect() |
207 | } | 230 | } |
208 | 231 | ||
209 | fn program_clauses_data<'a>( | 232 | fn program_clauses_data<'a>( |
210 | &self, | 233 | &self, |
211 | clauses: &'a Vec<chalk_ir::ProgramClause<Self>>, | 234 | clauses: &'a Arc<[chalk_ir::ProgramClause<Self>]>, |
212 | ) -> &'a [chalk_ir::ProgramClause<Self>] { | 235 | ) -> &'a [chalk_ir::ProgramClause<Self>] { |
213 | clauses | 236 | &clauses |
214 | } | 237 | } |
215 | 238 | ||
216 | fn intern_quantified_where_clauses( | 239 | fn intern_quantified_where_clauses( |
@@ -226,6 +249,34 @@ impl chalk_ir::interner::Interner for Interner { | |||
226 | ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] { | 249 | ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] { |
227 | clauses | 250 | clauses |
228 | } | 251 | } |
252 | |||
253 | fn intern_parameter_kinds( | ||
254 | &self, | ||
255 | data: impl IntoIterator<Item = chalk_ir::ParameterKind<()>>, | ||
256 | ) -> Self::InternedParameterKinds { | ||
257 | data.into_iter().collect() | ||
258 | } | ||
259 | |||
260 | fn parameter_kinds_data<'a>( | ||
261 | &self, | ||
262 | parameter_kinds: &'a Self::InternedParameterKinds, | ||
263 | ) -> &'a [chalk_ir::ParameterKind<()>] { | ||
264 | ¶meter_kinds | ||
265 | } | ||
266 | |||
267 | fn intern_canonical_var_kinds( | ||
268 | &self, | ||
269 | data: impl IntoIterator<Item = chalk_ir::ParameterKind<UniverseIndex>>, | ||
270 | ) -> Self::InternedCanonicalVarKinds { | ||
271 | data.into_iter().collect() | ||
272 | } | ||
273 | |||
274 | fn canonical_var_kinds_data<'a>( | ||
275 | &self, | ||
276 | canonical_var_kinds: &'a Self::InternedCanonicalVarKinds, | ||
277 | ) -> &'a [chalk_ir::ParameterKind<UniverseIndex>] { | ||
278 | &canonical_var_kinds | ||
279 | } | ||
229 | } | 280 | } |
230 | 281 | ||
231 | impl chalk_ir::interner::HasInterner for Interner { | 282 | impl chalk_ir::interner::HasInterner for Interner { |
@@ -268,9 +319,12 @@ impl ToChalk for Ty { | |||
268 | Ty::Projection(proj_ty) => { | 319 | Ty::Projection(proj_ty) => { |
269 | let associated_ty_id = proj_ty.associated_ty.to_chalk(db); | 320 | let associated_ty_id = proj_ty.associated_ty.to_chalk(db); |
270 | let substitution = proj_ty.parameters.to_chalk(db); | 321 | let substitution = proj_ty.parameters.to_chalk(db); |
271 | chalk_ir::AliasTy { associated_ty_id, substitution } | 322 | chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { |
272 | .cast(&Interner) | 323 | associated_ty_id, |
273 | .intern(&Interner) | 324 | substitution, |
325 | }) | ||
326 | .cast(&Interner) | ||
327 | .intern(&Interner) | ||
274 | } | 328 | } |
275 | Ty::Placeholder(id) => { | 329 | Ty::Placeholder(id) => { |
276 | let interned_id = db.intern_type_param_id(id); | 330 | let interned_id = db.intern_type_param_id(id); |
@@ -314,16 +368,17 @@ impl ToChalk for Ty { | |||
314 | ); | 368 | ); |
315 | Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) | 369 | Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) |
316 | } | 370 | } |
317 | chalk_ir::TyData::Alias(proj) => { | 371 | chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => { |
318 | let associated_ty = from_chalk(db, proj.associated_ty_id); | 372 | let associated_ty = from_chalk(db, proj.associated_ty_id); |
319 | let parameters = from_chalk(db, proj.substitution); | 373 | let parameters = from_chalk(db, proj.substitution); |
320 | Ty::Projection(ProjectionTy { associated_ty, parameters }) | 374 | Ty::Projection(ProjectionTy { associated_ty, parameters }) |
321 | } | 375 | } |
376 | chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(), | ||
322 | chalk_ir::TyData::Function(_) => unimplemented!(), | 377 | chalk_ir::TyData::Function(_) => unimplemented!(), |
323 | chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), | 378 | chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx), |
324 | chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, | 379 | chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown, |
325 | chalk_ir::TyData::Dyn(where_clauses) => { | 380 | chalk_ir::TyData::Dyn(where_clauses) => { |
326 | assert_eq!(where_clauses.bounds.binders.len(), 1); | 381 | assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); |
327 | let predicates = where_clauses | 382 | let predicates = where_clauses |
328 | .bounds | 383 | .bounds |
329 | .skip_binders() | 384 | .skip_binders() |
@@ -404,6 +459,7 @@ impl ToChalk for TypeCtor { | |||
404 | match type_name { | 459 | match type_name { |
405 | TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), | 460 | TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()), |
406 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), | 461 | TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)), |
462 | TypeName::OpaqueType(_) => unreachable!(), | ||
407 | TypeName::Error => { | 463 | TypeName::Error => { |
408 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor | 464 | // this should not be reached, since we don't represent TypeName::Error with TypeCtor |
409 | unreachable!() | 465 | unreachable!() |
@@ -460,7 +516,8 @@ impl ToChalk for GenericPredicate { | |||
460 | } | 516 | } |
461 | GenericPredicate::Projection(projection_pred) => { | 517 | GenericPredicate::Projection(projection_pred) => { |
462 | let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner); | 518 | let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner); |
463 | let alias = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner); | 519 | let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner); |
520 | let alias = chalk_ir::AliasTy::Projection(projection); | ||
464 | make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0) | 521 | make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0) |
465 | } | 522 | } |
466 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), | 523 | GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"), |
@@ -481,7 +538,13 @@ impl ToChalk for GenericPredicate { | |||
481 | GenericPredicate::Implemented(from_chalk(db, tr)) | 538 | GenericPredicate::Implemented(from_chalk(db, tr)) |
482 | } | 539 | } |
483 | chalk_ir::WhereClause::AliasEq(projection_eq) => { | 540 | chalk_ir::WhereClause::AliasEq(projection_eq) => { |
484 | let projection_ty = from_chalk(db, projection_eq.alias); | 541 | let projection_ty = from_chalk( |
542 | db, | ||
543 | match projection_eq.alias { | ||
544 | chalk_ir::AliasTy::Projection(p) => p, | ||
545 | _ => unimplemented!(), | ||
546 | }, | ||
547 | ); | ||
485 | let ty = from_chalk(db, projection_eq.ty); | 548 | let ty = from_chalk(db, projection_eq.ty); |
486 | GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty }) | 549 | GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty }) |
487 | } | 550 | } |
@@ -490,10 +553,10 @@ impl ToChalk for GenericPredicate { | |||
490 | } | 553 | } |
491 | 554 | ||
492 | impl ToChalk for ProjectionTy { | 555 | impl ToChalk for ProjectionTy { |
493 | type Chalk = chalk_ir::AliasTy<Interner>; | 556 | type Chalk = chalk_ir::ProjectionTy<Interner>; |
494 | 557 | ||
495 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasTy<Interner> { | 558 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { |
496 | chalk_ir::AliasTy { | 559 | chalk_ir::ProjectionTy { |
497 | associated_ty_id: self.associated_ty.to_chalk(db), | 560 | associated_ty_id: self.associated_ty.to_chalk(db), |
498 | substitution: self.parameters.to_chalk(db), | 561 | substitution: self.parameters.to_chalk(db), |
499 | } | 562 | } |
@@ -501,7 +564,7 @@ impl ToChalk for ProjectionTy { | |||
501 | 564 | ||
502 | fn from_chalk( | 565 | fn from_chalk( |
503 | db: &dyn HirDatabase, | 566 | db: &dyn HirDatabase, |
504 | projection_ty: chalk_ir::AliasTy<Interner>, | 567 | projection_ty: chalk_ir::ProjectionTy<Interner>, |
505 | ) -> ProjectionTy { | 568 | ) -> ProjectionTy { |
506 | ProjectionTy { | 569 | ProjectionTy { |
507 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), | 570 | associated_ty: from_chalk(db, projection_ty.associated_ty_id), |
@@ -514,7 +577,10 @@ impl ToChalk for super::ProjectionPredicate { | |||
514 | type Chalk = chalk_ir::AliasEq<Interner>; | 577 | type Chalk = chalk_ir::AliasEq<Interner>; |
515 | 578 | ||
516 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { | 579 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> { |
517 | chalk_ir::AliasEq { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) } | 580 | chalk_ir::AliasEq { |
581 | alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)), | ||
582 | ty: self.ty.to_chalk(db), | ||
583 | } | ||
518 | } | 584 | } |
519 | 585 | ||
520 | fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self { | 586 | fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self { |
@@ -540,17 +606,24 @@ impl ToChalk for Obligation { | |||
540 | impl<T> ToChalk for Canonical<T> | 606 | impl<T> ToChalk for Canonical<T> |
541 | where | 607 | where |
542 | T: ToChalk, | 608 | T: ToChalk, |
609 | T::Chalk: HasInterner<Interner = Interner>, | ||
543 | { | 610 | { |
544 | type Chalk = chalk_ir::Canonical<T::Chalk>; | 611 | type Chalk = chalk_ir::Canonical<T::Chalk>; |
545 | 612 | ||
546 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { | 613 | fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { |
547 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); | 614 | let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT); |
548 | let value = self.value.to_chalk(db); | 615 | let value = self.value.to_chalk(db); |
549 | chalk_ir::Canonical { value, binders: vec![parameter; self.num_vars] } | 616 | chalk_ir::Canonical { |
617 | value, | ||
618 | binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]), | ||
619 | } | ||
550 | } | 620 | } |
551 | 621 | ||
552 | fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { | 622 | fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> { |
553 | Canonical { num_vars: canonical.binders.len(), value: from_chalk(db, canonical.value) } | 623 | Canonical { |
624 | num_vars: canonical.binders.len(&Interner), | ||
625 | value: from_chalk(db, canonical.value), | ||
626 | } | ||
554 | } | 627 | } |
555 | } | 628 | } |
556 | 629 | ||
@@ -649,9 +722,15 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData { | |||
649 | } | 722 | } |
650 | } | 723 | } |
651 | 724 | ||
652 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> { | 725 | fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> |
726 | where | ||
727 | T: HasInterner<Interner = Interner>, | ||
728 | { | ||
653 | chalk_ir::Binders::new( | 729 | chalk_ir::Binders::new( |
654 | std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars).collect(), | 730 | chalk_ir::ParameterKinds::from( |
731 | &Interner, | ||
732 | std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars), | ||
733 | ), | ||
655 | value, | 734 | value, |
656 | ) | 735 | ) |
657 | } | 736 | } |
@@ -799,6 +878,28 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> { | |||
799 | // FIXME tell Chalk about well-known traits (here and in trait_datum) | 878 | // FIXME tell Chalk about well-known traits (here and in trait_datum) |
800 | None | 879 | None |
801 | } | 880 | } |
881 | |||
882 | fn program_clauses_for_env( | ||
883 | &self, | ||
884 | environment: &chalk_ir::Environment<Interner>, | ||
885 | ) -> chalk_ir::ProgramClauses<Interner> { | ||
886 | self.db.program_clauses_for_chalk_env(self.krate, environment.clone()) | ||
887 | } | ||
888 | |||
889 | fn opaque_ty_data( | ||
890 | &self, | ||
891 | _id: chalk_ir::OpaqueTyId<Interner>, | ||
892 | ) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> { | ||
893 | unimplemented!() | ||
894 | } | ||
895 | } | ||
896 | |||
897 | pub(crate) fn program_clauses_for_chalk_env_query( | ||
898 | db: &dyn HirDatabase, | ||
899 | krate: CrateId, | ||
900 | environment: chalk_ir::Environment<Interner>, | ||
901 | ) -> chalk_ir::ProgramClauses<Interner> { | ||
902 | chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment) | ||
802 | } | 903 | } |
803 | 904 | ||
804 | pub(crate) fn associated_ty_data_query( | 905 | pub(crate) fn associated_ty_data_query( |