diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 435 |
1 files changed, 249 insertions, 186 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index e77f24e4e..503910dde 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -27,9 +27,8 @@ 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, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId, | 30 | builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId, |
31 | FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, | 31 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, |
32 | TypeParamId, | ||
33 | }; | 32 | }; |
34 | use itertools::Itertools; | 33 | use itertools::Itertools; |
35 | 34 | ||
@@ -47,9 +46,16 @@ pub use lower::{ | |||
47 | }; | 46 | }; |
48 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; | 47 | pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; |
49 | 48 | ||
50 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; | 49 | pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind}; |
51 | 50 | ||
52 | pub(crate) use crate::traits::chalk::Interner; | 51 | pub use crate::traits::chalk::Interner; |
52 | |||
53 | pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>; | ||
54 | pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>; | ||
55 | pub type FnDefId = chalk_ir::FnDefId<Interner>; | ||
56 | pub type ClosureId = chalk_ir::ClosureId<Interner>; | ||
57 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | ||
58 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | ||
53 | 59 | ||
54 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
55 | pub enum Lifetime { | 61 | pub enum Lifetime { |
@@ -60,7 +66,7 @@ pub enum Lifetime { | |||
60 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 66 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
61 | pub struct OpaqueTy { | 67 | pub struct OpaqueTy { |
62 | pub opaque_ty_id: OpaqueTyId, | 68 | pub opaque_ty_id: OpaqueTyId, |
63 | pub parameters: Substs, | 69 | pub substitution: Substs, |
64 | } | 70 | } |
65 | 71 | ||
66 | /// A "projection" type corresponds to an (unnormalized) | 72 | /// A "projection" type corresponds to an (unnormalized) |
@@ -68,17 +74,17 @@ pub struct OpaqueTy { | |||
68 | /// trait and all its parameters are fully known. | 74 | /// trait and all its parameters are fully known. |
69 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 75 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
70 | pub struct ProjectionTy { | 76 | pub struct ProjectionTy { |
71 | pub associated_ty: TypeAliasId, | 77 | pub associated_ty_id: AssocTypeId, |
72 | pub parameters: Substs, | 78 | pub substitution: Substs, |
73 | } | 79 | } |
74 | 80 | ||
75 | impl ProjectionTy { | 81 | impl ProjectionTy { |
76 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { | 82 | pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { |
77 | TraitRef { trait_: self.trait_(db), substs: self.parameters.clone() } | 83 | TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() } |
78 | } | 84 | } |
79 | 85 | ||
80 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { | 86 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { |
81 | match self.associated_ty.lookup(db.upcast()).container { | 87 | match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container { |
82 | AssocContainerId::TraitId(it) => it, | 88 | AssocContainerId::TraitId(it) => it, |
83 | _ => panic!("projection ty without parent trait"), | 89 | _ => panic!("projection ty without parent trait"), |
84 | } | 90 | } |
@@ -87,7 +93,7 @@ impl ProjectionTy { | |||
87 | 93 | ||
88 | impl TypeWalk for ProjectionTy { | 94 | impl TypeWalk for ProjectionTy { |
89 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 95 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
90 | self.parameters.walk(f); | 96 | self.substitution.walk(f); |
91 | } | 97 | } |
92 | 98 | ||
93 | fn walk_mut_binders( | 99 | fn walk_mut_binders( |
@@ -95,14 +101,11 @@ impl TypeWalk for ProjectionTy { | |||
95 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 101 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
96 | binders: DebruijnIndex, | 102 | binders: DebruijnIndex, |
97 | ) { | 103 | ) { |
98 | self.parameters.walk_mut_binders(f, binders); | 104 | self.substitution.walk_mut_binders(f, binders); |
99 | } | 105 | } |
100 | } | 106 | } |
101 | 107 | ||
102 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 108 | pub type FnSig = chalk_ir::FnSig<Interner>; |
103 | pub struct FnSig { | ||
104 | pub variadic: bool, | ||
105 | } | ||
106 | 109 | ||
107 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 110 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
108 | pub struct FnPointer { | 111 | pub struct FnPointer { |
@@ -131,7 +134,7 @@ pub enum AliasTy { | |||
131 | /// | 134 | /// |
132 | /// This should be cheap to clone. | 135 | /// This should be cheap to clone. |
133 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 136 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
134 | pub enum Ty { | 137 | pub enum TyKind { |
135 | /// Structures, enumerations and unions. | 138 | /// Structures, enumerations and unions. |
136 | Adt(AdtId<Interner>, Substs), | 139 | Adt(AdtId<Interner>, Substs), |
137 | 140 | ||
@@ -139,7 +142,7 @@ pub enum Ty { | |||
139 | /// when we have tried to normalize a projection like `T::Item` but | 142 | /// when we have tried to normalize a projection like `T::Item` but |
140 | /// couldn't find a better representation. In that case, we generate | 143 | /// couldn't find a better representation. In that case, we generate |
141 | /// an **application type** like `(Iterator::Item)<T>`. | 144 | /// an **application type** like `(Iterator::Item)<T>`. |
142 | AssociatedType(TypeAliasId, Substs), | 145 | AssociatedType(AssocTypeId, Substs), |
143 | 146 | ||
144 | /// a scalar type like `bool` or `u32` | 147 | /// a scalar type like `bool` or `u32` |
145 | Scalar(Scalar), | 148 | Scalar(Scalar), |
@@ -148,17 +151,17 @@ pub enum Ty { | |||
148 | Tuple(usize, Substs), | 151 | Tuple(usize, Substs), |
149 | 152 | ||
150 | /// An array with the given length. Written as `[T; n]`. | 153 | /// An array with the given length. Written as `[T; n]`. |
151 | Array(Substs), | 154 | Array(Ty), |
152 | 155 | ||
153 | /// The pointee of an array slice. Written as `[T]`. | 156 | /// The pointee of an array slice. Written as `[T]`. |
154 | Slice(Substs), | 157 | Slice(Ty), |
155 | 158 | ||
156 | /// A raw pointer. Written as `*mut T` or `*const T` | 159 | /// A raw pointer. Written as `*mut T` or `*const T` |
157 | Raw(Mutability, Substs), | 160 | Raw(Mutability, Ty), |
158 | 161 | ||
159 | /// A reference; a pointer with an associated lifetime. Written as | 162 | /// A reference; a pointer with an associated lifetime. Written as |
160 | /// `&'a mut T` or `&'a T`. | 163 | /// `&'a mut T` or `&'a T`. |
161 | Ref(Mutability, Substs), | 164 | Ref(Mutability, Ty), |
162 | 165 | ||
163 | /// This represents a placeholder for an opaque type in situations where we | 166 | /// This represents a placeholder for an opaque type in situations where we |
164 | /// don't know the hidden type (i.e. currently almost always). This is | 167 | /// don't know the hidden type (i.e. currently almost always). This is |
@@ -179,7 +182,7 @@ pub enum Ty { | |||
179 | /// fn foo() -> i32 { 1 } | 182 | /// fn foo() -> i32 { 1 } |
180 | /// let bar = foo; // bar: fn() -> i32 {foo} | 183 | /// let bar = foo; // bar: fn() -> i32 {foo} |
181 | /// ``` | 184 | /// ``` |
182 | FnDef(CallableDefId, Substs), | 185 | FnDef(FnDefId, Substs), |
183 | 186 | ||
184 | /// The pointee of a string slice. Written as `str`. | 187 | /// The pointee of a string slice. Written as `str`. |
185 | Str, | 188 | Str, |
@@ -191,10 +194,10 @@ pub enum Ty { | |||
191 | /// | 194 | /// |
192 | /// The closure signature is stored in a `FnPtr` type in the first type | 195 | /// The closure signature is stored in a `FnPtr` type in the first type |
193 | /// parameter. | 196 | /// parameter. |
194 | Closure(DefWithBodyId, ExprId, Substs), | 197 | Closure(ClosureId, Substs), |
195 | 198 | ||
196 | /// Represents a foreign type declared in external blocks. | 199 | /// Represents a foreign type declared in external blocks. |
197 | ForeignType(TypeAliasId), | 200 | ForeignType(ForeignDefId), |
198 | 201 | ||
199 | /// A pointer to a function. Written as `fn() -> i32`. | 202 | /// A pointer to a function. Written as `fn() -> i32`. |
200 | /// | 203 | /// |
@@ -216,7 +219,7 @@ pub enum Ty { | |||
216 | /// {}` when we're type-checking the body of that function. In this | 219 | /// {}` when we're type-checking the body of that function. In this |
217 | /// situation, we know this stands for *some* type, but don't know the exact | 220 | /// situation, we know this stands for *some* type, but don't know the exact |
218 | /// type. | 221 | /// type. |
219 | Placeholder(TypeParamId), | 222 | Placeholder(PlaceholderIndex), |
220 | 223 | ||
221 | /// A bound type variable. This is used in various places: when representing | 224 | /// A bound type variable. This is used in various places: when representing |
222 | /// some polymorphic type like the type of function `fn f<T>`, the type | 225 | /// some polymorphic type like the type of function `fn f<T>`, the type |
@@ -244,6 +247,29 @@ pub enum Ty { | |||
244 | Unknown, | 247 | Unknown, |
245 | } | 248 | } |
246 | 249 | ||
250 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | ||
251 | pub struct Ty(Arc<TyKind>); | ||
252 | |||
253 | impl TyKind { | ||
254 | pub fn intern(self, _interner: &Interner) -> Ty { | ||
255 | Ty(Arc::new(self)) | ||
256 | } | ||
257 | } | ||
258 | |||
259 | impl Ty { | ||
260 | pub fn interned(&self, _interner: &Interner) -> &TyKind { | ||
261 | &self.0 | ||
262 | } | ||
263 | |||
264 | pub fn interned_mut(&mut self) -> &mut TyKind { | ||
265 | Arc::make_mut(&mut self.0) | ||
266 | } | ||
267 | |||
268 | pub fn into_inner(self) -> TyKind { | ||
269 | Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone()) | ||
270 | } | ||
271 | } | ||
272 | |||
247 | /// A list of substitutions for generic parameters. | 273 | /// A list of substitutions for generic parameters. |
248 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 274 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
249 | pub struct Substs(Arc<[Ty]>); | 275 | pub struct Substs(Arc<[Ty]>); |
@@ -291,14 +317,22 @@ impl Substs { | |||
291 | } | 317 | } |
292 | 318 | ||
293 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 319 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
294 | pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { | 320 | pub(crate) fn type_params_for_generics( |
295 | Substs(generic_params.iter().map(|(id, _)| Ty::Placeholder(id)).collect()) | 321 | db: &dyn HirDatabase, |
322 | generic_params: &Generics, | ||
323 | ) -> Substs { | ||
324 | Substs( | ||
325 | generic_params | ||
326 | .iter() | ||
327 | .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner)) | ||
328 | .collect(), | ||
329 | ) | ||
296 | } | 330 | } |
297 | 331 | ||
298 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 332 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
299 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { | 333 | pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { |
300 | let params = generics(db.upcast(), def.into()); | 334 | let params = generics(db.upcast(), def.into()); |
301 | Substs::type_params_for_generics(¶ms) | 335 | Substs::type_params_for_generics(db, ¶ms) |
302 | } | 336 | } |
303 | 337 | ||
304 | /// Return Substs that replace each parameter by a bound variable. | 338 | /// Return Substs that replace each parameter by a bound variable. |
@@ -307,7 +341,7 @@ impl Substs { | |||
307 | generic_params | 341 | generic_params |
308 | .iter() | 342 | .iter() |
309 | .enumerate() | 343 | .enumerate() |
310 | .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) | 344 | .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)) |
311 | .collect(), | 345 | .collect(), |
312 | ) | 346 | ) |
313 | } | 347 | } |
@@ -355,11 +389,14 @@ impl SubstsBuilder { | |||
355 | } | 389 | } |
356 | 390 | ||
357 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { | 391 | pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { |
358 | self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx)))) | 392 | self.fill( |
393 | (starting_from..) | ||
394 | .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)), | ||
395 | ) | ||
359 | } | 396 | } |
360 | 397 | ||
361 | pub fn fill_with_unknown(self) -> Self { | 398 | pub fn fill_with_unknown(self) -> Self { |
362 | self.fill(iter::repeat(Ty::Unknown)) | 399 | self.fill(iter::repeat(TyKind::Unknown.intern(&Interner))) |
363 | } | 400 | } |
364 | 401 | ||
365 | pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { | 402 | pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { |
@@ -601,47 +638,50 @@ impl TypeWalk for CallableSig { | |||
601 | 638 | ||
602 | impl Ty { | 639 | impl Ty { |
603 | pub fn unit() -> Self { | 640 | pub fn unit() -> Self { |
604 | Ty::Tuple(0, Substs::empty()) | 641 | TyKind::Tuple(0, Substs::empty()).intern(&Interner) |
605 | } | 642 | } |
606 | 643 | ||
607 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { | 644 | pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { |
608 | Ty::Adt(AdtId(adt), substs) | 645 | TyKind::Adt(AdtId(adt), substs).intern(&Interner) |
609 | } | 646 | } |
610 | 647 | ||
611 | pub fn fn_ptr(sig: CallableSig) -> Self { | 648 | pub fn fn_ptr(sig: CallableSig) -> Self { |
612 | Ty::Function(FnPointer { | 649 | TyKind::Function(FnPointer { |
613 | num_args: sig.params().len(), | 650 | num_args: sig.params().len(), |
614 | sig: FnSig { variadic: sig.is_varargs }, | 651 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, |
615 | substs: Substs(sig.params_and_return), | 652 | substs: Substs(sig.params_and_return), |
616 | }) | 653 | }) |
654 | .intern(&Interner) | ||
617 | } | 655 | } |
618 | 656 | ||
619 | pub fn builtin(builtin: BuiltinType) -> Self { | 657 | pub fn builtin(builtin: BuiltinType) -> Self { |
620 | match builtin { | 658 | match builtin { |
621 | BuiltinType::Char => Ty::Scalar(Scalar::Char), | 659 | BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner), |
622 | BuiltinType::Bool => Ty::Scalar(Scalar::Bool), | 660 | BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner), |
623 | BuiltinType::Str => Ty::Str, | 661 | BuiltinType::Str => TyKind::Str.intern(&Interner), |
624 | BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), | 662 | BuiltinType::Int(t) => { |
625 | BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), | 663 | TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner) |
626 | BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), | 664 | } |
665 | BuiltinType::Uint(t) => { | ||
666 | TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner) | ||
667 | } | ||
668 | BuiltinType::Float(t) => { | ||
669 | TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner) | ||
670 | } | ||
627 | } | 671 | } |
628 | } | 672 | } |
629 | 673 | ||
630 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { | 674 | pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { |
631 | match self { | 675 | match self.interned(&Interner) { |
632 | Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), | 676 | TyKind::Ref(mutability, ty) => Some((ty, *mutability)), |
633 | _ => None, | 677 | _ => None, |
634 | } | 678 | } |
635 | } | 679 | } |
636 | 680 | ||
637 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { | 681 | pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { |
638 | match self { | 682 | match self.interned(&Interner) { |
639 | Ty::Ref(mutability, parameters) => { | 683 | TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)), |
640 | Some((parameters.as_single(), Rawness::Ref, *mutability)) | 684 | TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)), |
641 | } | ||
642 | Ty::Raw(mutability, parameters) => { | ||
643 | Some((parameters.as_single(), Rawness::RawPtr, *mutability)) | ||
644 | } | ||
645 | _ => None, | 685 | _ => None, |
646 | } | 686 | } |
647 | } | 687 | } |
@@ -649,73 +689,79 @@ impl Ty { | |||
649 | pub fn strip_references(&self) -> &Ty { | 689 | pub fn strip_references(&self) -> &Ty { |
650 | let mut t: &Ty = self; | 690 | let mut t: &Ty = self; |
651 | 691 | ||
652 | while let Ty::Ref(_mutability, parameters) = t { | 692 | while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) { |
653 | t = parameters.as_single(); | 693 | t = ty; |
654 | } | 694 | } |
655 | 695 | ||
656 | t | 696 | t |
657 | } | 697 | } |
658 | 698 | ||
659 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { | 699 | pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { |
660 | match self { | 700 | match self.interned(&Interner) { |
661 | Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), | 701 | TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), |
662 | _ => None, | 702 | _ => None, |
663 | } | 703 | } |
664 | } | 704 | } |
665 | 705 | ||
666 | pub fn as_tuple(&self) -> Option<&Substs> { | 706 | pub fn as_tuple(&self) -> Option<&Substs> { |
667 | match self { | 707 | match self.interned(&Interner) { |
668 | Ty::Tuple(_, substs) => Some(substs), | 708 | TyKind::Tuple(_, substs) => Some(substs), |
669 | _ => None, | 709 | _ => None, |
670 | } | 710 | } |
671 | } | 711 | } |
672 | 712 | ||
673 | pub fn as_generic_def(&self) -> Option<GenericDefId> { | 713 | pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> { |
674 | match *self { | 714 | match *self.interned(&Interner) { |
675 | Ty::Adt(AdtId(adt), ..) => Some(adt.into()), | 715 | TyKind::Adt(AdtId(adt), ..) => Some(adt.into()), |
676 | Ty::FnDef(callable, ..) => Some(callable.into()), | 716 | TyKind::FnDef(callable, ..) => { |
677 | Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), | 717 | Some(db.lookup_intern_callable_def(callable.into()).into()) |
678 | Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), | 718 | } |
719 | TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()), | ||
720 | TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()), | ||
679 | _ => None, | 721 | _ => None, |
680 | } | 722 | } |
681 | } | 723 | } |
682 | 724 | ||
683 | pub fn is_never(&self) -> bool { | 725 | pub fn is_never(&self) -> bool { |
684 | matches!(self, Ty::Never) | 726 | matches!(self.interned(&Interner), TyKind::Never) |
685 | } | 727 | } |
686 | 728 | ||
687 | pub fn is_unknown(&self) -> bool { | 729 | pub fn is_unknown(&self) -> bool { |
688 | matches!(self, Ty::Unknown) | 730 | matches!(self.interned(&Interner), TyKind::Unknown) |
689 | } | 731 | } |
690 | 732 | ||
691 | pub fn equals_ctor(&self, other: &Ty) -> bool { | 733 | pub fn equals_ctor(&self, other: &Ty) -> bool { |
692 | match (self, other) { | 734 | match (self.interned(&Interner), other.interned(&Interner)) { |
693 | (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, | 735 | (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2, |
694 | (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, | 736 | (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true, |
695 | (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, | 737 | (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2, |
696 | (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, | 738 | (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, |
697 | (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) | 739 | (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => { |
698 | | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, | 740 | ty_id == ty_id2 |
699 | (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { | 741 | } |
700 | expr == expr2 && def == def2 | 742 | (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2, |
743 | (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2, | ||
744 | (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..)) | ||
745 | | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => { | ||
746 | mutability == mutability2 | ||
701 | } | 747 | } |
702 | (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) | ||
703 | | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2, | ||
704 | ( | 748 | ( |
705 | Ty::Function(FnPointer { num_args, sig, .. }), | 749 | TyKind::Function(FnPointer { num_args, sig, .. }), |
706 | Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), | 750 | TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), |
707 | ) => num_args == num_args2 && sig == sig2, | 751 | ) => num_args == num_args2 && sig == sig2, |
708 | (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, | 752 | (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => { |
709 | (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, | 753 | cardinality == cardinality2 |
710 | (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, | 754 | } |
755 | (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true, | ||
756 | (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2, | ||
711 | _ => false, | 757 | _ => false, |
712 | } | 758 | } |
713 | } | 759 | } |
714 | 760 | ||
715 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 761 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
716 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 762 | pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
717 | match self { | 763 | match self.interned(&Interner) { |
718 | Ty::Dyn(bounds) => bounds.get(0).and_then(|b| match b { | 764 | TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b { |
719 | GenericPredicate::Implemented(trait_ref) => Some(trait_ref), | 765 | GenericPredicate::Implemented(trait_ref) => Some(trait_ref), |
720 | _ => None, | 766 | _ => None, |
721 | }), | 767 | }), |
@@ -729,28 +775,37 @@ impl Ty { | |||
729 | } | 775 | } |
730 | 776 | ||
731 | fn builtin_deref(&self) -> Option<Ty> { | 777 | fn builtin_deref(&self) -> Option<Ty> { |
732 | match self { | 778 | match self.interned(&Interner) { |
733 | Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), | 779 | TyKind::Ref(.., ty) => Some(ty.clone()), |
734 | Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), | 780 | TyKind::Raw(.., ty) => Some(ty.clone()), |
735 | _ => None, | 781 | _ => None, |
736 | } | 782 | } |
737 | } | 783 | } |
738 | 784 | ||
739 | pub fn as_fn_def(&self) -> Option<FunctionId> { | 785 | pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> { |
740 | match self { | 786 | match self.interned(&Interner) { |
741 | &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), | 787 | &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())), |
742 | _ => None, | 788 | _ => None, |
743 | } | 789 | } |
744 | } | 790 | } |
745 | 791 | ||
792 | pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> { | ||
793 | if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) { | ||
794 | Some(func) | ||
795 | } else { | ||
796 | None | ||
797 | } | ||
798 | } | ||
799 | |||
746 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { | 800 | pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { |
747 | match self { | 801 | match self.interned(&Interner) { |
748 | Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), | 802 | TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), |
749 | Ty::FnDef(def, parameters) => { | 803 | TyKind::FnDef(def, parameters) => { |
750 | let sig = db.callable_item_signature(*def); | 804 | let callable_def = db.lookup_intern_callable_def((*def).into()); |
805 | let sig = db.callable_item_signature(callable_def); | ||
751 | Some(sig.subst(¶meters)) | 806 | Some(sig.subst(¶meters)) |
752 | } | 807 | } |
753 | Ty::Closure(.., substs) => { | 808 | TyKind::Closure(.., substs) => { |
754 | let sig_param = &substs[0]; | 809 | let sig_param = &substs[0]; |
755 | sig_param.callable_sig(db) | 810 | sig_param.callable_sig(db) |
756 | } | 811 | } |
@@ -758,72 +813,39 @@ impl Ty { | |||
758 | } | 813 | } |
759 | } | 814 | } |
760 | 815 | ||
761 | /// If this is a type with type parameters (an ADT or function), replaces | ||
762 | /// the `Substs` for these type parameters with the given ones. (So e.g. if | ||
763 | /// `self` is `Option<_>` and the substs contain `u32`, we'll have | ||
764 | /// `Option<u32>` afterwards.) | ||
765 | pub fn apply_substs(mut self, new_substs: Substs) -> Ty { | ||
766 | match &mut self { | ||
767 | Ty::Adt(_, substs) | ||
768 | | Ty::Slice(substs) | ||
769 | | Ty::Array(substs) | ||
770 | | Ty::Raw(_, substs) | ||
771 | | Ty::Ref(_, substs) | ||
772 | | Ty::FnDef(_, substs) | ||
773 | | Ty::Function(FnPointer { substs, .. }) | ||
774 | | Ty::Tuple(_, substs) | ||
775 | | Ty::OpaqueType(_, substs) | ||
776 | | Ty::AssociatedType(_, substs) | ||
777 | | Ty::Closure(.., substs) => { | ||
778 | assert_eq!(substs.len(), new_substs.len()); | ||
779 | *substs = new_substs; | ||
780 | } | ||
781 | _ => (), | ||
782 | } | ||
783 | self | ||
784 | } | ||
785 | |||
786 | /// Returns the type parameters of this type if it has some (i.e. is an ADT | 816 | /// Returns the type parameters of this type if it has some (i.e. is an ADT |
787 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. | 817 | /// or function); so if `self` is `Option<u32>`, this returns the `u32`. |
788 | pub fn substs(&self) -> Option<&Substs> { | 818 | pub fn substs(&self) -> Option<&Substs> { |
789 | match self { | 819 | match self.interned(&Interner) { |
790 | Ty::Adt(_, substs) | 820 | TyKind::Adt(_, substs) |
791 | | Ty::Slice(substs) | 821 | | TyKind::FnDef(_, substs) |
792 | | Ty::Array(substs) | 822 | | TyKind::Function(FnPointer { substs, .. }) |
793 | | Ty::Raw(_, substs) | 823 | | TyKind::Tuple(_, substs) |
794 | | Ty::Ref(_, substs) | 824 | | TyKind::OpaqueType(_, substs) |
795 | | Ty::FnDef(_, substs) | 825 | | TyKind::AssociatedType(_, substs) |
796 | | Ty::Function(FnPointer { substs, .. }) | 826 | | TyKind::Closure(.., substs) => Some(substs), |
797 | | Ty::Tuple(_, substs) | ||
798 | | Ty::OpaqueType(_, substs) | ||
799 | | Ty::AssociatedType(_, substs) | ||
800 | | Ty::Closure(.., substs) => Some(substs), | ||
801 | _ => None, | 827 | _ => None, |
802 | } | 828 | } |
803 | } | 829 | } |
804 | 830 | ||
805 | pub fn substs_mut(&mut self) -> Option<&mut Substs> { | 831 | fn substs_mut(&mut self) -> Option<&mut Substs> { |
806 | match self { | 832 | match self.interned_mut() { |
807 | Ty::Adt(_, substs) | 833 | TyKind::Adt(_, substs) |
808 | | Ty::Slice(substs) | 834 | | TyKind::FnDef(_, substs) |
809 | | Ty::Array(substs) | 835 | | TyKind::Function(FnPointer { substs, .. }) |
810 | | Ty::Raw(_, substs) | 836 | | TyKind::Tuple(_, substs) |
811 | | Ty::Ref(_, substs) | 837 | | TyKind::OpaqueType(_, substs) |
812 | | Ty::FnDef(_, substs) | 838 | | TyKind::AssociatedType(_, substs) |
813 | | Ty::Function(FnPointer { substs, .. }) | 839 | | TyKind::Closure(.., substs) => Some(substs), |
814 | | Ty::Tuple(_, substs) | ||
815 | | Ty::OpaqueType(_, substs) | ||
816 | | Ty::AssociatedType(_, substs) | ||
817 | | Ty::Closure(.., substs) => Some(substs), | ||
818 | _ => None, | 840 | _ => None, |
819 | } | 841 | } |
820 | } | 842 | } |
821 | 843 | ||
822 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { | 844 | pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { |
823 | match self { | 845 | match self.interned(&Interner) { |
824 | Ty::OpaqueType(opaque_ty_id, ..) => { | 846 | TyKind::OpaqueType(opaque_ty_id, ..) => { |
825 | match opaque_ty_id { | 847 | match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) { |
826 | OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { | 848 | ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => { |
827 | let krate = def.module(db.upcast()).krate(); | 849 | let krate = def.module(db.upcast()).krate(); |
828 | if let Some(future_trait) = db | 850 | if let Some(future_trait) = db |
829 | .lang_item(krate, "future_trait".into()) | 851 | .lang_item(krate, "future_trait".into()) |
@@ -841,32 +863,34 @@ impl Ty { | |||
841 | None | 863 | None |
842 | } | 864 | } |
843 | } | 865 | } |
844 | OpaqueTyId::ReturnTypeImplTrait(..) => None, | 866 | ImplTraitId::ReturnTypeImplTrait(..) => None, |
845 | } | 867 | } |
846 | } | 868 | } |
847 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 869 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
848 | let predicates = match opaque_ty.opaque_ty_id { | 870 | let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into()) |
849 | OpaqueTyId::ReturnTypeImplTrait(func, idx) => { | 871 | { |
872 | ImplTraitId::ReturnTypeImplTrait(func, idx) => { | ||
850 | db.return_type_impl_traits(func).map(|it| { | 873 | db.return_type_impl_traits(func).map(|it| { |
851 | let data = (*it) | 874 | let data = (*it) |
852 | .as_ref() | 875 | .as_ref() |
853 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); | 876 | .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); |
854 | data.subst(&opaque_ty.parameters) | 877 | data.subst(&opaque_ty.substitution) |
855 | }) | 878 | }) |
856 | } | 879 | } |
857 | // It always has an parameter for Future::Output type. | 880 | // It always has an parameter for Future::Output type. |
858 | OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 881 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
859 | }; | 882 | }; |
860 | 883 | ||
861 | predicates.map(|it| it.value) | 884 | predicates.map(|it| it.value) |
862 | } | 885 | } |
863 | Ty::Placeholder(id) => { | 886 | TyKind::Placeholder(idx) => { |
887 | let id = from_placeholder_idx(db, *idx); | ||
864 | let generic_params = db.generic_params(id.parent); | 888 | let generic_params = db.generic_params(id.parent); |
865 | let param_data = &generic_params.types[id.local_id]; | 889 | let param_data = &generic_params.types[id.local_id]; |
866 | match param_data.provenance { | 890 | match param_data.provenance { |
867 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { | 891 | hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { |
868 | let predicates = db | 892 | let predicates = db |
869 | .generic_predicates_for_param(*id) | 893 | .generic_predicates_for_param(id) |
870 | .into_iter() | 894 | .into_iter() |
871 | .map(|pred| pred.value.clone()) | 895 | .map(|pred| pred.value.clone()) |
872 | .collect_vec(); | 896 | .collect_vec(); |
@@ -881,15 +905,18 @@ impl Ty { | |||
881 | } | 905 | } |
882 | 906 | ||
883 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { | 907 | pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { |
884 | match self { | 908 | match self.interned(&Interner) { |
885 | Ty::AssociatedType(type_alias_id, ..) => { | 909 | TyKind::AssociatedType(id, ..) => { |
886 | match type_alias_id.lookup(db.upcast()).container { | 910 | match from_assoc_type_id(*id).lookup(db.upcast()).container { |
887 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 911 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
888 | _ => None, | 912 | _ => None, |
889 | } | 913 | } |
890 | } | 914 | } |
891 | Ty::Alias(AliasTy::Projection(projection_ty)) => { | 915 | TyKind::Alias(AliasTy::Projection(projection_ty)) => { |
892 | match projection_ty.associated_ty.lookup(db.upcast()).container { | 916 | match from_assoc_type_id(projection_ty.associated_ty_id) |
917 | .lookup(db.upcast()) | ||
918 | .container | ||
919 | { | ||
893 | AssocContainerId::TraitId(trait_id) => Some(trait_id), | 920 | AssocContainerId::TraitId(trait_id) => Some(trait_id), |
894 | _ => None, | 921 | _ => None, |
895 | } | 922 | } |
@@ -908,13 +935,13 @@ pub trait TypeWalk { | |||
908 | } | 935 | } |
909 | /// Walk the type, counting entered binders. | 936 | /// Walk the type, counting entered binders. |
910 | /// | 937 | /// |
911 | /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers | 938 | /// `TyKind::Bound` variables use DeBruijn indexing, which means that 0 refers |
912 | /// to the innermost binder, 1 to the next, etc.. So when we want to | 939 | /// to the innermost binder, 1 to the next, etc.. So when we want to |
913 | /// substitute a certain bound variable, we can't just walk the whole type | 940 | /// substitute a certain bound variable, we can't just walk the whole type |
914 | /// and blindly replace each instance of a certain index; when we 'enter' | 941 | /// and blindly replace each instance of a certain index; when we 'enter' |
915 | /// things that introduce new bound variables, we have to keep track of | 942 | /// things that introduce new bound variables, we have to keep track of |
916 | /// that. Currently, the only thing that introduces bound variables on our | 943 | /// that. Currently, the only thing that introduces bound variables on our |
917 | /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound | 944 | /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound |
918 | /// variable for the self type. | 945 | /// variable for the self type. |
919 | fn walk_mut_binders( | 946 | fn walk_mut_binders( |
920 | &mut self, | 947 | &mut self, |
@@ -932,7 +959,7 @@ pub trait TypeWalk { | |||
932 | { | 959 | { |
933 | self.walk_mut_binders( | 960 | self.walk_mut_binders( |
934 | &mut |ty_mut, binders| { | 961 | &mut |ty_mut, binders| { |
935 | let ty = mem::replace(ty_mut, Ty::Unknown); | 962 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
936 | *ty_mut = f(ty, binders); | 963 | *ty_mut = f(ty, binders); |
937 | }, | 964 | }, |
938 | binders, | 965 | binders, |
@@ -945,13 +972,13 @@ pub trait TypeWalk { | |||
945 | Self: Sized, | 972 | Self: Sized, |
946 | { | 973 | { |
947 | self.walk_mut(&mut |ty_mut| { | 974 | self.walk_mut(&mut |ty_mut| { |
948 | let ty = mem::replace(ty_mut, Ty::Unknown); | 975 | let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner)); |
949 | *ty_mut = f(ty); | 976 | *ty_mut = f(ty); |
950 | }); | 977 | }); |
951 | self | 978 | self |
952 | } | 979 | } |
953 | 980 | ||
954 | /// Substitutes `Ty::Bound` vars with the given substitution. | 981 | /// Substitutes `TyKind::Bound` vars with the given substitution. |
955 | fn subst_bound_vars(self, substs: &Substs) -> Self | 982 | fn subst_bound_vars(self, substs: &Substs) -> Self |
956 | where | 983 | where |
957 | Self: Sized, | 984 | Self: Sized, |
@@ -959,14 +986,14 @@ pub trait TypeWalk { | |||
959 | self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) | 986 | self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) |
960 | } | 987 | } |
961 | 988 | ||
962 | /// Substitutes `Ty::Bound` vars with the given substitution. | 989 | /// Substitutes `TyKind::Bound` vars with the given substitution. |
963 | fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self | 990 | fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self |
964 | where | 991 | where |
965 | Self: Sized, | 992 | Self: Sized, |
966 | { | 993 | { |
967 | self.walk_mut_binders( | 994 | self.walk_mut_binders( |
968 | &mut |ty, binders| { | 995 | &mut |ty, binders| { |
969 | if let &mut Ty::BoundVar(bound) = ty { | 996 | if let &mut TyKind::BoundVar(bound) = ty.interned_mut() { |
970 | if bound.debruijn >= binders { | 997 | if bound.debruijn >= binders { |
971 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); | 998 | *ty = substs.0[bound.index].clone().shift_bound_vars(binders); |
972 | } | 999 | } |
@@ -977,17 +1004,17 @@ pub trait TypeWalk { | |||
977 | self | 1004 | self |
978 | } | 1005 | } |
979 | 1006 | ||
980 | /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. | 1007 | /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`. |
981 | fn shift_bound_vars(self, n: DebruijnIndex) -> Self | 1008 | fn shift_bound_vars(self, n: DebruijnIndex) -> Self |
982 | where | 1009 | where |
983 | Self: Sized, | 1010 | Self: Sized, |
984 | { | 1011 | { |
985 | self.fold_binders( | 1012 | self.fold_binders( |
986 | &mut |ty, binders| match ty { | 1013 | &mut |ty, binders| match ty.interned(&Interner) { |
987 | Ty::BoundVar(bound) if bound.debruijn >= binders => { | 1014 | TyKind::BoundVar(bound) if bound.debruijn >= binders => { |
988 | Ty::BoundVar(bound.shifted_in_from(n)) | 1015 | TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner) |
989 | } | 1016 | } |
990 | ty => ty, | 1017 | _ => ty, |
991 | }, | 1018 | }, |
992 | DebruijnIndex::INNERMOST, | 1019 | DebruijnIndex::INNERMOST, |
993 | ) | 1020 | ) |
@@ -996,22 +1023,25 @@ pub trait TypeWalk { | |||
996 | 1023 | ||
997 | impl TypeWalk for Ty { | 1024 | impl TypeWalk for Ty { |
998 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 1025 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
999 | match self { | 1026 | match self.interned(&Interner) { |
1000 | Ty::Alias(AliasTy::Projection(p_ty)) => { | 1027 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1001 | for t in p_ty.parameters.iter() { | 1028 | for t in p_ty.substitution.iter() { |
1002 | t.walk(f); | 1029 | t.walk(f); |
1003 | } | 1030 | } |
1004 | } | 1031 | } |
1005 | Ty::Alias(AliasTy::Opaque(o_ty)) => { | 1032 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { |
1006 | for t in o_ty.parameters.iter() { | 1033 | for t in o_ty.substitution.iter() { |
1007 | t.walk(f); | 1034 | t.walk(f); |
1008 | } | 1035 | } |
1009 | } | 1036 | } |
1010 | Ty::Dyn(predicates) => { | 1037 | TyKind::Dyn(predicates) => { |
1011 | for p in predicates.iter() { | 1038 | for p in predicates.iter() { |
1012 | p.walk(f); | 1039 | p.walk(f); |
1013 | } | 1040 | } |
1014 | } | 1041 | } |
1042 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1043 | ty.walk(f); | ||
1044 | } | ||
1015 | _ => { | 1045 | _ => { |
1016 | if let Some(substs) = self.substs() { | 1046 | if let Some(substs) = self.substs() { |
1017 | for t in substs.iter() { | 1047 | for t in substs.iter() { |
@@ -1028,17 +1058,20 @@ impl TypeWalk for Ty { | |||
1028 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 1058 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
1029 | binders: DebruijnIndex, | 1059 | binders: DebruijnIndex, |
1030 | ) { | 1060 | ) { |
1031 | match self { | 1061 | match self.interned_mut() { |
1032 | Ty::Alias(AliasTy::Projection(p_ty)) => { | 1062 | TyKind::Alias(AliasTy::Projection(p_ty)) => { |
1033 | p_ty.parameters.walk_mut_binders(f, binders); | 1063 | p_ty.substitution.walk_mut_binders(f, binders); |
1034 | } | 1064 | } |
1035 | Ty::Dyn(predicates) => { | 1065 | TyKind::Dyn(predicates) => { |
1036 | for p in make_mut_slice(predicates) { | 1066 | for p in make_mut_slice(predicates) { |
1037 | p.walk_mut_binders(f, binders.shifted_in()); | 1067 | p.walk_mut_binders(f, binders.shifted_in()); |
1038 | } | 1068 | } |
1039 | } | 1069 | } |
1040 | Ty::Alias(AliasTy::Opaque(o_ty)) => { | 1070 | TyKind::Alias(AliasTy::Opaque(o_ty)) => { |
1041 | o_ty.parameters.walk_mut_binders(f, binders); | 1071 | o_ty.substitution.walk_mut_binders(f, binders); |
1072 | } | ||
1073 | TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => { | ||
1074 | ty.walk_mut_binders(f, binders); | ||
1042 | } | 1075 | } |
1043 | _ => { | 1076 | _ => { |
1044 | if let Some(substs) = self.substs_mut() { | 1077 | if let Some(substs) = self.substs_mut() { |
@@ -1068,7 +1101,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> { | |||
1068 | } | 1101 | } |
1069 | 1102 | ||
1070 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] | 1103 | #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] |
1071 | pub enum OpaqueTyId { | 1104 | pub enum ImplTraitId { |
1072 | ReturnTypeImplTrait(hir_def::FunctionId, u16), | 1105 | ReturnTypeImplTrait(hir_def::FunctionId, u16), |
1073 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), | 1106 | AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), |
1074 | } | 1107 | } |
@@ -1082,3 +1115,33 @@ pub struct ReturnTypeImplTraits { | |||
1082 | pub(crate) struct ReturnTypeImplTrait { | 1115 | pub(crate) struct ReturnTypeImplTrait { |
1083 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, | 1116 | pub(crate) bounds: Binders<Vec<GenericPredicate>>, |
1084 | } | 1117 | } |
1118 | |||
1119 | pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId { | ||
1120 | chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id)) | ||
1121 | } | ||
1122 | |||
1123 | pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId { | ||
1124 | salsa::InternKey::from_intern_id(id.0) | ||
1125 | } | ||
1126 | |||
1127 | pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId { | ||
1128 | chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id)) | ||
1129 | } | ||
1130 | |||
1131 | pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId { | ||
1132 | salsa::InternKey::from_intern_id(id.0) | ||
1133 | } | ||
1134 | |||
1135 | pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId { | ||
1136 | assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT); | ||
1137 | let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx)); | ||
1138 | db.lookup_intern_type_param_id(interned_id) | ||
1139 | } | ||
1140 | |||
1141 | pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex { | ||
1142 | let interned_id = db.intern_type_param_id(id); | ||
1143 | PlaceholderIndex { | ||
1144 | ui: chalk_ir::UniverseIndex::ROOT, | ||
1145 | idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(), | ||
1146 | } | ||
1147 | } | ||