diff options
Diffstat (limited to 'crates/hir/src/lib.rs')
-rw-r--r-- | crates/hir/src/lib.rs | 192 |
1 files changed, 109 insertions, 83 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 05a60e158..0afc06906 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -44,6 +44,7 @@ use hir_def::{ | |||
44 | per_ns::PerNs, | 44 | per_ns::PerNs, |
45 | resolver::{HasResolver, Resolver}, | 45 | resolver::{HasResolver, Resolver}, |
46 | src::HasSource as _, | 46 | src::HasSource as _, |
47 | type_ref::TraitRef, | ||
47 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, | 48 | AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, |
48 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, | 49 | DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, |
49 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, | 50 | LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, |
@@ -51,14 +52,15 @@ use hir_def::{ | |||
51 | }; | 52 | }; |
52 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | 53 | use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; |
53 | use hir_ty::{ | 54 | use hir_ty::{ |
54 | autoderef, | 55 | autoderef, could_unify, |
55 | method_resolution::{self, TyFingerprint}, | 56 | method_resolution::{self, def_crates, TyFingerprint}, |
56 | primitive::UintTy, | 57 | primitive::UintTy, |
57 | to_assoc_type_id, | 58 | subst_prefix, |
58 | traits::{FnTrait, Solution, SolutionVariables}, | 59 | traits::FnTrait, |
59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, | 60 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, |
60 | DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, | 61 | DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution, |
61 | Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause, | 62 | TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, |
63 | WhereClause, | ||
62 | }; | 64 | }; |
63 | use itertools::Itertools; | 65 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 66 | use rustc_hash::FxHashSet; |
@@ -514,8 +516,8 @@ impl Field { | |||
514 | VariantDef::Union(it) => it.id.into(), | 516 | VariantDef::Union(it) => it.id.into(), |
515 | VariantDef::Variant(it) => it.parent.id.into(), | 517 | VariantDef::Variant(it) => it.parent.id.into(), |
516 | }; | 518 | }; |
517 | let substs = Substitution::type_params(db, generic_def_id); | 519 | let substs = TyBuilder::type_params_subst(db, generic_def_id); |
518 | let ty = db.field_types(var_id)[self.id].clone().subst(&substs); | 520 | let ty = db.field_types(var_id)[self.id].clone().substitute(&Interner, &substs); |
519 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) | 521 | Type::new(db, self.parent.module(db).id.krate(), var_id, ty) |
520 | } | 522 | } |
521 | 523 | ||
@@ -701,7 +703,7 @@ impl_from!(Struct, Union, Enum for Adt); | |||
701 | impl Adt { | 703 | impl Adt { |
702 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 704 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
703 | let subst = db.generic_defaults(self.into()); | 705 | let subst = db.generic_defaults(self.into()); |
704 | subst.iter().any(|ty| ty.value.is_unknown()) | 706 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
705 | } | 707 | } |
706 | 708 | ||
707 | /// Turns this ADT into a type. Any type parameters of the ADT will be | 709 | /// Turns this ADT into a type. Any type parameters of the ADT will be |
@@ -831,7 +833,7 @@ impl Function { | |||
831 | } | 833 | } |
832 | 834 | ||
833 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 835 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
834 | if !db.function_data(self.id).has_self_param { | 836 | if !db.function_data(self.id).has_self_param() { |
835 | return None; | 837 | return None; |
836 | } | 838 | } |
837 | Some(SelfParam { func: self.id }) | 839 | Some(SelfParam { func: self.id }) |
@@ -863,7 +865,7 @@ impl Function { | |||
863 | } | 865 | } |
864 | 866 | ||
865 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | 867 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { |
866 | db.function_data(self.id).qualifier.is_unsafe | 868 | db.function_data(self.id).is_unsafe() |
867 | } | 869 | } |
868 | 870 | ||
869 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 871 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
@@ -877,7 +879,7 @@ impl Function { | |||
877 | /// | 879 | /// |
878 | /// This is false in the case of required (not provided) trait methods. | 880 | /// This is false in the case of required (not provided) trait methods. |
879 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { | 881 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { |
880 | db.function_data(self.id).has_body | 882 | db.function_data(self.id).has_body() |
881 | } | 883 | } |
882 | 884 | ||
883 | /// A textual representation of the HIR of this function for debugging purposes. | 885 | /// A textual representation of the HIR of this function for debugging purposes. |
@@ -956,7 +958,7 @@ impl SelfParam { | |||
956 | func_data | 958 | func_data |
957 | .params | 959 | .params |
958 | .first() | 960 | .first() |
959 | .map(|param| match *param { | 961 | .map(|param| match &**param { |
960 | TypeRef::Reference(.., mutability) => match mutability { | 962 | TypeRef::Reference(.., mutability) => match mutability { |
961 | hir_def::type_ref::Mutability::Shared => Access::Shared, | 963 | hir_def::type_ref::Mutability::Shared => Access::Shared, |
962 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, | 964 | hir_def::type_ref::Mutability::Mut => Access::Exclusive, |
@@ -1010,7 +1012,7 @@ impl Const { | |||
1010 | } | 1012 | } |
1011 | 1013 | ||
1012 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { | 1014 | pub fn type_ref(self, db: &dyn HirDatabase) -> TypeRef { |
1013 | db.const_data(self.id).type_ref.clone() | 1015 | db.const_data(self.id).type_ref.as_ref().clone() |
1014 | } | 1016 | } |
1015 | } | 1017 | } |
1016 | 1018 | ||
@@ -1088,7 +1090,7 @@ pub struct TypeAlias { | |||
1088 | impl TypeAlias { | 1090 | impl TypeAlias { |
1089 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 1091 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
1090 | let subst = db.generic_defaults(self.id.into()); | 1092 | let subst = db.generic_defaults(self.id.into()); |
1091 | subst.iter().any(|ty| ty.value.is_unknown()) | 1093 | subst.iter().any(|ty| ty.skip_binders().is_unknown()) |
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 1096 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
@@ -1100,7 +1102,7 @@ impl TypeAlias { | |||
1100 | } | 1102 | } |
1101 | 1103 | ||
1102 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1104 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
1103 | db.type_alias_data(self.id).type_ref.clone() | 1105 | db.type_alias_data(self.id).type_ref.as_deref().cloned() |
1104 | } | 1106 | } |
1105 | 1107 | ||
1106 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 1108 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
@@ -1128,7 +1130,7 @@ pub struct BuiltinType { | |||
1128 | impl BuiltinType { | 1130 | impl BuiltinType { |
1129 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { | 1131 | pub fn ty(self, db: &dyn HirDatabase, module: Module) -> Type { |
1130 | let resolver = module.id.resolver(db.upcast()); | 1132 | let resolver = module.id.resolver(db.upcast()); |
1131 | Type::new_with_resolver(db, &resolver, Ty::builtin(self.inner)) | 1133 | Type::new_with_resolver(db, &resolver, TyBuilder::builtin(self.inner)) |
1132 | .expect("crate not present in resolver") | 1134 | .expect("crate not present in resolver") |
1133 | } | 1135 | } |
1134 | 1136 | ||
@@ -1501,8 +1503,8 @@ impl TypeParam { | |||
1501 | let resolver = self.id.parent.resolver(db.upcast()); | 1503 | let resolver = self.id.parent.resolver(db.upcast()); |
1502 | let krate = self.id.parent.module(db.upcast()).krate(); | 1504 | let krate = self.id.parent.module(db.upcast()).krate(); |
1503 | let ty = params.get(local_idx)?.clone(); | 1505 | let ty = params.get(local_idx)?.clone(); |
1504 | let subst = Substitution::type_params(db, self.id.parent); | 1506 | let subst = TyBuilder::type_params_subst(db, self.id.parent); |
1505 | let ty = ty.subst(&subst.prefix(local_idx)); | 1507 | let ty = ty.substitute(&Interner, &subst_prefix(&subst, local_idx)); |
1506 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) | 1508 | Some(Type::new_with_resolver_inner(db, krate, &resolver, ty)) |
1507 | } | 1509 | } |
1508 | } | 1510 | } |
@@ -1567,15 +1569,15 @@ impl Impl { | |||
1567 | } | 1569 | } |
1568 | 1570 | ||
1569 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { | 1571 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { |
1570 | let def_crates = match ty.def_crates(db, krate) { | 1572 | let def_crates = match def_crates(db, &ty, krate) { |
1571 | Some(def_crates) => def_crates, | 1573 | Some(def_crates) => def_crates, |
1572 | None => return Vec::new(), | 1574 | None => return Vec::new(), |
1573 | }; | 1575 | }; |
1574 | 1576 | ||
1575 | let filter = |impl_def: &Impl| { | 1577 | let filter = |impl_def: &Impl| { |
1576 | let target_ty = impl_def.target_ty(db); | 1578 | let self_ty = impl_def.self_ty(db); |
1577 | let rref = target_ty.remove_ref(); | 1579 | let rref = self_ty.remove_ref(); |
1578 | ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty)) | 1580 | ty.equals_ctor(rref.as_ref().map_or(&self_ty.ty, |it| &it.ty)) |
1579 | }; | 1581 | }; |
1580 | 1582 | ||
1581 | let mut all = Vec::new(); | 1583 | let mut all = Vec::new(); |
@@ -1613,16 +1615,16 @@ impl Impl { | |||
1613 | 1615 | ||
1614 | // FIXME: the return type is wrong. This should be a hir version of | 1616 | // FIXME: the return type is wrong. This should be a hir version of |
1615 | // `TraitRef` (ie, resolved `TypeRef`). | 1617 | // `TraitRef` (ie, resolved `TypeRef`). |
1616 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1618 | pub fn trait_(self, db: &dyn HirDatabase) -> Option<TraitRef> { |
1617 | db.impl_data(self.id).target_trait.clone() | 1619 | db.impl_data(self.id).target_trait.as_deref().cloned() |
1618 | } | 1620 | } |
1619 | 1621 | ||
1620 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { | 1622 | pub fn self_ty(self, db: &dyn HirDatabase) -> Type { |
1621 | let impl_data = db.impl_data(self.id); | 1623 | let impl_data = db.impl_data(self.id); |
1622 | let resolver = self.id.resolver(db.upcast()); | 1624 | let resolver = self.id.resolver(db.upcast()); |
1623 | let krate = self.id.lookup(db.upcast()).container.krate(); | 1625 | let krate = self.id.lookup(db.upcast()).container.krate(); |
1624 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1626 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
1625 | let ty = ctx.lower_ty(&impl_data.target_type); | 1627 | let ty = ctx.lower_ty(&impl_data.self_ty); |
1626 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1628 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1627 | } | 1629 | } |
1628 | 1630 | ||
@@ -1702,30 +1704,29 @@ impl Type { | |||
1702 | fn from_def( | 1704 | fn from_def( |
1703 | db: &dyn HirDatabase, | 1705 | db: &dyn HirDatabase, |
1704 | krate: CrateId, | 1706 | krate: CrateId, |
1705 | def: impl HasResolver + Into<TyDefId> + Into<GenericDefId>, | 1707 | def: impl HasResolver + Into<TyDefId>, |
1706 | ) -> Type { | 1708 | ) -> Type { |
1707 | let substs = Substitution::build_for_def(db, def).fill_with_unknown().build(); | 1709 | let ty = TyBuilder::def_ty(db, def.into()).fill_with_unknown().build(); |
1708 | let ty = db.ty(def.into()).subst(&substs); | ||
1709 | Type::new(db, krate, def, ty) | 1710 | Type::new(db, krate, def, ty) |
1710 | } | 1711 | } |
1711 | 1712 | ||
1712 | pub fn is_unit(&self) -> bool { | 1713 | pub fn is_unit(&self) -> bool { |
1713 | matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..)) | 1714 | matches!(self.ty.kind(&Interner), TyKind::Tuple(0, ..)) |
1714 | } | 1715 | } |
1715 | pub fn is_bool(&self) -> bool { | 1716 | pub fn is_bool(&self) -> bool { |
1716 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool)) | 1717 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Bool)) |
1717 | } | 1718 | } |
1718 | 1719 | ||
1719 | pub fn is_mutable_reference(&self) -> bool { | 1720 | pub fn is_mutable_reference(&self) -> bool { |
1720 | matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1721 | matches!(self.ty.kind(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1721 | } | 1722 | } |
1722 | 1723 | ||
1723 | pub fn is_usize(&self) -> bool { | 1724 | pub fn is_usize(&self) -> bool { |
1724 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | 1725 | matches!(self.ty.kind(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) |
1725 | } | 1726 | } |
1726 | 1727 | ||
1727 | pub fn remove_ref(&self) -> Option<Type> { | 1728 | pub fn remove_ref(&self) -> Option<Type> { |
1728 | match &self.ty.interned(&Interner) { | 1729 | match &self.ty.kind(&Interner) { |
1729 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1730 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1730 | _ => None, | 1731 | _ => None, |
1731 | } | 1732 | } |
@@ -1784,16 +1785,13 @@ impl Type { | |||
1784 | } | 1785 | } |
1785 | 1786 | ||
1786 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { | 1787 | pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { |
1787 | let trait_ref = hir_ty::TraitRef { | 1788 | let trait_ref = TyBuilder::trait_ref(db, trait_.id) |
1788 | trait_id: hir_ty::to_chalk_trait_id(trait_.id), | 1789 | .push(self.ty.clone()) |
1789 | substitution: Substitution::build_for_def(db, trait_.id) | 1790 | .fill(args.iter().map(|t| t.ty.clone())) |
1790 | .push(self.ty.clone()) | 1791 | .build(); |
1791 | .fill(args.iter().map(|t| t.ty.clone())) | ||
1792 | .build(), | ||
1793 | }; | ||
1794 | 1792 | ||
1795 | let goal = Canonical { | 1793 | let goal = Canonical { |
1796 | value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), | 1794 | value: hir_ty::InEnvironment::new(&self.env.env, trait_ref.cast(&Interner)), |
1797 | binders: CanonicalVarKinds::empty(&Interner), | 1795 | binders: CanonicalVarKinds::empty(&Interner), |
1798 | }; | 1796 | }; |
1799 | 1797 | ||
@@ -1803,22 +1801,18 @@ impl Type { | |||
1803 | pub fn normalize_trait_assoc_type( | 1801 | pub fn normalize_trait_assoc_type( |
1804 | &self, | 1802 | &self, |
1805 | db: &dyn HirDatabase, | 1803 | db: &dyn HirDatabase, |
1806 | trait_: Trait, | ||
1807 | args: &[Type], | 1804 | args: &[Type], |
1808 | alias: TypeAlias, | 1805 | alias: TypeAlias, |
1809 | ) -> Option<Type> { | 1806 | ) -> Option<Type> { |
1810 | let subst = Substitution::build_for_def(db, trait_.id) | 1807 | let projection = TyBuilder::assoc_type_projection(db, alias.id) |
1811 | .push(self.ty.clone()) | 1808 | .push(self.ty.clone()) |
1812 | .fill(args.iter().map(|t| t.ty.clone())) | 1809 | .fill(args.iter().map(|t| t.ty.clone())) |
1813 | .build(); | 1810 | .build(); |
1814 | let goal = Canonical::new( | 1811 | let goal = hir_ty::make_canonical( |
1815 | InEnvironment::new( | 1812 | InEnvironment::new( |
1816 | self.env.env.clone(), | 1813 | &self.env.env, |
1817 | AliasEq { | 1814 | AliasEq { |
1818 | alias: AliasTy::Projection(ProjectionTy { | 1815 | alias: AliasTy::Projection(projection), |
1819 | associated_ty_id: to_assoc_type_id(alias.id), | ||
1820 | substitution: subst, | ||
1821 | }), | ||
1822 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) | 1816 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) |
1823 | .intern(&Interner), | 1817 | .intern(&Interner), |
1824 | } | 1818 | } |
@@ -1828,9 +1822,12 @@ impl Type { | |||
1828 | ); | 1822 | ); |
1829 | 1823 | ||
1830 | match db.trait_solve(self.krate, goal)? { | 1824 | match db.trait_solve(self.krate, goal)? { |
1831 | Solution::Unique(SolutionVariables(subst)) => { | 1825 | Solution::Unique(s) => s |
1832 | subst.value.first().map(|ty| self.derived(ty.clone())) | 1826 | .value |
1833 | } | 1827 | .subst |
1828 | .interned() | ||
1829 | .first() | ||
1830 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | ||
1834 | Solution::Ambig(_) => None, | 1831 | Solution::Ambig(_) => None, |
1835 | } | 1832 | } |
1836 | } | 1833 | } |
@@ -1852,15 +1849,15 @@ impl Type { | |||
1852 | } | 1849 | } |
1853 | 1850 | ||
1854 | pub fn is_closure(&self) -> bool { | 1851 | pub fn is_closure(&self) -> bool { |
1855 | matches!(&self.ty.interned(&Interner), TyKind::Closure { .. }) | 1852 | matches!(&self.ty.kind(&Interner), TyKind::Closure { .. }) |
1856 | } | 1853 | } |
1857 | 1854 | ||
1858 | pub fn is_fn(&self) -> bool { | 1855 | pub fn is_fn(&self) -> bool { |
1859 | matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) | 1856 | matches!(&self.ty.kind(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1860 | } | 1857 | } |
1861 | 1858 | ||
1862 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1859 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1863 | let adt_id = match self.ty.interned(&Interner) { | 1860 | let adt_id = match self.ty.kind(&Interner) { |
1864 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1861 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1865 | _ => return false, | 1862 | _ => return false, |
1866 | }; | 1863 | }; |
@@ -1873,27 +1870,30 @@ impl Type { | |||
1873 | } | 1870 | } |
1874 | 1871 | ||
1875 | pub fn is_raw_ptr(&self) -> bool { | 1872 | pub fn is_raw_ptr(&self) -> bool { |
1876 | matches!(&self.ty.interned(&Interner), TyKind::Raw(..)) | 1873 | matches!(&self.ty.kind(&Interner), TyKind::Raw(..)) |
1877 | } | 1874 | } |
1878 | 1875 | ||
1879 | pub fn contains_unknown(&self) -> bool { | 1876 | pub fn contains_unknown(&self) -> bool { |
1880 | return go(&self.ty); | 1877 | return go(&self.ty); |
1881 | 1878 | ||
1882 | fn go(ty: &Ty) -> bool { | 1879 | fn go(ty: &Ty) -> bool { |
1883 | match ty.interned(&Interner) { | 1880 | match ty.kind(&Interner) { |
1884 | TyKind::Unknown => true, | 1881 | TyKind::Error => true, |
1885 | 1882 | ||
1886 | TyKind::Adt(_, substs) | 1883 | TyKind::Adt(_, substs) |
1887 | | TyKind::AssociatedType(_, substs) | 1884 | | TyKind::AssociatedType(_, substs) |
1888 | | TyKind::Tuple(_, substs) | 1885 | | TyKind::Tuple(_, substs) |
1889 | | TyKind::OpaqueType(_, substs) | 1886 | | TyKind::OpaqueType(_, substs) |
1890 | | TyKind::FnDef(_, substs) | 1887 | | TyKind::FnDef(_, substs) |
1891 | | TyKind::Closure(_, substs) => substs.iter().any(go), | 1888 | | TyKind::Closure(_, substs) => { |
1892 | 1889 | substs.iter(&Interner).filter_map(|a| a.ty(&Interner)).any(go) | |
1893 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | ||
1894 | go(ty) | ||
1895 | } | 1890 | } |
1896 | 1891 | ||
1892 | TyKind::Array(ty, _) | ||
1893 | | TyKind::Slice(ty) | ||
1894 | | TyKind::Raw(_, ty) | ||
1895 | | TyKind::Ref(_, _, ty) => go(ty), | ||
1896 | |||
1897 | TyKind::Scalar(_) | 1897 | TyKind::Scalar(_) |
1898 | | TyKind::Str | 1898 | | TyKind::Str |
1899 | | TyKind::Never | 1899 | | TyKind::Never |
@@ -1903,13 +1903,13 @@ impl Type { | |||
1903 | | TyKind::Dyn(_) | 1903 | | TyKind::Dyn(_) |
1904 | | TyKind::Function(_) | 1904 | | TyKind::Function(_) |
1905 | | TyKind::Alias(_) | 1905 | | TyKind::Alias(_) |
1906 | | TyKind::ForeignType(_) => false, | 1906 | | TyKind::Foreign(_) => false, |
1907 | } | 1907 | } |
1908 | } | 1908 | } |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1912 | let (variant_id, substs) = match self.ty.interned(&Interner) { | 1912 | let (variant_id, substs) = match self.ty.kind(&Interner) { |
1913 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1913 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), |
1914 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), | 1914 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), |
1915 | _ => return Vec::new(), | 1915 | _ => return Vec::new(), |
@@ -1919,15 +1919,18 @@ impl Type { | |||
1919 | .iter() | 1919 | .iter() |
1920 | .map(|(local_id, ty)| { | 1920 | .map(|(local_id, ty)| { |
1921 | let def = Field { parent: variant_id.into(), id: local_id }; | 1921 | let def = Field { parent: variant_id.into(), id: local_id }; |
1922 | let ty = ty.clone().subst(substs); | 1922 | let ty = ty.clone().substitute(&Interner, substs); |
1923 | (def, self.derived(ty)) | 1923 | (def, self.derived(ty)) |
1924 | }) | 1924 | }) |
1925 | .collect() | 1925 | .collect() |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1929 | if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) { | 1929 | if let TyKind::Tuple(_, substs) = &self.ty.kind(&Interner) { |
1930 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1930 | substs |
1931 | .iter(&Interner) | ||
1932 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())) | ||
1933 | .collect() | ||
1931 | } else { | 1934 | } else { |
1932 | Vec::new() | 1935 | Vec::new() |
1933 | } | 1936 | } |
@@ -1953,7 +1956,7 @@ impl Type { | |||
1953 | krate: Crate, | 1956 | krate: Crate, |
1954 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 1957 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1955 | ) -> Option<T> { | 1958 | ) -> Option<T> { |
1956 | for krate in self.ty.def_crates(db, krate.id)? { | 1959 | for krate in def_crates(db, &self.ty, krate.id)? { |
1957 | let impls = db.inherent_impls_in_crate(krate); | 1960 | let impls = db.inherent_impls_in_crate(krate); |
1958 | 1961 | ||
1959 | for impl_def in impls.for_self_ty(&self.ty) { | 1962 | for impl_def in impls.for_self_ty(&self.ty) { |
@@ -1970,10 +1973,11 @@ impl Type { | |||
1970 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1973 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1971 | self.ty | 1974 | self.ty |
1972 | .strip_references() | 1975 | .strip_references() |
1973 | .substs() | 1976 | .as_adt() |
1974 | .into_iter() | 1977 | .into_iter() |
1975 | .flat_map(|substs| substs.iter()) | 1978 | .flat_map(|(_, substs)| substs.iter(&Interner)) |
1976 | .map(move |ty| self.derived(ty.clone())) | 1979 | .filter_map(|arg| arg.ty(&Interner).cloned()) |
1980 | .map(move |ty| self.derived(ty)) | ||
1977 | } | 1981 | } |
1978 | 1982 | ||
1979 | pub fn iterate_method_candidates<T>( | 1983 | pub fn iterate_method_candidates<T>( |
@@ -2079,7 +2083,7 @@ impl Type { | |||
2079 | substs: &Substitution, | 2083 | substs: &Substitution, |
2080 | cb: &mut impl FnMut(Type), | 2084 | cb: &mut impl FnMut(Type), |
2081 | ) { | 2085 | ) { |
2082 | for ty in substs.iter() { | 2086 | for ty in substs.iter(&Interner).filter_map(|a| a.ty(&Interner)) { |
2083 | walk_type(db, &type_.derived(ty.clone()), cb); | 2087 | walk_type(db, &type_.derived(ty.clone()), cb); |
2084 | } | 2088 | } |
2085 | } | 2089 | } |
@@ -2095,7 +2099,12 @@ impl Type { | |||
2095 | WhereClause::Implemented(trait_ref) => { | 2099 | WhereClause::Implemented(trait_ref) => { |
2096 | cb(type_.clone()); | 2100 | cb(type_.clone()); |
2097 | // skip the self type. it's likely the type we just got the bounds from | 2101 | // skip the self type. it's likely the type we just got the bounds from |
2098 | for ty in trait_ref.substitution.iter().skip(1) { | 2102 | for ty in trait_ref |
2103 | .substitution | ||
2104 | .iter(&Interner) | ||
2105 | .skip(1) | ||
2106 | .filter_map(|a| a.ty(&Interner)) | ||
2107 | { | ||
2099 | walk_type(db, &type_.derived(ty.clone()), cb); | 2108 | walk_type(db, &type_.derived(ty.clone()), cb); |
2100 | } | 2109 | } |
2101 | } | 2110 | } |
@@ -2106,19 +2115,23 @@ impl Type { | |||
2106 | 2115 | ||
2107 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2116 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
2108 | let ty = type_.ty.strip_references(); | 2117 | let ty = type_.ty.strip_references(); |
2109 | match ty.interned(&Interner) { | 2118 | match ty.kind(&Interner) { |
2110 | TyKind::Adt(..) => { | 2119 | TyKind::Adt(_, substs) => { |
2111 | cb(type_.derived(ty.clone())); | 2120 | cb(type_.derived(ty.clone())); |
2121 | walk_substs(db, type_, &substs, cb); | ||
2112 | } | 2122 | } |
2113 | TyKind::AssociatedType(..) => { | 2123 | TyKind::AssociatedType(_, substs) => { |
2114 | if let Some(_) = ty.associated_type_parent_trait(db) { | 2124 | if let Some(_) = ty.associated_type_parent_trait(db) { |
2115 | cb(type_.derived(ty.clone())); | 2125 | cb(type_.derived(ty.clone())); |
2116 | } | 2126 | } |
2127 | walk_substs(db, type_, &substs, cb); | ||
2117 | } | 2128 | } |
2118 | TyKind::OpaqueType(..) => { | 2129 | TyKind::OpaqueType(_, subst) => { |
2119 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2130 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
2120 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2131 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
2121 | } | 2132 | } |
2133 | |||
2134 | walk_substs(db, type_, subst, cb); | ||
2122 | } | 2135 | } |
2123 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { | 2136 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
2124 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2137 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
@@ -2141,19 +2154,32 @@ impl Type { | |||
2141 | ); | 2154 | ); |
2142 | } | 2155 | } |
2143 | 2156 | ||
2144 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | 2157 | TyKind::Ref(_, _, ty) |
2158 | | TyKind::Raw(_, ty) | ||
2159 | | TyKind::Array(ty, _) | ||
2160 | | TyKind::Slice(ty) => { | ||
2145 | walk_type(db, &type_.derived(ty.clone()), cb); | 2161 | walk_type(db, &type_.derived(ty.clone()), cb); |
2146 | } | 2162 | } |
2147 | 2163 | ||
2164 | TyKind::FnDef(_, substs) | ||
2165 | | TyKind::Tuple(_, substs) | ||
2166 | | TyKind::Closure(.., substs) => { | ||
2167 | walk_substs(db, type_, &substs, cb); | ||
2168 | } | ||
2169 | TyKind::Function(hir_ty::FnPointer { substitution, .. }) => { | ||
2170 | walk_substs(db, type_, &substitution.0, cb); | ||
2171 | } | ||
2172 | |||
2148 | _ => {} | 2173 | _ => {} |
2149 | } | 2174 | } |
2150 | if let Some(substs) = ty.substs() { | ||
2151 | walk_substs(db, type_, &substs, cb); | ||
2152 | } | ||
2153 | } | 2175 | } |
2154 | 2176 | ||
2155 | walk_type(db, self, &mut cb); | 2177 | walk_type(db, self, &mut cb); |
2156 | } | 2178 | } |
2179 | |||
2180 | pub fn could_unify_with(&self, other: &Type) -> bool { | ||
2181 | could_unify(&self.ty, &other.ty) | ||
2182 | } | ||
2157 | } | 2183 | } |
2158 | 2184 | ||
2159 | // FIXME: closures | 2185 | // FIXME: closures |