aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/lib.rs67
-rw-r--r--crates/hir_ty/src/autoderef.rs9
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs21
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs4
-rw-r--r--crates/hir_ty/src/display.rs116
-rw-r--r--crates/hir_ty/src/infer.rs49
-rw-r--r--crates/hir_ty/src/infer/coerce.rs38
-rw-r--r--crates/hir_ty/src/infer/expr.rs235
-rw-r--r--crates/hir_ty/src/infer/pat.rs41
-rw-r--r--crates/hir_ty/src/infer/path.rs6
-rw-r--r--crates/hir_ty/src/infer/unify.rs105
-rw-r--r--crates/hir_ty/src/lib.rs276
-rw-r--r--crates/hir_ty/src/lower.rs122
-rw-r--r--crates/hir_ty/src/method_resolution.rs76
-rw-r--r--crates/hir_ty/src/op.rs66
-rw-r--r--crates/hir_ty/src/traits.rs6
-rw-r--r--crates/hir_ty/src/traits/chalk.rs32
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs91
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs6
20 files changed, 755 insertions, 619 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 58adc8fd3..7b9de11ed 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -54,8 +54,8 @@ use hir_ty::{
54 method_resolution, 54 method_resolution,
55 traits::{FnTrait, Solution, SolutionVariables}, 55 traits::{FnTrait, Solution, SolutionVariables},
56 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate, 56 AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, DebruijnIndex, GenericPredicate,
57 InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, 57 InEnvironment, Interner, Obligation, ProjectionPredicate, ProjectionTy, Scalar, Substs,
58 Ty, TyDefId, TyVariableKind, 58 TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind,
59}; 59};
60use rustc_hash::FxHashSet; 60use rustc_hash::FxHashSet;
61use stdx::{format_to, impl_from}; 61use stdx::{format_to, impl_from};
@@ -677,7 +677,7 @@ impl_from!(Struct, Union, Enum for Adt);
677impl Adt { 677impl Adt {
678 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 678 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
679 let subst = db.generic_defaults(self.into()); 679 let subst = db.generic_defaults(self.into());
680 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 680 subst.iter().any(|ty| ty.value.is_unknown())
681 } 681 }
682 682
683 /// Turns this ADT into a type. Any type parameters of the ADT will be 683 /// Turns this ADT into a type. Any type parameters of the ADT will be
@@ -1012,7 +1012,7 @@ pub struct TypeAlias {
1012impl TypeAlias { 1012impl TypeAlias {
1013 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool { 1013 pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
1014 let subst = db.generic_defaults(self.id.into()); 1014 let subst = db.generic_defaults(self.id.into());
1015 subst.iter().any(|ty| &ty.value == &Ty::Unknown) 1015 subst.iter().any(|ty| ty.value.is_unknown())
1016 } 1016 }
1017 1017
1018 pub fn module(self, db: &dyn HirDatabase) -> Module { 1018 pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -1384,7 +1384,7 @@ impl TypeParam {
1384 pub fn ty(self, db: &dyn HirDatabase) -> Type { 1384 pub fn ty(self, db: &dyn HirDatabase) -> Type {
1385 let resolver = self.id.parent.resolver(db.upcast()); 1385 let resolver = self.id.parent.resolver(db.upcast());
1386 let krate = self.id.parent.module(db.upcast()).krate(); 1386 let krate = self.id.parent.module(db.upcast()).krate();
1387 let ty = Ty::Placeholder(self.id); 1387 let ty = TyKind::Placeholder(self.id).intern(&Interner);
1388 Type::new_with_resolver_inner(db, krate, &resolver, ty) 1388 Type::new_with_resolver_inner(db, krate, &resolver, ty)
1389 } 1389 }
1390 1390
@@ -1584,25 +1584,25 @@ impl Type {
1584 } 1584 }
1585 1585
1586 pub fn is_unit(&self) -> bool { 1586 pub fn is_unit(&self) -> bool {
1587 matches!(self.ty.value, Ty::Tuple(0, ..)) 1587 matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
1588 } 1588 }
1589 pub fn is_bool(&self) -> bool { 1589 pub fn is_bool(&self) -> bool {
1590 matches!(self.ty.value, Ty::Scalar(Scalar::Bool)) 1590 matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
1591 } 1591 }
1592 1592
1593 pub fn is_mutable_reference(&self) -> bool { 1593 pub fn is_mutable_reference(&self) -> bool {
1594 matches!(self.ty.value, Ty::Ref(hir_ty::Mutability::Mut, ..)) 1594 matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
1595 } 1595 }
1596 1596
1597 pub fn remove_ref(&self) -> Option<Type> { 1597 pub fn remove_ref(&self) -> Option<Type> {
1598 match &self.ty.value { 1598 match &self.ty.value.interned(&Interner) {
1599 Ty::Ref(.., substs) => Some(self.derived(substs[0].clone())), 1599 TyKind::Ref(.., substs) => Some(self.derived(substs[0].clone())),
1600 _ => None, 1600 _ => None,
1601 } 1601 }
1602 } 1602 }
1603 1603
1604 pub fn is_unknown(&self) -> bool { 1604 pub fn is_unknown(&self) -> bool {
1605 matches!(self.ty.value, Ty::Unknown) 1605 self.ty.value.is_unknown()
1606 } 1606 }
1607 1607
1608 /// Checks that particular type `ty` implements `std::future::Future`. 1608 /// Checks that particular type `ty` implements `std::future::Future`.
@@ -1684,7 +1684,7 @@ impl Type {
1684 .build(); 1684 .build();
1685 let predicate = ProjectionPredicate { 1685 let predicate = ProjectionPredicate {
1686 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst }, 1686 projection_ty: ProjectionTy { associated_ty: alias.id, parameters: subst },
1687 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)), 1687 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner),
1688 }; 1688 };
1689 let goal = Canonical { 1689 let goal = Canonical {
1690 value: InEnvironment::new( 1690 value: InEnvironment::new(
@@ -1712,8 +1712,8 @@ impl Type {
1712 } 1712 }
1713 1713
1714 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> { 1714 pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
1715 let def = match self.ty.value { 1715 let def = match self.ty.value.interned(&Interner) {
1716 Ty::FnDef(def, _) => Some(def), 1716 &TyKind::FnDef(def, _) => Some(def),
1717 _ => None, 1717 _ => None,
1718 }; 1718 };
1719 1719
@@ -1722,16 +1722,16 @@ impl Type {
1722 } 1722 }
1723 1723
1724 pub fn is_closure(&self) -> bool { 1724 pub fn is_closure(&self) -> bool {
1725 matches!(&self.ty.value, Ty::Closure { .. }) 1725 matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
1726 } 1726 }
1727 1727
1728 pub fn is_fn(&self) -> bool { 1728 pub fn is_fn(&self) -> bool {
1729 matches!(&self.ty.value, Ty::FnDef(..) | Ty::Function { .. }) 1729 matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
1730 } 1730 }
1731 1731
1732 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool { 1732 pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
1733 let adt_id = match self.ty.value { 1733 let adt_id = match self.ty.value.interned(&Interner) {
1734 Ty::Adt(hir_ty::AdtId(adt_id), ..) => adt_id, 1734 &TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
1735 _ => return false, 1735 _ => return false,
1736 }; 1736 };
1737 1737
@@ -1743,24 +1743,25 @@ impl Type {
1743 } 1743 }
1744 1744
1745 pub fn is_raw_ptr(&self) -> bool { 1745 pub fn is_raw_ptr(&self) -> bool {
1746 matches!(&self.ty.value, Ty::Raw(..)) 1746 matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
1747 } 1747 }
1748 1748
1749 pub fn contains_unknown(&self) -> bool { 1749 pub fn contains_unknown(&self) -> bool {
1750 return go(&self.ty.value); 1750 return go(&self.ty.value);
1751 1751
1752 fn go(ty: &Ty) -> bool { 1752 fn go(ty: &Ty) -> bool {
1753 match ty { 1753 if ty.is_unknown() {
1754 Ty::Unknown => true, 1754 true
1755 _ => ty.substs().map_or(false, |substs| substs.iter().any(go)), 1755 } else {
1756 ty.substs().map_or(false, |substs| substs.iter().any(go))
1756 } 1757 }
1757 } 1758 }
1758 } 1759 }
1759 1760
1760 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> { 1761 pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
1761 let (variant_id, substs) = match self.ty.value { 1762 let (variant_id, substs) = match self.ty.value.interned(&Interner) {
1762 Ty::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs), 1763 &TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
1763 Ty::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs), 1764 &TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
1764 _ => return Vec::new(), 1765 _ => return Vec::new(),
1765 }; 1766 };
1766 1767
@@ -1775,7 +1776,7 @@ impl Type {
1775 } 1776 }
1776 1777
1777 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> { 1778 pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
1778 if let Ty::Tuple(_, substs) = &self.ty.value { 1779 if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
1779 substs.iter().map(|ty| self.derived(ty.clone())).collect() 1780 substs.iter().map(|ty| self.derived(ty.clone())).collect()
1780 } else { 1781 } else {
1781 Vec::new() 1782 Vec::new()
@@ -1957,33 +1958,33 @@ impl Type {
1957 1958
1958 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) { 1959 fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
1959 let ty = type_.ty.value.strip_references(); 1960 let ty = type_.ty.value.strip_references();
1960 match ty { 1961 match ty.interned(&Interner) {
1961 Ty::Adt(..) => { 1962 TyKind::Adt(..) => {
1962 cb(type_.derived(ty.clone())); 1963 cb(type_.derived(ty.clone()));
1963 } 1964 }
1964 Ty::AssociatedType(..) => { 1965 TyKind::AssociatedType(..) => {
1965 if let Some(_) = ty.associated_type_parent_trait(db) { 1966 if let Some(_) = ty.associated_type_parent_trait(db) {
1966 cb(type_.derived(ty.clone())); 1967 cb(type_.derived(ty.clone()));
1967 } 1968 }
1968 } 1969 }
1969 Ty::OpaqueType(..) => { 1970 TyKind::OpaqueType(..) => {
1970 if let Some(bounds) = ty.impl_trait_bounds(db) { 1971 if let Some(bounds) = ty.impl_trait_bounds(db) {
1971 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 1972 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1972 } 1973 }
1973 } 1974 }
1974 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 1975 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
1975 if let Some(bounds) = ty.impl_trait_bounds(db) { 1976 if let Some(bounds) = ty.impl_trait_bounds(db) {
1976 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 1977 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1977 } 1978 }
1978 1979
1979 walk_substs(db, type_, &opaque_ty.parameters, cb); 1980 walk_substs(db, type_, &opaque_ty.parameters, cb);
1980 } 1981 }
1981 Ty::Placeholder(_) => { 1982 TyKind::Placeholder(_) => {
1982 if let Some(bounds) = ty.impl_trait_bounds(db) { 1983 if let Some(bounds) = ty.impl_trait_bounds(db) {
1983 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb); 1984 walk_bounds(db, &type_.derived(ty.clone()), &bounds, cb);
1984 } 1985 }
1985 } 1986 }
1986 Ty::Dyn(bounds) => { 1987 TyKind::Dyn(bounds) => {
1987 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb); 1988 walk_bounds(db, &type_.derived(ty.clone()), bounds.as_ref(), cb);
1988 } 1989 }
1989 1990
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index be1fd1f13..09009a3d8 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -14,7 +14,7 @@ use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 traits::{InEnvironment, Solution}, 15 traits::{InEnvironment, Solution},
16 utils::generics, 16 utils::generics,
17 BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, 17 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind,
18}; 18};
19 19
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -81,7 +81,8 @@ 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::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 84 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
85 .intern(&Interner),
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 86 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
86 }; 87 };
87 88
@@ -114,8 +115,8 @@ fn deref_by_trait(
114 // new variables in that case 115 // new variables in that case
115 116
116 for i in 1..vars.0.kinds.len() { 117 for i in 1..vars.0.kinds.len() {
117 if vars.0.value[i - 1] 118 if vars.0.value[i - 1].interned(&Interner)
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 119 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
119 { 120 {
120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 121 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
121 return None; 122 return None;
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index 2751cd304..b2bfd68d4 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -15,7 +15,7 @@ use crate::{
15 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
16 }, 16 },
17 utils::variant_data, 17 utils::variant_data,
18 AdtId, InferenceResult, Ty, 18 AdtId, InferenceResult, Interner, Ty, TyKind,
19}; 19};
20 20
21pub(crate) use hir_def::{ 21pub(crate) use hir_def::{
@@ -289,11 +289,10 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) = 289 let (body, source_map): (Arc<Body>, Arc<BodySourceMap>) =
290 db.body_with_source_map(self.owner.into()); 290 db.body_with_source_map(self.owner.into());
291 291
292 let match_expr_ty = match infer.type_of_expr.get(match_expr) { 292 let match_expr_ty = if infer.type_of_expr[match_expr].is_unknown() {
293 // If we can't resolve the type of the match expression 293 return;
294 // we cannot perform exhaustiveness checks. 294 } else {
295 None | Some(Ty::Unknown) => return, 295 &infer.type_of_expr[match_expr]
296 Some(ty) => ty,
297 }; 296 };
298 297
299 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db }; 298 let cx = MatchCheckCtx { match_expr, body, infer: infer.clone(), db };
@@ -379,14 +378,14 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
379 _ => return, 378 _ => return,
380 }; 379 };
381 380
382 let (params, required) = match mismatch.expected { 381 let (params, required) = match mismatch.expected.interned(&Interner) {
383 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 382 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
384 if enum_id == core_result_enum => 383 if *enum_id == core_result_enum =>
385 { 384 {
386 (parameters, "Ok".to_string()) 385 (parameters, "Ok".to_string())
387 } 386 }
388 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters) 387 TyKind::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
389 if enum_id == core_option_enum => 388 if *enum_id == core_option_enum =>
390 { 389 {
391 (parameters, "Some".to_string()) 390 (parameters, "Some".to_string())
392 } 391 }
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 04d39c571..5a5cdcbf3 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, AdtId, InferenceResult, Ty}; 230use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, TyKind};
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
@@ -626,13 +626,13 @@ pub(super) fn is_useful(
626 // - enum with no variants 626 // - enum with no variants
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().interned(&Interner) {
630 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ..) => { 630 TyKind::Adt(AdtId(hir_def::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::Never => return Ok(Usefulness::NotUseful), 635 TyKind::Never => return Ok(Usefulness::NotUseful),
636 _ => (), 636 _ => (),
637 } 637 }
638 638
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index e77a20fea..e095bee28 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,7 +11,7 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty}; 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Interner, TyKind};
15 15
16pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(super) struct UnsafeValidator<'a, 'b: 'a> {
17 owner: DefWithBodyId, 17 owner: DefWithBodyId,
@@ -110,7 +110,7 @@ fn walk_unsafe(
110 } 110 }
111 } 111 }
112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
113 if let Ty::Raw(..) = &infer[*expr] { 113 if let TyKind::Raw(..) = &infer[*expr].interned(&Interner) {
114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
115 } 115 }
116 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index ab51cb0a6..ee15f4f52 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -12,8 +12,8 @@ use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, 14 db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig,
15 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 15 GenericPredicate, Interner, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar,
16 TraitRef, Ty, 16 Substs, TraitRef, Ty, TyKind,
17}; 17};
18 18
19pub struct HirFormatter<'a> { 19pub struct HirFormatter<'a> {
@@ -267,32 +267,32 @@ impl HirDisplay for Ty {
267 return write!(f, "{}", TYPE_HINT_TRUNCATION); 267 return write!(f, "{}", TYPE_HINT_TRUNCATION);
268 } 268 }
269 269
270 match self { 270 match self.interned(&Interner) {
271 Ty::Never => write!(f, "!")?, 271 TyKind::Never => write!(f, "!")?,
272 Ty::Str => write!(f, "str")?, 272 TyKind::Str => write!(f, "str")?,
273 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, 273 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?,
274 Ty::Scalar(Scalar::Char) => write!(f, "char")?, 274 TyKind::Scalar(Scalar::Char) => write!(f, "char")?,
275 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, 275 &TyKind::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
276 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, 276 &TyKind::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
277 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, 277 &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
278 Ty::Slice(parameters) => { 278 TyKind::Slice(parameters) => {
279 let t = parameters.as_single(); 279 let t = parameters.as_single();
280 write!(f, "[")?; 280 write!(f, "[")?;
281 t.hir_fmt(f)?; 281 t.hir_fmt(f)?;
282 write!(f, "]")?; 282 write!(f, "]")?;
283 } 283 }
284 Ty::Array(parameters) => { 284 TyKind::Array(parameters) => {
285 let t = parameters.as_single(); 285 let t = parameters.as_single();
286 write!(f, "[")?; 286 write!(f, "[")?;
287 t.hir_fmt(f)?; 287 t.hir_fmt(f)?;
288 write!(f, "; _]")?; 288 write!(f, "; _]")?;
289 } 289 }
290 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { 290 TyKind::Raw(m, parameters) | TyKind::Ref(m, parameters) => {
291 let t = parameters.as_single(); 291 let t = parameters.as_single();
292 let ty_display = 292 let ty_display =
293 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 293 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
294 294
295 if matches!(self, Ty::Raw(..)) { 295 if matches!(self.interned(&Interner), TyKind::Raw(..)) {
296 write!( 296 write!(
297 f, 297 f,
298 "*{}", 298 "*{}",
@@ -313,11 +313,11 @@ impl HirDisplay for Ty {
313 } 313 }
314 314
315 let datas; 315 let datas;
316 let predicates = match t { 316 let predicates = match t.interned(&Interner) {
317 Ty::Dyn(predicates) if predicates.len() > 1 => { 317 TyKind::Dyn(predicates) if predicates.len() > 1 => {
318 Cow::Borrowed(predicates.as_ref()) 318 Cow::Borrowed(predicates.as_ref())
319 } 319 }
320 &Ty::Alias(AliasTy::Opaque(OpaqueTy { 320 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
321 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 321 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
322 ref parameters, 322 ref parameters,
323 })) => { 323 })) => {
@@ -347,7 +347,7 @@ impl HirDisplay for Ty {
347 write!(f, "{}", ty_display)?; 347 write!(f, "{}", ty_display)?;
348 } 348 }
349 } 349 }
350 Ty::Tuple(_, substs) => { 350 TyKind::Tuple(_, substs) => {
351 if substs.len() == 1 { 351 if substs.len() == 1 {
352 write!(f, "(")?; 352 write!(f, "(")?;
353 substs[0].hir_fmt(f)?; 353 substs[0].hir_fmt(f)?;
@@ -358,11 +358,11 @@ impl HirDisplay for Ty {
358 write!(f, ")")?; 358 write!(f, ")")?;
359 } 359 }
360 } 360 }
361 Ty::Function(fn_ptr) => { 361 TyKind::Function(fn_ptr) => {
362 let sig = CallableSig::from_fn_ptr(fn_ptr); 362 let sig = CallableSig::from_fn_ptr(fn_ptr);
363 sig.hir_fmt(f)?; 363 sig.hir_fmt(f)?;
364 } 364 }
365 Ty::FnDef(def, parameters) => { 365 TyKind::FnDef(def, parameters) => {
366 let def = *def; 366 let def = *def;
367 let sig = f.db.callable_item_signature(def).subst(parameters); 367 let sig = f.db.callable_item_signature(def).subst(parameters);
368 match def { 368 match def {
@@ -401,7 +401,7 @@ impl HirDisplay for Ty {
401 write!(f, " -> {}", ret_display)?; 401 write!(f, " -> {}", ret_display)?;
402 } 402 }
403 } 403 }
404 Ty::Adt(AdtId(def_id), parameters) => { 404 TyKind::Adt(AdtId(def_id), parameters) => {
405 match f.display_target { 405 match f.display_target {
406 DisplayTarget::Diagnostics | DisplayTarget::Test => { 406 DisplayTarget::Diagnostics | DisplayTarget::Test => {
407 let name = match *def_id { 407 let name = match *def_id {
@@ -427,37 +427,39 @@ impl HirDisplay for Ty {
427 } 427 }
428 428
429 if parameters.len() > 0 { 429 if parameters.len() > 0 {
430 let parameters_to_write = 430 let parameters_to_write = if f.display_target.is_source_code()
431 if f.display_target.is_source_code() || f.omit_verbose_types() { 431 || f.omit_verbose_types()
432 match self 432 {
433 .as_generic_def() 433 match self
434 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 434 .as_generic_def()
435 .filter(|defaults| !defaults.is_empty()) 435 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
436 { 436 .filter(|defaults| !defaults.is_empty())
437 None => parameters.0.as_ref(), 437 {
438 Some(default_parameters) => { 438 None => parameters.0.as_ref(),
439 let mut default_from = 0; 439 Some(default_parameters) => {
440 for (i, parameter) in parameters.iter().enumerate() { 440 let mut default_from = 0;
441 match (parameter, default_parameters.get(i)) { 441 for (i, parameter) in parameters.iter().enumerate() {
442 (&Ty::Unknown, _) | (_, None) => { 442 match (parameter.interned(&Interner), default_parameters.get(i))
443 {
444 (&TyKind::Unknown, _) | (_, None) => {
445 default_from = i + 1;
446 }
447 (_, Some(default_parameter)) => {
448 let actual_default = default_parameter
449 .clone()
450 .subst(&parameters.prefix(i));
451 if parameter != &actual_default {
443 default_from = i + 1; 452 default_from = i + 1;
444 } 453 }
445 (_, Some(default_parameter)) => {
446 let actual_default = default_parameter
447 .clone()
448 .subst(&parameters.prefix(i));
449 if parameter != &actual_default {
450 default_from = i + 1;
451 }
452 }
453 } 454 }
454 } 455 }
455 &parameters.0[0..default_from]
456 } 456 }
457 &parameters.0[0..default_from]
457 } 458 }
458 } else { 459 }
459 parameters.0.as_ref() 460 } else {
460 }; 461 parameters.0.as_ref()
462 };
461 if !parameters_to_write.is_empty() { 463 if !parameters_to_write.is_empty() {
462 write!(f, "<")?; 464 write!(f, "<")?;
463 f.write_joined(parameters_to_write, ", ")?; 465 f.write_joined(parameters_to_write, ", ")?;
@@ -465,7 +467,7 @@ impl HirDisplay for Ty {
465 } 467 }
466 } 468 }
467 } 469 }
468 Ty::AssociatedType(type_alias, parameters) => { 470 TyKind::AssociatedType(type_alias, parameters) => {
469 let trait_ = match type_alias.lookup(f.db.upcast()).container { 471 let trait_ = match type_alias.lookup(f.db.upcast()).container {
470 AssocContainerId::TraitId(it) => it, 472 AssocContainerId::TraitId(it) => it,
471 _ => panic!("not an associated type"), 473 _ => panic!("not an associated type"),
@@ -488,11 +490,11 @@ impl HirDisplay for Ty {
488 projection_ty.hir_fmt(f)?; 490 projection_ty.hir_fmt(f)?;
489 } 491 }
490 } 492 }
491 Ty::ForeignType(type_alias) => { 493 TyKind::ForeignType(type_alias) => {
492 let type_alias = f.db.type_alias_data(*type_alias); 494 let type_alias = f.db.type_alias_data(*type_alias);
493 write!(f, "{}", type_alias.name)?; 495 write!(f, "{}", type_alias.name)?;
494 } 496 }
495 Ty::OpaqueType(opaque_ty_id, parameters) => { 497 TyKind::OpaqueType(opaque_ty_id, parameters) => {
496 match opaque_ty_id { 498 match opaque_ty_id {
497 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 499 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
498 let datas = 500 let datas =
@@ -511,7 +513,7 @@ impl HirDisplay for Ty {
511 } 513 }
512 } 514 }
513 } 515 }
514 Ty::Closure(.., substs) => { 516 TyKind::Closure(.., substs) => {
515 let sig = substs[0].callable_sig(f.db); 517 let sig = substs[0].callable_sig(f.db);
516 if let Some(sig) = sig { 518 if let Some(sig) = sig {
517 if sig.params().is_empty() { 519 if sig.params().is_empty() {
@@ -535,7 +537,7 @@ impl HirDisplay for Ty {
535 write!(f, "{{closure}}")?; 537 write!(f, "{{closure}}")?;
536 } 538 }
537 } 539 }
538 Ty::Placeholder(id) => { 540 TyKind::Placeholder(id) => {
539 let generics = generics(f.db.upcast(), id.parent); 541 let generics = generics(f.db.upcast(), id.parent);
540 let param_data = &generics.params.types[id.local_id]; 542 let param_data = &generics.params.types[id.local_id];
541 match param_data.provenance { 543 match param_data.provenance {
@@ -553,12 +555,12 @@ impl HirDisplay for Ty {
553 } 555 }
554 } 556 }
555 } 557 }
556 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 558 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
557 Ty::Dyn(predicates) => { 559 TyKind::Dyn(predicates) => {
558 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 560 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
559 } 561 }
560 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 562 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
561 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 563 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
562 match opaque_ty.opaque_ty_id { 564 match opaque_ty.opaque_ty_id {
563 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 565 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
564 let datas = 566 let datas =
@@ -574,7 +576,7 @@ impl HirDisplay for Ty {
574 } 576 }
575 }; 577 };
576 } 578 }
577 Ty::Unknown => { 579 TyKind::Unknown => {
578 if f.display_target.is_source_code() { 580 if f.display_target.is_source_code() {
579 return Err(HirDisplayError::DisplaySourceCodeError( 581 return Err(HirDisplayError::DisplaySourceCodeError(
580 DisplaySourceCodeError::UnknownType, 582 DisplaySourceCodeError::UnknownType,
@@ -582,7 +584,7 @@ impl HirDisplay for Ty {
582 } 584 }
583 write!(f, "{{unknown}}")?; 585 write!(f, "{{unknown}}")?;
584 } 586 }
585 Ty::InferenceVar(..) => write!(f, "_")?, 587 TyKind::InferenceVar(..) => write!(f, "_")?,
586 } 588 }
587 Ok(()) 589 Ok(())
588 } 590 }
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4d771a91e..acde99b04 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -41,7 +41,8 @@ use super::{
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45 AliasTy, Interner, TyKind,
45}; 46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -169,7 +170,7 @@ impl Index<ExprId> for InferenceResult {
169 type Output = Ty; 170 type Output = Ty;
170 171
171 fn index(&self, expr: ExprId) -> &Ty { 172 fn index(&self, expr: ExprId) -> &Ty {
172 self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) 173 self.type_of_expr.get(expr).unwrap_or(&Ty(TyKind::Unknown))
173 } 174 }
174} 175}
175 176
@@ -177,7 +178,7 @@ impl Index<PatId> for InferenceResult {
177 type Output = Ty; 178 type Output = Ty;
178 179
179 fn index(&self, pat: PatId) -> &Ty { 180 fn index(&self, pat: PatId) -> &Ty {
180 self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) 181 self.type_of_pat.get(pat).unwrap_or(&Ty(TyKind::Unknown))
181 } 182 }
182} 183}
183 184
@@ -226,7 +227,7 @@ impl<'a> InferenceContext<'a> {
226 result: InferenceResult::default(), 227 result: InferenceResult::default(),
227 table: unify::InferenceTable::new(), 228 table: unify::InferenceTable::new(),
228 obligations: Vec::default(), 229 obligations: Vec::default(),
229 return_ty: Ty::Unknown, // set in collect_fn_signature 230 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
230 trait_env: TraitEnvironment::lower(db, &resolver), 231 trait_env: TraitEnvironment::lower(db, &resolver),
231 db, 232 db,
232 owner, 233 owner,
@@ -237,15 +238,19 @@ impl<'a> InferenceContext<'a> {
237 } 238 }
238 } 239 }
239 240
241 fn err_ty(&self) -> Ty {
242 TyKind::Unknown.intern(&Interner)
243 }
244
240 fn resolve_all(mut self) -> InferenceResult { 245 fn resolve_all(mut self) -> InferenceResult {
241 // FIXME resolve obligations as well (use Guidance if necessary) 246 // FIXME resolve obligations as well (use Guidance if necessary)
242 let mut result = std::mem::take(&mut self.result); 247 let mut result = std::mem::take(&mut self.result);
243 for ty in result.type_of_expr.values_mut() { 248 for ty in result.type_of_expr.values_mut() {
244 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 249 let resolved = self.table.resolve_ty_completely(ty.clone());
245 *ty = resolved; 250 *ty = resolved;
246 } 251 }
247 for ty in result.type_of_pat.values_mut() { 252 for ty in result.type_of_pat.values_mut() {
248 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 253 let resolved = self.table.resolve_ty_completely(ty.clone());
249 *ty = resolved; 254 *ty = resolved;
250 } 255 }
251 result 256 result
@@ -298,8 +303,8 @@ impl<'a> InferenceContext<'a> {
298 303
299 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 304 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it.
300 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty { 305 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
301 match ty { 306 match ty.interned(&Interner) {
302 Ty::Unknown => self.table.new_type_var(), 307 TyKind::Unknown => self.table.new_type_var(),
303 _ => ty, 308 _ => ty,
304 } 309 }
305 } 310 }
@@ -383,7 +388,7 @@ impl<'a> InferenceContext<'a> {
383 self.obligations.push(Obligation::Projection(projection)); 388 self.obligations.push(Obligation::Projection(projection));
384 self.resolve_ty_as_possible(ty) 389 self.resolve_ty_as_possible(ty)
385 } 390 }
386 None => Ty::Unknown, 391 None => self.err_ty(),
387 } 392 }
388 } 393 }
389 394
@@ -395,8 +400,10 @@ impl<'a> InferenceContext<'a> {
395 /// to do it as well. 400 /// to do it as well.
396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 401 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
397 let ty = self.resolve_ty_as_possible(ty); 402 let ty = self.resolve_ty_as_possible(ty);
398 ty.fold(&mut |ty| match ty { 403 ty.fold(&mut |ty| match ty.interned(&Interner) {
399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), 404 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
405 self.normalize_projection_ty(proj_ty.clone())
406 }
400 _ => ty, 407 _ => ty,
401 }) 408 })
402 } 409 }
@@ -412,7 +419,7 @@ impl<'a> InferenceContext<'a> {
412 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 419 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
413 let path = match path { 420 let path = match path {
414 Some(path) => path, 421 Some(path) => path,
415 None => return (Ty::Unknown, None), 422 None => return (self.err_ty(), None),
416 }; 423 };
417 let resolver = &self.resolver; 424 let resolver = &self.resolver;
418 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 425 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
@@ -421,7 +428,7 @@ impl<'a> InferenceContext<'a> {
421 let (resolution, unresolved) = 428 let (resolution, unresolved) =
422 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 429 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
423 Some(it) => it, 430 Some(it) => it,
424 None => return (Ty::Unknown, None), 431 None => return (self.err_ty(), None),
425 }; 432 };
426 return match resolution { 433 return match resolution {
427 TypeNs::AdtId(AdtId::StructId(strukt)) => { 434 TypeNs::AdtId(AdtId::StructId(strukt)) => {
@@ -462,11 +469,11 @@ impl<'a> InferenceContext<'a> {
462 } 469 }
463 } 470 }
464 // FIXME potentially resolve assoc type 471 // FIXME potentially resolve assoc type
465 (Ty::Unknown, None) 472 (self.err_ty(), None)
466 } 473 }
467 Some(_) => { 474 Some(_) => {
468 // FIXME diagnostic 475 // FIXME diagnostic
469 (Ty::Unknown, None) 476 (self.err_ty(), None)
470 } 477 }
471 } 478 }
472 } 479 }
@@ -480,15 +487,15 @@ impl<'a> InferenceContext<'a> {
480 } 487 }
481 TypeNs::AdtSelfType(_) => { 488 TypeNs::AdtSelfType(_) => {
482 // FIXME this could happen in array size expressions, once we're checking them 489 // FIXME this could happen in array size expressions, once we're checking them
483 (Ty::Unknown, None) 490 (self.err_ty(), None)
484 } 491 }
485 TypeNs::GenericParam(_) => { 492 TypeNs::GenericParam(_) => {
486 // FIXME potentially resolve assoc type 493 // FIXME potentially resolve assoc type
487 (Ty::Unknown, None) 494 (self.err_ty(), None)
488 } 495 }
489 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { 496 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
490 // FIXME diagnostic 497 // FIXME diagnostic
491 (Ty::Unknown, None) 498 (self.err_ty(), None)
492 } 499 }
493 }; 500 };
494 501
@@ -500,7 +507,7 @@ impl<'a> InferenceContext<'a> {
500 result 507 result
501 } else { 508 } else {
502 // FIXME diagnostic 509 // FIXME diagnostic
503 (Ty::Unknown, None) 510 (TyKind::Unknown.intern(&Interner), None)
504 } 511 }
505 } 512 }
506 513
@@ -711,12 +718,12 @@ impl Expectation {
711 718
712 /// This expresses no expectation on the type. 719 /// This expresses no expectation on the type.
713 fn none() -> Self { 720 fn none() -> Self {
714 Expectation { ty: Ty::Unknown, rvalue_hint: false } 721 Expectation { ty: TyKind::Unknown.intern(&Interner), rvalue_hint: false }
715 } 722 }
716 723
717 fn coercion_target(&self) -> &Ty { 724 fn coercion_target(&self) -> &Ty {
718 if self.rvalue_hint { 725 if self.rvalue_hint {
719 &Ty::Unknown 726 &Ty(TyKind::Unknown)
720 } else { 727 } else {
721 &self.ty 728 &self.ty
722 } 729 }
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 7e8846f27..36670043a 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +7,7 @@
7use chalk_ir::{Mutability, TyVariableKind}; 7use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty}; 10use crate::{autoderef, traits::Solution, Interner, Obligation, Substs, TraitRef, Ty, TyKind};
11 11
12use super::{InEnvironment, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
13 13
@@ -33,7 +33,9 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 33 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 34 ty1.clone()
35 } else { 35 } else {
36 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) { 36 if let (TyKind::FnDef(..), TyKind::FnDef(..)) =
37 (ty1.interned(&Interner), ty2.interned(&Interner))
38 {
37 cov_mark::hit!(coerce_fn_reification); 39 cov_mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 40 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 41 // pointers to have a chance at getting a match. See
@@ -51,13 +53,13 @@ impl<'a> InferenceContext<'a> {
51 } 53 }
52 54
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 55 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 56 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 57 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => { 58 (TyKind::Never, TyKind::InferenceVar(tv, TyVariableKind::General)) => {
57 self.table.type_variable_table.set_diverging(*tv, true); 59 self.table.type_variable_table.set_diverging(*tv, true);
58 return true; 60 return true;
59 } 61 }
60 (Ty::Never, _) => return true, 62 (TyKind::Never, _) => return true,
61 63
62 // Trivial cases, this should go after `never` check to 64 // Trivial cases, this should go after `never` check to
63 // avoid infer result type to be never 65 // avoid infer result type to be never
@@ -69,33 +71,33 @@ impl<'a> InferenceContext<'a> {
69 } 71 }
70 72
71 // Pointer weakening and function to pointer 73 // Pointer weakening and function to pointer
72 match (&mut from_ty, to_ty) { 74 match (&mut from_ty.0, to_ty.interned(&Interner)) {
73 // `*mut T` -> `*const T` 75 // `*mut T` -> `*const T`
74 // `&mut T` -> `&T` 76 // `&mut T` -> `&T`
75 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..)) 77 (TyKind::Raw(m1, ..), TyKind::Raw(m2 @ Mutability::Not, ..))
76 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => { 78 | (TyKind::Ref(m1, ..), TyKind::Ref(m2 @ Mutability::Not, ..)) => {
77 *m1 = *m2; 79 *m1 = *m2;
78 } 80 }
79 // `&T` -> `*const T` 81 // `&T` -> `*const T`
80 // `&mut T` -> `*mut T`/`*const T` 82 // `&mut T` -> `*mut T`/`*const T`
81 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..)) 83 (TyKind::Ref(.., substs), &TyKind::Raw(m2 @ Mutability::Not, ..))
82 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => { 84 | (TyKind::Ref(Mutability::Mut, substs), &TyKind::Raw(m2, ..)) => {
83 from_ty = Ty::Raw(m2, substs.clone()); 85 from_ty = TyKind::Raw(m2, substs.clone()).intern(&Interner);
84 } 86 }
85 87
86 // Illegal mutability conversion 88 // Illegal mutability conversion
87 (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..)) 89 (TyKind::Raw(Mutability::Not, ..), TyKind::Raw(Mutability::Mut, ..))
88 | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false, 90 | (TyKind::Ref(Mutability::Not, ..), TyKind::Ref(Mutability::Mut, ..)) => return false,
89 91
90 // `{function_type}` -> `fn()` 92 // `{function_type}` -> `fn()`
91 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) { 93 (TyKind::FnDef(..), TyKind::Function { .. }) => match from_ty.callable_sig(self.db) {
92 None => return false, 94 None => return false,
93 Some(sig) => { 95 Some(sig) => {
94 from_ty = Ty::fn_ptr(sig); 96 from_ty = Ty::fn_ptr(sig);
95 } 97 }
96 }, 98 },
97 99
98 (Ty::Closure(.., substs), Ty::Function { .. }) => { 100 (TyKind::Closure(.., substs), TyKind::Function { .. }) => {
99 from_ty = substs[0].clone(); 101 from_ty = substs[0].clone();
100 } 102 }
101 103
@@ -107,9 +109,11 @@ impl<'a> InferenceContext<'a> {
107 } 109 }
108 110
109 // Auto Deref if cannot coerce 111 // Auto Deref if cannot coerce
110 match (&from_ty, to_ty) { 112 match (from_ty.interned(&Interner), to_ty.interned(&Interner)) {
111 // FIXME: DerefMut 113 // FIXME: DerefMut
112 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]), 114 (TyKind::Ref(_, st1), TyKind::Ref(_, st2)) => {
115 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
116 }
113 117
114 // Otherwise, normal unify 118 // Otherwise, normal unify
115 _ => self.unify(&from_ty, to_ty), 119 _ => self.unify(&from_ty, to_ty),
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 262177ffb..4e77f22fd 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -20,8 +20,8 @@ use crate::{
20 primitive::{self, UintTy}, 20 primitive::{self, UintTy},
21 traits::{FnTrait, InEnvironment}, 21 traits::{FnTrait, InEnvironment},
22 utils::{generics, variant_data, Generics}, 22 utils::{generics, variant_data, Generics},
23 AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, 23 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, OpaqueTyId, Rawness,
24 Substs, TraitRef, Ty, 24 Scalar, Substs, TraitRef, Ty, TyKind,
25}; 25};
26 26
27use super::{ 27use super::{
@@ -57,7 +57,7 @@ impl<'a> InferenceContext<'a> {
57 // Return actual type when type mismatch. 57 // Return actual type when type mismatch.
58 // This is needed for diagnostic when return type mismatch. 58 // This is needed for diagnostic when return type mismatch.
59 ty 59 ty
60 } else if expected.coercion_target() == &Ty::Unknown { 60 } else if expected.coercion_target().is_unknown() {
61 ty 61 ty
62 } else { 62 } else {
63 expected.ty.clone() 63 expected.ty.clone()
@@ -84,7 +84,7 @@ impl<'a> InferenceContext<'a> {
84 arg_tys.push(arg); 84 arg_tys.push(arg);
85 } 85 }
86 let parameters = param_builder.build(); 86 let parameters = param_builder.build();
87 let arg_ty = Ty::Tuple(num_args, parameters); 87 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
88 let substs = 88 let substs =
89 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 89 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
90 90
@@ -116,10 +116,13 @@ impl<'a> InferenceContext<'a> {
116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
117 let body = Arc::clone(&self.body); // avoid borrow checker problem 117 let body = Arc::clone(&self.body); // avoid borrow checker problem
118 let ty = match &body[tgt_expr] { 118 let ty = match &body[tgt_expr] {
119 Expr::Missing => Ty::Unknown, 119 Expr::Missing => self.err_ty(),
120 Expr::If { condition, then_branch, else_branch } => { 120 Expr::If { condition, then_branch, else_branch } => {
121 // if let is desugared to match, so this is always simple if 121 // if let is desugared to match, so this is always simple if
122 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); 122 self.infer_expr(
123 *condition,
124 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
125 );
123 126
124 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 127 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
125 let mut both_arms_diverge = Diverges::Always; 128 let mut both_arms_diverge = Diverges::Always;
@@ -167,14 +170,14 @@ impl<'a> InferenceContext<'a> {
167 Expr::TryBlock { body } => { 170 Expr::TryBlock { body } => {
168 let _inner = self.infer_expr(*body, expected); 171 let _inner = self.infer_expr(*body, expected);
169 // FIXME should be std::result::Result<{inner}, _> 172 // FIXME should be std::result::Result<{inner}, _>
170 Ty::Unknown 173 self.err_ty()
171 } 174 }
172 Expr::Async { body } => { 175 Expr::Async { body } => {
173 // Use the first type parameter as the output type of future. 176 // Use the first type parameter as the output type of future.
174 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 177 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
175 let inner_ty = self.infer_expr(*body, &Expectation::none()); 178 let inner_ty = self.infer_expr(*body, &Expectation::none());
176 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 179 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
177 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) 180 TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner)
178 } 181 }
179 Expr::Loop { body, label } => { 182 Expr::Loop { body, label } => {
180 self.breakables.push(BreakableContext { 183 self.breakables.push(BreakableContext {
@@ -192,17 +195,20 @@ impl<'a> InferenceContext<'a> {
192 if ctxt.may_break { 195 if ctxt.may_break {
193 ctxt.break_ty 196 ctxt.break_ty
194 } else { 197 } else {
195 Ty::Never 198 TyKind::Never.intern(&Interner)
196 } 199 }
197 } 200 }
198 Expr::While { condition, body, label } => { 201 Expr::While { condition, body, label } => {
199 self.breakables.push(BreakableContext { 202 self.breakables.push(BreakableContext {
200 may_break: false, 203 may_break: false,
201 break_ty: Ty::Unknown, 204 break_ty: self.err_ty(),
202 label: label.map(|label| self.body[label].name.clone()), 205 label: label.map(|label| self.body[label].name.clone()),
203 }); 206 });
204 // while let is desugared to a match loop, so this is always simple while 207 // while let is desugared to a match loop, so this is always simple while
205 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); 208 self.infer_expr(
209 *condition,
210 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
211 );
206 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 212 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
207 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 213 let _ctxt = self.breakables.pop().expect("breakable stack broken");
208 // the body may not run, so it diverging doesn't mean we diverge 214 // the body may not run, so it diverging doesn't mean we diverge
@@ -214,7 +220,7 @@ impl<'a> InferenceContext<'a> {
214 220
215 self.breakables.push(BreakableContext { 221 self.breakables.push(BreakableContext {
216 may_break: false, 222 may_break: false,
217 break_ty: Ty::Unknown, 223 break_ty: self.err_ty(),
218 label: label.map(|label| self.body[label].name.clone()), 224 label: label.map(|label| self.body[label].name.clone()),
219 }); 225 });
220 let pat_ty = 226 let pat_ty =
@@ -249,12 +255,14 @@ impl<'a> InferenceContext<'a> {
249 None => self.table.new_type_var(), 255 None => self.table.new_type_var(),
250 }; 256 };
251 sig_tys.push(ret_ty.clone()); 257 sig_tys.push(ret_ty.clone());
252 let sig_ty = Ty::Function(FnPointer { 258 let sig_ty = TyKind::Function(FnPointer {
253 num_args: sig_tys.len() - 1, 259 num_args: sig_tys.len() - 1,
254 sig: FnSig { variadic: false }, 260 sig: FnSig { variadic: false },
255 substs: Substs(sig_tys.clone().into()), 261 substs: Substs(sig_tys.clone().into()),
256 }); 262 })
257 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); 263 .intern(&Interner);
264 let closure_ty =
265 TyKind::Closure(self.owner, tgt_expr, Substs::single(sig_ty)).intern(&Interner);
258 266
259 // Eagerly try to relate the closure type with the expected 267 // Eagerly try to relate the closure type with the expected
260 // type, otherwise we often won't have enough information to 268 // type, otherwise we often won't have enough information to
@@ -295,7 +303,7 @@ impl<'a> InferenceContext<'a> {
295 args.len(), 303 args.len(),
296 ) 304 )
297 }) 305 })
298 .unwrap_or((Vec::new(), Ty::Unknown)); 306 .unwrap_or((Vec::new(), self.err_ty()));
299 self.register_obligations_for_call(&callee_ty); 307 self.register_obligations_for_call(&callee_ty);
300 self.check_call_arguments(args, &param_tys); 308 self.check_call_arguments(args, &param_tys);
301 self.normalize_associated_types_in(ret_ty) 309 self.normalize_associated_types_in(ret_ty)
@@ -305,8 +313,11 @@ impl<'a> InferenceContext<'a> {
305 Expr::Match { expr, arms } => { 313 Expr::Match { expr, arms } => {
306 let input_ty = self.infer_expr(*expr, &Expectation::none()); 314 let input_ty = self.infer_expr(*expr, &Expectation::none());
307 315
308 let mut result_ty = 316 let mut result_ty = if arms.is_empty() {
309 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; 317 TyKind::Never.intern(&Interner)
318 } else {
319 self.table.new_type_var()
320 };
310 321
311 let matchee_diverges = self.diverges; 322 let matchee_diverges = self.diverges;
312 let mut all_arms_diverge = Diverges::Always; 323 let mut all_arms_diverge = Diverges::Always;
@@ -317,7 +328,7 @@ impl<'a> InferenceContext<'a> {
317 if let Some(guard_expr) = arm.guard { 328 if let Some(guard_expr) = arm.guard {
318 self.infer_expr( 329 self.infer_expr(
319 guard_expr, 330 guard_expr,
320 &Expectation::has_type(Ty::Scalar(Scalar::Bool)), 331 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
321 ); 332 );
322 } 333 }
323 334
@@ -333,9 +344,9 @@ impl<'a> InferenceContext<'a> {
333 Expr::Path(p) => { 344 Expr::Path(p) => {
334 // FIXME this could be more efficient... 345 // FIXME this could be more efficient...
335 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 346 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
336 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 347 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty())
337 } 348 }
338 Expr::Continue { .. } => Ty::Never, 349 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
339 Expr::Break { expr, label } => { 350 Expr::Break { expr, label } => {
340 let val_ty = if let Some(expr) = expr { 351 let val_ty = if let Some(expr) = expr {
341 self.infer_expr(*expr, &Expectation::none()) 352 self.infer_expr(*expr, &Expectation::none())
@@ -347,7 +358,7 @@ impl<'a> InferenceContext<'a> {
347 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { 358 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
348 ctxt.break_ty.clone() 359 ctxt.break_ty.clone()
349 } else { 360 } else {
350 Ty::Unknown 361 self.err_ty()
351 }; 362 };
352 363
353 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); 364 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty);
@@ -360,7 +371,7 @@ impl<'a> InferenceContext<'a> {
360 expr: tgt_expr, 371 expr: tgt_expr,
361 }); 372 });
362 } 373 }
363 Ty::Never 374 TyKind::Never.intern(&Interner)
364 } 375 }
365 Expr::Return { expr } => { 376 Expr::Return { expr } => {
366 if let Some(expr) = expr { 377 if let Some(expr) = expr {
@@ -369,14 +380,14 @@ impl<'a> InferenceContext<'a> {
369 let unit = Ty::unit(); 380 let unit = Ty::unit();
370 self.coerce(&unit, &self.return_ty.clone()); 381 self.coerce(&unit, &self.return_ty.clone());
371 } 382 }
372 Ty::Never 383 TyKind::Never.intern(&Interner)
373 } 384 }
374 Expr::Yield { expr } => { 385 Expr::Yield { expr } => {
375 // FIXME: track yield type for coercion 386 // FIXME: track yield type for coercion
376 if let Some(expr) = expr { 387 if let Some(expr) = expr {
377 self.infer_expr(*expr, &Expectation::none()); 388 self.infer_expr(*expr, &Expectation::none());
378 } 389 }
379 Ty::Never 390 TyKind::Never.intern(&Interner)
380 } 391 }
381 Expr::RecordLit { path, fields, spread } => { 392 Expr::RecordLit { path, fields, spread } => {
382 let (ty, def_id) = self.resolve_variant(path.as_ref()); 393 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -404,8 +415,9 @@ impl<'a> InferenceContext<'a> {
404 if let Some(field_def) = field_def { 415 if let Some(field_def) = field_def {
405 self.result.record_field_resolutions.insert(field.expr, field_def); 416 self.result.record_field_resolutions.insert(field.expr, field_def);
406 } 417 }
407 let field_ty = field_def 418 let field_ty = field_def.map_or(self.err_ty(), |it| {
408 .map_or(Ty::Unknown, |it| field_types[it.local_id].clone().subst(&substs)); 419 field_types[it.local_id].clone().subst(&substs)
420 });
409 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 421 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
410 } 422 }
411 if let Some(expr) = spread { 423 if let Some(expr) = spread {
@@ -424,27 +436,33 @@ impl<'a> InferenceContext<'a> {
424 environment: self.trait_env.clone(), 436 environment: self.trait_env.clone(),
425 }, 437 },
426 ) 438 )
427 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 439 .find_map(|derefed_ty| {
428 Ty::Tuple(_, substs) => { 440 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
429 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 441 TyKind::Tuple(_, substs) => {
430 } 442 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
431 Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 443 }
432 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 444 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
433 let field = FieldId { parent: s.into(), local_id }; 445 self.db.struct_data(*s).variant_data.field(name).map(|local_id| {
434 self.write_field_resolution(tgt_expr, field); 446 let field = FieldId { parent: (*s).into(), local_id };
435 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters) 447 self.write_field_resolution(tgt_expr, field);
436 }) 448 self.db.field_types((*s).into())[field.local_id]
437 } 449 .clone()
438 Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { 450 .subst(&parameters)
439 self.db.union_data(u).variant_data.field(name).map(|local_id| { 451 })
440 let field = FieldId { parent: u.into(), local_id }; 452 }
441 self.write_field_resolution(tgt_expr, field); 453 TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
442 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters) 454 self.db.union_data(*u).variant_data.field(name).map(|local_id| {
443 }) 455 let field = FieldId { parent: (*u).into(), local_id };
456 self.write_field_resolution(tgt_expr, field);
457 self.db.field_types((*u).into())[field.local_id]
458 .clone()
459 .subst(&parameters)
460 })
461 }
462 _ => None,
444 } 463 }
445 _ => None,
446 }) 464 })
447 .unwrap_or(Ty::Unknown); 465 .unwrap_or(self.err_ty());
448 let ty = self.insert_type_vars(ty); 466 let ty = self.insert_type_vars(ty);
449 self.normalize_associated_types_in(ty) 467 self.normalize_associated_types_in(ty)
450 } 468 }
@@ -481,9 +499,10 @@ impl<'a> InferenceContext<'a> {
481 }; 499 };
482 let inner_ty = self.infer_expr_inner(*expr, &expectation); 500 let inner_ty = self.infer_expr_inner(*expr, &expectation);
483 match rawness { 501 match rawness {
484 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), 502 Rawness::RawPtr => TyKind::Raw(mutability, Substs::single(inner_ty)),
485 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), 503 Rawness::Ref => TyKind::Ref(mutability, Substs::single(inner_ty)),
486 } 504 }
505 .intern(&Interner)
487 } 506 }
488 Expr::Box { expr } => { 507 Expr::Box { expr } => {
489 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 508 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
@@ -499,7 +518,7 @@ impl<'a> InferenceContext<'a> {
499 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 518 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
500 Ty::adt_ty(box_, sb.build()) 519 Ty::adt_ty(box_, sb.build())
501 } else { 520 } else {
502 Ty::Unknown 521 self.err_ty()
503 } 522 }
504 } 523 }
505 Expr::UnaryOp { expr, op } => { 524 Expr::UnaryOp { expr, op } => {
@@ -519,31 +538,31 @@ impl<'a> InferenceContext<'a> {
519 Some(derefed_ty) => { 538 Some(derefed_ty) => {
520 canonicalized.decanonicalize_ty(derefed_ty.value) 539 canonicalized.decanonicalize_ty(derefed_ty.value)
521 } 540 }
522 None => Ty::Unknown, 541 None => self.err_ty(),
523 } 542 }
524 } 543 }
525 None => Ty::Unknown, 544 None => self.err_ty(),
526 }, 545 },
527 UnaryOp::Neg => { 546 UnaryOp::Neg => {
528 match &inner_ty { 547 match inner_ty.interned(&Interner) {
529 // Fast path for builtins 548 // Fast path for builtins
530 Ty::Scalar(Scalar::Int(_)) 549 TyKind::Scalar(Scalar::Int(_))
531 | Ty::Scalar(Scalar::Uint(_)) 550 | TyKind::Scalar(Scalar::Uint(_))
532 | Ty::Scalar(Scalar::Float(_)) 551 | TyKind::Scalar(Scalar::Float(_))
533 | Ty::InferenceVar(_, TyVariableKind::Integer) 552 | TyKind::InferenceVar(_, TyVariableKind::Integer)
534 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, 553 | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty,
535 // Otherwise we resolve via the std::ops::Neg trait 554 // Otherwise we resolve via the std::ops::Neg trait
536 _ => self 555 _ => self
537 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 556 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
538 } 557 }
539 } 558 }
540 UnaryOp::Not => { 559 UnaryOp::Not => {
541 match &inner_ty { 560 match inner_ty.interned(&Interner) {
542 // Fast path for builtins 561 // Fast path for builtins
543 Ty::Scalar(Scalar::Bool) 562 TyKind::Scalar(Scalar::Bool)
544 | Ty::Scalar(Scalar::Int(_)) 563 | TyKind::Scalar(Scalar::Int(_))
545 | Ty::Scalar(Scalar::Uint(_)) 564 | TyKind::Scalar(Scalar::Uint(_))
546 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, 565 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
547 // Otherwise we resolve via the std::ops::Not trait 566 // Otherwise we resolve via the std::ops::Not trait
548 _ => self 567 _ => self
549 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 568 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -554,7 +573,9 @@ impl<'a> InferenceContext<'a> {
554 Expr::BinaryOp { lhs, rhs, op } => match op { 573 Expr::BinaryOp { lhs, rhs, op } => match op {
555 Some(op) => { 574 Some(op) => {
556 let lhs_expectation = match op { 575 let lhs_expectation = match op {
557 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), 576 BinaryOp::LogicOp(..) => {
577 Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner))
578 }
558 _ => Expectation::none(), 579 _ => Expectation::none(),
559 }; 580 };
560 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 581 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -563,7 +584,7 @@ impl<'a> InferenceContext<'a> {
563 584
564 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 585 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
565 586
566 if ret == Ty::Unknown { 587 if ret.is_unknown() {
567 cov_mark::hit!(infer_expr_inner_binary_operator_overload); 588 cov_mark::hit!(infer_expr_inner_binary_operator_overload);
568 589
569 self.resolve_associated_type_with_params( 590 self.resolve_associated_type_with_params(
@@ -575,7 +596,7 @@ impl<'a> InferenceContext<'a> {
575 ret 596 ret
576 } 597 }
577 } 598 }
578 _ => Ty::Unknown, 599 _ => self.err_ty(),
579 }, 600 },
580 Expr::Range { lhs, rhs, range_type } => { 601 Expr::Range { lhs, rhs, range_type } => {
581 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); 602 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none()));
@@ -586,33 +607,33 @@ impl<'a> InferenceContext<'a> {
586 match (range_type, lhs_ty, rhs_ty) { 607 match (range_type, lhs_ty, rhs_ty) {
587 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 608 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
588 Some(adt) => Ty::adt_ty(adt, Substs::empty()), 609 Some(adt) => Ty::adt_ty(adt, Substs::empty()),
589 None => Ty::Unknown, 610 None => self.err_ty(),
590 }, 611 },
591 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 612 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
592 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 613 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
593 None => Ty::Unknown, 614 None => self.err_ty(),
594 }, 615 },
595 (RangeOp::Inclusive, None, Some(ty)) => { 616 (RangeOp::Inclusive, None, Some(ty)) => {
596 match self.resolve_range_to_inclusive() { 617 match self.resolve_range_to_inclusive() {
597 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 618 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
598 None => Ty::Unknown, 619 None => self.err_ty(),
599 } 620 }
600 } 621 }
601 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 622 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
602 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 623 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
603 None => Ty::Unknown, 624 None => self.err_ty(),
604 }, 625 },
605 (RangeOp::Inclusive, Some(_), Some(ty)) => { 626 (RangeOp::Inclusive, Some(_), Some(ty)) => {
606 match self.resolve_range_inclusive() { 627 match self.resolve_range_inclusive() {
607 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 628 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
608 None => Ty::Unknown, 629 None => self.err_ty(),
609 } 630 }
610 } 631 }
611 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 632 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
612 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 633 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
613 None => Ty::Unknown, 634 None => self.err_ty(),
614 }, 635 },
615 (RangeOp::Inclusive, _, None) => Ty::Unknown, 636 (RangeOp::Inclusive, _, None) => self.err_ty(),
616 } 637 }
617 } 638 }
618 Expr::Index { base, index } => { 639 Expr::Index { base, index } => {
@@ -631,19 +652,19 @@ impl<'a> InferenceContext<'a> {
631 index_trait, 652 index_trait,
632 ); 653 );
633 let self_ty = 654 let self_ty =
634 self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); 655 self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value));
635 self.resolve_associated_type_with_params( 656 self.resolve_associated_type_with_params(
636 self_ty, 657 self_ty,
637 self.resolve_ops_index_output(), 658 self.resolve_ops_index_output(),
638 &[index_ty], 659 &[index_ty],
639 ) 660 )
640 } else { 661 } else {
641 Ty::Unknown 662 self.err_ty()
642 } 663 }
643 } 664 }
644 Expr::Tuple { exprs } => { 665 Expr::Tuple { exprs } => {
645 let mut tys = match &expected.ty { 666 let mut tys = match expected.ty.interned(&Interner) {
646 Ty::Tuple(_, substs) => substs 667 TyKind::Tuple(_, substs) => substs
647 .iter() 668 .iter()
648 .cloned() 669 .cloned()
649 .chain(repeat_with(|| self.table.new_type_var())) 670 .chain(repeat_with(|| self.table.new_type_var()))
@@ -656,11 +677,11 @@ impl<'a> InferenceContext<'a> {
656 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 677 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
657 } 678 }
658 679
659 Ty::Tuple(tys.len(), Substs(tys.into())) 680 TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner)
660 } 681 }
661 Expr::Array(array) => { 682 Expr::Array(array) => {
662 let elem_ty = match &expected.ty { 683 let elem_ty = match expected.ty.interned(&Interner) {
663 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), 684 TyKind::Array(st) | TyKind::Slice(st) => st.as_single().clone(),
664 _ => self.table.new_type_var(), 685 _ => self.table.new_type_var(),
665 }; 686 };
666 687
@@ -677,43 +698,51 @@ impl<'a> InferenceContext<'a> {
677 ); 698 );
678 self.infer_expr( 699 self.infer_expr(
679 *repeat, 700 *repeat,
680 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), 701 &Expectation::has_type(
702 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
703 ),
681 ); 704 );
682 } 705 }
683 } 706 }
684 707
685 Ty::Array(Substs::single(elem_ty)) 708 TyKind::Array(Substs::single(elem_ty)).intern(&Interner)
686 } 709 }
687 Expr::Literal(lit) => match lit { 710 Expr::Literal(lit) => match lit {
688 Literal::Bool(..) => Ty::Scalar(Scalar::Bool), 711 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
689 Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), 712 Literal::String(..) => {
713 TyKind::Ref(Mutability::Not, Substs::single(TyKind::Str.intern(&Interner)))
714 .intern(&Interner)
715 }
690 Literal::ByteString(..) => { 716 Literal::ByteString(..) => {
691 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); 717 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
692 let array_type = Ty::Array(Substs::single(byte_type)); 718 let array_type = TyKind::Array(Substs::single(byte_type)).intern(&Interner);
693 Ty::Ref(Mutability::Not, Substs::single(array_type)) 719 TyKind::Ref(Mutability::Not, Substs::single(array_type)).intern(&Interner)
694 } 720 }
695 Literal::Char(..) => Ty::Scalar(Scalar::Char), 721 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
696 Literal::Int(_v, ty) => match ty { 722 Literal::Int(_v, ty) => match ty {
697 Some(int_ty) => { 723 Some(int_ty) => {
698 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) 724 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
725 .intern(&Interner)
699 } 726 }
700 None => self.table.new_integer_var(), 727 None => self.table.new_integer_var(),
701 }, 728 },
702 Literal::Uint(_v, ty) => match ty { 729 Literal::Uint(_v, ty) => match ty {
703 Some(int_ty) => { 730 Some(int_ty) => {
704 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) 731 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
732 .intern(&Interner)
705 } 733 }
706 None => self.table.new_integer_var(), 734 None => self.table.new_integer_var(),
707 }, 735 },
708 Literal::Float(_v, ty) => match ty { 736 Literal::Float(_v, ty) => match ty {
709 Some(float_ty) => { 737 Some(float_ty) => {
710 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) 738 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
739 .intern(&Interner)
711 } 740 }
712 None => self.table.new_float_var(), 741 None => self.table.new_float_var(),
713 }, 742 },
714 }, 743 },
715 }; 744 };
716 // use a new type variable if we got Ty::Unknown here 745 // use a new type variable if we got unknown here
717 let ty = self.insert_type_vars_shallow(ty); 746 let ty = self.insert_type_vars_shallow(ty);
718 let ty = self.resolve_ty_as_possible(ty); 747 let ty = self.resolve_ty_as_possible(ty);
719 self.write_expr_ty(tgt_expr, ty.clone()); 748 self.write_expr_ty(tgt_expr, ty.clone());
@@ -730,7 +759,7 @@ impl<'a> InferenceContext<'a> {
730 match stmt { 759 match stmt {
731 Statement::Let { pat, type_ref, initializer } => { 760 Statement::Let { pat, type_ref, initializer } => {
732 let decl_ty = 761 let decl_ty =
733 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); 762 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty());
734 763
735 // Always use the declared type when specified 764 // Always use the declared type when specified
736 let mut ty = decl_ty.clone(); 765 let mut ty = decl_ty.clone();
@@ -738,7 +767,7 @@ impl<'a> InferenceContext<'a> {
738 if let Some(expr) = initializer { 767 if let Some(expr) = initializer {
739 let actual_ty = 768 let actual_ty =
740 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); 769 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
741 if decl_ty == Ty::Unknown { 770 if decl_ty.is_unknown() {
742 ty = actual_ty; 771 ty = actual_ty;
743 } 772 }
744 } 773 }
@@ -802,7 +831,7 @@ impl<'a> InferenceContext<'a> {
802 self.write_method_resolution(tgt_expr, func); 831 self.write_method_resolution(tgt_expr, func);
803 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 832 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
804 } 833 }
805 None => (receiver_ty, Binders::new(0, Ty::Unknown), None), 834 None => (receiver_ty, Binders::new(0, self.err_ty()), None),
806 }; 835 };
807 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 836 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
808 let method_ty = method_ty.subst(&substs); 837 let method_ty = method_ty.subst(&substs);
@@ -813,15 +842,17 @@ impl<'a> InferenceContext<'a> {
813 if !sig.params().is_empty() { 842 if !sig.params().is_empty() {
814 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) 843 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone())
815 } else { 844 } else {
816 (Ty::Unknown, Vec::new(), sig.ret().clone()) 845 (self.err_ty(), Vec::new(), sig.ret().clone())
817 } 846 }
818 } 847 }
819 None => (Ty::Unknown, Vec::new(), Ty::Unknown), 848 None => (self.err_ty(), Vec::new(), self.err_ty()),
820 }; 849 };
821 // Apply autoref so the below unification works correctly 850 // Apply autoref so the below unification works correctly
822 // FIXME: return correct autorefs from lookup_method 851 // FIXME: return correct autorefs from lookup_method
823 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 852 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
824 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), 853 Some((_, mutability)) => {
854 TyKind::Ref(mutability, Substs::single(derefed_receiver_ty)).intern(&Interner)
855 }
825 _ => derefed_receiver_ty, 856 _ => derefed_receiver_ty,
826 }; 857 };
827 self.unify(&expected_receiver_ty, &actual_receiver_ty); 858 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -837,7 +868,7 @@ impl<'a> InferenceContext<'a> {
837 // that we have more information about the types of arguments when we 868 // that we have more information about the types of arguments when we
838 // type-check the functions. This isn't really the right way to do this. 869 // type-check the functions. This isn't really the right way to do this.
839 for &check_closures in &[false, true] { 870 for &check_closures in &[false, true] {
840 let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); 871 let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty()));
841 for (&arg, param_ty) in args.iter().zip(param_iter) { 872 for (&arg, param_ty) in args.iter().zip(param_iter) {
842 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); 873 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. });
843 if is_closure != check_closures { 874 if is_closure != check_closures {
@@ -867,7 +898,7 @@ impl<'a> InferenceContext<'a> {
867 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 898 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
868 substs.push(receiver_ty.clone()); 899 substs.push(receiver_ty.clone());
869 } else { 900 } else {
870 substs.push(Ty::Unknown); 901 substs.push(self.err_ty());
871 } 902 }
872 } 903 }
873 } 904 }
@@ -891,15 +922,15 @@ impl<'a> InferenceContext<'a> {
891 }; 922 };
892 let supplied_params = substs.len(); 923 let supplied_params = substs.len();
893 for _ in supplied_params..total_len { 924 for _ in supplied_params..total_len {
894 substs.push(Ty::Unknown); 925 substs.push(self.err_ty());
895 } 926 }
896 assert_eq!(substs.len(), total_len); 927 assert_eq!(substs.len(), total_len);
897 Substs(substs.into()) 928 Substs(substs.into())
898 } 929 }
899 930
900 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 931 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
901 if let &Ty::FnDef(def, ref parameters) = callable_ty { 932 if let TyKind::FnDef(def, parameters) = callable_ty.interned(&Interner) {
902 let generic_predicates = self.db.generic_predicates(def.into()); 933 let generic_predicates = self.db.generic_predicates((*def).into());
903 for predicate in generic_predicates.iter() { 934 for predicate in generic_predicates.iter() {
904 let predicate = predicate.clone().subst(parameters); 935 let predicate = predicate.clone().subst(parameters);
905 if let Some(obligation) = Obligation::from_predicate(predicate) { 936 if let Some(obligation) = Obligation::from_predicate(predicate) {
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index a0ac8d80f..a16755cda 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -12,7 +12,7 @@ use hir_def::{
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13 13
14use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
15use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty}; 15use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substs, Ty, TyKind};
16 16
17impl<'a> InferenceContext<'a> { 17impl<'a> InferenceContext<'a> {
18 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -46,7 +46,7 @@ impl<'a> InferenceContext<'a> {
46 let expected_ty = var_data 46 let expected_ty = var_data
47 .as_ref() 47 .as_ref()
48 .and_then(|d| d.field(&Name::new_tuple_field(i))) 48 .and_then(|d| d.field(&Name::new_tuple_field(i)))
49 .map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); 49 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
50 let expected_ty = self.normalize_associated_types_in(expected_ty); 50 let expected_ty = self.normalize_associated_types_in(expected_ty);
51 self.infer_pat(subpat, &expected_ty, default_bm); 51 self.infer_pat(subpat, &expected_ty, default_bm);
52 } 52 }
@@ -80,8 +80,8 @@ impl<'a> InferenceContext<'a> {
80 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def); 80 self.result.record_pat_field_resolutions.insert(subpat.pat, field_def);
81 } 81 }
82 82
83 let expected_ty = 83 let expected_ty = matching_field
84 matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); 84 .map_or(self.err_ty(), |field| field_tys[field].clone().subst(&substs));
85 let expected_ty = self.normalize_associated_types_in(expected_ty); 85 let expected_ty = self.normalize_associated_types_in(expected_ty);
86 self.infer_pat(subpat.pat, &expected_ty, default_bm); 86 self.infer_pat(subpat.pat, &expected_ty, default_bm);
87 } 87 }
@@ -129,7 +129,8 @@ impl<'a> InferenceContext<'a> {
129 None => (&args[..], &[][..]), 129 None => (&args[..], &[][..]),
130 }; 130 };
131 let n_uncovered_patterns = expectations.len().saturating_sub(args.len()); 131 let n_uncovered_patterns = expectations.len().saturating_sub(args.len());
132 let mut expectations_iter = expectations.iter().chain(repeat(&Ty::Unknown)); 132 let err_ty = self.err_ty();
133 let mut expectations_iter = expectations.iter().chain(repeat(&err_ty));
133 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm); 134 let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
134 135
135 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len()); 136 let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
@@ -137,7 +138,7 @@ impl<'a> InferenceContext<'a> {
137 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());
138 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
139 140
140 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into())) 141 TyKind::Tuple(inner_tys.len(), Substs(inner_tys.into())).intern(&Interner)
141 } 142 }
142 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
143 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -147,7 +148,7 @@ impl<'a> InferenceContext<'a> {
147 } 148 }
148 ty 149 ty
149 } else { 150 } else {
150 Ty::Unknown 151 self.err_ty()
151 } 152 }
152 } 153 }
153 Pat::Ref { pat, mutability } => { 154 Pat::Ref { pat, mutability } => {
@@ -159,10 +160,10 @@ impl<'a> InferenceContext<'a> {
159 } 160 }
160 inner_ty 161 inner_ty
161 } 162 }
162 _ => &Ty::Unknown, 163 _ => &Ty(TyKind::Unknown),
163 }; 164 };
164 let subty = self.infer_pat(*pat, expectation, default_bm); 165 let subty = self.infer_pat(*pat, expectation, default_bm);
165 Ty::Ref(mutability, Substs::single(subty)) 166 TyKind::Ref(mutability, Substs::single(subty)).intern(&Interner)
166 } 167 }
167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 168 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
168 p.as_ref(), 169 p.as_ref(),
@@ -178,7 +179,7 @@ impl<'a> InferenceContext<'a> {
178 Pat::Path(path) => { 179 Pat::Path(path) => {
179 // FIXME use correct resolver for the surrounding expression 180 // FIXME use correct resolver for the surrounding expression
180 let resolver = self.resolver.clone(); 181 let resolver = self.resolver.clone();
181 self.infer_path(&resolver, &path, pat.into()).unwrap_or(Ty::Unknown) 182 self.infer_path(&resolver, &path, pat.into()).unwrap_or(self.err_ty())
182 } 183 }
183 Pat::Bind { mode, name: _, subpat } => { 184 Pat::Bind { mode, name: _, subpat } => {
184 let mode = if mode == &BindingAnnotation::Unannotated { 185 let mode = if mode == &BindingAnnotation::Unannotated {
@@ -195,7 +196,7 @@ impl<'a> InferenceContext<'a> {
195 196
196 let bound_ty = match mode { 197 let bound_ty = match mode {
197 BindingMode::Ref(mutability) => { 198 BindingMode::Ref(mutability) => {
198 Ty::Ref(mutability, Substs::single(inner_ty.clone())) 199 TyKind::Ref(mutability, Substs::single(inner_ty.clone())).intern(&Interner)
199 } 200 }
200 BindingMode::Move => inner_ty.clone(), 201 BindingMode::Move => inner_ty.clone(),
201 }; 202 };
@@ -204,17 +205,17 @@ impl<'a> InferenceContext<'a> {
204 return inner_ty; 205 return inner_ty;
205 } 206 }
206 Pat::Slice { prefix, slice, suffix } => { 207 Pat::Slice { prefix, slice, suffix } => {
207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected { 208 let (container_ty, elem_ty): (fn(_) -> _, _) = match expected.interned(&Interner) {
208 Ty::Array(st) => (Ty::Array, st.as_single().clone()), 209 TyKind::Array(st) => (TyKind::Array, st.as_single().clone()),
209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), 210 TyKind::Slice(st) => (TyKind::Slice, st.as_single().clone()),
210 _ => (Ty::Slice, Ty::Unknown), 211 _ => (TyKind::Slice, self.err_ty()),
211 }; 212 };
212 213
213 for pat_id in prefix.iter().chain(suffix) { 214 for pat_id in prefix.iter().chain(suffix) {
214 self.infer_pat(*pat_id, &elem_ty, default_bm); 215 self.infer_pat(*pat_id, &elem_ty, default_bm);
215 } 216 }
216 217
217 let pat_ty = container_ty(Substs::single(elem_ty)); 218 let pat_ty = container_ty(Substs::single(elem_ty)).intern(&Interner);
218 if let Some(slice_pat_id) = slice { 219 if let Some(slice_pat_id) = slice {
219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 220 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
220 } 221 }
@@ -232,20 +233,20 @@ impl<'a> InferenceContext<'a> {
232 Some(box_adt) => { 233 Some(box_adt) => {
233 let inner_expected = match expected.as_adt() { 234 let inner_expected = match expected.as_adt() {
234 Some((adt, substs)) if adt == box_adt => substs.as_single(), 235 Some((adt, substs)) if adt == box_adt => substs.as_single(),
235 _ => &Ty::Unknown, 236 _ => &Ty(TyKind::Unknown),
236 }; 237 };
237 238
238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 239 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
239 Ty::adt_ty(box_adt, Substs::single(inner_ty)) 240 Ty::adt_ty(box_adt, Substs::single(inner_ty))
240 } 241 }
241 None => Ty::Unknown, 242 None => self.err_ty(),
242 }, 243 },
243 Pat::ConstBlock(expr) => { 244 Pat::ConstBlock(expr) => {
244 self.infer_expr(*expr, &Expectation::has_type(expected.clone())) 245 self.infer_expr(*expr, &Expectation::has_type(expected.clone()))
245 } 246 }
246 Pat::Missing => Ty::Unknown, 247 Pat::Missing => self.err_ty(),
247 }; 248 };
248 // use a new type variable if we got Ty::Unknown here 249 // use a new type variable if we got error type here
249 let ty = self.insert_type_vars_shallow(ty); 250 let ty = self.insert_type_vars_shallow(ty);
250 if !self.unify(&ty, expected) { 251 if !self.unify(&ty, expected) {
251 // FIXME record mismatch, we need to change the type of self.type_mismatches for that 252 // FIXME record mismatch, we need to change the type of self.type_mismatches for that
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index ae3554bac..392952178 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -9,7 +9,7 @@ use hir_def::{
9}; 9};
10use hir_expand::name::Name; 10use hir_expand::name::Name;
11 11
12use crate::{method_resolution, Substs, Ty, ValueTyDefId}; 12use crate::{method_resolution, Interner, Substs, Ty, TyKind, ValueTyDefId};
13 13
14use super::{ExprOrPatId, InferenceContext, TraitRef}; 14use super::{ExprOrPatId, InferenceContext, TraitRef};
15 15
@@ -144,7 +144,7 @@ impl<'a> InferenceContext<'a> {
144 remaining_segments_for_ty, 144 remaining_segments_for_ty,
145 true, 145 true,
146 ); 146 );
147 if let Ty::Unknown = ty { 147 if let TyKind::Unknown = ty.interned(&Interner) {
148 return None; 148 return None;
149 } 149 }
150 150
@@ -209,7 +209,7 @@ impl<'a> InferenceContext<'a> {
209 name: &Name, 209 name: &Name,
210 id: ExprOrPatId, 210 id: ExprOrPatId,
211 ) -> Option<(ValueNs, Option<Substs>)> { 211 ) -> Option<(ValueNs, Option<Substs>)> {
212 if let Ty::Unknown = ty { 212 if let TyKind::Unknown = ty.interned(&Interner) {
213 return None; 213 return None;
214 } 214 }
215 215
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 54fcfed10..16d89ed1b 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -7,8 +7,8 @@ use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
7 7
8use super::{InferenceContext, Obligation}; 8use super::{InferenceContext, Obligation};
9use crate::{ 9use crate::{
10 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar, 10 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Interner,
11 Substs, Ty, TypeWalk, 11 Scalar, Substs, Ty, TyKind, TypeWalk,
12}; 12};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -49,8 +49,8 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
49 49
50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 50 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
51 t.fold_binders( 51 t.fold_binders(
52 &mut |ty, binders| match ty { 52 &mut |ty, binders| match ty.interned(&Interner) {
53 Ty::InferenceVar(var, kind) => { 53 &TyKind::InferenceVar(var, kind) => {
54 let inner = var.to_inner(); 54 let inner = var.to_inner();
55 if self.var_stack.contains(&inner) { 55 if self.var_stack.contains(&inner) {
56 // recursive type 56 // recursive type
@@ -66,7 +66,7 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
66 } else { 66 } else {
67 let root = self.ctx.table.var_unification_table.find(inner); 67 let root = self.ctx.table.var_unification_table.find(inner);
68 let position = self.add(InferenceVar::from_inner(root), kind); 68 let position = self.add(InferenceVar::from_inner(root), kind);
69 Ty::BoundVar(BoundVar::new(binders, position)) 69 TyKind::BoundVar(BoundVar::new(binders, position)).intern(&Interner)
70 } 70 }
71 } 71 }
72 _ => ty, 72 _ => ty,
@@ -108,10 +108,10 @@ impl<T> Canonicalized<T> {
108 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 108 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
109 ty.walk_mut_binders( 109 ty.walk_mut_binders(
110 &mut |ty, binders| { 110 &mut |ty, binders| {
111 if let &mut Ty::BoundVar(bound) = ty { 111 if let &mut TyKind::BoundVar(bound) = &mut ty.0 {
112 if bound.debruijn >= binders { 112 if bound.debruijn >= binders {
113 let (v, k) = self.free_vars[bound.index]; 113 let (v, k) = self.free_vars[bound.index];
114 *ty = Ty::InferenceVar(v, k); 114 *ty = TyKind::InferenceVar(v, k).intern(&Interner);
115 } 115 }
116 } 116 }
117 }, 117 },
@@ -142,7 +142,7 @@ impl<T> Canonicalized<T> {
142 // eagerly replace projections in the type; we may be getting types 142 // eagerly replace projections in the type; we may be getting types
143 // e.g. from where clauses where this hasn't happened yet 143 // e.g. from where clauses where this hasn't happened yet
144 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 144 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
145 ctx.table.unify(&Ty::InferenceVar(v, k), &ty); 145 ctx.table.unify(&TyKind::InferenceVar(v, k).intern(&Interner), &ty);
146 } 146 }
147 } 147 }
148} 148}
@@ -166,7 +166,10 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
166 // (kind of hacky) 166 // (kind of hacky)
167 for (i, var) in vars.iter().enumerate() { 167 for (i, var) in vars.iter().enumerate() {
168 if &*table.resolve_ty_shallow(var) == var { 168 if &*table.resolve_ty_shallow(var) == var {
169 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i))); 169 table.unify(
170 var,
171 &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)).intern(&Interner),
172 );
170 } 173 }
171 } 174 }
172 Some( 175 Some(
@@ -196,11 +199,12 @@ impl TypeVariableTable {
196 199
197 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty { 200 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
198 match kind { 201 match kind {
199 _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never, 202 _ if self.inner[iv.to_inner().0 as usize].diverging => TyKind::Never,
200 TyVariableKind::General => Ty::Unknown, 203 TyVariableKind::General => TyKind::Unknown,
201 TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)), 204 TyVariableKind::Integer => TyKind::Scalar(Scalar::Int(IntTy::I32)),
202 TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)), 205 TyVariableKind::Float => TyKind::Scalar(Scalar::Float(FloatTy::F64)),
203 } 206 }
207 .intern(&Interner)
204 } 208 }
205} 209}
206 210
@@ -227,7 +231,7 @@ impl InferenceTable {
227 self.type_variable_table.push(TypeVariableData { diverging }); 231 self.type_variable_table.push(TypeVariableData { diverging });
228 let key = self.var_unification_table.new_key(TypeVarValue::Unknown); 232 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
229 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1); 233 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
230 Ty::InferenceVar(InferenceVar::from_inner(key), kind) 234 TyKind::InferenceVar(InferenceVar::from_inner(key), kind).intern(&Interner)
231 } 235 }
232 236
233 pub(crate) fn new_type_var(&mut self) -> Ty { 237 pub(crate) fn new_type_var(&mut self) -> Ty {
@@ -290,12 +294,12 @@ impl InferenceTable {
290 } 294 }
291 295
292 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 296 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
293 match (ty1, ty2) { 297 match (ty1.interned(&Interner), ty2.interned(&Interner)) {
294 (Ty::Unknown, _) | (_, Ty::Unknown) => true, 298 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true,
295 299
296 (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, 300 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
297 301
298 (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 302 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => {
299 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 303 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) {
300 if !self.unify_preds(pred1, pred2, depth + 1) { 304 if !self.unify_preds(pred1, pred2, depth + 1) {
301 return false; 305 return false;
@@ -305,16 +309,16 @@ impl InferenceTable {
305 } 309 }
306 310
307 ( 311 (
308 Ty::InferenceVar(tv1, TyVariableKind::General), 312 TyKind::InferenceVar(tv1, TyVariableKind::General),
309 Ty::InferenceVar(tv2, TyVariableKind::General), 313 TyKind::InferenceVar(tv2, TyVariableKind::General),
310 ) 314 )
311 | ( 315 | (
312 Ty::InferenceVar(tv1, TyVariableKind::Integer), 316 TyKind::InferenceVar(tv1, TyVariableKind::Integer),
313 Ty::InferenceVar(tv2, TyVariableKind::Integer), 317 TyKind::InferenceVar(tv2, TyVariableKind::Integer),
314 ) 318 )
315 | ( 319 | (
316 Ty::InferenceVar(tv1, TyVariableKind::Float), 320 TyKind::InferenceVar(tv1, TyVariableKind::Float),
317 Ty::InferenceVar(tv2, TyVariableKind::Float), 321 TyKind::InferenceVar(tv2, TyVariableKind::Float),
318 ) if self.type_variable_table.is_diverging(*tv1) 322 ) if self.type_variable_table.is_diverging(*tv1)
319 == self.type_variable_table.is_diverging(*tv2) => 323 == self.type_variable_table.is_diverging(*tv2) =>
320 { 324 {
@@ -326,24 +330,37 @@ impl InferenceTable {
326 // The order of MaybeNeverTypeVar matters here. 330 // The order of MaybeNeverTypeVar matters here.
327 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 331 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
328 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 332 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
329 (Ty::InferenceVar(tv, TyVariableKind::General), other) 333 (TyKind::InferenceVar(tv, TyVariableKind::General), other)
330 | (other, Ty::InferenceVar(tv, TyVariableKind::General)) 334 | (other, TyKind::InferenceVar(tv, TyVariableKind::General))
331 | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_)))
332 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer))
333 | ( 335 | (
334 Ty::InferenceVar(tv, TyVariableKind::Integer), 336 TyKind::InferenceVar(tv, TyVariableKind::Integer),
335 other @ Ty::Scalar(Scalar::Uint(_)), 337 other @ TyKind::Scalar(Scalar::Int(_)),
336 ) 338 )
337 | ( 339 | (
338 other @ Ty::Scalar(Scalar::Uint(_)), 340 other @ TyKind::Scalar(Scalar::Int(_)),
339 Ty::InferenceVar(tv, TyVariableKind::Integer), 341 TyKind::InferenceVar(tv, TyVariableKind::Integer),
340 ) 342 )
341 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) 343 | (
342 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => 344 TyKind::InferenceVar(tv, TyVariableKind::Integer),
343 { 345 other @ TyKind::Scalar(Scalar::Uint(_)),
346 )
347 | (
348 other @ TyKind::Scalar(Scalar::Uint(_)),
349 TyKind::InferenceVar(tv, TyVariableKind::Integer),
350 )
351 | (
352 TyKind::InferenceVar(tv, TyVariableKind::Float),
353 other @ TyKind::Scalar(Scalar::Float(_)),
354 )
355 | (
356 other @ TyKind::Scalar(Scalar::Float(_)),
357 TyKind::InferenceVar(tv, TyVariableKind::Float),
358 ) => {
344 // the type var is unknown since we tried to resolve it 359 // the type var is unknown since we tried to resolve it
345 self.var_unification_table 360 self.var_unification_table.union_value(
346 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); 361 tv.to_inner(),
362 TypeVarValue::Known(other.clone().intern(&Interner)),
363 );
347 true 364 true
348 } 365 }
349 366
@@ -387,8 +404,8 @@ impl InferenceTable {
387 if i > 0 { 404 if i > 0 {
388 cov_mark::hit!(type_var_resolves_to_int_var); 405 cov_mark::hit!(type_var_resolves_to_int_var);
389 } 406 }
390 match &*ty { 407 match &ty.0 {
391 Ty::InferenceVar(tv, _) => { 408 TyKind::InferenceVar(tv, _) => {
392 let inner = tv.to_inner(); 409 let inner = tv.to_inner();
393 match self.var_unification_table.inlined_probe_value(inner).known() { 410 match self.var_unification_table.inlined_probe_value(inner).known() {
394 Some(known_ty) => { 411 Some(known_ty) => {
@@ -410,8 +427,8 @@ impl InferenceTable {
410 /// be resolved as far as possible, i.e. contain no type variables with 427 /// be resolved as far as possible, i.e. contain no type variables with
411 /// known type. 428 /// known type.
412 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 429 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
413 ty.fold(&mut |ty| match ty { 430 ty.fold(&mut |ty| match ty.interned(&Interner) {
414 Ty::InferenceVar(tv, kind) => { 431 &TyKind::InferenceVar(tv, kind) => {
415 let inner = tv.to_inner(); 432 let inner = tv.to_inner();
416 if tv_stack.contains(&inner) { 433 if tv_stack.contains(&inner) {
417 cov_mark::hit!(type_var_cycles_resolve_as_possible); 434 cov_mark::hit!(type_var_cycles_resolve_as_possible);
@@ -435,10 +452,10 @@ impl InferenceTable {
435 } 452 }
436 453
437 /// Resolves the type completely; type variables without known type are 454 /// Resolves the type completely; type variables without known type are
438 /// replaced by Ty::Unknown. 455 /// replaced by TyKind::Unknown.
439 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 456 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
440 ty.fold(&mut |ty| match ty { 457 ty.fold(&mut |ty| match ty.interned(&Interner) {
441 Ty::InferenceVar(tv, kind) => { 458 &TyKind::InferenceVar(tv, kind) => {
442 let inner = tv.to_inner(); 459 let inner = tv.to_inner();
443 if tv_stack.contains(&inner) { 460 if tv_stack.contains(&inner) {
444 cov_mark::hit!(type_var_cycles_resolve_completely); 461 cov_mark::hit!(type_var_cycles_resolve_completely);
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index e77f24e4e..2309db492 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -49,7 +49,7 @@ pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironmen
49 49
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; 50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
51 51
52pub(crate) use crate::traits::chalk::Interner; 52pub use crate::traits::chalk::Interner;
53 53
54#[derive(Clone, PartialEq, Eq, Debug, Hash)] 54#[derive(Clone, PartialEq, Eq, Debug, Hash)]
55pub enum Lifetime { 55pub enum Lifetime {
@@ -131,7 +131,7 @@ pub enum AliasTy {
131/// 131///
132/// This should be cheap to clone. 132/// This should be cheap to clone.
133#[derive(Clone, PartialEq, Eq, Debug, Hash)] 133#[derive(Clone, PartialEq, Eq, Debug, Hash)]
134pub enum Ty { 134pub enum TyKind {
135 /// Structures, enumerations and unions. 135 /// Structures, enumerations and unions.
136 Adt(AdtId<Interner>, Substs), 136 Adt(AdtId<Interner>, Substs),
137 137
@@ -244,6 +244,21 @@ pub enum Ty {
244 Unknown, 244 Unknown,
245} 245}
246 246
247#[derive(Clone, PartialEq, Eq, Debug, Hash)]
248pub struct Ty(TyKind);
249
250impl TyKind {
251 pub fn intern(self, _interner: &Interner) -> Ty {
252 Ty(self)
253 }
254}
255
256impl Ty {
257 pub fn interned(&self, _interner: &Interner) -> &TyKind {
258 &self.0
259 }
260}
261
247/// A list of substitutions for generic parameters. 262/// A list of substitutions for generic parameters.
248#[derive(Clone, PartialEq, Eq, Debug, Hash)] 263#[derive(Clone, PartialEq, Eq, Debug, Hash)]
249pub struct Substs(Arc<[Ty]>); 264pub struct Substs(Arc<[Ty]>);
@@ -292,7 +307,12 @@ impl Substs {
292 307
293 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 308 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
294 pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { 309 pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs {
295 Substs(generic_params.iter().map(|(id, _)| Ty::Placeholder(id)).collect()) 310 Substs(
311 generic_params
312 .iter()
313 .map(|(id, _)| TyKind::Placeholder(id).intern(&Interner))
314 .collect(),
315 )
296 } 316 }
297 317
298 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 318 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
@@ -307,7 +327,7 @@ impl Substs {
307 generic_params 327 generic_params
308 .iter() 328 .iter()
309 .enumerate() 329 .enumerate()
310 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) 330 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner))
311 .collect(), 331 .collect(),
312 ) 332 )
313 } 333 }
@@ -355,11 +375,14 @@ impl SubstsBuilder {
355 } 375 }
356 376
357 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 377 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
358 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx)))) 378 self.fill(
379 (starting_from..)
380 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
381 )
359 } 382 }
360 383
361 pub fn fill_with_unknown(self) -> Self { 384 pub fn fill_with_unknown(self) -> Self {
362 self.fill(iter::repeat(Ty::Unknown)) 385 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
363 } 386 }
364 387
365 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { 388 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
@@ -601,45 +624,52 @@ impl TypeWalk for CallableSig {
601 624
602impl Ty { 625impl Ty {
603 pub fn unit() -> Self { 626 pub fn unit() -> Self {
604 Ty::Tuple(0, Substs::empty()) 627 TyKind::Tuple(0, Substs::empty()).intern(&Interner)
605 } 628 }
606 629
607 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { 630 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty {
608 Ty::Adt(AdtId(adt), substs) 631 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
609 } 632 }
610 633
611 pub fn fn_ptr(sig: CallableSig) -> Self { 634 pub fn fn_ptr(sig: CallableSig) -> Self {
612 Ty::Function(FnPointer { 635 TyKind::Function(FnPointer {
613 num_args: sig.params().len(), 636 num_args: sig.params().len(),
614 sig: FnSig { variadic: sig.is_varargs }, 637 sig: FnSig { variadic: sig.is_varargs },
615 substs: Substs(sig.params_and_return), 638 substs: Substs(sig.params_and_return),
616 }) 639 })
640 .intern(&Interner)
617 } 641 }
618 642
619 pub fn builtin(builtin: BuiltinType) -> Self { 643 pub fn builtin(builtin: BuiltinType) -> Self {
620 match builtin { 644 match builtin {
621 BuiltinType::Char => Ty::Scalar(Scalar::Char), 645 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
622 BuiltinType::Bool => Ty::Scalar(Scalar::Bool), 646 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
623 BuiltinType::Str => Ty::Str, 647 BuiltinType::Str => TyKind::Str.intern(&Interner),
624 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), 648 BuiltinType::Int(t) => {
625 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), 649 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))).intern(&Interner)
626 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))), 650 }
651 BuiltinType::Uint(t) => {
652 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
653 }
654 BuiltinType::Float(t) => {
655 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
656 }
627 } 657 }
628 } 658 }
629 659
630 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 660 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
631 match self { 661 match self.interned(&Interner) {
632 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), 662 TyKind::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
633 _ => None, 663 _ => None,
634 } 664 }
635 } 665 }
636 666
637 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 667 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
638 match self { 668 match self.interned(&Interner) {
639 Ty::Ref(mutability, parameters) => { 669 TyKind::Ref(mutability, parameters) => {
640 Some((parameters.as_single(), Rawness::Ref, *mutability)) 670 Some((parameters.as_single(), Rawness::Ref, *mutability))
641 } 671 }
642 Ty::Raw(mutability, parameters) => { 672 TyKind::Raw(mutability, parameters) => {
643 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 673 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
644 } 674 }
645 _ => None, 675 _ => None,
@@ -649,7 +679,7 @@ impl Ty {
649 pub fn strip_references(&self) -> &Ty { 679 pub fn strip_references(&self) -> &Ty {
650 let mut t: &Ty = self; 680 let mut t: &Ty = self;
651 681
652 while let Ty::Ref(_mutability, parameters) = t { 682 while let TyKind::Ref(_mutability, parameters) = t.interned(&Interner) {
653 t = parameters.as_single(); 683 t = parameters.as_single();
654 } 684 }
655 685
@@ -657,65 +687,69 @@ impl Ty {
657 } 687 }
658 688
659 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { 689 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> {
660 match self { 690 match self.interned(&Interner) {
661 Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), 691 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
662 _ => None, 692 _ => None,
663 } 693 }
664 } 694 }
665 695
666 pub fn as_tuple(&self) -> Option<&Substs> { 696 pub fn as_tuple(&self) -> Option<&Substs> {
667 match self { 697 match self.interned(&Interner) {
668 Ty::Tuple(_, substs) => Some(substs), 698 TyKind::Tuple(_, substs) => Some(substs),
669 _ => None, 699 _ => None,
670 } 700 }
671 } 701 }
672 702
673 pub fn as_generic_def(&self) -> Option<GenericDefId> { 703 pub fn as_generic_def(&self) -> Option<GenericDefId> {
674 match *self { 704 match *self.interned(&Interner) {
675 Ty::Adt(AdtId(adt), ..) => Some(adt.into()), 705 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
676 Ty::FnDef(callable, ..) => Some(callable.into()), 706 TyKind::FnDef(callable, ..) => Some(callable.into()),
677 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), 707 TyKind::AssociatedType(type_alias, ..) => Some(type_alias.into()),
678 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), 708 TyKind::ForeignType(type_alias, ..) => Some(type_alias.into()),
679 _ => None, 709 _ => None,
680 } 710 }
681 } 711 }
682 712
683 pub fn is_never(&self) -> bool { 713 pub fn is_never(&self) -> bool {
684 matches!(self, Ty::Never) 714 matches!(self.interned(&Interner), TyKind::Never)
685 } 715 }
686 716
687 pub fn is_unknown(&self) -> bool { 717 pub fn is_unknown(&self) -> bool {
688 matches!(self, Ty::Unknown) 718 matches!(self.interned(&Interner), TyKind::Unknown)
689 } 719 }
690 720
691 pub fn equals_ctor(&self, other: &Ty) -> bool { 721 pub fn equals_ctor(&self, other: &Ty) -> bool {
692 match (self, other) { 722 match (self.interned(&Interner), other.interned(&Interner)) {
693 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, 723 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
694 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, 724 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
695 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, 725 (TyKind::FnDef(def_id, ..), TyKind::FnDef(def_id2, ..)) => def_id == def_id2,
696 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2, 726 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
697 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) 727 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..))
698 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, 728 | (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
699 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { 729 (TyKind::Closure(def, expr, _), TyKind::Closure(def2, expr2, _)) => {
700 expr == expr2 && def == def2 730 expr == expr2 && def == def2
701 } 731 }
702 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..)) 732 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
703 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2, 733 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
734 mutability == mutability2
735 }
704 ( 736 (
705 Ty::Function(FnPointer { num_args, sig, .. }), 737 TyKind::Function(FnPointer { num_args, sig, .. }),
706 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), 738 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
707 ) => num_args == num_args2 && sig == sig2, 739 ) => num_args == num_args2 && sig == sig2,
708 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, 740 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
709 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, 741 cardinality == cardinality2
710 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, 742 }
743 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
744 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
711 _ => false, 745 _ => false,
712 } 746 }
713 } 747 }
714 748
715 /// If this is a `dyn Trait` type, this returns the `Trait` part. 749 /// If this is a `dyn Trait` type, this returns the `Trait` part.
716 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 750 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
717 match self { 751 match self.interned(&Interner) {
718 Ty::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 752 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b {
719 GenericPredicate::Implemented(trait_ref) => Some(trait_ref), 753 GenericPredicate::Implemented(trait_ref) => Some(trait_ref),
720 _ => None, 754 _ => None,
721 }), 755 }),
@@ -729,28 +763,28 @@ impl Ty {
729 } 763 }
730 764
731 fn builtin_deref(&self) -> Option<Ty> { 765 fn builtin_deref(&self) -> Option<Ty> {
732 match self { 766 match self.interned(&Interner) {
733 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), 767 TyKind::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
734 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), 768 TyKind::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
735 _ => None, 769 _ => None,
736 } 770 }
737 } 771 }
738 772
739 pub fn as_fn_def(&self) -> Option<FunctionId> { 773 pub fn as_fn_def(&self) -> Option<FunctionId> {
740 match self { 774 match self.interned(&Interner) {
741 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), 775 &TyKind::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
742 _ => None, 776 _ => None,
743 } 777 }
744 } 778 }
745 779
746 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { 780 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
747 match self { 781 match self.interned(&Interner) {
748 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), 782 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
749 Ty::FnDef(def, parameters) => { 783 TyKind::FnDef(def, parameters) => {
750 let sig = db.callable_item_signature(*def); 784 let sig = db.callable_item_signature(*def);
751 Some(sig.subst(&parameters)) 785 Some(sig.subst(&parameters))
752 } 786 }
753 Ty::Closure(.., substs) => { 787 TyKind::Closure(.., substs) => {
754 let sig_param = &substs[0]; 788 let sig_param = &substs[0];
755 sig_param.callable_sig(db) 789 sig_param.callable_sig(db)
756 } 790 }
@@ -763,18 +797,18 @@ impl Ty {
763 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 797 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
764 /// `Option<u32>` afterwards.) 798 /// `Option<u32>` afterwards.)
765 pub fn apply_substs(mut self, new_substs: Substs) -> Ty { 799 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
766 match &mut self { 800 match &mut self.0 {
767 Ty::Adt(_, substs) 801 TyKind::Adt(_, substs)
768 | Ty::Slice(substs) 802 | TyKind::Slice(substs)
769 | Ty::Array(substs) 803 | TyKind::Array(substs)
770 | Ty::Raw(_, substs) 804 | TyKind::Raw(_, substs)
771 | Ty::Ref(_, substs) 805 | TyKind::Ref(_, substs)
772 | Ty::FnDef(_, substs) 806 | TyKind::FnDef(_, substs)
773 | Ty::Function(FnPointer { substs, .. }) 807 | TyKind::Function(FnPointer { substs, .. })
774 | Ty::Tuple(_, substs) 808 | TyKind::Tuple(_, substs)
775 | Ty::OpaqueType(_, substs) 809 | TyKind::OpaqueType(_, substs)
776 | Ty::AssociatedType(_, substs) 810 | TyKind::AssociatedType(_, substs)
777 | Ty::Closure(.., substs) => { 811 | TyKind::Closure(.., substs) => {
778 assert_eq!(substs.len(), new_substs.len()); 812 assert_eq!(substs.len(), new_substs.len());
779 *substs = new_substs; 813 *substs = new_substs;
780 } 814 }
@@ -786,42 +820,42 @@ impl Ty {
786 /// Returns the type parameters of this type if it has some (i.e. is an ADT 820 /// Returns the type parameters of this type if it has some (i.e. is an ADT
787 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 821 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
788 pub fn substs(&self) -> Option<&Substs> { 822 pub fn substs(&self) -> Option<&Substs> {
789 match self { 823 match self.interned(&Interner) {
790 Ty::Adt(_, substs) 824 TyKind::Adt(_, substs)
791 | Ty::Slice(substs) 825 | TyKind::Slice(substs)
792 | Ty::Array(substs) 826 | TyKind::Array(substs)
793 | Ty::Raw(_, substs) 827 | TyKind::Raw(_, substs)
794 | Ty::Ref(_, substs) 828 | TyKind::Ref(_, substs)
795 | Ty::FnDef(_, substs) 829 | TyKind::FnDef(_, substs)
796 | Ty::Function(FnPointer { substs, .. }) 830 | TyKind::Function(FnPointer { substs, .. })
797 | Ty::Tuple(_, substs) 831 | TyKind::Tuple(_, substs)
798 | Ty::OpaqueType(_, substs) 832 | TyKind::OpaqueType(_, substs)
799 | Ty::AssociatedType(_, substs) 833 | TyKind::AssociatedType(_, substs)
800 | Ty::Closure(.., substs) => Some(substs), 834 | TyKind::Closure(.., substs) => Some(substs),
801 _ => None, 835 _ => None,
802 } 836 }
803 } 837 }
804 838
805 pub fn substs_mut(&mut self) -> Option<&mut Substs> { 839 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
806 match self { 840 match &mut self.0 {
807 Ty::Adt(_, substs) 841 TyKind::Adt(_, substs)
808 | Ty::Slice(substs) 842 | TyKind::Slice(substs)
809 | Ty::Array(substs) 843 | TyKind::Array(substs)
810 | Ty::Raw(_, substs) 844 | TyKind::Raw(_, substs)
811 | Ty::Ref(_, substs) 845 | TyKind::Ref(_, substs)
812 | Ty::FnDef(_, substs) 846 | TyKind::FnDef(_, substs)
813 | Ty::Function(FnPointer { substs, .. }) 847 | TyKind::Function(FnPointer { substs, .. })
814 | Ty::Tuple(_, substs) 848 | TyKind::Tuple(_, substs)
815 | Ty::OpaqueType(_, substs) 849 | TyKind::OpaqueType(_, substs)
816 | Ty::AssociatedType(_, substs) 850 | TyKind::AssociatedType(_, substs)
817 | Ty::Closure(.., substs) => Some(substs), 851 | TyKind::Closure(.., substs) => Some(substs),
818 _ => None, 852 _ => None,
819 } 853 }
820 } 854 }
821 855
822 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 856 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
823 match self { 857 match self.interned(&Interner) {
824 Ty::OpaqueType(opaque_ty_id, ..) => { 858 TyKind::OpaqueType(opaque_ty_id, ..) => {
825 match opaque_ty_id { 859 match opaque_ty_id {
826 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 860 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
827 let krate = def.module(db.upcast()).krate(); 861 let krate = def.module(db.upcast()).krate();
@@ -844,7 +878,7 @@ impl Ty {
844 OpaqueTyId::ReturnTypeImplTrait(..) => None, 878 OpaqueTyId::ReturnTypeImplTrait(..) => None,
845 } 879 }
846 } 880 }
847 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 881 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
848 let predicates = match opaque_ty.opaque_ty_id { 882 let predicates = match opaque_ty.opaque_ty_id {
849 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 883 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
850 db.return_type_impl_traits(func).map(|it| { 884 db.return_type_impl_traits(func).map(|it| {
@@ -860,7 +894,7 @@ impl Ty {
860 894
861 predicates.map(|it| it.value) 895 predicates.map(|it| it.value)
862 } 896 }
863 Ty::Placeholder(id) => { 897 TyKind::Placeholder(id) => {
864 let generic_params = db.generic_params(id.parent); 898 let generic_params = db.generic_params(id.parent);
865 let param_data = &generic_params.types[id.local_id]; 899 let param_data = &generic_params.types[id.local_id];
866 match param_data.provenance { 900 match param_data.provenance {
@@ -881,14 +915,14 @@ impl Ty {
881 } 915 }
882 916
883 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 917 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
884 match self { 918 match self.interned(&Interner) {
885 Ty::AssociatedType(type_alias_id, ..) => { 919 TyKind::AssociatedType(type_alias_id, ..) => {
886 match type_alias_id.lookup(db.upcast()).container { 920 match type_alias_id.lookup(db.upcast()).container {
887 AssocContainerId::TraitId(trait_id) => Some(trait_id), 921 AssocContainerId::TraitId(trait_id) => Some(trait_id),
888 _ => None, 922 _ => None,
889 } 923 }
890 } 924 }
891 Ty::Alias(AliasTy::Projection(projection_ty)) => { 925 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
892 match projection_ty.associated_ty.lookup(db.upcast()).container { 926 match projection_ty.associated_ty.lookup(db.upcast()).container {
893 AssocContainerId::TraitId(trait_id) => Some(trait_id), 927 AssocContainerId::TraitId(trait_id) => Some(trait_id),
894 _ => None, 928 _ => None,
@@ -908,13 +942,13 @@ pub trait TypeWalk {
908 } 942 }
909 /// Walk the type, counting entered binders. 943 /// Walk the type, counting entered binders.
910 /// 944 ///
911 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers 945 /// `TyKind::Bound` variables use DeBruijn indexing, which means that 0 refers
912 /// to the innermost binder, 1 to the next, etc.. So when we want to 946 /// to the innermost binder, 1 to the next, etc.. So when we want to
913 /// substitute a certain bound variable, we can't just walk the whole type 947 /// substitute a certain bound variable, we can't just walk the whole type
914 /// and blindly replace each instance of a certain index; when we 'enter' 948 /// and blindly replace each instance of a certain index; when we 'enter'
915 /// things that introduce new bound variables, we have to keep track of 949 /// things that introduce new bound variables, we have to keep track of
916 /// that. Currently, the only thing that introduces bound variables on our 950 /// that. Currently, the only thing that introduces bound variables on our
917 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound 951 /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound
918 /// variable for the self type. 952 /// variable for the self type.
919 fn walk_mut_binders( 953 fn walk_mut_binders(
920 &mut self, 954 &mut self,
@@ -932,7 +966,7 @@ pub trait TypeWalk {
932 { 966 {
933 self.walk_mut_binders( 967 self.walk_mut_binders(
934 &mut |ty_mut, binders| { 968 &mut |ty_mut, binders| {
935 let ty = mem::replace(ty_mut, Ty::Unknown); 969 let ty = mem::replace(ty_mut, Ty(TyKind::Unknown));
936 *ty_mut = f(ty, binders); 970 *ty_mut = f(ty, binders);
937 }, 971 },
938 binders, 972 binders,
@@ -945,13 +979,13 @@ pub trait TypeWalk {
945 Self: Sized, 979 Self: Sized,
946 { 980 {
947 self.walk_mut(&mut |ty_mut| { 981 self.walk_mut(&mut |ty_mut| {
948 let ty = mem::replace(ty_mut, Ty::Unknown); 982 let ty = mem::replace(ty_mut, Ty(TyKind::Unknown));
949 *ty_mut = f(ty); 983 *ty_mut = f(ty);
950 }); 984 });
951 self 985 self
952 } 986 }
953 987
954 /// Substitutes `Ty::Bound` vars with the given substitution. 988 /// Substitutes `TyKind::Bound` vars with the given substitution.
955 fn subst_bound_vars(self, substs: &Substs) -> Self 989 fn subst_bound_vars(self, substs: &Substs) -> Self
956 where 990 where
957 Self: Sized, 991 Self: Sized,
@@ -959,14 +993,14 @@ pub trait TypeWalk {
959 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) 993 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST)
960 } 994 }
961 995
962 /// Substitutes `Ty::Bound` vars with the given substitution. 996 /// Substitutes `TyKind::Bound` vars with the given substitution.
963 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self 997 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self
964 where 998 where
965 Self: Sized, 999 Self: Sized,
966 { 1000 {
967 self.walk_mut_binders( 1001 self.walk_mut_binders(
968 &mut |ty, binders| { 1002 &mut |ty, binders| {
969 if let &mut Ty::BoundVar(bound) = ty { 1003 if let &mut TyKind::BoundVar(bound) = &mut ty.0 {
970 if bound.debruijn >= binders { 1004 if bound.debruijn >= binders {
971 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1005 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
972 } 1006 }
@@ -977,17 +1011,17 @@ pub trait TypeWalk {
977 self 1011 self
978 } 1012 }
979 1013
980 /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. 1014 /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
981 fn shift_bound_vars(self, n: DebruijnIndex) -> Self 1015 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
982 where 1016 where
983 Self: Sized, 1017 Self: Sized,
984 { 1018 {
985 self.fold_binders( 1019 self.fold_binders(
986 &mut |ty, binders| match ty { 1020 &mut |ty, binders| match &ty.0 {
987 Ty::BoundVar(bound) if bound.debruijn >= binders => { 1021 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
988 Ty::BoundVar(bound.shifted_in_from(n)) 1022 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
989 } 1023 }
990 ty => ty, 1024 _ => ty,
991 }, 1025 },
992 DebruijnIndex::INNERMOST, 1026 DebruijnIndex::INNERMOST,
993 ) 1027 )
@@ -996,18 +1030,18 @@ pub trait TypeWalk {
996 1030
997impl TypeWalk for Ty { 1031impl TypeWalk for Ty {
998 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1032 fn walk(&self, f: &mut impl FnMut(&Ty)) {
999 match self { 1033 match self.interned(&Interner) {
1000 Ty::Alias(AliasTy::Projection(p_ty)) => { 1034 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1001 for t in p_ty.parameters.iter() { 1035 for t in p_ty.parameters.iter() {
1002 t.walk(f); 1036 t.walk(f);
1003 } 1037 }
1004 } 1038 }
1005 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1039 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1006 for t in o_ty.parameters.iter() { 1040 for t in o_ty.parameters.iter() {
1007 t.walk(f); 1041 t.walk(f);
1008 } 1042 }
1009 } 1043 }
1010 Ty::Dyn(predicates) => { 1044 TyKind::Dyn(predicates) => {
1011 for p in predicates.iter() { 1045 for p in predicates.iter() {
1012 p.walk(f); 1046 p.walk(f);
1013 } 1047 }
@@ -1028,16 +1062,16 @@ impl TypeWalk for Ty {
1028 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 1062 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1029 binders: DebruijnIndex, 1063 binders: DebruijnIndex,
1030 ) { 1064 ) {
1031 match self { 1065 match &mut self.0 {
1032 Ty::Alias(AliasTy::Projection(p_ty)) => { 1066 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1033 p_ty.parameters.walk_mut_binders(f, binders); 1067 p_ty.parameters.walk_mut_binders(f, binders);
1034 } 1068 }
1035 Ty::Dyn(predicates) => { 1069 TyKind::Dyn(predicates) => {
1036 for p in make_mut_slice(predicates) { 1070 for p in make_mut_slice(predicates) {
1037 p.walk_mut_binders(f, binders.shifted_in()); 1071 p.walk_mut_binders(f, binders.shifted_in());
1038 } 1072 }
1039 } 1073 }
1040 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1074 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1041 o_ty.parameters.walk_mut_binders(f, binders); 1075 o_ty.parameters.walk_mut_binders(f, binders);
1042 } 1076 }
1043 _ => { 1077 _ => {
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index d84ec9b7a..9fe7e3dce 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -34,7 +34,7 @@ use crate::{
34 }, 34 },
35 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, 35 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
36 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, 36 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
37 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 37 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
38}; 38};
39 39
40#[derive(Debug)] 40#[derive(Debug)]
@@ -146,10 +146,10 @@ impl Ty {
146 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { 146 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) {
147 let mut res = None; 147 let mut res = None;
148 let ty = match type_ref { 148 let ty = match type_ref {
149 TypeRef::Never => Ty::Never, 149 TypeRef::Never => TyKind::Never.intern(&Interner),
150 TypeRef::Tuple(inner) => { 150 TypeRef::Tuple(inner) => {
151 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); 151 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect();
152 Ty::Tuple(inner_tys.len(), Substs(inner_tys)) 152 TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner)
153 } 153 }
154 TypeRef::Path(path) => { 154 TypeRef::Path(path) => {
155 let (ty, res_) = Ty::from_hir_path(ctx, path); 155 let (ty, res_) = Ty::from_hir_path(ctx, path);
@@ -158,38 +158,42 @@ impl Ty {
158 } 158 }
159 TypeRef::RawPtr(inner, mutability) => { 159 TypeRef::RawPtr(inner, mutability) => {
160 let inner_ty = Ty::from_hir(ctx, inner); 160 let inner_ty = Ty::from_hir(ctx, inner);
161 Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 161 TyKind::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
162 .intern(&Interner)
162 } 163 }
163 TypeRef::Array(inner) => { 164 TypeRef::Array(inner) => {
164 let inner_ty = Ty::from_hir(ctx, inner); 165 let inner_ty = Ty::from_hir(ctx, inner);
165 Ty::Array(Substs::single(inner_ty)) 166 TyKind::Array(Substs::single(inner_ty)).intern(&Interner)
166 } 167 }
167 TypeRef::Slice(inner) => { 168 TypeRef::Slice(inner) => {
168 let inner_ty = Ty::from_hir(ctx, inner); 169 let inner_ty = Ty::from_hir(ctx, inner);
169 Ty::Slice(Substs::single(inner_ty)) 170 TyKind::Slice(Substs::single(inner_ty)).intern(&Interner)
170 } 171 }
171 TypeRef::Reference(inner, _, mutability) => { 172 TypeRef::Reference(inner, _, mutability) => {
172 let inner_ty = Ty::from_hir(ctx, inner); 173 let inner_ty = Ty::from_hir(ctx, inner);
173 Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 174 TyKind::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
175 .intern(&Interner)
174 } 176 }
175 TypeRef::Placeholder => Ty::Unknown, 177 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
176 TypeRef::Fn(params, is_varargs) => { 178 TypeRef::Fn(params, is_varargs) => {
177 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 179 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
178 Ty::Function(FnPointer { 180 TyKind::Function(FnPointer {
179 num_args: substs.len() - 1, 181 num_args: substs.len() - 1,
180 sig: FnSig { variadic: *is_varargs }, 182 sig: FnSig { variadic: *is_varargs },
181 substs, 183 substs,
182 }) 184 })
185 .intern(&Interner)
183 } 186 }
184 TypeRef::DynTrait(bounds) => { 187 TypeRef::DynTrait(bounds) => {
185 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 188 let self_ty =
189 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
186 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 190 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
187 bounds 191 bounds
188 .iter() 192 .iter()
189 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone())) 193 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
190 .collect() 194 .collect()
191 }); 195 });
192 Ty::Dyn(predicates) 196 TyKind::Dyn(predicates).intern(&Interner)
193 } 197 }
194 TypeRef::ImplTrait(bounds) => { 198 TypeRef::ImplTrait(bounds) => {
195 match ctx.impl_trait_mode { 199 match ctx.impl_trait_mode {
@@ -226,10 +230,11 @@ impl Ty {
226 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); 230 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
227 let generics = generics(ctx.db.upcast(), func.into()); 231 let generics = generics(ctx.db.upcast(), func.into());
228 let parameters = Substs::bound_vars(&generics, ctx.in_binders); 232 let parameters = Substs::bound_vars(&generics, ctx.in_binders);
229 Ty::Alias(AliasTy::Opaque(OpaqueTy { 233 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
230 opaque_ty_id: impl_trait_id, 234 opaque_ty_id: impl_trait_id,
231 parameters, 235 parameters,
232 })) 236 }))
237 .intern(&Interner)
233 } 238 }
234 ImplTraitLoweringMode::Param => { 239 ImplTraitLoweringMode::Param => {
235 let idx = ctx.impl_trait_counter.get(); 240 let idx = ctx.impl_trait_counter.get();
@@ -243,10 +248,10 @@ impl Ty {
243 data.provenance == TypeParamProvenance::ArgumentImplTrait 248 data.provenance == TypeParamProvenance::ArgumentImplTrait
244 }) 249 })
245 .nth(idx as usize) 250 .nth(idx as usize)
246 .map_or(Ty::Unknown, |(id, _)| Ty::Placeholder(id)); 251 .map_or(TyKind::Unknown, |(id, _)| TyKind::Placeholder(id));
247 param 252 param.intern(&Interner)
248 } else { 253 } else {
249 Ty::Unknown 254 TyKind::Unknown.intern(&Interner)
250 } 255 }
251 } 256 }
252 ImplTraitLoweringMode::Variable => { 257 ImplTraitLoweringMode::Variable => {
@@ -260,18 +265,19 @@ impl Ty {
260 } else { 265 } else {
261 (0, 0, 0, 0) 266 (0, 0, 0, 0)
262 }; 267 };
263 Ty::BoundVar(BoundVar::new( 268 TyKind::BoundVar(BoundVar::new(
264 ctx.in_binders, 269 ctx.in_binders,
265 idx as usize + parent_params + self_params + list_params, 270 idx as usize + parent_params + self_params + list_params,
266 )) 271 ))
272 .intern(&Interner)
267 } 273 }
268 ImplTraitLoweringMode::Disallowed => { 274 ImplTraitLoweringMode::Disallowed => {
269 // FIXME: report error 275 // FIXME: report error
270 Ty::Unknown 276 TyKind::Unknown.intern(&Interner)
271 } 277 }
272 } 278 }
273 } 279 }
274 TypeRef::Error => Ty::Unknown, 280 TypeRef::Error => TyKind::Unknown.intern(&Interner),
275 }; 281 };
276 (ty, res) 282 (ty, res)
277 } 283 }
@@ -315,7 +321,7 @@ impl Ty {
315 (Ty::select_associated_type(ctx, res, segment), None) 321 (Ty::select_associated_type(ctx, res, segment), None)
316 } else if remaining_segments.len() > 1 { 322 } else if remaining_segments.len() > 1 {
317 // FIXME report error (ambiguous associated type) 323 // FIXME report error (ambiguous associated type)
318 (Ty::Unknown, None) 324 (TyKind::Unknown.intern(&Interner), None)
319 } else { 325 } else {
320 (ty, res) 326 (ty, res)
321 } 327 }
@@ -332,7 +338,10 @@ impl Ty {
332 TypeNs::TraitId(trait_) => { 338 TypeNs::TraitId(trait_) => {
333 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 339 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
334 let self_ty = if remaining_segments.len() == 0 { 340 let self_ty = if remaining_segments.len() == 0 {
335 Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))) 341 Some(
342 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
343 .intern(&Interner),
344 )
336 } else { 345 } else {
337 None 346 None
338 }; 347 };
@@ -348,21 +357,23 @@ impl Ty {
348 match found { 357 match found {
349 Some((super_trait_ref, associated_ty)) => { 358 Some((super_trait_ref, associated_ty)) => {
350 // FIXME handle type parameters on the segment 359 // FIXME handle type parameters on the segment
351 Ty::Alias(AliasTy::Projection(ProjectionTy { 360 TyKind::Alias(AliasTy::Projection(ProjectionTy {
352 associated_ty, 361 associated_ty,
353 parameters: super_trait_ref.substs, 362 parameters: super_trait_ref.substs,
354 })) 363 }))
364 .intern(&Interner)
355 } 365 }
356 None => { 366 None => {
357 // FIXME: report error (associated type not found) 367 // FIXME: report error (associated type not found)
358 Ty::Unknown 368 TyKind::Unknown.intern(&Interner)
359 } 369 }
360 } 370 }
361 } else if remaining_segments.len() > 1 { 371 } else if remaining_segments.len() > 1 {
362 // FIXME report error (ambiguous associated type) 372 // FIXME report error (ambiguous associated type)
363 Ty::Unknown 373 TyKind::Unknown.intern(&Interner)
364 } else { 374 } else {
365 Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) 375 TyKind::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)]))
376 .intern(&Interner)
366 }; 377 };
367 return (ty, None); 378 return (ty, None);
368 } 379 }
@@ -372,12 +383,13 @@ impl Ty {
372 ctx.resolver.generic_def().expect("generics in scope"), 383 ctx.resolver.generic_def().expect("generics in scope"),
373 ); 384 );
374 match ctx.type_param_mode { 385 match ctx.type_param_mode {
375 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 386 TypeParamLoweringMode::Placeholder => TyKind::Placeholder(param_id),
376 TypeParamLoweringMode::Variable => { 387 TypeParamLoweringMode::Variable => {
377 let idx = generics.param_idx(param_id).expect("matching generics"); 388 let idx = generics.param_idx(param_id).expect("matching generics");
378 Ty::BoundVar(BoundVar::new(ctx.in_binders, idx)) 389 TyKind::BoundVar(BoundVar::new(ctx.in_binders, idx))
379 } 390 }
380 } 391 }
392 .intern(&Interner)
381 } 393 }
382 TypeNs::SelfType(impl_id) => { 394 TypeNs::SelfType(impl_id) => {
383 let generics = generics(ctx.db.upcast(), impl_id.into()); 395 let generics = generics(ctx.db.upcast(), impl_id.into());
@@ -414,7 +426,7 @@ impl Ty {
414 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) 426 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
415 } 427 }
416 // FIXME: report error 428 // FIXME: report error
417 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 429 TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None),
418 }; 430 };
419 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 431 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments)
420 } 432 }
@@ -428,7 +440,7 @@ impl Ty {
428 let (resolution, remaining_index) = 440 let (resolution, remaining_index) =
429 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { 441 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) {
430 Some(it) => it, 442 Some(it) => it,
431 None => return (Ty::Unknown, None), 443 None => return (TyKind::Unknown.intern(&Interner), None),
432 }; 444 };
433 let (resolved_segment, remaining_segments) = match remaining_index { 445 let (resolved_segment, remaining_segments) = match remaining_index {
434 None => ( 446 None => (
@@ -473,18 +485,21 @@ impl Ty {
473 // associated_type_shorthand_candidates does not do that 485 // associated_type_shorthand_candidates does not do that
474 let substs = substs.shift_bound_vars(ctx.in_binders); 486 let substs = substs.shift_bound_vars(ctx.in_binders);
475 // FIXME handle type parameters on the segment 487 // FIXME handle type parameters on the segment
476 return Some(Ty::Alias(AliasTy::Projection(ProjectionTy { 488 return Some(
477 associated_ty, 489 TyKind::Alias(AliasTy::Projection(ProjectionTy {
478 parameters: substs, 490 associated_ty,
479 }))); 491 parameters: substs,
492 }))
493 .intern(&Interner),
494 );
480 } 495 }
481 496
482 None 497 None
483 }); 498 });
484 499
485 ty.unwrap_or(Ty::Unknown) 500 ty.unwrap_or(TyKind::Unknown.intern(&Interner))
486 } else { 501 } else {
487 Ty::Unknown 502 TyKind::Unknown.intern(&Interner)
488 } 503 }
489 } 504 }
490 505
@@ -553,13 +568,13 @@ fn substs_from_path_segment(
553 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 568 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split());
554 let total_len = parent_params + self_params + type_params + impl_trait_params; 569 let total_len = parent_params + self_params + type_params + impl_trait_params;
555 570
556 substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); 571 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
557 572
558 let mut had_explicit_type_args = false; 573 let mut had_explicit_type_args = false;
559 574
560 if let Some(generic_args) = &segment.args_and_bindings { 575 if let Some(generic_args) = &segment.args_and_bindings {
561 if !generic_args.has_self_type { 576 if !generic_args.has_self_type {
562 substs.extend(iter::repeat(Ty::Unknown).take(self_params)); 577 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
563 } 578 }
564 let expected_num = 579 let expected_num =
565 if generic_args.has_self_type { self_params + type_params } else { type_params }; 580 if generic_args.has_self_type { self_params + type_params } else { type_params };
@@ -602,7 +617,7 @@ fn substs_from_path_segment(
602 // add placeholders for args that were not provided 617 // add placeholders for args that were not provided
603 // FIXME: emit diagnostics in contexts where this is not allowed 618 // FIXME: emit diagnostics in contexts where this is not allowed
604 for _ in substs.len()..total_len { 619 for _ in substs.len()..total_len {
605 substs.push(Ty::Unknown); 620 substs.push(TyKind::Unknown.intern(&Interner));
606 } 621 }
607 assert_eq!(substs.len(), total_len); 622 assert_eq!(substs.len(), total_len);
608 623
@@ -674,12 +689,13 @@ impl GenericPredicate {
674 let param_id = 689 let param_id =
675 hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; 690 hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
676 match ctx.type_param_mode { 691 match ctx.type_param_mode {
677 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 692 TypeParamLoweringMode::Placeholder => TyKind::Placeholder(param_id),
678 TypeParamLoweringMode::Variable => { 693 TypeParamLoweringMode::Variable => {
679 let idx = generics.param_idx(param_id).expect("matching generics"); 694 let idx = generics.param_idx(param_id).expect("matching generics");
680 Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) 695 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
681 } 696 }
682 } 697 }
698 .intern(&Interner)
683 } 699 }
684 }; 700 };
685 GenericPredicate::from_type_bound(ctx, bound, self_ty) 701 GenericPredicate::from_type_bound(ctx, bound, self_ty)
@@ -751,7 +767,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
751 preds.extend(GenericPredicate::from_type_bound( 767 preds.extend(GenericPredicate::from_type_bound(
752 ctx, 768 ctx,
753 bound, 769 bound,
754 Ty::Alias(AliasTy::Projection(projection_ty.clone())), 770 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
755 )); 771 ));
756 } 772 }
757 preds 773 preds
@@ -761,7 +777,8 @@ fn assoc_type_bindings_from_type_bound<'a>(
761impl ReturnTypeImplTrait { 777impl ReturnTypeImplTrait {
762 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { 778 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
763 cov_mark::hit!(lower_rpit); 779 cov_mark::hit!(lower_rpit);
764 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 780 let self_ty =
781 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
765 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 782 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
766 bounds 783 bounds
767 .iter() 784 .iter()
@@ -994,17 +1011,20 @@ pub(crate) fn generic_defaults_query(
994 .iter() 1011 .iter()
995 .enumerate() 1012 .enumerate()
996 .map(|(idx, (_, p))| { 1013 .map(|(idx, (_, p))| {
997 let mut ty = p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)); 1014 let mut ty = p
1015 .default
1016 .as_ref()
1017 .map_or(TyKind::Unknown.intern(&Interner), |t| Ty::from_hir(&ctx, t));
998 1018
999 // Each default can only refer to previous parameters. 1019 // Each default can only refer to previous parameters.
1000 ty.walk_mut_binders( 1020 ty.walk_mut_binders(
1001 &mut |ty, binders| match ty { 1021 &mut |ty, binders| match &mut ty.0 {
1002 Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 1022 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => {
1003 if *index >= idx { 1023 if *index >= idx {
1004 // type variable default referring to parameter coming 1024 // type variable default referring to parameter coming
1005 // after it. This is forbidden (FIXME: report 1025 // after it. This is forbidden (FIXME: report
1006 // diagnostic) 1026 // diagnostic)
1007 *ty = Ty::Unknown; 1027 *ty = TyKind::Unknown.intern(&Interner);
1008 } 1028 }
1009 } 1029 }
1010 _ => {} 1030 _ => {}
@@ -1040,7 +1060,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1040fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1060fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1041 let generics = generics(db.upcast(), def.into()); 1061 let generics = generics(db.upcast(), def.into());
1042 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1062 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1043 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1063 Binders::new(substs.len(), TyKind::FnDef(def.into(), substs).intern(&Interner))
1044} 1064}
1045 1065
1046/// Build the declared type of a const. 1066/// Build the declared type of a const.
@@ -1083,7 +1103,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1083 } 1103 }
1084 let generics = generics(db.upcast(), def.into()); 1104 let generics = generics(db.upcast(), def.into());
1085 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1105 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1086 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1106 Binders::new(substs.len(), TyKind::FnDef(def.into(), substs).intern(&Interner))
1087} 1107}
1088 1108
1089fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1109fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1108,7 +1128,7 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1108 } 1128 }
1109 let generics = generics(db.upcast(), def.parent.into()); 1129 let generics = generics(db.upcast(), def.parent.into());
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1130 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1111 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1131 Binders::new(substs.len(), TyKind::FnDef(def.into(), substs).intern(&Interner))
1112} 1132}
1113 1133
1114fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1134fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@@ -1123,7 +1143,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1123 let ctx = 1143 let ctx =
1124 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1144 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1125 if db.type_alias_data(t).is_extern { 1145 if db.type_alias_data(t).is_extern {
1126 Binders::new(0, Ty::ForeignType(t)) 1146 Binders::new(0, TyKind::ForeignType(t).intern(&Interner))
1127 } else { 1147 } else {
1128 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1148 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1129 let type_ref = &db.type_alias_data(t).type_ref; 1149 let type_ref = &db.type_alias_data(t).type_ref;
@@ -1199,7 +1219,7 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId)
1199 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), 1219 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(),
1200 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), 1220 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(),
1201 }; 1221 };
1202 Binders::new(num_binders, Ty::Unknown) 1222 Binders::new(num_binders, TyKind::Unknown.intern(&Interner))
1203} 1223}
1204 1224
1205pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1225pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
@@ -1237,7 +1257,7 @@ pub(crate) fn impl_self_ty_recover(
1237 impl_id: &ImplId, 1257 impl_id: &ImplId,
1238) -> Binders<Ty> { 1258) -> Binders<Ty> {
1239 let generics = generics(db.upcast(), (*impl_id).into()); 1259 let generics = generics(db.upcast(), (*impl_id).into());
1240 Binders::new(generics.len(), Ty::Unknown) 1260 Binders::new(generics.len(), TyKind::Unknown.intern(&Interner))
1241} 1261}
1242 1262
1243pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1263pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index d57c6de70..f9877e760 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -19,8 +19,8 @@ use crate::{
19 db::HirDatabase, 19 db::HirDatabase,
20 primitive::{self, FloatTy, IntTy, UintTy}, 20 primitive::{self, FloatTy, IntTy, UintTy},
21 utils::all_super_traits, 21 utils::all_super_traits,
22 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, 22 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Interner, Scalar, Substs,
23 TraitEnvironment, TraitRef, Ty, TypeWalk, 23 TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
24}; 24};
25 25
26/// This is used as a key for indexing impls. 26/// This is used as a key for indexing impls.
@@ -44,18 +44,20 @@ impl TyFingerprint {
44 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 44 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
45 /// `impl &S`. Hence, this will return `None` for reference types and such. 45 /// `impl &S`. Hence, this will return `None` for reference types and such.
46 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 46 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
47 let fp = match ty { 47 let fp = match *ty.interned(&Interner) {
48 &Ty::Str => TyFingerprint::Str, 48 TyKind::Str => TyFingerprint::Str,
49 &Ty::Never => TyFingerprint::Never, 49 TyKind::Never => TyFingerprint::Never,
50 &Ty::Slice(..) => TyFingerprint::Slice, 50 TyKind::Slice(..) => TyFingerprint::Slice,
51 &Ty::Array(..) => TyFingerprint::Array, 51 TyKind::Array(..) => TyFingerprint::Array,
52 &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), 52 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar),
53 &Ty::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 53 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt),
54 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 54 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
55 &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 55 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability),
56 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), 56 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
57 &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), 57 TyKind::Function(FnPointer { num_args, sig, .. }) => {
58 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 58 TyFingerprint::FnPtr(num_args, sig)
59 }
60 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
59 _ => return None, 61 _ => return None,
60 }; 62 };
61 Some(fp) 63 Some(fp)
@@ -230,31 +232,31 @@ impl Ty {
230 232
231 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 233 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
232 234
233 let lang_item_targets = match self { 235 let lang_item_targets = match self.interned(&Interner) {
234 Ty::Adt(AdtId(def_id), _) => { 236 TyKind::Adt(AdtId(def_id), _) => {
235 return mod_to_crate_ids(def_id.module(db.upcast())); 237 return mod_to_crate_ids(def_id.module(db.upcast()));
236 } 238 }
237 Ty::ForeignType(type_alias_id) => { 239 TyKind::ForeignType(type_alias_id) => {
238 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 240 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
239 } 241 }
240 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 242 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
241 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), 243 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
242 Ty::Scalar(Scalar::Float(f)) => match f { 244 TyKind::Scalar(Scalar::Float(f)) => match f {
243 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 245 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
244 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 246 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
245 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 247 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
246 }, 248 },
247 &Ty::Scalar(Scalar::Int(t)) => { 249 &TyKind::Scalar(Scalar::Int(t)) => {
248 lang_item_crate!(primitive::int_ty_to_string(t)) 250 lang_item_crate!(primitive::int_ty_to_string(t))
249 } 251 }
250 &Ty::Scalar(Scalar::Uint(t)) => { 252 &TyKind::Scalar(Scalar::Uint(t)) => {
251 lang_item_crate!(primitive::uint_ty_to_string(t)) 253 lang_item_crate!(primitive::uint_ty_to_string(t))
252 } 254 }
253 Ty::Str => lang_item_crate!("str_alloc", "str"), 255 TyKind::Str => lang_item_crate!("str_alloc", "str"),
254 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 256 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
255 Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 257 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
256 Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 258 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
257 Ty::Dyn(_) => { 259 TyKind::Dyn(_) => {
258 return self.dyn_trait().and_then(|trait_| { 260 return self.dyn_trait().and_then(|trait_| {
259 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 261 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
260 }); 262 });
@@ -430,7 +432,8 @@ fn iterate_method_candidates_with_autoref(
430 } 432 }
431 let refed = Canonical { 433 let refed = Canonical {
432 kinds: deref_chain[0].kinds.clone(), 434 kinds: deref_chain[0].kinds.clone(),
433 value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), 435 value: TyKind::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone()))
436 .intern(&Interner),
434 }; 437 };
435 if iterate_method_candidates_by_receiver( 438 if iterate_method_candidates_by_receiver(
436 &refed, 439 &refed,
@@ -446,7 +449,8 @@ fn iterate_method_candidates_with_autoref(
446 } 449 }
447 let ref_muted = Canonical { 450 let ref_muted = Canonical {
448 kinds: deref_chain[0].kinds.clone(), 451 kinds: deref_chain[0].kinds.clone(),
449 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), 452 value: TyKind::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone()))
453 .intern(&Interner),
450 }; 454 };
451 if iterate_method_candidates_by_receiver( 455 if iterate_method_candidates_by_receiver(
452 &ref_muted, 456 &ref_muted,
@@ -526,7 +530,7 @@ fn iterate_trait_method_candidates(
526 // if ty is `dyn Trait`, the trait doesn't need to be in scope 530 // if ty is `dyn Trait`, the trait doesn't need to be in scope
527 let inherent_trait = 531 let inherent_trait =
528 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 532 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t));
529 let env_traits = if let Ty::Placeholder(_) = self_ty.value { 533 let env_traits = if let TyKind::Placeholder(_) = self_ty.value.interned(&Interner) {
530 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope 534 // if we have `T: Trait` in the param env, the trait doesn't need to be in scope
531 env.traits_in_scope_from_clauses(&self_ty.value) 535 env.traits_in_scope_from_clauses(&self_ty.value)
532 .flat_map(|t| all_super_traits(db.upcast(), t)) 536 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -679,13 +683,13 @@ pub(crate) fn inherent_impl_substs(
679} 683}
680 684
681/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 685/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
682/// num_vars_to_keep) by `Ty::Unknown`. 686/// num_vars_to_keep) by `TyKind::Unknown`.
683fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 687fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
684 s.fold_binders( 688 s.fold_binders(
685 &mut |ty, binders| { 689 &mut |ty, binders| {
686 if let Ty::BoundVar(bound) = &ty { 690 if let TyKind::BoundVar(bound) = ty.interned(&Interner) {
687 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 691 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
688 Ty::Unknown 692 TyKind::Unknown.intern(&Interner)
689 } else { 693 } else {
690 ty 694 ty
691 } 695 }
@@ -772,9 +776,11 @@ fn autoderef_method_receiver(
772) -> Vec<Canonical<Ty>> { 776) -> Vec<Canonical<Ty>> {
773 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 777 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
774 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 778 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
775 if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) { 779 if let Some(TyKind::Array(parameters)) =
780 deref_chain.last().map(|ty| ty.value.interned(&Interner))
781 {
776 let kinds = deref_chain.last().unwrap().kinds.clone(); 782 let kinds = deref_chain.last().unwrap().kinds.clone();
777 let unsized_ty = Ty::Slice(parameters.clone()); 783 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
778 deref_chain.push(Canonical { value: unsized_ty, kinds }) 784 deref_chain.push(Canonical { value: unsized_ty, kinds })
779 } 785 }
780 deref_chain 786 deref_chain
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index bb9b8bbfc..527c5cbbd 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -2,51 +2,55 @@
2use chalk_ir::TyVariableKind; 2use chalk_ir::TyVariableKind;
3use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 3use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
4 4
5use crate::{Scalar, Ty}; 5use crate::{Interner, Scalar, Ty, TyKind};
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
12 Ty::Scalar(Scalar::Int(_)) 12 match lhs_ty.interned(&Interner) {
13 | Ty::Scalar(Scalar::Uint(_)) 13 TyKind::Scalar(Scalar::Int(_))
14 | Ty::Scalar(Scalar::Float(_)) => lhs_ty, 14 | TyKind::Scalar(Scalar::Uint(_))
15 Ty::InferenceVar(_, TyVariableKind::Integer) 15 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
16 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 16 TyKind::InferenceVar(_, TyVariableKind::Integer)
17 _ => Ty::Unknown, 17 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
18 }, 18 _ => TyKind::Unknown.intern(&Interner),
19 BinaryOp::ArithOp(_) => match rhs_ty { 19 }
20 Ty::Scalar(Scalar::Int(_)) 20 }
21 | Ty::Scalar(Scalar::Uint(_)) 21 BinaryOp::ArithOp(_) => match rhs_ty.interned(&Interner) {
22 | Ty::Scalar(Scalar::Float(_)) => rhs_ty, 22 TyKind::Scalar(Scalar::Int(_))
23 Ty::InferenceVar(_, TyVariableKind::Integer) 23 | TyKind::Scalar(Scalar::Uint(_))
24 | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty, 24 | TyKind::Scalar(Scalar::Float(_)) => rhs_ty,
25 _ => Ty::Unknown, 25 TyKind::InferenceVar(_, TyVariableKind::Integer)
26 | TyKind::InferenceVar(_, TyVariableKind::Float) => rhs_ty,
27 _ => TyKind::Unknown.intern(&Interner),
26 }, 28 },
27 } 29 }
28} 30}
29 31
30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 32pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
31 match op { 33 match op {
32 BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool), 34 BinaryOp::LogicOp(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
33 BinaryOp::Assignment { op: None } => lhs_ty, 35 BinaryOp::Assignment { op: None } => lhs_ty,
34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 36 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty.interned(&Interner) {
35 Ty::Scalar(_) | Ty::Str => lhs_ty, 37 TyKind::Scalar(_) | TyKind::Str => lhs_ty,
36 Ty::InferenceVar(_, TyVariableKind::Integer) 38 TyKind::InferenceVar(_, TyVariableKind::Integer)
37 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 39 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
38 _ => Ty::Unknown, 40 _ => TyKind::Unknown.intern(&Interner),
39 }, 41 },
40 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, 42 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => {
43 TyKind::Unknown.intern(&Interner)
44 }
41 BinaryOp::CmpOp(CmpOp::Ord { .. }) 45 BinaryOp::CmpOp(CmpOp::Ord { .. })
42 | BinaryOp::Assignment { op: Some(_) } 46 | BinaryOp::Assignment { op: Some(_) }
43 | BinaryOp::ArithOp(_) => match lhs_ty { 47 | BinaryOp::ArithOp(_) => match lhs_ty.interned(&Interner) {
44 Ty::Scalar(Scalar::Int(_)) 48 TyKind::Scalar(Scalar::Int(_))
45 | Ty::Scalar(Scalar::Uint(_)) 49 | TyKind::Scalar(Scalar::Uint(_))
46 | Ty::Scalar(Scalar::Float(_)) => lhs_ty, 50 | TyKind::Scalar(Scalar::Float(_)) => lhs_ty,
47 Ty::InferenceVar(_, TyVariableKind::Integer) 51 TyKind::InferenceVar(_, TyVariableKind::Integer)
48 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty, 52 | TyKind::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
49 _ => Ty::Unknown, 53 _ => TyKind::Unknown.intern(&Interner),
50 }, 54 },
51 } 55 }
52} 56}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 27f350f70..500d1781c 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -10,7 +10,9 @@ use stdx::panic_context;
10 10
11use crate::{db::HirDatabase, DebruijnIndex, Substs}; 11use crate::{db::HirDatabase, DebruijnIndex, Substs};
12 12
13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{
14 Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
15};
14 16
15use self::chalk::{from_chalk, Interner, ToChalk}; 17use self::chalk::{from_chalk, Interner, ToChalk};
16 18
@@ -132,7 +134,7 @@ pub(crate) fn trait_solve_query(
132 log::info!("trait_solve_query({})", goal.value.value.display(db)); 134 log::info!("trait_solve_query({})", goal.value.value.display(db));
133 135
134 if let Obligation::Projection(pred) = &goal.value.value { 136 if let Obligation::Projection(pred) = &goal.value.value {
135 if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] { 137 if let TyKind::BoundVar(_) = &pred.projection_ty.parameters[0].interned(&Interner) {
136 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 138 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
137 return Some(Solution::Ambig(Guidance::Unknown)); 139 return Some(Solution::Ambig(Guidance::Unknown));
138 } 140 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 1a2a3a8c7..55181cc49 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -20,13 +20,14 @@ use crate::{
20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
21 utils::generics, 21 utils::generics,
22 BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate, 22 BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, 23 ProjectionTy, Substs, TraitRef, Ty, TyKind,
24}; 24};
25use mapping::{ 25use mapping::{
26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, 26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType,
27 TypeAliasAsValue, 27 TypeAliasAsValue,
28}; 28};
29 29
30pub use self::interner::Interner;
30pub(crate) use self::interner::*; 31pub(crate) use self::interner::*;
31 32
32pub(super) mod tls; 33pub(super) mod tls;
@@ -90,7 +91,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
90 ty: &Ty, 91 ty: &Ty,
91 binders: &CanonicalVarKinds<Interner>, 92 binders: &CanonicalVarKinds<Interner>,
92 ) -> Option<chalk_ir::TyVariableKind> { 93 ) -> Option<chalk_ir::TyVariableKind> {
93 if let Ty::BoundVar(bv) = ty { 94 if let TyKind::BoundVar(bv) = ty.interned(&Interner) {
94 let binders = binders.as_slice(&Interner); 95 let binders = binders.as_slice(&Interner);
95 if bv.debruijn == DebruijnIndex::INNERMOST { 96 if bv.debruijn == DebruijnIndex::INNERMOST {
96 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { 97 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
@@ -220,21 +221,25 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
220 let impl_bound = GenericPredicate::Implemented(TraitRef { 221 let impl_bound = GenericPredicate::Implemented(TraitRef {
221 trait_: future_trait, 222 trait_: future_trait,
222 // Self type as the first parameter. 223 // Self type as the first parameter.
223 substs: Substs::single(Ty::BoundVar(BoundVar { 224 substs: Substs::single(
224 debruijn: DebruijnIndex::INNERMOST, 225 TyKind::BoundVar(BoundVar {
225 index: 0, 226 debruijn: DebruijnIndex::INNERMOST,
226 })), 227 index: 0,
228 })
229 .intern(&Interner),
230 ),
227 }); 231 });
228 let proj_bound = GenericPredicate::Projection(ProjectionPredicate { 232 let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
229 // The parameter of the opaque type. 233 // The parameter of the opaque type.
230 ty: Ty::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }), 234 ty: TyKind::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 })
235 .intern(&Interner),
231 projection_ty: ProjectionTy { 236 projection_ty: ProjectionTy {
232 associated_ty: future_output, 237 associated_ty: future_output,
233 // Self type as the first parameter. 238 // Self type as the first parameter.
234 parameters: Substs::single(Ty::BoundVar(BoundVar::new( 239 parameters: Substs::single(
235 DebruijnIndex::INNERMOST, 240 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
236 0, 241 .intern(&Interner),
237 ))), 242 ),
238 }, 243 },
239 }); 244 });
240 let bound = OpaqueTyDatumBound { 245 let bound = OpaqueTyDatumBound {
@@ -263,7 +268,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
263 268
264 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> { 269 fn hidden_opaque_type(&self, _id: chalk_ir::OpaqueTyId<Interner>) -> chalk_ir::Ty<Interner> {
265 // FIXME: actually provide the hidden type; it is relevant for auto traits 270 // FIXME: actually provide the hidden type; it is relevant for auto traits
266 Ty::Unknown.to_chalk(self.db) 271 TyKind::Unknown.intern(&Interner).to_chalk(self.db)
267 } 272 }
268 273
269 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool { 274 fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
@@ -391,7 +396,8 @@ pub(crate) fn associated_ty_data_query(
391 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); 396 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
392 let ctx = crate::TyLoweringContext::new(db, &resolver) 397 let ctx = crate::TyLoweringContext::new(db, &resolver)
393 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); 398 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
394 let self_ty = Ty::BoundVar(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); 399 let self_ty =
400 TyKind::BoundVar(BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)).intern(&Interner);
395 let bounds = type_alias_data 401 let bounds = type_alias_data
396 .bounds 402 .bounds
397 .iter() 403 .iter()
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index b0415e8b0..44cfb9359 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -26,10 +26,10 @@ use super::*;
26impl ToChalk for Ty { 26impl ToChalk for Ty {
27 type Chalk = chalk_ir::Ty<Interner>; 27 type Chalk = chalk_ir::Ty<Interner>;
28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
29 match self { 29 match self.0 {
30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), 30 TyKind::Ref(m, parameters) => ref_to_chalk(db, m, parameters),
31 Ty::Array(parameters) => array_to_chalk(db, parameters), 31 TyKind::Array(parameters) => array_to_chalk(db, parameters),
32 Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => { 32 TyKind::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => {
33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); 33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
34 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 34 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
35 num_binders: 0, 35 num_binders: 0,
@@ -38,57 +38,57 @@ impl ToChalk for Ty {
38 }) 38 })
39 .intern(&Interner) 39 .intern(&Interner)
40 } 40 }
41 Ty::AssociatedType(type_alias, substs) => { 41 TyKind::AssociatedType(type_alias, substs) => {
42 let assoc_type = TypeAliasAsAssocType(type_alias); 42 let assoc_type = TypeAliasAsAssocType(type_alias);
43 let assoc_type_id = assoc_type.to_chalk(db); 43 let assoc_type_id = assoc_type.to_chalk(db);
44 let substitution = substs.to_chalk(db); 44 let substitution = substs.to_chalk(db);
45 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) 45 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
46 } 46 }
47 47
48 Ty::OpaqueType(impl_trait_id, substs) => { 48 TyKind::OpaqueType(impl_trait_id, substs) => {
49 let id = impl_trait_id.to_chalk(db); 49 let id = impl_trait_id.to_chalk(db);
50 let substitution = substs.to_chalk(db); 50 let substitution = substs.to_chalk(db);
51 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) 51 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
52 } 52 }
53 53
54 Ty::ForeignType(type_alias) => { 54 TyKind::ForeignType(type_alias) => {
55 let foreign_type = TypeAliasAsForeignType(type_alias); 55 let foreign_type = TypeAliasAsForeignType(type_alias);
56 let foreign_type_id = foreign_type.to_chalk(db); 56 let foreign_type_id = foreign_type.to_chalk(db);
57 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) 57 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
58 } 58 }
59 59
60 Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), 60 TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
61 61
62 Ty::Tuple(cardinality, substs) => { 62 TyKind::Tuple(cardinality, substs) => {
63 let substitution = substs.to_chalk(db); 63 let substitution = substs.to_chalk(db);
64 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 64 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
65 } 65 }
66 Ty::Raw(mutability, substs) => { 66 TyKind::Raw(mutability, substs) => {
67 let ty = substs[0].clone().to_chalk(db); 67 let ty = substs[0].clone().to_chalk(db);
68 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) 68 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner)
69 } 69 }
70 Ty::Slice(substs) => { 70 TyKind::Slice(substs) => {
71 chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) 71 chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner)
72 } 72 }
73 Ty::Str => chalk_ir::TyKind::Str.intern(&Interner), 73 TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner),
74 Ty::FnDef(callable_def, substs) => { 74 TyKind::FnDef(callable_def, substs) => {
75 let id = callable_def.to_chalk(db); 75 let id = callable_def.to_chalk(db);
76 let substitution = substs.to_chalk(db); 76 let substitution = substs.to_chalk(db);
77 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) 77 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
78 } 78 }
79 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), 79 TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner),
80 80
81 Ty::Closure(def, expr, substs) => { 81 TyKind::Closure(def, expr, substs) => {
82 let closure_id = db.intern_closure((def, expr)); 82 let closure_id = db.intern_closure((def, expr));
83 let substitution = substs.to_chalk(db); 83 let substitution = substs.to_chalk(db);
84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
85 } 85 }
86 86
87 Ty::Adt(adt_id, substs) => { 87 TyKind::Adt(adt_id, substs) => {
88 let substitution = substs.to_chalk(db); 88 let substitution = substs.to_chalk(db);
89 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner) 89 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner)
90 } 90 }
91 Ty::Alias(AliasTy::Projection(proj_ty)) => { 91 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
92 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); 92 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db);
93 let substitution = proj_ty.parameters.to_chalk(db); 93 let substitution = proj_ty.parameters.to_chalk(db);
94 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { 94 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
@@ -98,7 +98,7 @@ impl ToChalk for Ty {
98 .cast(&Interner) 98 .cast(&Interner)
99 .intern(&Interner) 99 .intern(&Interner)
100 } 100 }
101 Ty::Placeholder(id) => { 101 TyKind::Placeholder(id) => {
102 let interned_id = db.intern_type_param_id(id); 102 let interned_id = db.intern_type_param_id(id);
103 PlaceholderIndex { 103 PlaceholderIndex {
104 ui: UniverseIndex::ROOT, 104 ui: UniverseIndex::ROOT,
@@ -106,9 +106,9 @@ impl ToChalk for Ty {
106 } 106 }
107 .to_ty::<Interner>(&Interner) 107 .to_ty::<Interner>(&Interner)
108 } 108 }
109 Ty::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), 109 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
110 Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"), 110 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
111 Ty::Dyn(predicates) => { 111 TyKind::Dyn(predicates) => {
112 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 112 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
113 &Interner, 113 &Interner,
114 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), 114 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
@@ -119,7 +119,7 @@ impl ToChalk for Ty {
119 }; 119 };
120 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) 120 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
121 } 121 }
122 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 122 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
123 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); 123 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
124 let substitution = opaque_ty.parameters.to_chalk(db); 124 let substitution = opaque_ty.parameters.to_chalk(db);
125 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { 125 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
@@ -128,30 +128,30 @@ impl ToChalk for Ty {
128 })) 128 }))
129 .intern(&Interner) 129 .intern(&Interner)
130 } 130 }
131 Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner), 131 TyKind::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
132 } 132 }
133 } 133 }
134 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 134 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
135 match chalk.data(&Interner).kind.clone() { 135 match chalk.data(&Interner).kind.clone() {
136 chalk_ir::TyKind::Error => Ty::Unknown, 136 chalk_ir::TyKind::Error => TyKind::Unknown,
137 chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))), 137 chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(Substs::single(from_chalk(db, ty))),
138 chalk_ir::TyKind::Placeholder(idx) => { 138 chalk_ir::TyKind::Placeholder(idx) => {
139 assert_eq!(idx.ui, UniverseIndex::ROOT); 139 assert_eq!(idx.ui, UniverseIndex::ROOT);
140 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 140 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
141 crate::salsa::InternId::from(idx.idx), 141 crate::salsa::InternId::from(idx.idx),
142 ); 142 );
143 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id)) 143 TyKind::Placeholder(db.lookup_intern_type_param_id(interned_id))
144 } 144 }
145 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { 145 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
146 let associated_ty = 146 let associated_ty =
147 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; 147 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
148 let parameters = from_chalk(db, proj.substitution); 148 let parameters = from_chalk(db, proj.substitution);
149 Ty::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters })) 149 TyKind::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters }))
150 } 150 }
151 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 151 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
152 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 152 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
153 let parameters = from_chalk(db, opaque_ty.substitution); 153 let parameters = from_chalk(db, opaque_ty.substitution);
154 Ty::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })) 154 TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }))
155 } 155 }
156 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 156 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
157 num_binders, 157 num_binders,
@@ -164,14 +164,14 @@ impl ToChalk for Ty {
164 db, 164 db,
165 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 165 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
166 ); 166 );
167 Ty::Function(FnPointer { 167 TyKind::Function(FnPointer {
168 num_args: (substs.len() - 1), 168 num_args: (substs.len() - 1),
169 sig: FnSig { variadic }, 169 sig: FnSig { variadic },
170 substs, 170 substs,
171 }) 171 })
172 } 172 }
173 chalk_ir::TyKind::BoundVar(idx) => Ty::BoundVar(idx), 173 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
174 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, 174 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
175 chalk_ir::TyKind::Dyn(where_clauses) => { 175 chalk_ir::TyKind::Dyn(where_clauses) => {
176 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 176 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
177 let predicates = where_clauses 177 let predicates = where_clauses
@@ -180,49 +180,50 @@ impl ToChalk for Ty {
180 .iter(&Interner) 180 .iter(&Interner)
181 .map(|c| from_chalk(db, c.clone())) 181 .map(|c| from_chalk(db, c.clone()))
182 .collect(); 182 .collect();
183 Ty::Dyn(predicates) 183 TyKind::Dyn(predicates)
184 } 184 }
185 185
186 chalk_ir::TyKind::Adt(adt_id, subst) => Ty::Adt(adt_id, from_chalk(db, subst)), 186 chalk_ir::TyKind::Adt(adt_id, subst) => TyKind::Adt(adt_id, from_chalk(db, subst)),
187 chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType( 187 chalk_ir::TyKind::AssociatedType(type_id, subst) => TyKind::AssociatedType(
188 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, 188 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0,
189 from_chalk(db, subst), 189 from_chalk(db, subst),
190 ), 190 ),
191 191
192 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { 192 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
193 Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) 193 TyKind::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst))
194 } 194 }
195 195
196 chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), 196 chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar),
197 chalk_ir::TyKind::Tuple(cardinality, subst) => { 197 chalk_ir::TyKind::Tuple(cardinality, subst) => {
198 Ty::Tuple(cardinality, from_chalk(db, subst)) 198 TyKind::Tuple(cardinality, from_chalk(db, subst))
199 } 199 }
200 chalk_ir::TyKind::Raw(mutability, ty) => { 200 chalk_ir::TyKind::Raw(mutability, ty) => {
201 Ty::Raw(mutability, Substs::single(from_chalk(db, ty))) 201 TyKind::Raw(mutability, Substs::single(from_chalk(db, ty)))
202 } 202 }
203 chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), 203 chalk_ir::TyKind::Slice(ty) => TyKind::Slice(Substs::single(from_chalk(db, ty))),
204 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { 204 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
205 Ty::Ref(mutability, Substs::single(from_chalk(db, ty))) 205 TyKind::Ref(mutability, Substs::single(from_chalk(db, ty)))
206 } 206 }
207 chalk_ir::TyKind::Str => Ty::Str, 207 chalk_ir::TyKind::Str => TyKind::Str,
208 chalk_ir::TyKind::Never => Ty::Never, 208 chalk_ir::TyKind::Never => TyKind::Never,
209 209
210 chalk_ir::TyKind::FnDef(fn_def_id, subst) => { 210 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
211 Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) 211 TyKind::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst))
212 } 212 }
213 213
214 chalk_ir::TyKind::Closure(id, subst) => { 214 chalk_ir::TyKind::Closure(id, subst) => {
215 let id: crate::db::ClosureId = id.into(); 215 let id: crate::db::ClosureId = id.into();
216 let (def, expr) = db.lookup_intern_closure(id); 216 let (def, expr) = db.lookup_intern_closure(id);
217 Ty::Closure(def, expr, from_chalk(db, subst)) 217 TyKind::Closure(def, expr, from_chalk(db, subst))
218 } 218 }
219 219
220 chalk_ir::TyKind::Foreign(foreign_def_id) => { 220 chalk_ir::TyKind::Foreign(foreign_def_id) => {
221 Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0) 221 TyKind::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
222 } 222 }
223 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME 223 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
224 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME 224 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
225 } 225 }
226 .intern(&Interner)
226 } 227 }
227} 228}
228 229
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index ad0759bda..c81c1d26e 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -12,7 +12,7 @@ use hir::{
12 AssocItem, Crate, HasSource, HirDisplay, ModuleDef, 12 AssocItem, Crate, HasSource, HirDisplay, ModuleDef,
13}; 13};
14use hir_def::FunctionId; 14use hir_def::FunctionId;
15use hir_ty::{Ty, TypeWalk}; 15use hir_ty::TypeWalk;
16use ide_db::base_db::{ 16use ide_db::base_db::{
17 salsa::{self, ParallelDatabase}, 17 salsa::{self, ParallelDatabase},
18 SourceDatabaseExt, 18 SourceDatabaseExt,
@@ -187,12 +187,12 @@ impl AnalysisStatsCmd {
187 for (expr_id, _) in body.exprs.iter() { 187 for (expr_id, _) in body.exprs.iter() {
188 let ty = &inference_result[expr_id]; 188 let ty = &inference_result[expr_id];
189 num_exprs += 1; 189 num_exprs += 1;
190 if let Ty::Unknown = ty { 190 if ty.is_unknown() {
191 num_exprs_unknown += 1; 191 num_exprs_unknown += 1;
192 } else { 192 } else {
193 let mut is_partially_unknown = false; 193 let mut is_partially_unknown = false;
194 ty.walk(&mut |ty| { 194 ty.walk(&mut |ty| {
195 if let Ty::Unknown = ty { 195 if ty.is_unknown() {
196 is_partially_unknown = true; 196 is_partially_unknown = true;
197 } 197 }
198 }); 198 });