diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/src/display.rs | 2 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 225 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 4 |
3 files changed, 134 insertions, 97 deletions
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs index 9f6d7be48..97a78ca25 100644 --- a/crates/hir/src/display.rs +++ b/crates/hir/src/display.rs | |||
@@ -217,7 +217,7 @@ impl HirDisplay for Variant { | |||
217 | 217 | ||
218 | impl HirDisplay for Type { | 218 | impl HirDisplay for Type { |
219 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | 219 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
220 | self.ty.value.hir_fmt(f) | 220 | self.ty.hir_fmt(f) |
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 746b4c942..6fa676c4d 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -56,9 +56,9 @@ use hir_ty::{ | |||
56 | primitive::UintTy, | 56 | primitive::UintTy, |
57 | to_assoc_type_id, | 57 | to_assoc_type_id, |
58 | traits::{FnTrait, Solution, SolutionVariables}, | 58 | traits::{FnTrait, Solution, SolutionVariables}, |
59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, Cast, DebruijnIndex, | 59 | AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, |
60 | InEnvironment, Interner, ProjectionTy, Scalar, Substitution, Ty, TyDefId, TyKind, | 60 | DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, |
61 | TyVariableKind, WhereClause, | 61 | Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause, |
62 | }; | 62 | }; |
63 | use itertools::Itertools; | 63 | use itertools::Itertools; |
64 | use rustc_hash::FxHashSet; | 64 | use rustc_hash::FxHashSet; |
@@ -154,11 +154,7 @@ impl Crate { | |||
154 | } | 154 | } |
155 | 155 | ||
156 | pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { | 156 | pub fn transitive_reverse_dependencies(self, db: &dyn HirDatabase) -> Vec<Crate> { |
157 | db.crate_graph() | 157 | db.crate_graph().transitive_rev_deps(self.id).into_iter().map(|id| Crate { id }).collect() |
158 | .transitive_reverse_dependencies(self.id) | ||
159 | .into_iter() | ||
160 | .map(|id| Crate { id }) | ||
161 | .collect() | ||
162 | } | 158 | } |
163 | 159 | ||
164 | pub fn root_module(self, db: &dyn HirDatabase) -> Module { | 160 | pub fn root_module(self, db: &dyn HirDatabase) -> Module { |
@@ -213,7 +209,7 @@ impl Crate { | |||
213 | Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), | 209 | Some(TokenTree::Leaf(Leaf::Literal(Literal{ref text, ..}))) => Some(text), |
214 | _ => None | 210 | _ => None |
215 | } | 211 | } |
216 | }).flat_map(|t| t).next(); | 212 | }).flatten().next(); |
217 | 213 | ||
218 | doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") | 214 | doc_url.map(|s| s.trim_matches('"').trim_end_matches('/').to_owned() + "/") |
219 | } | 215 | } |
@@ -851,17 +847,12 @@ impl Function { | |||
851 | .iter() | 847 | .iter() |
852 | .enumerate() | 848 | .enumerate() |
853 | .map(|(idx, type_ref)| { | 849 | .map(|(idx, type_ref)| { |
854 | let ty = Type { | 850 | let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) }; |
855 | krate, | ||
856 | ty: InEnvironment { | ||
857 | value: ctx.lower_ty(type_ref), | ||
858 | environment: environment.clone(), | ||
859 | }, | ||
860 | }; | ||
861 | Param { func: self, ty, idx } | 851 | Param { func: self, ty, idx } |
862 | }) | 852 | }) |
863 | .collect() | 853 | .collect() |
864 | } | 854 | } |
855 | |||
865 | pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> { | 856 | pub fn method_params(self, db: &dyn HirDatabase) -> Option<Vec<Param>> { |
866 | if self.self_param(db).is_none() { | 857 | if self.self_param(db).is_none() { |
867 | return None; | 858 | return None; |
@@ -919,7 +910,7 @@ impl From<hir_ty::Mutability> for Access { | |||
919 | } | 910 | } |
920 | } | 911 | } |
921 | 912 | ||
922 | #[derive(Debug)] | 913 | #[derive(Clone, Debug)] |
923 | pub struct Param { | 914 | pub struct Param { |
924 | func: Function, | 915 | func: Function, |
925 | /// The index in parameter list, including self parameter. | 916 | /// The index in parameter list, including self parameter. |
@@ -932,13 +923,25 @@ impl Param { | |||
932 | &self.ty | 923 | &self.ty |
933 | } | 924 | } |
934 | 925 | ||
926 | pub fn as_local(&self, db: &dyn HirDatabase) -> Local { | ||
927 | let parent = DefWithBodyId::FunctionId(self.func.into()); | ||
928 | let body = db.body(parent); | ||
929 | Local { parent, pat_id: body.params[self.idx] } | ||
930 | } | ||
931 | |||
935 | pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> { | 932 | pub fn pattern_source(&self, db: &dyn HirDatabase) -> Option<ast::Pat> { |
936 | let params = self.func.source(db)?.value.param_list()?; | 933 | self.source(db).and_then(|p| p.value.pat()) |
934 | } | ||
935 | |||
936 | pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Param>> { | ||
937 | let InFile { file_id, value } = self.func.source(db)?; | ||
938 | let params = value.param_list()?; | ||
937 | if params.self_param().is_some() { | 939 | if params.self_param().is_some() { |
938 | params.params().nth(self.idx.checked_sub(1)?)?.pat() | 940 | params.params().nth(self.idx.checked_sub(1)?) |
939 | } else { | 941 | } else { |
940 | params.params().nth(self.idx)?.pat() | 942 | params.params().nth(self.idx) |
941 | } | 943 | } |
944 | .map(|value| InFile { file_id, value }) | ||
942 | } | 945 | } |
943 | } | 946 | } |
944 | 947 | ||
@@ -970,6 +973,14 @@ impl SelfParam { | |||
970 | Access::Owned => "self", | 973 | Access::Owned => "self", |
971 | } | 974 | } |
972 | } | 975 | } |
976 | |||
977 | pub fn source(&self, db: &dyn HirDatabase) -> Option<InFile<ast::SelfParam>> { | ||
978 | let InFile { file_id, value } = Function::from(self.func).source(db)?; | ||
979 | value | ||
980 | .param_list() | ||
981 | .and_then(|params| params.self_param()) | ||
982 | .map(|value| InFile { file_id, value }) | ||
983 | } | ||
973 | } | 984 | } |
974 | 985 | ||
975 | impl HasVisibility for Function { | 986 | impl HasVisibility for Function { |
@@ -1127,6 +1138,14 @@ impl BuiltinType { | |||
1127 | } | 1138 | } |
1128 | 1139 | ||
1129 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1140 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
1141 | pub enum MacroKind { | ||
1142 | Declarative, | ||
1143 | ProcMacro, | ||
1144 | Derive, | ||
1145 | BuiltIn, | ||
1146 | } | ||
1147 | |||
1148 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
1130 | pub struct MacroDef { | 1149 | pub struct MacroDef { |
1131 | pub(crate) id: MacroDefId, | 1150 | pub(crate) id: MacroDefId, |
1132 | } | 1151 | } |
@@ -1150,15 +1169,15 @@ impl MacroDef { | |||
1150 | } | 1169 | } |
1151 | } | 1170 | } |
1152 | 1171 | ||
1153 | /// Indicate it is a proc-macro | 1172 | pub fn kind(&self) -> MacroKind { |
1154 | pub fn is_proc_macro(&self) -> bool { | 1173 | match self.id.kind { |
1155 | matches!(self.id.kind, MacroDefKind::ProcMacro(..)) | 1174 | MacroDefKind::Declarative(_) => MacroKind::Declarative, |
1156 | } | 1175 | MacroDefKind::BuiltIn(_, _) => MacroKind::BuiltIn, |
1157 | 1176 | MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive, | |
1158 | /// Indicate it is a derive macro | 1177 | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn, |
1159 | pub fn is_derive_macro(&self) -> bool { | 1178 | // FIXME might be a derive |
1160 | // FIXME: wrong for `ProcMacro` | 1179 | MacroDefKind::ProcMacro(_, _) => MacroKind::ProcMacro, |
1161 | matches!(self.id.kind, MacroDefKind::ProcMacro(..) | MacroDefKind::BuiltInDerive(..)) | 1180 | } |
1162 | } | 1181 | } |
1163 | } | 1182 | } |
1164 | 1183 | ||
@@ -1337,6 +1356,13 @@ impl Local { | |||
1337 | } | 1356 | } |
1338 | } | 1357 | } |
1339 | 1358 | ||
1359 | pub fn as_self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | ||
1360 | match self.parent { | ||
1361 | DefWithBodyId::FunctionId(func) if self.is_self(db) => Some(SelfParam { func }), | ||
1362 | _ => None, | ||
1363 | } | ||
1364 | } | ||
1365 | |||
1340 | // FIXME: why is this an option? It shouldn't be? | 1366 | // FIXME: why is this an option? It shouldn't be? |
1341 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 1367 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
1342 | let body = db.body(self.parent); | 1368 | let body = db.body(self.parent); |
@@ -1460,7 +1486,7 @@ impl TypeParam { | |||
1460 | pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { | 1486 | pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { |
1461 | db.generic_predicates_for_param(self.id) | 1487 | db.generic_predicates_for_param(self.id) |
1462 | .into_iter() | 1488 | .into_iter() |
1463 | .filter_map(|pred| match &pred.value { | 1489 | .filter_map(|pred| match &pred.skip_binders().skip_binders() { |
1464 | hir_ty::WhereClause::Implemented(trait_ref) => { | 1490 | hir_ty::WhereClause::Implemented(trait_ref) => { |
1465 | Some(Trait::from(trait_ref.hir_trait_id())) | 1491 | Some(Trait::from(trait_ref.hir_trait_id())) |
1466 | } | 1492 | } |
@@ -1540,8 +1566,8 @@ impl Impl { | |||
1540 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() | 1566 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() |
1541 | } | 1567 | } |
1542 | 1568 | ||
1543 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { | 1569 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> { |
1544 | let def_crates = match ty.value.def_crates(db, krate) { | 1570 | let def_crates = match ty.def_crates(db, krate) { |
1545 | Some(def_crates) => def_crates, | 1571 | Some(def_crates) => def_crates, |
1546 | None => return Vec::new(), | 1572 | None => return Vec::new(), |
1547 | }; | 1573 | }; |
@@ -1549,14 +1575,14 @@ impl Impl { | |||
1549 | let filter = |impl_def: &Impl| { | 1575 | let filter = |impl_def: &Impl| { |
1550 | let target_ty = impl_def.target_ty(db); | 1576 | let target_ty = impl_def.target_ty(db); |
1551 | let rref = target_ty.remove_ref(); | 1577 | let rref = target_ty.remove_ref(); |
1552 | ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) | 1578 | ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty)) |
1553 | }; | 1579 | }; |
1554 | 1580 | ||
1555 | let mut all = Vec::new(); | 1581 | let mut all = Vec::new(); |
1556 | def_crates.iter().for_each(|&id| { | 1582 | def_crates.iter().for_each(|&id| { |
1557 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | 1583 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) |
1558 | }); | 1584 | }); |
1559 | let fp = TyFingerprint::for_impl(&ty.value); | 1585 | let fp = TyFingerprint::for_impl(&ty); |
1560 | for id in def_crates | 1586 | for id in def_crates |
1561 | .iter() | 1587 | .iter() |
1562 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) | 1588 | .flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db)) |
@@ -1578,8 +1604,7 @@ impl Impl { | |||
1578 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { | 1604 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { |
1579 | let krate = trait_.module(db).krate(); | 1605 | let krate = trait_.module(db).krate(); |
1580 | let mut all = Vec::new(); | 1606 | let mut all = Vec::new(); |
1581 | for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter().chain(Some(krate)) | 1607 | for Crate { id } in krate.transitive_reverse_dependencies(db).into_iter() { |
1582 | { | ||
1583 | let impls = db.trait_impls_in_crate(id); | 1608 | let impls = db.trait_impls_in_crate(id); |
1584 | all.extend(impls.for_trait(trait_.id).map(Self::from)) | 1609 | all.extend(impls.for_trait(trait_.id).map(Self::from)) |
1585 | } | 1610 | } |
@@ -1643,7 +1668,8 @@ impl Impl { | |||
1643 | #[derive(Clone, PartialEq, Eq, Debug)] | 1668 | #[derive(Clone, PartialEq, Eq, Debug)] |
1644 | pub struct Type { | 1669 | pub struct Type { |
1645 | krate: CrateId, | 1670 | krate: CrateId, |
1646 | ty: InEnvironment<Ty>, | 1671 | env: Arc<TraitEnvironment>, |
1672 | ty: Ty, | ||
1647 | } | 1673 | } |
1648 | 1674 | ||
1649 | impl Type { | 1675 | impl Type { |
@@ -1663,14 +1689,14 @@ impl Type { | |||
1663 | ) -> Type { | 1689 | ) -> Type { |
1664 | let environment = | 1690 | let environment = |
1665 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | 1691 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); |
1666 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1692 | Type { krate, env: environment, ty } |
1667 | } | 1693 | } |
1668 | 1694 | ||
1669 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | 1695 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { |
1670 | let resolver = lexical_env.resolver(db.upcast()); | 1696 | let resolver = lexical_env.resolver(db.upcast()); |
1671 | let environment = | 1697 | let environment = |
1672 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | 1698 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); |
1673 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1699 | Type { krate, env: environment, ty } |
1674 | } | 1700 | } |
1675 | 1701 | ||
1676 | fn from_def( | 1702 | fn from_def( |
@@ -1684,29 +1710,29 @@ impl Type { | |||
1684 | } | 1710 | } |
1685 | 1711 | ||
1686 | pub fn is_unit(&self) -> bool { | 1712 | pub fn is_unit(&self) -> bool { |
1687 | matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) | 1713 | matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..)) |
1688 | } | 1714 | } |
1689 | pub fn is_bool(&self) -> bool { | 1715 | pub fn is_bool(&self) -> bool { |
1690 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) | 1716 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool)) |
1691 | } | 1717 | } |
1692 | 1718 | ||
1693 | pub fn is_mutable_reference(&self) -> bool { | 1719 | pub fn is_mutable_reference(&self) -> bool { |
1694 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) | 1720 | matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1695 | } | 1721 | } |
1696 | 1722 | ||
1697 | pub fn is_usize(&self) -> bool { | 1723 | pub fn is_usize(&self) -> bool { |
1698 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) | 1724 | matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize))) |
1699 | } | 1725 | } |
1700 | 1726 | ||
1701 | pub fn remove_ref(&self) -> Option<Type> { | 1727 | pub fn remove_ref(&self) -> Option<Type> { |
1702 | match &self.ty.value.interned(&Interner) { | 1728 | match &self.ty.interned(&Interner) { |
1703 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), | 1729 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1704 | _ => None, | 1730 | _ => None, |
1705 | } | 1731 | } |
1706 | } | 1732 | } |
1707 | 1733 | ||
1708 | pub fn is_unknown(&self) -> bool { | 1734 | pub fn is_unknown(&self) -> bool { |
1709 | self.ty.value.is_unknown() | 1735 | self.ty.is_unknown() |
1710 | } | 1736 | } |
1711 | 1737 | ||
1712 | /// Checks that particular type `ty` implements `std::future::Future`. | 1738 | /// Checks that particular type `ty` implements `std::future::Future`. |
@@ -1723,11 +1749,12 @@ impl Type { | |||
1723 | None => return false, | 1749 | None => return false, |
1724 | }; | 1750 | }; |
1725 | 1751 | ||
1726 | let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; | 1752 | let canonical_ty = |
1753 | Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) }; | ||
1727 | method_resolution::implements_trait( | 1754 | method_resolution::implements_trait( |
1728 | &canonical_ty, | 1755 | &canonical_ty, |
1729 | db, | 1756 | db, |
1730 | self.ty.environment.clone(), | 1757 | self.env.clone(), |
1731 | krate, | 1758 | krate, |
1732 | std_future_trait, | 1759 | std_future_trait, |
1733 | ) | 1760 | ) |
@@ -1745,11 +1772,12 @@ impl Type { | |||
1745 | None => return false, | 1772 | None => return false, |
1746 | }; | 1773 | }; |
1747 | 1774 | ||
1748 | let canonical_ty = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; | 1775 | let canonical_ty = |
1776 | Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) }; | ||
1749 | method_resolution::implements_trait_unique( | 1777 | method_resolution::implements_trait_unique( |
1750 | &canonical_ty, | 1778 | &canonical_ty, |
1751 | db, | 1779 | db, |
1752 | self.ty.environment.clone(), | 1780 | self.env.clone(), |
1753 | krate, | 1781 | krate, |
1754 | fnonce_trait, | 1782 | fnonce_trait, |
1755 | ) | 1783 | ) |
@@ -1759,17 +1787,14 @@ impl Type { | |||
1759 | let trait_ref = hir_ty::TraitRef { | 1787 | let trait_ref = hir_ty::TraitRef { |
1760 | trait_id: hir_ty::to_chalk_trait_id(trait_.id), | 1788 | trait_id: hir_ty::to_chalk_trait_id(trait_.id), |
1761 | substitution: Substitution::build_for_def(db, trait_.id) | 1789 | substitution: Substitution::build_for_def(db, trait_.id) |
1762 | .push(self.ty.value.clone()) | 1790 | .push(self.ty.clone()) |
1763 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1791 | .fill(args.iter().map(|t| t.ty.clone())) |
1764 | .build(), | 1792 | .build(), |
1765 | }; | 1793 | }; |
1766 | 1794 | ||
1767 | let goal = Canonical { | 1795 | let goal = Canonical { |
1768 | value: hir_ty::InEnvironment::new( | 1796 | value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), |
1769 | self.ty.environment.clone(), | 1797 | binders: CanonicalVarKinds::empty(&Interner), |
1770 | trait_ref.cast(&Interner), | ||
1771 | ), | ||
1772 | kinds: Arc::new([]), | ||
1773 | }; | 1798 | }; |
1774 | 1799 | ||
1775 | db.trait_solve(self.krate, goal).is_some() | 1800 | db.trait_solve(self.krate, goal).is_some() |
@@ -1783,12 +1808,12 @@ impl Type { | |||
1783 | alias: TypeAlias, | 1808 | alias: TypeAlias, |
1784 | ) -> Option<Type> { | 1809 | ) -> Option<Type> { |
1785 | let subst = Substitution::build_for_def(db, trait_.id) | 1810 | let subst = Substitution::build_for_def(db, trait_.id) |
1786 | .push(self.ty.value.clone()) | 1811 | .push(self.ty.clone()) |
1787 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1812 | .fill(args.iter().map(|t| t.ty.clone())) |
1788 | .build(); | 1813 | .build(); |
1789 | let goal = Canonical { | 1814 | let goal = Canonical::new( |
1790 | value: InEnvironment::new( | 1815 | InEnvironment::new( |
1791 | self.ty.environment.clone(), | 1816 | self.env.env.clone(), |
1792 | AliasEq { | 1817 | AliasEq { |
1793 | alias: AliasTy::Projection(ProjectionTy { | 1818 | alias: AliasTy::Projection(ProjectionTy { |
1794 | associated_ty_id: to_assoc_type_id(alias.id), | 1819 | associated_ty_id: to_assoc_type_id(alias.id), |
@@ -1799,8 +1824,8 @@ impl Type { | |||
1799 | } | 1824 | } |
1800 | .cast(&Interner), | 1825 | .cast(&Interner), |
1801 | ), | 1826 | ), |
1802 | kinds: Arc::new([TyVariableKind::General]), | 1827 | [TyVariableKind::General].iter().copied(), |
1803 | }; | 1828 | ); |
1804 | 1829 | ||
1805 | match db.trait_solve(self.krate, goal)? { | 1830 | match db.trait_solve(self.krate, goal)? { |
1806 | Solution::Unique(SolutionVariables(subst)) => { | 1831 | Solution::Unique(SolutionVariables(subst)) => { |
@@ -1820,22 +1845,22 @@ impl Type { | |||
1820 | } | 1845 | } |
1821 | 1846 | ||
1822 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1847 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1823 | let def = self.ty.value.callable_def(db); | 1848 | let def = self.ty.callable_def(db); |
1824 | 1849 | ||
1825 | let sig = self.ty.value.callable_sig(db)?; | 1850 | let sig = self.ty.callable_sig(db)?; |
1826 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) | 1851 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) |
1827 | } | 1852 | } |
1828 | 1853 | ||
1829 | pub fn is_closure(&self) -> bool { | 1854 | pub fn is_closure(&self) -> bool { |
1830 | matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) | 1855 | matches!(&self.ty.interned(&Interner), TyKind::Closure { .. }) |
1831 | } | 1856 | } |
1832 | 1857 | ||
1833 | pub fn is_fn(&self) -> bool { | 1858 | pub fn is_fn(&self) -> bool { |
1834 | matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) | 1859 | matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1835 | } | 1860 | } |
1836 | 1861 | ||
1837 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1862 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1838 | let adt_id = match self.ty.value.interned(&Interner) { | 1863 | let adt_id = match self.ty.interned(&Interner) { |
1839 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1864 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1840 | _ => return false, | 1865 | _ => return false, |
1841 | }; | 1866 | }; |
@@ -1848,11 +1873,11 @@ impl Type { | |||
1848 | } | 1873 | } |
1849 | 1874 | ||
1850 | pub fn is_raw_ptr(&self) -> bool { | 1875 | pub fn is_raw_ptr(&self) -> bool { |
1851 | matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) | 1876 | matches!(&self.ty.interned(&Interner), TyKind::Raw(..)) |
1852 | } | 1877 | } |
1853 | 1878 | ||
1854 | pub fn contains_unknown(&self) -> bool { | 1879 | pub fn contains_unknown(&self) -> bool { |
1855 | return go(&self.ty.value); | 1880 | return go(&self.ty); |
1856 | 1881 | ||
1857 | fn go(ty: &Ty) -> bool { | 1882 | fn go(ty: &Ty) -> bool { |
1858 | match ty.interned(&Interner) { | 1883 | match ty.interned(&Interner) { |
@@ -1884,7 +1909,7 @@ impl Type { | |||
1884 | } | 1909 | } |
1885 | 1910 | ||
1886 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1911 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1887 | let (variant_id, substs) = match self.ty.value.interned(&Interner) { | 1912 | let (variant_id, substs) = match self.ty.interned(&Interner) { |
1888 | &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), |
1889 | &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), |
1890 | _ => return Vec::new(), | 1915 | _ => return Vec::new(), |
@@ -1901,7 +1926,7 @@ impl Type { | |||
1901 | } | 1926 | } |
1902 | 1927 | ||
1903 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1928 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1904 | if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { | 1929 | if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) { |
1905 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1930 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1906 | } else { | 1931 | } else { |
1907 | Vec::new() | 1932 | Vec::new() |
@@ -1911,9 +1936,10 @@ impl Type { | |||
1911 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { | 1936 | pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { |
1912 | // There should be no inference vars in types passed here | 1937 | // There should be no inference vars in types passed here |
1913 | // FIXME check that? | 1938 | // FIXME check that? |
1914 | let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; | 1939 | let canonical = |
1915 | let environment = self.ty.environment.clone(); | 1940 | Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) }; |
1916 | let ty = InEnvironment { value: canonical, environment }; | 1941 | let environment = self.env.env.clone(); |
1942 | let ty = InEnvironment { goal: canonical, environment }; | ||
1917 | autoderef(db, Some(self.krate), ty) | 1943 | autoderef(db, Some(self.krate), ty) |
1918 | .map(|canonical| canonical.value) | 1944 | .map(|canonical| canonical.value) |
1919 | .map(move |ty| self.derived(ty)) | 1945 | .map(move |ty| self.derived(ty)) |
@@ -1927,10 +1953,10 @@ impl Type { | |||
1927 | krate: Crate, | 1953 | krate: Crate, |
1928 | mut callback: impl FnMut(AssocItem) -> Option<T>, | 1954 | mut callback: impl FnMut(AssocItem) -> Option<T>, |
1929 | ) -> Option<T> { | 1955 | ) -> Option<T> { |
1930 | for krate in self.ty.value.def_crates(db, krate.id)? { | 1956 | for krate in self.ty.def_crates(db, krate.id)? { |
1931 | let impls = db.inherent_impls_in_crate(krate); | 1957 | let impls = db.inherent_impls_in_crate(krate); |
1932 | 1958 | ||
1933 | for impl_def in impls.for_self_ty(&self.ty.value) { | 1959 | for impl_def in impls.for_self_ty(&self.ty) { |
1934 | for &item in db.impl_data(*impl_def).items.iter() { | 1960 | for &item in db.impl_data(*impl_def).items.iter() { |
1935 | if let Some(result) = callback(item.into()) { | 1961 | if let Some(result) = callback(item.into()) { |
1936 | return Some(result); | 1962 | return Some(result); |
@@ -1943,7 +1969,6 @@ impl Type { | |||
1943 | 1969 | ||
1944 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { | 1970 | pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { |
1945 | self.ty | 1971 | self.ty |
1946 | .value | ||
1947 | .strip_references() | 1972 | .strip_references() |
1948 | .substs() | 1973 | .substs() |
1949 | .into_iter() | 1974 | .into_iter() |
@@ -1962,9 +1987,10 @@ impl Type { | |||
1962 | // There should be no inference vars in types passed here | 1987 | // There should be no inference vars in types passed here |
1963 | // FIXME check that? | 1988 | // FIXME check that? |
1964 | // FIXME replace Unknown by bound vars here | 1989 | // FIXME replace Unknown by bound vars here |
1965 | let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; | 1990 | let canonical = |
1991 | Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) }; | ||
1966 | 1992 | ||
1967 | let env = self.ty.environment.clone(); | 1993 | let env = self.env.clone(); |
1968 | let krate = krate.id; | 1994 | let krate = krate.id; |
1969 | 1995 | ||
1970 | method_resolution::iterate_method_candidates( | 1996 | method_resolution::iterate_method_candidates( |
@@ -1994,9 +2020,10 @@ impl Type { | |||
1994 | // There should be no inference vars in types passed here | 2020 | // There should be no inference vars in types passed here |
1995 | // FIXME check that? | 2021 | // FIXME check that? |
1996 | // FIXME replace Unknown by bound vars here | 2022 | // FIXME replace Unknown by bound vars here |
1997 | let canonical = Canonical { value: self.ty.value.clone(), kinds: Arc::new([]) }; | 2023 | let canonical = |
2024 | Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) }; | ||
1998 | 2025 | ||
1999 | let env = self.ty.environment.clone(); | 2026 | let env = self.env.clone(); |
2000 | let krate = krate.id; | 2027 | let krate = krate.id; |
2001 | 2028 | ||
2002 | method_resolution::iterate_method_candidates( | 2029 | method_resolution::iterate_method_candidates( |
@@ -2013,18 +2040,18 @@ impl Type { | |||
2013 | } | 2040 | } |
2014 | 2041 | ||
2015 | pub fn as_adt(&self) -> Option<Adt> { | 2042 | pub fn as_adt(&self) -> Option<Adt> { |
2016 | let (adt, _subst) = self.ty.value.as_adt()?; | 2043 | let (adt, _subst) = self.ty.as_adt()?; |
2017 | Some(adt.into()) | 2044 | Some(adt.into()) |
2018 | } | 2045 | } |
2019 | 2046 | ||
2020 | pub fn as_dyn_trait(&self) -> Option<Trait> { | 2047 | pub fn as_dyn_trait(&self) -> Option<Trait> { |
2021 | self.ty.value.dyn_trait().map(Into::into) | 2048 | self.ty.dyn_trait().map(Into::into) |
2022 | } | 2049 | } |
2023 | 2050 | ||
2024 | pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { | 2051 | pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> { |
2025 | self.ty.value.impl_trait_bounds(db).map(|it| { | 2052 | self.ty.impl_trait_bounds(db).map(|it| { |
2026 | it.into_iter() | 2053 | it.into_iter() |
2027 | .filter_map(|pred| match pred { | 2054 | .filter_map(|pred| match pred.skip_binders() { |
2028 | hir_ty::WhereClause::Implemented(trait_ref) => { | 2055 | hir_ty::WhereClause::Implemented(trait_ref) => { |
2029 | Some(Trait::from(trait_ref.hir_trait_id())) | 2056 | Some(Trait::from(trait_ref.hir_trait_id())) |
2030 | } | 2057 | } |
@@ -2035,14 +2062,11 @@ impl Type { | |||
2035 | } | 2062 | } |
2036 | 2063 | ||
2037 | pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { | 2064 | pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> { |
2038 | self.ty.value.associated_type_parent_trait(db).map(Into::into) | 2065 | self.ty.associated_type_parent_trait(db).map(Into::into) |
2039 | } | 2066 | } |
2040 | 2067 | ||
2041 | fn derived(&self, ty: Ty) -> Type { | 2068 | fn derived(&self, ty: Ty) -> Type { |
2042 | Type { | 2069 | Type { krate: self.krate, env: self.env.clone(), ty } |
2043 | krate: self.krate, | ||
2044 | ty: InEnvironment { value: ty, environment: self.ty.environment.clone() }, | ||
2045 | } | ||
2046 | } | 2070 | } |
2047 | 2071 | ||
2048 | pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { | 2072 | pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) { |
@@ -2063,14 +2087,17 @@ impl Type { | |||
2063 | fn walk_bounds( | 2087 | fn walk_bounds( |
2064 | db: &dyn HirDatabase, | 2088 | db: &dyn HirDatabase, |
2065 | type_: &Type, | 2089 | type_: &Type, |
2066 | bounds: &[WhereClause], | 2090 | bounds: &[QuantifiedWhereClause], |
2067 | cb: &mut impl FnMut(Type), | 2091 | cb: &mut impl FnMut(Type), |
2068 | ) { | 2092 | ) { |
2069 | for pred in bounds { | 2093 | for pred in bounds { |
2070 | match pred { | 2094 | match pred.skip_binders() { |
2071 | WhereClause::Implemented(trait_ref) => { | 2095 | WhereClause::Implemented(trait_ref) => { |
2072 | cb(type_.clone()); | 2096 | cb(type_.clone()); |
2073 | walk_substs(db, type_, &trait_ref.substitution, cb); | 2097 | // 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) { | ||
2099 | walk_type(db, &type_.derived(ty.clone()), cb); | ||
2100 | } | ||
2074 | } | 2101 | } |
2075 | _ => (), | 2102 | _ => (), |
2076 | } | 2103 | } |
@@ -2078,7 +2105,7 @@ impl Type { | |||
2078 | } | 2105 | } |
2079 | 2106 | ||
2080 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2107 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
2081 | let ty = type_.ty.value.strip_references(); | 2108 | let ty = type_.ty.strip_references(); |
2082 | match ty.interned(&Interner) { | 2109 | match ty.interned(&Interner) { |
2083 | TyKind::Adt(..) => { | 2110 | TyKind::Adt(..) => { |
2084 | cb(type_.derived(ty.clone())); | 2111 | cb(type_.derived(ty.clone())); |
@@ -2106,7 +2133,12 @@ impl Type { | |||
2106 | } | 2133 | } |
2107 | } | 2134 | } |
2108 | TyKind::Dyn(bounds) => { | 2135 | TyKind::Dyn(bounds) => { |
2109 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 2136 | walk_bounds( |
2137 | db, | ||
2138 | &type_.derived(ty.clone()), | ||
2139 | bounds.bounds.skip_binders().interned(), | ||
2140 | cb, | ||
2141 | ); | ||
2110 | } | 2142 | } |
2111 | 2143 | ||
2112 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | 2144 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { |
@@ -2201,6 +2233,7 @@ pub enum ScopeDef { | |||
2201 | ImplSelfType(Impl), | 2233 | ImplSelfType(Impl), |
2202 | AdtSelfType(Adt), | 2234 | AdtSelfType(Adt), |
2203 | Local(Local), | 2235 | Local(Local), |
2236 | Label(Label), | ||
2204 | Unknown, | 2237 | Unknown, |
2205 | } | 2238 | } |
2206 | 2239 | ||
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 15651bb22..1198e3f0b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -839,6 +839,10 @@ impl<'a> SemanticsScope<'a> { | |||
839 | let parent = resolver.body_owner().unwrap(); | 839 | let parent = resolver.body_owner().unwrap(); |
840 | ScopeDef::Local(Local { parent, pat_id }) | 840 | ScopeDef::Local(Local { parent, pat_id }) |
841 | } | 841 | } |
842 | resolver::ScopeDef::Label(label_id) => { | ||
843 | let parent = resolver.body_owner().unwrap(); | ||
844 | ScopeDef::Label(Label { parent, label_id }) | ||
845 | } | ||
842 | }; | 846 | }; |
843 | f(name, def) | 847 | f(name, def) |
844 | }) | 848 | }) |