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