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.rs156
-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/lib.rs114
-rw-r--r--crates/hir_def/src/nameres.rs14
-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_expand/src/builtin_macro.rs64
-rw-r--r--crates/hir_expand/src/name.rs1
-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.rs187
-rw-r--r--crates/hir_ty/src/infer.rs41
-rw-r--r--crates/hir_ty/src/infer/coerce.rs85
-rw-r--r--crates/hir_ty/src/infer/expr.rs229
-rw-r--r--crates/hir_ty/src/infer/pat.rs27
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
-rw-r--r--crates/hir_ty/src/lib.rs599
-rw-r--r--crates/hir_ty/src/lower.rs80
-rw-r--r--crates/hir_ty/src/method_resolution.rs166
-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.rs310
-rw-r--r--crates/ide/src/diagnostics.rs67
-rw-r--r--crates/ide/src/references.rs9
-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/source_change.rs2
-rw-r--r--crates/mbe/Cargo.toml5
-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/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
69 files changed, 9208 insertions, 1770 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..00b0dc082 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -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, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment,
36 TyDefId, TyKind, TypeCtor, 36 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};
@@ -1547,25 +1547,19 @@ impl Type {
1547 } 1547 }
1548 1548
1549 pub fn is_unit(&self) -> bool { 1549 pub fn is_unit(&self) -> bool {
1550 matches!( 1550 matches!(self.ty.value, Ty::Tuple(0, ..))
1551 self.ty.value,
1552 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { cardinality: 0 }, .. })
1553 )
1554 } 1551 }
1555 pub fn is_bool(&self) -> bool { 1552 pub fn is_bool(&self) -> bool {
1556 matches!(self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. })) 1553 matches!(self.ty.value, Ty::Scalar(Scalar::Bool))
1557 } 1554 }
1558 1555
1559 pub fn is_mutable_reference(&self) -> bool { 1556 pub fn is_mutable_reference(&self) -> bool {
1560 matches!( 1557 matches!(self.ty.value, Ty::Ref(Mutability::Mut, ..))
1561 self.ty.value,
1562 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(Mutability::Mut), .. })
1563 )
1564 } 1558 }
1565 1559
1566 pub fn remove_ref(&self) -> Option<Type> { 1560 pub fn remove_ref(&self) -> Option<Type> {
1567 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { 1561 if let Ty::Ref(.., substs) = &self.ty.value {
1568 self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) 1562 Some(self.derived(substs[0].clone()))
1569 } else { 1563 } else {
1570 None 1564 None
1571 } 1565 }
@@ -1654,14 +1648,14 @@ impl Type {
1654 .build(); 1648 .build();
1655 let predicate = ProjectionPredicate { 1649 let predicate = ProjectionPredicate {
1656 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, 1650 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
1657 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)), 1651 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)),
1658 }; 1652 };
1659 let goal = Canonical { 1653 let goal = Canonical {
1660 value: InEnvironment::new( 1654 value: InEnvironment::new(
1661 self.ty.environment.clone(), 1655 self.ty.environment.clone(),
1662 Obligation::Projection(predicate), 1656 Obligation::Projection(predicate),
1663 ), 1657 ),
1664 kinds: Arc::new([TyKind::General]), 1658 kinds: Arc::new([TyVariableKind::General]),
1665 }; 1659 };
1666 1660
1667 match db.trait_solve(self.krate, goal)? { 1661 match db.trait_solve(self.krate, goal)? {
@@ -1685,7 +1679,7 @@ impl Type {
1685 1679
1686 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1680 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1687 let def = match self.ty.value { 1681 let def = match self.ty.value {
1688 Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(def), parameters: _ }) => Some(def), 1682 Ty::FnDef(def, _) => Some(def),
1689 _ => None, 1683 _ => None,
1690 }; 1684 };
1691 1685
@@ -1694,20 +1688,16 @@ impl Type {
1694 } 1688 }
1695 1689
1696 pub fn is_closure(&self) -> bool { 1690 pub fn is_closure(&self) -> bool {
1697 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::Closure { .. }, .. })) 1691 matches!(&self.ty.value, Ty::Closure { .. })
1698 } 1692 }
1699 1693
1700 pub fn is_fn(&self) -> bool { 1694 pub fn is_fn(&self) -> bool {
1701 matches!( 1695 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 } 1696 }
1707 1697
1708 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1698 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1709 let adt_id = match self.ty.value { 1699 let adt_id = match self.ty.value {
1710 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_id), .. }) => adt_id, 1700 Ty::Adt(adt_id, ..) => adt_id,
1711 _ => return false, 1701 _ => return false,
1712 }; 1702 };
1713 1703
@@ -1719,7 +1709,7 @@ impl Type {
1719 } 1709 }
1720 1710
1721 pub fn is_raw_ptr(&self) -> bool { 1711 pub fn is_raw_ptr(&self) -> bool {
1722 matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) 1712 matches!(&self.ty.value, Ty::Raw(..))
1723 } 1713 }
1724 1714
1725 pub fn contains_unknown(&self) -> bool { 1715 pub fn contains_unknown(&self) -> bool {
@@ -1728,44 +1718,34 @@ impl Type {
1728 fn go(ty: &Ty) -> bool { 1718 fn go(ty: &Ty) -> bool {
1729 match ty { 1719 match ty {
1730 Ty::Unknown => true, 1720 Ty::Unknown => true,
1731 Ty::Apply(a_ty) => a_ty.parameters.iter().any(go), 1721 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)),
1732 _ => false,
1733 } 1722 }
1734 } 1723 }
1735 } 1724 }
1736 1725
1737 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1726 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1738 if let Ty::Apply(a_ty) = &self.ty.value { 1727 let (variant_id, substs) = match self.ty.value {
1739 let variant_id = match a_ty.ctor { 1728 Ty::Adt(AdtId::StructId(s), ref substs) => (s.into(), substs),
1740 TypeCtor::Adt(AdtId::StructId(s)) => s.into(), 1729 Ty::Adt(AdtId::UnionId(u), ref substs) => (u.into(), substs),
1741 TypeCtor::Adt(AdtId::UnionId(u)) => u.into(), 1730 _ => 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 }; 1731 };
1755 Vec::new() 1732
1733 db.field_types(variant_id)
1734 .iter()
1735 .map(|(local_id, ty)| {
1736 let def = Field { parent: variant_id.into(), id: local_id };
1737 let ty = ty.clone().subst(substs);
1738 (def, self.derived(ty))
1739 })
1740 .collect()
1756 } 1741 }
1757 1742
1758 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1743 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1759 let mut res = Vec::new(); 1744 if let Ty::Tuple(_, substs) = &self.ty.value {
1760 if let Ty::Apply(a_ty) = &self.ty.value { 1745 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1761 if let TypeCtor::Tuple { .. } = a_ty.ctor { 1746 } else {
1762 for ty in a_ty.parameters.iter() { 1747 Vec::new()
1763 let ty = ty.clone(); 1748 }
1764 res.push(self.derived(ty));
1765 }
1766 }
1767 };
1768 res
1769 } 1749 }
1770 1750
1771 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a { 1751 pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
@@ -1802,15 +1782,13 @@ impl Type {
1802 } 1782 }
1803 1783
1804 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ { 1784 pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
1805 let ty = self.ty.value.strip_references(); 1785 self.ty
1806 let substs = match ty { 1786 .value
1807 Ty::Apply(apply_ty) => &apply_ty.parameters, 1787 .strip_references()
1808 Ty::Opaque(opaque_ty) => &opaque_ty.parameters, 1788 .substs()
1809 _ => return Either::Left(iter::empty()), 1789 .into_iter()
1810 }; 1790 .flat_map(|substs| substs.iter())
1811 1791 .map(move |ty| self.derived(ty.clone()))
1812 let iter = substs.iter().map(move |ty| self.derived(ty.clone()));
1813 Either::Right(iter)
1814 } 1792 }
1815 1793
1816 pub fn iterate_method_candidates<T>( 1794 pub fn iterate_method_candidates<T>(
@@ -1900,17 +1878,8 @@ impl Type {
1900 1878
1901 // FIXME: provide required accessors such that it becomes implementable from outside. 1879 // FIXME: provide required accessors such that it becomes implementable from outside.
1902 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool { 1880 pub fn is_equal_for_find_impls(&self, other: &Type) -> bool {
1903 match (&self.ty.value, &other.ty.value) { 1881 let rref = other.remove_ref();
1904 (Ty::Apply(a_original_ty), Ty::Apply(ApplicationTy { ctor, parameters })) => match ctor 1882 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 } 1883 }
1915 1884
1916 fn derived(&self, ty: Ty) -> Type { 1885 fn derived(&self, ty: Ty) -> Type {
@@ -1955,28 +1924,20 @@ impl Type {
1955 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 1924 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1956 let ty = type_.ty.value.strip_references(); 1925 let ty = type_.ty.value.strip_references();
1957 match ty { 1926 match ty {
1958 Ty::Apply(ApplicationTy { ctor, parameters }) => { 1927 Ty::Adt(..) => {
1959 match ctor { 1928 cb(type_.derived(ty.clone()));
1960 TypeCtor::Adt(_) => { 1929 }
1961 cb(type_.derived(ty.clone())); 1930 Ty::AssociatedType(..) => {
1962 } 1931 if let Some(_) = ty.associated_type_parent_trait(db) {
1963 TypeCtor::AssociatedType(_) => { 1932 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 } 1933 }
1975
1976 // adt params, tuples, etc...
1977 walk_substs(db, type_, parameters, cb);
1978 } 1934 }
1979 Ty::Opaque(opaque_ty) => { 1935 Ty::OpaqueType(..) => {
1936 if let Some(bounds) = ty.impl_trait_bounds(db) {
1937 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1938 }
1939 }
1940 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
1980 if let Some(bounds) = ty.impl_trait_bounds(db) { 1941 if let Some(bounds) = ty.impl_trait_bounds(db) {
1981 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 1942 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1982 } 1943 }
@@ -1992,7 +1953,10 @@ impl Type {
1992 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 1953 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1993 } 1954 }
1994 1955
1995 _ => (), 1956 _ => {}
1957 }
1958 if let Some(substs) = ty.substs() {
1959 walk_substs(db, type_, &substs, cb);
1996 } 1960 }
1997 } 1961 }
1998 1962
@@ -2010,7 +1974,7 @@ impl HirDisplay for Type {
2010#[derive(Debug)] 1974#[derive(Debug)]
2011pub struct Callable { 1975pub struct Callable {
2012 ty: Type, 1976 ty: Type,
2013 sig: FnSig, 1977 sig: CallableSig,
2014 def: Option<CallableDefId>, 1978 def: Option<CallableDefId>,
2015 pub(crate) is_bound_method: bool, 1979 pub(crate) is_bound_method: bool,
2016} 1980}
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/lib.rs b/crates/hir_def/src/lib.rs
index b50923747..6802bc250 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;
@@ -592,8 +594,15 @@ impl AsMacroCall for InFile<&ast::MacroCall> {
592 error_sink(mbe::ExpandError::Other("malformed macro invocation".into())); 594 error_sink(mbe::ExpandError::Other("malformed macro invocation".into()));
593 } 595 }
594 596
595 AstIdWithPath::new(ast_id.file_id, ast_id.value, path?) 597 macro_call_as_call_id(
596 .as_call_id_with_errors(db, krate, resolver, error_sink) 598 &AstIdWithPath::new(ast_id.file_id, ast_id.value, path?),
599 db,
600 krate,
601 resolver,
602 error_sink,
603 )
604 .ok()?
605 .ok()
597 } 606 }
598} 607}
599 608
@@ -610,61 +619,50 @@ impl<T: ast::AstNode> AstIdWithPath<T> {
610 } 619 }
611} 620}
612 621
613impl AsMacroCall for AstIdWithPath<ast::MacroCall> { 622struct UnresolvedMacro;
614 fn as_call_id_with_errors( 623
615 &self, 624fn macro_call_as_call_id(
616 db: &dyn db::DefDatabase, 625 call: &AstIdWithPath<ast::MacroCall>,
617 krate: CrateId, 626 db: &dyn db::DefDatabase,
618 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 627 krate: CrateId,
619 error_sink: &mut dyn FnMut(mbe::ExpandError), 628 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
620 ) -> Option<MacroCallId> { 629 error_sink: &mut dyn FnMut(mbe::ExpandError),
621 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 630) -> Result<Result<MacroCallId, ErrorEmitted>, UnresolvedMacro> {
622 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 631 let def: MacroDefId = resolver(call.path.clone()).ok_or(UnresolvedMacro)?;
623 None 632
624 })?; 633 let res = if let MacroDefKind::BuiltInEager(_) = def.kind {
625 634 let macro_call = InFile::new(call.ast_id.file_id, call.ast_id.to_node(db.upcast()));
626 if let MacroDefKind::BuiltInEager(_) = def.kind { 635 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())); 636
628 let hygiene = Hygiene::new(db.upcast(), self.ast_id.file_id); 637 expand_eager_macro(
629 638 db.upcast(),
630 Some( 639 krate,
631 expand_eager_macro( 640 macro_call,
632 db.upcast(), 641 def,
633 krate, 642 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?),
634 macro_call, 643 error_sink,
635 def, 644 )
636 &|path: ast::Path| resolver(path::ModPath::from_src(path, &hygiene)?), 645 .map(MacroCallId::from)
637 error_sink, 646 } else {
638 ) 647 Ok(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(call.ast_id)).into())
639 .ok()? 648 };
640 .into(), 649 Ok(res)
641 )
642 } else {
643 Some(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(self.ast_id)).into())
644 }
645 }
646} 650}
647 651
648impl AsMacroCall for AstIdWithPath<ast::Item> { 652fn item_attr_as_call_id(
649 fn as_call_id_with_errors( 653 item_attr: &AstIdWithPath<ast::Item>,
650 &self, 654 db: &dyn db::DefDatabase,
651 db: &dyn db::DefDatabase, 655 krate: CrateId,
652 krate: CrateId, 656 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>,
653 resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, 657) -> Result<MacroCallId, UnresolvedMacro> {
654 error_sink: &mut dyn FnMut(mbe::ExpandError), 658 let def: MacroDefId = resolver(item_attr.path.clone()).ok_or(UnresolvedMacro)?;
655 ) -> Option<MacroCallId> { 659 let last_segment = item_attr.path.segments().last().ok_or(UnresolvedMacro)?;
656 let def: MacroDefId = resolver(self.path.clone()).or_else(|| { 660 let res = def
657 error_sink(mbe::ExpandError::Other(format!("could not resolve macro `{}`", self.path))); 661 .as_lazy_macro(
658 None 662 db.upcast(),
659 })?; 663 krate,
660 664 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 ) 665 )
669 } 666 .into();
667 Ok(res)
670} 668}
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index f92232eb3..6a3456f2e 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -417,6 +417,8 @@ mod diagnostics {
417 417
418 UnresolvedProcMacro { ast: MacroCallKind }, 418 UnresolvedProcMacro { ast: MacroCallKind },
419 419
420 UnresolvedMacroCall { ast: AstId<ast::MacroCall> },
421
420 MacroError { ast: MacroCallKind, message: String }, 422 MacroError { ast: MacroCallKind, message: String },
421 } 423 }
422 424
@@ -477,6 +479,13 @@ mod diagnostics {
477 Self { in_module: container, kind: DiagnosticKind::MacroError { ast, message } } 479 Self { in_module: container, kind: DiagnosticKind::MacroError { ast, message } }
478 } 480 }
479 481
482 pub(super) fn unresolved_macro_call(
483 container: LocalModuleId,
484 ast: AstId<ast::MacroCall>,
485 ) -> Self {
486 Self { in_module: container, kind: DiagnosticKind::UnresolvedMacroCall { ast } }
487 }
488
480 pub(super) fn add_to( 489 pub(super) fn add_to(
481 &self, 490 &self,
482 db: &dyn DefDatabase, 491 db: &dyn DefDatabase,
@@ -589,6 +598,11 @@ mod diagnostics {
589 }); 598 });
590 } 599 }
591 600
601 DiagnosticKind::UnresolvedMacroCall { ast } => {
602 let node = ast.to_node(db.upcast());
603 sink.push(UnresolvedMacroCall { file: ast.file_id, node: AstPtr::new(&node) });
604 }
605
592 DiagnosticKind::MacroError { ast, message } => { 606 DiagnosticKind::MacroError { ast, message } => {
593 let (file, ast) = match ast { 607 let (file, ast) = match ast {
594 MacroCallKind::FnLike(ast) => { 608 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_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/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..f3a4333cb 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,8 +3,9 @@
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;
10use hir_def::{ 11use hir_def::{
@@ -234,36 +235,62 @@ impl HirDisplay for &Ty {
234 } 235 }
235} 236}
236 237
237impl HirDisplay for ApplicationTy { 238impl HirDisplay for ProjectionTy {
239 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
240 if f.should_truncate() {
241 return write!(f, "{}", TYPE_HINT_TRUNCATION);
242 }
243
244 let trait_ = f.db.trait_data(self.trait_(f.db));
245 let first_parameter = self.parameters[0].into_displayable(
246 f.db,
247 f.max_size,
248 f.omit_verbose_types,
249 f.display_target,
250 );
251 write!(f, "<{} as {}", first_parameter, trait_.name)?;
252 if self.parameters.len() > 1 {
253 write!(f, "<")?;
254 f.write_joined(&self.parameters[1..], ", ")?;
255 write!(f, ">")?;
256 }
257 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
258 Ok(())
259 }
260}
261
262impl HirDisplay for Ty {
238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 263 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
239 if f.should_truncate() { 264 if f.should_truncate() {
240 return write!(f, "{}", TYPE_HINT_TRUNCATION); 265 return write!(f, "{}", TYPE_HINT_TRUNCATION);
241 } 266 }
242 267
243 match self.ctor { 268 match self {
244 TypeCtor::Bool => write!(f, "bool")?, 269 Ty::Never => write!(f, "!")?,
245 TypeCtor::Char => write!(f, "char")?, 270 Ty::Str => write!(f, "str")?,
246 TypeCtor::Int(t) => write!(f, "{}", t)?, 271 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
247 TypeCtor::Float(t) => write!(f, "{}", t)?, 272 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
248 TypeCtor::Str => write!(f, "str")?, 273 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
249 TypeCtor::Slice => { 274 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
250 let t = self.parameters.as_single(); 275 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
276 Ty::Slice(parameters) => {
277 let t = parameters.as_single();
251 write!(f, "[")?; 278 write!(f, "[")?;
252 t.hir_fmt(f)?; 279 t.hir_fmt(f)?;
253 write!(f, "]")?; 280 write!(f, "]")?;
254 } 281 }
255 TypeCtor::Array => { 282 Ty::Array(parameters) => {
256 let t = self.parameters.as_single(); 283 let t = parameters.as_single();
257 write!(f, "[")?; 284 write!(f, "[")?;
258 t.hir_fmt(f)?; 285 t.hir_fmt(f)?;
259 write!(f, "; _]")?; 286 write!(f, "; _]")?;
260 } 287 }
261 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 288 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => {
262 let t = self.parameters.as_single(); 289 let t = parameters.as_single();
263 let ty_display = 290 let ty_display =
264 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 291 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
265 292
266 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 293 if matches!(self, Ty::Raw(..)) {
267 write!(f, "*{}", m.as_keyword_for_ptr())?; 294 write!(f, "*{}", m.as_keyword_for_ptr())?;
268 } else { 295 } else {
269 write!(f, "&{}", m.as_keyword_for_ref())?; 296 write!(f, "&{}", m.as_keyword_for_ref())?;
@@ -274,10 +301,10 @@ impl HirDisplay for ApplicationTy {
274 Ty::Dyn(predicates) if predicates.len() > 1 => { 301 Ty::Dyn(predicates) if predicates.len() > 1 => {
275 Cow::Borrowed(predicates.as_ref()) 302 Cow::Borrowed(predicates.as_ref())
276 } 303 }
277 &Ty::Opaque(OpaqueTy { 304 &Ty::Alias(AliasTy::Opaque(OpaqueTy {
278 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 305 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
279 ref parameters, 306 ref parameters,
280 }) => { 307 })) => {
281 datas = 308 datas =
282 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 309 f.db.return_type_impl_traits(func).expect("impl trait id without data");
283 let data = (*datas) 310 let data = (*datas)
@@ -304,25 +331,24 @@ impl HirDisplay for ApplicationTy {
304 write!(f, "{}", ty_display)?; 331 write!(f, "{}", ty_display)?;
305 } 332 }
306 } 333 }
307 TypeCtor::Never => write!(f, "!")?, 334 Ty::Tuple(_, substs) => {
308 TypeCtor::Tuple { .. } => { 335 if substs.len() == 1 {
309 let ts = &self.parameters;
310 if ts.len() == 1 {
311 write!(f, "(")?; 336 write!(f, "(")?;
312 ts[0].hir_fmt(f)?; 337 substs[0].hir_fmt(f)?;
313 write!(f, ",)")?; 338 write!(f, ",)")?;
314 } else { 339 } else {
315 write!(f, "(")?; 340 write!(f, "(")?;
316 f.write_joined(&*ts.0, ", ")?; 341 f.write_joined(&*substs.0, ", ")?;
317 write!(f, ")")?; 342 write!(f, ")")?;
318 } 343 }
319 } 344 }
320 TypeCtor::FnPtr { is_varargs, .. } => { 345 Ty::Function(fn_ptr) => {
321 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 346 let sig = CallableSig::from_fn_ptr(fn_ptr);
322 sig.hir_fmt(f)?; 347 sig.hir_fmt(f)?;
323 } 348 }
324 TypeCtor::FnDef(def) => { 349 Ty::FnDef(def, parameters) => {
325 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 350 let def = *def;
351 let sig = f.db.callable_item_signature(def).subst(parameters);
326 match def { 352 match def {
327 CallableDefId::FunctionId(ff) => { 353 CallableDefId::FunctionId(ff) => {
328 write!(f, "fn {}", f.db.function_data(ff).name)? 354 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -332,7 +358,7 @@ impl HirDisplay for ApplicationTy {
332 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 358 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
333 } 359 }
334 }; 360 };
335 if self.parameters.len() > 0 { 361 if parameters.len() > 0 {
336 let generics = generics(f.db.upcast(), def.into()); 362 let generics = generics(f.db.upcast(), def.into());
337 let (parent_params, self_param, type_params, _impl_trait_params) = 363 let (parent_params, self_param, type_params, _impl_trait_params) =
338 generics.provenance_split(); 364 generics.provenance_split();
@@ -340,7 +366,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? 366 // 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 { 367 if total_len > 0 {
342 write!(f, "<")?; 368 write!(f, "<")?;
343 f.write_joined(&self.parameters.0[..total_len], ", ")?; 369 f.write_joined(&parameters.0[..total_len], ", ")?;
344 write!(f, ">")?; 370 write!(f, ">")?;
345 } 371 }
346 } 372 }
@@ -359,10 +385,10 @@ impl HirDisplay for ApplicationTy {
359 write!(f, " -> {}", ret_display)?; 385 write!(f, " -> {}", ret_display)?;
360 } 386 }
361 } 387 }
362 TypeCtor::Adt(def_id) => { 388 Ty::Adt(def_id, parameters) => {
363 match f.display_target { 389 match f.display_target {
364 DisplayTarget::Diagnostics | DisplayTarget::Test => { 390 DisplayTarget::Diagnostics | DisplayTarget::Test => {
365 let name = match def_id { 391 let name = match *def_id {
366 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 392 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
367 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 393 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
368 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), 394 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
@@ -372,7 +398,7 @@ impl HirDisplay for ApplicationTy {
372 DisplayTarget::SourceCode { module_id } => { 398 DisplayTarget::SourceCode { module_id } => {
373 if let Some(path) = find_path::find_path( 399 if let Some(path) = find_path::find_path(
374 f.db.upcast(), 400 f.db.upcast(),
375 ItemInNs::Types(def_id.into()), 401 ItemInNs::Types((*def_id).into()),
376 module_id, 402 module_id,
377 ) { 403 ) {
378 write!(f, "{}", path)?; 404 write!(f, "{}", path)?;
@@ -384,19 +410,18 @@ impl HirDisplay for ApplicationTy {
384 } 410 }
385 } 411 }
386 412
387 if self.parameters.len() > 0 { 413 if parameters.len() > 0 {
388 let parameters_to_write = 414 let parameters_to_write =
389 if f.display_target.is_source_code() || f.omit_verbose_types() { 415 if f.display_target.is_source_code() || f.omit_verbose_types() {
390 match self 416 match self
391 .ctor
392 .as_generic_def() 417 .as_generic_def()
393 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 418 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
394 .filter(|defaults| !defaults.is_empty()) 419 .filter(|defaults| !defaults.is_empty())
395 { 420 {
396 None => self.parameters.0.as_ref(), 421 None => parameters.0.as_ref(),
397 Some(default_parameters) => { 422 Some(default_parameters) => {
398 let mut default_from = 0; 423 let mut default_from = 0;
399 for (i, parameter) in self.parameters.iter().enumerate() { 424 for (i, parameter) in parameters.iter().enumerate() {
400 match (parameter, default_parameters.get(i)) { 425 match (parameter, default_parameters.get(i)) {
401 (&Ty::Unknown, _) | (_, None) => { 426 (&Ty::Unknown, _) | (_, None) => {
402 default_from = i + 1; 427 default_from = i + 1;
@@ -404,18 +429,18 @@ impl HirDisplay for ApplicationTy {
404 (_, Some(default_parameter)) => { 429 (_, Some(default_parameter)) => {
405 let actual_default = default_parameter 430 let actual_default = default_parameter
406 .clone() 431 .clone()
407 .subst(&self.parameters.prefix(i)); 432 .subst(&parameters.prefix(i));
408 if parameter != &actual_default { 433 if parameter != &actual_default {
409 default_from = i + 1; 434 default_from = i + 1;
410 } 435 }
411 } 436 }
412 } 437 }
413 } 438 }
414 &self.parameters.0[0..default_from] 439 &parameters.0[0..default_from]
415 } 440 }
416 } 441 }
417 } else { 442 } else {
418 self.parameters.0.as_ref() 443 parameters.0.as_ref()
419 }; 444 };
420 if !parameters_to_write.is_empty() { 445 if !parameters_to_write.is_empty() {
421 write!(f, "<")?; 446 write!(f, "<")?;
@@ -424,61 +449,54 @@ impl HirDisplay for ApplicationTy {
424 } 449 }
425 } 450 }
426 } 451 }
427 TypeCtor::AssociatedType(type_alias) => { 452 Ty::AssociatedType(type_alias, parameters) => {
428 let trait_ = match type_alias.lookup(f.db.upcast()).container { 453 let trait_ = match type_alias.lookup(f.db.upcast()).container {
429 AssocContainerId::TraitId(it) => it, 454 AssocContainerId::TraitId(it) => it,
430 _ => panic!("not an associated type"), 455 _ => panic!("not an associated type"),
431 }; 456 };
432 let trait_ = f.db.trait_data(trait_); 457 let trait_ = f.db.trait_data(trait_);
433 let type_alias_data = f.db.type_alias_data(type_alias); 458 let type_alias_data = f.db.type_alias_data(*type_alias);
434 459
435 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 460 // 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() { 461 if f.display_target.is_test() {
437 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 462 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
438 if self.parameters.len() > 0 { 463 if parameters.len() > 0 {
439 write!(f, "<")?; 464 write!(f, "<")?;
440 f.write_joined(&*self.parameters.0, ", ")?; 465 f.write_joined(&*parameters.0, ", ")?;
441 write!(f, ">")?; 466 write!(f, ">")?;
442 } 467 }
443 } else { 468 } else {
444 let projection_ty = ProjectionTy { 469 let projection_ty =
445 associated_ty: type_alias, 470 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
446 parameters: self.parameters.clone(),
447 };
448 471
449 projection_ty.hir_fmt(f)?; 472 projection_ty.hir_fmt(f)?;
450 } 473 }
451 } 474 }
452 TypeCtor::ForeignType(type_alias) => { 475 Ty::ForeignType(type_alias) => {
453 let type_alias = f.db.type_alias_data(type_alias); 476 let type_alias = f.db.type_alias_data(*type_alias);
454 write!(f, "{}", type_alias.name)?; 477 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 } 478 }
461 TypeCtor::OpaqueType(opaque_ty_id) => { 479 Ty::OpaqueType(opaque_ty_id, parameters) => {
462 match opaque_ty_id { 480 match opaque_ty_id {
463 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 481 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
464 let datas = 482 let datas =
465 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 483 f.db.return_type_impl_traits(func).expect("impl trait id without data");
466 let data = (*datas) 484 let data = (*datas)
467 .as_ref() 485 .as_ref()
468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 486 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
469 let bounds = data.subst(&self.parameters); 487 let bounds = data.subst(&parameters);
470 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 488 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 489 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
472 } 490 }
473 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 491 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
474 write!(f, "impl Future<Output = ")?; 492 write!(f, "impl Future<Output = ")?;
475 self.parameters[0].hir_fmt(f)?; 493 parameters[0].hir_fmt(f)?;
476 write!(f, ">")?; 494 write!(f, ">")?;
477 } 495 }
478 } 496 }
479 } 497 }
480 TypeCtor::Closure { .. } => { 498 Ty::Closure(.., substs) => {
481 let sig = self.parameters[0].callable_sig(f.db); 499 let sig = substs[0].callable_sig(f.db);
482 if let Some(sig) = sig { 500 if let Some(sig) = sig {
483 if sig.params().is_empty() { 501 if sig.params().is_empty() {
484 write!(f, "||")?; 502 write!(f, "||")?;
@@ -501,44 +519,6 @@ impl HirDisplay for ApplicationTy {
501 write!(f, "{{closure}}")?; 519 write!(f, "{{closure}}")?;
502 } 520 }
503 } 521 }
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) => { 522 Ty::Placeholder(id) => {
543 let generics = generics(f.db.upcast(), id.parent); 523 let generics = generics(f.db.upcast(), id.parent);
544 let param_data = &generics.params.types[id.local_id]; 524 let param_data = &generics.params.types[id.local_id];
@@ -557,11 +537,12 @@ impl HirDisplay for Ty {
557 } 537 }
558 } 538 }
559 } 539 }
560 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 540 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
561 Ty::Dyn(predicates) => { 541 Ty::Dyn(predicates) => {
562 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 542 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
563 } 543 }
564 Ty::Opaque(opaque_ty) => { 544 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
545 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
565 match opaque_ty.opaque_ty_id { 546 match opaque_ty.opaque_ty_id {
566 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 547 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
567 let datas = 548 let datas =
@@ -585,13 +566,13 @@ impl HirDisplay for Ty {
585 } 566 }
586 write!(f, "{{unknown}}")?; 567 write!(f, "{{unknown}}")?;
587 } 568 }
588 Ty::Infer(..) => write!(f, "_")?, 569 Ty::InferenceVar(..) => write!(f, "_")?,
589 } 570 }
590 Ok(()) 571 Ok(())
591 } 572 }
592} 573}
593 574
594impl HirDisplay for FnSig { 575impl HirDisplay for CallableSig {
595 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 576 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
596 write!(f, "fn(")?; 577 write!(f, "fn(")?;
597 f.write_joined(self.params(), ", ")?; 578 f.write_joined(self.params(), ", ")?;
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4b683c5a7..18a4f5e8a 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -36,25 +36,15 @@ use stdx::impl_from;
36use syntax::SmolStr; 36use syntax::SmolStr;
37 37
38use super::{ 38use super::{
39 primitive::{FloatTy, IntTy},
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 39 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 40 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 41};
43use crate::{ 42use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 43 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy,
45}; 44};
46 45
47pub(crate) use unify::unify; 46pub(crate) use unify::unify;
48 47
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; 48mod unify;
59mod path; 49mod path;
60mod expr; 50mod expr;
@@ -405,7 +395,7 @@ impl<'a> InferenceContext<'a> {
405 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 395 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
406 let ty = self.resolve_ty_as_possible(ty); 396 let ty = self.resolve_ty_as_possible(ty);
407 ty.fold(&mut |ty| match ty { 397 ty.fold(&mut |ty| match ty {
408 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 398 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty),
409 _ => ty, 399 _ => ty,
410 }) 400 })
411 } 401 }
@@ -664,30 +654,17 @@ impl<'a> InferenceContext<'a> {
664/// two are used for inference of literal values (e.g. `100` could be one of 654/// two are used for inference of literal values (e.g. `100` could be one of
665/// several integer types). 655/// several integer types).
666#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 656#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
667pub enum InferTy { 657pub struct InferenceVar {
668 TypeVar(unify::TypeVarId), 658 index: u32,
669 IntVar(unify::TypeVarId),
670 FloatVar(unify::TypeVarId),
671 MaybeNeverTypeVar(unify::TypeVarId),
672} 659}
673 660
674impl InferTy { 661impl InferenceVar {
675 fn to_inner(self) -> unify::TypeVarId { 662 fn to_inner(self) -> unify::TypeVarId {
676 match self { 663 unify::TypeVarId(self.index)
677 InferTy::TypeVar(ty)
678 | InferTy::IntVar(ty)
679 | InferTy::FloatVar(ty)
680 | InferTy::MaybeNeverTypeVar(ty) => ty,
681 }
682 } 664 }
683 665
684 fn fallback_value(self) -> Ty { 666 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
685 match self { 667 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 } 668 }
692} 669}
693 670
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..c33d8c61e 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 chalk_ir::TyVariableKind;
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 8use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
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::Shared, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Shared, ..)) => {
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::Shared, ..))
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::Shared, ..), Ty::Raw(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 89 | (Ty::Ref(Mutability::Shared, ..), 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..7852b3d23 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::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,
@@ -16,10 +16,11 @@ use test_utils::mark;
16 16
17use crate::{ 17use crate::{
18 autoderef, method_resolution, op, 18 autoderef, method_resolution, op,
19 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 20 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 21 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 22 Binders, CallableDefId, FnPointer, FnSig, Mutability, Obligation, OpaqueTyId, Rawness, Scalar,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 23 Substs, TraitRef, Ty,
23}; 24};
24 25
25use super::{ 26use super::{
@@ -82,10 +83,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 83 arg_tys.push(arg);
83 } 84 }
84 let parameters = param_builder.build(); 85 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 86 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 87 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 88 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 89
@@ -120,7 +118,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 118 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 119 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 120 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 121 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 122
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 123 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 124 let mut both_arms_diverge = Diverges::Always;
@@ -175,7 +173,7 @@ impl<'a> InferenceContext<'a> {
175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 173 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
176 let inner_ty = self.infer_expr(*body, &Expectation::none()); 174 let inner_ty = self.infer_expr(*body, &Expectation::none());
177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 175 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
178 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 176 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
179 } 177 }
180 Expr::Loop { body, label } => { 178 Expr::Loop { body, label } => {
181 self.breakables.push(BreakableContext { 179 self.breakables.push(BreakableContext {
@@ -193,7 +191,7 @@ impl<'a> InferenceContext<'a> {
193 if ctxt.may_break { 191 if ctxt.may_break {
194 ctxt.break_ty 192 ctxt.break_ty
195 } else { 193 } else {
196 Ty::simple(TypeCtor::Never) 194 Ty::Never
197 } 195 }
198 } 196 }
199 Expr::While { condition, body, label } => { 197 Expr::While { condition, body, label } => {
@@ -203,7 +201,7 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 201 label: label.map(|label| self.body[label].name.clone()),
204 }); 202 });
205 // while let is desugared to a match loop, so this is always simple while 203 // 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))); 204 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 205 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 206 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 207 // the body may not run, so it diverging doesn't mean we diverge
@@ -250,12 +248,12 @@ impl<'a> InferenceContext<'a> {
250 None => self.table.new_type_var(), 248 None => self.table.new_type_var(),
251 }; 249 };
252 sig_tys.push(ret_ty.clone()); 250 sig_tys.push(ret_ty.clone());
253 let sig_ty = Ty::apply( 251 let sig_ty = Ty::Function(FnPointer {
254 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 252 num_args: sig_tys.len() - 1,
255 Substs(sig_tys.clone().into()), 253 sig: FnSig { variadic: false },
256 ); 254 substs: Substs(sig_tys.clone().into()),
257 let closure_ty = 255 });
258 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 256 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
259 257
260 // Eagerly try to relate the closure type with the expected 258 // Eagerly try to relate the closure type with the expected
261 // type, otherwise we often won't have enough information to 259 // type, otherwise we often won't have enough information to
@@ -306,11 +304,8 @@ impl<'a> InferenceContext<'a> {
306 Expr::Match { expr, arms } => { 304 Expr::Match { expr, arms } => {
307 let input_ty = self.infer_expr(*expr, &Expectation::none()); 305 let input_ty = self.infer_expr(*expr, &Expectation::none());
308 306
309 let mut result_ty = if arms.is_empty() { 307 let mut result_ty =
310 Ty::simple(TypeCtor::Never) 308 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
311 } else {
312 self.table.new_type_var()
313 };
314 309
315 let matchee_diverges = self.diverges; 310 let matchee_diverges = self.diverges;
316 let mut all_arms_diverge = Diverges::Always; 311 let mut all_arms_diverge = Diverges::Always;
@@ -321,7 +316,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 316 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 317 self.infer_expr(
323 guard_expr, 318 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 319 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
325 ); 320 );
326 } 321 }
327 322
@@ -339,7 +334,7 @@ impl<'a> InferenceContext<'a> {
339 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 334 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) 335 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
341 } 336 }
342 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 337 Expr::Continue { .. } => Ty::Never,
343 Expr::Break { expr, label } => { 338 Expr::Break { expr, label } => {
344 let val_ty = if let Some(expr) = expr { 339 let val_ty = if let Some(expr) = expr {
345 self.infer_expr(*expr, &Expectation::none()) 340 self.infer_expr(*expr, &Expectation::none())
@@ -364,8 +359,7 @@ impl<'a> InferenceContext<'a> {
364 expr: tgt_expr, 359 expr: tgt_expr,
365 }); 360 });
366 } 361 }
367 362 Ty::Never
368 Ty::simple(TypeCtor::Never)
369 } 363 }
370 Expr::Return { expr } => { 364 Expr::Return { expr } => {
371 if let Some(expr) = expr { 365 if let Some(expr) = expr {
@@ -374,14 +368,14 @@ impl<'a> InferenceContext<'a> {
374 let unit = Ty::unit(); 368 let unit = Ty::unit();
375 self.coerce(&unit, &self.return_ty.clone()); 369 self.coerce(&unit, &self.return_ty.clone());
376 } 370 }
377 Ty::simple(TypeCtor::Never) 371 Ty::Never
378 } 372 }
379 Expr::Yield { expr } => { 373 Expr::Yield { expr } => {
380 // FIXME: track yield type for coercion 374 // FIXME: track yield type for coercion
381 if let Some(expr) = expr { 375 if let Some(expr) = expr {
382 self.infer_expr(*expr, &Expectation::none()); 376 self.infer_expr(*expr, &Expectation::none());
383 } 377 }
384 Ty::simple(TypeCtor::Never) 378 Ty::Never
385 } 379 }
386 Expr::RecordLit { path, fields, spread } => { 380 Expr::RecordLit { path, fields, spread } => {
387 let (ty, def_id) = self.resolve_variant(path.as_ref()); 381 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -391,7 +385,7 @@ impl<'a> InferenceContext<'a> {
391 385
392 self.unify(&ty, &expected.ty); 386 self.unify(&ty, &expected.ty);
393 387
394 let substs = ty.substs().unwrap_or_else(Substs::empty); 388 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(); 389 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)); 390 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
397 for (field_idx, field) in fields.iter().enumerate() { 391 for (field_idx, field) in fields.iter().enumerate() {
@@ -430,30 +424,23 @@ impl<'a> InferenceContext<'a> {
430 }, 424 },
431 ) 425 )
432 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 426 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
433 Ty::Apply(a_ty) => match a_ty.ctor { 427 Ty::Tuple(_, substs) => {
434 TypeCtor::Tuple { .. } => name 428 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
435 .as_tuple_index() 429 }
436 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 430 Ty::Adt(AdtId::StructId(s), parameters) => {
437 TypeCtor::Adt(AdtId::StructId(s)) => { 431 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| { 432 let field = FieldId { parent: s.into(), local_id };
439 let field = FieldId { parent: s.into(), local_id }; 433 self.write_field_resolution(tgt_expr, field);
440 self.write_field_resolution(tgt_expr, field); 434 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
441 self.db.field_types(s.into())[field.local_id] 435 })
442 .clone() 436 }
443 .subst(&a_ty.parameters) 437 Ty::Adt(AdtId::UnionId(u), parameters) => {
444 }) 438 self.db.union_data(u).variant_data.field(name).map(|local_id| {
445 } 439 let field = FieldId { parent: u.into(), local_id };
446 TypeCtor::Adt(AdtId::UnionId(u)) => { 440 self.write_field_resolution(tgt_expr, field);
447 self.db.union_data(u).variant_data.field(name).map(|local_id| { 441 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
448 let field = FieldId { parent: u.into(), local_id }; 442 })
449 self.write_field_resolution(tgt_expr, field); 443 }
450 self.db.field_types(u.into())[field.local_id]
451 .clone()
452 .subst(&a_ty.parameters)
453 })
454 }
455 _ => None,
456 },
457 _ => None, 444 _ => None,
458 }) 445 })
459 .unwrap_or(Ty::Unknown); 446 .unwrap_or(Ty::Unknown);
@@ -491,19 +478,24 @@ impl<'a> InferenceContext<'a> {
491 Expectation::none() 478 Expectation::none()
492 }; 479 };
493 let inner_ty = self.infer_expr_inner(*expr, &expectation); 480 let inner_ty = self.infer_expr_inner(*expr, &expectation);
494 let ty = match rawness { 481 match rawness {
495 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 482 Rawness::RawPtr => Ty::Raw(*mutability, Substs::single(inner_ty)),
496 Rawness::Ref => TypeCtor::Ref(*mutability), 483 Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)),
497 }; 484 }
498 Ty::apply_one(ty, inner_ty)
499 } 485 }
500 Expr::Box { expr } => { 486 Expr::Box { expr } => {
501 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 487 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
502 if let Some(box_) = self.resolve_boxed_box() { 488 if let Some(box_) = self.resolve_boxed_box() {
503 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 489 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
504 sb = sb.push(inner_ty); 490 sb = sb.push(inner_ty);
491 match self.db.generic_defaults(box_.into()).as_ref() {
492 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
493 sb = sb.push(alloc_ty.value.clone());
494 }
495 _ => (),
496 }
505 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 497 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
506 Ty::apply(TypeCtor::Adt(box_), sb.build()) 498 Ty::Adt(box_, sb.build())
507 } else { 499 } else {
508 Ty::Unknown 500 Ty::Unknown
509 } 501 }
@@ -533,13 +525,11 @@ impl<'a> InferenceContext<'a> {
533 UnaryOp::Neg => { 525 UnaryOp::Neg => {
534 match &inner_ty { 526 match &inner_ty {
535 // Fast path for builtins 527 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 528 Ty::Scalar(Scalar::Int(_))
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 529 | Ty::Scalar(Scalar::Uint(_))
538 .. 530 | Ty::Scalar(Scalar::Float(_))
539 }) 531 | Ty::InferenceVar(_, TyVariableKind::Integer)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 532 | 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 533 // Otherwise we resolve via the std::ops::Neg trait
544 _ => self 534 _ => self
545 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 535 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -548,9 +538,10 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 538 UnaryOp::Not => {
549 match &inner_ty { 539 match &inner_ty {
550 // Fast path for builtins 540 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 541 Ty::Scalar(Scalar::Bool)
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 542 | Ty::Scalar(Scalar::Int(_))
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 543 | Ty::Scalar(Scalar::Uint(_))
544 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 545 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 546 _ => self
556 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 547 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -561,7 +552,7 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 552 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 553 Some(op) => {
563 let lhs_expectation = match op { 554 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 555 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
565 _ => Expectation::none(), 556 _ => Expectation::none(),
566 }; 557 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 558 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -592,31 +583,31 @@ impl<'a> InferenceContext<'a> {
592 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 583 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
593 match (range_type, lhs_ty, rhs_ty) { 584 match (range_type, lhs_ty, rhs_ty) {
594 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 585 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
595 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 586 Some(adt) => Ty::Adt(adt, Substs::empty()),
596 None => Ty::Unknown, 587 None => Ty::Unknown,
597 }, 588 },
598 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 589 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
599 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 590 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
600 None => Ty::Unknown, 591 None => Ty::Unknown,
601 }, 592 },
602 (RangeOp::Inclusive, None, Some(ty)) => { 593 (RangeOp::Inclusive, None, Some(ty)) => {
603 match self.resolve_range_to_inclusive() { 594 match self.resolve_range_to_inclusive() {
604 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 595 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
605 None => Ty::Unknown, 596 None => Ty::Unknown,
606 } 597 }
607 } 598 }
608 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 599 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
609 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 600 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
610 None => Ty::Unknown, 601 None => Ty::Unknown,
611 }, 602 },
612 (RangeOp::Inclusive, Some(_), Some(ty)) => { 603 (RangeOp::Inclusive, Some(_), Some(ty)) => {
613 match self.resolve_range_inclusive() { 604 match self.resolve_range_inclusive() {
614 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 605 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
615 None => Ty::Unknown, 606 None => Ty::Unknown,
616 } 607 }
617 } 608 }
618 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 609 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
619 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 610 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
620 None => Ty::Unknown, 611 None => Ty::Unknown,
621 }, 612 },
622 (RangeOp::Inclusive, _, None) => Ty::Unknown, 613 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -650,7 +641,7 @@ impl<'a> InferenceContext<'a> {
650 } 641 }
651 Expr::Tuple { exprs } => { 642 Expr::Tuple { exprs } => {
652 let mut tys = match &expected.ty { 643 let mut tys = match &expected.ty {
653 ty_app!(TypeCtor::Tuple { .. }, st) => st 644 Ty::Tuple(_, substs) => substs
654 .iter() 645 .iter()
655 .cloned() 646 .cloned()
656 .chain(repeat_with(|| self.table.new_type_var())) 647 .chain(repeat_with(|| self.table.new_type_var()))
@@ -663,15 +654,11 @@ impl<'a> InferenceContext<'a> {
663 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 654 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
664 } 655 }
665 656
666 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 657 Ty::Tuple(tys.len(), Substs(tys.into()))
667 } 658 }
668 Expr::Array(array) => { 659 Expr::Array(array) => {
669 let elem_ty = match &expected.ty { 660 let elem_ty = match &expected.ty {
670 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 661 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 }
675 _ => self.table.new_type_var(), 662 _ => self.table.new_type_var(),
676 }; 663 };
677 664
@@ -688,30 +675,38 @@ impl<'a> InferenceContext<'a> {
688 ); 675 );
689 self.infer_expr( 676 self.infer_expr(
690 *repeat, 677 *repeat,
691 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 678 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
692 ); 679 );
693 } 680 }
694 } 681 }
695 682
696 Ty::apply_one(TypeCtor::Array, elem_ty) 683 Ty::Array(Substs::single(elem_ty))
697 } 684 }
698 Expr::Literal(lit) => match lit { 685 Expr::Literal(lit) => match lit {
699 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 686 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
700 Literal::String(..) => { 687 Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)),
701 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
702 }
703 Literal::ByteString(..) => { 688 Literal::ByteString(..) => {
704 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 689 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
705 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 690 let array_type = Ty::Array(Substs::single(byte_type));
706 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 691 Ty::Ref(Mutability::Shared, Substs::single(array_type))
707 } 692 }
708 Literal::Char(..) => Ty::simple(TypeCtor::Char), 693 Literal::Char(..) => Ty::Scalar(Scalar::Char),
709 Literal::Int(_v, ty) => match ty { 694 Literal::Int(_v, ty) => match ty {
710 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 695 Some(int_ty) => {
696 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
697 }
698 None => self.table.new_integer_var(),
699 },
700 Literal::Uint(_v, ty) => match ty {
701 Some(int_ty) => {
702 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
703 }
711 None => self.table.new_integer_var(), 704 None => self.table.new_integer_var(),
712 }, 705 },
713 Literal::Float(_v, ty) => match ty { 706 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 707 Some(float_ty) => {
708 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
709 }
715 None => self.table.new_float_var(), 710 None => self.table.new_float_var(),
716 }, 711 },
717 }, 712 },
@@ -767,7 +762,7 @@ impl<'a> InferenceContext<'a> {
767 // `!`). 762 // `!`).
768 if self.diverges.is_always() { 763 if self.diverges.is_always() {
769 // we don't even make an attempt at coercion 764 // we don't even make an attempt at coercion
770 self.table.new_maybe_never_type_var() 765 self.table.new_maybe_never_var()
771 } else { 766 } else {
772 self.coerce(&Ty::unit(), expected.coercion_target()); 767 self.coerce(&Ty::unit(), expected.coercion_target());
773 Ty::unit() 768 Ty::unit()
@@ -824,7 +819,7 @@ impl<'a> InferenceContext<'a> {
824 // Apply autoref so the below unification works correctly 819 // Apply autoref so the below unification works correctly
825 // FIXME: return correct autorefs from lookup_method 820 // FIXME: return correct autorefs from lookup_method
826 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 821 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
827 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 822 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
828 _ => derefed_receiver_ty, 823 _ => derefed_receiver_ty,
829 }; 824 };
830 self.unify(&expected_receiver_ty, &actual_receiver_ty); 825 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -901,30 +896,26 @@ impl<'a> InferenceContext<'a> {
901 } 896 }
902 897
903 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 898 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
904 if let Ty::Apply(a_ty) = callable_ty { 899 if let &Ty::FnDef(def, ref parameters) = callable_ty {
905 if let TypeCtor::FnDef(def) = a_ty.ctor { 900 let generic_predicates = self.db.generic_predicates(def.into());
906 let generic_predicates = self.db.generic_predicates(def.into()); 901 for predicate in generic_predicates.iter() {
907 for predicate in generic_predicates.iter() { 902 let predicate = predicate.clone().subst(parameters);
908 let predicate = predicate.clone().subst(&a_ty.parameters); 903 if let Some(obligation) = Obligation::from_predicate(predicate) {
909 if let Some(obligation) = Obligation::from_predicate(predicate) { 904 self.obligations.push(obligation);
910 self.obligations.push(obligation);
911 }
912 } 905 }
913 // add obligation for trait implementation, if this is a trait method 906 }
914 match def { 907 // add obligation for trait implementation, if this is a trait method
915 CallableDefId::FunctionId(f) => { 908 match def {
916 if let AssocContainerId::TraitId(trait_) = 909 CallableDefId::FunctionId(f) => {
917 f.lookup(self.db.upcast()).container 910 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
918 { 911 {
919 // construct a TraitDef 912 // construct a TraitDef
920 let substs = a_ty 913 let substs =
921 .parameters 914 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
922 .prefix(generics(self.db.upcast(), trait_.into()).len()); 915 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
923 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
924 }
925 } 916 }
926 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
927 } 917 }
918 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
928 } 919 }
929 } 920 }
930 } 921 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..a318e47f3 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -13,7 +13,7 @@ use hir_expand::name::Name;
13use test_utils::mark; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 19 fn infer_tuple_struct_pat(
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> {
32 } 32 }
33 self.unify(&ty, expected); 33 self.unify(&ty, expected);
34 34
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 35 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 36
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 38 let (pre, post) = match ellipsis {
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> {
71 71
72 self.unify(&ty, expected); 72 self.unify(&ty, expected);
73 73
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 74 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 75
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 77 for subpat in subpats {
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 140
141 Ty::apply( 141 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into()))
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 142 }
146 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 162 _ => &Ty::Unknown,
166 }; 163 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 164 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 165 Ty::Ref(*mutability, Substs::single(subty))
169 } 166 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 168 p.as_ref(),
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> {
198 195
199 let bound_ty = match mode { 196 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 197 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 198 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 199 }
203 BindingMode::Move => inner_ty.clone(), 200 BindingMode::Move => inner_ty.clone(),
204 }; 201 };
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 204 return inner_ty;
208 } 205 }
209 Pat::Slice { prefix, slice, suffix } => { 206 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 208 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 210 _ => (Ty::Slice, Ty::Unknown),
214 }; 211 };
215 212
216 for pat_id in prefix.iter().chain(suffix) { 213 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 214 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 215 }
219 216
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 217 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 218 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 220 }
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> {
239 }; 236 };
240 237
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 239 Ty::Adt(box_adt, Substs::single(inner_ty))
243 } 240 }
244 None => Ty::Unknown, 241 None => Ty::Unknown,
245 }, 242 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 76984242e..99a89a7f3 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,14 +2,15 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind};
5use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
6 7
7use test_utils::mark; 8use test_utils::mark;
8 9
9use super::{InferenceContext, Obligation}; 10use super::{InferenceContext, Obligation};
10use crate::{ 11use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, 12 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar,
12 TyKind, TypeCtor, TypeWalk, 13 Substs, Ty, TypeWalk,
13}; 14};
14 15
15impl<'a> InferenceContext<'a> { 16impl<'a> InferenceContext<'a> {
@@ -26,7 +27,7 @@ where
26 'a: 'b, 27 'a: 'b,
27{ 28{
28 ctx: &'b mut InferenceContext<'a>, 29 ctx: &'b mut InferenceContext<'a>,
29 free_vars: Vec<InferTy>, 30 free_vars: Vec<(InferenceVar, TyVariableKind)>,
30 /// A stack of type variables that is used to detect recursive types (which 31 /// A stack of type variables that is used to detect recursive types (which
31 /// are an error, but we need to protect against them to avoid stack 32 /// are an error, but we need to protect against them to avoid stack
32 /// overflows). 33 /// overflows).
@@ -36,17 +37,14 @@ where
36#[derive(Debug)] 37#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 38pub(super) struct Canonicalized<T> {
38 pub(super) value: Canonical<T>, 39 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 40 free_vars: Vec<(InferenceVar, TyVariableKind)>,
40} 41}
41 42
42impl<'a, 'b> Canonicalizer<'a, 'b> 43impl<'a, 'b> Canonicalizer<'a, 'b> {
43where 44 fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize {
44 'a: 'b, 45 self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| {
45{
46 fn add(&mut self, free_var: InferTy) -> usize {
47 self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| {
48 let next_index = self.free_vars.len(); 46 let next_index = self.free_vars.len();
49 self.free_vars.push(free_var); 47 self.free_vars.push((free_var, kind));
50 next_index 48 next_index
51 }) 49 })
52 } 50 }
@@ -54,11 +52,11 @@ where
54 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 52 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
55 t.fold_binders( 53 t.fold_binders(
56 &mut |ty, binders| match ty { 54 &mut |ty, binders| match ty {
57 Ty::Infer(tv) => { 55 Ty::InferenceVar(var, kind) => {
58 let inner = tv.to_inner(); 56 let inner = var.to_inner();
59 if self.var_stack.contains(&inner) { 57 if self.var_stack.contains(&inner) {
60 // recursive type 58 // recursive type
61 return tv.fallback_value(); 59 return self.ctx.table.type_variable_table.fallback_value(var, kind);
62 } 60 }
63 if let Some(known_ty) = 61 if let Some(known_ty) =
64 self.ctx.table.var_unification_table.inlined_probe_value(inner).known() 62 self.ctx.table.var_unification_table.inlined_probe_value(inner).known()
@@ -69,14 +67,8 @@ where
69 result 67 result
70 } else { 68 } else {
71 let root = self.ctx.table.var_unification_table.find(inner); 69 let root = self.ctx.table.var_unification_table.find(inner);
72 let free_var = match tv { 70 let position = self.add(InferenceVar::from_inner(root), kind);
73 InferTy::TypeVar(_) => InferTy::TypeVar(root), 71 Ty::BoundVar(BoundVar::new(binders, position))
74 InferTy::IntVar(_) => InferTy::IntVar(root),
75 InferTy::FloatVar(_) => InferTy::FloatVar(root),
76 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root),
77 };
78 let position = self.add(free_var);
79 Ty::Bound(BoundVar::new(binders, position))
80 } 72 }
81 } 73 }
82 _ => ty, 74 _ => ty,
@@ -86,19 +78,7 @@ where
86 } 78 }
87 79
88 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 80 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
89 let kinds = self 81 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect();
90 .free_vars
91 .iter()
92 .map(|v| match v {
93 // mapping MaybeNeverTypeVar to the same kind as general ones
94 // should be fine, because as opposed to int or float type vars,
95 // they don't restrict what kind of type can go into them, they
96 // just affect fallback.
97 InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General,
98 InferTy::IntVar(_) => TyKind::Integer,
99 InferTy::FloatVar(_) => TyKind::Float,
100 })
101 .collect();
102 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 82 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars }
103 } 83 }
104 84
@@ -130,9 +110,10 @@ impl<T> Canonicalized<T> {
130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 110 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 111 ty.walk_mut_binders(
132 &mut |ty, binders| { 112 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 113 if let &mut Ty::BoundVar(bound) = ty {
134 if bound.debruijn >= binders { 114 if bound.debruijn >= binders {
135 *ty = Ty::Infer(self.free_vars[bound.index]); 115 let (v, k) = self.free_vars[bound.index];
116 *ty = Ty::InferenceVar(v, k);
136 } 117 }
137 } 118 }
138 }, 119 },
@@ -152,18 +133,18 @@ impl<T> Canonicalized<T> {
152 .kinds 133 .kinds
153 .iter() 134 .iter()
154 .map(|k| match k { 135 .map(|k| match k {
155 TyKind::General => ctx.table.new_type_var(), 136 TyVariableKind::General => ctx.table.new_type_var(),
156 TyKind::Integer => ctx.table.new_integer_var(), 137 TyVariableKind::Integer => ctx.table.new_integer_var(),
157 TyKind::Float => ctx.table.new_float_var(), 138 TyVariableKind::Float => ctx.table.new_float_var(),
158 }) 139 })
159 .collect(), 140 .collect(),
160 ); 141 );
161 for (i, ty) in solution.value.into_iter().enumerate() { 142 for (i, ty) in solution.value.into_iter().enumerate() {
162 let var = self.free_vars[i]; 143 let (v, k) = self.free_vars[i];
163 // eagerly replace projections in the type; we may be getting types 144 // eagerly replace projections in the type; we may be getting types
164 // e.g. from where clauses where this hasn't happened yet 145 // e.g. from where clauses where this hasn't happened yet
165 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 146 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
166 ctx.table.unify(&Ty::Infer(var), &ty); 147 ctx.table.unify(&Ty::InferenceVar(v, k), &ty);
167 } 148 }
168 } 149 }
169} 150}
@@ -187,7 +168,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
187 // (kind of hacky) 168 // (kind of hacky)
188 for (i, var) in vars.iter().enumerate() { 169 for (i, var) in vars.iter().enumerate() {
189 if &*table.resolve_ty_shallow(var) == var { 170 if &*table.resolve_ty_shallow(var) == var {
190 table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); 171 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)));
191 } 172 }
192 } 173 }
193 Some( 174 Some(
@@ -198,31 +179,73 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
198} 179}
199 180
200#[derive(Clone, Debug)] 181#[derive(Clone, Debug)]
182pub(super) struct TypeVariableTable {
183 inner: Vec<TypeVariableData>,
184}
185
186