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.rs412
1 files changed, 249 insertions, 163 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index e77f24e4e..484652073 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),
@@ -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,21 @@ pub enum Ty {
244 Unknown, 247 Unknown,
245} 248}
246 249
250#[derive(Clone, PartialEq, Eq, Debug, Hash)]
251pub struct Ty(TyKind);
252
253impl TyKind {
254 pub fn intern(self, _interner: &Interner) -> Ty {
255 Ty(self)
256 }
257}
258
259impl Ty {
260 pub fn interned(&self, _interner: &Interner) -> &TyKind {
261 &self.0
262 }
263}
264
247/// A list of substitutions for generic parameters. 265/// A list of substitutions for generic parameters.
248#[derive(Clone, PartialEq, Eq, Debug, Hash)] 266#[derive(Clone, PartialEq, Eq, Debug, Hash)]
249pub struct Substs(Arc<[Ty]>); 267pub struct Substs(Arc<[Ty]>);
@@ -291,14 +309,22 @@ impl Substs {
291 } 309 }
292 310
293 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 311 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
294 pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { 312 pub(crate) fn type_params_for_generics(
295 Substs(generic_params.iter().map(|(id, _)| Ty::Placeholder(id)).collect()) 313 db: &dyn HirDatabase,
314 generic_params: &Generics,
315 ) -> Substs {
316 Substs(
317 generic_params
318 .iter()
319 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
320 .collect(),
321 )
296 } 322 }
297 323
298 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 324 /// 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 { 325 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs {
300 let params = generics(db.upcast(), def.into()); 326 let params = generics(db.upcast(), def.into());
301 Substs::type_params_for_generics(&params) 327 Substs::type_params_for_generics(db, &params)
302 } 328 }
303 329
304 /// Return Substs that replace each parameter by a bound variable. 330 /// Return Substs that replace each parameter by a bound variable.
@@ -307,7 +333,7 @@ impl Substs {
307 generic_params 333 generic_params
308 .iter() 334 .iter()
309 .enumerate() 335 .enumerate()
310 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) 336 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner))
311 .collect(), 337 .collect(),
312 ) 338 )
313 } 339 }
@@ -355,11 +381,14 @@ impl SubstsBuilder {
355 } 381 }
356 382
357 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 383 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)))) 384 self.fill(
385 (starting_from..)
386 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
387 )
359 } 388 }
360 389
361 pub fn fill_with_unknown(self) -> Self { 390 pub fn fill_with_unknown(self) -> Self {
362 self.fill(iter::repeat(Ty::Unknown)) 391 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
363 } 392 }
364 393
365 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { 394 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
@@ -601,45 +630,52 @@ impl TypeWalk for CallableSig {
601 630
602impl Ty { 631impl Ty {
603 pub fn unit() -> Self { 632 pub fn unit() -> Self {
604 Ty::Tuple(0, Substs::empty()) 633 TyKind::Tuple(0, Substs::empty()).intern(&Interner)
605 } 634 }
606 635
607 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { 636 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty {
608 Ty::Adt(AdtId(adt), substs) 637 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
609 } 638 }
610 639
611 pub fn fn_ptr(sig: CallableSig) -> Self { 640 pub fn fn_ptr(sig: CallableSig) -> Self {
612 Ty::Function(FnPointer { 641 TyKind::Function(FnPointer {
613 num_args: sig.params().len(), 642 num_args: sig.params().len(),
614 sig: FnSig { variadic: sig.is_varargs }, 643 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
615 substs: Substs(sig.params_and_return), 644 substs: Substs(sig.params_and_return),
616 }) 645 })
646 .intern(&Interner)
617 } 647 }
618 648
619 pub fn builtin(builtin: BuiltinType) -> Self { 649 pub fn builtin(builtin: BuiltinType) -> Self {
620 match builtin { 650 match builtin {
621 BuiltinType::Char => Ty::Scalar(Scalar::Char), 651 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
622 BuiltinType::Bool => Ty::Scalar(Scalar::Bool), 652 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
623 BuiltinType::Str => Ty::Str, 653 BuiltinType::Str => TyKind::Str.intern(&Interner),
624 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), 654 BuiltinType::Int(t) => {
625 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), 655 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))), 656 }
657 BuiltinType::Uint(t) => {
658 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
659 }
660 BuiltinType::Float(t) => {
661 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
662 }
627 } 663 }
628 } 664 }
629 665
630 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 666 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
631 match self { 667 match self.interned(&Interner) {
632 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), 668 TyKind::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
633 _ => None, 669 _ => None,
634 } 670 }
635 } 671 }
636 672
637 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 673 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
638 match self { 674 match self.interned(&Interner) {
639 Ty::Ref(mutability, parameters) => { 675 TyKind::Ref(mutability, parameters) => {
640 Some((parameters.as_single(), Rawness::Ref, *mutability)) 676 Some((parameters.as_single(), Rawness::Ref, *mutability))
641 } 677 }
642 Ty::Raw(mutability, parameters) => { 678 TyKind::Raw(mutability, parameters) => {
643 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 679 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
644 } 680 }
645 _ => None, 681 _ => None,
@@ -649,7 +685,7 @@ impl Ty {
649 pub fn strip_references(&self) -> &Ty { 685 pub fn strip_references(&self) -> &Ty {
650 let mut t: &Ty = self; 686 let mut t: &Ty = self;
651 687
652 while let Ty::Ref(_mutability, parameters) = t { 688 while let TyKind::Ref(_mutability, parameters) = t.interned(&Interner) {
653 t = parameters.as_single(); 689 t = parameters.as_single();
654 } 690 }
655 691
@@ -657,65 +693,71 @@ impl Ty {
657 } 693 }
658 694
659 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { 695 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> {
660 match self { 696 match self.interned(&Interner) {
661 Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), 697 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
662 _ => None, 698 _ => None,
663 } 699 }
664 } 700 }
665 701
666 pub fn as_tuple(&self) -> Option<&Substs> { 702 pub fn as_tuple(&self) -> Option<&Substs> {
667 match self { 703 match self.interned(&Interner) {
668 Ty::Tuple(_, substs) => Some(substs), 704 TyKind::Tuple(_, substs) => Some(substs),
669 _ => None, 705 _ => None,
670 } 706 }
671 } 707 }
672 708
673 pub fn as_generic_def(&self) -> Option<GenericDefId> { 709 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
674 match *self { 710 match *self.interned(&Interner) {
675 Ty::Adt(AdtId(adt), ..) => Some(adt.into()), 711 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
676 Ty::FnDef(callable, ..) => Some(callable.into()), 712 TyKind::FnDef(callable, ..) => {
677 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), 713 Some(db.lookup_intern_callable_def(callable.into()).into())
678 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), 714 }
715 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
716 TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
679 _ => None, 717 _ => None,
680 } 718 }
681 } 719 }
682 720
683 pub fn is_never(&self) -> bool { 721 pub fn is_never(&self) -> bool {
684 matches!(self, Ty::Never) 722 matches!(self.interned(&Interner), TyKind::Never)
685 } 723 }
686 724
687 pub fn is_unknown(&self) -> bool { 725 pub fn is_unknown(&self) -> bool {
688 matches!(self, Ty::Unknown) 726 matches!(self.interned(&Interner), TyKind::Unknown)
689 } 727 }
690 728
691 pub fn equals_ctor(&self, other: &Ty) -> bool { 729 pub fn equals_ctor(&self, other: &Ty) -> bool {
692 match (self, other) { 730 match (self.interned(&Interner), other.interned(&Interner)) {
693 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, 731 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
694 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, 732 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
695 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, 733 (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, 734 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
697 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) 735 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
698 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, 736 ty_id == ty_id2
699 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { 737 }
700 expr == expr2 && def == def2 738 (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
739 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
740 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
741 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
742 mutability == mutability2
701 } 743 }
702 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
703 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
704 ( 744 (
705 Ty::Function(FnPointer { num_args, sig, .. }), 745 TyKind::Function(FnPointer { num_args, sig, .. }),
706 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), 746 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
707 ) => num_args == num_args2 && sig == sig2, 747 ) => num_args == num_args2 && sig == sig2,
708 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, 748 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
709 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, 749 cardinality == cardinality2
710 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, 750 }
751 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
752 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
711 _ => false, 753 _ => false,
712 } 754 }
713 } 755 }
714 756
715 /// If this is a `dyn Trait` type, this returns the `Trait` part. 757 /// If this is a `dyn Trait` type, this returns the `Trait` part.
716 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 758 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
717 match self { 759 match self.interned(&Interner) {
718 Ty::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 760 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b {
719 GenericPredicate::Implemented(trait_ref) => Some(trait_ref), 761 GenericPredicate::Implemented(trait_ref) => Some(trait_ref),
720 _ => None, 762 _ => None,
721 }), 763 }),
@@ -729,28 +771,37 @@ impl Ty {
729 } 771 }
730 772
731 fn builtin_deref(&self) -> Option<Ty> { 773 fn builtin_deref(&self) -> Option<Ty> {
732 match self { 774 match self.interned(&Interner) {
733 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), 775 TyKind::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
734 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), 776 TyKind::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
735 _ => None, 777 _ => None,
736 } 778 }
737 } 779 }
738 780
739 pub fn as_fn_def(&self) -> Option<FunctionId> { 781 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
740 match self { 782 match self.interned(&Interner) {
741 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), 783 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
742 _ => None, 784 _ => None,
743 } 785 }
744 } 786 }
745 787
788 pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
789 if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
790 Some(func)
791 } else {
792 None
793 }
794 }
795
746 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { 796 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
747 match self { 797 match self.interned(&Interner) {
748 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), 798 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
749 Ty::FnDef(def, parameters) => { 799 TyKind::FnDef(def, parameters) => {
750 let sig = db.callable_item_signature(*def); 800 let callable_def = db.lookup_intern_callable_def((*def).into());
801 let sig = db.callable_item_signature(callable_def);
751 Some(sig.subst(&parameters)) 802 Some(sig.subst(&parameters))
752 } 803 }
753 Ty::Closure(.., substs) => { 804 TyKind::Closure(.., substs) => {
754 let sig_param = &substs[0]; 805 let sig_param = &substs[0];
755 sig_param.callable_sig(db) 806 sig_param.callable_sig(db)
756 } 807 }
@@ -763,18 +814,18 @@ impl Ty {
763 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 814 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
764 /// `Option<u32>` afterwards.) 815 /// `Option<u32>` afterwards.)
765 pub fn apply_substs(mut self, new_substs: Substs) -> Ty { 816 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
766 match &mut self { 817 match &mut self.0 {
767 Ty::Adt(_, substs) 818 TyKind::Adt(_, substs)
768 | Ty::Slice(substs) 819 | TyKind::Slice(substs)
769 | Ty::Array(substs) 820 | TyKind::Array(substs)
770 | Ty::Raw(_, substs) 821 | TyKind::Raw(_, substs)
771 | Ty::Ref(_, substs) 822 | TyKind::Ref(_, substs)
772 | Ty::FnDef(_, substs) 823 | TyKind::FnDef(_, substs)
773 | Ty::Function(FnPointer { substs, .. }) 824 | TyKind::Function(FnPointer { substs, .. })
774 | Ty::Tuple(_, substs) 825 | TyKind::Tuple(_, substs)
775 | Ty::OpaqueType(_, substs) 826 | TyKind::OpaqueType(_, substs)
776 | Ty::AssociatedType(_, substs) 827 | TyKind::AssociatedType(_, substs)
777 | Ty::Closure(.., substs) => { 828 | TyKind::Closure(.., substs) => {
778 assert_eq!(substs.len(), new_substs.len()); 829 assert_eq!(substs.len(), new_substs.len());
779 *substs = new_substs; 830 *substs = new_substs;
780 } 831 }
@@ -786,44 +837,44 @@ impl Ty {
786 /// Returns the type parameters of this type if it has some (i.e. is an ADT 837 /// 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`. 838 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
788 pub fn substs(&self) -> Option<&Substs> { 839 pub fn substs(&self) -> Option<&Substs> {
789 match self { 840 match self.interned(&Interner) {
790 Ty::Adt(_, substs) 841 TyKind::Adt(_, substs)
791 | Ty::Slice(substs) 842 | TyKind::Slice(substs)
792 | Ty::Array(substs) 843 | TyKind::Array(substs)
793 | Ty::Raw(_, substs) 844 | TyKind::Raw(_, substs)
794 | Ty::Ref(_, substs) 845 | TyKind::Ref(_, substs)
795 | Ty::FnDef(_, substs) 846 | TyKind::FnDef(_, substs)
796 | Ty::Function(FnPointer { substs, .. }) 847 | TyKind::Function(FnPointer { substs, .. })
797 | Ty::Tuple(_, substs) 848 | TyKind::Tuple(_, substs)
798 | Ty::OpaqueType(_, substs) 849 | TyKind::OpaqueType(_, substs)
799 | Ty::AssociatedType(_, substs) 850 | TyKind::AssociatedType(_, substs)
800 | Ty::Closure(.., substs) => Some(substs), 851 | TyKind::Closure(.., substs) => Some(substs),
801 _ => None, 852 _ => None,
802 } 853 }
803 } 854 }
804 855
805 pub fn substs_mut(&mut self) -> Option<&mut Substs> { 856 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
806 match self { 857 match &mut self.0 {
807 Ty::Adt(_, substs) 858 TyKind::Adt(_, substs)
808 | Ty::Slice(substs) 859 | TyKind::Slice(substs)
809 | Ty::Array(substs) 860 | TyKind::Array(substs)
810 | Ty::Raw(_, substs) 861 | TyKind::Raw(_, substs)
811 | Ty::Ref(_, substs) 862 | TyKind::Ref(_, substs)
812 | Ty::FnDef(_, substs) 863 | TyKind::FnDef(_, substs)
813 | Ty::Function(FnPointer { substs, .. }) 864 | TyKind::Function(FnPointer { substs, .. })
814 | Ty::Tuple(_, substs) 865 | TyKind::Tuple(_, substs)
815 | Ty::OpaqueType(_, substs) 866 | TyKind::OpaqueType(_, substs)
816 | Ty::AssociatedType(_, substs) 867 | TyKind::AssociatedType(_, substs)
817 | Ty::Closure(.., substs) => Some(substs), 868 | TyKind::Closure(.., substs) => Some(substs),
818 _ => None, 869 _ => None,
819 } 870 }
820 } 871 }
821 872
822 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 873 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
823 match self { 874 match self.interned(&Interner) {
824 Ty::OpaqueType(opaque_ty_id, ..) => { 875 TyKind::OpaqueType(opaque_ty_id, ..) => {
825 match opaque_ty_id { 876 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
826 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 877 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
827 let krate = def.module(db.upcast()).krate(); 878 let krate = def.module(db.upcast()).krate();
828 if let Some(future_trait) = db 879 if let Some(future_trait) = db
829 .lang_item(krate, "future_trait".into()) 880 .lang_item(krate, "future_trait".into())
@@ -841,32 +892,34 @@ impl Ty {
841 None 892 None
842 } 893 }
843 } 894 }
844 OpaqueTyId::ReturnTypeImplTrait(..) => None, 895 ImplTraitId::ReturnTypeImplTrait(..) => None,
845 } 896 }
846 } 897 }
847 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 898 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
848 let predicates = match opaque_ty.opaque_ty_id { 899 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
849 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 900 {
901 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
850 db.return_type_impl_traits(func).map(|it| { 902 db.return_type_impl_traits(func).map(|it| {
851 let data = (*it) 903 let data = (*it)
852 .as_ref() 904 .as_ref()
853 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 905 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
854 data.subst(&opaque_ty.parameters) 906 data.subst(&opaque_ty.substitution)
855 }) 907 })
856 } 908 }
857 // It always has an parameter for Future::Output type. 909 // It always has an parameter for Future::Output type.
858 OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), 910 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
859 }; 911 };
860 912
861 predicates.map(|it| it.value) 913 predicates.map(|it| it.value)
862 } 914 }
863 Ty::Placeholder(id) => { 915 TyKind::Placeholder(idx) => {
916 let id = from_placeholder_idx(db, *idx);
864 let generic_params = db.generic_params(id.parent); 917 let generic_params = db.generic_params(id.parent);
865 let param_data = &generic_params.types[id.local_id]; 918 let param_data = &generic_params.types[id.local_id];
866 match param_data.provenance { 919 match param_data.provenance {
867 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { 920 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
868 let predicates = db 921 let predicates = db
869 .generic_predicates_for_param(*id) 922 .generic_predicates_for_param(id)
870 .into_iter() 923 .into_iter()
871 .map(|pred| pred.value.clone()) 924 .map(|pred| pred.value.clone())
872 .collect_vec(); 925 .collect_vec();
@@ -881,15 +934,18 @@ impl Ty {
881 } 934 }
882 935
883 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 936 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
884 match self { 937 match self.interned(&Interner) {
885 Ty::AssociatedType(type_alias_id, ..) => { 938 TyKind::AssociatedType(id, ..) => {
886 match type_alias_id.lookup(db.upcast()).container { 939 match from_assoc_type_id(*id).lookup(db.upcast()).container {
887 AssocContainerId::TraitId(trait_id) => Some(trait_id), 940 AssocContainerId::TraitId(trait_id) => Some(trait_id),
888 _ => None, 941 _ => None,
889 } 942 }
890 } 943 }
891 Ty::Alias(AliasTy::Projection(projection_ty)) => { 944 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
892 match projection_ty.associated_ty.lookup(db.upcast()).container { 945 match from_assoc_type_id(projection_ty.associated_ty_id)
946 .lookup(db.upcast())
947 .container
948 {
893 AssocContainerId::TraitId(trait_id) => Some(trait_id), 949 AssocContainerId::TraitId(trait_id) => Some(trait_id),
894 _ => None, 950 _ => None,
895 } 951 }
@@ -908,13 +964,13 @@ pub trait TypeWalk {
908 } 964 }
909 /// Walk the type, counting entered binders. 965 /// Walk the type, counting entered binders.
910 /// 966 ///
911 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers 967 /// `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 968 /// 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 969 /// 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' 970 /// 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 971 /// things that introduce new bound variables, we have to keep track of
916 /// that. Currently, the only thing that introduces bound variables on our 972 /// that. Currently, the only thing that introduces bound variables on our
917 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound 973 /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound
918 /// variable for the self type. 974 /// variable for the self type.
919 fn walk_mut_binders( 975 fn walk_mut_binders(
920 &mut self, 976 &mut self,
@@ -932,7 +988,7 @@ pub trait TypeWalk {
932 { 988 {
933 self.walk_mut_binders( 989 self.walk_mut_binders(
934 &mut |ty_mut, binders| { 990 &mut |ty_mut, binders| {
935 let ty = mem::replace(ty_mut, Ty::Unknown); 991 let ty = mem::replace(ty_mut, Ty(TyKind::Unknown));
936 *ty_mut = f(ty, binders); 992 *ty_mut = f(ty, binders);
937 }, 993 },
938 binders, 994 binders,
@@ -945,13 +1001,13 @@ pub trait TypeWalk {
945 Self: Sized, 1001 Self: Sized,
946 { 1002 {
947 self.walk_mut(&mut |ty_mut| { 1003 self.walk_mut(&mut |ty_mut| {
948 let ty = mem::replace(ty_mut, Ty::Unknown); 1004 let ty = mem::replace(ty_mut, Ty(TyKind::Unknown));
949 *ty_mut = f(ty); 1005 *ty_mut = f(ty);
950 }); 1006 });
951 self 1007 self
952 } 1008 }
953 1009
954 /// Substitutes `Ty::Bound` vars with the given substitution. 1010 /// Substitutes `TyKind::Bound` vars with the given substitution.
955 fn subst_bound_vars(self, substs: &Substs) -> Self 1011 fn subst_bound_vars(self, substs: &Substs) -> Self
956 where 1012 where
957 Self: Sized, 1013 Self: Sized,
@@ -959,14 +1015,14 @@ pub trait TypeWalk {
959 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) 1015 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST)
960 } 1016 }
961 1017
962 /// Substitutes `Ty::Bound` vars with the given substitution. 1018 /// Substitutes `TyKind::Bound` vars with the given substitution.
963 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self 1019 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self
964 where 1020 where
965 Self: Sized, 1021 Self: Sized,
966 { 1022 {
967 self.walk_mut_binders( 1023 self.walk_mut_binders(
968 &mut |ty, binders| { 1024 &mut |ty, binders| {
969 if let &mut Ty::BoundVar(bound) = ty { 1025 if let &mut TyKind::BoundVar(bound) = &mut ty.0 {
970 if bound.debruijn >= binders { 1026 if bound.debruijn >= binders {
971 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1027 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
972 } 1028 }
@@ -977,17 +1033,17 @@ pub trait TypeWalk {
977 self 1033 self
978 } 1034 }
979 1035
980 /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. 1036 /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
981 fn shift_bound_vars(self, n: DebruijnIndex) -> Self 1037 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
982 where 1038 where
983 Self: Sized, 1039 Self: Sized,
984 { 1040 {
985 self.fold_binders( 1041 self.fold_binders(
986 &mut |ty, binders| match ty { 1042 &mut |ty, binders| match &ty.0 {
987 Ty::BoundVar(bound) if bound.debruijn >= binders => { 1043 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
988 Ty::BoundVar(bound.shifted_in_from(n)) 1044 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
989 } 1045 }
990 ty => ty, 1046 _ => ty,
991 }, 1047 },
992 DebruijnIndex::INNERMOST, 1048 DebruijnIndex::INNERMOST,
993 ) 1049 )
@@ -996,18 +1052,18 @@ pub trait TypeWalk {
996 1052
997impl TypeWalk for Ty { 1053impl TypeWalk for Ty {
998 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1054 fn walk(&self, f: &mut impl FnMut(&Ty)) {
999 match self { 1055 match self.interned(&Interner) {
1000 Ty::Alias(AliasTy::Projection(p_ty)) => { 1056 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1001 for t in p_ty.parameters.iter() { 1057 for t in p_ty.substitution.iter() {
1002 t.walk(f); 1058 t.walk(f);
1003 } 1059 }
1004 } 1060 }
1005 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1061 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1006 for t in o_ty.parameters.iter() { 1062 for t in o_ty.substitution.iter() {
1007 t.walk(f); 1063 t.walk(f);
1008 } 1064 }
1009 } 1065 }
1010 Ty::Dyn(predicates) => { 1066 TyKind::Dyn(predicates) => {
1011 for p in predicates.iter() { 1067 for p in predicates.iter() {
1012 p.walk(f); 1068 p.walk(f);
1013 } 1069 }
@@ -1028,17 +1084,17 @@ impl TypeWalk for Ty {
1028 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 1084 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1029 binders: DebruijnIndex, 1085 binders: DebruijnIndex,
1030 ) { 1086 ) {
1031 match self { 1087 match &mut self.0 {
1032 Ty::Alias(AliasTy::Projection(p_ty)) => { 1088 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1033 p_ty.parameters.walk_mut_binders(f, binders); 1089 p_ty.substitution.walk_mut_binders(f, binders);
1034 } 1090 }
1035 Ty::Dyn(predicates) => { 1091 TyKind::Dyn(predicates) => {
1036 for p in make_mut_slice(predicates) { 1092 for p in make_mut_slice(predicates) {
1037 p.walk_mut_binders(f, binders.shifted_in()); 1093 p.walk_mut_binders(f, binders.shifted_in());
1038 } 1094 }
1039 } 1095 }
1040 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1096 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1041 o_ty.parameters.walk_mut_binders(f, binders); 1097 o_ty.substitution.walk_mut_binders(f, binders);
1042 } 1098 }
1043 _ => { 1099 _ => {
1044 if let Some(substs) = self.substs_mut() { 1100 if let Some(substs) = self.substs_mut() {
@@ -1068,7 +1124,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> {
1068} 1124}
1069 1125
1070#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 1126#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1071pub enum OpaqueTyId { 1127pub enum ImplTraitId {
1072 ReturnTypeImplTrait(hir_def::FunctionId, u16), 1128 ReturnTypeImplTrait(hir_def::FunctionId, u16),
1073 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), 1129 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
1074} 1130}
@@ -1082,3 +1138,33 @@ pub struct ReturnTypeImplTraits {
1082pub(crate) struct ReturnTypeImplTrait { 1138pub(crate) struct ReturnTypeImplTrait {
1083 pub(crate) bounds: Binders<Vec<GenericPredicate>>, 1139 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1084} 1140}
1141
1142pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
1143 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
1144}
1145
1146pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
1147 salsa::InternKey::from_intern_id(id.0)
1148}
1149
1150pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
1151 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
1152}
1153
1154pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
1155 salsa::InternKey::from_intern_id(id.0)
1156}
1157
1158pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
1159 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
1160 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
1161 db.lookup_intern_type_param_id(interned_id)
1162}
1163
1164pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
1165 let interned_id = db.intern_type_param_id(id);
1166 PlaceholderIndex {
1167 ui: chalk_ir::UniverseIndex::ROOT,
1168 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
1169 }
1170}