aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs88
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};
48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{AliasEq, InEnvironment, Obligation, TraitEnvironment};
49 49
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; 50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
51 51
@@ -58,6 +58,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
60 60
61pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
62
61#[derive(Clone, PartialEq, Eq, Debug, Hash)] 63#[derive(Clone, PartialEq, Eq, Debug, Hash)]
62pub enum Lifetime { 64pub 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
75impl 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
82impl ProjectionTy { 98impl 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
150impl 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)]
498pub struct TraitRef { 535pub 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
504impl TraitRef { 540impl 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
510impl TypeWalk for TraitRef { 550impl 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
1202pub fn to_chalk_trait_id(id: TraitId) -> ChalkTraitId {
1203 chalk_ir::TraitId(salsa::InternKey::as_intern_id(&id))
1204}
1205
1206pub fn from_chalk_trait_id(id: ChalkTraitId) -> TraitId {
1207 salsa::InternKey::from_intern_id(id.0)
1208}