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.rs435
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
28use base_db::salsa; 28use base_db::salsa;
29use hir_def::{ 29use 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};
34use itertools::Itertools; 33use itertools::Itertools;
35 34
@@ -47,9 +46,16 @@ pub use lower::{
47}; 46};
48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 47pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
49 48
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; 49pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
51 50
52pub(crate) use crate::traits::chalk::Interner; 51pub use crate::traits::chalk::Interner;
52
53pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
54pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
55pub type FnDefId = chalk_ir::FnDefId<Interner>;
56pub type ClosureId = chalk_ir::ClosureId<Interner>;
57pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
58pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
53 59
54#[derive(Clone, PartialEq, Eq, Debug, Hash)] 60#[derive(Clone, PartialEq, Eq, Debug, Hash)]
55pub enum Lifetime { 61pub enum Lifetime {
@@ -60,7 +66,7 @@ pub enum Lifetime {
60#[derive(Clone, PartialEq, Eq, Debug, Hash)] 66#[derive(Clone, PartialEq, Eq, Debug, Hash)]
61pub struct OpaqueTy { 67pub 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)]
70pub struct ProjectionTy { 76pub 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
75impl ProjectionTy { 81impl 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
88impl TypeWalk for ProjectionTy { 94impl 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)] 108pub type FnSig = chalk_ir::FnSig<Interner>;
103pub struct FnSig {
104 pub variadic: bool,
105}
106 109
107#[derive(Clone, PartialEq, Eq, Debug, Hash)] 110#[derive(Clone, PartialEq, Eq, Debug, Hash)]
108pub struct FnPointer { 111pub 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)]
134pub enum Ty { 137pub 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)]
251pub struct Ty(Arc<TyKind>);
252
253impl TyKind {
254 pub fn intern(self, _interner: &Interner) -> Ty {
255 Ty(Arc::new(self))
256 }
257}
258
259impl 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)]
249pub struct Substs(Arc<[Ty]>); 275pub 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(&params) 335 Substs::type_params_for_generics(db, &params)
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
602impl Ty { 639impl 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(&parameters)) 806 Some(sig.subst(&parameters))
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
997impl TypeWalk for Ty { 1024impl 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)]
1071pub enum OpaqueTyId { 1104pub 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 {
1082pub(crate) struct ReturnTypeImplTrait { 1115pub(crate) struct ReturnTypeImplTrait {
1083 pub(crate) bounds: Binders<Vec<GenericPredicate>>, 1116 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1084} 1117}
1118
1119pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
1120 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
1121}
1122
1123pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
1124 salsa::InternKey::from_intern_id(id.0)
1125}
1126
1127pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
1128 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
1129}
1130
1131pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
1132 salsa::InternKey::from_intern_id(id.0)
1133}
1134
1135pub 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
1141pub 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}