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.rs86
1 files changed, 45 insertions, 41 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 1131eaf92..c2a20c480 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -27,11 +27,9 @@ use std::{iter, mem, ops::Deref, sync::Arc};
27 27
28use base_db::salsa; 28use base_db::salsa;
29use hir_def::{ 29use hir_def::{
30 builtin_type::BuiltinType, 30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AdtId, AssocContainerId,
31 expr::ExprId, 31 DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId,
32 type_ref::{Mutability, Rawness}, 32 TypeAliasId, TypeParamId,
33 AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId,
34 Lookup, TraitId, TypeAliasId, TypeParamId,
35}; 33};
36use itertools::Itertools; 34use itertools::Itertools;
37 35
@@ -49,7 +47,7 @@ pub use lower::{
49}; 47};
50pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
51 49
52pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar, TyVariableKind}; 50pub use chalk_ir::{BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
53 51
54#[derive(Clone, PartialEq, Eq, Debug, Hash)] 52#[derive(Clone, PartialEq, Eq, Debug, Hash)]
55pub enum Lifetime { 53pub enum Lifetime {
@@ -111,6 +109,19 @@ pub struct FnPointer {
111 pub substs: Substs, 109 pub substs: Substs,
112} 110}
113 111
112#[derive(Clone, PartialEq, Eq, Debug, Hash)]
113pub enum AliasTy {
114 /// A "projection" type corresponds to an (unnormalized)
115 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
116 /// trait and all its parameters are fully known.
117 Projection(ProjectionTy),
118 /// An opaque type (`impl Trait`).
119 ///
120 /// This is currently only used for return type impl trait; each instance of
121 /// `impl Trait` in a return type gets its own ID.
122 Opaque(OpaqueTy),
123}
124
114/// A type. 125/// A type.
115/// 126///
116/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 127/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -141,7 +152,7 @@ pub enum Ty {
141 Slice(Substs), 152 Slice(Substs),
142 153
143 /// A raw pointer. Written as `*mut T` or `*const T` 154 /// A raw pointer. Written as `*mut T` or `*const T`
144 RawPtr(Mutability, Substs), 155 Raw(Mutability, Substs),
145 156
146 /// A reference; a pointer with an associated lifetime. Written as 157 /// A reference; a pointer with an associated lifetime. Written as
147 /// `&'a mut T` or `&'a T`. 158 /// `&'a mut T` or `&'a T`.
@@ -193,16 +204,11 @@ pub enum Ty {
193 /// ``` 204 /// ```
194 Function(FnPointer), 205 Function(FnPointer),
195 206
196 /// A "projection" type corresponds to an (unnormalized) 207 /// An "alias" type represents some form of type alias, such as:
197 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 208 /// - An associated type projection like `<T as Iterator>::Item`
198 /// trait and all its parameters are fully known. 209 /// - `impl Trait` types
199 Projection(ProjectionTy), 210 /// - Named type aliases like `type Foo<X> = Vec<X>`
200 211 Alias(AliasTy),
201 /// An opaque type (`impl Trait`).
202 ///
203 /// This is currently only used for return type impl trait; each instance of
204 /// `impl Trait` in a return type gets its own ID.
205 Opaque(OpaqueTy),
206 212
207 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 213 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
208 /// {}` when we're type-checking the body of that function. In this 214 /// {}` when we're type-checking the body of that function. In this
@@ -215,7 +221,7 @@ pub enum Ty {
215 /// parameters get turned into variables; during trait resolution, inference 221 /// parameters get turned into variables; during trait resolution, inference
216 /// variables get turned into bound variables and back; and in `Dyn` the 222 /// variables get turned into bound variables and back; and in `Dyn` the
217 /// `Self` type is represented with a bound variable as well. 223 /// `Self` type is represented with a bound variable as well.
218 Bound(BoundVar), 224 BoundVar(BoundVar),
219 225
220 /// A type variable used during type checking. 226 /// A type variable used during type checking.
221 InferenceVar(InferenceVar, TyVariableKind), 227 InferenceVar(InferenceVar, TyVariableKind),
@@ -299,7 +305,7 @@ impl Substs {
299 generic_params 305 generic_params
300 .iter() 306 .iter()
301 .enumerate() 307 .enumerate()
302 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 308 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
303 .collect(), 309 .collect(),
304 ) 310 )
305 } 311 }
@@ -347,7 +353,7 @@ impl SubstsBuilder {
347 } 353 }
348 354
349 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 355 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
350 self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx)))) 356 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx))))
351 } 357 }
352 358
353 pub fn fill_with_unknown(self) -> Self { 359 pub fn fill_with_unknown(self) -> Self {
@@ -627,7 +633,7 @@ impl Ty {
627 Ty::Ref(mutability, parameters) => { 633 Ty::Ref(mutability, parameters) => {
628 Some((parameters.as_single(), Rawness::Ref, *mutability)) 634 Some((parameters.as_single(), Rawness::Ref, *mutability))
629 } 635 }
630 Ty::RawPtr(mutability, parameters) => { 636 Ty::Raw(mutability, parameters) => {
631 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 637 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
632 } 638 }
633 _ => None, 639 _ => None,
@@ -688,9 +694,7 @@ impl Ty {
688 expr == expr2 && def == def2 694 expr == expr2 && def == def2
689 } 695 }
690 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) 696 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
691 | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => { 697 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
692 mutability == mutability2
693 }
694 ( 698 (
695 Ty::Function(FnPointer { num_args, sig, .. }), 699 Ty::Function(FnPointer { num_args, sig, .. }),
696 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), 700 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
@@ -721,7 +725,7 @@ impl Ty {
721 fn builtin_deref(&self) -> Option<Ty> { 725 fn builtin_deref(&self) -> Option<Ty> {
722 match self { 726 match self {
723 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), 727 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
724 Ty::RawPtr(.., parameters) => Some(Ty::clone(parameters.as_single())), 728 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
725 _ => None, 729 _ => None,
726 } 730 }
727 } 731 }
@@ -757,7 +761,7 @@ impl Ty {
757 Ty::Adt(_, substs) 761 Ty::Adt(_, substs)
758 | Ty::Slice(substs) 762 | Ty::Slice(substs)
759 | Ty::Array(substs) 763 | Ty::Array(substs)
760 | Ty::RawPtr(_, substs) 764 | Ty::Raw(_, substs)
761 | Ty::Ref(_, substs) 765 | Ty::Ref(_, substs)
762 | Ty::FnDef(_, substs) 766 | Ty::FnDef(_, substs)
763 | Ty::Function(FnPointer { substs, .. }) 767 | Ty::Function(FnPointer { substs, .. })
@@ -780,7 +784,7 @@ impl Ty {
780 Ty::Adt(_, substs) 784 Ty::Adt(_, substs)
781 | Ty::Slice(substs) 785 | Ty::Slice(substs)
782 | Ty::Array(substs) 786 | Ty::Array(substs)
783 | Ty::RawPtr(_, substs) 787 | Ty::Raw(_, substs)
784 | Ty::Ref(_, substs) 788 | Ty::Ref(_, substs)
785 | Ty::FnDef(_, substs) 789 | Ty::FnDef(_, substs)
786 | Ty::Function(FnPointer { substs, .. }) 790 | Ty::Function(FnPointer { substs, .. })
@@ -797,7 +801,7 @@ impl Ty {
797 Ty::Adt(_, substs) 801 Ty::Adt(_, substs)
798 | Ty::Slice(substs) 802 | Ty::Slice(substs)
799 | Ty::Array(substs) 803 | Ty::Array(substs)
800 | Ty::RawPtr(_, substs) 804 | Ty::Raw(_, substs)
801 | Ty::Ref(_, substs) 805 | Ty::Ref(_, substs)
802 | Ty::FnDef(_, substs) 806 | Ty::FnDef(_, substs)
803 | Ty::Function(FnPointer { substs, .. }) 807 | Ty::Function(FnPointer { substs, .. })
@@ -834,7 +838,7 @@ impl Ty {
834 OpaqueTyId::ReturnTypeImplTrait(..) => None, 838 OpaqueTyId::ReturnTypeImplTrait(..) => None,
835 } 839 }
836 } 840 }
837 Ty::Opaque(opaque_ty) => { 841 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
838 let predicates = match opaque_ty.opaque_ty_id { 842 let predicates = match opaque_ty.opaque_ty_id {
839 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 843 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
840 db.return_type_impl_traits(func).map(|it| { 844 db.return_type_impl_traits(func).map(|it| {
@@ -878,7 +882,7 @@ impl Ty {
878 _ => None, 882 _ => None,
879 } 883 }
880 } 884 }
881 Ty::Projection(projection_ty) => { 885 Ty::Alias(AliasTy::Projection(projection_ty)) => {
882 match projection_ty.associated_ty.lookup(db.upcast()).container { 886 match projection_ty.associated_ty.lookup(db.upcast()).container {
883 AssocContainerId::TraitId(trait_id) => Some(trait_id), 887 AssocContainerId::TraitId(trait_id) => Some(trait_id),
884 _ => None, 888 _ => None,
@@ -956,7 +960,7 @@ pub trait TypeWalk {
956 { 960 {
957 self.walk_mut_binders( 961 self.walk_mut_binders(
958 &mut |ty, binders| { 962 &mut |ty, binders| {
959 if let &mut Ty::Bound(bound) = ty { 963 if let &mut Ty::BoundVar(bound) = ty {
960 if bound.debruijn >= binders { 964 if bound.debruijn >= binders {
961 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 965 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
962 } 966 }
@@ -974,8 +978,8 @@ pub trait TypeWalk {
974 { 978 {
975 self.fold_binders( 979 self.fold_binders(
976 &mut |ty, binders| match ty { 980 &mut |ty, binders| match ty {
977 Ty::Bound(bound) if bound.debruijn >= binders => { 981 Ty::BoundVar(bound) if bound.debruijn >= binders => {
978 Ty::Bound(bound.shifted_in_from(n)) 982 Ty::BoundVar(bound.shifted_in_from(n))
979 } 983 }
980 ty => ty, 984 ty => ty,
981 }, 985 },
@@ -987,21 +991,21 @@ pub trait TypeWalk {
987impl TypeWalk for Ty { 991impl TypeWalk for Ty {
988 fn walk(&self, f: &mut impl FnMut(&Ty)) { 992 fn walk(&self, f: &mut impl FnMut(&Ty)) {
989 match self { 993 match self {
990 Ty::Projection(p_ty) => { 994 Ty::Alias(AliasTy::Projection(p_ty)) => {
991 for t in p_ty.parameters.iter() { 995 for t in p_ty.parameters.iter() {
992 t.walk(f); 996 t.walk(f);
993 } 997 }
994 } 998 }
999 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1000 for t in o_ty.parameters.iter() {
1001 t.walk(f);
1002 }
1003 }
995 Ty::Dyn(predicates) => { 1004 Ty::Dyn(predicates) => {
996 for p in predicates.iter() { 1005 for p in predicates.iter() {
997 p.walk(f); 1006 p.walk(f);
998 } 1007 }
999 } 1008 }
1000 Ty::Opaque(o_ty) => {
1001 for t in o_ty.parameters.iter() {
1002 t.walk(f);
1003 }
1004 }
1005 _ => { 1009 _ => {
1006 if let Some(substs) = self.substs() { 1010 if let Some(substs) = self.substs() {
1007 for t in substs.iter() { 1011 for t in substs.iter() {
@@ -1019,7 +1023,7 @@ impl TypeWalk for Ty {
1019 binders: DebruijnIndex, 1023 binders: DebruijnIndex,
1020 ) { 1024 ) {
1021 match self { 1025 match self {
1022 Ty::Projection(p_ty) => { 1026 Ty::Alias(AliasTy::Projection(p_ty)) => {
1023 p_ty.parameters.walk_mut_binders(f, binders); 1027 p_ty.parameters.walk_mut_binders(f, binders);
1024 } 1028 }
1025 Ty::Dyn(predicates) => { 1029 Ty::Dyn(predicates) => {
@@ -1027,7 +1031,7 @@ impl TypeWalk for Ty {
1027 p.walk_mut_binders(f, binders.shifted_in()); 1031 p.walk_mut_binders(f, binders.shifted_in());
1028 } 1032 }
1029 } 1033 }
1030 Ty::Opaque(o_ty) => { 1034 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1031 o_ty.parameters.walk_mut_binders(f, binders); 1035 o_ty.parameters.walk_mut_binders(f, binders);
1032 } 1036 }
1033 _ => { 1037 _ => {