aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/base_db/src/change.rs2
-rw-r--r--crates/hir/src/code_model.rs165
-rw-r--r--crates/hir/src/diagnostics.rs4
-rw-r--r--crates/hir/src/semantics.rs8
-rw-r--r--crates/hir/src/source_analyzer.rs16
-rw-r--r--crates/hir_def/src/body.rs2
-rw-r--r--crates/hir_def/src/body/lower.rs17
-rw-r--r--crates/hir_def/src/body/tests/block.rs29
-rw-r--r--crates/hir_def/src/builtin_type.rs132
-rw-r--r--crates/hir_def/src/diagnostics.rs28
-rw-r--r--crates/hir_def/src/expr.rs3
-rw-r--r--crates/hir_def/src/find_path.rs59
-rw-r--r--crates/hir_def/src/item_scope.rs22
-rw-r--r--crates/hir_def/src/lib.rs137
-rw-r--r--crates/hir_def/src/nameres.rs26
-rw-r--r--crates/hir_def/src/nameres/collector.rs81
-rw-r--r--crates/hir_def/src/nameres/path_resolution.rs21
-rw-r--r--crates/hir_def/src/path/lower.rs13
-rw-r--r--crates/hir_expand/src/builtin_macro.rs64
-rw-r--r--crates/hir_expand/src/name.rs1
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/autoderef.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs206
-rw-r--r--crates/hir_ty/src/infer.rs46
-rw-r--r--crates/hir_ty/src/infer/coerce.rs87
-rw-r--r--crates/hir_ty/src/infer/expr.rs236
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
-rw-r--r--crates/hir_ty/src/lib.rs607
-rw-r--r--crates/hir_ty/src/lower.rs88
-rw-r--r--crates/hir_ty/src/method_resolution.rs167
-rw-r--r--crates/hir_ty/src/op.rs50
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/tests/simple.rs55
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs24
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs332
-rw-r--r--crates/ide/src/diagnostics.rs67
-rw-r--r--crates/ide/src/hover.rs29
-rw-r--r--crates/ide/src/references.rs34
-rw-r--r--crates/ide/src/references/rename.rs9
-rw-r--r--crates/ide_assists/src/handlers/apply_demorgan.rs78
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs6
-rw-r--r--crates/ide_assists/src/handlers/early_return.rs2
-rw-r--r--crates/ide_assists/src/handlers/flip_comma.rs26
-rw-r--r--crates/ide_assists/src/handlers/generate_enum_is_method.rs (renamed from crates/ide_assists/src/handlers/generate_enum_match_method.rs)128
-rw-r--r--crates/ide_assists/src/handlers/generate_enum_projection_method.rs331
-rw-r--r--crates/ide_assists/src/handlers/invert_if.rs2
-rw-r--r--crates/ide_assists/src/handlers/replace_for_loop_with_for_each.rs321
-rw-r--r--crates/ide_assists/src/handlers/replace_let_with_if_let.rs2
-rw-r--r--crates/ide_assists/src/lib.rs15
-rw-r--r--crates/ide_assists/src/tests.rs2
-rw-r--r--crates/ide_assists/src/tests/generated.rs89
-rw-r--r--crates/ide_assists/src/utils.rs74
-rw-r--r--crates/ide_completion/src/generated_lint_completions.rs6379
-rw-r--r--crates/ide_db/src/apply_change.rs2
-rw-r--r--crates/ide_db/src/helpers.rs4
-rw-r--r--crates/ide_db/src/helpers/famous_defs_fixture.rs11
-rw-r--r--crates/ide_db/src/search.rs15
-rw-r--r--crates/ide_db/src/source_change.rs2
-rw-r--r--crates/mbe/Cargo.toml2
-rw-r--r--crates/mbe/src/benchmark.rs211
-rw-r--r--crates/mbe/src/expander/matcher.rs68
-rw-r--r--crates/mbe/src/lib.rs7
-rw-r--r--crates/mbe/src/syntax_bridge.rs41
-rw-r--r--crates/mbe/src/tests.rs23
-rw-r--r--crates/mbe/src/tt_iter.rs77
-rw-r--r--crates/proc_macro_srv/src/rustc_server.rs40
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs2
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs2
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs3
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs9
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs4
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/main.rs18
-rw-r--r--crates/rust-analyzer/tests/rust-analyzer/support.rs12
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/ast/make.rs7
-rw-r--r--crates/test_utils/src/bench_fixture.rs5
81 files changed, 9472 insertions, 1855 deletions
diff --git a/crates/base_db/src/change.rs b/crates/base_db/src/change.rs
index 043e03bba..04e294e41 100644
--- a/crates/base_db/src/change.rs
+++ b/crates/base_db/src/change.rs
@@ -19,7 +19,7 @@ pub struct Change {
19 19
20impl fmt::Debug for Change { 20impl fmt::Debug for Change {
21 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { 21 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
22 let mut d = fmt.debug_struct("AnalysisChange"); 22 let mut d = fmt.debug_struct("Change");
23 if let Some(roots) = &self.roots { 23 if let Some(roots) = &self.roots {
24 d.field("roots", roots); 24 d.field("roots", roots);
25 } 25 }
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index b3218833d..fc1a74641 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -14,7 +14,7 @@ use hir_def::{
14 per_ns::PerNs, 14 per_ns::PerNs,
15 resolver::{HasResolver, Resolver}, 15 resolver::{HasResolver, Resolver},
16 src::HasSource as _, 16 src::HasSource as _,
17 type_ref::{Mutability, TypeRef}, 17 type_ref::TypeRef,
18 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, 18 AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId,
19 DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, 19 DefWithBodyId, EnumId, FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId,
20 LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, 20 LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId,
@@ -31,9 +31,9 @@ use hir_ty::{
31 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter}, 31 display::{write_bounds_like_dyn_trait_with_prefix, HirDisplayError, HirFormatter},
32 method_resolution, 32 method_resolution,
33 traits::{FnTrait, Solution, SolutionVariables}, 33 traits::{FnTrait, Solution, SolutionVariables},
34 ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, 34 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
35 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, 35 InEnvironment, Mutability, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs,
36 TyDefId, TyKind, TypeCtor, 36 TraitEnvironment, Ty, TyDefId, TyVariableKind,
37}; 37};
38use rustc_hash::FxHashSet; 38use rustc_hash::FxHashSet;
39use stdx::{format_to, impl_from}; 39use stdx::{format_to, impl_from};
@@ -836,7 +836,7 @@ pub enum Access {
836impl From<Mutability> for Access { 836impl From<Mutability> for Access {
837 fn from(mutability: Mutability) -> Access { 837 fn from(mutability: Mutability) -> Access {
838 match mutability { 838 match mutability {
839 Mutability::Shared => Access::Shared, 839 Mutability::Not => Access::Shared,
840 Mutability::Mut => Access::Exclusive, 840 Mutability::Mut => Access::Exclusive,
841 } 841 }
842 } 842 }
@@ -865,7 +865,10 @@ impl SelfParam {
865 .params 865 .params
866 .first() 866 .first()
867 .map(|param| match *param { 867 .map(|param| match *param {
868 TypeRef::Reference(.., mutability) => mutability.into(), 868 TypeRef::Reference(.., mutability) => match mutability {
869 hir_def::type_ref::Mutability::Shared => Access::Shared,
870 hir_def::type_ref::Mutability::Mut => Access::Exclusive,
871 },
869 _ => Access::Owned, 872 _ => Access::Owned,
870 }) 873 })
871 .unwrap_or(Access::Owned) 874 .unwrap_or(Access::Owned)
@@ -1547,25 +1550,19 @@ impl Type {
1547 } 1550 }
1548 1551
1549 pub fn is_unit(&self) -> bool { 1552 pub fn is_unit(&self) -> bool {
1550 matches!( 1553 matches!(self.ty.value, Ty::Tuple(0, ..))
1551 self.ty.value,
1552 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. })
1553 )
1554 } 1554 }
1555 pub fn is_bool(&self) -> bool { 1555 pub fn is_bool(&self) -> bool {
1556 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1556 matches!(self.ty.value, Ty::Scalar(Scalar::Bool))
1557 } 1557 }
1558 1558
1559 pub fn is_mutable_reference(&self) -> bool { 1559 pub fn is_mutable_reference(&self) -> bool {
1560 matches!( 1560 matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..))
1561 self.ty.value,
1562 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. })
1563 )
1564 } 1561 }
1565 1562
1566 pub fn remove_ref(&self) -> Option<Type> { 1563 pub fn remove_ref(&self) -> Option<Type> {
1567 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { 1564 if let Ty::Ref(.., substs) = &self.ty.value {
1568 self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) 1565 Some(self.derived(substs[0].clone()))
1569 } else { 1566 } else {
1570 None 1567 None
1571 } 1568 }
@@ -1654,14 +1651,14 @@ impl Type {
1654 .build(); 1651 .build();
1655 let predicate = ProjectionPredicate { 1652 let predicate = ProjectionPredicate {
1656 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, 1653 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
1657 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)), 1654 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
1658 }; 1655 };
1659 let goal = Canonical { 1656 let goal = Canonical {
1660 value: InEnvironment::new( 1657 value: InEnvironment::new(
1661 self.ty.environment.clone(), 1658 self.ty.environment.clone(),
1662 Obligation::Projection(predicate), 1659 Obligation::Projection(predicate),
1663 ), 1660 ),
1664 kinds: Arc::new([TyKind::General]), 1661 kinds: Arc::new([TyVariableKind::General]),
1665 }; 1662 };
1666 1663
1667 match db.trait_solve(self.krate, goal)? { 1664 match db.trait_solve(self.krate, goal)? {
@@ -1685,7 +1682,7 @@ impl Type {
1685 1682
1686 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1683 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1687 let def = match self.ty.value { 1684 let def = match self.ty.value {
1688 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), 1685 Ty::FnDef(def, _) => Some(def),
1689 _ => None, 1686 _ => None,
1690 }; 1687 };
1691 1688
@@ -1694,20 +1691,16 @@ impl Type {
1694 } 1691 }
1695 1692
1696 pub fn is_closure(&self) -> bool { 1693 pub fn is_closure(&self) -> bool {
1697 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) 1694 matches!(&self.ty.value, Ty::Closure { .. })
1698 } 1695 }
1699 1696
1700 pub fn is_fn(&self) -> bool { 1697 pub fn is_fn(&self) -> bool {
1701 matches!( 1698 matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. })
1702 &self.ty.value,
1703 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. })
1704 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. })
1705 )
1706 } 1699 }
1707 1700
1708 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1701 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1709 let adt_id = match self.ty.value { 1702 let adt_id = match self.ty.value {
1710 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, 1703 Ty::Adt(adt_id, ..) => adt_id,
1711 _ => return false, 1704 _ => return false,
1712 }; 1705 };
1713 1706
@@ -1719,7 +1712,7 @@ impl Type {
1719 } 1712 }
1720 1713
1721 pub fn is_raw_ptr(&self) -> bool { 1714 pub fn is_raw_ptr(&self) -> bool {
1722 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) 1715 matches!(&self.ty.value, Ty::Raw(..))
1723 } 1716 }
1724 1717
1725 pub fn contains_unknown(&self) -> bool { 1718 pub fn contains_unknown(&self) -> bool {
@@ -1728,44 +1721,34 @@ impl Type {
1728 fn go(ty: &Ty) -> bool { 1721 fn go(ty: &Ty) -> bool {
1729 match ty { 1722 match ty {
1730 Ty::Unknown => true, 1723 Ty::Unknown => true,
1731 Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), 1724 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)),
1732 _ => false,
1733 } 1725 }
1734 } 1726 }
1735 } 1727 }
1736 1728
1737 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1729 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1738 if let Ty::Apply(a_ty) = &self.ty.value { 1730 let (variant_id, substs) = match self.ty.value {
1739 let variant_id = match a_ty.ctor { 1731 Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs),
1740 TypeCtor::Adt(AdtId::StructId(s)) => s.into(), 1732 Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs),
1741 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), 1733 _ => return Vec::new(),
1742 _ => return Vec::new(),
1743 };
1744
1745 return db
1746 .field_types(variant_id)
1747 .iter()
1748 .map(|(local_id, ty)| {
1749 let def = Field { parent: variant_id.into(), id: local_id };
1750 let ty = ty.clone().subst(&a_ty.parameters);
1751 (def, self.derived(ty))
1752 })
1753 .collect();
1754 }; 1734 };
1755 Vec::new() 1735
1736 db.field_types(variant_id)
1737 .iter()
1738 .map(|(local_id, ty)| {
1739 let def = Field { parent: variant_id.into(), id: local_id };
1740 let ty = ty.clone().subst(substs);
1741 (def, self.derived(ty))
1742 })
1743 .collect()
1756 } 1744 }
1757 1745
1758 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1746 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1759 let mut res = Vec::new(); 1747 if let Ty::Tuple(_, substs) = &self.ty.value {
1760 if let Ty::Apply(a_ty) = &self.ty.value { 1748 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1761 if let TypeCtor::Tuple { .. } = a_ty.ctor { 1749 } else {
1762 for ty in a_ty.parameters.iter() { 1750 Vec::new()
1763 let ty = ty.clone(); 1751 }
1764 res.push(self.derived(ty));
1765 }
1766 }
1767 };
1768 res
1769 } 1752 }
1770 1753
1771 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1754 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
@@ -1802,15 +1785,13 @@ impl Type {
1802 } 1785 }
1803 1786
1804 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1787 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1805 let ty = self.ty.value.strip_references(); 1788 self.ty
1806 let substs = match ty { 1789 .value
1807 Ty::Apply(apply_ty) => &apply_ty.parameters, 1790 .strip_references()
1808 Ty::Opaque(opaque_ty) => &opaque_ty.parameters, 1791 .substs()
1809 _ => return Either::Left(iter::empty()), 1792 .into_iter()
1810 }; 1793 .flat_map(|substs| substs.iter())
1811 1794 .map(move |ty| self.derived(ty.clone()))
1812 let iter = substs.iter().map(move |ty| self.derived(ty.clone()));
1813 Either::Right(iter)
1814 } 1795 }
1815 1796
1816 pub fn iterate_method_candidates<T>( 1797 pub fn iterate_method_candidates<T>(
@@ -1900,17 +1881,8 @@ impl Type {
1900 1881
1901 // FIXME: provide required accessors such that it becomes implementable from outside. 1882 // FIXME: provide required accessors such that it becomes implementable from outside.
1902 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { 1883 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1903 match (&self.ty.value, &other.ty.value) { 1884 let rref = other.remove_ref();
1904 (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor 1885 self.ty.value.equals_ctor(rref.as_ref().map_or(&other.ty.value, |it| &it.ty.value))
1905 {
1906 TypeCtor::Ref(..) => match parameters.as_single() {
1907 Ty::Apply(a_ty) => a_original_ty.ctor == a_ty.ctor,
1908 _ => false,
1909 },
1910 _ => a_original_ty.ctor == *ctor,
1911 },
1912 _ => false,
1913 }
1914 } 1886 }
1915 1887
1916 fn derived(&self, ty: Ty) -> Type { 1888 fn derived(&self, ty: Ty) -> Type {
@@ -1955,28 +1927,20 @@ impl Type {
1955 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 1927 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1956 let ty = type_.ty.value.strip_references(); 1928 let ty = type_.ty.value.strip_references();
1957 match ty { 1929 match ty {
1958 Ty::Apply(ApplicationTy { ctor, parameters }) => { 1930 Ty::Adt(..) => {
1959 match ctor { 1931 cb(type_.derived(ty.clone()));
1960 TypeCtor::Adt(_) => { 1932 }
1961 cb(type_.derived(ty.clone())); 1933 Ty::AssociatedType(..) => {
1962 } 1934 if let Some(_) = ty.associated_type_parent_trait(db) {
1963 TypeCtor::AssociatedType(_) => { 1935 cb(type_.derived(ty.clone()));
1964 if let Some(_) = ty.associated_type_parent_trait(db) {
1965 cb(type_.derived(ty.clone()));
1966 }
1967 }
1968 TypeCtor::OpaqueType(..) => {
1969 if let Some(bounds) = ty.impl_trait_bounds(db) {
1970 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1971 }
1972 }
1973 _ => (),
1974 } 1936 }
1975
1976 // adt params, tuples, etc...
1977 walk_substs(db, type_, parameters, cb);
1978 } 1937 }
1979 Ty::Opaque(opaque_ty) => { 1938 Ty::OpaqueType(..) => {
1939 if let Some(bounds) = ty.impl_trait_bounds(db) {
1940 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1941 }
1942 }
1943 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
1980 if let Some(bounds) = ty.impl_trait_bounds(db) { 1944 if let Some(bounds) = ty.impl_trait_bounds(db) {
1981 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 1945 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1982 } 1946 }
@@ -1992,7 +1956,10 @@ impl Type {
1992 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 1956 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1993 } 1957 }
1994 1958
1995 _ => (), 1959 _ => {}
1960 }
1961 if let Some(substs) = ty.substs() {
1962 walk_substs(db, type_, &substs, cb);
1996 } 1963 }
1997 } 1964 }
1998 1965
@@ -2010,7 +1977,7 @@ impl HirDisplay for Type {
2010#[derive(Debug)] 1977#[derive(Debug)]
2011pub struct Callable { 1978pub struct Callable {
2012 ty: Type, 1979 ty: Type,
2013 sig: FnSig, 1980 sig: CallableSig,
2014 def: Option<CallableDefId>, 1981 def: Option<CallableDefId>,
2015 pub(crate) is_bound_method: bool, 1982 pub(crate) is_bound_method: bool,
2016} 1983}
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 5343a036c..b1ebba516 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -1,5 +1,7 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2pub use hir_def::diagnostics::{InactiveCode, UnresolvedModule, UnresolvedProcMacro}; 2pub use hir_def::diagnostics::{
3 InactiveCode, UnresolvedMacroCall, UnresolvedModule, UnresolvedProcMacro,
4};
3pub use hir_expand::diagnostics::{ 5pub use hir_expand::diagnostics::{
4 Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, 6 Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder,
5}; 7};
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 59292d5a2..144851f83 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -16,13 +16,12 @@ use rustc_hash::{FxHashMap, FxHashSet};
16use syntax::{ 16use syntax::{
17 algo::find_node_at_offset, 17 algo::find_node_at_offset,
18 ast::{self, GenericParamsOwner, LoopBodyOwner}, 18 ast::{self, GenericParamsOwner, LoopBodyOwner},
19 match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize, 19 match_ast, AstNode, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextSize,
20}; 20};
21 21
22use crate::{ 22use crate::{
23 code_model::Access, 23 code_model::Access,
24 db::HirDatabase, 24 db::HirDatabase,
25 diagnostics::Diagnostic,
26 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, 25 semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
27 source_analyzer::{resolve_hir_path, SourceAnalyzer}, 26 source_analyzer::{resolve_hir_path, SourceAnalyzer},
28 AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label, 27 AssocItem, Callable, ConstParam, Crate, Field, Function, HirFileId, Impl, InFile, Label,
@@ -141,7 +140,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
141 self.imp.original_range(node) 140 self.imp.original_range(node)
142 } 141 }
143 142
144 pub fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 143 pub fn diagnostics_display_range(&self, diagnostics: InFile<SyntaxNodePtr>) -> FileRange {
145 self.imp.diagnostics_display_range(diagnostics) 144 self.imp.diagnostics_display_range(diagnostics)
146 } 145 }
147 146
@@ -385,8 +384,7 @@ impl<'db> SemanticsImpl<'db> {
385 node.as_ref().original_file_range(self.db.upcast()) 384 node.as_ref().original_file_range(self.db.upcast())
386 } 385 }
387 386
388 fn diagnostics_display_range(&self, diagnostics: &dyn Diagnostic) -> FileRange { 387 fn diagnostics_display_range(&self, src: InFile<SyntaxNodePtr>) -> FileRange {
389 let src = diagnostics.display_source();
390 let root = self.db.parse_or_expand(src.file_id).unwrap(); 388 let root = self.db.parse_or_expand(src.file_id).unwrap();
391 let node = src.value.to_node(&root); 389 let node = src.value.to_node(&root);
392 self.cache(root, src.file_id); 390 self.cache(root, src.file_id);
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index dc21f6051..64ce4add1 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -20,7 +20,7 @@ use hir_def::{
20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile}; 20use hir_expand::{hygiene::Hygiene, name::AsName, HirFileId, InFile};
21use hir_ty::{ 21use hir_ty::{
22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields}, 22 diagnostics::{record_literal_missing_fields, record_pattern_missing_fields},
23 InferenceResult, Substs, Ty, 23 InferenceResult, Substs,
24}; 24};
25use syntax::{ 25use syntax::{
26 ast::{self, AstNode}, 26 ast::{self, AstNode},
@@ -299,14 +299,11 @@ impl SourceAnalyzer {
299 let infer = self.infer.as_ref()?; 299 let infer = self.infer.as_ref()?;
300 300
301 let expr_id = self.expr_id(db, &literal.clone().into())?; 301 let expr_id = self.expr_id(db, &literal.clone().into())?;
302 let substs = match &infer.type_of_expr[expr_id] { 302 let substs = infer.type_of_expr[expr_id].substs()?;
303 Ty::Apply(a_ty) => &a_ty.parameters,
304 _ => return None,
305 };
306 303
307 let (variant, missing_fields, _exhaustive) = 304 let (variant, missing_fields, _exhaustive) =
308 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?; 305 record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?;
309 let res = self.missing_fields(db, krate, substs, variant, missing_fields); 306 let res = self.missing_fields(db, krate, &substs, variant, missing_fields);
310 Some(res) 307 Some(res)
311 } 308 }
312 309
@@ -320,14 +317,11 @@ impl SourceAnalyzer {
320 let infer = self.infer.as_ref()?; 317 let infer = self.infer.as_ref()?;
321 318
322 let pat_id = self.pat_id(&pattern.clone().into())?; 319 let pat_id = self.pat_id(&pattern.clone().into())?;
323 let substs = match &infer.type_of_pat[pat_id] { 320 let substs = infer.type_of_pat[pat_id].substs()?;
324 Ty::Apply(a_ty) => &a_ty.parameters,
325 _ => return None,
326 };
327 321
328 let (variant, missing_fields, _exhaustive) = 322 let (variant, missing_fields, _exhaustive) =
329 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?; 323 record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?;
330 let res = self.missing_fields(db, krate, substs, variant, missing_fields); 324 let res = self.missing_fields(db, krate, &substs, variant, missing_fields);
331 Some(res) 325 Some(res)
332 } 326 }
333 327
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 9a432f7d1..ff4b4a0cf 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -123,7 +123,7 @@ impl Expander {
123 Some(it) => it, 123 Some(it) => it,
124 None => { 124 None => {
125 if err.is_none() { 125 if err.is_none() {
126 eprintln!("no error despite `as_call_id_with_errors` returning `None`"); 126 log::warn!("no error despite `as_call_id_with_errors` returning `None`");
127 } 127 }
128 return ExpandResult { value: None, err }; 128 return ExpandResult { value: None, err };
129 } 129 }
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index c18001e15..40beb2f7a 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -24,7 +24,7 @@ use test_utils::mark;
24use crate::{ 24use crate::{
25 adt::StructKind, 25 adt::StructKind,
26 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, 26 body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
27 builtin_type::{BuiltinFloat, BuiltinInt}, 27 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
28 db::DefDatabase, 28 db::DefDatabase,
29 diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, 29 diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro},
30 expr::{ 30 expr::{
@@ -1065,11 +1065,16 @@ impl From<ast::LiteralKind> for Literal {
1065 fn from(ast_lit_kind: ast::LiteralKind) -> Self { 1065 fn from(ast_lit_kind: ast::LiteralKind) -> Self {
1066 match ast_lit_kind { 1066 match ast_lit_kind {
1067 LiteralKind::IntNumber(lit) => { 1067 LiteralKind::IntNumber(lit) => {
1068 if let Some(float_suffix) = lit.suffix().and_then(BuiltinFloat::from_suffix) { 1068 if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
1069 return Literal::Float(Default::default(), Some(float_suffix)); 1069 return Literal::Float(Default::default(), builtin);
1070 } else if let builtin @ Some(_) =
1071 lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it))
1072 {
1073 Literal::Int(Default::default(), builtin)
1074 } else {
1075 let builtin = lit.suffix().and_then(|it| BuiltinUint::from_suffix(&it));
1076 Literal::Uint(Default::default(), builtin)
1070 } 1077 }
1071 let ty = lit.suffix().and_then(|it| BuiltinInt::from_suffix(&it));
1072 Literal::Int(Default::default(), ty)
1073 } 1078 }
1074 LiteralKind::FloatNumber(lit) => { 1079 LiteralKind::FloatNumber(lit) => {
1075 let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it)); 1080 let ty = lit.suffix().and_then(|it| BuiltinFloat::from_suffix(&it));
@@ -1077,7 +1082,7 @@ impl From<ast::LiteralKind> for Literal {
1077 } 1082 }
1078 LiteralKind::ByteString(_) => Literal::ByteString(Default::default()), 1083 LiteralKind::ByteString(_) => Literal::ByteString(Default::default()),
1079 LiteralKind::String(_) => Literal::String(Default::default()), 1084 LiteralKind::String(_) => Literal::String(Default::default()),
1080 LiteralKind::Byte => Literal::Int(Default::default(), Some(BuiltinInt::U8)), 1085 LiteralKind::Byte => Literal::Uint(Default::default(), Some(BuiltinUint::U8)),
1081 LiteralKind::Bool(val) => Literal::Bool(val), 1086 LiteralKind::Bool(val) => Literal::Bool(val),
1082 LiteralKind::Char => Literal::Char(Default::default()), 1087 LiteralKind::Char => Literal::Char(Default::default()),
1083 } 1088 }
diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs
index a5ec0883f..8bca72a17 100644
--- a/crates/hir_def/src/body/tests/block.rs
+++ b/crates/hir_def/src/body/tests/block.rs
@@ -259,3 +259,32 @@ fn main() {
259 "#]], 259 "#]],
260 ); 260 );
261} 261}
262
263#[test]
264fn underscore_import() {
265 // This used to panic, because the default (private) visibility inside block expressions would
266 // point into the containing `DefMap`, which visibilities should never be able to do.
267 mark::check!(adjust_vis_in_block_def_map);
268 check_at(
269 r#"
270mod m {
271 fn main() {
272 use Tr as _;
273 trait Tr {}
274 $0
275 }
276}
277 "#,
278 expect![[r#"
279 block scope
280 _: t
281 Tr: t
282
283 crate
284 m: t
285
286 crate::m
287 main: v
288 "#]],
289 );
290}
diff --git a/crates/hir_def/src/builtin_type.rs b/crates/hir_def/src/builtin_type.rs
index 0f872b5c0..7cbaf30b8 100644
--- a/crates/hir_def/src/builtin_type.rs
+++ b/crates/hir_def/src/builtin_type.rs
@@ -6,38 +6,32 @@
6use std::fmt; 6use std::fmt;
7 7
8use hir_expand::name::{name, AsName, Name}; 8use hir_expand::name::{name, AsName, Name};
9 9/// Different signed int types.
10#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 10#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
11pub enum Signedness { 11pub enum BuiltinInt {
12 Signed, 12 Isize,
13 Unsigned, 13 I8,
14} 14 I16,
15 15 I32,
16#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] 16 I64,
17pub enum IntBitness { 17 I128,
18 Xsize,
19 X8,
20 X16,
21 X32,
22 X64,
23 X128,
24}
25
26#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
27pub enum FloatBitness {
28 X32,
29 X64,
30} 18}
31 19
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 20/// Different unsigned int types.
33pub struct BuiltinInt { 21#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
34 pub signedness: Signedness, 22pub enum BuiltinUint {
35 pub bitness: IntBitness, 23 Usize,
24 U8,
25 U16,
26 U32,
27 U64,
28 U128,
36} 29}
37 30
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 31#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
39pub struct BuiltinFloat { 32pub enum BuiltinFloat {
40 pub bitness: FloatBitness, 33 F32,
34 F64,
41} 35}
42 36
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -46,6 +40,7 @@ pub enum BuiltinType {
46 Bool, 40 Bool,
47 Str, 41 Str,
48 Int(BuiltinInt), 42 Int(BuiltinInt),
43 Uint(BuiltinUint),
49 Float(BuiltinFloat), 44 Float(BuiltinFloat),
50} 45}
51 46
@@ -56,19 +51,19 @@ impl BuiltinType {
56 (name![bool], BuiltinType::Bool), 51 (name![bool], BuiltinType::Bool),
57 (name![str], BuiltinType::Str), 52 (name![str], BuiltinType::Str),
58 53
59 (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)), 54 (name![isize], BuiltinType::Int(BuiltinInt::Isize)),
60 (name![i8], BuiltinType::Int(BuiltinInt::I8)), 55 (name![i8], BuiltinType::Int(BuiltinInt::I8)),
61 (name![i16], BuiltinType::Int(BuiltinInt::I16)), 56 (name![i16], BuiltinType::Int(BuiltinInt::I16)),
62 (name![i32], BuiltinType::Int(BuiltinInt::I32)), 57 (name![i32], BuiltinType::Int(BuiltinInt::I32)),
63 (name![i64], BuiltinType::Int(BuiltinInt::I64)), 58 (name![i64], BuiltinType::Int(BuiltinInt::I64)),
64 (name![i128], BuiltinType::Int(BuiltinInt::I128)), 59 (name![i128], BuiltinType::Int(BuiltinInt::I128)),
65 60
66 (name![usize], BuiltinType::Int(BuiltinInt::USIZE)), 61 (name![usize], BuiltinType::Uint(BuiltinUint::Usize)),
67 (name![u8], BuiltinType::Int(BuiltinInt::U8)), 62 (name![u8], BuiltinType::Uint(BuiltinUint::U8)),
68 (name![u16], BuiltinType::Int(BuiltinInt::U16)), 63 (name![u16], BuiltinType::Uint(BuiltinUint::U16)),
69 (name![u32], BuiltinType::Int(BuiltinInt::U32)), 64 (name![u32], BuiltinType::Uint(BuiltinUint::U32)),
70 (name![u64], BuiltinType::Int(BuiltinInt::U64)), 65 (name![u64], BuiltinType::Uint(BuiltinUint::U64)),
71 (name![u128], BuiltinType::Int(BuiltinInt::U128)), 66 (name![u128], BuiltinType::Uint(BuiltinUint::U128)),
72 67
73 (name![f32], BuiltinType::Float(BuiltinFloat::F32)), 68 (name![f32], BuiltinType::Float(BuiltinFloat::F32)),
74 (name![f64], BuiltinType::Float(BuiltinFloat::F64)), 69 (name![f64], BuiltinType::Float(BuiltinFloat::F64)),
@@ -81,24 +76,25 @@ impl AsName for BuiltinType {
81 BuiltinType::Char => name![char], 76 BuiltinType::Char => name![char],
82 BuiltinType::Bool => name![bool], 77 BuiltinType::Bool => name![bool],
83 BuiltinType::Str => name![str], 78 BuiltinType::Str => name![str],
84 BuiltinType::Int(BuiltinInt { signedness, bitness }) => match (signedness, bitness) { 79 BuiltinType::Int(it) => match it {
85 (Signedness::Signed, IntBitness::Xsize) => name![isize], 80 BuiltinInt::Isize => name![isize],
86 (Signedness::Signed, IntBitness::X8) => name![i8], 81 BuiltinInt::I8 => name![i8],
87 (Signedness::Signed, IntBitness::X16) => name![i16], 82 BuiltinInt::I16 => name![i16],
88 (Signedness::Signed, IntBitness::X32) => name![i32], 83 BuiltinInt::I32 => name![i32],
89 (Signedness::Signed, IntBitness::X64) => name![i64], 84 BuiltinInt::I64 => name![i64],
90 (Signedness::Signed, IntBitness::X128) => name![i128], 85 BuiltinInt::I128 => name![i128],
91 86 },
92 (Signedness::Unsigned, IntBitness::Xsize) => name![usize], 87 BuiltinType::Uint(it) => match it {
93 (Signedness::Unsigned, IntBitness::X8) => name![u8], 88 BuiltinUint::Usize => name![usize],
94 (Signedness::Unsigned, IntBitness::X16) => name![u16], 89 BuiltinUint::U8 => name![u8],
95 (Signedness::Unsigned, IntBitness::X32) => name![u32], 90 BuiltinUint::U16 => name![u16],
96 (Signedness::Unsigned, IntBitness::X64) => name![u64], 91 BuiltinUint::U32 => name![u32],
97 (Signedness::Unsigned, IntBitness::X128) => name![u128], 92 BuiltinUint::U64 => name![u64],
93 BuiltinUint::U128 => name![u128],
98 }, 94 },
99 BuiltinType::Float(BuiltinFloat { bitness }) => match bitness { 95 BuiltinType::Float(it) => match it {
100 FloatBitness::X32 => name![f32], 96 BuiltinFloat::F32 => name![f32],
101 FloatBitness::X64 => name![f64], 97 BuiltinFloat::F64 => name![f64],
102 }, 98 },
103 } 99 }
104 } 100 }
@@ -113,31 +109,26 @@ impl fmt::Display for BuiltinType {
113 109
114#[rustfmt::skip] 110#[rustfmt::skip]
115impl BuiltinInt { 111impl BuiltinInt {
116 pub const ISIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::Xsize };
117 pub const I8 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X8 };
118 pub const I16 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X16 };
119 pub const I32 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X32 };
120 pub const I64 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X64 };
121 pub const I128 : BuiltinInt = BuiltinInt { signedness: Signedness::Signed, bitness: IntBitness::X128 };
122
123 pub const USIZE: BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize };
124 pub const U8 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X8 };
125 pub const U16 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X16 };
126 pub const U32 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X32 };
127 pub const U64 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X64 };
128 pub const U128 : BuiltinInt = BuiltinInt { signedness: Signedness::Unsigned, bitness: IntBitness::X128 };
129
130
131 pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> { 112 pub fn from_suffix(suffix: &str) -> Option<BuiltinInt> {
132 let res = match suffix { 113 let res = match suffix {
133 "isize" => Self::ISIZE, 114 "isize" => Self::Isize,
134 "i8" => Self::I8, 115 "i8" => Self::I8,
135 "i16" => Self::I16, 116 "i16" => Self::I16,
136 "i32" => Self::I32, 117 "i32" => Self::I32,
137 "i64" => Self::I64, 118 "i64" => Self::I64,
138 "i128" => Self::I128, 119 "i128" => Self::I128,
139 120
140 "usize" => Self::USIZE, 121 _ => return None,
122 };
123 Some(res)
124 }
125}
126
127#[rustfmt::skip]
128impl BuiltinUint {
129 pub fn from_suffix(suffix: &str) -> Option<BuiltinUint> {
130 let res = match suffix {
131 "usize" => Self::Usize,
141 "u8" => Self::U8, 132 "u8" => Self::U8,
142 "u16" => Self::U16, 133 "u16" => Self::U16,
143 "u32" => Self::U32, 134 "u32" => Self::U32,
@@ -152,9 +143,6 @@ impl BuiltinInt {
152 143
153#[rustfmt::skip] 144#[rustfmt::skip]
154impl BuiltinFloat { 145impl BuiltinFloat {
155 pub const F32: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X32 };
156 pub const F64: BuiltinFloat = BuiltinFloat { bitness: FloatBitness::X64 };
157
158 pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> { 146 pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
159 let res = match suffix { 147 let res = match suffix {
160 "f32" => BuiltinFloat::F32, 148 "f32" => BuiltinFloat::F32,
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs
index ab3f059ce..ac7474f63 100644
--- a/crates/hir_def/src/diagnostics.rs
+++ b/crates/hir_def/src/diagnostics.rs
@@ -95,6 +95,34 @@ impl Diagnostic for UnresolvedImport {
95 } 95 }
96} 96}
97 97
98// Diagnostic: unresolved-macro-call
99//
100// This diagnostic is triggered if rust-analyzer is unable to resolove path to a
101// macro in a macro invocation.
102#[derive(Debug)]
103pub struct UnresolvedMacroCall {
104 pub file: HirFileId,
105 pub node: AstPtr<ast::MacroCall>,
106}
107
108impl Diagnostic for UnresolvedMacroCall {
109 fn code(&self) -> DiagnosticCode {
110 DiagnosticCode("unresolved-macro-call")
111 }
112 fn message(&self) -> String {
113 "unresolved macro call".to_string()
114 }
115 fn display_source(&self) -> InFile<SyntaxNodePtr> {
116 InFile::new(self.file, self.node.clone().into())
117 }
118 fn as_any(&self) -> &(dyn Any + Send + 'static) {
119 self
120 }
121 fn is_experimental(&self) -> bool {
122 true
123 }
124}
125
98// Diagnostic: inactive-code 126// Diagnostic: inactive-code
99// 127//
100// This diagnostic is shown for code with inactive `#[cfg]` attributes. 128// This diagnostic is shown for code with inactive `#[cfg]` attributes.
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index 4d72eaeaf..24be93773 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -17,7 +17,7 @@ use la_arena::{Idx, RawIdx};
17use syntax::ast::RangeOp; 17use syntax::ast::RangeOp;
18 18
19use crate::{ 19use crate::{
20 builtin_type::{BuiltinFloat, BuiltinInt}, 20 builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
21 path::{GenericArgs, Path}, 21 path::{GenericArgs, Path},
22 type_ref::{Mutability, Rawness, TypeRef}, 22 type_ref::{Mutability, Rawness, TypeRef},
23 BlockId, 23 BlockId,
@@ -43,6 +43,7 @@ pub enum Literal {
43 Char(char), 43 Char(char),
44 Bool(bool), 44 Bool(bool),
45 Int(u64, Option<BuiltinInt>), 45 Int(u64, Option<BuiltinInt>),
46 Uint(u64, Option<BuiltinUint>),
46 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq 47 Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
47} 48}
48 49
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 5e2a711b8..3e19a7702 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -1,5 +1,7 @@
1//! An algorithm to find a path to refer to a certain item. 1//! An algorithm to find a path to refer to a certain item.
2 2
3use std::iter;
4
3use hir_expand::name::{known, AsName, Name}; 5use hir_expand::name::{known, AsName, Name};
4use rustc_hash::FxHashSet; 6use rustc_hash::FxHashSet;
5use test_utils::mark; 7use test_utils::mark;
@@ -95,7 +97,7 @@ fn find_path_inner(
95 item: ItemInNs, 97 item: ItemInNs,
96 from: ModuleId, 98 from: ModuleId,
97 max_len: usize, 99 max_len: usize,
98 prefixed: Option<PrefixKind>, 100 mut prefixed: Option<PrefixKind>,
99) -> Option<ModPath> { 101) -> Option<ModPath> {
100 if max_len == 0 { 102 if max_len == 0 {
101 return None; 103 return None;
@@ -114,8 +116,9 @@ fn find_path_inner(
114 } 116 }
115 117
116 // - if the item is the crate root, return `crate` 118 // - if the item is the crate root, return `crate`
117 let root = def_map.module_id(def_map.root()); 119 let root = def_map.crate_root(db);
118 if item == ItemInNs::Types(ModuleDefId::ModuleId(root)) && def_map.block_id().is_none() { 120 if item == ItemInNs::Types(ModuleDefId::ModuleId(root)) && def_map.block_id().is_none() {
121 // FIXME: the `block_id()` check should be unnecessary, but affects the result
119 return Some(ModPath::from_segments(PathKind::Crate, Vec::new())); 122 return Some(ModPath::from_segments(PathKind::Crate, Vec::new()));
120 } 123 }
121 124
@@ -165,7 +168,7 @@ fn find_path_inner(
165 168
166 // - otherwise, look for modules containing (reexporting) it and import it from one of those 169 // - otherwise, look for modules containing (reexporting) it and import it from one of those
167 170
168 let crate_root = def_map.module_id(def_map.root()); 171 let crate_root = def_map.crate_root(db);
169 let crate_attrs = db.attrs(crate_root.into()); 172 let crate_attrs = db.attrs(crate_root.into());
170 let prefer_no_std = crate_attrs.by_key("no_std").exists(); 173 let prefer_no_std = crate_attrs.by_key("no_std").exists();
171 let mut best_path = None; 174 let mut best_path = None;
@@ -228,12 +231,16 @@ fn find_path_inner(
228 } 231 }
229 } 232 }
230 233
231 if let Some(mut prefix) = prefixed.map(PrefixKind::prefix) { 234 // If the item is declared inside a block expression, don't use a prefix, as we don't handle
232 if matches!(prefix, PathKind::Crate | PathKind::Super(0)) && def_map.block_id().is_some() { 235 // that correctly (FIXME).
233 // Inner items cannot be referred to via `crate::` or `self::` paths. 236 if let Some(item_module) = item.as_module_def_id().and_then(|did| did.module(db)) {
234 prefix = PathKind::Plain; 237 if item_module.def_map(db).block_id().is_some() && prefixed.is_some() {
238 mark::hit!(prefixed_in_block_expression);
239 prefixed = Some(PrefixKind::Plain);
235 } 240 }
241 }
236 242
243 if let Some(prefix) = prefixed.map(PrefixKind::prefix) {
237 best_path.or_else(|| { 244 best_path.or_else(|| {
238 scope_name.map(|scope_name| ModPath::from_segments(prefix, vec![scope_name])) 245 scope_name.map(|scope_name| ModPath::from_segments(prefix, vec![scope_name]))
239 }) 246 })
@@ -285,12 +292,12 @@ fn find_local_import_locations(
285 let data = &def_map[from.local_id]; 292 let data = &def_map[from.local_id];
286 let mut worklist = 293 let mut worklist =
287 data.children.values().map(|child| def_map.module_id(*child)).collect::<Vec<_>>(); 294 data.children.values().map(|child| def_map.module_id(*child)).collect::<Vec<_>>();
288 let mut parent = data.parent; 295 for ancestor in iter::successors(from.containing_module(db), |m| m.containing_module(db)) {
289 while let Some(p) = parent { 296 worklist.push(ancestor);
290 worklist.push(def_map.module_id(p));
291 parent = def_map[p].parent;
292 } 297 }
293 298
299 let def_map = def_map.crate_root(db).def_map(db);
300
294 let mut seen: FxHashSet<_> = FxHashSet::default(); 301 let mut seen: FxHashSet<_> = FxHashSet::default();
295 302
296 let mut locations = Vec::new(); 303 let mut locations = Vec::new();
@@ -301,7 +308,14 @@ fn find_local_import_locations(
301 308
302 let ext_def_map; 309 let ext_def_map;
303 let data = if module.krate == from.krate { 310 let data = if module.krate == from.krate {
304 &def_map[module.local_id] 311 if module.block.is_some() {
312 // Re-query the block's DefMap
313 ext_def_map = module.def_map(db);
314 &ext_def_map[module.local_id]
315 } else {
316 // Reuse the root DefMap
317 &def_map[module.local_id]
318 }
305 } else { 319 } else {
306 // The crate might reexport a module defined in another crate. 320 // The crate might reexport a module defined in another crate.
307 ext_def_map = module.def_map(db); 321 ext_def_map = module.def_map(db);
@@ -828,6 +842,7 @@ mod tests {
828 842
829 #[test] 843 #[test]
830 fn inner_items_from_inner_module() { 844 fn inner_items_from_inner_module() {
845 mark::check!(prefixed_in_block_expression);
831 check_found_path( 846 check_found_path(
832 r#" 847 r#"
833 fn main() { 848 fn main() {
@@ -869,4 +884,24 @@ mod tests {
869 "super::Struct", 884 "super::Struct",
870 ); 885 );
871 } 886 }
887
888 #[test]
889 fn outer_items_with_inner_items_present() {
890 check_found_path(
891 r#"
892 mod module {
893 pub struct CompleteMe;
894 }
895
896 fn main() {
897 fn inner() {}
898 $0
899 }
900 "#,
901 "module::CompleteMe",
902 "module::CompleteMe",
903 "crate::module::CompleteMe",
904 "self::module::CompleteMe",
905 )
906 }
872} 907}
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index ee46c3330..4e5daa2ff 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -12,8 +12,8 @@ use stdx::format_to;
12use test_utils::mark; 12use test_utils::mark;
13 13
14use crate::{ 14use crate::{
15 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, 15 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, ImplId,
16 LocalModuleId, Lookup, MacroDefId, ModuleDefId, ModuleId, TraitId, 16 LocalModuleId, MacroDefId, ModuleDefId, ModuleId, TraitId,
17}; 17};
18 18
19#[derive(Copy, Clone)] 19#[derive(Copy, Clone)]
@@ -375,19 +375,9 @@ impl ItemInNs {
375 375
376 /// Returns the crate defining this item (or `None` if `self` is built-in). 376 /// Returns the crate defining this item (or `None` if `self` is built-in).
377 pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> { 377 pub fn krate(&self, db: &dyn DefDatabase) -> Option<CrateId> {
378 Some(match self { 378 match self {
379 ItemInNs::Types(did) | ItemInNs::Values(did) => match did { 379 ItemInNs::Types(did) | ItemInNs::Values(did) => did.module(db).map(|m| m.krate),
380 ModuleDefId::ModuleId(id) => id.krate, 380 ItemInNs::Macros(id) => Some(id.krate),
381 ModuleDefId::FunctionId(id) => id.lookup(db).module(db).krate, 381 }
382 ModuleDefId::AdtId(id) => id.module(db).krate,
383 ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container.module(db).krate,
384 ModuleDefId::ConstId(id) => id.lookup(db).container.module(db).krate,
385 ModuleDefId::StaticId(id) => id.lookup(db).container.module(db).krate,
386 ModuleDefId::TraitId(id) => id.lookup(db).container.module(db).krate,
387 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate,
388 ModuleDefId::BuiltinType(_) => return None,
389 },
390 ItemInNs::Macros(id) => return Some(id.krate),
391 })
392 } 382 }
393} 383}
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index b50923747..4498d94bb 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -57,8 +57,10 @@ use std::{
57 57
58use base_db::{impl_intern_key, salsa, CrateId}; 58use base_db::{impl_intern_key, salsa, CrateId};
59use hir_expand::{ 59use hir_expand::{
60 ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile, 60 ast_id_map::FileAstId,
61 MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 61 eager::{expand_eager_macro, ErrorEmitted},
62 hygiene::Hygiene,
63 AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
62}; 64};
63use la_arena::Idx; 65use la_arena::Idx;
64use nameres::DefMap; 66use nameres::DefMap;
@@ -95,6 +97,10 @@ impl ModuleId {
95 pub fn krate(&self) -> CrateId { 97 pub fn krate(&self) -> CrateId {
96 self.krate 98 self.krate
97 } 99 }
100
101 pub fn containing_module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
102 self.def_map(db).containing_module(self.local_id)
103 }
98} 104}
99 105
100/// An ID of a module, **local** to a specific crate 106/// An ID of a module, **local** to a specific crate
@@ -527,6 +533,25 @@ impl HasModule for StaticLoc {
527 } 533 }
528} 534}
529 535
536impl ModuleDefId {
537 /// Returns the module containing `self` (or `self`, if `self` is itself a module).
538 ///
539 /// Returns `None` if `self` refers to a primitive type.
540 pub fn module(&self, db: &dyn db::DefDatabase) -> Option<ModuleId> {
541 Some(match self {
542 ModuleDefId::ModuleId(id) => *id,
543 ModuleDefId::FunctionId(id) => id.lookup(db).module(db),
544 ModuleDefId::AdtId(id) => id.module(db),
545 ModuleDefId::EnumVariantId(id) => id.parent.lookup(db).container.module(db),
546 ModuleDefId::ConstId(id) => id.lookup(db).container.module(db),
547 ModuleDefId::StaticId(id) => id.lookup(db).container.module(db),
548 ModuleDefId::TraitId(id) => id.lookup(db).container.module(db),
549 ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db),
550 ModuleDefId::BuiltinType(_) => return None,
551 })
552 }
553}
554
530impl AttrDefId { 555impl AttrDefId {
531 pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { 556 pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
532 match self { 557 match self {
@@ -592,8 +617,15 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
592 error_sink(mbe::ExpandError::Other("malformed macro invocation".into())); 617 error_sink(mbe::ExpandError::Other("malformed macro invocation".into()));
593 } 618 }
594 619
595 AstIdWithPath::new(ast_id.file_id, ast_id.value, path?) 620 macro_call_as_call_id(
596 .as_call_id_with_errors(db, krate, resolver, error_sink) 621 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path?),
622 db,
623 krate,
624 resolver,
625 error_sink,
626 )
627 .ok()?
628 .ok()
597 } 629 }
598} 630}
599 631
@@ -610,61 +642,50 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
610 } 642 }
611} 643}
612 644
613impl AsMacroCall for AstIdWithPath<ast::MacroCall> { 645struct UnresolvedMacro;
614 fn as_call_id_with_errors( 646
615 &self, 647fn macro_call_as_call_id(
616 db: &dyn db::DefDatabase, 648 call: &AstIdWithPath<ast::MacroCall>,
617 krate: CrateId, 649 db: &dyn db::DefDatabase,
618 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 650 krate: CrateId,
619 error_sink: &mut dyn FnMut(mbe::ExpandError), 651 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
620 ) -> Option<MacroCallId> { 652 error_sink: &mut dyn FnMut(mbe::ExpandError),
621 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 653) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
622 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 654 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
623 None 655
624 })?; 656 let res = if let MacroDefKind::BuiltInEager(_) = def.kind {
625 657 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
626 if let MacroDefKind::BuiltInEager(_) = def.kind { 658 let hygiene = Hygiene::new(db.upcast(), call.ast_id.file_id);
627 let macro_call = InFile::new(self.ast_id.file_id, self.ast_id.to_node(db.upcast())); 659
628 let hygiene = Hygiene::new(db.upcast(), self.ast_id.file_id); 660 expand_eager_macro(
629 661 db.upcast(),
630 Some( 662 krate,
631 expand_eager_macro( 663 macro_call,
632 db.upcast(), 664 def,
633 krate, 665 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?),
634 macro_call, 666 error_sink,
635 def, 667 )
636 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), 668 .map(MacroCallId::from)
637 error_sink, 669 } else {
638 ) 670 Ok(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(call.ast_id)).into())
639 .ok()? 671 };
640 .into(), 672 Ok(res)
641 )
642 } else {
643 Some(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(self.ast_id)).into())
644 }
645 }
646} 673}
647 674
648impl AsMacroCall for AstIdWithPath<ast::Item> { 675fn item_attr_as_call_id(
649 fn as_call_id_with_errors( 676 item_attr: &AstIdWithPath<ast::Item>,
650 &self, 677 db: &dyn db::DefDatabase,
651 db: &dyn db::DefDatabase, 678 krate: CrateId,
652 krate: CrateId, 679 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
653 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 680) -> Result<MacroCallId, UnresolvedMacro> {
654 error_sink: &mut dyn FnMut(mbe::ExpandError), 681 let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?;
655 ) -> Option<MacroCallId> { 682 let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?;
656 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 683 let res = def
657 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 684 .as_lazy_macro(
658 None 685 db.upcast(),
659 })?; 686 krate,
660 687 MacroCallKind::Attr(item_attr.ast_id, last_segment.to_string()),
661 Some(
662 def.as_lazy_macro(
663 db.upcast(),
664 krate,
665 MacroCallKind::Attr(self.ast_id, self.path.segments().last()?.to_string()),
666 )
667 .into(),
668 ) 688 )
669 } 689 .into();
690 Ok(res)
670} 691}
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index f92232eb3..003d668ca 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -343,6 +343,18 @@ impl DefMap {
343 Some(self.block?.parent) 343 Some(self.block?.parent)
344 } 344 }
345 345
346 /// Returns the module containing `local_mod`, either the parent `mod`, or the module containing
347 /// the block, if `self` corresponds to a block expression.
348 pub fn containing_module(&self, local_mod: LocalModuleId) -> Option<ModuleId> {
349 match &self[local_mod].parent {
350 Some(parent) => Some(self.module_id(*parent)),
351 None => match &self.block {
352 Some(block) => Some(block.parent),
353 None => None,
354 },
355 }
356 }
357
346 // FIXME: this can use some more human-readable format (ideally, an IR 358 // FIXME: this can use some more human-readable format (ideally, an IR
347 // even), as this should be a great debugging aid. 359 // even), as this should be a great debugging aid.
348 pub fn dump(&self, db: &dyn DefDatabase) -> String { 360 pub fn dump(&self, db: &dyn DefDatabase) -> String {
@@ -417,6 +429,8 @@ mod diagnostics {
417 429
418 UnresolvedProcMacro { ast: MacroCallKind }, 430 UnresolvedProcMacro { ast: MacroCallKind },
419 431
432 UnresolvedMacroCall { ast: AstId<ast::MacroCall> },
433
420 MacroError { ast: MacroCallKind, message: String }, 434 MacroError { ast: MacroCallKind, message: String },
421 } 435 }
422 436
@@ -477,6 +491,13 @@ mod diagnostics {
477 Self { in_module: container, kind: DiagnosticKind::MacroError { ast, message } } 491 Self { in_module: container, kind: DiagnosticKind::MacroError { ast, message } }
478 } 492 }
479 493
494 pub(super) fn unresolved_macro_call(
495 container: LocalModuleId,
496 ast: AstId<ast::MacroCall>,
497 ) -> Self {
498 Self { in_module: container, kind: DiagnosticKind::UnresolvedMacroCall { ast } }
499 }
500
480 pub(super) fn add_to( 501 pub(super) fn add_to(
481 &self, 502 &self,
482 db: &dyn DefDatabase, 503 db: &dyn DefDatabase,
@@ -589,6 +610,11 @@ mod diagnostics {
589 }); 610 });
590 } 611 }
591 612
613 DiagnosticKind::UnresolvedMacroCall { ast } => {
614 let node = ast.to_node(db.upcast());
615 sink.push(UnresolvedMacroCall { file: ast.file_id, node: AstPtr::new(&node) });
616 }
617
592 DiagnosticKind::MacroError { ast, message } => { 618 DiagnosticKind::MacroError { ast, message } => {
593 let (file, ast) = match ast { 619 let (file, ast) = match ast {
594 MacroCallKind::FnLike(ast) => { 620 MacroCallKind::FnLike(ast) => {
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 9996a0807..e51d89b43 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -13,7 +13,7 @@ use hir_expand::{
13 builtin_macro::find_builtin_macro, 13 builtin_macro::find_builtin_macro,
14 name::{AsName, Name}, 14 name::{AsName, Name},
15 proc_macro::ProcMacroExpander, 15 proc_macro::ProcMacroExpander,
16 HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 16 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
17}; 17};
18use hir_expand::{InFile, MacroCallLoc}; 18use hir_expand::{InFile, MacroCallLoc};
19use rustc_hash::{FxHashMap, FxHashSet}; 19use rustc_hash::{FxHashMap, FxHashSet};
@@ -24,11 +24,13 @@ use tt::{Leaf, TokenTree};
24use crate::{ 24use crate::{
25 attr::Attrs, 25 attr::Attrs,
26 db::DefDatabase, 26 db::DefDatabase,
27 item_attr_as_call_id,
27 item_scope::{ImportType, PerNsGlobImports}, 28 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 29 item_tree::{
29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, 30 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30 StructDefKind, 31 StructDefKind,
31 }, 32 },
33 macro_call_as_call_id,
32 nameres::{ 34 nameres::{
33 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 35 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
34 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode, 36 BuiltinShadowMode, DefMap, ModuleData, ModuleOrigin, ResolveMode,
@@ -36,9 +38,9 @@ use crate::{
36 path::{ImportAlias, ModPath, PathKind}, 38 path::{ImportAlias, ModPath, PathKind},
37 per_ns::PerNs, 39 per_ns::PerNs,
38 visibility::{RawVisibility, Visibility}, 40 visibility::{RawVisibility, Visibility},
39 AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, 41 AdtId, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc,
40 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, 42 ImplLoc, Intern, LocalModuleId, ModuleDefId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc,
41 TypeAliasLoc, UnionLoc, 43 UnionLoc, UnresolvedMacro,
42}; 44};
43 45
44const GLOB_RECURSION_LIMIT: usize = 100; 46const GLOB_RECURSION_LIMIT: usize = 100;
@@ -790,8 +792,11 @@ impl DefCollector<'_> {
790 return false; 792 return false;
791 } 793 }
792 794
793 if let Some(call_id) = 795 match macro_call_as_call_id(
794 directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { 796 &directive.ast_id,
797 self.db,
798 self.def_map.krate,
799 |path| {
795 let resolved_res = self.def_map.resolve_path_fp_with_macro( 800 let resolved_res = self.def_map.resolve_path_fp_with_macro(
796 self.db, 801 self.db,
797 ResolveMode::Other, 802 ResolveMode::Other,
@@ -800,24 +805,29 @@ impl DefCollector<'_> {
800 BuiltinShadowMode::Module, 805 BuiltinShadowMode::Module,
801 ); 806 );
802 resolved_res.resolved_def.take_macros() 807 resolved_res.resolved_def.take_macros()
803 }) 808 },
804 { 809 &mut |_err| (),
805 resolved.push((directive.module_id, call_id, directive.depth)); 810 ) {
806 res = ReachedFixedPoint::No; 811 Ok(Ok(call_id)) => {
807 return false; 812 resolved.push((directive.module_id, call_id, directive.depth));
813 res = ReachedFixedPoint::No;
814 return false;
815 }
816 Err(UnresolvedMacro) | Ok(Err(_)) => {}
808 } 817 }
809 818
810 true 819 true
811 }); 820 });
812 attribute_macros.retain(|directive| { 821 attribute_macros.retain(|directive| {
813 if let Some(call_id) = 822 match item_attr_as_call_id(&directive.ast_id, self.db, self.def_map.krate, |path| {
814 directive.ast_id.as_call_id(self.db, self.def_map.krate, |path| { 823 self.resolve_attribute_macro(&directive, &path)
815 self.resolve_attribute_macro(&directive, &path) 824 }) {
816 }) 825 Ok(call_id) => {
817 { 826 resolved.push((directive.module_id, call_id, 0));
818 resolved.push((directive.module_id, call_id, 0)); 827 res = ReachedFixedPoint::No;
819 res = ReachedFixedPoint::No; 828 return false;
820 return false; 829 }
830 Err(UnresolvedMacro) => (),
821 } 831 }
822 832
823 true 833 true
@@ -902,7 +912,8 @@ impl DefCollector<'_> {
902 912
903 for directive in &self.unexpanded_macros { 913 for directive in &self.unexpanded_macros {
904 let mut error = None; 914 let mut error = None;
905 directive.ast_id.as_call_id_with_errors( 915 match macro_call_as_call_id(
916 &directive.ast_id,
906 self.db, 917 self.db,
907 self.def_map.krate, 918 self.def_map.krate,
908 |path| { 919 |path| {
@@ -918,15 +929,15 @@ impl DefCollector<'_> {
918 &mut |e| { 929 &mut |e| {
919 error.get_or_insert(e); 930 error.get_or_insert(e);
920 }, 931 },
921 ); 932 ) {
922 933 Ok(_) => (),
923 if let Some(err) = error { 934 Err(UnresolvedMacro) => {
924 self.def_map.diagnostics.push(DefDiagnostic::macro_error( 935 self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
925 directive.module_id, 936 directive.module_id,
926 MacroCallKind::FnLike(directive.ast_id.ast_id), 937 directive.ast_id.ast_id,
927 err.to_string(), 938 ));
928 )); 939 }
929 } 940 };
930 } 941 }
931 942
932 // Emit diagnostics for all remaining unresolved imports. 943 // Emit diagnostics for all remaining unresolved imports.
@@ -1446,8 +1457,11 @@ impl ModCollector<'_, '_> {
1446 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); 1457 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
1447 1458
1448 // Case 1: try to resolve in legacy scope and expand macro_rules 1459 // Case 1: try to resolve in legacy scope and expand macro_rules
1449 if let Some(macro_call_id) = 1460 if let Ok(Ok(macro_call_id)) = macro_call_as_call_id(
1450 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { 1461 &ast_id,
1462 self.def_collector.db,
1463 self.def_collector.def_map.krate,
1464 |path| {
1451 path.as_ident().and_then(|name| { 1465 path.as_ident().and_then(|name| {
1452 self.def_collector.def_map.with_ancestor_maps( 1466 self.def_collector.def_map.with_ancestor_maps(
1453 self.def_collector.db, 1467 self.def_collector.db,
@@ -1455,8 +1469,9 @@ impl ModCollector<'_, '_> {
1455 &mut |map, module| map[module].scope.get_legacy_macro(&name), 1469 &mut |map, module| map[module].scope.get_legacy_macro(&name),
1456 ) 1470 )
1457 }) 1471 })
1458 }) 1472 },
1459 { 1473 &mut |_err| (),
1474 ) {
1460 self.def_collector.unexpanded_macros.push(MacroDirective { 1475 self.def_collector.unexpanded_macros.push(MacroDirective {
1461 module_id: self.module_id, 1476 module_id: self.module_id,
1462 ast_id, 1477 ast_id,
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs
index fdcdc23ae..dd1db0094 100644
--- a/crates/hir_def/src/nameres/path_resolution.rs
+++ b/crates/hir_def/src/nameres/path_resolution.rs
@@ -77,7 +77,7 @@ impl DefMap {
77 original_module: LocalModuleId, 77 original_module: LocalModuleId,
78 visibility: &RawVisibility, 78 visibility: &RawVisibility,
79 ) -> Option<Visibility> { 79 ) -> Option<Visibility> {
80 match visibility { 80 let mut vis = match visibility {
81 RawVisibility::Module(path) => { 81 RawVisibility::Module(path) => {
82 let (result, remaining) = 82 let (result, remaining) =
83 self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); 83 self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
@@ -86,15 +86,28 @@ impl DefMap {
86 } 86 }
87 let types = result.take_types()?; 87 let types = result.take_types()?;
88 match types { 88 match types {
89 ModuleDefId::ModuleId(m) => Some(Visibility::Module(m)), 89 ModuleDefId::ModuleId(m) => Visibility::Module(m),
90 _ => { 90 _ => {
91 // error: visibility needs to refer to module 91 // error: visibility needs to refer to module
92 None 92 return None;
93 } 93 }
94 } 94 }
95 } 95 }
96 RawVisibility::Public => Some(Visibility::Public), 96 RawVisibility::Public => Visibility::Public,
97 };
98
99 // In block expressions, `self` normally refers to the containing non-block module, and
100 // `super` to its parent (etc.). However, visibilities must only refer to a module in the
101 // DefMap they're written in, so we restrict them when that happens.
102 if let Visibility::Module(m) = vis {
103 if self.block_id() != m.block {
104 mark::hit!(adjust_vis_in_block_def_map);
105 vis = Visibility::Module(self.module_id(self.root()));
106 log::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
107 }
97 } 108 }
109
110 Some(vis)
98 } 111 }
99 112
100 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change 113 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index a469546c1..505493a74 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -101,8 +101,12 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
101 break; 101 break;
102 } 102 }
103 ast::PathSegmentKind::SelfKw => { 103 ast::PathSegmentKind::SelfKw => {
104 kind = PathKind::Super(0); 104 // don't break out if `self` is the last segment of a path, this mean we got an
105 break; 105 // use tree like `foo::{self}` which we want to resolve as `foo`
106 if !segments.is_empty() {
107 kind = PathKind::Super(0);
108 break;
109 }
106 } 110 }
107 ast::PathSegmentKind::SuperKw => { 111 ast::PathSegmentKind::SuperKw => {
108 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 }; 112 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 };
@@ -117,6 +121,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
117 segments.reverse(); 121 segments.reverse();
118 generic_args.reverse(); 122 generic_args.reverse();
119 123
124 if segments.is_empty() && kind == PathKind::Plain && type_anchor.is_none() {
125 // plain empty paths don't exist, this means we got a single `self` segment as our path
126 kind = PathKind::Super(0);
127 }
128
120 // handle local_inner_macros : 129 // handle local_inner_macros :
121 // Basically, even in rustc it is quite hacky: 130 // Basically, even in rustc it is quite hacky:
122 // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 131 // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs
index 57bc6fbd7..eb57ea7d6 100644
--- a/crates/hir_expand/src/builtin_macro.rs
+++ b/crates/hir_expand/src/builtin_macro.rs
@@ -6,7 +6,7 @@ use crate::{
6 6
7use base_db::{AnchoredPath, FileId}; 7use base_db::{AnchoredPath, FileId};
8use either::Either; 8use either::Either;
9use mbe::{parse_to_token_tree, ExpandResult}; 9use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
10use parser::FragmentKind; 10use parser::FragmentKind;
11use syntax::ast::{self, AstToken}; 11use syntax::ast::{self, AstToken};
12 12
@@ -182,25 +182,10 @@ fn assert_expand(
182 // ```, 182 // ```,
183 // which is wrong but useful. 183 // which is wrong but useful.
184 184
185 let mut args = Vec::new(); 185 let args = parse_exprs_with_sep(tt, ',');
186 let mut current = Vec::new();
187 for tt in tt.token_trees.iter().cloned() {
188 match tt {
189 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
190 args.push(current);
191 current = Vec::new();
192 }
193 _ => {
194 current.push(tt);
195 }
196 }
197 }
198 if !current.is_empty() {
199 args.push(current);
200 }
201 186
202 let arg_tts = args.into_iter().flat_map(|arg| { 187 let arg_tts = args.into_iter().flat_map(|arg| {
203 quote! { &(##arg), } 188 quote! { &(#arg), }
204 }.token_trees).collect::<Vec<_>>(); 189 }.token_trees).collect::<Vec<_>>();
205 190
206 let expanded = quote! { 191 let expanded = quote! {
@@ -238,35 +223,21 @@ fn format_args_expand(
238 // ]) 223 // ])
239 // ```, 224 // ```,
240 // which is still not really correct, but close enough for now 225 // which is still not really correct, but close enough for now
241 let mut args = Vec::new(); 226 let mut args = parse_exprs_with_sep(tt, ',');
242 let mut current = Vec::new(); 227
243 for tt in tt.token_trees.iter().cloned() {
244 match tt {
245 tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
246 args.push(current);
247 current = Vec::new();
248 }
249 _ => {
250 current.push(tt);
251 }
252 }
253 }
254 if !current.is_empty() {
255 args.push(current);
256 }
257 if args.is_empty() { 228 if args.is_empty() {
258 return ExpandResult::only_err(mbe::ExpandError::NoMatchingRule); 229 return ExpandResult::only_err(mbe::ExpandError::NoMatchingRule);
259 } 230 }
260 for arg in &mut args { 231 for arg in &mut args {
261 // Remove `key =`. 232 // Remove `key =`.
262 if matches!(arg.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint) 233 if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint)
263 { 234 {
264 arg.drain(..2); 235 arg.token_trees.drain(..2);
265 } 236 }
266 } 237 }
267 let _format_string = args.remove(0); 238 let _format_string = args.remove(0);
268 let arg_tts = args.into_iter().flat_map(|arg| { 239 let arg_tts = args.into_iter().flat_map(|arg| {
269 quote! { std::fmt::ArgumentV1::new(&(##arg), std::fmt::Display::fmt), } 240 quote! { std::fmt::ArgumentV1::new(&(#arg), std::fmt::Display::fmt), }
270 }.token_trees).collect::<Vec<_>>(); 241 }.token_trees).collect::<Vec<_>>();
271 let expanded = quote! { 242 let expanded = quote! {
272 std::fmt::Arguments::new_v1(&[], &[##arg_tts]) 243 std::fmt::Arguments::new_v1(&[], &[##arg_tts])
@@ -720,6 +691,25 @@ mod tests {
720 } 691 }
721 692
722 #[test] 693 #[test]
694 fn test_format_args_expand_with_comma_exprs() {
695 let expanded = expand_builtin_macro(
696 r#"
697 #[rustc_builtin_macro]
698 macro_rules! format_args {
699 ($fmt:expr) => ({ /* compiler built-in */ });
700 ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ })
701 }
702 format_args!("{} {:?}", a::<A,B>(), b);
703 "#,
704 );
705
706 assert_eq!(
707 expanded,
708 r#"std::fmt::Arguments::new_v1(&[], &[std::fmt::ArgumentV1::new(&(a::<A,B>()),std::fmt::Display::fmt),std::fmt::ArgumentV1::new(&(b),std::fmt::Display::fmt),])"#
709 );
710 }
711
712 #[test]
723 fn test_include_bytes_expand() { 713 fn test_include_bytes_expand() {
724 let expanded = expand_builtin_macro( 714 let expanded = expand_builtin_macro(
725 r#" 715 r#"
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index c7609e90d..c94fb580a 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -189,6 +189,7 @@ pub mod known {
189 // Components of known path (function name) 189 // Components of known path (function name)
190 filter_map, 190 filter_map,
191 next, 191 next,
192 iter_mut,
192 // Builtin macros 193 // Builtin macros
193 file, 194 file,
194 column, 195 column,
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 6ef9d1e7e..d1302d749 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.58", default-features = false } 20chalk-solve = { version = "0.59", default-features = false }
21chalk-ir = "0.58" 21chalk-ir = "0.59"
22chalk-recursive = "0.58" 22chalk-recursive = "0.59"
23la-arena = { version = "0.2.0", path = "../../lib/arena" } 23la-arena = { version = "0.2.0", path = "../../lib/arena" }
24 24
25stdx = { path = "../stdx", version = "0.0.0" } 25stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index ece68183e..be1fd1f13 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -81,7 +81,7 @@ fn deref_by_trait(
81 81
82 // Now do the assoc type projection 82 // Now do the assoc type projection
83 let projection = super::traits::ProjectionPredicate { 83 let projection = super::traits::ProjectionPredicate {
84 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 84 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())),
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 85 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
86 }; 86 };
87 87
@@ -89,8 +89,10 @@ fn deref_by_trait(
89 89
90 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 90 let in_env = InEnvironment { value: obligation, environment: ty.environment };
91 91
92 let canonical = 92 let canonical = Canonical::new(
93 Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); 93 in_env,
94 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)),
95 );
94 96
95 let solution = db.trait_solve(krate, canonical)?; 97 let solution = db.trait_solve(krate, canonical)?;
96 98
@@ -112,7 +114,8 @@ fn deref_by_trait(
112 // new variables in that case 114 // new variables in that case
113 115
114 for i in 1..vars.0.kinds.len() { 116 for i in 1..vars.0.kinds.len() {
115 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 117 if vars.0.value[i - 1]
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
116 { 119 {
117 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
118 return None; 121 return None;
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index d740b7265..66a88e2b6 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -17,7 +17,7 @@ use crate::{
17 MissingPatFields, RemoveThisSemicolon, 17 MissingPatFields, RemoveThisSemicolon,
18 }, 18 },
19 utils::variant_data, 19 utils::variant_data,
20 ApplicationTy, InferenceResult, Ty, TypeCtor, 20 InferenceResult, Ty,
21}; 21};
22 22
23pub(crate) use hir_def::{ 23pub(crate) use hir_def::{
@@ -381,14 +381,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
381 _ => return, 381 _ => return,
382 }; 382 };
383 383
384 let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); 384 let (params, required) = match mismatch.expected {
385 let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); 385 Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_result_enum => {
386
387 let (params, required) = match &mismatch.expected {
388 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => {
389 (parameters, "Ok".to_string()) 386 (parameters, "Ok".to_string())
390 } 387 }
391 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { 388 Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_option_enum => {
392 (parameters, "Some".to_string()) 389 (parameters, "Some".to_string())
393 } 390 }
394 _ => return, 391 _ => return,
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 1c1423fbf..86fee0050 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -227,7 +227,7 @@ use hir_def::{
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; 230use crate::{db::HirDatabase, InferenceResult, Ty};
231 231
232#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
233/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
@@ -627,14 +627,12 @@ pub(super) fn is_useful(
627 // - `!` type 627 // - `!` type
628 // In those cases, no match arm is useful. 628 // In those cases, no match arm is useful.
629 match cx.infer[cx.match_expr].strip_references() { 629 match cx.infer[cx.match_expr].strip_references() {
630 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { 630 Ty::Adt(AdtId::EnumId(enum_id), ..) => {
631 if cx.db.enum_data(*enum_id).variants.is_empty() { 631 if cx.db.enum_data(*enum_id).variants.is_empty() {
632 return Ok(Usefulness::NotUseful); 632 return Ok(Usefulness::NotUseful);
633 } 633 }
634 } 634 }
635 Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { 635 Ty::Never => return Ok(Usefulness::NotUseful),
636 return Ok(Usefulness::NotUseful);
637 }
638 _ => (), 636 _ => (),
639 } 637 }
640 638
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 9c506112d..e77a20fea 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,9 +11,7 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{ 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty};
15 db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor,
16};
17 15
18pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(super) struct UnsafeValidator<'a, 'b: 'a> {
19 owner: DefWithBodyId, 17 owner: DefWithBodyId,
@@ -112,7 +110,7 @@ fn walk_unsafe(
112 } 110 }
113 } 111 }
114 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
115 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { 113 if let Ty::Raw(..) = &infer[*expr] {
116 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
117 } 115 }
118 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 271fcbfaf..d4a8b48e6 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,10 +3,12 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, 6 db::HirDatabase, primitive, utils::generics, AliasTy, CallableDefId, CallableSig,
7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs,
8 TraitRef, Ty,
8}; 9};
9use arrayvec::ArrayVec; 10use arrayvec::ArrayVec;
11use chalk_ir::Mutability;
10use hir_def::{ 12use hir_def::{
11 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, 13 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId,
12 AssocContainerId, HasModule, Lookup, ModuleId, TraitId, 14 AssocContainerId, HasModule, Lookup, ModuleId, TraitId,
@@ -234,39 +236,79 @@ impl HirDisplay for &Ty {
234 } 236 }
235} 237}
236 238
237impl HirDisplay for ApplicationTy { 239impl HirDisplay for ProjectionTy {
238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 240 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
239 if f.should_truncate() { 241 if f.should_truncate() {
240 return write!(f, "{}", TYPE_HINT_TRUNCATION); 242 return write!(f, "{}", TYPE_HINT_TRUNCATION);
241 } 243 }
242 244
243 match self.ctor { 245 let trait_ = f.db.trait_data(self.trait_(f.db));
244 TypeCtor::Bool => write!(f, "bool")?, 246 let first_parameter = self.parameters[0].into_displayable(
245 TypeCtor::Char => write!(f, "char")?, 247 f.db,
246 TypeCtor::Int(t) => write!(f, "{}", t)?, 248 f.max_size,
247 TypeCtor::Float(t) => write!(f, "{}", t)?, 249 f.omit_verbose_types,
248 TypeCtor::Str => write!(f, "str")?, 250 f.display_target,
249 TypeCtor::Slice => { 251 );
250 let t = self.parameters.as_single(); 252 write!(f, "<{} as {}", first_parameter, trait_.name)?;
253 if self.parameters.len() > 1 {
254 write!(f, "<")?;
255 f.write_joined(&self.parameters[1..], ", ")?;
256 write!(f, ">")?;
257 }
258 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
259 Ok(())
260 }
261}
262
263impl HirDisplay for Ty {
264 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
265 if f.should_truncate() {
266 return write!(f, "{}", TYPE_HINT_TRUNCATION);
267 }
268
269 match self {
270 Ty::Never => write!(f, "!")?,
271 Ty::Str => write!(f, "str")?,
272 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
273 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
274 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
275 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
276 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
277 Ty::Slice(parameters) => {
278 let t = parameters.as_single();
251 write!(f, "[")?; 279 write!(f, "[")?;
252 t.hir_fmt(f)?; 280 t.hir_fmt(f)?;
253 write!(f, "]")?; 281 write!(f, "]")?;
254 } 282 }
255 TypeCtor::Array => { 283 Ty::Array(parameters) => {
256 let t = self.parameters.as_single(); 284 let t = parameters.as_single();
257 write!(f, "[")?; 285 write!(f, "[")?;
258 t.hir_fmt(f)?; 286 t.hir_fmt(f)?;
259 write!(f, "; _]")?; 287 write!(f, "; _]")?;
260 } 288 }
261 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 289 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => {
262 let t = self.parameters.as_single(); 290 let t = parameters.as_single();
263 let ty_display = 291 let ty_display =
264 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 292 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
265 293
266 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 294 if matches!(self, Ty::Raw(..)) {
267 write!(f, "*{}", m.as_keyword_for_ptr())?; 295 write!(
296 f,
297 "*{}",
298 match m {
299 Mutability::Not => "const ",
300 Mutability::Mut => "mut ",
301 }
302 )?;
268 } else { 303 } else {
269 write!(f, "&{}", m.as_keyword_for_ref())?; 304 write!(
305 f,
306 "&{}",
307 match m {
308 Mutability::Not => "",
309 Mutability::Mut => "mut ",
310 }
311 )?;
270 } 312 }
271 313
272 let datas; 314 let datas;
@@ -274,10 +316,10 @@ impl HirDisplay for ApplicationTy {
274 Ty::Dyn(predicates) if predicates.len() > 1 => { 316 Ty::Dyn(predicates) if predicates.len() > 1 => {
275 Cow::Borrowed(predicates.as_ref()) 317 Cow::Borrowed(predicates.as_ref())
276 } 318 }
277 &Ty::Opaque(OpaqueTy { 319 &Ty::Alias(AliasTy::Opaque(OpaqueTy {
278 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 320 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
279 ref parameters, 321 ref parameters,
280 }) => { 322 })) => {
281 datas = 323 datas =
282 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 324 f.db.return_type_impl_traits(func).expect("impl trait id without data");
283 let data = (*datas) 325 let data = (*datas)
@@ -304,25 +346,24 @@ impl HirDisplay for ApplicationTy {
304 write!(f, "{}", ty_display)?; 346 write!(f, "{}", ty_display)?;
305 } 347 }
306 } 348 }
307 TypeCtor::Never => write!(f, "!")?, 349 Ty::Tuple(_, substs) => {
308 TypeCtor::Tuple { .. } => { 350 if substs.len() == 1 {
309 let ts = &self.parameters;
310 if ts.len() == 1 {
311 write!(f, "(")?; 351 write!(f, "(")?;
312 ts[0].hir_fmt(f)?; 352 substs[0].hir_fmt(f)?;
313 write!(f, ",)")?; 353 write!(f, ",)")?;
314 } else { 354 } else {
315 write!(f, "(")?; 355 write!(f, "(")?;
316 f.write_joined(&*ts.0, ", ")?; 356 f.write_joined(&*substs.0, ", ")?;
317 write!(f, ")")?; 357 write!(f, ")")?;
318 } 358 }
319 } 359 }
320 TypeCtor::FnPtr { is_varargs, .. } => { 360 Ty::Function(fn_ptr) => {
321 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 361 let sig = CallableSig::from_fn_ptr(fn_ptr);
322 sig.hir_fmt(f)?; 362 sig.hir_fmt(f)?;
323 } 363 }
324 TypeCtor::FnDef(def) => { 364 Ty::FnDef(def, parameters) => {
325 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 365 let def = *def;
366 let sig = f.db.callable_item_signature(def).subst(parameters);
326 match def { 367 match def {
327 CallableDefId::FunctionId(ff) => { 368 CallableDefId::FunctionId(ff) => {
328 write!(f, "fn {}", f.db.function_data(ff).name)? 369 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -332,7 +373,7 @@ impl HirDisplay for ApplicationTy {
332 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 373 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
333 } 374 }
334 }; 375 };
335 if self.parameters.len() > 0 { 376 if parameters.len() > 0 {
336 let generics = generics(f.db.upcast(), def.into()); 377 let generics = generics(f.db.upcast(), def.into());
337 let (parent_params, self_param, type_params, _impl_trait_params) = 378 let (parent_params, self_param, type_params, _impl_trait_params) =
338 generics.provenance_split(); 379 generics.provenance_split();
@@ -340,7 +381,7 @@ impl HirDisplay for ApplicationTy {
340 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 381 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
341 if total_len > 0 { 382 if total_len > 0 {
342 write!(f, "<")?; 383 write!(f, "<")?;
343 f.write_joined(&self.parameters.0[..total_len], ", ")?; 384 f.write_joined(&parameters.0[..total_len], ", ")?;
344 write!(f, ">")?; 385 write!(f, ">")?;
345 } 386 }
346 } 387 }
@@ -359,10 +400,10 @@ impl HirDisplay for ApplicationTy {
359 write!(f, " -> {}", ret_display)?; 400 write!(f, " -> {}", ret_display)?;
360 } 401 }
361 } 402 }
362 TypeCtor::Adt(def_id) => { 403 Ty::Adt(def_id, parameters) => {
363 match f.display_target { 404 match f.display_target {
364 DisplayTarget::Diagnostics | DisplayTarget::Test => { 405 DisplayTarget::Diagnostics | DisplayTarget::Test => {
365 let name = match def_id { 406 let name = match *def_id {
366 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 407 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
367 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 408 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
368 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), 409 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
@@ -372,7 +413,7 @@ impl HirDisplay for ApplicationTy {
372 DisplayTarget::SourceCode { module_id } => { 413 DisplayTarget::SourceCode { module_id } => {
373 if let Some(path) = find_path::find_path( 414 if let Some(path) = find_path::find_path(
374 f.db.upcast(), 415 f.db.upcast(),
375 ItemInNs::Types(def_id.into()), 416 ItemInNs::Types((*def_id).into()),
376 module_id, 417 module_id,
377 ) { 418 ) {
378 write!(f, "{}", path)?; 419 write!(f, "{}", path)?;
@@ -384,19 +425,18 @@ impl HirDisplay for ApplicationTy {
384 } 425 }
385 } 426 }
386 427
387 if self.parameters.len() > 0 { 428 if parameters.len() > 0 {
388 let parameters_to_write = 429 let parameters_to_write =
389 if f.display_target.is_source_code() || f.omit_verbose_types() { 430 if f.display_target.is_source_code() || f.omit_verbose_types() {
390 match self 431 match self
391 .ctor
392 .as_generic_def() 432 .as_generic_def()
393 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 433 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
394 .filter(|defaults| !defaults.is_empty()) 434 .filter(|defaults| !defaults.is_empty())
395 { 435 {
396 None => self.parameters.0.as_ref(), 436 None => parameters.0.as_ref(),
397 Some(default_parameters) => { 437 Some(default_parameters) => {
398 let mut default_from = 0; 438 let mut default_from = 0;
399 for (i, parameter) in self.parameters.iter().enumerate() { 439 for (i, parameter) in parameters.iter().enumerate() {
400 match (parameter, default_parameters.get(i)) { 440 match (parameter, default_parameters.get(i)) {
401 (&Ty::Unknown, _) | (_, None) => { 441 (&Ty::Unknown, _) | (_, None) => {
402 default_from = i + 1; 442 default_from = i + 1;
@@ -404,18 +444,18 @@ impl HirDisplay for ApplicationTy {
404 (_, Some(default_parameter)) => { 444 (_, Some(default_parameter)) => {
405 let actual_default = default_parameter 445 let actual_default = default_parameter
406 .clone() 446 .clone()
407 .subst(&self.parameters.prefix(i)); 447 .subst(&parameters.prefix(i));
408 if parameter != &actual_default { 448 if parameter != &actual_default {
409 default_from = i + 1; 449 default_from = i + 1;
410 } 450 }
411 } 451 }
412 } 452 }
413 } 453 }
414 &self.parameters.0[0..default_from] 454 &parameters.0[0..default_from]
415 } 455 }
416 } 456 }
417 } else { 457 } else {
418 self.parameters.0.as_ref() 458 parameters.0.as_ref()
419 }; 459 };
420 if !parameters_to_write.is_empty() { 460 if !parameters_to_write.is_empty() {
421 write!(f, "<")?; 461 write!(f, "<")?;
@@ -424,61 +464,54 @@ impl HirDisplay for ApplicationTy {
424 } 464 }
425 } 465 }
426 } 466 }
427 TypeCtor::AssociatedType(type_alias) => { 467 Ty::AssociatedType(type_alias, parameters) => {
428 let trait_ = match type_alias.lookup(f.db.upcast()).container { 468 let trait_ = match type_alias.lookup(f.db.upcast()).container {
429 AssocContainerId::TraitId(it) => it, 469 AssocContainerId::TraitId(it) => it,
430 _ => panic!("not an associated type"), 470 _ => panic!("not an associated type"),
431 }; 471 };
432 let trait_ = f.db.trait_data(trait_); 472 let trait_ = f.db.trait_data(trait_);
433 let type_alias_data = f.db.type_alias_data(type_alias); 473 let type_alias_data = f.db.type_alias_data(*type_alias);
434 474
435 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 475 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
436 if f.display_target.is_test() { 476 if f.display_target.is_test() {
437 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 477 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
438 if self.parameters.len() > 0 { 478 if parameters.len() > 0 {
439 write!(f, "<")?; 479 write!(f, "<")?;
440 f.write_joined(&*self.parameters.0, ", ")?; 480 f.write_joined(&*parameters.0, ", ")?;
441 write!(f, ">")?; 481 write!(f, ">")?;
442 } 482 }
443 } else { 483 } else {
444 let projection_ty = ProjectionTy { 484 let projection_ty =
445 associated_ty: type_alias, 485 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
446 parameters: self.parameters.clone(),
447 };
448 486
449 projection_ty.hir_fmt(f)?; 487 projection_ty.hir_fmt(f)?;
450 } 488 }
451 } 489 }
452 TypeCtor::ForeignType(type_alias) => { 490 Ty::ForeignType(type_alias) => {
453 let type_alias = f.db.type_alias_data(type_alias); 491 let type_alias = f.db.type_alias_data(*type_alias);
454 write!(f, "{}", type_alias.name)?; 492 write!(f, "{}", type_alias.name)?;
455 if self.parameters.len() > 0 {
456 write!(f, "<")?;
457 f.write_joined(&*self.parameters.0, ", ")?;
458 write!(f, ">")?;
459 }
460 } 493 }
461 TypeCtor::OpaqueType(opaque_ty_id) => { 494 Ty::OpaqueType(opaque_ty_id, parameters) => {
462 match opaque_ty_id { 495 match opaque_ty_id {
463 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 496 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
464 let datas = 497 let datas =
465 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 498 f.db.return_type_impl_traits(func).expect("impl trait id without data");
466 let data = (*datas) 499 let data = (*datas)
467 .as_ref() 500 .as_ref()
468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 501 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
469 let bounds = data.subst(&self.parameters); 502 let bounds = data.subst(&parameters);
470 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 503 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
471 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 504 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
472 } 505 }
473 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 506 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
474 write!(f, "impl Future<Output = ")?; 507 write!(f, "impl Future<Output = ")?;
475 self.parameters[0].hir_fmt(f)?; 508 parameters[0].hir_fmt(f)?;
476 write!(f, ">")?; 509 write!(f, ">")?;
477 } 510 }
478 } 511 }
479 } 512 }
480 TypeCtor::Closure { .. } => { 513 Ty::Closure(.., substs) => {
481 let sig = self.parameters[0].callable_sig(f.db); 514 let sig = substs[0].callable_sig(f.db);
482 if let Some(sig) = sig { 515 if let Some(sig) = sig {
483 if sig.params().is_empty() { 516 if sig.params().is_empty() {
484 write!(f, "||")?; 517 write!(f, "||")?;
@@ -501,44 +534,6 @@ impl HirDisplay for ApplicationTy {
501 write!(f, "{{closure}}")?; 534 write!(f, "{{closure}}")?;
502 } 535 }
503 } 536 }
504 }
505 Ok(())
506 }
507}
508
509impl HirDisplay for ProjectionTy {
510 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
511 if f.should_truncate() {
512 return write!(f, "{}", TYPE_HINT_TRUNCATION);
513 }
514
515 let trait_ = f.db.trait_data(self.trait_(f.db));
516 let first_parameter = self.parameters[0].into_displayable(
517 f.db,
518 f.max_size,
519 f.omit_verbose_types,
520 f.display_target,
521 );
522 write!(f, "<{} as {}", first_parameter, trait_.name)?;
523 if self.parameters.len() > 1 {
524 write!(f, "<")?;
525 f.write_joined(&self.parameters[1..], ", ")?;
526 write!(f, ">")?;
527 }
528 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
529 Ok(())
530 }
531}
532
533impl HirDisplay for Ty {
534 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
535 if f.should_truncate() {
536 return write!(f, "{}", TYPE_HINT_TRUNCATION);
537 }
538
539 match self {
540 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
541 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
542 Ty::Placeholder(id) => { 537 Ty::Placeholder(id) => {
543 let generics = generics(f.db.upcast(), id.parent); 538 let generics = generics(f.db.upcast(), id.parent);
544 let param_data = &generics.params.types[id.local_id]; 539 let param_data = &generics.params.types[id.local_id];
@@ -557,11 +552,12 @@ impl HirDisplay for Ty {
557 } 552 }
558 } 553 }
559 } 554 }
560 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 555 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
561 Ty::Dyn(predicates) => { 556 Ty::Dyn(predicates) => {
562 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 557 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
563 } 558 }
564 Ty::Opaque(opaque_ty) => { 559 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
560 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
565 match opaque_ty.opaque_ty_id { 561 match opaque_ty.opaque_ty_id {
566 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 562 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
567 let datas = 563 let datas =
@@ -585,13 +581,13 @@ impl HirDisplay for Ty {
585 } 581 }
586 write!(f, "{{unknown}}")?; 582 write!(f, "{{unknown}}")?;
587 } 583 }
588 Ty::Infer(..) => write!(f, "_")?, 584 Ty::InferenceVar(..) => write!(f, "_")?,
589 } 585 }
590 Ok(()) 586 Ok(())
591 } 587 }
592} 588}
593 589
594impl HirDisplay for FnSig { 590impl HirDisplay for CallableSig {
595 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 591 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
596 write!(f, "fn(")?; 592 write!(f, "fn(")?;
597 f.write_joined(self.params(), ", ")?; 593 f.write_joined(self.params(), ", ")?;
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4b683c5a7..4d771a91e 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,6 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::Mutability;
21use hir_def::{ 22use hir_def::{
22 body::Body, 23 body::Body,
23 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -25,7 +26,7 @@ use hir_def::{
25 lang_item::LangItemTarget, 26 lang_item::LangItemTarget,
26 path::{path, Path}, 27 path::{path, Path},
27 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
28 type_ref::{Mutability, TypeRef}, 29 type_ref::TypeRef,
29 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, 30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId,
30 TypeAliasId, VariantId, 31 TypeAliasId, VariantId,
31}; 32};
@@ -36,25 +37,15 @@ use stdx::impl_from;
36use syntax::SmolStr; 37use syntax::SmolStr;
37 38
38use super::{ 39use super::{
39 primitive::{FloatTy, IntTy},
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy,
45}; 45};
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
48 48
49macro_rules! ty_app {
50 ($ctor:pat, $param:pat) => {
51 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
52 };
53 ($ctor:pat) => {
54 ty_app!($ctor, _)
55 };
56}
57
58mod unify; 49mod unify;
59mod path; 50mod path;
60mod expr; 51mod expr;
@@ -97,7 +88,7 @@ impl BindingMode {
97 fn convert(annotation: BindingAnnotation) -> BindingMode { 88 fn convert(annotation: BindingAnnotation) -> BindingMode {
98 match annotation { 89 match annotation {
99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, 90 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), 91 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
101 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), 92 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
102 } 93 }
103 } 94 }
@@ -405,7 +396,7 @@ impl<'a> InferenceContext<'a> {
405 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
406 let ty = self.resolve_ty_as_possible(ty); 397 let ty = self.resolve_ty_as_possible(ty);
407 ty.fold(&mut |ty| match ty { 398 ty.fold(&mut |ty| match ty {
408 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty),
409 _ => ty, 400 _ => ty,
410 }) 401 })
411 } 402 }
@@ -664,30 +655,17 @@ impl<'a> InferenceContext<'a> {
664/// two are used for inference of literal values (e.g. `100` could be one of 655/// two are used for inference of literal values (e.g. `100` could be one of
665/// several integer types). 656/// several integer types).
666#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 657#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
667pub enum InferTy { 658pub struct InferenceVar {
668 TypeVar(unify::TypeVarId), 659 index: u32,
669 IntVar(unify::TypeVarId),
670 FloatVar(unify::TypeVarId),
671 MaybeNeverTypeVar(unify::TypeVarId),
672} 660}
673 661
674impl InferTy { 662impl InferenceVar {
675 fn to_inner(self) -> unify::TypeVarId { 663 fn to_inner(self) -> unify::TypeVarId {
676 match self { 664 unify::TypeVarId(self.index)
677 InferTy::TypeVar(ty)
678 | InferTy::IntVar(ty)
679 | InferTy::FloatVar(ty)
680 | InferTy::MaybeNeverTypeVar(ty) => ty,
681 }
682 } 665 }
683 666
684 fn fallback_value(self) -> Ty { 667 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
685 match self { 668 InferenceVar { index }
686 InferTy::TypeVar(..) => Ty::Unknown,
687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())),
688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())),
689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
690 }
691 } 669 }
692} 670}
693 671
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..cf0a3add4 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,13 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget;
8use test_utils::mark; 9use test_utils::mark;
9 10
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 11use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 12
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 13use super::{InEnvironment, InferenceContext};
13 14
14impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
15 /// Unify two types, but may coerce the first one to the second one 16 /// Unify two types, but may coerce the first one to the second one
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 34 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 35 ty1.clone()
35 } else { 36 } else {
36 if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 37 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 38 mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 39 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 40 // pointers to have a chance at getting a match. See
@@ -53,12 +54,11 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 54 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 55 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 56 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 57 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => {
57 let var = self.table.new_maybe_never_type_var(); 58 self.table.type_variable_table.set_diverging(*tv, true);
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
59 return true; 59 return true;
60 } 60 }
61 (ty_app!(TypeCtor::Never), _) => return true, 61 (Ty::Never, _) => return true,
62 62
63 // Trivial cases, this should go after `never` check to 63 // Trivial cases, this should go after `never` check to
64 // avoid infer result type to be never 64 // avoid infer result type to be never
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> {
71 71
72 // Pointer weakening and function to pointer 72 // Pointer weakening and function to pointer
73 match (&mut from_ty, to_ty) { 73 match (&mut from_ty, to_ty) {
74 // `*mut T`, `&mut T, `&T`` -> `*const T` 74 // `*mut T` -> `*const T`
75 // `&mut T` -> `&T` 75 // `&mut T` -> `&T`
76 // `&mut T` -> `*mut T` 76 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => {
78 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 78 *m1 = *m2;
79 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) 79 }
80 | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { 80 // `&T` -> `*const T`
81 *c1 = *c2; 81 // `&mut T` -> `*mut T`/`*const T`
82 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..))
83 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => {
84 from_ty = Ty::Raw(m2, substs.clone());
82 } 85 }
83 86
84 // Illegal mutablity conversion 87 // Illegal mutability conversion
85 ( 88 (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 89 | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
87 ty_app!(TypeCtor::RawPtr(Mutability::Mut)),
88 )
89 | (
90 ty_app!(TypeCtor::Ref(Mutability::Shared)),
91 ty_app!(TypeCtor::Ref(Mutability::Mut)),
92 ) => return false,
93 90
94 // `{function_type}` -> `fn()` 91 // `{function_type}` -> `fn()`
95 (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { 92 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
96 match from_ty.callable_sig(self.db) { 93 None => return false,
97 None => return false, 94 Some(sig) => {
98 Some(sig) => { 95 from_ty = Ty::fn_ptr(sig);
99 from_ty = Ty::fn_ptr(sig);
100 }
101 } 96 }
102 } 97 },
103 98
104 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { 99 (Ty::Closure(.., substs), Ty::Function { .. }) => {
105 from_ty = params[0].clone(); 100 from_ty = substs[0].clone();
106 } 101 }
107 102
108 _ => {} 103 _ => {}
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> {
115 // Auto Deref if cannot coerce 110 // Auto Deref if cannot coerce
116 match (&from_ty, to_ty) { 111 match (&from_ty, to_ty) {
117 // FIXME: DerefMut 112 // FIXME: DerefMut
118 (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { 113 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]),
119 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
120 }
121 114
122 // Otherwise, normal unify 115 // Otherwise, normal unify
123 _ => self.unify(&from_ty, to_ty), 116 _ => self.unify(&from_ty, to_ty),
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> {
178 }, 171 },
179 ) { 172 ) {
180 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 173 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
181 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 174 let from_ty = self.resolve_ty_shallow(&derefed_ty);
182 // Stop when constructor matches. 175 // Stop when constructor matches.
183 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 176 if from_ty.equals_ctor(&to_ty) {
184 // It will not recurse to `coerce`. 177 // It will not recurse to `coerce`.
185 return self.table.unify_substs(st1, st2, 0); 178 return match (from_ty.substs(), to_ty.substs()) {
186 } 179 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
187 _ => { 180 (None, None) => true,
188 if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 181 _ => false,
189 return true; 182 };
190 } 183 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
191 } 184 return true;
192 } 185 }
193 } 186 }
194 187
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..cf1f1038a 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,8 +3,8 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind};
6use hir_def::{ 7use hir_def::{
7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
@@ -15,11 +15,14 @@ use syntax::ast::RangeOp;
15use test_utils::mark; 15use test_utils::mark;
16 16
17use crate::{ 17use crate::{
18 autoderef, method_resolution, op, 18 autoderef,
19 lower::lower_to_chalk_mutability,
20 method_resolution, op,
21 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 22 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 24 Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 25 TraitRef, Ty,
23}; 26};
24 27
25use super::{ 28use super::{
@@ -82,10 +85,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 85 arg_tys.push(arg);
83 } 86 }
84 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 88 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 89 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 120 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 121 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 122 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 123 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 124
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 126 let mut both_arms_diverge = Diverges::Always;
@@ -175,7 +175,7 @@ impl<'a> InferenceContext<'a> {
175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
176 let inner_ty = self.infer_expr(*body, &Expectation::none()); 176 let inner_ty = self.infer_expr(*body, &Expectation::none());
177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
178 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 178 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
179 } 179 }
180 Expr::Loop { body, label } => { 180 Expr::Loop { body, label } => {
181 self.breakables.push(BreakableContext { 181 self.breakables.push(BreakableContext {
@@ -193,7 +193,7 @@ impl<'a> InferenceContext<'a> {
193 if ctxt.may_break { 193 if ctxt.may_break {
194 ctxt.break_ty 194 ctxt.break_ty
195 } else { 195 } else {
196 Ty::simple(TypeCtor::Never) 196 Ty::Never
197 } 197 }
198 } 198 }
199 Expr::While { condition, body, label } => { 199 Expr::While { condition, body, label } => {
@@ -203,7 +203,7 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 203 label: label.map(|label| self.body[label].name.clone()),
204 }); 204 });
205 // while let is desugared to a match loop, so this is always simple while 205 // while let is desugared to a match loop, so this is always simple while
206 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 206 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 207 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 208 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 209 // the body may not run, so it diverging doesn't mean we diverge
@@ -250,12 +250,12 @@ impl<'a> InferenceContext<'a> {
250 None => self.table.new_type_var(), 250 None => self.table.new_type_var(),
251 }; 251 };
252 sig_tys.push(ret_ty.clone()); 252 sig_tys.push(ret_ty.clone());
253 let sig_ty = Ty::apply( 253 let sig_ty = Ty::Function(FnPointer {
254 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 254 num_args: sig_tys.len() - 1,
255 Substs(sig_tys.clone().into()), 255 sig: FnSig { variadic: false },
256 ); 256 substs: Substs(sig_tys.clone().into()),
257 let closure_ty = 257 });
258 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 258 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
259 259
260 // Eagerly try to relate the closure type with the expected 260 // Eagerly try to relate the closure type with the expected
261 // type, otherwise we often won't have enough information to 261 // type, otherwise we often won't have enough information to
@@ -306,11 +306,8 @@ impl<'a> InferenceContext<'a> {
306 Expr::Match { expr, arms } => { 306 Expr::Match { expr, arms } => {
307 let input_ty = self.infer_expr(*expr, &Expectation::none()); 307 let input_ty = self.infer_expr(*expr, &Expectation::none());
308 308
309 let mut result_ty = if arms.is_empty() { 309 let mut result_ty =
310 Ty::simple(TypeCtor::Never) 310 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
311 } else {
312 self.table.new_type_var()
313 };
314 311
315 let matchee_diverges = self.diverges; 312 let matchee_diverges = self.diverges;
316 let mut all_arms_diverge = Diverges::Always; 313 let mut all_arms_diverge = Diverges::Always;
@@ -321,7 +318,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 318 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 319 self.infer_expr(
323 guard_expr, 320 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 321 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
325 ); 322 );
326 } 323 }
327 324
@@ -339,7 +336,7 @@ impl<'a> InferenceContext<'a> {
339 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 336 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
340 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 337 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
341 } 338 }
342 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 339 Expr::Continue { .. } => Ty::Never,
343 Expr::Break { expr, label } => { 340 Expr::Break { expr, label } => {
344 let val_ty = if let Some(expr) = expr { 341 let val_ty = if let Some(expr) = expr {
345 self.infer_expr(*expr, &Expectation::none()) 342 self.infer_expr(*expr, &Expectation::none())
@@ -364,8 +361,7 @@ impl<'a> InferenceContext<'a> {
364 expr: tgt_expr, 361 expr: tgt_expr,
365 }); 362 });
366 } 363 }
367 364 Ty::Never
368 Ty::simple(TypeCtor::Never)
369 } 365 }
370 Expr::Return { expr } => { 366 Expr::Return { expr } => {
371 if let Some(expr) = expr { 367 if let Some(expr) = expr {
@@ -374,14 +370,14 @@ impl<'a> InferenceContext<'a> {
374 let unit = Ty::unit(); 370 let unit = Ty::unit();
375 self.coerce(&unit, &self.return_ty.clone()); 371 self.coerce(&unit, &self.return_ty.clone());
376 } 372 }
377 Ty::simple(TypeCtor::Never) 373 Ty::Never
378 } 374 }
379 Expr::Yield { expr } => { 375 Expr::Yield { expr } => {
380 // FIXME: track yield type for coercion 376 // FIXME: track yield type for coercion
381 if let Some(expr) = expr { 377 if let Some(expr) = expr {
382 self.infer_expr(*expr, &Expectation::none()); 378 self.infer_expr(*expr, &Expectation::none());
383 } 379 }
384 Ty::simple(TypeCtor::Never) 380 Ty::Never
385 } 381 }
386 Expr::RecordLit { path, fields, spread } => { 382 Expr::RecordLit { path, fields, spread } => {
387 let (ty, def_id) = self.resolve_variant(path.as_ref()); 383 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -391,7 +387,7 @@ impl<'a> InferenceContext<'a> {
391 387
392 self.unify(&ty, &expected.ty); 388 self.unify(&ty, &expected.ty);
393 389
394 let substs = ty.substs().unwrap_or_else(Substs::empty); 390 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
395 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 391 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
396 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 392 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
397 for (field_idx, field) in fields.iter().enumerate() { 393 for (field_idx, field) in fields.iter().enumerate() {
@@ -430,30 +426,23 @@ impl<'a> InferenceContext<'a> {
430 }, 426 },
431 ) 427 )
432 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 428 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
433 Ty::Apply(a_ty) => match a_ty.ctor { 429 Ty::Tuple(_, substs) => {
434 TypeCtor::Tuple { .. } => name 430 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
435 .as_tuple_index() 431 }
436 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 432 Ty::Adt(AdtId::StructId(s), parameters) => {
437 TypeCtor::Adt(AdtId::StructId(s)) => { 433 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
438 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 434 let field = FieldId { parent: s.into(), local_id };
439 let field = FieldId { parent: s.into(), local_id }; 435 self.write_field_resolution(tgt_expr, field);
440 self.write_field_resolution(tgt_expr, field); 436 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
441 self.db.field_types(s.into())[field.local_id] 437 })
442 .clone() 438 }
443 .subst(&a_ty.parameters) 439 Ty::Adt(AdtId::UnionId(u), parameters) => {
444 }) 440 self.db.union_data(u).variant_data.field(name).map(|local_id| {
445 } 441 let field = FieldId { parent: u.into(), local_id };
446 TypeCtor::Adt(AdtId::UnionId(u)) => { 442 self.write_field_resolution(tgt_expr, field);
447 self.db.union_data(u).variant_data.field(name).map(|local_id| { 443 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
448 let field = FieldId { parent: u.into(), local_id }; 444 })
449 self.write_field_resolution(tgt_expr, field); 445 }
450 self.db.field_types(u.into())[field.local_id]
451 .clone()
452 .subst(&a_ty.parameters)
453 })
454 }
455 _ => None,
456 },
457 _ => None, 446 _ => None,
458 }) 447 })
459 .unwrap_or(Ty::Unknown); 448 .unwrap_or(Ty::Unknown);
@@ -475,10 +464,11 @@ impl<'a> InferenceContext<'a> {
475 cast_ty 464 cast_ty
476 } 465 }
477 Expr::Ref { expr, rawness, mutability } => { 466 Expr::Ref { expr, rawness, mutability } => {
467 let mutability = lower_to_chalk_mutability(*mutability);
478 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 468 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
479 &expected.ty.as_reference_or_ptr() 469 &expected.ty.as_reference_or_ptr()
480 { 470 {
481 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 471 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not {
482 // FIXME: throw type error - expected mut reference but found shared ref, 472 // FIXME: throw type error - expected mut reference but found shared ref,
483 // which cannot be coerced 473 // which cannot be coerced
484 } 474 }
@@ -491,19 +481,24 @@ impl<'a> InferenceContext<'a> {
491 Expectation::none() 481 Expectation::none()
492 }; 482 };
493 let inner_ty = self.infer_expr_inner(*expr, &expectation); 483 let inner_ty = self.infer_expr_inner(*expr, &expectation);
494 let ty = match rawness { 484 match rawness {
495 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 485 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)),
496 Rawness::Ref => TypeCtor::Ref(*mutability), 486 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)),
497 }; 487 }
498 Ty::apply_one(ty, inner_ty)
499 } 488 }
500 Expr::Box { expr } => { 489 Expr::Box { expr } => {
501 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 490 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
502 if let Some(box_) = self.resolve_boxed_box() { 491 if let Some(box_) = self.resolve_boxed_box() {
503 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 492 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
504 sb = sb.push(inner_ty); 493 sb = sb.push(inner_ty);
494 match self.db.generic_defaults(box_.into()).as_ref() {
495 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
496 sb = sb.push(alloc_ty.value.clone());
497 }
498 _ => (),
499 }
505 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 500 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
506 Ty::apply(TypeCtor::Adt(box_), sb.build()) 501 Ty::Adt(box_, sb.build())
507 } else { 502 } else {
508 Ty::Unknown 503 Ty::Unknown
509 } 504 }
@@ -533,13 +528,11 @@ impl<'a> InferenceContext<'a> {
533 UnaryOp::Neg => { 528 UnaryOp::Neg => {
534 match &inner_ty { 529 match &inner_ty {
535 // Fast path for builtins 530 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 531 Ty::Scalar(Scalar::Int(_))
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 532 | Ty::Scalar(Scalar::Uint(_))
538 .. 533 | Ty::Scalar(Scalar::Float(_))
539 }) 534 | Ty::InferenceVar(_, TyVariableKind::Integer)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 535 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty,
541 | Ty::Infer(InferTy::IntVar(..))
542 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
543 // Otherwise we resolve via the std::ops::Neg trait 536 // Otherwise we resolve via the std::ops::Neg trait
544 _ => self 537 _ => self
545 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 538 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -548,9 +541,10 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 541 UnaryOp::Not => {
549 match &inner_ty { 542 match &inner_ty {
550 // Fast path for builtins 543 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 544 Ty::Scalar(Scalar::Bool)
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 545 | Ty::Scalar(Scalar::Int(_))
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 546 | Ty::Scalar(Scalar::Uint(_))
547 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 548 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 549 _ => self
556 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 550 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -561,7 +555,7 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 555 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 556 Some(op) => {
563 let lhs_expectation = match op { 557 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 558 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
565 _ => Expectation::none(), 559 _ => Expectation::none(),
566 }; 560 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 561 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -592,31 +586,31 @@ impl<'a> InferenceContext<'a> {
592 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 586 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
593 match (range_type, lhs_ty, rhs_ty) { 587 match (range_type, lhs_ty, rhs_ty) {
594 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 588 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
595 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 589 Some(adt) => Ty::Adt(adt, Substs::empty()),
596 None => Ty::Unknown, 590 None => Ty::Unknown,
597 }, 591 },
598 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 592 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
599 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 593 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
600 None => Ty::Unknown, 594 None => Ty::Unknown,
601 }, 595 },
602 (RangeOp::Inclusive, None, Some(ty)) => { 596 (RangeOp::Inclusive, None, Some(ty)) => {
603 match self.resolve_range_to_inclusive() { 597 match self.resolve_range_to_inclusive() {
604 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 598 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
605 None => Ty::Unknown, 599 None => Ty::Unknown,
606 } 600 }
607 } 601 }
608 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 602 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
609 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 603 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
610 None => Ty::Unknown, 604 None => Ty::Unknown,
611 }, 605 },
612 (RangeOp::Inclusive, Some(_), Some(ty)) => { 606 (RangeOp::Inclusive, Some(_), Some(ty)) => {
613 match self.resolve_range_inclusive() { 607 match self.resolve_range_inclusive() {
614 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 608 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
615 None => Ty::Unknown, 609 None => Ty::Unknown,
616 } 610 }
617 } 611 }
618 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 612 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
619 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 613 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
620 None => Ty::Unknown, 614 None => Ty::Unknown,
621 }, 615 },
622 (RangeOp::Inclusive, _, None) => Ty::Unknown, 616 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -650,7 +644,7 @@ impl<'a> InferenceContext<'a> {
650 } 644 }
651 Expr::Tuple { exprs } => { 645 Expr::Tuple { exprs } => {
652 let mut tys = match &expected.ty { 646 let mut tys = match &expected.ty {
653 ty_app!(TypeCtor::Tuple { .. }, st) => st 647 Ty::Tuple(_, substs) => substs
654 .iter() 648 .iter()
655 .cloned() 649 .cloned()
656 .chain(repeat_with(|| self.table.new_type_var())) 650 .chain(repeat_with(|| self.table.new_type_var()))
@@ -663,15 +657,11 @@ impl<'a> InferenceContext<'a> {
663 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 657 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
664 } 658 }
665 659
666 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 660 Ty::Tuple(tys.len(), Substs(tys.into()))
667 } 661 }
668 Expr::Array(array) => { 662 Expr::Array(array) => {
669 let elem_ty = match &expected.ty { 663 let elem_ty = match &expected.ty {
670 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 664 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
671 #[allow(unreachable_patterns)]
672 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
673 st.as_single().clone()
674 }