diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 86 |
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 | ||
28 | use base_db::salsa; | 28 | use base_db::salsa; |
29 | use hir_def::{ | 29 | use 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 | }; |
36 | use itertools::Itertools; | 34 | use itertools::Itertools; |
37 | 35 | ||
@@ -49,7 +47,7 @@ pub use lower::{ | |||
49 | }; | 47 | }; |
50 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
51 | 49 | ||
52 | pub use chalk_ir::{BoundVar, DebruijnIndex, Scalar, TyVariableKind}; | 50 | pub use chalk_ir::{BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; |
53 | 51 | ||
54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 52 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
55 | pub enum Lifetime { | 53 | pub 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)] | ||
113 | pub 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 { | |||
987 | impl TypeWalk for Ty { | 991 | impl 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 | _ => { |