diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 88 |
1 files changed, 68 insertions, 20 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 52b498ff7..2afcb5413 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -45,7 +45,7 @@ pub use lower::{ | |||
45 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, | 45 | associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, |
46 | TyDefId, TyLoweringContext, ValueTyDefId, | 46 | TyDefId, TyLoweringContext, ValueTyDefId, |
47 | }; | 47 | }; |
48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 48 | pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment}; |
49 | 49 | ||
50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; | 50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; |
51 | 51 | ||
@@ -58,6 +58,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>; | |||
58 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 58 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
59 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | 59 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; |
60 | 60 | ||
61 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | ||
62 | |||
61 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 63 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
62 | pub enum Lifetime { | 64 | pub enum Lifetime { |
63 | Parameter(LifetimeParamId), | 65 | Parameter(LifetimeParamId), |
@@ -70,6 +72,20 @@ pub struct OpaqueTy { | |||
70 | pub substitution: Substitution, | 72 | pub substitution: Substitution, |
71 | } | 73 | } |
72 | 74 | ||
75 | impl TypeWalk for OpaqueTy { | ||
76 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
77 | self.substitution.walk(f); | ||
78 | } | ||
79 | |||
80 | fn walk_mut_binders( | ||
81 | &mut self, | ||
82 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
83 | binders: DebruijnIndex, | ||
84 | ) { | ||
85 | self.substitution.walk_mut_binders(f, binders); | ||
86 | } | ||
87 | } | ||
88 | |||
73 | /// A "projection" type corresponds to an (unnormalized) | 89 | /// A "projection" type corresponds to an (unnormalized) |
74 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the | 90 | /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the |
75 | /// trait and all its parameters are fully known. | 91 | /// trait and all its parameters are fully known. |
@@ -81,7 +97,10 @@ pub struct ProjectionTy { | |||
81 | 97 | ||
82 | impl ProjectionTy { | 98 | impl ProjectionTy { |
83 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { | 99 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { |
84 | TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() } | 100 | TraitRef { |
101 | trait_id: to_chalk_trait_id(self.trait_(db)), | ||
102 | substitution: self.substitution.clone(), | ||
103 | } | ||
85 | } | 104 | } |
86 | 105 | ||
87 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { | 106 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { |
@@ -128,6 +147,25 @@ pub enum AliasTy { | |||
128 | Opaque(OpaqueTy), | 147 | Opaque(OpaqueTy), |
129 | } | 148 | } |
130 | 149 | ||
150 | impl TypeWalk for AliasTy { | ||
151 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | ||
152 | match self { | ||
153 | AliasTy::Projection(it) => it.walk(f), | ||
154 | AliasTy::Opaque(it) => it.walk(f), | ||
155 | } | ||
156 | } | ||
157 | |||
158 | fn walk_mut_binders( | ||
159 | &mut self, | ||
160 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | ||
161 | binders: DebruijnIndex, | ||
162 | ) { | ||
163 | match self { | ||
164 | AliasTy::Projection(it) => it.walk_mut_binders(f, binders), | ||
165 | AliasTy::Opaque(it) => it.walk_mut_binders(f, binders), | ||
166 | } | ||
167 | } | ||
168 | } | ||
131 | /// A type. | 169 | /// A type. |
132 | /// | 170 | /// |
133 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents | 171 | /// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents |
@@ -493,23 +531,25 @@ impl<T: TypeWalk> TypeWalk for Binders<T> { | |||
493 | } | 531 | } |
494 | 532 | ||
495 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. | 533 | /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. |
496 | /// Name to be bikeshedded: TraitBound? TraitImplements? | ||
497 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 534 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
498 | pub struct TraitRef { | 535 | pub struct TraitRef { |
499 | /// FIXME name? | 536 | pub trait_id: ChalkTraitId, |
500 | pub trait_: TraitId, | 537 | pub substitution: Substitution, |
501 | pub substs: Substitution, | ||
502 | } | 538 | } |
503 | 539 | ||
504 | impl TraitRef { | 540 | impl TraitRef { |
505 | pub fn self_ty(&self) -> &Ty { | 541 | pub fn self_type_parameter(&self) -> &Ty { |
506 | &self.substs[0] | 542 | &self.substitution[0] |
543 | } | ||
544 | |||
545 | pub fn hir_trait_id(&self) -> TraitId { | ||
546 | from_chalk_trait_id(self.trait_id) | ||
507 | } | 547 | } |
508 | } | 548 | } |
509 | 549 | ||
510 | impl TypeWalk for TraitRef { | 550 | impl TypeWalk for TraitRef { |
511 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 551 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
512 | self.substs.walk(f); | 552 | self.substitution.walk(f); |
513 | } | 553 | } |
514 | 554 | ||
515 | fn walk_mut_binders( | 555 | fn walk_mut_binders( |
@@ -517,7 +557,7 @@ impl TypeWalk for TraitRef { | |||
517 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 557 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
518 | binders: DebruijnIndex, | 558 | binders: DebruijnIndex, |
519 | ) { | 559 | ) { |
520 | self.substs.walk_mut_binders(f, binders); | 560 | self.substitution.walk_mut_binders(f, binders); |
521 | } | 561 | } |
522 | } | 562 | } |
523 | 563 | ||
@@ -528,7 +568,7 @@ pub enum GenericPredicate { | |||
528 | /// The given trait needs to be implemented for its type parameters. | 568 | /// The given trait needs to be implemented for its type parameters. |
529 | Implemented(TraitRef), | 569 | Implemented(TraitRef), |
530 | /// An associated type bindings like in `Iterator<Item = T>`. | 570 | /// An associated type bindings like in `Iterator<Item = T>`. |
531 | Projection(ProjectionPredicate), | 571 | AliasEq(AliasEq), |
532 | /// We couldn't resolve the trait reference. (If some type parameters can't | 572 | /// We couldn't resolve the trait reference. (If some type parameters can't |
533 | /// be resolved, they will just be Unknown). | 573 | /// be resolved, they will just be Unknown). |
534 | Error, | 574 | Error, |
@@ -546,8 +586,10 @@ impl GenericPredicate { | |||
546 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { | 586 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> Option<TraitRef> { |
547 | match self { | 587 | match self { |
548 | GenericPredicate::Implemented(tr) => Some(tr.clone()), | 588 | GenericPredicate::Implemented(tr) => Some(tr.clone()), |
549 | GenericPredicate::Projection(proj) => Some(proj.projection_ty.trait_ref(db)), | 589 | GenericPredicate::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => { |
550 | GenericPredicate::Error => None, | 590 | Some(proj.trait_ref(db)) |
591 | } | ||
592 | GenericPredicate::AliasEq(_) | GenericPredicate::Error => None, | ||
551 | } | 593 | } |
552 | } | 594 | } |
553 | } | 595 | } |
@@ -556,7 +598,7 @@ impl TypeWalk for GenericPredicate { | |||
556 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 598 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
557 | match self { | 599 | match self { |
558 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), | 600 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk(f), |
559 | GenericPredicate::Projection(projection_pred) => projection_pred.walk(f), | 601 | GenericPredicate::AliasEq(alias_eq) => alias_eq.walk(f), |
560 | GenericPredicate::Error => {} | 602 | GenericPredicate::Error => {} |
561 | } | 603 | } |
562 | } | 604 | } |
@@ -568,9 +610,7 @@ impl TypeWalk for GenericPredicate { | |||
568 | ) { | 610 | ) { |
569 | match self { | 611 | match self { |
570 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), | 612 | GenericPredicate::Implemented(trait_ref) => trait_ref.walk_mut_binders(f, binders), |
571 | GenericPredicate::Projection(projection_pred) => { | 613 | GenericPredicate::AliasEq(alias_eq) => alias_eq.walk_mut_binders(f, binders), |
572 | projection_pred.walk_mut_binders(f, binders) | ||
573 | } | ||
574 | GenericPredicate::Error => {} | 614 | GenericPredicate::Error => {} |
575 | } | 615 | } |
576 | } | 616 | } |
@@ -784,7 +824,7 @@ impl Ty { | |||
784 | 824 | ||
785 | /// If this is a `dyn Trait`, returns that trait. | 825 | /// If this is a `dyn Trait`, returns that trait. |
786 | pub fn dyn_trait(&self) -> Option<TraitId> { | 826 | pub fn dyn_trait(&self) -> Option<TraitId> { |
787 | self.dyn_trait_ref().map(|it| it.trait_) | 827 | self.dyn_trait_ref().map(|it| it.trait_id).map(from_chalk_trait_id) |
788 | } | 828 | } |
789 | 829 | ||
790 | fn builtin_deref(&self) -> Option<Ty> { | 830 | fn builtin_deref(&self) -> Option<Ty> { |
@@ -868,8 +908,8 @@ impl Ty { | |||
868 | // Parameters will be walked outside, and projection predicate is not used. | 908 | // Parameters will be walked outside, and projection predicate is not used. |
869 | // So just provide the Future trait. | 909 | // So just provide the Future trait. |
870 | let impl_bound = GenericPredicate::Implemented(TraitRef { | 910 | let impl_bound = GenericPredicate::Implemented(TraitRef { |
871 | trait_: future_trait, | 911 | trait_id: to_chalk_trait_id(future_trait), |
872 | substs: Substitution::empty(), | 912 | substitution: Substitution::empty(), |
873 | }); | 913 | }); |
874 | Some(vec![impl_bound]) | 914 | Some(vec![impl_bound]) |
875 | } else { | 915 | } else { |
@@ -1158,3 +1198,11 @@ pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderI | |||
1158 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | 1198 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), |
1159 | } | 1199 | } |
1160 | } | 1200 | } |
1201 | |||
1202 | pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId { | ||
1203 | chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id)) | ||
1204 | } | ||
1205 | |||
1206 | pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId { | ||
1207 | salsa::InternKey::from_intern_id(id.0) | ||
1208 | } | ||