diff options
Diffstat (limited to 'crates/hir')
-rw-r--r-- | crates/hir/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 174 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 8 | ||||
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 22 | ||||
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 5 |
5 files changed, 139 insertions, 71 deletions
diff --git a/crates/hir/Cargo.toml b/crates/hir/Cargo.toml index d4ea7327e..55e9c3f0c 100644 --- a/crates/hir/Cargo.toml +++ b/crates/hir/Cargo.toml | |||
@@ -15,6 +15,7 @@ rustc-hash = "1.1.0" | |||
15 | either = "1.5.3" | 15 | either = "1.5.3" |
16 | arrayvec = "0.5.1" | 16 | arrayvec = "0.5.1" |
17 | itertools = "0.10.0" | 17 | itertools = "0.10.0" |
18 | smallvec = "1.4.0" | ||
18 | 19 | ||
19 | stdx = { path = "../stdx", version = "0.0.0" } | 20 | stdx = { path = "../stdx", version = "0.0.0" } |
20 | syntax = { path = "../syntax", version = "0.0.0" } | 21 | syntax = { path = "../syntax", version = "0.0.0" } |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 58adc8fd3..c5161dadd 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -51,11 +51,12 @@ use hir_expand::{diagnostics::DiagnosticSink, name::name, MacroDefKind}; | |||
51 | use hir_ty::{ | 51 | use hir_ty::{ |
52 | autoderef, | 52 | autoderef, |
53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, | 53 | display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, |
54 | method_resolution, | 54 | method_resolution::{self, TyFingerprint}, |
55 | to_assoc_type_id, | ||
55 | traits::{FnTrait, Solution, SolutionVariables}, | 56 | traits::{FnTrait, Solution, SolutionVariables}, |
56 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, | 57 | AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, |
57 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, | 58 | InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, Ty, |
58 | Ty, TyDefId, TyVariableKind, | 59 | TyDefId, TyKind, TyVariableKind, |
59 | }; | 60 | }; |
60 | use rustc_hash::FxHashSet; | 61 | use rustc_hash::FxHashSet; |
61 | use stdx::{format_to, impl_from}; | 62 | use stdx::{format_to, impl_from}; |
@@ -266,8 +267,7 @@ impl ModuleDef { | |||
266 | } | 267 | } |
267 | 268 | ||
268 | pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { | 269 | pub fn canonical_path(&self, db: &dyn HirDatabase) -> Option<String> { |
269 | let mut segments = Vec::new(); | 270 | let mut segments = vec![self.name(db)?.to_string()]; |
270 | segments.push(self.name(db)?.to_string()); | ||
271 | for m in self.module(db)?.path_to_root(db) { | 271 | for m in self.module(db)?.path_to_root(db) { |
272 | segments.extend(m.name(db).map(|it| it.to_string())) | 272 | segments.extend(m.name(db).map(|it| it.to_string())) |
273 | } | 273 | } |
@@ -677,7 +677,7 @@ impl_from!(Struct, Union, Enum for Adt); | |||
677 | impl Adt { | 677 | impl Adt { |
678 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 678 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
679 | let subst = db.generic_defaults(self.into()); | 679 | let subst = db.generic_defaults(self.into()); |
680 | subst.iter().any(|ty| &ty.value == &Ty::Unknown) | 680 | subst.iter().any(|ty| ty.value.is_unknown()) |
681 | } | 681 | } |
682 | 682 | ||
683 | /// Turns this ADT into a type. Any type parameters of the ADT will be | 683 | /// Turns this ADT into a type. Any type parameters of the ADT will be |
@@ -696,8 +696,8 @@ impl Adt { | |||
696 | } | 696 | } |
697 | } | 697 | } |
698 | 698 | ||
699 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 699 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
700 | Some(self.module(db).krate()) | 700 | self.module(db).krate() |
701 | } | 701 | } |
702 | 702 | ||
703 | pub fn name(self, db: &dyn HirDatabase) -> Name { | 703 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
@@ -802,7 +802,7 @@ impl Function { | |||
802 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); | 802 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); |
803 | let ret_type = &db.function_data(self.id).ret_type; | 803 | let ret_type = &db.function_data(self.id).ret_type; |
804 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 804 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
805 | let ty = Ty::from_hir_ext(&ctx, ret_type).0; | 805 | let ty = ctx.lower_ty(ret_type); |
806 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 806 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
807 | } | 807 | } |
808 | 808 | ||
@@ -817,7 +817,7 @@ impl Function { | |||
817 | let resolver = self.id.resolver(db.upcast()); | 817 | let resolver = self.id.resolver(db.upcast()); |
818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); | 818 | let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate(); |
819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 819 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
820 | let environment = TraitEnvironment::lower(db, &resolver); | 820 | let environment = db.trait_environment(self.id.into()); |
821 | db.function_data(self.id) | 821 | db.function_data(self.id) |
822 | .params | 822 | .params |
823 | .iter() | 823 | .iter() |
@@ -825,7 +825,7 @@ impl Function { | |||
825 | let ty = Type { | 825 | let ty = Type { |
826 | krate, | 826 | krate, |
827 | ty: InEnvironment { | 827 | ty: InEnvironment { |
828 | value: Ty::from_hir_ext(&ctx, type_ref).0, | 828 | value: ctx.lower_ty(type_ref), |
829 | environment: environment.clone(), | 829 | environment: environment.clone(), |
830 | }, | 830 | }, |
831 | }; | 831 | }; |
@@ -1012,15 +1012,15 @@ pub struct TypeAlias { | |||
1012 | impl TypeAlias { | 1012 | impl TypeAlias { |
1013 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { | 1013 | pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { |
1014 | let subst = db.generic_defaults(self.id.into()); | 1014 | let subst = db.generic_defaults(self.id.into()); |
1015 | subst.iter().any(|ty| &ty.value == &Ty::Unknown) | 1015 | subst.iter().any(|ty| ty.value.is_unknown()) |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | pub fn module(self, db: &dyn HirDatabase) -> Module { | 1018 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } | 1019 | Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> { | 1022 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
1023 | Some(self.module(db).krate()) | 1023 | self.module(db).krate() |
1024 | } | 1024 | } |
1025 | 1025 | ||
1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1026 | pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
@@ -1384,7 +1384,7 @@ impl TypeParam { | |||
1384 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | 1384 | pub fn ty(self, db: &dyn HirDatabase) -> Type { |
1385 | let resolver = self.id.parent.resolver(db.upcast()); | 1385 | let resolver = self.id.parent.resolver(db.upcast()); |
1386 | let krate = self.id.parent.module(db.upcast()).krate(); | 1386 | let krate = self.id.parent.module(db.upcast()).krate(); |
1387 | let ty = Ty::Placeholder(self.id); | 1387 | let ty = TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id)).intern(&Interner); |
1388 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1388 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1389 | } | 1389 | } |
1390 | 1390 | ||
@@ -1483,9 +1483,44 @@ impl Impl { | |||
1483 | 1483 | ||
1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() | 1484 | inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect() |
1485 | } | 1485 | } |
1486 | pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl> { | 1486 | |
1487 | let impls = db.trait_impls_in_crate(krate.id); | 1487 | pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> { |
1488 | impls.for_trait(trait_.id).map(Self::from).collect() | 1488 | let def_crates = match ty.value.def_crates(db, krate) { |
1489 | Some(def_crates) => def_crates, | ||
1490 | None => return Vec::new(), | ||
1491 | }; | ||
1492 | |||
1493 | let filter = |impl_def: &Impl| { | ||
1494 | let target_ty = impl_def.target_ty(db); | ||
1495 | let rref = target_ty.remove_ref(); | ||
1496 | ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value)) | ||
1497 | }; | ||
1498 | |||
1499 | let mut all = Vec::new(); | ||
1500 | def_crates.into_iter().for_each(|id| { | ||
1501 | all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter)) | ||
1502 | }); | ||
1503 | let fp = TyFingerprint::for_impl(&ty.value); | ||
1504 | for id in db.crate_graph().iter() { | ||
1505 | match fp { | ||
1506 | Some(fp) => all.extend( | ||
1507 | db.trait_impls_in_crate(id).for_self_ty(fp).map(Self::from).filter(filter), | ||
1508 | ), | ||
1509 | None => all | ||
1510 | .extend(db.trait_impls_in_crate(id).all_impls().map(Self::from).filter(filter)), | ||
1511 | } | ||
1512 | } | ||
1513 | all | ||
1514 | } | ||
1515 | |||
1516 | pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> { | ||
1517 | let krate = trait_.module(db).krate(); | ||
1518 | let mut all = Vec::new(); | ||
1519 | for Crate { id } in krate.reverse_dependencies(db).into_iter().chain(Some(krate)) { | ||
1520 | let impls = db.trait_impls_in_crate(id); | ||
1521 | all.extend(impls.for_trait(trait_.id).map(Self::from)) | ||
1522 | } | ||
1523 | all | ||
1489 | } | 1524 | } |
1490 | 1525 | ||
1491 | // FIXME: the return type is wrong. This should be a hir version of | 1526 | // FIXME: the return type is wrong. This should be a hir version of |
@@ -1499,7 +1534,7 @@ impl Impl { | |||
1499 | let resolver = self.id.resolver(db.upcast()); | 1534 | let resolver = self.id.resolver(db.upcast()); |
1500 | let krate = self.id.lookup(db.upcast()).container.krate(); | 1535 | let krate = self.id.lookup(db.upcast()).container.krate(); |
1501 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1536 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
1502 | let ty = Ty::from_hir(&ctx, &impl_data.target_type); | 1537 | let ty = ctx.lower_ty(&impl_data.target_type); |
1503 | Type::new_with_resolver_inner(db, krate, &resolver, ty) | 1538 | Type::new_with_resolver_inner(db, krate, &resolver, ty) |
1504 | } | 1539 | } |
1505 | 1540 | ||
@@ -1563,13 +1598,15 @@ impl Type { | |||
1563 | resolver: &Resolver, | 1598 | resolver: &Resolver, |
1564 | ty: Ty, | 1599 | ty: Ty, |
1565 | ) -> Type { | 1600 | ) -> Type { |
1566 | let environment = TraitEnvironment::lower(db, &resolver); | 1601 | let environment = |
1602 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1567 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1603 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1568 | } | 1604 | } |
1569 | 1605 | ||
1570 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { | 1606 | fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type { |
1571 | let resolver = lexical_env.resolver(db.upcast()); | 1607 | let resolver = lexical_env.resolver(db.upcast()); |
1572 | let environment = TraitEnvironment::lower(db, &resolver); | 1608 | let environment = |
1609 | resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d)); | ||
1573 | Type { krate, ty: InEnvironment { value: ty, environment } } | 1610 | Type { krate, ty: InEnvironment { value: ty, environment } } |
1574 | } | 1611 | } |
1575 | 1612 | ||
@@ -1584,25 +1621,25 @@ impl Type { | |||
1584 | } | 1621 | } |
1585 | 1622 | ||
1586 | pub fn is_unit(&self) -> bool { | 1623 | pub fn is_unit(&self) -> bool { |
1587 | matches!(self.ty.value, Ty::Tuple(0, ..)) | 1624 | matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..)) |
1588 | } | 1625 | } |
1589 | pub fn is_bool(&self) -> bool { | 1626 | pub fn is_bool(&self) -> bool { |
1590 | matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) | 1627 | matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool)) |
1591 | } | 1628 | } |
1592 | 1629 | ||
1593 | pub fn is_mutable_reference(&self) -> bool { | 1630 | pub fn is_mutable_reference(&self) -> bool { |
1594 | matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..)) | 1631 | matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..)) |
1595 | } | 1632 | } |
1596 | 1633 | ||
1597 | pub fn remove_ref(&self) -> Option<Type> { | 1634 | pub fn remove_ref(&self) -> Option<Type> { |
1598 | match &self.ty.value { | 1635 | match &self.ty.value.interned(&Interner) { |
1599 | Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())), | 1636 | TyKind::Ref(.., ty) => Some(self.derived(ty.clone())), |
1600 | _ => None, | 1637 | _ => None, |
1601 | } | 1638 | } |
1602 | } | 1639 | } |
1603 | 1640 | ||
1604 | pub fn is_unknown(&self) -> bool { | 1641 | pub fn is_unknown(&self) -> bool { |
1605 | matches!(self.ty.value, Ty::Unknown) | 1642 | self.ty.value.is_unknown() |
1606 | } | 1643 | } |
1607 | 1644 | ||
1608 | /// Checks that particular type `ty` implements `std::future::Future`. | 1645 | /// Checks that particular type `ty` implements `std::future::Future`. |
@@ -1683,8 +1720,11 @@ impl Type { | |||
1683 | .fill(args.iter().map(|t| t.ty.value.clone())) | 1720 | .fill(args.iter().map(|t| t.ty.value.clone())) |
1684 | .build(); | 1721 | .build(); |
1685 | let predicate = ProjectionPredicate { | 1722 | let predicate = ProjectionPredicate { |
1686 | projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, | 1723 | projection_ty: ProjectionTy { |
1687 | ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), | 1724 | associated_ty_id: to_assoc_type_id(alias.id), |
1725 | substitution: subst, | ||
1726 | }, | ||
1727 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner), | ||
1688 | }; | 1728 | }; |
1689 | let goal = Canonical { | 1729 | let goal = Canonical { |
1690 | value: InEnvironment::new( | 1730 | value: InEnvironment::new( |
@@ -1712,26 +1752,23 @@ impl Type { | |||
1712 | } | 1752 | } |
1713 | 1753 | ||
1714 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { | 1754 | pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { |
1715 | let def = match self.ty.value { | 1755 | let def = self.ty.value.callable_def(db); |
1716 | Ty::FnDef(def, _) => Some(def), | ||
1717 | _ => None, | ||
1718 | }; | ||
1719 | 1756 | ||
1720 | let sig = self.ty.value.callable_sig(db)?; | 1757 | let sig = self.ty.value.callable_sig(db)?; |
1721 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) | 1758 | Some(Callable { ty: self.clone(), sig, def, is_bound_method: false }) |
1722 | } | 1759 | } |
1723 | 1760 | ||
1724 | pub fn is_closure(&self) -> bool { | 1761 | pub fn is_closure(&self) -> bool { |
1725 | matches!(&self.ty.value, Ty::Closure { .. }) | 1762 | matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. }) |
1726 | } | 1763 | } |
1727 | 1764 | ||
1728 | pub fn is_fn(&self) -> bool { | 1765 | pub fn is_fn(&self) -> bool { |
1729 | matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) | 1766 | matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. }) |
1730 | } | 1767 | } |
1731 | 1768 | ||
1732 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { | 1769 | pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { |
1733 | let adt_id = match self.ty.value { | 1770 | let adt_id = match self.ty.value.interned(&Interner) { |
1734 | Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, | 1771 | &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, |
1735 | _ => return false, | 1772 | _ => return false, |
1736 | }; | 1773 | }; |
1737 | 1774 | ||
@@ -1743,24 +1780,45 @@ impl Type { | |||
1743 | } | 1780 | } |
1744 | 1781 | ||
1745 | pub fn is_raw_ptr(&self) -> bool { | 1782 | pub fn is_raw_ptr(&self) -> bool { |
1746 | matches!(&self.ty.value, Ty::Raw(..)) | 1783 | matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..)) |
1747 | } | 1784 | } |
1748 | 1785 | ||
1749 | pub fn contains_unknown(&self) -> bool { | 1786 | pub fn contains_unknown(&self) -> bool { |
1750 | return go(&self.ty.value); | 1787 | return go(&self.ty.value); |
1751 | 1788 | ||
1752 | fn go(ty: &Ty) -> bool { | 1789 | fn go(ty: &Ty) -> bool { |
1753 | match ty { | 1790 | match ty.interned(&Interner) { |
1754 | Ty::Unknown => true, | 1791 | TyKind::Unknown => true, |
1755 | _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), | 1792 | |
1793 | TyKind::Adt(_, substs) | ||
1794 | | TyKind::AssociatedType(_, substs) | ||
1795 | | TyKind::Tuple(_, substs) | ||
1796 | | TyKind::OpaqueType(_, substs) | ||
1797 | | TyKind::FnDef(_, substs) | ||
1798 | | TyKind::Closure(_, substs) => substs.iter().any(go), | ||
1799 | |||
1800 | TyKind::Array(ty) | TyKind::Slice(ty) | TyKind::Raw(_, ty) | TyKind::Ref(_, ty) => { | ||
1801 | go(ty) | ||
1802 | } | ||
1803 | |||
1804 | TyKind::Scalar(_) | ||
1805 | | TyKind::Str | ||
1806 | | TyKind::Never | ||
1807 | | TyKind::Placeholder(_) | ||
1808 | | TyKind::BoundVar(_) | ||
1809 | | TyKind::InferenceVar(_, _) | ||
1810 | | TyKind::Dyn(_) | ||
1811 | | TyKind::Function(_) | ||
1812 | | TyKind::Alias(_) | ||
1813 | | TyKind::ForeignType(_) => false, | ||
1756 | } | 1814 | } |
1757 | } | 1815 | } |
1758 | } | 1816 | } |
1759 | 1817 | ||
1760 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { | 1818 | pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { |
1761 | let (variant_id, substs) = match self.ty.value { | 1819 | let (variant_id, substs) = match self.ty.value.interned(&Interner) { |
1762 | Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), | 1820 | &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), |
1763 | Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), | 1821 | &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), |
1764 | _ => return Vec::new(), | 1822 | _ => return Vec::new(), |
1765 | }; | 1823 | }; |
1766 | 1824 | ||
@@ -1775,7 +1833,7 @@ impl Type { | |||
1775 | } | 1833 | } |
1776 | 1834 | ||
1777 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { | 1835 | pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { |
1778 | if let Ty::Tuple(_, substs) = &self.ty.value { | 1836 | if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) { |
1779 | substs.iter().map(|ty| self.derived(ty.clone())).collect() | 1837 | substs.iter().map(|ty| self.derived(ty.clone())).collect() |
1780 | } else { | 1838 | } else { |
1781 | Vec::new() | 1839 | Vec::new() |
@@ -1910,12 +1968,6 @@ impl Type { | |||
1910 | self.ty.value.associated_type_parent_trait(db).map(Into::into) | 1968 | self.ty.value.associated_type_parent_trait(db).map(Into::into) |
1911 | } | 1969 | } |
1912 | 1970 | ||
1913 | // FIXME: provide required accessors such that it becomes implementable from outside. | ||
1914 | pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { | ||
1915 | let rref = other.remove_ref(); | ||
1916 | self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value)) | ||
1917 | } | ||
1918 | |||
1919 | fn derived(&self, ty: Ty) -> Type { | 1971 | fn derived(&self, ty: Ty) -> Type { |
1920 | Type { | 1972 | Type { |
1921 | krate: self.krate, | 1973 | krate: self.krate, |
@@ -1957,36 +2009,40 @@ impl Type { | |||
1957 | 2009 | ||
1958 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { | 2010 | fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { |
1959 | let ty = type_.ty.value.strip_references(); | 2011 | let ty = type_.ty.value.strip_references(); |
1960 | match ty { | 2012 | match ty.interned(&Interner) { |
1961 | Ty::Adt(..) => { | 2013 | TyKind::Adt(..) => { |
1962 | cb(type_.derived(ty.clone())); | 2014 | cb(type_.derived(ty.clone())); |
1963 | } | 2015 | } |
1964 | Ty::AssociatedType(..) => { | 2016 | TyKind::AssociatedType(..) => { |
1965 | if let Some(_) = ty.associated_type_parent_trait(db) { | 2017 | if let Some(_) = ty.associated_type_parent_trait(db) { |
1966 | cb(type_.derived(ty.clone())); | 2018 | cb(type_.derived(ty.clone())); |
1967 | } | 2019 | } |
1968 | } | 2020 | } |
1969 | Ty::OpaqueType(..) => { | 2021 | TyKind::OpaqueType(..) => { |
1970 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2022 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1971 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2023 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1972 | } | 2024 | } |
1973 | } | 2025 | } |
1974 | Ty::Alias(AliasTy::Opaque(opaque_ty)) => { | 2026 | TyKind::Alias(AliasTy::Opaque(opaque_ty)) => { |
1975 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2027 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1976 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2028 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1977 | } | 2029 | } |
1978 | 2030 | ||
1979 | walk_substs(db, type_, &opaque_ty.parameters, cb); | 2031 | walk_substs(db, type_, &opaque_ty.substitution, cb); |
1980 | } | 2032 | } |
1981 | Ty::Placeholder(_) => { | 2033 | TyKind::Placeholder(_) => { |
1982 | if let Some(bounds) = ty.impl_trait_bounds(db) { | 2034 | if let Some(bounds) = ty.impl_trait_bounds(db) { |
1983 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); | 2035 | walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); |
1984 | } | 2036 | } |
1985 | } | 2037 | } |
1986 | Ty::Dyn(bounds) => { | 2038 | TyKind::Dyn(bounds) => { |
1987 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); | 2039 | walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); |
1988 | } | 2040 | } |
1989 | 2041 | ||
2042 | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) | TyKind::Array(ty) | TyKind::Slice(ty) => { | ||
2043 | walk_type(db, &type_.derived(ty.clone()), cb); | ||
2044 | } | ||
2045 | |||
1990 | _ => {} | 2046 | _ => {} |
1991 | } | 2047 | } |
1992 | if let Some(substs) = ty.substs() { | 2048 | if let Some(substs) = ty.substs() { |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 945638cc5..519339c0c 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -259,6 +259,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
259 | } | 259 | } |
260 | 260 | ||
261 | pub fn to_module_def(&self, file: FileId) -> Option<Module> { | 261 | pub fn to_module_def(&self, file: FileId) -> Option<Module> { |
262 | self.imp.to_module_def(file).next() | ||
263 | } | ||
264 | |||
265 | pub fn to_module_defs(&self, file: FileId) -> impl Iterator<Item = Module> { | ||
262 | self.imp.to_module_def(file) | 266 | self.imp.to_module_def(file) |
263 | } | 267 | } |
264 | 268 | ||
@@ -537,8 +541,8 @@ impl<'db> SemanticsImpl<'db> { | |||
537 | f(&mut ctx) | 541 | f(&mut ctx) |
538 | } | 542 | } |
539 | 543 | ||
540 | fn to_module_def(&self, file: FileId) -> Option<Module> { | 544 | fn to_module_def(&self, file: FileId) -> impl Iterator<Item = Module> { |
541 | self.with_ctx(|ctx| ctx.file_to_def(file)).map(Module::from) | 545 | self.with_ctx(|ctx| ctx.file_to_def(file)).into_iter().map(Module::from) |
542 | } | 546 | } |
543 | 547 | ||
544 | fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { | 548 | fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 6c612ee86..e9d820140 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -12,6 +12,7 @@ use hir_def::{ | |||
12 | }; | 12 | }; |
13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; | 13 | use hir_expand::{name::AsName, AstId, MacroDefKind}; |
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
15 | use smallvec::SmallVec; | ||
15 | use stdx::impl_from; | 16 | use stdx::impl_from; |
16 | use syntax::{ | 17 | use syntax::{ |
17 | ast::{self, NameOwner}, | 18 | ast::{self, NameOwner}, |
@@ -28,14 +29,19 @@ pub(super) struct SourceToDefCtx<'a, 'b> { | |||
28 | } | 29 | } |
29 | 30 | ||
30 | impl SourceToDefCtx<'_, '_> { | 31 | impl SourceToDefCtx<'_, '_> { |
31 | pub(super) fn file_to_def(&mut self, file: FileId) -> Option<ModuleId> { | 32 | pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> { |
32 | let _p = profile::span("SourceBinder::to_module_def"); | 33 | let _p = profile::span("SourceBinder::to_module_def"); |
33 | self.db.relevant_crates(file).iter().find_map(|&crate_id| { | 34 | let mut mods = SmallVec::new(); |
35 | for &crate_id in self.db.relevant_crates(file).iter() { | ||
34 | // FIXME: inner items | 36 | // FIXME: inner items |
35 | let crate_def_map = self.db.crate_def_map(crate_id); | 37 | let crate_def_map = self.db.crate_def_map(crate_id); |
36 | let local_id = crate_def_map.modules_for_file(file).next()?; | 38 | mods.extend( |
37 | Some(crate_def_map.module_id(local_id)) | 39 | crate_def_map |
38 | }) | 40 | .modules_for_file(file) |
41 | .map(|local_id| crate_def_map.module_id(local_id)), | ||
42 | ) | ||
43 | } | ||
44 | mods | ||
39 | } | 45 | } |
40 | 46 | ||
41 | pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { | 47 | pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> { |
@@ -55,7 +61,7 @@ impl SourceToDefCtx<'_, '_> { | |||
55 | Some(parent_declaration) => self.module_to_def(parent_declaration), | 61 | Some(parent_declaration) => self.module_to_def(parent_declaration), |
56 | None => { | 62 | None => { |
57 | let file_id = src.file_id.original_file(self.db.upcast()); | 63 | let file_id = src.file_id.original_file(self.db.upcast()); |
58 | self.file_to_def(file_id) | 64 | self.file_to_def(file_id).get(0).copied() |
59 | } | 65 | } |
60 | }?; | 66 | }?; |
61 | 67 | ||
@@ -185,7 +191,7 @@ impl SourceToDefCtx<'_, '_> { | |||
185 | ) -> Option<MacroDefId> { | 191 | ) -> Option<MacroDefId> { |
186 | let kind = MacroDefKind::Declarative; | 192 | let kind = MacroDefKind::Declarative; |
187 | let file_id = src.file_id.original_file(self.db.upcast()); | 193 | let file_id = src.file_id.original_file(self.db.upcast()); |
188 | let krate = self.file_to_def(file_id)?.krate(); | 194 | let krate = self.file_to_def(file_id).get(0).copied()?.krate(); |
189 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); | 195 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); |
190 | let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); | 196 | let ast_id = Some(AstId::new(src.file_id, file_ast_id.upcast())); |
191 | Some(MacroDefId { krate, ast_id, kind, local_inner: false }) | 197 | Some(MacroDefId { krate, ast_id, kind, local_inner: false }) |
@@ -245,7 +251,7 @@ impl SourceToDefCtx<'_, '_> { | |||
245 | return Some(res); | 251 | return Some(res); |
246 | } | 252 | } |
247 | 253 | ||
248 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast()))?; | 254 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?; |
249 | Some(def.into()) | 255 | Some(def.into()) |
250 | } | 256 | } |
251 | 257 | ||
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index d546512cb..4d59293e9 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs | |||
@@ -161,8 +161,9 @@ impl SourceAnalyzer { | |||
161 | db: &dyn HirDatabase, | 161 | db: &dyn HirDatabase, |
162 | field: &ast::RecordExprField, | 162 | field: &ast::RecordExprField, |
163 | ) -> Option<(Field, Option<Local>)> { | 163 | ) -> Option<(Field, Option<Local>)> { |
164 | let expr = field.expr()?; | 164 | let expr_id = |
165 | let expr_id = self.expr_id(db, &expr)?; | 165 | self.body_source_map.as_ref()?.node_field(InFile::new(self.file_id, field))?; |
166 | |||
166 | let local = if field.name_ref().is_some() { | 167 | let local = if field.name_ref().is_some() { |
167 | None | 168 | None |
168 | } else { | 169 | } else { |