aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/Cargo.toml4
-rw-r--r--crates/hir_ty/src/autoderef.rs15
-rw-r--r--crates/hir_ty/src/db.rs23
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs2
-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.rs12
-rw-r--r--crates/hir_ty/src/display.rs401
-rw-r--r--crates/hir_ty/src/infer.rs98
-rw-r--r--crates/hir_ty/src/infer/coerce.rs42
-rw-r--r--crates/hir_ty/src/infer/expr.rs253
-rw-r--r--crates/hir_ty/src/infer/pat.rs49
-rw-r--r--crates/hir_ty/src/infer/path.rs18
-rw-r--r--crates/hir_ty/src/infer/unify.rs133
-rw-r--r--crates/hir_ty/src/lib.rs462
-rw-r--r--crates/hir_ty/src/lower.rs724
-rw-r--r--crates/hir_ty/src/method_resolution.rs93
-rw-r--r--crates/hir_ty/src/op.rs66
-rw-r--r--crates/hir_ty/src/tests.rs10
-rw-r--r--crates/hir_ty/src/tests/macros.rs16
-rw-r--r--crates/hir_ty/src/tests/traits.rs216
-rw-r--r--crates/hir_ty/src/traits.rs15
-rw-r--r--crates/hir_ty/src/traits/chalk.rs68
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs9
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs251
-rw-r--r--crates/hir_ty/src/traits/chalk/tls.rs9
26 files changed, 1688 insertions, 1330 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index b9c93f56f..0ef27cd37 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2018"
10doctest = false 10doctest = false
11 11
12[dependencies] 12[dependencies]
13cov-mark = "1.1" 13cov-mark = { version = "1.1", features = ["thread-local"] }
14itertools = "0.10.0" 14itertools = "0.10.0"
15arrayvec = "0.5.1" 15arrayvec = "0.5.1"
16smallvec = "1.2.0" 16smallvec = "1.2.0"
@@ -31,7 +31,7 @@ profile = { path = "../profile", version = "0.0.0" }
31syntax = { path = "../syntax", version = "0.0.0" } 31syntax = { path = "../syntax", version = "0.0.0" }
32 32
33[dev-dependencies] 33[dev-dependencies]
34test_utils = { path = "../test_utils" } 34test_utils = { path = "../test_utils" }
35expect-test = "1.1" 35expect-test = "1.1"
36tracing = "0.1" 36tracing = "0.1"
37tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } 37tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index be1fd1f13..56c6b92d4 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -12,9 +12,10 @@ use log::{info, warn};
12 12
13use crate::{ 13use crate::{
14 db::HirDatabase, 14 db::HirDatabase,
15 to_assoc_type_id,
15 traits::{InEnvironment, Solution}, 16 traits::{InEnvironment, Solution},
16 utils::generics, 17 utils::generics,
17 BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, 18 BoundVar, Canonical, DebruijnIndex, Interner, Obligation, Substs, TraitRef, Ty, TyKind,
18}; 19};
19 20
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 21const AUTODEREF_RECURSION_LIMIT: usize = 10;
@@ -81,8 +82,12 @@ fn deref_by_trait(
81 82
82 // Now do the assoc type projection 83 // Now do the assoc type projection
83 let projection = super::traits::ProjectionPredicate { 84 let projection = super::traits::ProjectionPredicate {
84 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 85 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len()))
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 86 .intern(&Interner),
87 projection_ty: super::ProjectionTy {
88 associated_ty_id: to_assoc_type_id(target),
89 substitution: parameters,
90 },
86 }; 91 };
87 92
88 let obligation = super::Obligation::Projection(projection); 93 let obligation = super::Obligation::Projection(projection);
@@ -114,8 +119,8 @@ fn deref_by_trait(
114 // new variables in that case 119 // new variables in that case
115 120
116 for i in 1..vars.0.kinds.len() { 121 for i in 1..vars.0.kinds.len() {
117 if vars.0.value[i - 1] 122 if vars.0.value[i - 1].interned(&Interner)
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 123 != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
119 { 124 {
120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 125 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
121 return None; 126 return None;
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index 06714409f..74a048672 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -12,7 +12,7 @@ use la_arena::ArenaMap;
12use crate::{ 12use crate::{
13 method_resolution::{InherentImpls, TraitImpls}, 13 method_resolution::{InherentImpls, TraitImpls},
14 traits::chalk, 14 traits::chalk,
15 Binders, CallableDefId, GenericPredicate, InferenceResult, OpaqueTyId, PolyFnSig, 15 Binders, CallableDefId, FnDefId, GenericPredicate, ImplTraitId, InferenceResult, PolyFnSig,
16 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId, 16 ReturnTypeImplTraits, TraitRef, Ty, TyDefId, ValueTyDefId,
17}; 17};
18use hir_expand::name::Name; 18use hir_expand::name::Name;
@@ -65,6 +65,9 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
65 #[salsa::invoke(crate::lower::generic_predicates_query)] 65 #[salsa::invoke(crate::lower::generic_predicates_query)]
66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>; 66 fn generic_predicates(&self, def: GenericDefId) -> Arc<[Binders<GenericPredicate>]>;
67 67
68 #[salsa::invoke(crate::lower::trait_environment_query)]
69 fn trait_environment(&self, def: GenericDefId) -> Arc<crate::TraitEnvironment>;
70
68 #[salsa::invoke(crate::lower::generic_defaults_query)] 71 #[salsa::invoke(crate::lower::generic_defaults_query)]
69 fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>; 72 fn generic_defaults(&self, def: GenericDefId) -> Arc<[Binders<Ty>]>;
70 73
@@ -81,11 +84,11 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
81 #[salsa::interned] 84 #[salsa::interned]
82 fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId; 85 fn intern_callable_def(&self, callable_def: CallableDefId) -> InternedCallableDefId;
83 #[salsa::interned] 86 #[salsa::interned]
84 fn intern_type_param_id(&self, param_id: TypeParamId) -> GlobalTypeParamId; 87 fn intern_type_param_id(&self, param_id: TypeParamId) -> InternedTypeParamId;
85 #[salsa::interned] 88 #[salsa::interned]
86 fn intern_impl_trait_id(&self, id: OpaqueTyId) -> InternedOpaqueTyId; 89 fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
87 #[salsa::interned] 90 #[salsa::interned]
88 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> ClosureId; 91 fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
89 92
90 #[salsa::invoke(chalk::associated_ty_data_query)] 93 #[salsa::invoke(chalk::associated_ty_data_query)]
91 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>; 94 fn associated_ty_data(&self, id: chalk::AssocTypeId) -> Arc<chalk::AssociatedTyDatum>;
@@ -100,10 +103,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
100 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>; 103 fn impl_datum(&self, krate: CrateId, impl_id: chalk::ImplId) -> Arc<chalk::ImplDatum>;
101 104
102 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)] 105 #[salsa::invoke(crate::traits::chalk::fn_def_datum_query)]
103 fn fn_def_datum(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> Arc<chalk::FnDefDatum>; 106 fn fn_def_datum(&self, krate: CrateId, fn_def_id: FnDefId) -> Arc<chalk::FnDefDatum>;
104 107
105 #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)] 108 #[salsa::invoke(crate::traits::chalk::fn_def_variance_query)]
106 fn fn_def_variance(&self, krate: CrateId, fn_def_id: chalk::FnDefId) -> chalk::Variances; 109 fn fn_def_variance(&self, krate: CrateId, fn_def_id: FnDefId) -> chalk::Variances;
107 110
108 #[salsa::invoke(crate::traits::chalk::adt_variance_query)] 111 #[salsa::invoke(crate::traits::chalk::adt_variance_query)]
109 fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances; 112 fn adt_variance(&self, krate: CrateId, adt_id: chalk::AdtId) -> chalk::Variances;
@@ -149,16 +152,16 @@ fn hir_database_is_object_safe() {
149} 152}
150 153
151#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 154#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
152pub struct GlobalTypeParamId(salsa::InternId); 155pub struct InternedTypeParamId(salsa::InternId);
153impl_intern_key!(GlobalTypeParamId); 156impl_intern_key!(InternedTypeParamId);
154 157
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 158#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct InternedOpaqueTyId(salsa::InternId); 159pub struct InternedOpaqueTyId(salsa::InternId);
157impl_intern_key!(InternedOpaqueTyId); 160impl_intern_key!(InternedOpaqueTyId);
158 161
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 162#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
160pub struct ClosureId(salsa::InternId); 163pub struct InternedClosureId(salsa::InternId);
161impl_intern_key!(ClosureId); 164impl_intern_key!(InternedClosureId);
162 165
163/// This exists just for Chalk, because Chalk just has a single `FnDefId` where 166/// This exists just for Chalk, because Chalk just has a single `FnDefId` where
164/// we have different IDs for struct and enum variant constructors. 167/// we have different IDs for struct and enum variant constructors.
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 3605ca581..982ad5b9e 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -91,7 +91,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
91 91
92 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
93 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
94 if data.is_extern { 94 if data.is_in_extern_block {
95 cov_mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
96 return; 96 return;
97 } 97 }
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..44a7e5506 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,
@@ -32,7 +32,7 @@ impl<'a, 'b> UnsafeValidator<'a, 'b> {
32 let def = self.owner.into(); 32 let def = self.owner.into();
33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def); 33 let unsafe_expressions = unsafe_expressions(db, self.infer.as_ref(), def);
34 let is_unsafe = match self.owner { 34 let is_unsafe = match self.owner {
35 DefWithBodyId::FunctionId(it) => db.function_data(it).is_unsafe, 35 DefWithBodyId::FunctionId(it) => db.function_data(it).qualifier.is_unsafe,
36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false, 36 DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
37 }; 37 };
38 if is_unsafe 38 if is_unsafe
@@ -85,8 +85,8 @@ fn walk_unsafe(
85 let expr = &body.exprs[current]; 85 let expr = &body.exprs[current];
86 match expr { 86 match expr {
87 &Expr::Call { callee, .. } => { 87 &Expr::Call { callee, .. } => {
88 if let Some(func) = infer[callee].as_fn_def() { 88 if let Some(func) = infer[callee].as_fn_def(db) {
89 if db.function_data(func).is_unsafe { 89 if db.function_data(func).qualifier.is_unsafe {
90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 90 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
91 } 91 }
92 } 92 }
@@ -103,14 +103,14 @@ fn walk_unsafe(
103 Expr::MethodCall { .. } => { 103 Expr::MethodCall { .. } => {
104 if infer 104 if infer
105 .method_resolution(current) 105 .method_resolution(current)
106 .map(|func| db.function_data(func).is_unsafe) 106 .map(|func| db.function_data(func).qualifier.is_unsafe)
107 .unwrap_or(false) 107 .unwrap_or(false)
108 { 108 {
109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 109 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
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..c572bb114 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -5,15 +5,22 @@ use std::{borrow::Cow, fmt};
5use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability; 6use chalk_ir::Mutability;
7use hir_def::{ 7use hir_def::{
8 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, 8 db::DefDatabase,
9 find_path,
10 generics::TypeParamProvenance,
11 item_scope::ItemInNs,
12 path::{GenericArg, Path, PathKind},
13 type_ref::{TypeBound, TypeRef},
14 visibility::Visibility,
9 AssocContainerId, Lookup, ModuleId, TraitId, 15 AssocContainerId, Lookup, ModuleId, TraitId,
10}; 16};
11use hir_expand::name::Name; 17use hir_expand::name::Name;
12 18
13use crate::{ 19use crate::{
14 db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig, 20 db::HirDatabase, from_assoc_type_id, from_foreign_def_id, from_placeholder_idx, primitive,
15 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 21 to_assoc_type_id, traits::chalk::from_chalk, utils::generics, AdtId, AliasTy, CallableDefId,
16 TraitRef, Ty, 22 CallableSig, GenericPredicate, ImplTraitId, Interner, Lifetime, Obligation, OpaqueTy,
23 ProjectionTy, Scalar, Substs, TraitRef, Ty, TyKind,
17}; 24};
18 25
19pub struct HirFormatter<'a> { 26pub struct HirFormatter<'a> {
@@ -231,7 +238,7 @@ where
231 238
232const TYPE_HINT_TRUNCATION: &str = "…"; 239const TYPE_HINT_TRUNCATION: &str = "…";
233 240
234impl HirDisplay for &Ty { 241impl<T: HirDisplay> HirDisplay for &'_ T {
235 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 242 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
236 HirDisplay::hir_fmt(*self, f) 243 HirDisplay::hir_fmt(*self, f)
237 } 244 }
@@ -244,19 +251,19 @@ impl HirDisplay for ProjectionTy {
244 } 251 }
245 252
246 let trait_ = f.db.trait_data(self.trait_(f.db)); 253 let trait_ = f.db.trait_data(self.trait_(f.db));
247 let first_parameter = self.parameters[0].into_displayable( 254 let first_parameter = self.substitution[0].into_displayable(
248 f.db, 255 f.db,
249 f.max_size, 256 f.max_size,
250 f.omit_verbose_types, 257 f.omit_verbose_types,
251 f.display_target, 258 f.display_target,
252 ); 259 );
253 write!(f, "<{} as {}", first_parameter, trait_.name)?; 260 write!(f, "<{} as {}", first_parameter, trait_.name)?;
254 if self.parameters.len() > 1 { 261 if self.substitution.len() > 1 {
255 write!(f, "<")?; 262 write!(f, "<")?;
256 f.write_joined(&self.parameters[1..], ", ")?; 263 f.write_joined(&self.substitution[1..], ", ")?;
257 write!(f, ">")?; 264 write!(f, ">")?;
258 } 265 }
259 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?; 266 write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
260 Ok(()) 267 Ok(())
261 } 268 }
262} 269}
@@ -267,32 +274,29 @@ impl HirDisplay for Ty {
267 return write!(f, "{}", TYPE_HINT_TRUNCATION); 274 return write!(f, "{}", TYPE_HINT_TRUNCATION);
268 } 275 }
269 276
270 match self { 277 match self.interned(&Interner) {
271 Ty::Never => write!(f, "!")?, 278 TyKind::Never => write!(f, "!")?,
272 Ty::Str => write!(f, "str")?, 279 TyKind::Str => write!(f, "str")?,
273 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?, 280 TyKind::Scalar(Scalar::Bool) => write!(f, "bool")?,
274 Ty::Scalar(Scalar::Char) => write!(f, "char")?, 281 TyKind::Scalar(Scalar::Char) => write!(f, "char")?,
275 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?, 282 &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))?, 283 &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))?, 284 &TyKind::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
278 Ty::Slice(parameters) => { 285 TyKind::Slice(t) => {
279 let t = parameters.as_single();
280 write!(f, "[")?; 286 write!(f, "[")?;
281 t.hir_fmt(f)?; 287 t.hir_fmt(f)?;
282 write!(f, "]")?; 288 write!(f, "]")?;
283 } 289 }
284 Ty::Array(parameters) => { 290 TyKind::Array(t) => {
285 let t = parameters.as_single();
286 write!(f, "[")?; 291 write!(f, "[")?;
287 t.hir_fmt(f)?; 292 t.hir_fmt(f)?;
288 write!(f, "; _]")?; 293 write!(f, "; _]")?;
289 } 294 }
290 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => { 295 TyKind::Raw(m, t) | TyKind::Ref(m, t) => {
291 let t = parameters.as_single();
292 let ty_display = 296 let ty_display =
293 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 297 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
294 298
295 if matches!(self, Ty::Raw(..)) { 299 if matches!(self.interned(&Interner), TyKind::Raw(..)) {
296 write!( 300 write!(
297 f, 301 f,
298 "*{}", 302 "*{}",
@@ -312,22 +316,29 @@ impl HirDisplay for Ty {
312 )?; 316 )?;
313 } 317 }
314 318
319 // FIXME: all this just to decide whether to use parentheses...
315 let datas; 320 let datas;
316 let predicates = match t { 321 let predicates = match t.interned(&Interner) {
317 Ty::Dyn(predicates) if predicates.len() > 1 => { 322 TyKind::Dyn(predicates) if predicates.len() > 1 => {
318 Cow::Borrowed(predicates.as_ref()) 323 Cow::Borrowed(predicates.as_ref())
319 } 324 }
320 &Ty::Alias(AliasTy::Opaque(OpaqueTy { 325 &TyKind::Alias(AliasTy::Opaque(OpaqueTy {
321 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 326 opaque_ty_id,
322 ref parameters, 327 substitution: ref parameters,
323 })) => { 328 })) => {
324 datas = 329 let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty_id.into());
325 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 330 if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
326 let data = (*datas) 331 datas =
327 .as_ref() 332 f.db.return_type_impl_traits(func)
328 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 333 .expect("impl trait id without data");
329 let bounds = data.subst(parameters); 334 let data = (*datas)
330 Cow::Owned(bounds.value) 335 .as_ref()
336 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
337 let bounds = data.subst(parameters);
338 Cow::Owned(bounds.value)
339 } else {
340 Cow::Borrowed(&[][..])
341 }
331 } 342 }
332 _ => Cow::Borrowed(&[][..]), 343 _ => Cow::Borrowed(&[][..]),
333 }; 344 };
@@ -347,7 +358,7 @@ impl HirDisplay for Ty {
347 write!(f, "{}", ty_display)?; 358 write!(f, "{}", ty_display)?;
348 } 359 }
349 } 360 }
350 Ty::Tuple(_, substs) => { 361 TyKind::Tuple(_, substs) => {
351 if substs.len() == 1 { 362 if substs.len() == 1 {
352 write!(f, "(")?; 363 write!(f, "(")?;
353 substs[0].hir_fmt(f)?; 364 substs[0].hir_fmt(f)?;
@@ -358,12 +369,12 @@ impl HirDisplay for Ty {
358 write!(f, ")")?; 369 write!(f, ")")?;
359 } 370 }
360 } 371 }
361 Ty::Function(fn_ptr) => { 372 TyKind::Function(fn_ptr) => {
362 let sig = CallableSig::from_fn_ptr(fn_ptr); 373 let sig = CallableSig::from_fn_ptr(fn_ptr);
363 sig.hir_fmt(f)?; 374 sig.hir_fmt(f)?;
364 } 375 }
365 Ty::FnDef(def, parameters) => { 376 TyKind::FnDef(def, parameters) => {
366 let def = *def; 377 let def = from_chalk(f.db, *def);
367 let sig = f.db.callable_item_signature(def).subst(parameters); 378 let sig = f.db.callable_item_signature(def).subst(parameters);
368 match def { 379 match def {
369 CallableDefId::FunctionId(ff) => { 380 CallableDefId::FunctionId(ff) => {
@@ -401,7 +412,7 @@ impl HirDisplay for Ty {
401 write!(f, " -> {}", ret_display)?; 412 write!(f, " -> {}", ret_display)?;
402 } 413 }
403 } 414 }
404 Ty::Adt(AdtId(def_id), parameters) => { 415 TyKind::Adt(AdtId(def_id), parameters) => {
405 match f.display_target { 416 match f.display_target {
406 DisplayTarget::Diagnostics | DisplayTarget::Test => { 417 DisplayTarget::Diagnostics | DisplayTarget::Test => {
407 let name = match *def_id { 418 let name = match *def_id {
@@ -427,37 +438,39 @@ impl HirDisplay for Ty {
427 } 438 }
428 439
429 if parameters.len() > 0 { 440 if parameters.len() > 0 {
430 let parameters_to_write = 441 let parameters_to_write = if f.display_target.is_source_code()
431 if f.display_target.is_source_code() || f.omit_verbose_types() { 442 || f.omit_verbose_types()
432 match self 443 {
433 .as_generic_def() 444 match self
434 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 445 .as_generic_def(f.db)
435 .filter(|defaults| !defaults.is_empty()) 446 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
436 { 447 .filter(|defaults| !defaults.is_empty())
437 None => parameters.0.as_ref(), 448 {
438 Some(default_parameters) => { 449 None => parameters.0.as_ref(),
439 let mut default_from = 0; 450 Some(default_parameters) => {
440 for (i, parameter) in parameters.iter().enumerate() { 451 let mut default_from = 0;
441 match (parameter, default_parameters.get(i)) { 452 for (i, parameter) in parameters.iter().enumerate() {
442 (&Ty::Unknown, _) | (_, None) => { 453 match (parameter.interned(&Interner), default_parameters.get(i))
454 {
455 (&TyKind::Unknown, _) | (_, None) => {
456 default_from = i + 1;
457 }
458 (_, Some(default_parameter)) => {
459 let actual_default = default_parameter
460 .clone()
461 .subst(&parameters.prefix(i));
462 if parameter != &actual_default {
443 default_from = i + 1; 463 default_from = i + 1;
444 } 464 }
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 } 465 }
454 } 466 }
455 &parameters.0[0..default_from]
456 } 467 }
468 &parameters.0[0..default_from]
457 } 469 }
458 } else { 470 }
459 parameters.0.as_ref() 471 } else {
460 }; 472 parameters.0.as_ref()
473 };
461 if !parameters_to_write.is_empty() { 474 if !parameters_to_write.is_empty() {
462 write!(f, "<")?; 475 write!(f, "<")?;
463 f.write_joined(parameters_to_write, ", ")?; 476 f.write_joined(parameters_to_write, ", ")?;
@@ -465,13 +478,14 @@ impl HirDisplay for Ty {
465 } 478 }
466 } 479 }
467 } 480 }
468 Ty::AssociatedType(type_alias, parameters) => { 481 TyKind::AssociatedType(assoc_type_id, parameters) => {
482 let type_alias = from_assoc_type_id(*assoc_type_id);
469 let trait_ = match type_alias.lookup(f.db.upcast()).container { 483 let trait_ = match type_alias.lookup(f.db.upcast()).container {
470 AssocContainerId::TraitId(it) => it, 484 AssocContainerId::TraitId(it) => it,
471 _ => panic!("not an associated type"), 485 _ => panic!("not an associated type"),
472 }; 486 };
473 let trait_ = f.db.trait_data(trait_); 487 let trait_ = f.db.trait_data(trait_);
474 let type_alias_data = f.db.type_alias_data(*type_alias); 488 let type_alias_data = f.db.type_alias_data(type_alias);
475 489
476 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 490 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
477 if f.display_target.is_test() { 491 if f.display_target.is_test() {
@@ -482,19 +496,22 @@ impl HirDisplay for Ty {
482 write!(f, ">")?; 496 write!(f, ">")?;
483 } 497 }
484 } else { 498 } else {
485 let projection_ty = 499 let projection_ty = ProjectionTy {
486 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() }; 500 associated_ty_id: to_assoc_type_id(type_alias),
501 substitution: parameters.clone(),
502 };
487 503
488 projection_ty.hir_fmt(f)?; 504 projection_ty.hir_fmt(f)?;
489 } 505 }
490 } 506 }
491 Ty::ForeignType(type_alias) => { 507 TyKind::ForeignType(type_alias) => {
492 let type_alias = f.db.type_alias_data(*type_alias); 508 let type_alias = f.db.type_alias_data(from_foreign_def_id(*type_alias));
493 write!(f, "{}", type_alias.name)?; 509 write!(f, "{}", type_alias.name)?;
494 } 510 }
495 Ty::OpaqueType(opaque_ty_id, parameters) => { 511 TyKind::OpaqueType(opaque_ty_id, parameters) => {
496 match opaque_ty_id { 512 let impl_trait_id = f.db.lookup_intern_impl_trait_id((*opaque_ty_id).into());
497 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 513 match impl_trait_id {
514 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
498 let datas = 515 let datas =
499 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 516 f.db.return_type_impl_traits(func).expect("impl trait id without data");
500 let data = (*datas) 517 let data = (*datas)
@@ -504,14 +521,14 @@ impl HirDisplay for Ty {
504 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 521 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
505 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 522 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
506 } 523 }
507 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 524 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
508 write!(f, "impl Future<Output = ")?; 525 write!(f, "impl Future<Output = ")?;
509 parameters[0].hir_fmt(f)?; 526 parameters[0].hir_fmt(f)?;
510 write!(f, ">")?; 527 write!(f, ">")?;
511 } 528 }
512 } 529 }
513 } 530 }
514 Ty::Closure(.., substs) => { 531 TyKind::Closure(.., substs) => {
515 let sig = substs[0].callable_sig(f.db); 532 let sig = substs[0].callable_sig(f.db);
516 if let Some(sig) = sig { 533 if let Some(sig) = sig {
517 if sig.params().is_empty() { 534 if sig.params().is_empty() {
@@ -535,7 +552,8 @@ impl HirDisplay for Ty {
535 write!(f, "{{closure}}")?; 552 write!(f, "{{closure}}")?;
536 } 553 }
537 } 554 }
538 Ty::Placeholder(id) => { 555 TyKind::Placeholder(idx) => {
556 let id = from_placeholder_idx(f.db, *idx);
539 let generics = generics(f.db.upcast(), id.parent); 557 let generics = generics(f.db.upcast(), id.parent);
540 let param_data = &generics.params.types[id.local_id]; 558 let param_data = &generics.params.types[id.local_id];
541 match param_data.provenance { 559 match param_data.provenance {
@@ -543,8 +561,8 @@ impl HirDisplay for Ty {
543 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))? 561 write!(f, "{}", param_data.name.clone().unwrap_or_else(Name::missing))?
544 } 562 }
545 TypeParamProvenance::ArgumentImplTrait => { 563 TypeParamProvenance::ArgumentImplTrait => {
546 let bounds = f.db.generic_predicates_for_param(*id); 564 let bounds = f.db.generic_predicates_for_param(id);
547 let substs = Substs::type_params_for_generics(&generics); 565 let substs = Substs::type_params_for_generics(f.db, &generics);
548 write_bounds_like_dyn_trait_with_prefix( 566 write_bounds_like_dyn_trait_with_prefix(
549 "impl", 567 "impl",
550 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(), 568 &bounds.iter().map(|b| b.clone().subst(&substs)).collect::<Vec<_>>(),
@@ -553,28 +571,29 @@ impl HirDisplay for Ty {
553 } 571 }
554 } 572 }
555 } 573 }
556 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 574 TyKind::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
557 Ty::Dyn(predicates) => { 575 TyKind::Dyn(predicates) => {
558 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 576 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
559 } 577 }
560 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?, 578 TyKind::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
561 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 579 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
562 match opaque_ty.opaque_ty_id { 580 let impl_trait_id = f.db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into());
563 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 581 match impl_trait_id {
582 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
564 let datas = 583 let datas =
565 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 584 f.db.return_type_impl_traits(func).expect("impl trait id without data");
566 let data = (*datas) 585 let data = (*datas)
567 .as_ref() 586 .as_ref()
568 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 587 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
569 let bounds = data.subst(&opaque_ty.parameters); 588 let bounds = data.subst(&opaque_ty.substitution);
570 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 589 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
571 } 590 }
572 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 591 ImplTraitId::AsyncBlockTypeImplTrait(..) => {
573 write!(f, "{{async block}}")?; 592 write!(f, "{{async block}}")?;
574 } 593 }
575 }; 594 };
576 } 595 }
577 Ty::Unknown => { 596 TyKind::Unknown => {
578 if f.display_target.is_source_code() { 597 if f.display_target.is_source_code() {
579 return Err(HirDisplayError::DisplaySourceCodeError( 598 return Err(HirDisplayError::DisplaySourceCodeError(
580 DisplaySourceCodeError::UnknownType, 599 DisplaySourceCodeError::UnknownType,
@@ -582,7 +601,7 @@ impl HirDisplay for Ty {
582 } 601 }
583 write!(f, "{{unknown}}")?; 602 write!(f, "{{unknown}}")?;
584 } 603 }
585 Ty::InferenceVar(..) => write!(f, "_")?, 604 TyKind::InferenceVar(..) => write!(f, "_")?,
586 } 605 }
587 Ok(()) 606 Ok(())
588 } 607 }
@@ -695,7 +714,9 @@ fn write_bounds_like_dyn_trait(
695 write!(f, "<")?; 714 write!(f, "<")?;
696 angle_open = true; 715 angle_open = true;
697 } 716 }
698 let type_alias = f.db.type_alias_data(projection_pred.projection_ty.associated_ty); 717 let type_alias = f.db.type_alias_data(from_assoc_type_id(
718 projection_pred.projection_ty.associated_ty_id,
719 ));
699 write!(f, "{} = ", type_alias.name)?; 720 write!(f, "{} = ", type_alias.name)?;
700 projection_pred.ty.hir_fmt(f)?; 721 projection_pred.ty.hir_fmt(f)?;
701 } 722 }
@@ -746,12 +767,6 @@ impl HirDisplay for TraitRef {
746 } 767 }
747} 768}
748 769
749impl HirDisplay for &GenericPredicate {
750 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
751 HirDisplay::hir_fmt(*self, f)
752 }
753}
754
755impl HirDisplay for GenericPredicate { 770impl HirDisplay for GenericPredicate {
756 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 771 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
757 if f.should_truncate() { 772 if f.should_truncate() {
@@ -766,7 +781,10 @@ impl HirDisplay for GenericPredicate {
766 write!( 781 write!(
767 f, 782 f,
768 ">::{} = ", 783 ">::{} = ",
769 f.db.type_alias_data(projection_pred.projection_ty.associated_ty).name, 784 f.db.type_alias_data(from_assoc_type_id(
785 projection_pred.projection_ty.associated_ty_id
786 ))
787 .name,
770 )?; 788 )?;
771 projection_pred.ty.hir_fmt(f)?; 789 projection_pred.ty.hir_fmt(f)?;
772 } 790 }
@@ -807,3 +825,190 @@ impl HirDisplay for Obligation {
807 } 825 }
808 } 826 }
809} 827}
828
829pub fn write_visibility(
830 module_id: ModuleId,
831 vis: Visibility,
832 f: &mut HirFormatter,
833) -> Result<(), HirDisplayError> {
834 match vis {
835 Visibility::Public => write!(f, "pub "),
836 Visibility::Module(vis_id) => {
837 let def_map = module_id.def_map(f.db.upcast());
838 let root_module_id = def_map.module_id(def_map.root());
839 if vis_id == module_id {
840 // pub(self) or omitted
841 Ok(())
842 } else if root_module_id == vis_id {
843 write!(f, "pub(crate) ")
844 } else if module_id.containing_module(f.db.upcast()) == Some(vis_id) {
845 write!(f, "pub(super) ")
846 } else {
847 write!(f, "pub(in ...) ")
848 }
849 }
850 }
851}
852
853impl HirDisplay for TypeRef {
854 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
855 match self {
856 TypeRef::Never => write!(f, "!")?,
857 TypeRef::Placeholder => write!(f, "_")?,
858 TypeRef::Tuple(elems) => {
859 write!(f, "(")?;
860 f.write_joined(elems, ", ")?;
861 if elems.len() == 1 {
862 write!(f, ",")?;
863 }
864 write!(f, ")")?;
865 }
866 TypeRef::Path(path) => path.hir_fmt(f)?,
867 TypeRef::RawPtr(inner, mutability) => {
868 let mutability = match mutability {
869 hir_def::type_ref::Mutability::Shared => "*const ",
870 hir_def::type_ref::Mutability::Mut => "*mut ",
871 };
872 write!(f, "{}", mutability)?;
873 inner.hir_fmt(f)?;
874 }
875 TypeRef::Reference(inner, lifetime, mutability) => {
876 let mutability = match mutability {
877 hir_def::type_ref::Mutability::Shared => "",
878 hir_def::type_ref::Mutability::Mut => "mut ",
879 };
880 write!(f, "&")?;
881 if let Some(lifetime) = lifetime {
882 write!(f, "{} ", lifetime.name)?;
883 }
884 write!(f, "{}", mutability)?;
885 inner.hir_fmt(f)?;
886 }
887 TypeRef::Array(inner) => {
888 write!(f, "[")?;
889 inner.hir_fmt(f)?;
890 // FIXME: Array length?
891 write!(f, "; _]")?;
892 }
893 TypeRef::Slice(inner) => {
894 write!(f, "[")?;
895 inner.hir_fmt(f)?;
896 write!(f, "]")?;
897 }
898 TypeRef::Fn(tys, is_varargs) => {
899 // FIXME: Function pointer qualifiers.
900 write!(f, "fn(")?;
901 f.write_joined(&tys[..tys.len() - 1], ", ")?;
902 if *is_varargs {
903 write!(f, "{}...", if tys.len() == 1 { "" } else { ", " })?;
904 }
905 write!(f, ")")?;
906 let ret_ty = tys.last().unwrap();
907 match ret_ty {
908 TypeRef::Tuple(tup) if tup.is_empty() => {}
909 _ => {
910 write!(f, " -> ")?;
911 ret_ty.hir_fmt(f)?;
912 }
913 }
914 }
915 TypeRef::ImplTrait(bounds) => {
916 write!(f, "impl ")?;
917 f.write_joined(bounds, " + ")?;
918 }
919 TypeRef::DynTrait(bounds) => {
920 write!(f, "dyn ")?;
921 f.write_joined(bounds, " + ")?;
922 }
923 TypeRef::Error => write!(f, "{{error}}")?,
924 }
925 Ok(())
926 }
927}
928
929impl HirDisplay for TypeBound {
930 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
931 match self {
932 TypeBound::Path(path) => path.hir_fmt(f),
933 TypeBound::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
934 TypeBound::Error => write!(f, "{{error}}"),
935 }
936 }
937}
938
939impl HirDisplay for Path {
940 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
941 match (self.type_anchor(), self.kind()) {
942 (Some(anchor), _) => {
943 write!(f, "<")?;
944 anchor.hir_fmt(f)?;
945 write!(f, ">")?;
946 }
947 (_, PathKind::Plain) => {}
948 (_, PathKind::Abs) => write!(f, "::")?,
949 (_, PathKind::Crate) => write!(f, "crate")?,
950 (_, PathKind::Super(0)) => write!(f, "self")?,
951 (_, PathKind::Super(n)) => {
952 write!(f, "super")?;
953 for _ in 0..*n {
954 write!(f, "::super")?;
955 }
956 }
957 (_, PathKind::DollarCrate(_)) => write!(f, "{{extern_crate}}")?,
958 }
959
960 for (seg_idx, segment) in self.segments().iter().enumerate() {
961 if seg_idx != 0 {
962 write!(f, "::")?;
963 }
964 write!(f, "{}", segment.name)?;
965 if let Some(generic_args) = segment.args_and_bindings {
966 // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
967 // Do we actually format expressions?
968 write!(f, "<")?;
969 let mut first = true;
970 for arg in &generic_args.args {
971 if first {
972 first = false;
973 if generic_args.has_self_type {
974 // FIXME: Convert to `<Ty as Trait>` form.
975 write!(f, "Self = ")?;
976 }
977 } else {
978 write!(f, ", ")?;
979 }
980 arg.hir_fmt(f)?;
981 }
982 for binding in &generic_args.bindings {
983 if first {
984 first = false;
985 } else {
986 write!(f, ", ")?;
987 }
988 write!(f, "{}", binding.name)?;
989 match &binding.type_ref {
990 Some(ty) => {
991 write!(f, " = ")?;
992 ty.hir_fmt(f)?
993 }
994 None => {
995 write!(f, ": ")?;
996 f.write_joined(&binding.bounds, " + ")?;
997 }
998 }
999 }
1000 write!(f, ">")?;
1001 }
1002 }
1003 Ok(())
1004 }
1005}
1006
1007impl HirDisplay for GenericArg {
1008 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
1009 match self {
1010 GenericArg::Type(ty) => ty.hir_fmt(f),
1011 GenericArg::Lifetime(lifetime) => write!(f, "{}", lifetime.name),
1012 }
1013 }
1014}
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4d771a91e..9c385b845 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 to_assoc_type_id, AliasTy, Interner, TyKind,
45}; 46};
46 47
47pub(crate) use unify::unify; 48pub(crate) use unify::unify;
@@ -107,6 +108,17 @@ pub struct TypeMismatch {
107 pub actual: Ty, 108 pub actual: Ty,
108} 109}
109 110
111#[derive(Clone, PartialEq, Eq, Debug)]
112struct InternedStandardTypes {
113 unknown: Ty,
114}
115
116impl Default for InternedStandardTypes {
117 fn default() -> Self {
118 InternedStandardTypes { unknown: TyKind::Unknown.intern(&Interner) }
119 }
120}
121
110/// The result of type inference: A mapping from expressions and patterns to types. 122/// The result of type inference: A mapping from expressions and patterns to types.
111#[derive(Clone, PartialEq, Eq, Debug, Default)] 123#[derive(Clone, PartialEq, Eq, Debug, Default)]
112pub struct InferenceResult { 124pub struct InferenceResult {
@@ -125,6 +137,8 @@ pub struct InferenceResult {
125 pub type_of_expr: ArenaMap<ExprId, Ty>, 137 pub type_of_expr: ArenaMap<ExprId, Ty>,
126 pub type_of_pat: ArenaMap<PatId, Ty>, 138 pub type_of_pat: ArenaMap<PatId, Ty>,
127 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>, 139 pub(super) type_mismatches: ArenaMap<ExprId, TypeMismatch>,
140 /// Interned Unknown to return references to.
141 standard_types: InternedStandardTypes,
128} 142}
129 143
130impl InferenceResult { 144impl InferenceResult {
@@ -169,7 +183,7 @@ impl Index<ExprId> for InferenceResult {
169 type Output = Ty; 183 type Output = Ty;
170 184
171 fn index(&self, expr: ExprId) -> &Ty { 185 fn index(&self, expr: ExprId) -> &Ty {
172 self.type_of_expr.get(expr).unwrap_or(&Ty::Unknown) 186 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
173 } 187 }
174} 188}
175 189
@@ -177,7 +191,7 @@ impl Index<PatId> for InferenceResult {
177 type Output = Ty; 191 type Output = Ty;
178 192
179 fn index(&self, pat: PatId) -> &Ty { 193 fn index(&self, pat: PatId) -> &Ty {
180 self.type_of_pat.get(pat).unwrap_or(&Ty::Unknown) 194 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
181 } 195 }
182} 196}
183 197
@@ -226,8 +240,10 @@ impl<'a> InferenceContext<'a> {
226 result: InferenceResult::default(), 240 result: InferenceResult::default(),
227 table: unify::InferenceTable::new(), 241 table: unify::InferenceTable::new(),
228 obligations: Vec::default(), 242 obligations: Vec::default(),
229 return_ty: Ty::Unknown, // set in collect_fn_signature 243 return_ty: TyKind::Unknown.intern(&Interner), // set in collect_fn_signature
230 trait_env: TraitEnvironment::lower(db, &resolver), 244 trait_env: owner
245 .as_generic_def_id()
246 .map_or_else(Default::default, |d| db.trait_environment(d)),
231 db, 247 db,
232 owner, 248 owner,
233 body: db.body(owner), 249 body: db.body(owner),
@@ -237,15 +253,19 @@ impl<'a> InferenceContext<'a> {
237 } 253 }
238 } 254 }
239 255
256 fn err_ty(&self) -> Ty {
257 TyKind::Unknown.intern(&Interner)
258 }
259
240 fn resolve_all(mut self) -> InferenceResult { 260 fn resolve_all(mut self) -> InferenceResult {
241 // FIXME resolve obligations as well (use Guidance if necessary) 261 // FIXME resolve obligations as well (use Guidance if necessary)
242 let mut result = std::mem::take(&mut self.result); 262 let mut result = std::mem::take(&mut self.result);
243 for ty in result.type_of_expr.values_mut() { 263 for ty in result.type_of_expr.values_mut() {
244 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 264 let resolved = self.table.resolve_ty_completely(ty.clone());
245 *ty = resolved; 265 *ty = resolved;
246 } 266 }
247 for ty in result.type_of_pat.values_mut() { 267 for ty in result.type_of_pat.values_mut() {
248 let resolved = self.table.resolve_ty_completely(mem::replace(ty, Ty::Unknown)); 268 let resolved = self.table.resolve_ty_completely(ty.clone());
249 *ty = resolved; 269 *ty = resolved;
250 } 270 }
251 result 271 result
@@ -287,7 +307,7 @@ impl<'a> InferenceContext<'a> {
287 // FIXME use right resolver for block 307 // FIXME use right resolver for block
288 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 308 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
289 .with_impl_trait_mode(impl_trait_mode); 309 .with_impl_trait_mode(impl_trait_mode);
290 let ty = Ty::from_hir(&ctx, type_ref); 310 let ty = ctx.lower_ty(type_ref);
291 let ty = self.insert_type_vars(ty); 311 let ty = self.insert_type_vars(ty);
292 self.normalize_associated_types_in(ty) 312 self.normalize_associated_types_in(ty)
293 } 313 }
@@ -298,8 +318,8 @@ impl<'a> InferenceContext<'a> {
298 318
299 /// Replaces Ty::Unknown by a new type var, so we can maybe still infer it. 319 /// 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 { 320 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
301 match ty { 321 match ty.interned(&Interner) {
302 Ty::Unknown => self.table.new_type_var(), 322 TyKind::Unknown => self.table.new_type_var(),
303 _ => ty, 323 _ => ty,
304 } 324 }
305 } 325 }
@@ -377,13 +397,16 @@ impl<'a> InferenceContext<'a> {
377 let trait_ref = TraitRef { trait_, substs: substs.clone() }; 397 let trait_ref = TraitRef { trait_, substs: substs.clone() };
378 let projection = ProjectionPredicate { 398 let projection = ProjectionPredicate {
379 ty: ty.clone(), 399 ty: ty.clone(),
380 projection_ty: ProjectionTy { associated_ty: res_assoc_ty, parameters: substs }, 400 projection_ty: ProjectionTy {
401 associated_ty_id: to_assoc_type_id(res_assoc_ty),
402 substitution: substs,
403 },
381 }; 404 };
382 self.obligations.push(Obligation::Trait(trait_ref)); 405 self.obligations.push(Obligation::Trait(trait_ref));
383 self.obligations.push(Obligation::Projection(projection)); 406 self.obligations.push(Obligation::Projection(projection));
384 self.resolve_ty_as_possible(ty) 407 self.resolve_ty_as_possible(ty)
385 } 408 }
386 None => Ty::Unknown, 409 None => self.err_ty(),
387 } 410 }
388 } 411 }
389 412
@@ -395,8 +418,10 @@ impl<'a> InferenceContext<'a> {
395 /// to do it as well. 418 /// to do it as well.
396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 419 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
397 let ty = self.resolve_ty_as_possible(ty); 420 let ty = self.resolve_ty_as_possible(ty);
398 ty.fold(&mut |ty| match ty { 421 ty.fold(&mut |ty| match ty.interned(&Interner) {
399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty), 422 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
423 self.normalize_projection_ty(proj_ty.clone())
424 }
400 _ => ty, 425 _ => ty,
401 }) 426 })
402 } 427 }
@@ -412,7 +437,7 @@ impl<'a> InferenceContext<'a> {
412 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) { 437 fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option<VariantId>) {
413 let path = match path { 438 let path = match path {
414 Some(path) => path, 439 Some(path) => path,
415 None => return (Ty::Unknown, None), 440 None => return (self.err_ty(), None),
416 }; 441 };
417 let resolver = &self.resolver; 442 let resolver = &self.resolver;
418 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 443 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
@@ -421,30 +446,30 @@ impl<'a> InferenceContext<'a> {
421 let (resolution, unresolved) = 446 let (resolution, unresolved) =
422 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) { 447 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
423 Some(it) => it, 448 Some(it) => it,
424 None => return (Ty::Unknown, None), 449 None => return (self.err_ty(), None),
425 }; 450 };
426 return match resolution { 451 return match resolution {
427 TypeNs::AdtId(AdtId::StructId(strukt)) => { 452 TypeNs::AdtId(AdtId::StructId(strukt)) => {
428 let substs = Ty::substs_from_path(&ctx, path, strukt.into(), true); 453 let substs = ctx.substs_from_path(path, strukt.into(), true);
429 let ty = self.db.ty(strukt.into()); 454 let ty = self.db.ty(strukt.into());
430 let ty = self.insert_type_vars(ty.subst(&substs)); 455 let ty = self.insert_type_vars(ty.subst(&substs));
431 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved) 456 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
432 } 457 }
433 TypeNs::AdtId(AdtId::UnionId(u)) => { 458 TypeNs::AdtId(AdtId::UnionId(u)) => {
434 let substs = Ty::substs_from_path(&ctx, path, u.into(), true); 459 let substs = ctx.substs_from_path(path, u.into(), true);
435 let ty = self.db.ty(u.into()); 460 let ty = self.db.ty(u.into());
436 let ty = self.insert_type_vars(ty.subst(&substs)); 461 let ty = self.insert_type_vars(ty.subst(&substs));
437 forbid_unresolved_segments((ty, Some(u.into())), unresolved) 462 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
438 } 463 }
439 TypeNs::EnumVariantId(var) => { 464 TypeNs::EnumVariantId(var) => {
440 let substs = Ty::substs_from_path(&ctx, path, var.into(), true); 465 let substs = ctx.substs_from_path(path, var.into(), true);
441 let ty = self.db.ty(var.parent.into()); 466 let ty = self.db.ty(var.parent.into());
442 let ty = self.insert_type_vars(ty.subst(&substs)); 467 let ty = self.insert_type_vars(ty.subst(&substs));
443 forbid_unresolved_segments((ty, Some(var.into())), unresolved) 468 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
444 } 469 }
445 TypeNs::SelfType(impl_id) => { 470 TypeNs::SelfType(impl_id) => {
446 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 471 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
447 let substs = Substs::type_params_for_generics(&generics); 472 let substs = Substs::type_params_for_generics(self.db, &generics);
448 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 473 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
449 match unresolved { 474 match unresolved {
450 None => { 475 None => {
@@ -462,11 +487,11 @@ impl<'a> InferenceContext<'a> {
462 } 487 }
463 } 488 }
464 // FIXME potentially resolve assoc type 489 // FIXME potentially resolve assoc type
465 (Ty::Unknown, None) 490 (self.err_ty(), None)
466 } 491 }
467 Some(_) => { 492 Some(_) => {
468 // FIXME diagnostic 493 // FIXME diagnostic
469 (Ty::Unknown, None) 494 (self.err_ty(), None)
470 } 495 }
471 } 496 }
472 } 497 }
@@ -480,15 +505,15 @@ impl<'a> InferenceContext<'a> {
480 } 505 }
481 TypeNs::AdtSelfType(_) => { 506 TypeNs::AdtSelfType(_) => {
482 // FIXME this could happen in array size expressions, once we're checking them 507 // FIXME this could happen in array size expressions, once we're checking them
483 (Ty::Unknown, None) 508 (self.err_ty(), None)
484 } 509 }
485 TypeNs::GenericParam(_) => { 510 TypeNs::GenericParam(_) => {
486 // FIXME potentially resolve assoc type 511 // FIXME potentially resolve assoc type
487 (Ty::Unknown, None) 512 (self.err_ty(), None)
488 } 513 }
489 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => { 514 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
490 // FIXME diagnostic 515 // FIXME diagnostic
491 (Ty::Unknown, None) 516 (self.err_ty(), None)
492 } 517 }
493 }; 518 };
494 519
@@ -500,7 +525,7 @@ impl<'a> InferenceContext<'a> {
500 result 525 result
501 } else { 526 } else {
502 // FIXME diagnostic 527 // FIXME diagnostic
503 (Ty::Unknown, None) 528 (TyKind::Unknown.intern(&Interner), None)
504 } 529 }
505 } 530 }
506 531
@@ -529,7 +554,7 @@ impl<'a> InferenceContext<'a> {
529 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver) 554 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
530 .with_impl_trait_mode(ImplTraitLoweringMode::Param); 555 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
531 let param_tys = 556 let param_tys =
532 data.params.iter().map(|type_ref| Ty::from_hir(&ctx, type_ref)).collect::<Vec<_>>(); 557 data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
533 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) { 558 for (ty, pat) in param_tys.into_iter().zip(body.params.iter()) {
534 let ty = self.insert_type_vars(ty); 559 let ty = self.insert_type_vars(ty);
535 let ty = self.normalize_associated_types_in(ty); 560 let ty = self.normalize_associated_types_in(ty);
@@ -711,14 +736,19 @@ impl Expectation {
711 736
712 /// This expresses no expectation on the type. 737 /// This expresses no expectation on the type.
713 fn none() -> Self { 738 fn none() -> Self {
714 Expectation { ty: Ty::Unknown, rvalue_hint: false } 739 Expectation {
740 // FIXME
741 ty: TyKind::Unknown.intern(&Interner),
742 rvalue_hint: false,
743 }
715 } 744 }
716 745
717 fn coercion_target(&self) -> &Ty { 746 fn coercion_target(&self) -> Ty {
718 if self.rvalue_hint { 747 if self.rvalue_hint {
719 &Ty::Unknown 748 // FIXME
749 TyKind::Unknown.intern(&Interner)
720 } else { 750 } else {
721 &self.ty 751 self.ty.clone()
722 } 752 }
723 } 753 }
724} 754}
@@ -772,7 +802,7 @@ mod diagnostics {
772 802
773 #[derive(Debug, PartialEq, Eq, Clone)] 803 #[derive(Debug, PartialEq, Eq, Clone)]
774 pub(super) enum InferenceDiagnostic { 804 pub(super) enum InferenceDiagnostic {
775 NoSuchField { expr: ExprId, field: usize }, 805 NoSuchField { expr: ExprId },
776 BreakOutsideOfLoop { expr: ExprId }, 806 BreakOutsideOfLoop { expr: ExprId },
777 } 807 }
778 808
@@ -784,9 +814,9 @@ mod diagnostics {
784 sink: &mut DiagnosticSink, 814 sink: &mut DiagnosticSink,
785 ) { 815 ) {
786 match self { 816 match self {
787 InferenceDiagnostic::NoSuchField { expr, field } => { 817 InferenceDiagnostic::NoSuchField { expr } => {
788 let (_, source_map) = db.body_with_source_map(owner); 818 let (_, source_map) = db.body_with_source_map(owner);
789 let field = source_map.field_syntax(*expr, *field); 819 let field = source_map.field_syntax(*expr);
790 sink.push(NoSuchField { file: field.file_id, field: field.value }) 820 sink.push(NoSuchField { file: field.file_id, field: field.value })
791 } 821 }
792 InferenceDiagnostic::BreakOutsideOfLoop { expr } => { 822 InferenceDiagnostic::BreakOutsideOfLoop { expr } => {
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 7e8846f27..137419264 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 (from_ty.interned_mut(), 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,9 @@ 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)) => self.unify_autoderef_behind_ref(st1, st2),
113 115
114 // Otherwise, normal unify 116 // Otherwise, normal unify
115 _ => self.unify(&from_ty, to_ty), 117 _ => self.unify(&from_ty, to_ty),
@@ -174,11 +176,7 @@ impl<'a> InferenceContext<'a> {
174 // Stop when constructor matches. 176 // Stop when constructor matches.
175 if from_ty.equals_ctor(&to_ty) { 177 if from_ty.equals_ctor(&to_ty) {
176 // It will not recurse to `coerce`. 178 // It will not recurse to `coerce`.
177 return match (from_ty.substs(), to_ty.substs()) { 179 return self.table.unify(&from_ty, &to_ty);
178 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
179 (None, None) => true,
180 _ => false,
181 };
182 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 180 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
183 return true; 181 return true;
184 } 182 }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 262177ffb..f40dec17f 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,10 +18,11 @@ use crate::{
18 lower::lower_to_chalk_mutability, 18 lower::lower_to_chalk_mutability,
19 method_resolution, op, 19 method_resolution, op,
20 primitive::{self, UintTy}, 20 primitive::{self, UintTy},
21 traits::{FnTrait, InEnvironment}, 21 to_assoc_type_id,
22 traits::{chalk::from_chalk, FnTrait, InEnvironment},
22 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
23 AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, 24 AdtId, Binders, CallableDefId, FnPointer, FnSig, Interner, Obligation, Rawness, Scalar, Substs,
24 Substs, TraitRef, Ty, 25 TraitRef, Ty, TyKind,
25}; 26};
26 27
27use super::{ 28use super::{
@@ -57,7 +58,7 @@ impl<'a> InferenceContext<'a> {
57 // Return actual type when type mismatch. 58 // Return actual type when type mismatch.
58 // This is needed for diagnostic when return type mismatch. 59 // This is needed for diagnostic when return type mismatch.
59 ty 60 ty
60 } else if expected.coercion_target() == &Ty::Unknown { 61 } else if expected.coercion_target().is_unknown() {
61 ty 62 ty
62 } else { 63 } else {
63 expected.ty.clone() 64 expected.ty.clone()
@@ -84,7 +85,7 @@ impl<'a> InferenceContext<'a> {
84 arg_tys.push(arg); 85 arg_tys.push(arg);
85 } 86 }
86 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
87 let arg_ty = Ty::Tuple(num_args, parameters); 88 let arg_ty = TyKind::Tuple(num_args, parameters).intern(&Interner);
88 let substs = 89 let substs =
89 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
90 91
@@ -97,8 +98,10 @@ impl<'a> InferenceContext<'a> {
97 }); 98 });
98 if self.db.trait_solve(krate, goal.value).is_some() { 99 if self.db.trait_solve(krate, goal.value).is_some() {
99 self.obligations.push(implements_fn_trait); 100 self.obligations.push(implements_fn_trait);
100 let output_proj_ty = 101 let output_proj_ty = crate::ProjectionTy {
101 crate::ProjectionTy { associated_ty: output_assoc_type, parameters: substs }; 102 associated_ty_id: to_assoc_type_id(output_assoc_type),
103 substitution: substs,
104 };
102 let return_ty = self.normalize_projection_ty(output_proj_ty); 105 let return_ty = self.normalize_projection_ty(output_proj_ty);
103 Some((arg_tys, return_ty)) 106 Some((arg_tys, return_ty))
104 } else { 107 } else {
@@ -116,10 +119,13 @@ impl<'a> InferenceContext<'a> {
116 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { 119 fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
117 let body = Arc::clone(&self.body); // avoid borrow checker problem 120 let body = Arc::clone(&self.body); // avoid borrow checker problem
118 let ty = match &body[tgt_expr] { 121 let ty = match &body[tgt_expr] {
119 Expr::Missing => Ty::Unknown, 122 Expr::Missing => self.err_ty(),
120 Expr::If { condition, then_branch, else_branch } => { 123 Expr::If { condition, then_branch, else_branch } => {
121 // if let is desugared to match, so this is always simple if 124 // if let is desugared to match, so this is always simple if
122 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); 125 self.infer_expr(
126 *condition,
127 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
128 );
123 129
124 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 130 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
125 let mut both_arms_diverge = Diverges::Always; 131 let mut both_arms_diverge = Diverges::Always;
@@ -167,14 +173,15 @@ impl<'a> InferenceContext<'a> {
167 Expr::TryBlock { body } => { 173 Expr::TryBlock { body } => {
168 let _inner = self.infer_expr(*body, expected); 174 let _inner = self.infer_expr(*body, expected);
169 // FIXME should be std::result::Result<{inner}, _> 175 // FIXME should be std::result::Result<{inner}, _>
170 Ty::Unknown 176 self.err_ty()
171 } 177 }
172 Expr::Async { body } => { 178 Expr::Async { body } => {
173 // Use the first type parameter as the output type of future. 179 // Use the first type parameter as the output type of future.
174 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 180 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
175 let inner_ty = self.infer_expr(*body, &Expectation::none()); 181 let inner_ty = self.infer_expr(*body, &Expectation::none());
176 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 182 let impl_trait_id = crate::ImplTraitId::AsyncBlockTypeImplTrait(self.owner, *body);
177 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) 183 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
184 TyKind::OpaqueType(opaque_ty_id, Substs::single(inner_ty)).intern(&Interner)
178 } 185 }
179 Expr::Loop { body, label } => { 186 Expr::Loop { body, label } => {
180 self.breakables.push(BreakableContext { 187 self.breakables.push(BreakableContext {
@@ -192,17 +199,20 @@ impl<'a> InferenceContext<'a> {
192 if ctxt.may_break { 199 if ctxt.may_break {
193 ctxt.break_ty 200 ctxt.break_ty
194 } else { 201 } else {
195 Ty::Never 202 TyKind::Never.intern(&Interner)
196 } 203 }
197 } 204 }
198 Expr::While { condition, body, label } => { 205 Expr::While { condition, body, label } => {
199 self.breakables.push(BreakableContext { 206 self.breakables.push(BreakableContext {
200 may_break: false, 207 may_break: false,
201 break_ty: Ty::Unknown, 208 break_ty: self.err_ty(),
202 label: label.map(|label| self.body[label].name.clone()), 209 label: label.map(|label| self.body[label].name.clone()),
203 }); 210 });
204 // while let is desugared to a match loop, so this is always simple while 211 // 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))); 212 self.infer_expr(
213 *condition,
214 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
215 );
206 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 216 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
207 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 217 let _ctxt = self.breakables.pop().expect("breakable stack broken");
208 // the body may not run, so it diverging doesn't mean we diverge 218 // the body may not run, so it diverging doesn't mean we diverge
@@ -214,7 +224,7 @@ impl<'a> InferenceContext<'a> {
214 224
215 self.breakables.push(BreakableContext { 225 self.breakables.push(BreakableContext {
216 may_break: false, 226 may_break: false,
217 break_ty: Ty::Unknown, 227 break_ty: self.err_ty(),
218 label: label.map(|label| self.body[label].name.clone()), 228 label: label.map(|label| self.body[label].name.clone()),
219 }); 229 });
220 let pat_ty = 230 let pat_ty =
@@ -249,12 +259,15 @@ impl<'a> InferenceContext<'a> {
249 None => self.table.new_type_var(), 259 None => self.table.new_type_var(),
250 }; 260 };
251 sig_tys.push(ret_ty.clone()); 261 sig_tys.push(ret_ty.clone());
252 let sig_ty = Ty::Function(FnPointer { 262 let sig_ty = TyKind::Function(FnPointer {
253 num_args: sig_tys.len() - 1, 263 num_args: sig_tys.len() - 1,
254 sig: FnSig { variadic: false }, 264 sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
255 substs: Substs(sig_tys.clone().into()), 265 substs: Substs(sig_tys.clone().into()),
256 }); 266 })
257 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty)); 267 .intern(&Interner);
268 let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
269 let closure_ty =
270 TyKind::Closure(closure_id, Substs::single(sig_ty)).intern(&Interner);
258 271
259 // Eagerly try to relate the closure type with the expected 272 // Eagerly try to relate the closure type with the expected
260 // type, otherwise we often won't have enough information to 273 // type, otherwise we often won't have enough information to
@@ -295,7 +308,7 @@ impl<'a> InferenceContext<'a> {
295 args.len(), 308 args.len(),
296 ) 309 )
297 }) 310 })
298 .unwrap_or((Vec::new(), Ty::Unknown)); 311 .unwrap_or((Vec::new(), self.err_ty()));
299 self.register_obligations_for_call(&callee_ty); 312 self.register_obligations_for_call(&callee_ty);
300 self.check_call_arguments(args, &param_tys); 313 self.check_call_arguments(args, &param_tys);
301 self.normalize_associated_types_in(ret_ty) 314 self.normalize_associated_types_in(ret_ty)
@@ -305,8 +318,11 @@ impl<'a> InferenceContext<'a> {
305 Expr::Match { expr, arms } => { 318 Expr::Match { expr, arms } => {
306 let input_ty = self.infer_expr(*expr, &Expectation::none()); 319 let input_ty = self.infer_expr(*expr, &Expectation::none());
307 320
308 let mut result_ty = 321 let mut result_ty = if arms.is_empty() {
309 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; 322 TyKind::Never.intern(&Interner)
323 } else {
324 self.table.new_type_var()
325 };
310 326
311 let matchee_diverges = self.diverges; 327 let matchee_diverges = self.diverges;
312 let mut all_arms_diverge = Diverges::Always; 328 let mut all_arms_diverge = Diverges::Always;
@@ -317,7 +333,7 @@ impl<'a> InferenceContext<'a> {
317 if let Some(guard_expr) = arm.guard { 333 if let Some(guard_expr) = arm.guard {
318 self.infer_expr( 334 self.infer_expr(
319 guard_expr, 335 guard_expr,
320 &Expectation::has_type(Ty::Scalar(Scalar::Bool)), 336 &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner)),
321 ); 337 );
322 } 338 }
323 339
@@ -333,9 +349,9 @@ impl<'a> InferenceContext<'a> {
333 Expr::Path(p) => { 349 Expr::Path(p) => {
334 // FIXME this could be more efficient... 350 // FIXME this could be more efficient...
335 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 351 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) 352 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(self.err_ty())
337 } 353 }
338 Expr::Continue { .. } => Ty::Never, 354 Expr::Continue { .. } => TyKind::Never.intern(&Interner),
339 Expr::Break { expr, label } => { 355 Expr::Break { expr, label } => {
340 let val_ty = if let Some(expr) = expr { 356 let val_ty = if let Some(expr) = expr {
341 self.infer_expr(*expr, &Expectation::none()) 357 self.infer_expr(*expr, &Expectation::none())
@@ -347,7 +363,7 @@ impl<'a> InferenceContext<'a> {
347 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) { 363 if let Some(ctxt) = find_breakable(&mut self.breakables, label.as_ref()) {
348 ctxt.break_ty.clone() 364 ctxt.break_ty.clone()
349 } else { 365 } else {
350 Ty::Unknown 366 self.err_ty()
351 }; 367 };
352 368
353 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty); 369 let merged_type = self.coerce_merge_branch(&last_ty, &val_ty);
@@ -360,7 +376,7 @@ impl<'a> InferenceContext<'a> {
360 expr: tgt_expr, 376 expr: tgt_expr,
361 }); 377 });
362 } 378 }
363 Ty::Never 379 TyKind::Never.intern(&Interner)
364 } 380 }
365 Expr::Return { expr } => { 381 Expr::Return { expr } => {
366 if let Some(expr) = expr { 382 if let Some(expr) = expr {
@@ -369,14 +385,14 @@ impl<'a> InferenceContext<'a> {
369 let unit = Ty::unit(); 385 let unit = Ty::unit();
370 self.coerce(&unit, &self.return_ty.clone()); 386 self.coerce(&unit, &self.return_ty.clone());
371 } 387 }
372 Ty::Never 388 TyKind::Never.intern(&Interner)
373 } 389 }
374 Expr::Yield { expr } => { 390 Expr::Yield { expr } => {
375 // FIXME: track yield type for coercion 391 // FIXME: track yield type for coercion
376 if let Some(expr) = expr { 392 if let Some(expr) = expr {
377 self.infer_expr(*expr, &Expectation::none()); 393 self.infer_expr(*expr, &Expectation::none());
378 } 394 }
379 Ty::Never 395 TyKind::Never.intern(&Interner)
380 } 396 }
381 Expr::RecordLit { path, fields, spread } => { 397 Expr::RecordLit { path, fields, spread } => {
382 let (ty, def_id) = self.resolve_variant(path.as_ref()); 398 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -389,14 +405,13 @@ impl<'a> InferenceContext<'a> {
389 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); 405 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
390 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 406 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
391 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 407 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
392 for (field_idx, field) in fields.iter().enumerate() { 408 for field in fields.iter() {
393 let field_def = 409 let field_def =
394 variant_data.as_ref().and_then(|it| match it.field(&field.name) { 410 variant_data.as_ref().and_then(|it| match it.field(&field.name) {
395 Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }), 411 Some(local_id) => Some(FieldId { parent: def_id.unwrap(), local_id }),
396 None => { 412 None => {
397 self.push_diagnostic(InferenceDiagnostic::NoSuchField { 413 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
398 expr: tgt_expr, 414 expr: field.expr,
399 field: field_idx,
400 }); 415 });
401 None 416 None
402 } 417 }
@@ -404,8 +419,9 @@ impl<'a> InferenceContext<'a> {
404 if let Some(field_def) = field_def { 419 if let Some(field_def) = field_def {
405 self.result.record_field_resolutions.insert(field.expr, field_def); 420 self.result.record_field_resolutions.insert(field.expr, field_def);
406 } 421 }
407 let field_ty = field_def 422 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)); 423 field_types[it.local_id].clone().subst(&substs)
424 });
409 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty)); 425 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_ty));
410 } 426 }
411 if let Some(expr) = spread { 427 if let Some(expr) = spread {
@@ -424,27 +440,33 @@ impl<'a> InferenceContext<'a> {
424 environment: self.trait_env.clone(), 440 environment: self.trait_env.clone(),
425 }, 441 },
426 ) 442 )
427 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 443 .find_map(|derefed_ty| {
428 Ty::Tuple(_, substs) => { 444 match canonicalized.decanonicalize_ty(derefed_ty.value).interned(&Interner) {
429 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) 445 TyKind::Tuple(_, substs) => {
430 } 446 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
431 Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { 447 }
432 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 448 TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
433 let field = FieldId { parent: s.into(), local_id }; 449 self.db.struct_data(*s).variant_data.field(name).map(|local_id| {
434 self.write_field_resolution(tgt_expr, field); 450 let field = FieldId { parent: (*s).into(), local_id };
435 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters) 451 self.write_field_resolution(tgt_expr, field);
436 }) 452 self.db.field_types((*s).into())[field.local_id]
437 } 453 .clone()
438 Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => { 454 .subst(&parameters)
439 self.db.union_data(u).variant_data.field(name).map(|local_id| { 455 })
440 let field = FieldId { parent: u.into(), local_id }; 456 }
441 self.write_field_resolution(tgt_expr, field); 457 TyKind::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
442 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters) 458 self.db.union_data(*u).variant_data.field(name).map(|local_id| {
443 }) 459 let field = FieldId { parent: (*u).into(), local_id };
460 self.write_field_resolution(tgt_expr, field);
461 self.db.field_types((*u).into())[field.local_id]
462 .clone()
463 .subst(&parameters)
464 })
465 }
466 _ => None,
444 } 467 }
445 _ => None,
446 }) 468 })
447 .unwrap_or(Ty::Unknown); 469 .unwrap_or(self.err_ty());
448 let ty = self.insert_type_vars(ty); 470 let ty = self.insert_type_vars(ty);
449 self.normalize_associated_types_in(ty) 471 self.normalize_associated_types_in(ty)
450 } 472 }
@@ -481,9 +503,10 @@ impl<'a> InferenceContext<'a> {
481 }; 503 };
482 let inner_ty = self.infer_expr_inner(*expr, &expectation); 504 let inner_ty = self.infer_expr_inner(*expr, &expectation);
483 match rawness { 505 match rawness {
484 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), 506 Rawness::RawPtr => TyKind::Raw(mutability, inner_ty),
485 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), 507 Rawness::Ref => TyKind::Ref(mutability, inner_ty),
486 } 508 }
509 .intern(&Interner)
487 } 510 }
488 Expr::Box { expr } => { 511 Expr::Box { expr } => {
489 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 512 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
@@ -499,7 +522,7 @@ impl<'a> InferenceContext<'a> {
499 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 522 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
500 Ty::adt_ty(box_, sb.build()) 523 Ty::adt_ty(box_, sb.build())
501 } else { 524 } else {
502 Ty::Unknown 525 self.err_ty()
503 } 526 }
504 } 527 }
505 Expr::UnaryOp { expr, op } => { 528 Expr::UnaryOp { expr, op } => {
@@ -519,31 +542,31 @@ impl<'a> InferenceContext<'a> {
519 Some(derefed_ty) => { 542 Some(derefed_ty) => {
520 canonicalized.decanonicalize_ty(derefed_ty.value) 543 canonicalized.decanonicalize_ty(derefed_ty.value)
521 } 544 }
522 None => Ty::Unknown, 545 None => self.err_ty(),
523 } 546 }
524 } 547 }
525 None => Ty::Unknown, 548 None => self.err_ty(),
526 }, 549 },
527 UnaryOp::Neg => { 550 UnaryOp::Neg => {
528 match &inner_ty { 551 match inner_ty.interned(&Interner) {
529 // Fast path for builtins 552 // Fast path for builtins
530 Ty::Scalar(Scalar::Int(_)) 553 TyKind::Scalar(Scalar::Int(_))
531 | Ty::Scalar(Scalar::Uint(_)) 554 | TyKind::Scalar(Scalar::Uint(_))
532 | Ty::Scalar(Scalar::Float(_)) 555 | TyKind::Scalar(Scalar::Float(_))
533 | Ty::InferenceVar(_, TyVariableKind::Integer) 556 | TyKind::InferenceVar(_, TyVariableKind::Integer)
534 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, 557 | TyKind::InferenceVar(_, TyVariableKind::Float) => inner_ty,
535 // Otherwise we resolve via the std::ops::Neg trait 558 // Otherwise we resolve via the std::ops::Neg trait
536 _ => self 559 _ => self
537 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 560 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
538 } 561 }
539 } 562 }
540 UnaryOp::Not => { 563 UnaryOp::Not => {
541 match &inner_ty { 564 match inner_ty.interned(&Interner) {
542 // Fast path for builtins 565 // Fast path for builtins
543 Ty::Scalar(Scalar::Bool) 566 TyKind::Scalar(Scalar::Bool)
544 | Ty::Scalar(Scalar::Int(_)) 567 | TyKind::Scalar(Scalar::Int(_))
545 | Ty::Scalar(Scalar::Uint(_)) 568 | TyKind::Scalar(Scalar::Uint(_))
546 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, 569 | TyKind::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
547 // Otherwise we resolve via the std::ops::Not trait 570 // Otherwise we resolve via the std::ops::Not trait
548 _ => self 571 _ => self
549 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 572 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -554,7 +577,9 @@ impl<'a> InferenceContext<'a> {
554 Expr::BinaryOp { lhs, rhs, op } => match op { 577 Expr::BinaryOp { lhs, rhs, op } => match op {
555 Some(op) => { 578 Some(op) => {
556 let lhs_expectation = match op { 579 let lhs_expectation = match op {
557 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), 580 BinaryOp::LogicOp(..) => {
581 Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(&Interner))
582 }
558 _ => Expectation::none(), 583 _ => Expectation::none(),
559 }; 584 };
560 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 585 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -563,7 +588,7 @@ impl<'a> InferenceContext<'a> {
563 588
564 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 589 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
565 590
566 if ret == Ty::Unknown { 591 if ret.is_unknown() {
567 cov_mark::hit!(infer_expr_inner_binary_operator_overload); 592 cov_mark::hit!(infer_expr_inner_binary_operator_overload);
568 593
569 self.resolve_associated_type_with_params( 594 self.resolve_associated_type_with_params(
@@ -575,7 +600,7 @@ impl<'a> InferenceContext<'a> {
575 ret 600 ret
576 } 601 }
577 } 602 }
578 _ => Ty::Unknown, 603 _ => self.err_ty(),
579 }, 604 },
580 Expr::Range { lhs, rhs, range_type } => { 605 Expr::Range { lhs, rhs, range_type } => {
581 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none())); 606 let lhs_ty = lhs.map(|e| self.infer_expr_inner(e, &Expectation::none()));
@@ -586,33 +611,33 @@ impl<'a> InferenceContext<'a> {
586 match (range_type, lhs_ty, rhs_ty) { 611 match (range_type, lhs_ty, rhs_ty) {
587 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 612 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
588 Some(adt) => Ty::adt_ty(adt, Substs::empty()), 613 Some(adt) => Ty::adt_ty(adt, Substs::empty()),
589 None => Ty::Unknown, 614 None => self.err_ty(),
590 }, 615 },
591 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 616 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
592 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 617 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
593 None => Ty::Unknown, 618 None => self.err_ty(),
594 }, 619 },
595 (RangeOp::Inclusive, None, Some(ty)) => { 620 (RangeOp::Inclusive, None, Some(ty)) => {
596 match self.resolve_range_to_inclusive() { 621 match self.resolve_range_to_inclusive() {
597 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 622 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
598 None => Ty::Unknown, 623 None => self.err_ty(),
599 } 624 }
600 } 625 }
601 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 626 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
602 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 627 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
603 None => Ty::Unknown, 628 None => self.err_ty(),
604 }, 629 },
605 (RangeOp::Inclusive, Some(_), Some(ty)) => { 630 (RangeOp::Inclusive, Some(_), Some(ty)) => {
606 match self.resolve_range_inclusive() { 631 match self.resolve_range_inclusive() {
607 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 632 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
608 None => Ty::Unknown, 633 None => self.err_ty(),
609 } 634 }
610 } 635 }
611 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 636 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
612 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)), 637 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
613 None => Ty::Unknown, 638 None => self.err_ty(),
614 }, 639 },
615 (RangeOp::Inclusive, _, None) => Ty::Unknown, 640 (RangeOp::Inclusive, _, None) => self.err_ty(),
616 } 641 }
617 } 642 }
618 Expr::Index { base, index } => { 643 Expr::Index { base, index } => {
@@ -631,19 +656,19 @@ impl<'a> InferenceContext<'a> {
631 index_trait, 656 index_trait,
632 ); 657 );
633 let self_ty = 658 let self_ty =
634 self_ty.map_or(Ty::Unknown, |t| canonicalized.decanonicalize_ty(t.value)); 659 self_ty.map_or(self.err_ty(), |t| canonicalized.decanonicalize_ty(t.value));
635 self.resolve_associated_type_with_params( 660 self.resolve_associated_type_with_params(
636 self_ty, 661 self_ty,
637 self.resolve_ops_index_output(), 662 self.resolve_ops_index_output(),
638 &[index_ty], 663 &[index_ty],
639 ) 664 )
640 } else { 665 } else {
641 Ty::Unknown 666 self.err_ty()
642 } 667 }
643 } 668 }
644 Expr::Tuple { exprs } => { 669 Expr::Tuple { exprs } => {
645 let mut tys = match &expected.ty { 670 let mut tys = match expected.ty.interned(&Interner) {
646 Ty::Tuple(_, substs) => substs 671 TyKind::Tuple(_, substs) => substs
647 .iter() 672 .iter()
648 .cloned() 673 .cloned()
649 .chain(repeat_with(|| self.table.new_type_var())) 674 .chain(repeat_with(|| self.table.new_type_var()))
@@ -656,11 +681,11 @@ impl<'a> InferenceContext<'a> {
656 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 681 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
657 } 682 }
658 683
659 Ty::Tuple(tys.len(), Substs(tys.into())) 684 TyKind::Tuple(tys.len(), Substs(tys.into())).intern(&Interner)
660 } 685 }
661 Expr::Array(array) => { 686 Expr::Array(array) => {
662 let elem_ty = match &expected.ty { 687 let elem_ty = match expected.ty.interned(&Interner) {
663 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), 688 TyKind::Array(st) | TyKind::Slice(st) => st.clone(),
664 _ => self.table.new_type_var(), 689 _ => self.table.new_type_var(),
665 }; 690 };
666 691
@@ -677,43 +702,50 @@ impl<'a> InferenceContext<'a> {
677 ); 702 );
678 self.infer_expr( 703 self.infer_expr(
679 *repeat, 704 *repeat,
680 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), 705 &Expectation::has_type(
706 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
707 ),
681 ); 708 );
682 } 709 }
683 } 710 }
684 711
685 Ty::Array(Substs::single(elem_ty)) 712 TyKind::Array(elem_ty).intern(&Interner)
686 } 713 }
687 Expr::Literal(lit) => match lit { 714 Expr::Literal(lit) => match lit {
688 Literal::Bool(..) => Ty::Scalar(Scalar::Bool), 715 Literal::Bool(..) => TyKind::Scalar(Scalar::Bool).intern(&Interner),
689 Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), 716 Literal::String(..) => {
717 TyKind::Ref(Mutability::Not, TyKind::Str.intern(&Interner)).intern(&Interner)
718 }
690 Literal::ByteString(..) => { 719 Literal::ByteString(..) => {
691 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); 720 let byte_type = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(&Interner);
692 let array_type = Ty::Array(Substs::single(byte_type)); 721 let array_type = TyKind::Array(byte_type).intern(&Interner);
693 Ty::Ref(Mutability::Not, Substs::single(array_type)) 722 TyKind::Ref(Mutability::Not, array_type).intern(&Interner)
694 } 723 }
695 Literal::Char(..) => Ty::Scalar(Scalar::Char), 724 Literal::Char(..) => TyKind::Scalar(Scalar::Char).intern(&Interner),
696 Literal::Int(_v, ty) => match ty { 725 Literal::Int(_v, ty) => match ty {
697 Some(int_ty) => { 726 Some(int_ty) => {
698 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty))) 727 TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
728 .intern(&Interner)
699 } 729 }
700 None => self.table.new_integer_var(), 730 None => self.table.new_integer_var(),
701 }, 731 },
702 Literal::Uint(_v, ty) => match ty { 732 Literal::Uint(_v, ty) => match ty {
703 Some(int_ty) => { 733 Some(int_ty) => {
704 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty))) 734 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
735 .intern(&Interner)
705 } 736 }
706 None => self.table.new_integer_var(), 737 None => self.table.new_integer_var(),
707 }, 738 },
708 Literal::Float(_v, ty) => match ty { 739 Literal::Float(_v, ty) => match ty {
709 Some(float_ty) => { 740 Some(float_ty) => {
710 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty))) 741 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
742 .intern(&Interner)
711 } 743 }
712 None => self.table.new_float_var(), 744 None => self.table.new_float_var(),
713 }, 745 },
714 }, 746 },
715 }; 747 };
716 // use a new type variable if we got Ty::Unknown here 748 // use a new type variable if we got unknown here
717 let ty = self.insert_type_vars_shallow(ty); 749 let ty = self.insert_type_vars_shallow(ty);
718 let ty = self.resolve_ty_as_possible(ty); 750 let ty = self.resolve_ty_as_possible(ty);
719 self.write_expr_ty(tgt_expr, ty.clone()); 751 self.write_expr_ty(tgt_expr, ty.clone());
@@ -730,7 +762,7 @@ impl<'a> InferenceContext<'a> {
730 match stmt { 762 match stmt {
731 Statement::Let { pat, type_ref, initializer } => { 763 Statement::Let { pat, type_ref, initializer } => {
732 let decl_ty = 764 let decl_ty =
733 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(Ty::Unknown); 765 type_ref.as_ref().map(|tr| self.make_ty(tr)).unwrap_or(self.err_ty());
734 766
735 // Always use the declared type when specified 767 // Always use the declared type when specified
736 let mut ty = decl_ty.clone(); 768 let mut ty = decl_ty.clone();
@@ -738,7 +770,7 @@ impl<'a> InferenceContext<'a> {
738 if let Some(expr) = initializer { 770 if let Some(expr) = initializer {
739 let actual_ty = 771 let actual_ty =
740 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone())); 772 self.infer_expr_coerce(*expr, &Expectation::has_type(decl_ty.clone()));
741 if decl_ty == Ty::Unknown { 773 if decl_ty.is_unknown() {
742 ty = actual_ty; 774 ty = actual_ty;
743 } 775 }
744 } 776 }
@@ -766,7 +798,7 @@ impl<'a> InferenceContext<'a> {
766 // we don't even make an attempt at coercion 798 // we don't even make an attempt at coercion
767 self.table.new_maybe_never_var() 799 self.table.new_maybe_never_var()
768 } else { 800 } else {
769 self.coerce(&Ty::unit(), expected.coercion_target()); 801 self.coerce(&Ty::unit(), &expected.coercion_target());
770 Ty::unit() 802 Ty::unit()
771 } 803 }
772 }; 804 };
@@ -802,7 +834,7 @@ impl<'a> InferenceContext<'a> {
802 self.write_method_resolution(tgt_expr, func); 834 self.write_method_resolution(tgt_expr, func);
803 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into()))) 835 (ty, self.db.value_ty(func.into()), Some(generics(self.db.upcast(), func.into())))
804 } 836 }
805 None => (receiver_ty, Binders::new(0, Ty::Unknown), None), 837 None => (receiver_ty, Binders::new(0, self.err_ty()), None),
806 }; 838 };
807 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty); 839 let substs = self.substs_for_method_call(def_generics, generic_args, &derefed_receiver_ty);
808 let method_ty = method_ty.subst(&substs); 840 let method_ty = method_ty.subst(&substs);
@@ -813,15 +845,15 @@ impl<'a> InferenceContext<'a> {
813 if !sig.params().is_empty() { 845 if !sig.params().is_empty() {
814 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone()) 846 (sig.params()[0].clone(), sig.params()[1..].to_vec(), sig.ret().clone())
815 } else { 847 } else {
816 (Ty::Unknown, Vec::new(), sig.ret().clone()) 848 (self.err_ty(), Vec::new(), sig.ret().clone())
817 } 849 }
818 } 850 }
819 None => (Ty::Unknown, Vec::new(), Ty::Unknown), 851 None => (self.err_ty(), Vec::new(), self.err_ty()),
820 }; 852 };
821 // Apply autoref so the below unification works correctly 853 // Apply autoref so the below unification works correctly
822 // FIXME: return correct autorefs from lookup_method 854 // FIXME: return correct autorefs from lookup_method
823 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 855 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
824 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), 856 Some((_, mutability)) => TyKind::Ref(mutability, derefed_receiver_ty).intern(&Interner),
825 _ => derefed_receiver_ty, 857 _ => derefed_receiver_ty,
826 }; 858 };
827 self.unify(&expected_receiver_ty, &actual_receiver_ty); 859 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -837,7 +869,7 @@ impl<'a> InferenceContext<'a> {
837 // that we have more information about the types of arguments when we 869 // 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. 870 // type-check the functions. This isn't really the right way to do this.
839 for &check_closures in &[false, true] { 871 for &check_closures in &[false, true] {
840 let param_iter = param_tys.iter().cloned().chain(repeat(Ty::Unknown)); 872 let param_iter = param_tys.iter().cloned().chain(repeat(self.err_ty()));
841 for (&arg, param_ty) in args.iter().zip(param_iter) { 873 for (&arg, param_ty) in args.iter().zip(param_iter) {
842 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. }); 874 let is_closure = matches!(&self.body[arg], Expr::Lambda { .. });
843 if is_closure != check_closures { 875 if is_closure != check_closures {
@@ -867,7 +899,7 @@ impl<'a> InferenceContext<'a> {
867 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf { 899 if param.provenance == hir_def::generics::TypeParamProvenance::TraitSelf {
868 substs.push(receiver_ty.clone()); 900 substs.push(receiver_ty.clone());
869 } else { 901 } else {
870 substs.push(Ty::Unknown); 902 substs.push(self.err_ty());
871 } 903 }
872 } 904 }
873 } 905 }
@@ -891,14 +923,15 @@ impl<'a> InferenceContext<'a> {
891 }; 923 };
892 let supplied_params = substs.len(); 924 let supplied_params = substs.len();
893 for _ in supplied_params..total_len { 925 for _ in supplied_params..total_len {
894 substs.push(Ty::Unknown); 926 substs.push(self.err_ty());
895 } 927 }
896 assert_eq!(substs.len(), total_len); 928 assert_eq!(substs.len(), total_len);
897 Substs(substs.into()) 929 Substs(substs.into())
898 } 930 }
899 931
900 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 932 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
901 if let &Ty::FnDef(def, ref parameters) = callable_ty { 933 if let TyKind::FnDef(fn_def, parameters) = callable_ty.interned(&Interner) {
934 let def: CallableDefId = from_chalk(self.db, *fn_def);
902 let generic_predicates = self.db.generic_predicates(def.into()); 935 let generic_predicates = self.db.generic_predicates(def.into());
903 for predicate in generic_predicates.iter() { 936 for predicate in generic_predicates.iter() {
904 let predicate = predicate.clone().subst(parameters); 937 let predicate = predicate.clone().subst(parameters);
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index a0ac8d80f..9e8ca18ef 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 } => {
@@ -157,12 +158,12 @@ impl<'a> InferenceContext<'a> {
157 if mutability != exp_mut { 158 if mutability != exp_mut {
158 // FIXME: emit type error? 159 // FIXME: emit type error?
159 } 160 }
160 inner_ty 161 inner_ty.clone()
161 } 162 }
162 _ => &Ty::Unknown, 163 _ => self.result.standard_types.unknown.clone(),
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, 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, 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.clone()),
209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()), 210 TyKind::Slice(st) => (TyKind::Slice, st.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(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 }
@@ -231,21 +232,21 @@ impl<'a> InferenceContext<'a> {
231 Pat::Box { inner } => match self.resolve_boxed_box() { 232 Pat::Box { inner } => match self.resolve_boxed_box() {
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().clone(),
235 _ => &Ty::Unknown, 236 _ => self.result.standard_types.unknown.clone(),
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..af108fb6c 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
@@ -40,7 +40,7 @@ impl<'a> InferenceContext<'a> {
40 let ty = self.make_ty(type_ref); 40 let ty = self.make_ty(type_ref);
41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1); 41 let remaining_segments_for_ty = path.segments().take(path.segments().len() - 1);
42 let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver); 42 let ctx = crate::lower::TyLoweringContext::new(self.db, &resolver);
43 let (ty, _) = Ty::from_type_relative_path(&ctx, ty, None, remaining_segments_for_ty); 43 let (ty, _) = ctx.lower_ty_relative_path(ty, None, remaining_segments_for_ty);
44 self.resolve_ty_assoc_item( 44 self.resolve_ty_assoc_item(
45 ty, 45 ty,
46 &path.segments().last().expect("path had at least one segment").name, 46 &path.segments().last().expect("path had at least one segment").name,
@@ -79,7 +79,7 @@ impl<'a> InferenceContext<'a> {
79 } 79 }
80 ValueNs::ImplSelf(impl_id) => { 80 ValueNs::ImplSelf(impl_id) => {
81 let generics = crate::utils::generics(self.db.upcast(), impl_id.into()); 81 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
82 let substs = Substs::type_params_for_generics(&generics); 82 let substs = Substs::type_params_for_generics(self.db, &generics);
83 let ty = self.db.impl_self_ty(impl_id).subst(&substs); 83 let ty = self.db.impl_self_ty(impl_id).subst(&substs);
84 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() { 84 if let Some((AdtId::StructId(struct_id), substs)) = ty.as_adt() {
85 let ty = self.db.value_ty(struct_id.into()).subst(&substs); 85 let ty = self.db.value_ty(struct_id.into()).subst(&substs);
@@ -96,7 +96,7 @@ impl<'a> InferenceContext<'a> {
96 // self_subst is just for the parent 96 // self_subst is just for the parent
97 let parent_substs = self_subst.unwrap_or_else(Substs::empty); 97 let parent_substs = self_subst.unwrap_or_else(Substs::empty);
98 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 98 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
99 let substs = Ty::substs_from_path(&ctx, path, typable, true); 99 let substs = ctx.substs_from_path(path, typable, true);
100 let full_substs = Substs::builder(substs.len()) 100 let full_substs = Substs::builder(substs.len())
101 .use_parent_substs(&parent_substs) 101 .use_parent_substs(&parent_substs)
102 .fill(substs.0[parent_substs.len()..].iter().cloned()) 102 .fill(substs.0[parent_substs.len()..].iter().cloned())
@@ -126,7 +126,8 @@ impl<'a> InferenceContext<'a> {
126 let segment = 126 let segment =
127 remaining_segments.last().expect("there should be at least one segment here"); 127 remaining_segments.last().expect("there should be at least one segment here");
128 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 128 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
129 let trait_ref = TraitRef::from_resolved_path(&ctx, trait_, resolved_segment, None); 129 let trait_ref =
130 ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
130 self.resolve_trait_assoc_item(trait_ref, segment, id) 131 self.resolve_trait_assoc_item(trait_ref, segment, id)
131 } 132 }
132 (def, _) => { 133 (def, _) => {
@@ -137,14 +138,13 @@ impl<'a> InferenceContext<'a> {
137 let remaining_segments_for_ty = 138 let remaining_segments_for_ty =
138 remaining_segments.take(remaining_segments.len() - 1); 139 remaining_segments.take(remaining_segments.len() - 1);
139 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver); 140 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
140 let (ty, _) = Ty::from_partly_resolved_hir_path( 141 let (ty, _) = ctx.lower_partly_resolved_path(
141 &ctx,
142 def, 142 def,
143 resolved_segment, 143 resolved_segment,
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..7795f446f 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, FnPointer, GenericPredicate, InEnvironment, InferenceVar,
11 Substs, Ty, TypeWalk, 11 Interner, 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) = ty.interned_mut() {
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 {
@@ -279,10 +283,24 @@ impl InferenceTable {
279 let ty1 = self.resolve_ty_shallow(ty1); 283 let ty1 = self.resolve_ty_shallow(ty1);
280 let ty2 = self.resolve_ty_shallow(ty2); 284 let ty2 = self.resolve_ty_shallow(ty2);
281 if ty1.equals_ctor(&ty2) { 285 if ty1.equals_ctor(&ty2) {
282 match (ty1.substs(), ty2.substs()) { 286 match (ty1.interned(&Interner), ty2.interned(&Interner)) {
283 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1), 287 (TyKind::Adt(_, substs1), TyKind::Adt(_, substs2))
284 (None, None) => true, 288 | (TyKind::FnDef(_, substs1), TyKind::FnDef(_, substs2))
285 _ => false, 289 | (
290 TyKind::Function(FnPointer { substs: substs1, .. }),
291 TyKind::Function(FnPointer { substs: substs2, .. }),
292 )
293 | (TyKind::Tuple(_, substs1), TyKind::Tuple(_, substs2))
294 | (TyKind::OpaqueType(_, substs1), TyKind::OpaqueType(_, substs2))
295 | (TyKind::AssociatedType(_, substs1), TyKind::AssociatedType(_, substs2))
296 | (TyKind::Closure(.., substs1), TyKind::Closure(.., substs2)) => {
297 self.unify_substs(substs1, substs2, depth + 1)
298 }
299 (TyKind::Ref(_, ty1), TyKind::Ref(_, ty2))
300 | (TyKind::Raw(_, ty1), TyKind::Raw(_, ty2))
301 | (TyKind::Array(ty1), TyKind::Array(ty2))
302 | (TyKind::Slice(ty1), TyKind::Slice(ty2)) => self.unify_inner(ty1, ty2, depth + 1),
303 _ => true, /* we checked equals_ctor already */
286 } 304 }
287 } else { 305 } else {
288 self.unify_inner_trivial(&ty1, &ty2, depth) 306 self.unify_inner_trivial(&ty1, &ty2, depth)
@@ -290,12 +308,12 @@ impl InferenceTable {
290 } 308 }
291 309
292 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool { 310 pub(super) fn unify_inner_trivial(&mut self, ty1: &Ty, ty2: &Ty, depth: usize) -> bool {
293 match (ty1, ty2) { 311 match (ty1.interned(&Interner), ty2.interned(&Interner)) {
294 (Ty::Unknown, _) | (_, Ty::Unknown) => true, 312 (TyKind::Unknown, _) | (_, TyKind::Unknown) => true,
295 313
296 (Ty::Placeholder(p1), Ty::Placeholder(p2)) if *p1 == *p2 => true, 314 (TyKind::Placeholder(p1), TyKind::Placeholder(p2)) if *p1 == *p2 => true,
297 315
298 (Ty::Dyn(dyn1), Ty::Dyn(dyn2)) if dyn1.len() == dyn2.len() => { 316 (TyKind::Dyn(dyn1), TyKind::Dyn(dyn2)) if dyn1.len() == dyn2.len() => {
299 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) { 317 for (pred1, pred2) in dyn1.iter().zip(dyn2.iter()) {
300 if !self.unify_preds(pred1, pred2, depth + 1) { 318 if !self.unify_preds(pred1, pred2, depth + 1) {
301 return false; 319 return false;
@@ -305,16 +323,16 @@ impl InferenceTable {
305 } 323 }
306 324
307 ( 325 (
308 Ty::InferenceVar(tv1, TyVariableKind::General), 326 TyKind::InferenceVar(tv1, TyVariableKind::General),
309 Ty::InferenceVar(tv2, TyVariableKind::General), 327 TyKind::InferenceVar(tv2, TyVariableKind::General),
310 ) 328 )
311 | ( 329 | (
312 Ty::InferenceVar(tv1, TyVariableKind::Integer), 330 TyKind::InferenceVar(tv1, TyVariableKind::Integer),
313 Ty::InferenceVar(tv2, TyVariableKind::Integer), 331 TyKind::InferenceVar(tv2, TyVariableKind::Integer),
314 ) 332 )
315 | ( 333 | (
316 Ty::InferenceVar(tv1, TyVariableKind::Float), 334 TyKind::InferenceVar(tv1, TyVariableKind::Float),
317 Ty::InferenceVar(tv2, TyVariableKind::Float), 335 TyKind::InferenceVar(tv2, TyVariableKind::Float),
318 ) if self.type_variable_table.is_diverging(*tv1) 336 ) if self.type_variable_table.is_diverging(*tv1)
319 == self.type_variable_table.is_diverging(*tv2) => 337 == self.type_variable_table.is_diverging(*tv2) =>
320 { 338 {
@@ -326,24 +344,37 @@ impl InferenceTable {
326 // The order of MaybeNeverTypeVar matters here. 344 // The order of MaybeNeverTypeVar matters here.
327 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 345 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
328 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 346 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
329 (Ty::InferenceVar(tv, TyVariableKind::General), other) 347 (TyKind::InferenceVar(tv, TyVariableKind::General), other)
330 | (other, Ty::InferenceVar(tv, TyVariableKind::General)) 348 | (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 | ( 349 | (
334 Ty::InferenceVar(tv, TyVariableKind::Integer), 350 TyKind::InferenceVar(tv, TyVariableKind::Integer),
335 other @ Ty::Scalar(Scalar::Uint(_)), 351 other @ TyKind::Scalar(Scalar::Int(_)),
336 ) 352 )
337 | ( 353 | (
338 other @ Ty::Scalar(Scalar::Uint(_)), 354 other @ TyKind::Scalar(Scalar::Int(_)),
339 Ty::InferenceVar(tv, TyVariableKind::Integer), 355 TyKind::InferenceVar(tv, TyVariableKind::Integer),
340 ) 356 )
341 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_))) 357 | (
342 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) => 358 TyKind::InferenceVar(tv, TyVariableKind::Integer),
343 { 359 other @ TyKind::Scalar(Scalar::Uint(_)),
360 )
361 | (
362 other @ TyKind::Scalar(Scalar::Uint(_)),
363 TyKind::InferenceVar(tv, TyVariableKind::Integer),
364 )
365 | (
366 TyKind::InferenceVar(tv, TyVariableKind::Float),
367 other @ TyKind::Scalar(Scalar::Float(_)),
368 )
369 | (
370 other @ TyKind::Scalar(Scalar::Float(_)),
371 TyKind::InferenceVar(tv, TyVariableKind::Float),
372 ) => {
344 // the type var is unknown since we tried to resolve it 373 // the type var is unknown since we tried to resolve it
345 self.var_unification_table 374 self.var_unification_table.union_value(
346 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone())); 375 tv.to_inner(),
376 TypeVarValue::Known(other.clone().intern(&Interner)),
377 );
347 true 378 true
348 } 379 }
349 380
@@ -364,11 +395,11 @@ impl InferenceTable {
364 self.unify_substs(&tr1.substs, &tr2.substs, depth + 1) 395 self.unify_substs(&tr1.substs, &tr2.substs, depth + 1)
365 } 396 }
366 (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2)) 397 (GenericPredicate::Projection(proj1), GenericPredicate::Projection(proj2))
367 if proj1.projection_ty.associated_ty == proj2.projection_ty.associated_ty => 398 if proj1.projection_ty.associated_ty_id == proj2.projection_ty.associated_ty_id =>
368 { 399 {
369 self.unify_substs( 400 self.unify_substs(
370 &proj1.projection_ty.parameters, 401 &proj1.projection_ty.substitution,
371 &proj2.projection_ty.parameters, 402 &proj2.projection_ty.substitution,
372 depth + 1, 403 depth + 1,
373 ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1) 404 ) && self.unify_inner(&proj1.ty, &proj2.ty, depth + 1)
374 } 405 }
@@ -387,8 +418,8 @@ impl InferenceTable {
387 if i > 0 { 418 if i > 0 {
388 cov_mark::hit!(type_var_resolves_to_int_var); 419 cov_mark::hit!(type_var_resolves_to_int_var);
389 } 420 }
390 match &*ty { 421 match ty.interned(&Interner) {
391 Ty::InferenceVar(tv, _) => { 422 TyKind::InferenceVar(tv, _) => {
392 let inner = tv.to_inner(); 423 let inner = tv.to_inner();
393 match self.var_unification_table.inlined_probe_value(inner).known() { 424 match self.var_unification_table.inlined_probe_value(inner).known() {
394 Some(known_ty) => { 425 Some(known_ty) => {
@@ -410,8 +441,8 @@ impl InferenceTable {
410 /// be resolved as far as possible, i.e. contain no type variables with 441 /// be resolved as far as possible, i.e. contain no type variables with
411 /// known type. 442 /// known type.
412 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 443 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
413 ty.fold(&mut |ty| match ty { 444 ty.fold(&mut |ty| match ty.interned(&Interner) {
414 Ty::InferenceVar(tv, kind) => { 445 &TyKind::InferenceVar(tv, kind) => {
415 let inner = tv.to_inner(); 446 let inner = tv.to_inner();
416 if tv_stack.contains(&inner) { 447 if tv_stack.contains(&inner) {
417 cov_mark::hit!(type_var_cycles_resolve_as_possible); 448 cov_mark::hit!(type_var_cycles_resolve_as_possible);
@@ -435,10 +466,10 @@ impl InferenceTable {
435 } 466 }
436 467
437 /// Resolves the type completely; type variables without known type are 468 /// Resolves the type completely; type variables without known type are
438 /// replaced by Ty::Unknown. 469 /// replaced by TyKind::Unknown.
439 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 470 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
440 ty.fold(&mut |ty| match ty { 471 ty.fold(&mut |ty| match ty.interned(&Interner) {
441 Ty::InferenceVar(tv, kind) => { 472 &TyKind::InferenceVar(tv, kind) => {
442 let inner = tv.to_inner(); 473 let inner = tv.to_inner();
443 if tv_stack.contains(&inner) { 474 if tv_stack.contains(&inner) {
444 cov_mark::hit!(type_var_cycles_resolve_completely); 475 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..850385280 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -27,11 +27,11 @@ use std::{iter, mem, ops::Deref, sync::Arc};
27 27
28use base_db::salsa; 28use base_db::salsa;
29use hir_def::{ 29use hir_def::{
30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId, 30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, FunctionId,
31 FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, 31 GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
32 TypeParamId,
33}; 32};
34use itertools::Itertools; 33use itertools::Itertools;
34use smallvec::SmallVec;
35 35
36use crate::{ 36use crate::{
37 db::HirDatabase, 37 db::HirDatabase,
@@ -47,9 +47,16 @@ pub use lower::{
47}; 47};
48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
49 49
50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind}; 50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Safety, Scalar, TyVariableKind};
51 51
52pub(crate) use crate::traits::chalk::Interner; 52pub use crate::traits::chalk::Interner;
53
54pub type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
55pub type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
56pub type FnDefId = chalk_ir::FnDefId<Interner>;
57pub type ClosureId = chalk_ir::ClosureId<Interner>;
58pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
59pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
53 60
54#[derive(Clone, PartialEq, Eq, Debug, Hash)] 61#[derive(Clone, PartialEq, Eq, Debug, Hash)]
55pub enum Lifetime { 62pub enum Lifetime {
@@ -60,7 +67,7 @@ pub enum Lifetime {
60#[derive(Clone, PartialEq, Eq, Debug, Hash)] 67#[derive(Clone, PartialEq, Eq, Debug, Hash)]
61pub struct OpaqueTy { 68pub struct OpaqueTy {
62 pub opaque_ty_id: OpaqueTyId, 69 pub opaque_ty_id: OpaqueTyId,
63 pub parameters: Substs, 70 pub substitution: Substs,
64} 71}
65 72
66/// A "projection" type corresponds to an (unnormalized) 73/// A "projection" type corresponds to an (unnormalized)
@@ -68,17 +75,17 @@ pub struct OpaqueTy {
68/// trait and all its parameters are fully known. 75/// trait and all its parameters are fully known.
69#[derive(Clone, PartialEq, Eq, Debug, Hash)] 76#[derive(Clone, PartialEq, Eq, Debug, Hash)]
70pub struct ProjectionTy { 77pub struct ProjectionTy {
71 pub associated_ty: TypeAliasId, 78 pub associated_ty_id: AssocTypeId,
72 pub parameters: Substs, 79 pub substitution: Substs,
73} 80}
74 81
75impl ProjectionTy { 82impl ProjectionTy {
76 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef { 83 pub fn trait_ref(&self, db: &dyn HirDatabase) -> TraitRef {
77 TraitRef { trait_: self.trait_(db), substs: self.parameters.clone() } 84 TraitRef { trait_: self.trait_(db), substs: self.substitution.clone() }
78 } 85 }
79 86
80 fn trait_(&self, db: &dyn HirDatabase) -> TraitId { 87 fn trait_(&self, db: &dyn HirDatabase) -> TraitId {
81 match self.associated_ty.lookup(db.upcast()).container { 88 match from_assoc_type_id(self.associated_ty_id).lookup(db.upcast()).container {
82 AssocContainerId::TraitId(it) => it, 89 AssocContainerId::TraitId(it) => it,
83 _ => panic!("projection ty without parent trait"), 90 _ => panic!("projection ty without parent trait"),
84 } 91 }
@@ -87,7 +94,7 @@ impl ProjectionTy {
87 94
88impl TypeWalk for ProjectionTy { 95impl TypeWalk for ProjectionTy {
89 fn walk(&self, f: &mut impl FnMut(&Ty)) { 96 fn walk(&self, f: &mut impl FnMut(&Ty)) {
90 self.parameters.walk(f); 97 self.substitution.walk(f);
91 } 98 }
92 99
93 fn walk_mut_binders( 100 fn walk_mut_binders(
@@ -95,14 +102,11 @@ impl TypeWalk for ProjectionTy {
95 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 102 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
96 binders: DebruijnIndex, 103 binders: DebruijnIndex,
97 ) { 104 ) {
98 self.parameters.walk_mut_binders(f, binders); 105 self.substitution.walk_mut_binders(f, binders);
99 } 106 }
100} 107}
101 108
102#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 109pub type FnSig = chalk_ir::FnSig<Interner>;
103pub struct FnSig {
104 pub variadic: bool,
105}
106 110
107#[derive(Clone, PartialEq, Eq, Debug, Hash)] 111#[derive(Clone, PartialEq, Eq, Debug, Hash)]
108pub struct FnPointer { 112pub struct FnPointer {
@@ -131,7 +135,7 @@ pub enum AliasTy {
131/// 135///
132/// This should be cheap to clone. 136/// This should be cheap to clone.
133#[derive(Clone, PartialEq, Eq, Debug, Hash)] 137#[derive(Clone, PartialEq, Eq, Debug, Hash)]
134pub enum Ty { 138pub enum TyKind {
135 /// Structures, enumerations and unions. 139 /// Structures, enumerations and unions.
136 Adt(AdtId<Interner>, Substs), 140 Adt(AdtId<Interner>, Substs),
137 141
@@ -139,7 +143,7 @@ pub enum Ty {
139 /// when we have tried to normalize a projection like `T::Item` but 143 /// when we have tried to normalize a projection like `T::Item` but
140 /// couldn't find a better representation. In that case, we generate 144 /// couldn't find a better representation. In that case, we generate
141 /// an **application type** like `(Iterator::Item)<T>`. 145 /// an **application type** like `(Iterator::Item)<T>`.
142 AssociatedType(TypeAliasId, Substs), 146 AssociatedType(AssocTypeId, Substs),
143 147
144 /// a scalar type like `bool` or `u32` 148 /// a scalar type like `bool` or `u32`
145 Scalar(Scalar), 149 Scalar(Scalar),
@@ -148,17 +152,17 @@ pub enum Ty {
148 Tuple(usize, Substs), 152 Tuple(usize, Substs),
149 153
150 /// An array with the given length. Written as `[T; n]`. 154 /// An array with the given length. Written as `[T; n]`.
151 Array(Substs), 155 Array(Ty),
152 156
153 /// The pointee of an array slice. Written as `[T]`. 157 /// The pointee of an array slice. Written as `[T]`.
154 Slice(Substs), 158 Slice(Ty),
155 159
156 /// A raw pointer. Written as `*mut T` or `*const T` 160 /// A raw pointer. Written as `*mut T` or `*const T`
157 Raw(Mutability, Substs), 161 Raw(Mutability, Ty),
158 162
159 /// A reference; a pointer with an associated lifetime. Written as 163 /// A reference; a pointer with an associated lifetime. Written as
160 /// `&'a mut T` or `&'a T`. 164 /// `&'a mut T` or `&'a T`.
161 Ref(Mutability, Substs), 165 Ref(Mutability, Ty),
162 166
163 /// This represents a placeholder for an opaque type in situations where we 167 /// This represents a placeholder for an opaque type in situations where we
164 /// don't know the hidden type (i.e. currently almost always). This is 168 /// don't know the hidden type (i.e. currently almost always). This is
@@ -179,7 +183,7 @@ pub enum Ty {
179 /// fn foo() -> i32 { 1 } 183 /// fn foo() -> i32 { 1 }
180 /// let bar = foo; // bar: fn() -> i32 {foo} 184 /// let bar = foo; // bar: fn() -> i32 {foo}
181 /// ``` 185 /// ```
182 FnDef(CallableDefId, Substs), 186 FnDef(FnDefId, Substs),
183 187
184 /// The pointee of a string slice. Written as `str`. 188 /// The pointee of a string slice. Written as `str`.
185 Str, 189 Str,
@@ -191,10 +195,10 @@ pub enum Ty {
191 /// 195 ///
192 /// The closure signature is stored in a `FnPtr` type in the first type 196 /// The closure signature is stored in a `FnPtr` type in the first type
193 /// parameter. 197 /// parameter.
194 Closure(DefWithBodyId, ExprId, Substs), 198 Closure(ClosureId, Substs),
195 199
196 /// Represents a foreign type declared in external blocks. 200 /// Represents a foreign type declared in external blocks.
197 ForeignType(TypeAliasId), 201 ForeignType(ForeignDefId),
198 202
199 /// A pointer to a function. Written as `fn() -> i32`. 203 /// A pointer to a function. Written as `fn() -> i32`.
200 /// 204 ///
@@ -216,7 +220,7 @@ pub enum Ty {
216 /// {}` when we're type-checking the body of that function. In this 220 /// {}` when we're type-checking the body of that function. In this
217 /// situation, we know this stands for *some* type, but don't know the exact 221 /// situation, we know this stands for *some* type, but don't know the exact
218 /// type. 222 /// type.
219 Placeholder(TypeParamId), 223 Placeholder(PlaceholderIndex),
220 224
221 /// A bound type variable. This is used in various places: when representing 225 /// A bound type variable. This is used in various places: when representing
222 /// some polymorphic type like the type of function `fn f<T>`, the type 226 /// some polymorphic type like the type of function `fn f<T>`, the type
@@ -244,9 +248,32 @@ pub enum Ty {
244 Unknown, 248 Unknown,
245} 249}
246 250
251#[derive(Clone, PartialEq, Eq, Debug, Hash)]
252pub struct Ty(Arc<TyKind>);
253
254impl TyKind {
255 pub fn intern(self, _interner: &Interner) -> Ty {
256 Ty(Arc::new(self))
257 }
258}
259
260impl Ty {
261 pub fn interned(&self, _interner: &Interner) -> &TyKind {
262 &self.0
263 }
264
265 pub fn interned_mut(&mut self) -> &mut TyKind {
266 Arc::make_mut(&mut self.0)
267 }
268
269 pub fn into_inner(self) -> TyKind {
270 Arc::try_unwrap(self.0).unwrap_or_else(|a| (*a).clone())
271 }
272}
273
247/// A list of substitutions for generic parameters. 274/// A list of substitutions for generic parameters.
248#[derive(Clone, PartialEq, Eq, Debug, Hash)] 275#[derive(Clone, PartialEq, Eq, Debug, Hash)]
249pub struct Substs(Arc<[Ty]>); 276pub struct Substs(SmallVec<[Ty; 2]>);
250 277
251impl TypeWalk for Substs { 278impl TypeWalk for Substs {
252 fn walk(&self, f: &mut impl FnMut(&Ty)) { 279 fn walk(&self, f: &mut impl FnMut(&Ty)) {
@@ -260,19 +287,27 @@ impl TypeWalk for Substs {
260 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 287 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
261 binders: DebruijnIndex, 288 binders: DebruijnIndex,
262 ) { 289 ) {
263 for t in make_mut_slice(&mut self.0) { 290 for t in &mut self.0 {
264 t.walk_mut_binders(f, binders); 291 t.walk_mut_binders(f, binders);
265 } 292 }
266 } 293 }
267} 294}
268 295
269impl Substs { 296impl Substs {
297 pub fn interned(&self, _: &Interner) -> &[Ty] {
298 &self.0
299 }
300
270 pub fn empty() -> Substs { 301 pub fn empty() -> Substs {
271 Substs(Arc::new([])) 302 Substs(SmallVec::new())
272 } 303 }
273 304
274 pub fn single(ty: Ty) -> Substs { 305 pub fn single(ty: Ty) -> Substs {
275 Substs(Arc::new([ty])) 306 Substs({
307 let mut v = SmallVec::new();
308 v.push(ty);
309 v
310 })
276 } 311 }
277 312
278 pub fn prefix(&self, n: usize) -> Substs { 313 pub fn prefix(&self, n: usize) -> Substs {
@@ -290,15 +325,27 @@ impl Substs {
290 &self.0[0] 325 &self.0[0]
291 } 326 }
292 327
328 pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self {
329 Substs(elements.into_iter().collect())
330 }
331
293 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 332 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
294 pub(crate) fn type_params_for_generics(generic_params: &Generics) -> Substs { 333 pub(crate) fn type_params_for_generics(
295 Substs(generic_params.iter().map(|(id, _)| Ty::Placeholder(id)).collect()) 334 db: &dyn HirDatabase,
335 generic_params: &Generics,
336 ) -> Substs {
337 Substs(
338 generic_params
339 .iter()
340 .map(|(id, _)| TyKind::Placeholder(to_placeholder_idx(db, id)).intern(&Interner))
341 .collect(),
342 )
296 } 343 }
297 344
298 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). 345 /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
299 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs { 346 pub fn type_params(db: &dyn HirDatabase, def: impl Into<GenericDefId>) -> Substs {
300 let params = generics(db.upcast(), def.into()); 347 let params = generics(db.upcast(), def.into());
301 Substs::type_params_for_generics(&params) 348 Substs::type_params_for_generics(db, &params)
302 } 349 }
303 350
304 /// Return Substs that replace each parameter by a bound variable. 351 /// Return Substs that replace each parameter by a bound variable.
@@ -307,7 +354,7 @@ impl Substs {
307 generic_params 354 generic_params
308 .iter() 355 .iter()
309 .enumerate() 356 .enumerate()
310 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx))) 357 .map(|(idx, _)| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner))
311 .collect(), 358 .collect(),
312 ) 359 )
313 } 360 }
@@ -355,11 +402,14 @@ impl SubstsBuilder {
355 } 402 }
356 403
357 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 404 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)))) 405 self.fill(
406 (starting_from..)
407 .map(|idx| TyKind::BoundVar(BoundVar::new(debruijn, idx)).intern(&Interner)),
408 )
359 } 409 }
360 410
361 pub fn fill_with_unknown(self) -> Self { 411 pub fn fill_with_unknown(self) -> Self {
362 self.fill(iter::repeat(Ty::Unknown)) 412 self.fill(iter::repeat(TyKind::Unknown.intern(&Interner)))
363 } 413 }
364 414
365 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self { 415 pub fn fill(mut self, filler: impl Iterator<Item = Ty>) -> Self {
@@ -563,13 +613,13 @@ impl CallableSig {
563 613
564 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { 614 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
565 CallableSig { 615 CallableSig {
566 params_and_return: Arc::clone(&fn_ptr.substs.0), 616 params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(),
567 is_varargs: fn_ptr.sig.variadic, 617 is_varargs: fn_ptr.sig.variadic,
568 } 618 }
569 } 619 }
570 620
571 pub fn from_substs(substs: &Substs) -> CallableSig { 621 pub fn from_substs(substs: &Substs) -> CallableSig {
572 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } 622 CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false }
573 } 623 }
574 624
575 pub fn params(&self) -> &[Ty] { 625 pub fn params(&self) -> &[Ty] {
@@ -601,47 +651,50 @@ impl TypeWalk for CallableSig {
601 651
602impl Ty { 652impl Ty {
603 pub fn unit() -> Self { 653 pub fn unit() -> Self {
604 Ty::Tuple(0, Substs::empty()) 654 TyKind::Tuple(0, Substs::empty()).intern(&Interner)
605 } 655 }
606 656
607 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty { 657 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty {
608 Ty::Adt(AdtId(adt), substs) 658 TyKind::Adt(AdtId(adt), substs).intern(&Interner)
609 } 659 }
610 660
611 pub fn fn_ptr(sig: CallableSig) -> Self { 661 pub fn fn_ptr(sig: CallableSig) -> Self {
612 Ty::Function(FnPointer { 662 TyKind::Function(FnPointer {
613 num_args: sig.params().len(), 663 num_args: sig.params().len(),
614 sig: FnSig { variadic: sig.is_varargs }, 664 sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs },
615 substs: Substs(sig.params_and_return), 665 substs: Substs::from_iter(&Interner, sig.params_and_return.iter().cloned()),
616 }) 666 })
667 .intern(&Interner)
617 } 668 }
618 669
619 pub fn builtin(builtin: BuiltinType) -> Self { 670 pub fn builtin(builtin: BuiltinType) -> Self {
620 match builtin { 671 match builtin {
621 BuiltinType::Char => Ty::Scalar(Scalar::Char), 672 BuiltinType::Char => TyKind::Scalar(Scalar::Char).intern(&Interner),
622 BuiltinType::Bool => Ty::Scalar(Scalar::Bool), 673 BuiltinType::Bool => TyKind::Scalar(Scalar::Bool).intern(&Interner),
623 BuiltinType::Str => Ty::Str, 674 BuiltinType::Str => TyKind::Str.intern(&Interner),
624 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), 675 BuiltinType::Int(t) => {
625 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))), 676 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))), 677 }
678 BuiltinType::Uint(t) => {
679 TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))).intern(&Interner)
680 }
681 BuiltinType::Float(t) => {
682 TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))).intern(&Interner)
683 }
627 } 684 }
628 } 685 }
629 686
630 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 687 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
631 match self { 688 match self.interned(&Interner) {
632 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)), 689 TyKind::Ref(mutability, ty) => Some((ty, *mutability)),
633 _ => None, 690 _ => None,
634 } 691 }
635 } 692 }
636 693
637 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 694 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
638 match self { 695 match self.interned(&Interner) {
639 Ty::Ref(mutability, parameters) => { 696 TyKind::Ref(mutability, ty) => Some((ty, Rawness::Ref, *mutability)),
640 Some((parameters.as_single(), Rawness::Ref, *mutability)) 697 TyKind::Raw(mutability, ty) => Some((ty, Rawness::RawPtr, *mutability)),
641 }
642 Ty::Raw(mutability, parameters) => {
643 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
644 }
645 _ => None, 698 _ => None,
646 } 699 }
647 } 700 }
@@ -649,73 +702,79 @@ impl Ty {
649 pub fn strip_references(&self) -> &Ty { 702 pub fn strip_references(&self) -> &Ty {
650 let mut t: &Ty = self; 703 let mut t: &Ty = self;
651 704
652 while let Ty::Ref(_mutability, parameters) = t { 705 while let TyKind::Ref(_mutability, ty) = t.interned(&Interner) {
653 t = parameters.as_single(); 706 t = ty;
654 } 707 }
655 708
656 t 709 t
657 } 710 }
658 711
659 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> { 712 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> {
660 match self { 713 match self.interned(&Interner) {
661 Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)), 714 TyKind::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
662 _ => None, 715 _ => None,
663 } 716 }
664 } 717 }
665 718
666 pub fn as_tuple(&self) -> Option<&Substs> { 719 pub fn as_tuple(&self) -> Option<&Substs> {
667 match self { 720 match self.interned(&Interner) {
668 Ty::Tuple(_, substs) => Some(substs), 721 TyKind::Tuple(_, substs) => Some(substs),
669 _ => None, 722 _ => None,
670 } 723 }
671 } 724 }
672 725
673 pub fn as_generic_def(&self) -> Option<GenericDefId> { 726 pub fn as_generic_def(&self, db: &dyn HirDatabase) -> Option<GenericDefId> {
674 match *self { 727 match *self.interned(&Interner) {
675 Ty::Adt(AdtId(adt), ..) => Some(adt.into()), 728 TyKind::Adt(AdtId(adt), ..) => Some(adt.into()),
676 Ty::FnDef(callable, ..) => Some(callable.into()), 729 TyKind::FnDef(callable, ..) => {
677 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()), 730 Some(db.lookup_intern_callable_def(callable.into()).into())
678 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()), 731 }
732 TyKind::AssociatedType(type_alias, ..) => Some(from_assoc_type_id(type_alias).into()),
733 TyKind::ForeignType(type_alias, ..) => Some(from_foreign_def_id(type_alias).into()),
679 _ => None, 734 _ => None,
680 } 735 }
681 } 736 }
682 737
683 pub fn is_never(&self) -> bool { 738 pub fn is_never(&self) -> bool {
684 matches!(self, Ty::Never) 739 matches!(self.interned(&Interner), TyKind::Never)
685 } 740 }
686 741
687 pub fn is_unknown(&self) -> bool { 742 pub fn is_unknown(&self) -> bool {
688 matches!(self, Ty::Unknown) 743 matches!(self.interned(&Interner), TyKind::Unknown)
689 } 744 }
690 745
691 pub fn equals_ctor(&self, other: &Ty) -> bool { 746 pub fn equals_ctor(&self, other: &Ty) -> bool {
692 match (self, other) { 747 match (self.interned(&Interner), other.interned(&Interner)) {
693 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2, 748 (TyKind::Adt(adt, ..), TyKind::Adt(adt2, ..)) => adt == adt2,
694 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true, 749 (TyKind::Slice(_), TyKind::Slice(_)) | (TyKind::Array(_), TyKind::Array(_)) => true,
695 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2, 750 (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, 751 (TyKind::OpaqueType(ty_id, ..), TyKind::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
697 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..)) 752 (TyKind::AssociatedType(ty_id, ..), TyKind::AssociatedType(ty_id2, ..)) => {
698 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2, 753 ty_id == ty_id2
699 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => { 754 }
700 expr == expr2 && def == def2 755 (TyKind::ForeignType(ty_id, ..), TyKind::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
756 (TyKind::Closure(id1, _), TyKind::Closure(id2, _)) => id1 == id2,
757 (TyKind::Ref(mutability, ..), TyKind::Ref(mutability2, ..))
758 | (TyKind::Raw(mutability, ..), TyKind::Raw(mutability2, ..)) => {
759 mutability == mutability2
701 } 760 }
702 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
703 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
704 ( 761 (
705 Ty::Function(FnPointer { num_args, sig, .. }), 762 TyKind::Function(FnPointer { num_args, sig, .. }),
706 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }), 763 TyKind::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
707 ) => num_args == num_args2 && sig == sig2, 764 ) => num_args == num_args2 && sig == sig2,
708 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2, 765 (TyKind::Tuple(cardinality, _), TyKind::Tuple(cardinality2, _)) => {
709 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true, 766 cardinality == cardinality2
710 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2, 767 }
768 (TyKind::Str, TyKind::Str) | (TyKind::Never, TyKind::Never) => true,
769 (TyKind::Scalar(scalar), TyKind::Scalar(scalar2)) => scalar == scalar2,
711 _ => false, 770 _ => false,
712 } 771 }
713 } 772 }
714 773
715 /// If this is a `dyn Trait` type, this returns the `Trait` part. 774 /// If this is a `dyn Trait` type, this returns the `Trait` part.
716 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 775 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
717 match self { 776 match self.interned(&Interner) {
718 Ty::Dyn(bounds) => bounds.get(0).and_then(|b| match b { 777 TyKind::Dyn(bounds) => bounds.get(0).and_then(|b| match b {
719 GenericPredicate::Implemented(trait_ref) => Some(trait_ref), 778 GenericPredicate::Implemented(trait_ref) => Some(trait_ref),
720 _ => None, 779 _ => None,
721 }), 780 }),
@@ -729,28 +788,37 @@ impl Ty {
729 } 788 }
730 789
731 fn builtin_deref(&self) -> Option<Ty> { 790 fn builtin_deref(&self) -> Option<Ty> {
732 match self { 791 match self.interned(&Interner) {
733 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())), 792 TyKind::Ref(.., ty) => Some(ty.clone()),
734 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())), 793 TyKind::Raw(.., ty) => Some(ty.clone()),
735 _ => None, 794 _ => None,
736 } 795 }
737 } 796 }
738 797
739 pub fn as_fn_def(&self) -> Option<FunctionId> { 798 pub fn callable_def(&self, db: &dyn HirDatabase) -> Option<CallableDefId> {
740 match self { 799 match self.interned(&Interner) {
741 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func), 800 &TyKind::FnDef(def, ..) => Some(db.lookup_intern_callable_def(def.into())),
742 _ => None, 801 _ => None,
743 } 802 }
744 } 803 }
745 804
805 pub fn as_fn_def(&self, db: &dyn HirDatabase) -> Option<FunctionId> {
806 if let Some(CallableDefId::FunctionId(func)) = self.callable_def(db) {
807 Some(func)
808 } else {
809 None
810 }
811 }
812
746 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> { 813 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
747 match self { 814 match self.interned(&Interner) {
748 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)), 815 TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
749 Ty::FnDef(def, parameters) => { 816 TyKind::FnDef(def, parameters) => {
750 let sig = db.callable_item_signature(*def); 817 let callable_def = db.lookup_intern_callable_def((*def).into());
818 let sig = db.callable_item_signature(callable_def);
751 Some(sig.subst(&parameters)) 819 Some(sig.subst(&parameters))
752 } 820 }
753 Ty::Closure(.., substs) => { 821 TyKind::Closure(.., substs) => {
754 let sig_param = &substs[0]; 822 let sig_param = &substs[0];
755 sig_param.callable_sig(db) 823 sig_param.callable_sig(db)
756 } 824 }
@@ -758,72 +826,39 @@ impl Ty {
758 } 826 }
759 } 827 }
760 828
761 /// If this is a type with type parameters (an ADT or function), replaces
762 /// the `Substs` for these type parameters with the given ones. (So e.g. if
763 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
764 /// `Option<u32>` afterwards.)
765 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
766 match &mut self {
767 Ty::Adt(_, substs)
768 | Ty::Slice(substs)
769 | Ty::Array(substs)
770 | Ty::Raw(_, substs)
771 | Ty::Ref(_, substs)
772 | Ty::FnDef(_, substs)
773 | Ty::Function(FnPointer { substs, .. })
774 | Ty::Tuple(_, substs)
775 | Ty::OpaqueType(_, substs)
776 | Ty::AssociatedType(_, substs)
777 | Ty::Closure(.., substs) => {
778 assert_eq!(substs.len(), new_substs.len());
779 *substs = new_substs;
780 }
781 _ => (),
782 }
783 self
784 }
785
786 /// Returns the type parameters of this type if it has some (i.e. is an ADT 829 /// 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`. 830 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
788 pub fn substs(&self) -> Option<&Substs> { 831 pub fn substs(&self) -> Option<&Substs> {
789 match self { 832 match self.interned(&Interner) {
790 Ty::Adt(_, substs) 833 TyKind::Adt(_, substs)
791 | Ty::Slice(substs) 834 | TyKind::FnDef(_, substs)
792 | Ty::Array(substs) 835 | TyKind::Function(FnPointer { substs, .. })
793 | Ty::Raw(_, substs) 836 | TyKind::Tuple(_, substs)
794 | Ty::Ref(_, substs) 837 | TyKind::OpaqueType(_, substs)
795 | Ty::FnDef(_, substs) 838 | TyKind::AssociatedType(_, substs)
796 | Ty::Function(FnPointer { substs, .. }) 839 | TyKind::Closure(.., substs) => Some(substs),
797 | Ty::Tuple(_, substs)
798 | Ty::OpaqueType(_, substs)
799 | Ty::AssociatedType(_, substs)
800 | Ty::Closure(.., substs) => Some(substs),
801 _ => None, 840 _ => None,
802 } 841 }
803 } 842 }
804 843
805 pub fn substs_mut(&mut self) -> Option<&mut Substs> { 844 fn substs_mut(&mut self) -> Option<&mut Substs> {
806 match self { 845 match self.interned_mut() {
807 Ty::Adt(_, substs) 846 TyKind::Adt(_, substs)
808 | Ty::Slice(substs) 847 | TyKind::FnDef(_, substs)
809 | Ty::Array(substs) 848 | TyKind::Function(FnPointer { substs, .. })
810 | Ty::Raw(_, substs) 849 | TyKind::Tuple(_, substs)
811 | Ty::Ref(_, substs) 850 | TyKind::OpaqueType(_, substs)
812 | Ty::FnDef(_, substs) 851 | TyKind::AssociatedType(_, substs)
813 | Ty::Function(FnPointer { substs, .. }) 852 | TyKind::Closure(.., substs) => Some(substs),
814 | Ty::Tuple(_, substs)
815 | Ty::OpaqueType(_, substs)
816 | Ty::AssociatedType(_, substs)
817 | Ty::Closure(.., substs) => Some(substs),
818 _ => None, 853 _ => None,
819 } 854 }
820 } 855 }
821 856
822 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 857 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
823 match self { 858 match self.interned(&Interner) {
824 Ty::OpaqueType(opaque_ty_id, ..) => { 859 TyKind::OpaqueType(opaque_ty_id, ..) => {
825 match opaque_ty_id { 860 match db.lookup_intern_impl_trait_id((*opaque_ty_id).into()) {
826 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 861 ImplTraitId::AsyncBlockTypeImplTrait(def, _expr) => {
827 let krate = def.module(db.upcast()).krate(); 862 let krate = def.module(db.upcast()).krate();
828 if let Some(future_trait) = db 863 if let Some(future_trait) = db
829 .lang_item(krate, "future_trait".into()) 864 .lang_item(krate, "future_trait".into())
@@ -841,32 +876,34 @@ impl Ty {
841 None 876 None
842 } 877 }
843 } 878 }
844 OpaqueTyId::ReturnTypeImplTrait(..) => None, 879 ImplTraitId::ReturnTypeImplTrait(..) => None,
845 } 880 }
846 } 881 }
847 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 882 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
848 let predicates = match opaque_ty.opaque_ty_id { 883 let predicates = match db.lookup_intern_impl_trait_id(opaque_ty.opaque_ty_id.into())
849 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 884 {
885 ImplTraitId::ReturnTypeImplTrait(func, idx) => {
850 db.return_type_impl_traits(func).map(|it| { 886 db.return_type_impl_traits(func).map(|it| {
851 let data = (*it) 887 let data = (*it)
852 .as_ref() 888 .as_ref()
853 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 889 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
854 data.subst(&opaque_ty.parameters) 890 data.subst(&opaque_ty.substitution)
855 }) 891 })
856 } 892 }
857 // It always has an parameter for Future::Output type. 893 // It always has an parameter for Future::Output type.
858 OpaqueTyId::AsyncBlockTypeImplTrait(..) => unreachable!(), 894 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
859 }; 895 };
860 896
861 predicates.map(|it| it.value) 897 predicates.map(|it| it.value)
862 } 898 }
863 Ty::Placeholder(id) => { 899 TyKind::Placeholder(idx) => {
900 let id = from_placeholder_idx(db, *idx);
864 let generic_params = db.generic_params(id.parent); 901 let generic_params = db.generic_params(id.parent);
865 let param_data = &generic_params.types[id.local_id]; 902 let param_data = &generic_params.types[id.local_id];
866 match param_data.provenance { 903 match param_data.provenance {
867 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => { 904 hir_def::generics::TypeParamProvenance::ArgumentImplTrait => {
868 let predicates = db 905 let predicates = db
869 .generic_predicates_for_param(*id) 906 .generic_predicates_for_param(id)
870 .into_iter() 907 .into_iter()
871 .map(|pred| pred.value.clone()) 908 .map(|pred| pred.value.clone())
872 .collect_vec(); 909 .collect_vec();
@@ -881,15 +918,18 @@ impl Ty {
881 } 918 }
882 919
883 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 920 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
884 match self { 921 match self.interned(&Interner) {
885 Ty::AssociatedType(type_alias_id, ..) => { 922 TyKind::AssociatedType(id, ..) => {
886 match type_alias_id.lookup(db.upcast()).container { 923 match from_assoc_type_id(*id).lookup(db.upcast()).container {
887 AssocContainerId::TraitId(trait_id) => Some(trait_id), 924 AssocContainerId::TraitId(trait_id) => Some(trait_id),
888 _ => None, 925 _ => None,
889 } 926 }
890 } 927 }
891 Ty::Alias(AliasTy::Projection(projection_ty)) => { 928 TyKind::Alias(AliasTy::Projection(projection_ty)) => {
892 match projection_ty.associated_ty.lookup(db.upcast()).container { 929 match from_assoc_type_id(projection_ty.associated_ty_id)
930 .lookup(db.upcast())
931 .container
932 {
893 AssocContainerId::TraitId(trait_id) => Some(trait_id), 933 AssocContainerId::TraitId(trait_id) => Some(trait_id),
894 _ => None, 934 _ => None,
895 } 935 }
@@ -908,13 +948,13 @@ pub trait TypeWalk {
908 } 948 }
909 /// Walk the type, counting entered binders. 949 /// Walk the type, counting entered binders.
910 /// 950 ///
911 /// `Ty::Bound` variables use DeBruijn indexing, which means that 0 refers 951 /// `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 952 /// 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 953 /// 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' 954 /// 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 955 /// things that introduce new bound variables, we have to keep track of
916 /// that. Currently, the only thing that introduces bound variables on our 956 /// that. Currently, the only thing that introduces bound variables on our
917 /// side are `Ty::Dyn` and `Ty::Opaque`, which each introduce a bound 957 /// side are `TyKind::Dyn` and `TyKind::Opaque`, which each introduce a bound
918 /// variable for the self type. 958 /// variable for the self type.
919 fn walk_mut_binders( 959 fn walk_mut_binders(
920 &mut self, 960 &mut self,
@@ -932,7 +972,7 @@ pub trait TypeWalk {
932 { 972 {
933 self.walk_mut_binders( 973 self.walk_mut_binders(
934 &mut |ty_mut, binders| { 974 &mut |ty_mut, binders| {
935 let ty = mem::replace(ty_mut, Ty::Unknown); 975 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
936 *ty_mut = f(ty, binders); 976 *ty_mut = f(ty, binders);
937 }, 977 },
938 binders, 978 binders,
@@ -945,13 +985,13 @@ pub trait TypeWalk {
945 Self: Sized, 985 Self: Sized,
946 { 986 {
947 self.walk_mut(&mut |ty_mut| { 987 self.walk_mut(&mut |ty_mut| {
948 let ty = mem::replace(ty_mut, Ty::Unknown); 988 let ty = mem::replace(ty_mut, TyKind::Unknown.intern(&Interner));
949 *ty_mut = f(ty); 989 *ty_mut = f(ty);
950 }); 990 });
951 self 991 self
952 } 992 }
953 993
954 /// Substitutes `Ty::Bound` vars with the given substitution. 994 /// Substitutes `TyKind::Bound` vars with the given substitution.
955 fn subst_bound_vars(self, substs: &Substs) -> Self 995 fn subst_bound_vars(self, substs: &Substs) -> Self
956 where 996 where
957 Self: Sized, 997 Self: Sized,
@@ -959,14 +999,14 @@ pub trait TypeWalk {
959 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST) 999 self.subst_bound_vars_at_depth(substs, DebruijnIndex::INNERMOST)
960 } 1000 }
961 1001
962 /// Substitutes `Ty::Bound` vars with the given substitution. 1002 /// Substitutes `TyKind::Bound` vars with the given substitution.
963 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self 1003 fn subst_bound_vars_at_depth(mut self, substs: &Substs, depth: DebruijnIndex) -> Self
964 where 1004 where
965 Self: Sized, 1005 Self: Sized,
966 { 1006 {
967 self.walk_mut_binders( 1007 self.walk_mut_binders(
968 &mut |ty, binders| { 1008 &mut |ty, binders| {
969 if let &mut Ty::BoundVar(bound) = ty { 1009 if let &mut TyKind::BoundVar(bound) = ty.interned_mut() {
970 if bound.debruijn >= binders { 1010 if bound.debruijn >= binders {
971 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 1011 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
972 } 1012 }
@@ -977,17 +1017,17 @@ pub trait TypeWalk {
977 self 1017 self
978 } 1018 }
979 1019
980 /// Shifts up debruijn indices of `Ty::Bound` vars by `n`. 1020 /// Shifts up debruijn indices of `TyKind::Bound` vars by `n`.
981 fn shift_bound_vars(self, n: DebruijnIndex) -> Self 1021 fn shift_bound_vars(self, n: DebruijnIndex) -> Self
982 where 1022 where
983 Self: Sized, 1023 Self: Sized,
984 { 1024 {
985 self.fold_binders( 1025 self.fold_binders(
986 &mut |ty, binders| match ty { 1026 &mut |ty, binders| match ty.interned(&Interner) {
987 Ty::BoundVar(bound) if bound.debruijn >= binders => { 1027 TyKind::BoundVar(bound) if bound.debruijn >= binders => {
988 Ty::BoundVar(bound.shifted_in_from(n)) 1028 TyKind::BoundVar(bound.shifted_in_from(n)).intern(&Interner)
989 } 1029 }
990 ty => ty, 1030 _ => ty,
991 }, 1031 },
992 DebruijnIndex::INNERMOST, 1032 DebruijnIndex::INNERMOST,
993 ) 1033 )
@@ -996,22 +1036,25 @@ pub trait TypeWalk {
996 1036
997impl TypeWalk for Ty { 1037impl TypeWalk for Ty {
998 fn walk(&self, f: &mut impl FnMut(&Ty)) { 1038 fn walk(&self, f: &mut impl FnMut(&Ty)) {
999 match self { 1039 match self.interned(&Interner) {
1000 Ty::Alias(AliasTy::Projection(p_ty)) => { 1040 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1001 for t in p_ty.parameters.iter() { 1041 for t in p_ty.substitution.iter() {
1002 t.walk(f); 1042 t.walk(f);
1003 } 1043 }
1004 } 1044 }
1005 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1045 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1006 for t in o_ty.parameters.iter() { 1046 for t in o_ty.substitution.iter() {
1007 t.walk(f); 1047 t.walk(f);
1008 } 1048 }
1009 } 1049 }
1010 Ty::Dyn(predicates) => { 1050 TyKind::Dyn(predicates) => {
1011 for p in predicates.iter() { 1051 for p in predicates.iter() {
1012 p.walk(f); 1052 p.walk(f);
1013 } 1053 }
1014 } 1054 }
1055 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1056 ty.walk(f);
1057 }
1015 _ => { 1058 _ => {
1016 if let Some(substs) = self.substs() { 1059 if let Some(substs) = self.substs() {
1017 for t in substs.iter() { 1060 for t in substs.iter() {
@@ -1028,17 +1071,20 @@ impl TypeWalk for Ty {
1028 f: &mut impl FnMut(&mut Ty, DebruijnIndex), 1071 f: &mut impl FnMut(&mut Ty, DebruijnIndex),
1029 binders: DebruijnIndex, 1072 binders: DebruijnIndex,
1030 ) { 1073 ) {
1031 match self { 1074 match self.interned_mut() {
1032 Ty::Alias(AliasTy::Projection(p_ty)) => { 1075 TyKind::Alias(AliasTy::Projection(p_ty)) => {
1033 p_ty.parameters.walk_mut_binders(f, binders); 1076 p_ty.substitution.walk_mut_binders(f, binders);
1034 } 1077 }
1035 Ty::Dyn(predicates) => { 1078 TyKind::Dyn(predicates) => {
1036 for p in make_mut_slice(predicates) { 1079 for p in make_mut_slice(predicates) {
1037 p.walk_mut_binders(f, binders.shifted_in()); 1080 p.walk_mut_binders(f, binders.shifted_in());
1038 } 1081 }
1039 } 1082 }
1040 Ty::Alias(AliasTy::Opaque(o_ty)) => { 1083 TyKind::Alias(AliasTy::Opaque(o_ty)) => {
1041 o_ty.parameters.walk_mut_binders(f, binders); 1084 o_ty.substitution.walk_mut_binders(f, binders);
1085 }
1086 TyKind::Slice(ty) | TyKind::Array(ty) | TyKind::Ref(_, ty) | TyKind::Raw(_, ty) => {
1087 ty.walk_mut_binders(f, binders);
1042 } 1088 }
1043 _ => { 1089 _ => {
1044 if let Some(substs) = self.substs_mut() { 1090 if let Some(substs) = self.substs_mut() {
@@ -1068,7 +1114,7 @@ impl<T: TypeWalk> TypeWalk for Vec<T> {
1068} 1114}
1069 1115
1070#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 1116#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
1071pub enum OpaqueTyId { 1117pub enum ImplTraitId {
1072 ReturnTypeImplTrait(hir_def::FunctionId, u16), 1118 ReturnTypeImplTrait(hir_def::FunctionId, u16),
1073 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId), 1119 AsyncBlockTypeImplTrait(hir_def::DefWithBodyId, ExprId),
1074} 1120}
@@ -1082,3 +1128,33 @@ pub struct ReturnTypeImplTraits {
1082pub(crate) struct ReturnTypeImplTrait { 1128pub(crate) struct ReturnTypeImplTrait {
1083 pub(crate) bounds: Binders<Vec<GenericPredicate>>, 1129 pub(crate) bounds: Binders<Vec<GenericPredicate>>,
1084} 1130}
1131
1132pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
1133 chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
1134}
1135
1136pub fn from_foreign_def_id(id: ForeignDefId) -> TypeAliasId {
1137 salsa::InternKey::from_intern_id(id.0)
1138}
1139
1140pub fn to_assoc_type_id(id: TypeAliasId) -> AssocTypeId {
1141 chalk_ir::AssocTypeId(salsa::InternKey::as_intern_id(&id))
1142}
1143
1144pub fn from_assoc_type_id(id: AssocTypeId) -> TypeAliasId {
1145 salsa::InternKey::from_intern_id(id.0)
1146}
1147
1148pub fn from_placeholder_idx(db: &dyn HirDatabase, idx: PlaceholderIndex) -> TypeParamId {
1149 assert_eq!(idx.ui, chalk_ir::UniverseIndex::ROOT);
1150 let interned_id = salsa::InternKey::from_intern_id(salsa::InternId::from(idx.idx));
1151 db.lookup_intern_type_param_id(interned_id)
1152}
1153
1154pub fn to_placeholder_idx(db: &dyn HirDatabase, id: TypeParamId) -> PlaceholderIndex {
1155 let interned_id = db.intern_type_param_id(id);
1156 PlaceholderIndex {
1157 ui: chalk_ir::UniverseIndex::ROOT,
1158 idx: salsa::InternKey::as_intern_id(&interned_id).as_usize(),
1159 }
1160}
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index d84ec9b7a..6ab757bfc 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,7 +8,7 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::{cast::Cast, Mutability}; 11use chalk_ir::{cast::Cast, Mutability, Safety};
12use hir_def::{ 12use hir_def::{
13 adt::StructKind, 13 adt::StructKind,
14 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
@@ -27,14 +27,15 @@ use stdx::impl_from;
27 27
28use crate::{ 28use crate::{
29 db::HirDatabase, 29 db::HirDatabase,
30 to_assoc_type_id, to_placeholder_idx,
30 traits::chalk::{Interner, ToChalk}, 31 traits::chalk::{Interner, ToChalk},
31 utils::{ 32 utils::{
32 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 33 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
33 make_mut_slice, variant_data, 34 variant_data,
34 }, 35 },
35 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, 36 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
36 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, 37 ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
37 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk, 38 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
38}; 39};
39 40
40#[derive(Debug)] 41#[derive(Debug)]
@@ -139,69 +140,70 @@ pub enum TypeParamLoweringMode {
139 Variable, 140 Variable,
140} 141}
141 142
142impl Ty { 143impl<'a> TyLoweringContext<'a> {
143 pub fn from_hir(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Self { 144 pub fn lower_ty(&self, type_ref: &TypeRef) -> Ty {
144 Ty::from_hir_ext(ctx, type_ref).0 145 self.lower_ty_ext(type_ref).0
145 } 146 }
146 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { 147
148 fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
147 let mut res = None; 149 let mut res = None;
148 let ty = match type_ref { 150 let ty = match type_ref {
149 TypeRef::Never => Ty::Never, 151 TypeRef::Never => TyKind::Never.intern(&Interner),
150 TypeRef::Tuple(inner) => { 152 TypeRef::Tuple(inner) => {
151 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); 153 let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
152 Ty::Tuple(inner_tys.len(), Substs(inner_tys)) 154 TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys))
155 .intern(&Interner)
153 } 156 }
154 TypeRef::Path(path) => { 157 TypeRef::Path(path) => {
155 let (ty, res_) = Ty::from_hir_path(ctx, path); 158 let (ty, res_) = self.lower_path(path);
156 res = res_; 159 res = res_;
157 ty 160 ty
158 } 161 }
159 TypeRef::RawPtr(inner, mutability) => { 162 TypeRef::RawPtr(inner, mutability) => {
160 let inner_ty = Ty::from_hir(ctx, inner); 163 let inner_ty = self.lower_ty(inner);
161 Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 164 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner)
162 } 165 }
163 TypeRef::Array(inner) => { 166 TypeRef::Array(inner) => {
164 let inner_ty = Ty::from_hir(ctx, inner); 167 let inner_ty = self.lower_ty(inner);
165 Ty::Array(Substs::single(inner_ty)) 168 TyKind::Array(inner_ty).intern(&Interner)
166 } 169 }
167 TypeRef::Slice(inner) => { 170 TypeRef::Slice(inner) => {
168 let inner_ty = Ty::from_hir(ctx, inner); 171 let inner_ty = self.lower_ty(inner);
169 Ty::Slice(Substs::single(inner_ty)) 172 TyKind::Slice(inner_ty).intern(&Interner)
170 } 173 }
171 TypeRef::Reference(inner, _, mutability) => { 174 TypeRef::Reference(inner, _, mutability) => {
172 let inner_ty = Ty::from_hir(ctx, inner); 175 let inner_ty = self.lower_ty(inner);
173 Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty)) 176 TyKind::Ref(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner)
174 } 177 }
175 TypeRef::Placeholder => Ty::Unknown, 178 TypeRef::Placeholder => TyKind::Unknown.intern(&Interner),
176 TypeRef::Fn(params, is_varargs) => { 179 TypeRef::Fn(params, is_varargs) => {
177 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 180 let substs = Substs(params.iter().map(|tr| self.lower_ty(tr)).collect());
178 Ty::Function(FnPointer { 181 TyKind::Function(FnPointer {
179 num_args: substs.len() - 1, 182 num_args: substs.len() - 1,
180 sig: FnSig { variadic: *is_varargs }, 183 sig: FnSig { abi: (), safety: Safety::Safe, variadic: *is_varargs },
181 substs, 184 substs,
182 }) 185 })
186 .intern(&Interner)
183 } 187 }
184 TypeRef::DynTrait(bounds) => { 188 TypeRef::DynTrait(bounds) => {
185 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 189 let self_ty =
186 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 190 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
187 bounds 191 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
188 .iter() 192 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
189 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
190 .collect()
191 }); 193 });
192 Ty::Dyn(predicates) 194 TyKind::Dyn(predicates).intern(&Interner)
193 } 195 }
194 TypeRef::ImplTrait(bounds) => { 196 TypeRef::ImplTrait(bounds) => {
195 match ctx.impl_trait_mode { 197 match self.impl_trait_mode {
196 ImplTraitLoweringMode::Opaque => { 198 ImplTraitLoweringMode::Opaque => {
197 let idx = ctx.impl_trait_counter.get(); 199 let idx = self.impl_trait_counter.get();
198 ctx.impl_trait_counter.set(idx + 1); 200 self.impl_trait_counter.set(idx + 1);
199 201
200 assert!(idx as usize == ctx.opaque_type_data.borrow().len()); 202 assert!(idx as usize == self.opaque_type_data.borrow().len());
201 // this dance is to make sure the data is in the right 203 // this dance is to make sure the data is in the right
202 // place even if we encounter more opaque types while 204 // place even if we encounter more opaque types while
203 // lowering the bounds 205 // lowering the bounds
204 ctx.opaque_type_data 206 self.opaque_type_data
205 .borrow_mut() 207 .borrow_mut()
206 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) }); 208 .push(ReturnTypeImplTrait { bounds: Binders::new(1, Vec::new()) });
207 // We don't want to lower the bounds inside the binders 209 // We don't want to lower the bounds inside the binders
@@ -213,65 +215,70 @@ impl Ty {
213 // other, but separately. So if the `T` refers to a type 215 // other, but separately. So if the `T` refers to a type
214 // parameter of the outer function, it's just one binder 216 // parameter of the outer function, it's just one binder
215 // away instead of two. 217 // away instead of two.
216 let actual_opaque_type_data = ctx 218 let actual_opaque_type_data = self
217 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| { 219 .with_debruijn(DebruijnIndex::INNERMOST, |ctx| {
218 ReturnTypeImplTrait::from_hir(ctx, &bounds) 220 ctx.lower_impl_trait(&bounds)
219 }); 221 });
220 ctx.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data; 222 self.opaque_type_data.borrow_mut()[idx as usize] = actual_opaque_type_data;
221 223
222 let func = match ctx.resolver.generic_def() { 224 let func = match self.resolver.generic_def() {
223 Some(GenericDefId::FunctionId(f)) => f, 225 Some(GenericDefId::FunctionId(f)) => f,
224 _ => panic!("opaque impl trait lowering in non-function"), 226 _ => panic!("opaque impl trait lowering in non-function"),
225 }; 227 };
226 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); 228 let impl_trait_id = ImplTraitId::ReturnTypeImplTrait(func, idx);
227 let generics = generics(ctx.db.upcast(), func.into()); 229 let opaque_ty_id = self.db.intern_impl_trait_id(impl_trait_id).into();
228 let parameters = Substs::bound_vars(&generics, ctx.in_binders); 230 let generics = generics(self.db.upcast(), func.into());
229 Ty::Alias(AliasTy::Opaque(OpaqueTy { 231 let parameters = Substs::bound_vars(&generics, self.in_binders);
230 opaque_ty_id: impl_trait_id, 232 TyKind::Alias(AliasTy::Opaque(OpaqueTy {
231 parameters, 233 opaque_ty_id,
234 substitution: parameters,
232 })) 235 }))
236 .intern(&Interner)
233 } 237 }
234 ImplTraitLoweringMode::Param => { 238 ImplTraitLoweringMode::Param => {
235 let idx = ctx.impl_trait_counter.get(); 239 let idx = self.impl_trait_counter.get();
236 // FIXME we're probably doing something wrong here 240 // FIXME we're probably doing something wrong here
237 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); 241 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
238 if let Some(def) = ctx.resolver.generic_def() { 242 if let Some(def) = self.resolver.generic_def() {
239 let generics = generics(ctx.db.upcast(), def); 243 let generics = generics(self.db.upcast(), def);
240 let param = generics 244 let param = generics
241 .iter() 245 .iter()
242 .filter(|(_, data)| { 246 .filter(|(_, data)| {
243 data.provenance == TypeParamProvenance::ArgumentImplTrait 247 data.provenance == TypeParamProvenance::ArgumentImplTrait
244 }) 248 })
245 .nth(idx as usize) 249 .nth(idx as usize)
246 .map_or(Ty::Unknown, |(id, _)| Ty::Placeholder(id)); 250 .map_or(TyKind::Unknown, |(id, _)| {
247 param 251 TyKind::Placeholder(to_placeholder_idx(self.db, id))
252 });
253 param.intern(&Interner)
248 } else { 254 } else {
249 Ty::Unknown 255 TyKind::Unknown.intern(&Interner)
250 } 256 }
251 } 257 }
252 ImplTraitLoweringMode::Variable => { 258 ImplTraitLoweringMode::Variable => {
253 let idx = ctx.impl_trait_counter.get(); 259 let idx = self.impl_trait_counter.get();
254 // FIXME we're probably doing something wrong here 260 // FIXME we're probably doing something wrong here
255 ctx.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16); 261 self.impl_trait_counter.set(idx + count_impl_traits(type_ref) as u16);
256 let (parent_params, self_params, list_params, _impl_trait_params) = 262 let (parent_params, self_params, list_params, _impl_trait_params) =
257 if let Some(def) = ctx.resolver.generic_def() { 263 if let Some(def) = self.resolver.generic_def() {
258 let generics = generics(ctx.db.upcast(), def); 264 let generics = generics(self.db.upcast(), def);
259 generics.provenance_split() 265 generics.provenance_split()
260 } else { 266 } else {
261 (0, 0, 0, 0) 267 (0, 0, 0, 0)
262 }; 268 };
263 Ty::BoundVar(BoundVar::new( 269 TyKind::BoundVar(BoundVar::new(
264 ctx.in_binders, 270 self.in_binders,
265 idx as usize + parent_params + self_params + list_params, 271 idx as usize + parent_params + self_params + list_params,
266 )) 272 ))
273 .intern(&Interner)
267 } 274 }
268 ImplTraitLoweringMode::Disallowed => { 275 ImplTraitLoweringMode::Disallowed => {
269 // FIXME: report error 276 // FIXME: report error
270 Ty::Unknown 277 TyKind::Unknown.intern(&Interner)
271 } 278 }
272 } 279 }
273 } 280 }
274 TypeRef::Error => Ty::Unknown, 281 TypeRef::Error => TyKind::Unknown.intern(&Interner),
275 }; 282 };
276 (ty, res) 283 (ty, res)
277 } 284 }
@@ -279,7 +286,7 @@ impl Ty {
279 /// This is only for `generic_predicates_for_param`, where we can't just 286 /// This is only for `generic_predicates_for_param`, where we can't just
280 /// lower the self types of the predicates since that could lead to cycles. 287 /// lower the self types of the predicates since that could lead to cycles.
281 /// So we just check here if the `type_ref` resolves to a generic param, and which. 288 /// So we just check here if the `type_ref` resolves to a generic param, and which.
282 fn from_hir_only_param(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> Option<TypeParamId> { 289 fn lower_ty_only_param(&self, type_ref: &TypeRef) -> Option<TypeParamId> {
283 let path = match type_ref { 290 let path = match type_ref {
284 TypeRef::Path(path) => path, 291 TypeRef::Path(path) => path,
285 _ => return None, 292 _ => return None,
@@ -291,7 +298,7 @@ impl Ty {
291 return None; 298 return None;
292 } 299 }
293 let resolution = 300 let resolution =
294 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { 301 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
295 Some((it, None)) => it, 302 Some((it, None)) => it,
296 _ => return None, 303 _ => return None,
297 }; 304 };
@@ -302,8 +309,8 @@ impl Ty {
302 } 309 }
303 } 310 }
304 311
305 pub(crate) fn from_type_relative_path( 312 pub(crate) fn lower_ty_relative_path(
306 ctx: &TyLoweringContext<'_>, 313 &self,
307 ty: Ty, 314 ty: Ty,
308 // We need the original resolution to lower `Self::AssocTy` correctly 315 // We need the original resolution to lower `Self::AssocTy` correctly
309 res: Option<TypeNs>, 316 res: Option<TypeNs>,
@@ -312,17 +319,17 @@ impl Ty {
312 if remaining_segments.len() == 1 { 319 if remaining_segments.len() == 1 {
313 // resolve unselected assoc types 320 // resolve unselected assoc types
314 let segment = remaining_segments.first().unwrap(); 321 let segment = remaining_segments.first().unwrap();
315 (Ty::select_associated_type(ctx, res, segment), None) 322 (self.select_associated_type(res, segment), None)
316 } else if remaining_segments.len() > 1 { 323 } else if remaining_segments.len() > 1 {
317 // FIXME report error (ambiguous associated type) 324 // FIXME report error (ambiguous associated type)
318 (Ty::Unknown, None) 325 (TyKind::Unknown.intern(&Interner), None)
319 } else { 326 } else {
320 (ty, res) 327 (ty, res)
321 } 328 }
322 } 329 }
323 330
324 pub(crate) fn from_partly_resolved_hir_path( 331 pub(crate) fn lower_partly_resolved_path(
325 ctx: &TyLoweringContext<'_>, 332 &self,
326 resolution: TypeNs, 333 resolution: TypeNs,
327 resolved_segment: PathSegment<'_>, 334 resolved_segment: PathSegment<'_>,
328 remaining_segments: PathSegments<'_>, 335 remaining_segments: PathSegments<'_>,
@@ -332,103 +339,109 @@ impl Ty {
332 TypeNs::TraitId(trait_) => { 339 TypeNs::TraitId(trait_) => {
333 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 340 // 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 { 341 let self_ty = if remaining_segments.len() == 0 {
335 Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))) 342 Some(
343 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
344 .intern(&Interner),
345 )
336 } else { 346 } else {
337 None 347 None
338 }; 348 };
339 let trait_ref = 349 let trait_ref =
340 TraitRef::from_resolved_path(ctx, trait_, resolved_segment, self_ty); 350 self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, self_ty);
341 let ty = if remaining_segments.len() == 1 { 351 let ty = if remaining_segments.len() == 1 {
342 let segment = remaining_segments.first().unwrap(); 352 let segment = remaining_segments.first().unwrap();
343 let found = associated_type_by_name_including_super_traits( 353 let found = associated_type_by_name_including_super_traits(
344 ctx.db, 354 self.db,
345 trait_ref, 355 trait_ref,
346 &segment.name, 356 &segment.name,
347 ); 357 );
348 match found { 358 match found {
349 Some((super_trait_ref, associated_ty)) => { 359 Some((super_trait_ref, associated_ty)) => {
350 // FIXME handle type parameters on the segment 360 // FIXME handle type parameters on the segment
351 Ty::Alias(AliasTy::Projection(ProjectionTy { 361 TyKind::Alias(AliasTy::Projection(ProjectionTy {
352 associated_ty, 362 associated_ty_id: to_assoc_type_id(associated_ty),
353 parameters: super_trait_ref.substs, 363 substitution: super_trait_ref.substs,
354 })) 364 }))
365 .intern(&Interner)
355 } 366 }
356 None => { 367 None => {
357 // FIXME: report error (associated type not found) 368 // FIXME: report error (associated type not found)
358 Ty::Unknown 369 TyKind::Unknown.intern(&Interner)
359 } 370 }
360 } 371 }
361 } else if remaining_segments.len() > 1 { 372 } else if remaining_segments.len() > 1 {
362 // FIXME report error (ambiguous associated type) 373 // FIXME report error (ambiguous associated type)
363 Ty::Unknown 374 TyKind::Unknown.intern(&Interner)
364 } else { 375 } else {
365 Ty::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)])) 376 TyKind::Dyn(Arc::new([GenericPredicate::Implemented(trait_ref)]))
377 .intern(&Interner)
366 }; 378 };
367 return (ty, None); 379 return (ty, None);
368 } 380 }
369 TypeNs::GenericParam(param_id) => { 381 TypeNs::GenericParam(param_id) => {
370 let generics = generics( 382 let generics = generics(
371 ctx.db.upcast(), 383 self.db.upcast(),
372 ctx.resolver.generic_def().expect("generics in scope"), 384 self.resolver.generic_def().expect("generics in scope"),
373 ); 385 );
374 match ctx.type_param_mode { 386 match self.type_param_mode {
375 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 387 TypeParamLoweringMode::Placeholder => {
388 TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
389 }
376 TypeParamLoweringMode::Variable => { 390 TypeParamLoweringMode::Variable => {
377 let idx = generics.param_idx(param_id).expect("matching generics"); 391 let idx = generics.param_idx(param_id).expect("matching generics");
378 Ty::BoundVar(BoundVar::new(ctx.in_binders, idx)) 392 TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
379 } 393 }
380 } 394 }
395 .intern(&Interner)
381 } 396 }
382 TypeNs::SelfType(impl_id) => { 397 TypeNs::SelfType(impl_id) => {
383 let generics = generics(ctx.db.upcast(), impl_id.into()); 398 let generics = generics(self.db.upcast(), impl_id.into());
384 let substs = match ctx.type_param_mode { 399 let substs = match self.type_param_mode {
385 TypeParamLoweringMode::Placeholder => { 400 TypeParamLoweringMode::Placeholder => {
386 Substs::type_params_for_generics(&generics) 401 Substs::type_params_for_generics(self.db, &generics)
387 } 402 }
388 TypeParamLoweringMode::Variable => { 403 TypeParamLoweringMode::Variable => {
389 Substs::bound_vars(&generics, ctx.in_binders) 404 Substs::bound_vars(&generics, self.in_binders)
390 } 405 }
391 }; 406 };
392 ctx.db.impl_self_ty(impl_id).subst(&substs) 407 self.db.impl_self_ty(impl_id).subst(&substs)
393 } 408 }
394 TypeNs::AdtSelfType(adt) => { 409 TypeNs::AdtSelfType(adt) => {
395 let generics = generics(ctx.db.upcast(), adt.into()); 410 let generics = generics(self.db.upcast(), adt.into());
396 let substs = match ctx.type_param_mode { 411 let substs = match self.type_param_mode {
397 TypeParamLoweringMode::Placeholder => { 412 TypeParamLoweringMode::Placeholder => {
398 Substs::type_params_for_generics(&generics) 413 Substs::type_params_for_generics(self.db, &generics)
399 } 414 }
400 TypeParamLoweringMode::Variable => { 415 TypeParamLoweringMode::Variable => {
401 Substs::bound_vars(&generics, ctx.in_binders) 416 Substs::bound_vars(&generics, self.in_binders)
402 } 417 }
403 }; 418 };
404 ctx.db.ty(adt.into()).subst(&substs) 419 self.db.ty(adt.into()).subst(&substs)
405 } 420 }
406 421
407 TypeNs::AdtId(it) => { 422 TypeNs::AdtId(it) => self.lower_path_inner(resolved_segment, it.into(), infer_args),
408 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args)
409 }
410 TypeNs::BuiltinType(it) => { 423 TypeNs::BuiltinType(it) => {
411 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) 424 self.lower_path_inner(resolved_segment, it.into(), infer_args)
412 } 425 }
413 TypeNs::TypeAliasId(it) => { 426 TypeNs::TypeAliasId(it) => {
414 Ty::from_hir_path_inner(ctx, resolved_segment, it.into(), infer_args) 427 self.lower_path_inner(resolved_segment, it.into(), infer_args)
415 } 428 }
416 // FIXME: report error 429 // FIXME: report error
417 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 430 TypeNs::EnumVariantId(_) => return (TyKind::Unknown.intern(&Interner), None),
418 }; 431 };
419 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 432 self.lower_ty_relative_path(ty, Some(resolution), remaining_segments)
420 } 433 }
421 434
422 pub(crate) fn from_hir_path(ctx: &TyLoweringContext<'_>, path: &Path) -> (Ty, Option<TypeNs>) { 435 pub(crate) fn lower_path(&self, path: &Path) -> (Ty, Option<TypeNs>) {
423 // Resolve the path (in type namespace) 436 // Resolve the path (in type namespace)
424 if let Some(type_ref) = path.type_anchor() { 437 if let Some(type_ref) = path.type_anchor() {
425 let (ty, res) = Ty::from_hir_ext(ctx, &type_ref); 438 let (ty, res) = self.lower_ty_ext(&type_ref);
426 return Ty::from_type_relative_path(ctx, ty, res, path.segments()); 439 return self.lower_ty_relative_path(ty, res, path.segments());
427 } 440 }
428 let (resolution, remaining_index) = 441 let (resolution, remaining_index) =
429 match ctx.resolver.resolve_path_in_type_ns(ctx.db.upcast(), path.mod_path()) { 442 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
430 Some(it) => it, 443 Some(it) => it,
431 None => return (Ty::Unknown, None), 444 None => return (TyKind::Unknown.intern(&Interner), None),
432 }; 445 };
433 let (resolved_segment, remaining_segments) = match remaining_index { 446 let (resolved_segment, remaining_segments) = match remaining_index {
434 None => ( 447 None => (
@@ -437,31 +450,23 @@ impl Ty {
437 ), 450 ),
438 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)), 451 Some(i) => (path.segments().get(i - 1).unwrap(), path.segments().skip(i)),
439 }; 452 };
440 Ty::from_partly_resolved_hir_path( 453 self.lower_partly_resolved_path(resolution, resolved_segment, remaining_segments, false)
441 ctx,
442 resolution,
443 resolved_segment,
444 remaining_segments,
445 false,
446 )
447 } 454 }
448 455
449 fn select_associated_type( 456 fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
450 ctx: &TyLoweringContext<'_>,
451 res: Option<TypeNs>,
452 segment: PathSegment<'_>,
453 ) -> Ty {
454 if let Some(res) = res { 457 if let Some(res) = res {
455 let ty = 458 let ty = associated_type_shorthand_candidates(
456 associated_type_shorthand_candidates(ctx.db, res, move |name, t, associated_ty| { 459 self.db,
460 res,
461 move |name, t, associated_ty| {
457 if name == segment.name { 462 if name == segment.name {
458 let substs = match ctx.type_param_mode { 463 let substs = match self.type_param_mode {
459 TypeParamLoweringMode::Placeholder => { 464 TypeParamLoweringMode::Placeholder => {
460 // if we're lowering to placeholders, we have to put 465 // if we're lowering to placeholders, we have to put
461 // them in now 466 // them in now
462 let s = Substs::type_params( 467 let s = Substs::type_params(
463 ctx.db, 468 self.db,
464 ctx.resolver.generic_def().expect( 469 self.resolver.generic_def().expect(
465 "there should be generics if there's a generic param", 470 "there should be generics if there's a generic param",
466 ), 471 ),
467 ); 472 );
@@ -471,25 +476,29 @@ impl Ty {
471 }; 476 };
472 // We need to shift in the bound vars, since 477 // We need to shift in the bound vars, since
473 // associated_type_shorthand_candidates does not do that 478 // associated_type_shorthand_candidates does not do that
474 let substs = substs.shift_bound_vars(ctx.in_binders); 479 let substs = substs.shift_bound_vars(self.in_binders);
475 // FIXME handle type parameters on the segment 480 // FIXME handle type parameters on the segment
476 return Some(Ty::Alias(AliasTy::Projection(ProjectionTy { 481 return Some(
477 associated_ty, 482 TyKind::Alias(AliasTy::Projection(ProjectionTy {
478 parameters: substs, 483 associated_ty_id: to_assoc_type_id(associated_ty),
479 }))); 484 substitution: substs,
485 }))
486 .intern(&Interner),
487 );
480 } 488 }
481 489
482 None 490 None
483 }); 491 },
492 );
484 493
485 ty.unwrap_or(Ty::Unknown) 494 ty.unwrap_or(TyKind::Unknown.intern(&Interner))
486 } else { 495 } else {
487 Ty::Unknown 496 TyKind::Unknown.intern(&Interner)
488 } 497 }
489 } 498 }
490 499
491 fn from_hir_path_inner( 500 fn lower_path_inner(
492 ctx: &TyLoweringContext<'_>, 501 &self,
493 segment: PathSegment<'_>, 502 segment: PathSegment<'_>,
494 typeable: TyDefId, 503 typeable: TyDefId,
495 infer_args: bool, 504 infer_args: bool,
@@ -499,14 +508,14 @@ impl Ty {
499 TyDefId::AdtId(it) => Some(it.into()), 508 TyDefId::AdtId(it) => Some(it.into()),
500 TyDefId::TypeAliasId(it) => Some(it.into()), 509 TyDefId::TypeAliasId(it) => Some(it.into()),
501 }; 510 };
502 let substs = substs_from_path_segment(ctx, segment, generic_def, infer_args); 511 let substs = self.substs_from_path_segment(segment, generic_def, infer_args);
503 ctx.db.ty(typeable).subst(&substs) 512 self.db.ty(typeable).subst(&substs)
504 } 513 }
505 514
506 /// Collect generic arguments from a path into a `Substs`. See also 515 /// Collect generic arguments from a path into a `Substs`. See also
507 /// `create_substs_for_ast_path` and `def_to_ty` in rustc. 516 /// `create_substs_for_ast_path` and `def_to_ty` in rustc.
508 pub(super) fn substs_from_path( 517 pub(super) fn substs_from_path(
509 ctx: &TyLoweringContext<'_>, 518 &self,
510 path: &Path, 519 path: &Path,
511 // Note that we don't call `db.value_type(resolved)` here, 520 // Note that we don't call `db.value_type(resolved)` here,
512 // `ValueTyDefId` is just a convenient way to pass generics and 521 // `ValueTyDefId` is just a convenient way to pass generics and
@@ -536,169 +545,161 @@ impl Ty {
536 (segment, Some(var.parent.into())) 545 (segment, Some(var.parent.into()))
537 } 546 }
538 }; 547 };
539 substs_from_path_segment(ctx, segment, generic_def, infer_args) 548 self.substs_from_path_segment(segment, generic_def, infer_args)
540 } 549 }
541}
542 550
543fn substs_from_path_segment( 551 fn substs_from_path_segment(
544 ctx: &TyLoweringContext<'_>, 552 &self,
545 segment: PathSegment<'_>, 553 segment: PathSegment<'_>,
546 def_generic: Option<GenericDefId>, 554 def_generic: Option<GenericDefId>,
547 infer_args: bool, 555 infer_args: bool,
548) -> Substs { 556 ) -> Substs {
549 let mut substs = Vec::new(); 557 let mut substs = Vec::new();
550 let def_generics = def_generic.map(|def| generics(ctx.db.upcast(), def)); 558 let def_generics = def_generic.map(|def| generics(self.db.upcast(), def));
551 559
552 let (parent_params, self_params, type_params, impl_trait_params) = 560 let (parent_params, self_params, type_params, impl_trait_params) =
553 def_generics.map_or((0, 0, 0, 0), |g| g.provenance_split()); 561 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; 562 let total_len = parent_params + self_params + type_params + impl_trait_params;
555 563
556 substs.extend(iter::repeat(Ty::Unknown).take(parent_params)); 564 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(parent_params));
557 565
558 let mut had_explicit_type_args = false; 566 let mut had_explicit_type_args = false;
559 567
560 if let Some(generic_args) = &segment.args_and_bindings { 568 if let Some(generic_args) = &segment.args_and_bindings {
561 if !generic_args.has_self_type { 569 if !generic_args.has_self_type {
562 substs.extend(iter::repeat(Ty::Unknown).take(self_params)); 570 substs.extend(iter::repeat(TyKind::Unknown.intern(&Interner)).take(self_params));
563 } 571 }
564 let expected_num = 572 let expected_num =
565 if generic_args.has_self_type { self_params + type_params } else { type_params }; 573 if generic_args.has_self_type { self_params + type_params } else { type_params };
566 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 }; 574 let skip = if generic_args.has_self_type && self_params == 0 { 1 } else { 0 };
567 // if args are provided, it should be all of them, but we can't rely on that 575 // if args are provided, it should be all of them, but we can't rely on that
568 for arg in generic_args 576 for arg in generic_args
569 .args 577 .args
570 .iter() 578 .iter()
571 .filter(|arg| matches!(arg, GenericArg::Type(_))) 579 .filter(|arg| matches!(arg, GenericArg::Type(_)))
572 .skip(skip) 580 .skip(skip)
573 .take(expected_num) 581 .take(expected_num)
574 { 582 {
575 match arg { 583 match arg {
576 GenericArg::Type(type_ref) => { 584 GenericArg::Type(type_ref) => {
577 had_explicit_type_args = true; 585 had_explicit_type_args = true;
578 let ty = Ty::from_hir(ctx, type_ref); 586 let ty = self.lower_ty(type_ref);
579 substs.push(ty); 587 substs.push(ty);
588 }
589 GenericArg::Lifetime(_) => {}
580 } 590 }
581 GenericArg::Lifetime(_) => {}
582 } 591 }
583 } 592 }
584 }
585 593
586 // handle defaults. In expression or pattern path segments without 594 // handle defaults. In expression or pattern path segments without
587 // explicitly specified type arguments, missing type arguments are inferred 595 // explicitly specified type arguments, missing type arguments are inferred
588 // (i.e. defaults aren't used). 596 // (i.e. defaults aren't used).
589 if !infer_args || had_explicit_type_args { 597 if !infer_args || had_explicit_type_args {
590 if let Some(def_generic) = def_generic { 598 if let Some(def_generic) = def_generic {
591 let defaults = ctx.db.generic_defaults(def_generic); 599 let defaults = self.db.generic_defaults(def_generic);
592 assert_eq!(total_len, defaults.len()); 600 assert_eq!(total_len, defaults.len());
593 601
594 for default_ty in defaults.iter().skip(substs.len()) { 602 for default_ty in defaults.iter().skip(substs.len()) {
595 // each default can depend on the previous parameters 603 // each default can depend on the previous parameters
596 let substs_so_far = Substs(substs.clone().into()); 604 let substs_so_far = Substs(substs.clone().into());
597 substs.push(default_ty.clone().subst(&substs_so_far)); 605 substs.push(default_ty.clone().subst(&substs_so_far));
606 }
598 } 607 }
599 } 608 }
600 }
601 609
602 // add placeholders for args that were not provided 610 // add placeholders for args that were not provided
603 // FIXME: emit diagnostics in contexts where this is not allowed 611 // FIXME: emit diagnostics in contexts where this is not allowed
604 for _ in substs.len()..total_len { 612 for _ in substs.len()..total_len {
605 substs.push(Ty::Unknown); 613 substs.push(TyKind::Unknown.intern(&Interner));
606 } 614 }
607 assert_eq!(substs.len(), total_len); 615 assert_eq!(substs.len(), total_len);
608 616
609 Substs(substs.into()) 617 Substs(substs.into())
610} 618 }
611 619
612impl TraitRef { 620 fn lower_trait_ref_from_path(
613 fn from_path( 621 &self,
614 ctx: &TyLoweringContext<'_>,
615 path: &Path, 622 path: &Path,
616 explicit_self_ty: Option<Ty>, 623 explicit_self_ty: Option<Ty>,
617 ) -> Option<Self> { 624 ) -> Option<TraitRef> {
618 let resolved = 625 let resolved =
619 match ctx.resolver.resolve_path_in_type_ns_fully(ctx.db.upcast(), path.mod_path())? { 626 match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path.mod_path())? {
620 TypeNs::TraitId(tr) => tr, 627 TypeNs::TraitId(tr) => tr,
621 _ => return None, 628 _ => return None,
622 }; 629 };
623 let segment = path.segments().last().expect("path should have at least one segment"); 630 let segment = path.segments().last().expect("path should have at least one segment");
624 Some(TraitRef::from_resolved_path(ctx, resolved, segment, explicit_self_ty)) 631 Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
625 } 632 }
626 633
627 pub(crate) fn from_resolved_path( 634 pub(crate) fn lower_trait_ref_from_resolved_path(
628 ctx: &TyLoweringContext<'_>, 635 &self,
629 resolved: TraitId, 636 resolved: TraitId,
630 segment: PathSegment<'_>, 637 segment: PathSegment<'_>,
631 explicit_self_ty: Option<Ty>, 638 explicit_self_ty: Option<Ty>,
632 ) -> Self { 639 ) -> TraitRef {
633 let mut substs = TraitRef::substs_from_path(ctx, segment, resolved); 640 let mut substs = self.trait_ref_substs_from_path(segment, resolved);
634 if let Some(self_ty) = explicit_self_ty { 641 if let Some(self_ty) = explicit_self_ty {
635 make_mut_slice(&mut substs.0)[0] = self_ty; 642 substs.0[0] = self_ty;
636 } 643 }
637 TraitRef { trait_: resolved, substs } 644 TraitRef { trait_: resolved, substs }
638 } 645 }
639 646
640 fn from_hir( 647 fn lower_trait_ref(
641 ctx: &TyLoweringContext<'_>, 648 &self,
642 type_ref: &TypeRef, 649 type_ref: &TypeRef,
643 explicit_self_ty: Option<Ty>, 650 explicit_self_ty: Option<Ty>,
644 ) -> Option<Self> { 651 ) -> Option<TraitRef> {
645 let path = match type_ref { 652 let path = match type_ref {
646 TypeRef::Path(path) => path, 653 TypeRef::Path(path) => path,
647 _ => return None, 654 _ => return None,
648 }; 655 };
649 TraitRef::from_path(ctx, path, explicit_self_ty) 656 self.lower_trait_ref_from_path(path, explicit_self_ty)
650 } 657 }
651 658
652 fn substs_from_path( 659 fn trait_ref_substs_from_path(&self, segment: PathSegment<'_>, resolved: TraitId) -> Substs {
653 ctx: &TyLoweringContext<'_>, 660 self.substs_from_path_segment(segment, Some(resolved.into()), false)
654 segment: PathSegment<'_>,
655 resolved: TraitId,
656 ) -> Substs {
657 substs_from_path_segment(ctx, segment, Some(resolved.into()), false)
658 } 661 }
659}
660 662
661impl GenericPredicate { 663 pub(crate) fn lower_where_predicate(
662 pub(crate) fn from_where_predicate<'a>( 664 &'a self,
663 ctx: &'a TyLoweringContext<'a>,
664 where_predicate: &'a WherePredicate, 665 where_predicate: &'a WherePredicate,
665 ) -> impl Iterator<Item = GenericPredicate> + 'a { 666 ) -> impl Iterator<Item = GenericPredicate> + 'a {
666 match where_predicate { 667 match where_predicate {
667 WherePredicate::ForLifetime { target, bound, .. } 668 WherePredicate::ForLifetime { target, bound, .. }
668 | WherePredicate::TypeBound { target, bound } => { 669 | WherePredicate::TypeBound { target, bound } => {
669 let self_ty = match target { 670 let self_ty = match target {
670 WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref), 671 WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
671 WherePredicateTypeTarget::TypeParam(param_id) => { 672 WherePredicateTypeTarget::TypeParam(param_id) => {
672 let generic_def = ctx.resolver.generic_def().expect("generics in scope"); 673 let generic_def = self.resolver.generic_def().expect("generics in scope");
673 let generics = generics(ctx.db.upcast(), generic_def); 674 let generics = generics(self.db.upcast(), generic_def);
674 let param_id = 675 let param_id =
675 hir_def::TypeParamId { parent: generic_def, local_id: *param_id }; 676 hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
676 match ctx.type_param_mode { 677 let placeholder = to_placeholder_idx(self.db, param_id);
677 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 678 match self.type_param_mode {
679 TypeParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
678 TypeParamLoweringMode::Variable => { 680 TypeParamLoweringMode::Variable => {
679 let idx = generics.param_idx(param_id).expect("matching generics"); 681 let idx = generics.param_idx(param_id).expect("matching generics");
680 Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx)) 682 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
681 } 683 }
682 } 684 }
685 .intern(&Interner)
683 } 686 }
684 }; 687 };
685 GenericPredicate::from_type_bound(ctx, bound, self_ty) 688 self.lower_type_bound(bound, self_ty).collect::<Vec<_>>().into_iter()
686 .collect::<Vec<_>>()
687 .into_iter()
688 } 689 }
689 WherePredicate::Lifetime { .. } => vec![].into_iter(), 690 WherePredicate::Lifetime { .. } => vec![].into_iter(),
690 } 691 }
691 } 692 }
692 693
693 pub(crate) fn from_type_bound<'a>( 694 pub(crate) fn lower_type_bound(
694 ctx: &'a TyLoweringContext<'a>, 695 &'a self,
695 bound: &'a TypeBound, 696 bound: &'a TypeBound,
696 self_ty: Ty, 697 self_ty: Ty,
697 ) -> impl Iterator<Item = GenericPredicate> + 'a { 698 ) -> impl Iterator<Item = GenericPredicate> + 'a {
698 let mut bindings = None; 699 let mut bindings = None;
699 let trait_ref = match bound { 700 let trait_ref = match bound {
700 TypeBound::Path(path) => { 701 TypeBound::Path(path) => {
701 bindings = TraitRef::from_path(ctx, path, Some(self_ty)); 702 bindings = self.lower_trait_ref_from_path(path, Some(self_ty));
702 Some( 703 Some(
703 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented), 704 bindings.clone().map_or(GenericPredicate::Error, GenericPredicate::Implemented),
704 ) 705 )
@@ -709,64 +710,62 @@ impl GenericPredicate {
709 trait_ref.into_iter().chain( 710 trait_ref.into_iter().chain(
710 bindings 711 bindings
711 .into_iter() 712 .into_iter()
712 .flat_map(move |tr| assoc_type_bindings_from_type_bound(ctx, bound, tr)), 713 .flat_map(move |tr| self.assoc_type_bindings_from_type_bound(bound, tr)),
713 ) 714 )
714 } 715 }
715}
716 716
717fn assoc_type_bindings_from_type_bound<'a>( 717 fn assoc_type_bindings_from_type_bound(
718 ctx: &'a TyLoweringContext<'a>, 718 &'a self,
719 bound: &'a TypeBound, 719 bound: &'a TypeBound,
720 trait_ref: TraitRef, 720 trait_ref: TraitRef,
721) -> impl Iterator<Item = GenericPredicate> + 'a { 721 ) -> impl Iterator<Item = GenericPredicate> + 'a {
722 let last_segment = match bound { 722 let last_segment = match bound {
723 TypeBound::Path(path) => path.segments().last(), 723 TypeBound::Path(path) => path.segments().last(),
724 TypeBound::Error | TypeBound::Lifetime(_) => None, 724 TypeBound::Error | TypeBound::Lifetime(_) => None,
725 }; 725 };
726 last_segment 726 last_segment
727 .into_iter() 727 .into_iter()
728 .flat_map(|segment| segment.args_and_bindings.into_iter()) 728 .flat_map(|segment| segment.args_and_bindings.into_iter())
729 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter()) 729 .flat_map(|args_and_bindings| args_and_bindings.bindings.iter())
730 .flat_map(move |binding| { 730 .flat_map(move |binding| {
731 let found = associated_type_by_name_including_super_traits( 731 let found = associated_type_by_name_including_super_traits(
732 ctx.db, 732 self.db,
733 trait_ref.clone(), 733 trait_ref.clone(),
734 &binding.name, 734 &binding.name,
735 ); 735 );
736 let (super_trait_ref, associated_ty) = match found { 736 let (super_trait_ref, associated_ty) = match found {
737 None => return SmallVec::<[GenericPredicate; 1]>::new(), 737 None => return SmallVec::<[GenericPredicate; 1]>::new(),
738 Some(t) => t, 738 Some(t) => t,
739 }; 739 };
740 let projection_ty = ProjectionTy { associated_ty, parameters: super_trait_ref.substs }; 740 let projection_ty = ProjectionTy {
741 let mut preds = SmallVec::with_capacity( 741 associated_ty_id: to_assoc_type_id(associated_ty),
742 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(), 742 substitution: super_trait_ref.substs,
743 ); 743 };
744 if let Some(type_ref) = &binding.type_ref { 744 let mut preds = SmallVec::with_capacity(
745 let ty = Ty::from_hir(ctx, type_ref); 745 binding.type_ref.as_ref().map_or(0, |_| 1) + binding.bounds.len(),
746 let projection_predicate = 746 );
747 ProjectionPredicate { projection_ty: projection_ty.clone(), ty }; 747 if let Some(type_ref) = &binding.type_ref {
748 preds.push(GenericPredicate::Projection(projection_predicate)); 748 let ty = self.lower_ty(type_ref);
749 } 749 let projection_predicate =
750 for bound in &binding.bounds { 750 ProjectionPredicate { projection_ty: projection_ty.clone(), ty };
751 preds.extend(GenericPredicate::from_type_bound( 751 preds.push(GenericPredicate::Projection(projection_predicate));
752 ctx, 752 }
753 bound, 753 for bound in &binding.bounds {
754 Ty::Alias(AliasTy::Projection(projection_ty.clone())), 754 preds.extend(self.lower_type_bound(
755 )); 755 bound,
756 } 756 TyKind::Alias(AliasTy::Projection(projection_ty.clone())).intern(&Interner),
757 preds 757 ));
758 }) 758 }
759} 759 preds
760 })
761 }
760 762
761impl ReturnTypeImplTrait { 763 fn lower_impl_trait(&self, bounds: &[TypeBound]) -> ReturnTypeImplTrait {
762 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
763 cov_mark::hit!(lower_rpit); 764 cov_mark::hit!(lower_rpit);
764 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 765 let self_ty =
765 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 766 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(&Interner);
766 bounds 767 let predicates = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
767 .iter() 768 bounds.iter().flat_map(|b| ctx.lower_type_bound(b, self_ty.clone())).collect()
768 .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
769 .collect()
770 }); 769 });
771 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) } 770 ReturnTypeImplTrait { bounds: Binders::new(1, predicates) }
772 } 771 }
@@ -862,7 +861,7 @@ pub(crate) fn field_types_query(
862 let ctx = 861 let ctx =
863 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 862 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
864 for (field_id, field_data) in var_data.fields().iter() { 863 for (field_id, field_data) in var_data.fields().iter() {
865 res.insert(field_id, Binders::new(generics.len(), Ty::from_hir(&ctx, &field_data.type_ref))) 864 res.insert(field_id, Binders::new(generics.len(), ctx.lower_ty(&field_data.type_ref)))
866 } 865 }
867 Arc::new(res) 866 Arc::new(res)
868} 867}
@@ -890,16 +889,13 @@ pub(crate) fn generic_predicates_for_param_query(
890 WherePredicate::ForLifetime { target, .. } 889 WherePredicate::ForLifetime { target, .. }
891 | WherePredicate::TypeBound { target, .. } => match target { 890 | WherePredicate::TypeBound { target, .. } => match target {
892 WherePredicateTypeTarget::TypeRef(type_ref) => { 891 WherePredicateTypeTarget::TypeRef(type_ref) => {
893 Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id) 892 ctx.lower_ty_only_param(type_ref) == Some(param_id)
894 } 893 }
895 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id, 894 WherePredicateTypeTarget::TypeParam(local_id) => *local_id == param_id.local_id,
896 }, 895 },
897 WherePredicate::Lifetime { .. } => false, 896 WherePredicate::Lifetime { .. } => false,
898 }) 897 })
899 .flat_map(|pred| { 898 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
900 GenericPredicate::from_where_predicate(&ctx, pred)
901 .map(|p| Binders::new(generics.len(), p))
902 })
903 .collect() 899 .collect()
904} 900}
905 901
@@ -911,55 +907,55 @@ pub(crate) fn generic_predicates_for_param_recover(
911 Arc::new([]) 907 Arc::new([])
912} 908}
913 909
914impl TraitEnvironment { 910pub(crate) fn trait_environment_query(
915 pub fn lower(db: &dyn HirDatabase, resolver: &Resolver) -> Arc<TraitEnvironment> { 911 db: &dyn HirDatabase,
916 let ctx = TyLoweringContext::new(db, &resolver) 912 def: GenericDefId,
917 .with_type_param_mode(TypeParamLoweringMode::Placeholder); 913) -> Arc<TraitEnvironment> {
918 let mut traits_in_scope = Vec::new(); 914 let resolver = def.resolver(db.upcast());
919 let mut clauses = Vec::new(); 915 let ctx = TyLoweringContext::new(db, &resolver)
920 for pred in resolver.where_predicates_in_scope() { 916 .with_type_param_mode(TypeParamLoweringMode::Placeholder);
921 for pred in GenericPredicate::from_where_predicate(&ctx, pred) { 917 let mut traits_in_scope = Vec::new();
922 if pred.is_error() { 918 let mut clauses = Vec::new();
923 continue; 919 for pred in resolver.where_predicates_in_scope() {
924 } 920 for pred in ctx.lower_where_predicate(pred) {
925 if let GenericPredicate::Implemented(tr) = &pred { 921 if pred.is_error() {
926 traits_in_scope.push((tr.self_ty().clone(), tr.trait_)); 922 continue;
927 }
928 let program_clause: chalk_ir::ProgramClause<Interner> =
929 pred.clone().to_chalk(db).cast(&Interner);
930 clauses.push(program_clause.into_from_env_clause(&Interner));
931 } 923 }
932 } 924 if let GenericPredicate::Implemented(tr) = &pred {
933 925 traits_in_scope.push((tr.self_ty().clone(), tr.trait_));
934 if let Some(def) = resolver.generic_def() {
935 let container: Option<AssocContainerId> = match def {
936 // FIXME: is there a function for this?
937 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
938 GenericDefId::AdtId(_) => None,
939 GenericDefId::TraitId(_) => None,
940 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
941 GenericDefId::ImplId(_) => None,
942 GenericDefId::EnumVariantId(_) => None,
943 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
944 };
945 if let Some(AssocContainerId::TraitId(trait_id)) = container {
946 // add `Self: Trait<T1, T2, ...>` to the environment in trait
947 // function default implementations (and hypothetical code
948 // inside consts or type aliases)
949 cov_mark::hit!(trait_self_implements_self);
950 let substs = Substs::type_params(db, trait_id);
951 let trait_ref = TraitRef { trait_: trait_id, substs };
952 let pred = GenericPredicate::Implemented(trait_ref);
953 let program_clause: chalk_ir::ProgramClause<Interner> =
954 pred.clone().to_chalk(db).cast(&Interner);
955 clauses.push(program_clause.into_from_env_clause(&Interner));
956 } 926 }
927 let program_clause: chalk_ir::ProgramClause<Interner> =
928 pred.clone().to_chalk(db).cast(&Interner);
929 clauses.push(program_clause.into_from_env_clause(&Interner));
957 } 930 }
931 }
958 932
959 let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses); 933 let container: Option<AssocContainerId> = match def {
960 934 // FIXME: is there a function for this?
961 Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env }) 935 GenericDefId::FunctionId(f) => Some(f.lookup(db.upcast()).container),
936 GenericDefId::AdtId(_) => None,
937 GenericDefId::TraitId(_) => None,
938 GenericDefId::TypeAliasId(t) => Some(t.lookup(db.upcast()).container),
939 GenericDefId::ImplId(_) => None,
940 GenericDefId::EnumVariantId(_) => None,
941 GenericDefId::ConstId(c) => Some(c.lookup(db.upcast()).container),
942 };
943 if let Some(AssocContainerId::TraitId(trait_id)) = container {
944 // add `Self: Trait<T1, T2, ...>` to the environment in trait
945 // function default implementations (and hypothetical code
946 // inside consts or type aliases)
947 cov_mark::hit!(trait_self_implements_self);
948 let substs = Substs::type_params(db, trait_id);
949 let trait_ref = TraitRef { trait_: trait_id, substs };
950 let pred = GenericPredicate::Implemented(trait_ref);
951 let program_clause: chalk_ir::ProgramClause<Interner> =
952 pred.clone().to_chalk(db).cast(&Interner);
953 clauses.push(program_clause.into_from_env_clause(&Interner));
962 } 954 }
955
956 let env = chalk_ir::Environment::new(&Interner).add_clauses(&Interner, clauses);
957
958 Arc::new(TraitEnvironment { traits_from_clauses: traits_in_scope, env })
963} 959}
964 960
965/// Resolve the where clause(s) of an item with generics. 961/// Resolve the where clause(s) of an item with generics.
@@ -973,10 +969,7 @@ pub(crate) fn generic_predicates_query(
973 let generics = generics(db.upcast(), def); 969 let generics = generics(db.upcast(), def);
974 resolver 970 resolver
975 .where_predicates_in_scope() 971 .where_predicates_in_scope()
976 .flat_map(|pred| { 972 .flat_map(|pred| ctx.lower_where_predicate(pred).map(|p| Binders::new(generics.len(), p)))
977 GenericPredicate::from_where_predicate(&ctx, pred)
978 .map(|p| Binders::new(generics.len(), p))
979 })
980 .collect() 973 .collect()
981} 974}
982 975
@@ -994,17 +987,18 @@ pub(crate) fn generic_defaults_query(
994 .iter() 987 .iter()
995 .enumerate() 988 .enumerate()
996 .map(|(idx, (_, p))| { 989 .map(|(idx, (_, p))| {
997 let mut ty = p.default.as_ref().map_or(Ty::Unknown, |t| Ty::from_hir(&ctx, t)); 990 let mut ty =
991 p.default.as_ref().map_or(TyKind::Unknown.intern(&Interner), |t| ctx.lower_ty(t));
998 992
999 // Each default can only refer to previous parameters. 993 // Each default can only refer to previous parameters.
1000 ty.walk_mut_binders( 994 ty.walk_mut_binders(
1001 &mut |ty, binders| match ty { 995 &mut |ty, binders| match ty.interned_mut() {
1002 Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => { 996 TyKind::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => {
1003 if *index >= idx { 997 if *index >= idx {
1004 // type variable default referring to parameter coming 998 // type variable default referring to parameter coming
1005 // after it. This is forbidden (FIXME: report 999 // after it. This is forbidden (FIXME: report
1006 // diagnostic) 1000 // diagnostic)
1007 *ty = Ty::Unknown; 1001 *ty = TyKind::Unknown.intern(&Interner);
1008 } 1002 }
1009 } 1003 }
1010 _ => {} 1004 _ => {}
@@ -1025,11 +1019,11 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025 let ctx_params = TyLoweringContext::new(db, &resolver) 1019 let ctx_params = TyLoweringContext::new(db, &resolver)
1026 .with_impl_trait_mode(ImplTraitLoweringMode::Variable) 1020 .with_impl_trait_mode(ImplTraitLoweringMode::Variable)
1027 .with_type_param_mode(TypeParamLoweringMode::Variable); 1021 .with_type_param_mode(TypeParamLoweringMode::Variable);
1028 let params = data.params.iter().map(|tr| Ty::from_hir(&ctx_params, tr)).collect::<Vec<_>>(); 1022 let params = data.params.iter().map(|tr| (&ctx_params).lower_ty(tr)).collect::<Vec<_>>();
1029 let ctx_ret = TyLoweringContext::new(db, &resolver) 1023 let ctx_ret = TyLoweringContext::new(db, &resolver)
1030 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1024 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1031 .with_type_param_mode(TypeParamLoweringMode::Variable); 1025 .with_type_param_mode(TypeParamLoweringMode::Variable);
1032 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1026 let ret = (&ctx_ret).lower_ty(&data.ret_type);
1033 let generics = generics(db.upcast(), def.into()); 1027 let generics = generics(db.upcast(), def.into());
1034 let num_binders = generics.len(); 1028 let num_binders = generics.len();
1035 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs)) 1029 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
@@ -1040,7 +1034,10 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1040fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1034fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1041 let generics = generics(db.upcast(), def.into()); 1035 let generics = generics(db.upcast(), def.into());
1042 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1036 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1043 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1037 Binders::new(
1038 substs.len(),
1039 TyKind::FnDef(CallableDefId::FunctionId(def).to_chalk(db), substs).intern(&Interner),
1040 )
1044} 1041}
1045 1042
1046/// Build the declared type of a const. 1043/// Build the declared type of a const.
@@ -1051,7 +1048,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> Binders<Ty> {
1051 let ctx = 1048 let ctx =
1052 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1049 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1053 1050
1054 Binders::new(generics.len(), Ty::from_hir(&ctx, &data.type_ref)) 1051 Binders::new(generics.len(), ctx.lower_ty(&data.type_ref))
1055} 1052}
1056 1053
1057/// Build the declared type of a static. 1054/// Build the declared type of a static.
@@ -1060,7 +1057,7 @@ fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> Binders<Ty> {
1060 let resolver = def.resolver(db.upcast()); 1057 let resolver = def.resolver(db.upcast());
1061 let ctx = TyLoweringContext::new(db, &resolver); 1058 let ctx = TyLoweringContext::new(db, &resolver);
1062 1059
1063 Binders::new(0, Ty::from_hir(&ctx, &data.type_ref)) 1060 Binders::new(0, ctx.lower_ty(&data.type_ref))
1064} 1061}
1065 1062
1066fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig { 1063fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnSig {
@@ -1069,8 +1066,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1069 let resolver = def.resolver(db.upcast()); 1066 let resolver = def.resolver(db.upcast());
1070 let ctx = 1067 let ctx =
1071 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1068 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1072 let params = 1069 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1073 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1074 let ret = type_for_adt(db, def.into()); 1070 let ret = type_for_adt(db, def.into());
1075 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1071 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1076} 1072}
@@ -1083,7 +1079,10 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1083 } 1079 }
1084 let generics = generics(db.upcast(), def.into()); 1080 let generics = generics(db.upcast(), def.into());
1085 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1081 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1086 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1082 Binders::new(
1083 substs.len(),
1084 TyKind::FnDef(CallableDefId::StructId(def).to_chalk(db), substs).intern(&Interner),
1085 )
1087} 1086}
1088 1087
1089fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1088fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1093,8 +1092,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1093 let resolver = def.parent.resolver(db.upcast()); 1092 let resolver = def.parent.resolver(db.upcast());
1094 let ctx = 1093 let ctx =
1095 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1094 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1096 let params = 1095 let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
1097 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1098 let ret = type_for_adt(db, def.parent.into()); 1096 let ret = type_for_adt(db, def.parent.into());
1099 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false)) 1097 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1100} 1098}
@@ -1108,7 +1106,10 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1108 } 1106 }
1109 let generics = generics(db.upcast(), def.parent.into()); 1107 let generics = generics(db.upcast(), def.parent.into());
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1108 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1111 Binders::new(substs.len(), Ty::FnDef(def.into(), substs)) 1109 Binders::new(
1110 substs.len(),
1111 TyKind::FnDef(CallableDefId::EnumVariantId(def).to_chalk(db), substs).intern(&Interner),
1112 )
1112} 1113}
1113 1114
1114fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1115fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
@@ -1123,11 +1124,11 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1123 let ctx = 1124 let ctx =
1124 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1125 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1125 if db.type_alias_data(t).is_extern { 1126 if db.type_alias_data(t).is_extern {
1126 Binders::new(0, Ty::ForeignType(t)) 1127 Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
1127 } else { 1128 } else {
1128 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1129 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1129 let type_ref = &db.type_alias_data(t).type_ref; 1130 let type_ref = &db.type_alias_data(t).type_ref;
1130 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1131 let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
1131 Binders::new(substs.len(), inner) 1132 Binders::new(substs.len(), inner)
1132 } 1133 }
1133} 1134}
@@ -1199,7 +1200,7 @@ pub(crate) fn ty_recover(db: &dyn HirDatabase, _cycle: &[String], def: &TyDefId)
1199 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(), 1200 TyDefId::AdtId(it) => generics(db.upcast(), it.into()).len(),
1200 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(), 1201 TyDefId::TypeAliasId(it) => generics(db.upcast(), it.into()).len(),
1201 }; 1202 };
1202 Binders::new(num_binders, Ty::Unknown) 1203 Binders::new(num_binders, TyKind::Unknown.intern(&Interner))
1203} 1204}
1204 1205
1205pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> { 1206pub(crate) fn value_ty_query(db: &dyn HirDatabase, def: ValueTyDefId) -> Binders<Ty> {
@@ -1219,7 +1220,7 @@ pub(crate) fn impl_self_ty_query(db: &dyn HirDatabase, impl_id: ImplId) -> Binde
1219 let generics = generics(db.upcast(), impl_id.into()); 1220 let generics = generics(db.upcast(), impl_id.into());
1220 let ctx = 1221 let ctx =
1221 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1222 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1222 Binders::new(generics.len(), Ty::from_hir(&ctx, &impl_data.target_type)) 1223 Binders::new(generics.len(), ctx.lower_ty(&impl_data.target_type))
1223} 1224}
1224 1225
1225pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty { 1226pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> Ty {
@@ -1228,7 +1229,7 @@ pub(crate) fn const_param_ty_query(db: &dyn HirDatabase, def: ConstParamId) -> T
1228 let resolver = def.parent.resolver(db.upcast()); 1229 let resolver = def.parent.resolver(db.upcast());
1229 let ctx = TyLoweringContext::new(db, &resolver); 1230 let ctx = TyLoweringContext::new(db, &resolver);
1230 1231
1231 Ty::from_hir(&ctx, &data.ty) 1232 ctx.lower_ty(&data.ty)
1232} 1233}
1233 1234
1234pub(crate) fn impl_self_ty_recover( 1235pub(crate) fn impl_self_ty_recover(
@@ -1237,7 +1238,7 @@ pub(crate) fn impl_self_ty_recover(
1237 impl_id: &ImplId, 1238 impl_id: &ImplId,
1238) -> Binders<Ty> { 1239) -> Binders<Ty> {
1239 let generics = generics(db.upcast(), (*impl_id).into()); 1240 let generics = generics(db.upcast(), (*impl_id).into());
1240 Binders::new(generics.len(), Ty::Unknown) 1241 Binders::new(generics.len(), TyKind::Unknown.intern(&Interner))
1241} 1242}
1242 1243
1243pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> { 1244pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<Binders<TraitRef>> {
@@ -1247,10 +1248,7 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
1247 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1248 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1248 let self_ty = db.impl_self_ty(impl_id); 1249 let self_ty = db.impl_self_ty(impl_id);
1249 let target_trait = impl_data.target_trait.as_ref()?; 1250 let target_trait = impl_data.target_trait.as_ref()?;
1250 Some(Binders::new( 1251 Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?))
1251 self_ty.num_binders,
1252 TraitRef::from_hir(&ctx, target_trait, Some(self_ty.value))?,
1253 ))
1254} 1252}
1255 1253
1256pub(crate) fn return_type_impl_traits( 1254pub(crate) fn return_type_impl_traits(
@@ -1263,7 +1261,7 @@ pub(crate) fn return_type_impl_traits(
1263 let ctx_ret = TyLoweringContext::new(db, &resolver) 1261 let ctx_ret = TyLoweringContext::new(db, &resolver)
1264 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque) 1262 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque)
1265 .with_type_param_mode(TypeParamLoweringMode::Variable); 1263 .with_type_param_mode(TypeParamLoweringMode::Variable);
1266 let _ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1264 let _ret = (&ctx_ret).lower_ty(&data.ret_type);
1267 let generics = generics(db.upcast(), def.into()); 1265 let generics = generics(db.upcast(), def.into());
1268 let num_binders = generics.len(); 1266 let num_binders = generics.len();
1269 let return_type_impl_traits = 1267 let return_type_impl_traits =
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index d57c6de70..be72c4a1c 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -9,7 +9,7 @@ use base_db::CrateId;
9use chalk_ir::Mutability; 9use chalk_ir::Mutability;
10use hir_def::{ 10use hir_def::{
11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, 11 lang_item::LangItemTarget, AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule,
12 ImplId, Lookup, ModuleId, TraitId, TypeAliasId, 12 ImplId, Lookup, ModuleId, TraitId,
13}; 13};
14use hir_expand::name::Name; 14use hir_expand::name::Name;
15use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
@@ -17,10 +17,11 @@ use rustc_hash::{FxHashMap, FxHashSet};
17use crate::{ 17use crate::{
18 autoderef, 18 autoderef,
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id,
20 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
21 utils::all_super_traits, 22 utils::all_super_traits,
22 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, 23 AdtId, Canonical, DebruijnIndex, FnPointer, FnSig, ForeignDefId, InEnvironment, Interner,
23 TraitEnvironment, TraitRef, Ty, TypeWalk, 24 Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeWalk,
24}; 25};
25 26
26/// This is used as a key for indexing impls. 27/// This is used as a key for indexing impls.
@@ -35,7 +36,7 @@ pub enum TyFingerprint {
35 Adt(hir_def::AdtId), 36 Adt(hir_def::AdtId),
36 Dyn(TraitId), 37 Dyn(TraitId),
37 Tuple(usize), 38 Tuple(usize),
38 ForeignType(TypeAliasId), 39 ForeignType(ForeignDefId),
39 FnPtr(usize, FnSig), 40 FnPtr(usize, FnSig),
40} 41}
41 42
@@ -43,19 +44,21 @@ impl TyFingerprint {
43 /// Creates a TyFingerprint for looking up an impl. Only certain types can 44 /// Creates a TyFingerprint for looking up an impl. Only certain types can
44 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 45 /// 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. 46 /// `impl &S`. Hence, this will return `None` for reference types and such.
46 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 47 pub fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
47 let fp = match ty { 48 let fp = match *ty.interned(&Interner) {
48 &Ty::Str => TyFingerprint::Str, 49 TyKind::Str => TyFingerprint::Str,
49 &Ty::Never => TyFingerprint::Never, 50 TyKind::Never => TyFingerprint::Never,
50 &Ty::Slice(..) => TyFingerprint::Slice, 51 TyKind::Slice(..) => TyFingerprint::Slice,
51 &Ty::Array(..) => TyFingerprint::Array, 52 TyKind::Array(..) => TyFingerprint::Array,
52 &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar), 53 TyKind::Scalar(scalar) => TyFingerprint::Scalar(scalar),
53 &Ty::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt), 54 TyKind::Adt(AdtId(adt), _) => TyFingerprint::Adt(adt),
54 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality), 55 TyKind::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
55 &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability), 56 TyKind::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability),
56 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id), 57 TyKind::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
57 &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig), 58 TyKind::Function(FnPointer { num_args, sig, .. }) => {
58 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?, 59 TyFingerprint::FnPtr(num_args, sig)
60 }
61 TyKind::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
59 _ => return None, 62 _ => return None,
60 }; 63 };
61 Some(fp) 64 Some(fp)
@@ -138,6 +141,14 @@ impl TraitImpls {
138 } 141 }
139 } 142 }
140 143
144 /// Queries all trait impls for the given type.
145 pub fn for_self_ty(&self, fp: TyFingerprint) -> impl Iterator<Item = ImplId> + '_ {
146 self.map
147 .values()
148 .flat_map(move |impls| impls.get(&None).into_iter().chain(impls.get(&Some(fp))))
149 .flat_map(|it| it.iter().copied())
150 }
151
141 /// Queries all impls of the given trait. 152 /// Queries all impls of the given trait.
142 pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ { 153 pub fn for_trait(&self, trait_: TraitId) -> impl Iterator<Item = ImplId> + '_ {
143 self.map 154 self.map
@@ -230,31 +241,33 @@ impl Ty {
230 241
231 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 242 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
232 243
233 let lang_item_targets = match self { 244 let lang_item_targets = match self.interned(&Interner) {
234 Ty::Adt(AdtId(def_id), _) => { 245 TyKind::Adt(AdtId(def_id), _) => {
235 return mod_to_crate_ids(def_id.module(db.upcast())); 246 return mod_to_crate_ids(def_id.module(db.upcast()));
236 } 247 }
237 Ty::ForeignType(type_alias_id) => { 248 TyKind::ForeignType(id) => {
238 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 249 return mod_to_crate_ids(
250 from_foreign_def_id(*id).lookup(db.upcast()).module(db.upcast()),
251 );
239 } 252 }
240 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 253 TyKind::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
241 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"), 254 TyKind::Scalar(Scalar::Char) => lang_item_crate!("char"),
242 Ty::Scalar(Scalar::Float(f)) => match f { 255 TyKind::Scalar(Scalar::Float(f)) => match f {
243 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 256 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
244 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 257 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
245 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"), 258 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
246 }, 259 },
247 &Ty::Scalar(Scalar::Int(t)) => { 260 &TyKind::Scalar(Scalar::Int(t)) => {
248 lang_item_crate!(primitive::int_ty_to_string(t)) 261 lang_item_crate!(primitive::int_ty_to_string(t))
249 } 262 }
250 &Ty::Scalar(Scalar::Uint(t)) => { 263 &TyKind::Scalar(Scalar::Uint(t)) => {
251 lang_item_crate!(primitive::uint_ty_to_string(t)) 264 lang_item_crate!(primitive::uint_ty_to_string(t))
252 } 265 }
253 Ty::Str => lang_item_crate!("str_alloc", "str"), 266 TyKind::Str => lang_item_crate!("str_alloc", "str"),
254 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"), 267 TyKind::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
255 Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"), 268 TyKind::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
256 Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"), 269 TyKind::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
257 Ty::Dyn(_) => { 270 TyKind::Dyn(_) => {
258 return self.dyn_trait().and_then(|trait_| { 271 return self.dyn_trait().and_then(|trait_| {
259 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 272 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
260 }); 273 });
@@ -430,7 +443,7 @@ fn iterate_method_candidates_with_autoref(
430 } 443 }
431 let refed = Canonical { 444 let refed = Canonical {
432 kinds: deref_chain[0].kinds.clone(), 445 kinds: deref_chain[0].kinds.clone(),
433 value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())), 446 value: TyKind::Ref(Mutability::Not, deref_chain[0].value.clone()).intern(&Interner),
434 }; 447 };
435 if iterate_method_candidates_by_receiver( 448 if iterate_method_candidates_by_receiver(
436 &refed, 449 &refed,
@@ -446,7 +459,7 @@ fn iterate_method_candidates_with_autoref(
446 } 459 }
447 let ref_muted = Canonical { 460 let ref_muted = Canonical {
448 kinds: deref_chain[0].kinds.clone(), 461 kinds: deref_chain[0].kinds.clone(),
449 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())), 462 value: TyKind::Ref(Mutability::Mut, deref_chain[0].value.clone()).intern(&Interner),
450 }; 463 };
451 if iterate_method_candidates_by_receiver( 464 if iterate_method_candidates_by_receiver(
452 &ref_muted, 465 &ref_muted,
@@ -526,7 +539,7 @@ fn iterate_trait_method_candidates(
526 // if ty is `dyn Trait`, the trait doesn't need to be in scope 539 // if ty is `dyn Trait`, the trait doesn't need to be in scope
527 let inherent_trait = 540 let inherent_trait =
528 self_ty.value.dyn_trait().into_iter().flat_map(|t| all_super_traits(db.upcast(), t)); 541 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 { 542 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 543 // 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) 544 env.traits_in_scope_from_clauses(&self_ty.value)
532 .flat_map(|t| all_super_traits(db.upcast(), t)) 545 .flat_map(|t| all_super_traits(db.upcast(), t))
@@ -679,13 +692,13 @@ pub(crate) fn inherent_impl_substs(
679} 692}
680 693
681/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past 694/// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
682/// num_vars_to_keep) by `Ty::Unknown`. 695/// num_vars_to_keep) by `TyKind::Unknown`.
683fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 696fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
684 s.fold_binders( 697 s.fold_binders(
685 &mut |ty, binders| { 698 &mut |ty, binders| {
686 if let Ty::BoundVar(bound) = &ty { 699 if let TyKind::BoundVar(bound) = ty.interned(&Interner) {
687 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 700 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
688 Ty::Unknown 701 TyKind::Unknown.intern(&Interner)
689 } else { 702 } else {
690 ty 703 ty
691 } 704 }
@@ -772,9 +785,11 @@ fn autoderef_method_receiver(
772) -> Vec<Canonical<Ty>> { 785) -> Vec<Canonical<Ty>> {
773 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 786 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!) 787 // 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) { 788 if let Some(TyKind::Array(parameters)) =
789 deref_chain.last().map(|ty| ty.value.interned(&Interner))
790 {
776 let kinds = deref_chain.last().unwrap().kinds.clone(); 791 let kinds = deref_chain.last().unwrap().kinds.clone();
777 let unsized_ty = Ty::Slice(parameters.clone()); 792 let unsized_ty = TyKind::Slice(parameters.clone()).intern(&Interner);
778 deref_chain.push(Canonical { value: unsized_ty, kinds }) 793 deref_chain.push(Canonical { value: unsized_ty, kinds })
779 } 794 }
780 deref_chain 795 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/tests.rs b/crates/hir_ty/src/tests.rs
index fc770ea60..0a4141e69 100644
--- a/crates/hir_ty/src/tests.rs
+++ b/crates/hir_ty/src/tests.rs
@@ -19,6 +19,7 @@ use hir_def::{
19 item_scope::ItemScope, 19 item_scope::ItemScope,
20 keys, 20 keys,
21 nameres::DefMap, 21 nameres::DefMap,
22 src::HasSource,
22 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId, 23 AssocItemId, DefWithBodyId, LocalModuleId, Lookup, ModuleDefId,
23}; 24};
24use hir_expand::{db::AstDatabase, InFile}; 25use hir_expand::{db::AstDatabase, InFile};
@@ -195,18 +196,15 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
195 defs.sort_by_key(|def| match def { 196 defs.sort_by_key(|def| match def {
196 DefWithBodyId::FunctionId(it) => { 197 DefWithBodyId::FunctionId(it) => {
197 let loc = it.lookup(&db); 198 let loc = it.lookup(&db);
198 let tree = db.item_tree(loc.id.file_id); 199 loc.source(&db).value.syntax().text_range().start()
199 tree.source(&db, loc.id).syntax().text_range().start()
200 } 200 }
201 DefWithBodyId::ConstId(it) => { 201 DefWithBodyId::ConstId(it) => {
202 let loc = it.lookup(&db); 202 let loc = it.lookup(&db);
203 let tree = db.item_tree(loc.id.file_id); 203 loc.source(&db).value.syntax().text_range().start()
204 tree.source(&db, loc.id).syntax().text_range().start()
205 } 204 }
206 DefWithBodyId::StaticId(it) => { 205 DefWithBodyId::StaticId(it) => {
207 let loc = it.lookup(&db); 206 let loc = it.lookup(&db);
208 let tree = db.item_tree(loc.id.file_id); 207 loc.source(&db).value.syntax().text_range().start()
209 tree.source(&db, loc.id).syntax().text_range().start()
210 } 208 }
211 }); 209 });
212 for def in defs { 210 for def in defs {
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs
index fb3afaedc..af4f8bb11 100644
--- a/crates/hir_ty/src/tests/macros.rs
+++ b/crates/hir_ty/src/tests/macros.rs
@@ -216,6 +216,22 @@ fn expr_macro_expanded_in_various_places() {
216} 216}
217 217
218#[test] 218#[test]
219fn expr_macro_expanded_in_stmts() {
220 check_infer(
221 r#"
222 macro_rules! id { ($($es:tt)*) => { $($es)* } }
223 fn foo() {
224 id! { let a = (); }
225 }
226 "#,
227 expect![[r#"
228 !0..8 'leta=();': ()
229 57..84 '{ ...); } }': ()
230 "#]],
231 );
232}
233
234#[test]
219fn infer_type_value_macro_having_same_name() { 235fn infer_type_value_macro_having_same_name() {
220 check_infer( 236 check_infer(
221 r#" 237 r#"
diff --git a/crates/hir_ty/src/tests/traits.rs b/crates/hir_ty/src/tests/traits.rs
index e185b1c0a..93d3ad020 100644
--- a/crates/hir_ty/src/tests/traits.rs
+++ b/crates/hir_ty/src/tests/traits.rs
@@ -1699,7 +1699,7 @@ fn super_trait_assoc_type_bounds() {
1699 1699
1700#[test] 1700#[test]
1701fn fn_trait() { 1701fn fn_trait() {
1702 check_infer( 1702 check_infer_with_mismatches(
1703 r#" 1703 r#"
1704 trait FnOnce<Args> { 1704 trait FnOnce<Args> {
1705 type Output; 1705 type Output;
@@ -1727,7 +1727,7 @@ fn fn_trait() {
1727 1727
1728#[test] 1728#[test]
1729fn fn_ptr_and_item() { 1729fn fn_ptr_and_item() {
1730 check_infer( 1730 check_infer_with_mismatches(
1731 r#" 1731 r#"
1732 #[lang="fn_once"] 1732 #[lang="fn_once"]
1733 trait FnOnce<Args> { 1733 trait FnOnce<Args> {
@@ -1743,12 +1743,12 @@ fn fn_ptr_and_item() {
1743 struct Bar<T>(T); 1743 struct Bar<T>(T);
1744 1744
1745 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> { 1745 impl<A1, R, F: FnOnce(A1) -> R> Foo<(A1, R)> for Bar<F> {
1746 fn foo(&self) -> (A1, R) {} 1746 fn foo(&self) -> (A1, R) { loop {} }
1747 } 1747 }
1748 1748
1749 enum Opt<T> { None, Some(T) } 1749 enum Opt<T> { None, Some(T) }
1750 impl<T> Opt<T> { 1750 impl<T> Opt<T> {
1751 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> {} 1751 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Opt<U> { loop {} }
1752 } 1752 }
1753 1753
1754 fn test() { 1754 fn test() {
@@ -1765,19 +1765,23 @@ fn fn_ptr_and_item() {
1765 80..84 'args': Args 1765 80..84 'args': Args
1766 139..143 'self': &Self 1766 139..143 'self': &Self
1767 243..247 'self': &Bar<F> 1767 243..247 'self': &Bar<F>
1768 260..262 '{}': () 1768 260..271 '{ loop {} }': (A1, R)
1769 346..350 'self': Opt<T> 1769 262..269 'loop {}': !
1770 352..353 'f': F 1770 267..269 '{}': ()
1771 368..370 '{}': () 1771 355..359 'self': Opt<T>
1772 384..500 '{ ...(f); }': () 1772 361..362 'f': F
1773 394..397 'bar': Bar<fn(u8) -> u32> 1773 377..388 '{ loop {} }': Opt<U>
1774 423..426 'bar': Bar<fn(u8) -> u32> 1774 379..386 'loop {}': !
1775 423..432 'bar.foo()': (u8, u32) 1775 384..386 '{}': ()
1776 443..446 'opt': Opt<u8> 1776 402..518 '{ ...(f); }': ()
1777 465..466 'f': fn(u8) -> u32 1777 412..415 'bar': Bar<fn(u8) -> u32>
1778 487..490 'opt': Opt<u8> 1778 441..444 'bar': Bar<fn(u8) -> u32>
1779 487..497 'opt.map(f)': Opt<u32> 1779 441..450 'bar.foo()': (u8, u32)
1780 495..496 'f': fn(u8) -> u32 1780 461..464 'opt': Opt<u8>
1781 483..484 'f': fn(u8) -> u32
1782 505..508 'opt': Opt<u8>
1783 505..515 'opt.map(f)': Opt<u32>
1784 513..514 'f': fn(u8) -> u32
1781 "#]], 1785 "#]],
1782 ); 1786 );
1783} 1787}
@@ -1859,7 +1863,7 @@ fn fn_trait_deref_with_ty_default() {
1859 1863
1860#[test] 1864#[test]
1861fn closure_1() { 1865fn closure_1() {
1862 check_infer( 1866 check_infer_with_mismatches(
1863 r#" 1867 r#"
1864 #[lang = "fn_once"] 1868 #[lang = "fn_once"]
1865 trait FnOnce<Args> { 1869 trait FnOnce<Args> {
@@ -1868,7 +1872,7 @@ fn closure_1() {
1868 1872
1869 enum Option<T> { Some(T), None } 1873 enum Option<T> { Some(T), None }
1870 impl<T> Option<T> { 1874 impl<T> Option<T> {
1871 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {} 1875 fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> { loop {} }
1872 } 1876 }
1873 1877
1874 fn test() { 1878 fn test() {
@@ -1881,37 +1885,39 @@ fn closure_1() {
1881 expect![[r#" 1885 expect![[r#"
1882 147..151 'self': Option<T> 1886 147..151 'self': Option<T>
1883 153..154 'f': F 1887 153..154 'f': F
1884 172..174 '{}': () 1888 172..183 '{ loop {} }': Option<U>
1885 188..307 '{ ... 1); }': () 1889 174..181 'loop {}': !
1886 198..199 'x': Option<u32> 1890 179..181 '{}': ()
1887 202..214 'Option::Some': Some<u32>(u32) -> Option<u32> 1891 197..316 '{ ... 1); }': ()
1888 202..220 'Option...(1u32)': Option<u32> 1892 207..208 'x': Option<u32>
1889 215..219 '1u32': u32 1893 211..223 'Option::Some': Some<u32>(u32) -> Option<u32>
1890 226..227 'x': Option<u32> 1894 211..229 'Option...(1u32)': Option<u32>
1891 226..242 'x.map(...v + 1)': Option<u32> 1895 224..228 '1u32': u32
1892 232..241 '|v| v + 1': |u32| -> u32 1896 235..236 'x': Option<u32>
1893 233..234 'v': u32 1897 235..251 'x.map(...v + 1)': Option<u32>
1894 236..237 'v': u32 1898 241..250 '|v| v + 1': |u32| -> u32
1895 236..241 'v + 1': u32 1899 242..243 'v': u32
1896 240..241 '1': u32 1900 245..246 'v': u32
1897 248..249 'x': Option<u32> 1901 245..250 'v + 1': u32
1898 248..264 'x.map(... 1u64)': Option<u64> 1902 249..250 '1': u32
1899 254..263 '|_v| 1u64': |u32| -> u64 1903 257..258 'x': Option<u32>
1900 255..257 '_v': u32 1904 257..273 'x.map(... 1u64)': Option<u64>
1901 259..263 '1u64': u64 1905 263..272 '|_v| 1u64': |u32| -> u64
1902 274..275 'y': Option<i64> 1906 264..266 '_v': u32
1903 291..292 'x': Option<u32> 1907 268..272 '1u64': u64
1904 291..304 'x.map(|_v| 1)': Option<i64> 1908 283..284 'y': Option<i64>
1905 297..303 '|_v| 1': |u32| -> i64 1909 300..301 'x': Option<u32>
1906 298..300 '_v': u32 1910 300..313 'x.map(|_v| 1)': Option<i64>
1907 302..303 '1': i64 1911 306..312 '|_v| 1': |u32| -> i64
1912 307..309 '_v': u32
1913 311..312 '1': i64
1908 "#]], 1914 "#]],
1909 ); 1915 );
1910} 1916}
1911 1917
1912#[test] 1918#[test]
1913fn closure_2() { 1919fn closure_2() {
1914 check_infer( 1920 check_infer_with_mismatches(
1915 r#" 1921 r#"
1916 trait FnOnce<Args> { 1922 trait FnOnce<Args> {
1917 type Output; 1923 type Output;
@@ -1951,22 +1957,22 @@ fn closure_2() {
1951 1957
1952#[test] 1958#[test]
1953fn closure_as_argument_inference_order() { 1959fn closure_as_argument_inference_order() {
1954 check_infer( 1960 check_infer_with_mismatches(
1955 r#" 1961 r#"
1956 #[lang = "fn_once"] 1962 #[lang = "fn_once"]
1957 trait FnOnce<Args> { 1963 trait FnOnce<Args> {
1958 type Output; 1964 type Output;
1959 } 1965 }
1960 1966
1961 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U {} 1967 fn foo1<T, U, F: FnOnce(T) -> U>(x: T, f: F) -> U { loop {} }
1962 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U {} 1968 fn foo2<T, U, F: FnOnce(T) -> U>(f: F, x: T) -> U { loop {} }
1963 1969
1964 struct S; 1970 struct S;
1965 impl S { 1971 impl S {
1966 fn method(self) -> u64; 1972 fn method(self) -> u64;
1967 1973
1968 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U {} 1974 fn foo1<T, U, F: FnOnce(T) -> U>(self, x: T, f: F) -> U { loop {} }
1969 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U {} 1975 fn foo2<T, U, F: FnOnce(T) -> U>(self, f: F, x: T) -> U { loop {} }
1970 } 1976 }
1971 1977
1972 fn test() { 1978 fn test() {
@@ -1979,52 +1985,60 @@ fn closure_as_argument_inference_order() {
1979 expect![[r#" 1985 expect![[r#"
1980 94..95 'x': T 1986 94..95 'x': T
1981 100..101 'f': F 1987 100..101 'f': F
1982 111..113 '{}': () 1988 111..122 '{ loop {} }': U
1983 147..148 'f': F 1989 113..120 'loop {}': !
1984 153..154 'x': T 1990 118..120 '{}': ()
1985 164..166 '{}': () 1991 156..157 'f': F
1986 201..205 'self': S 1992 162..163 'x': T
1987 253..257 'self': S 1993 173..184 '{ loop {} }': U
1988 259..260 'x': T 1994 175..182 'loop {}': !
1989 265..266 'f': F 1995 180..182 '{}': ()
1990 276..278 '{}': () 1996 219..223 'self': S
1991 316..320 'self': S 1997 271..275 'self': S
1992 322..323 'f': F 1998 277..278 'x': T
1993 328..329 'x': T 1999 283..284 'f': F
1994 339..341 '{}': () 2000 294..305 '{ loop {} }': U
1995 355..514 '{ ... S); }': () 2001 296..303 'loop {}': !
1996 365..367 'x1': u64 2002 301..303 '{}': ()
1997 370..374 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64 2003 343..347 'self': S
1998 370..393 'foo1(S...hod())': u64 2004 349..350 'f': F
1999 375..376 'S': S 2005 355..356 'x': T
2000 378..392 '|s| s.method()': |S| -> u64 2006 366..377 '{ loop {} }': U
2001 379..380 's': S 2007 368..375 'loop {}': !
2002 382..383 's': S 2008 373..375 '{}': ()
2003 382..392 's.method()': u64 2009 391..550 '{ ... S); }': ()
2004 403..405 'x2': u64 2010 401..403 'x1': u64
2005 408..412 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64 2011 406..410 'foo1': fn foo1<S, u64, |S| -> u64>(S, |S| -> u64) -> u64
2006 408..431 'foo2(|...(), S)': u64 2012 406..429 'foo1(S...hod())': u64
2007 413..427 '|s| s.method()': |S| -> u64 2013 411..412 'S': S
2008 414..415 's': S 2014 414..428 '|s| s.method()': |S| -> u64
2009 417..418 's': S 2015 415..416 's': S
2010 417..427 's.method()': u64 2016 418..419 's': S
2011 429..430 'S': S 2017 418..428 's.method()': u64
2012 441..443 'x3': u64 2018 439..441 'x2': u64
2013 446..447 'S': S 2019 444..448 'foo2': fn foo2<S, u64, |S| -> u64>(|S| -> u64, S) -> u64
2014 446..471 'S.foo1...hod())': u64 2020 444..467 'foo2(|...(), S)': u64
2015 453..454 'S': S 2021 449..463 '|s| s.method()': |S| -> u64
2016 456..470 '|s| s.method()': |S| -> u64 2022 450..451 's': S
2017 457..458 's': S 2023 453..454 's': S
2018 460..461 's': S 2024 453..463 's.method()': u64
2019 460..470 's.method()': u64 2025 465..466 'S': S
2020 481..483 'x4': u64 2026 477..479 'x3': u64
2021 486..487 'S': S 2027 482..483 'S': S
2022 486..511 'S.foo2...(), S)': u64 2028 482..507 'S.foo1...hod())': u64
2023 493..507 '|s| s.method()': |S| -> u64 2029 489..490 'S': S
2024 494..495 's': S 2030 492..506 '|s| s.method()': |S| -> u64
2025 497..498 's': S 2031 493..494 's': S
2026 497..507 's.method()': u64 2032 496..497 's': S
2027 509..510 'S': S 2033 496..506 's.method()': u64
2034 517..519 'x4': u64
2035 522..523 'S': S
2036 522..547 'S.foo2...(), S)': u64
2037 529..543 '|s| s.method()': |S| -> u64
2038 530..531 's': S
2039 533..534 's': S
2040 533..543 's.method()': u64
2041 545..546 'S': S
2028 "#]], 2042 "#]],
2029 ); 2043 );
2030} 2044}
@@ -2536,7 +2550,7 @@ fn test() {
2536 2550
2537#[test] 2551#[test]
2538fn iterator_chain() { 2552fn iterator_chain() {
2539 check_infer( 2553 check_infer_with_mismatches(
2540 r#" 2554 r#"
2541 //- /main.rs 2555 //- /main.rs
2542 #[lang = "fn_once"] 2556 #[lang = "fn_once"]
@@ -2939,7 +2953,7 @@ fn infer_closure_arg() {
2939 2953
2940#[test] 2954#[test]
2941fn infer_fn_trait_arg() { 2955fn infer_fn_trait_arg() {
2942 check_infer( 2956 check_infer_with_mismatches(
2943 r#" 2957 r#"
2944 //- /lib.rs deps:std 2958 //- /lib.rs deps:std
2945 2959
@@ -2986,7 +3000,8 @@ fn infer_fn_trait_arg() {
2986 3000
2987#[test] 3001#[test]
2988fn infer_box_fn_arg() { 3002fn infer_box_fn_arg() {
2989 check_infer( 3003 // The type mismatch is a bug
3004 check_infer_with_mismatches(
2990 r#" 3005 r#"
2991 //- /lib.rs deps:std 3006 //- /lib.rs deps:std
2992 3007
@@ -3025,7 +3040,7 @@ fn infer_box_fn_arg() {
3025 fn foo() { 3040 fn foo() {
3026 let s = Option::None; 3041 let s = Option::None;
3027 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {}); 3042 let f: Box<dyn FnOnce(&Option<i32>)> = box (|ps| {});
3028 f(&s) 3043 f(&s);
3029 } 3044 }
3030 "#, 3045 "#,
3031 expect![[r#" 3046 expect![[r#"
@@ -3037,7 +3052,7 @@ fn infer_box_fn_arg() {
3037 406..417 '&self.inner': &*mut T 3052 406..417 '&self.inner': &*mut T
3038 407..411 'self': &Box<T> 3053 407..411 'self': &Box<T>
3039 407..417 'self.inner': *mut T 3054 407..417 'self.inner': *mut T
3040 478..575 '{ ...(&s) }': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3055 478..576 '{ ...&s); }': ()
3041 488..489 's': Option<i32> 3056 488..489 's': Option<i32>
3042 492..504 'Option::None': Option<i32> 3057 492..504 'Option::None': Option<i32>
3043 514..515 'f': Box<dyn FnOnce(&Option<i32>)> 3058 514..515 'f': Box<dyn FnOnce(&Option<i32>)>
@@ -3049,6 +3064,7 @@ fn infer_box_fn_arg() {
3049 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)> 3064 568..573 'f(&s)': FnOnce::Output<dyn FnOnce(&Option<i32>), (&Option<i32>,)>
3050 570..572 '&s': &Option<i32> 3065 570..572 '&s': &Option<i32>
3051 571..572 's': Option<i32> 3066 571..572 's': Option<i32>
3067 549..562: expected Box<dyn FnOnce(&Option<i32>)>, got Box<|_| -> ()>
3052 "#]], 3068 "#]],
3053 ); 3069 );
3054} 3070}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index 27f350f70..a6a63c673 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
@@ -61,6 +63,15 @@ impl TraitEnvironment {
61 } 63 }
62} 64}
63 65
66impl Default for TraitEnvironment {
67 fn default() -> Self {
68 TraitEnvironment {
69 traits_from_clauses: Vec::new(),
70 env: chalk_ir::Environment::new(&Interner),
71 }
72 }
73}
74
64/// Something (usually a goal), along with an environment. 75/// Something (usually a goal), along with an environment.
65#[derive(Clone, Debug, PartialEq, Eq, Hash)] 76#[derive(Clone, Debug, PartialEq, Eq, Hash)]
66pub struct InEnvironment<T> { 77pub struct InEnvironment<T> {
@@ -132,7 +143,7 @@ pub(crate) fn trait_solve_query(
132 log::info!("trait_solve_query({})", goal.value.value.display(db)); 143 log::info!("trait_solve_query({})", goal.value.value.display(db));
133 144
134 if let Obligation::Projection(pred) = &goal.value.value { 145 if let Obligation::Projection(pred) = &goal.value.value {
135 if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] { 146 if let TyKind::BoundVar(_) = &pred.projection_ty.substitution[0].interned(&Interner) {
136 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 147 // 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)); 148 return Some(Solution::Ambig(Guidance::Unknown));
138 } 149 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 1a2a3a8c7..4bd8ba303 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -17,16 +17,18 @@ use super::ChalkContext;
17use crate::{ 17use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 display::HirDisplay, 19 display::HirDisplay,
20 from_assoc_type_id,
20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 21 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
22 to_assoc_type_id,
21 utils::generics, 23 utils::generics,
22 BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate, 24 BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, GenericPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, 25 ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TyKind,
24}; 26};
25use mapping::{ 27use mapping::{
26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, 28 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
27 TypeAliasAsValue,
28}; 29};
29 30
31pub use self::interner::Interner;
30pub(crate) use self::interner::*; 32pub(crate) use self::interner::*;
31 33
32pub(super) mod tls; 34pub(super) mod tls;
@@ -90,7 +92,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
90 ty: &Ty, 92 ty: &Ty,
91 binders: &CanonicalVarKinds<Interner>, 93 binders: &CanonicalVarKinds<Interner>,
92 ) -> Option<chalk_ir::TyVariableKind> { 94 ) -> Option<chalk_ir::TyVariableKind> {
93 if let Ty::BoundVar(bv) = ty { 95 if let TyKind::BoundVar(bv) = ty.interned(&Interner) {
94 let binders = binders.as_slice(&Interner); 96 let binders = binders.as_slice(&Interner);
95 if bv.debruijn == DebruijnIndex::INNERMOST { 97 if bv.debruijn == DebruijnIndex::INNERMOST {
96 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { 98 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
@@ -175,10 +177,9 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
175 } 177 }
176 178
177 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> { 179 fn opaque_ty_data(&self, id: chalk_ir::OpaqueTyId<Interner>) -> Arc<OpaqueTyDatum> {
178 let interned_id = crate::db::InternedOpaqueTyId::from(id); 180 let full_id = self.db.lookup_intern_impl_trait_id(id.into());
179 let full_id = self.db.lookup_intern_impl_trait_id(interned_id);
180 let bound = match full_id { 181 let bound = match full_id {
181 crate::OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 182 crate::ImplTraitId::ReturnTypeImplTrait(func, idx) => {
182 let datas = self 183 let datas = self
183 .db 184 .db
184 .return_type_impl_traits(func) 185 .return_type_impl_traits(func)
@@ -200,7 +201,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
200 let num_vars = datas.num_binders; 201 let num_vars = datas.num_binders;
201 make_binders(bound, num_vars) 202 make_binders(bound, num_vars)
202 } 203 }
203 crate::OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 204 crate::ImplTraitId::AsyncBlockTypeImplTrait(..) => {
204 if let Some((future_trait, future_output)) = self 205 if let Some((future_trait, future_output)) = self
205 .db 206 .db
206 .lang_item(self.krate, "future_trait".into()) 207 .lang_item(self.krate, "future_trait".into())
@@ -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_id: to_assoc_type_id(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 substitution: 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 {
@@ -378,7 +383,7 @@ pub(crate) fn associated_ty_data_query(
378 id: AssocTypeId, 383 id: AssocTypeId,
379) -> Arc<AssociatedTyDatum> { 384) -> Arc<AssociatedTyDatum> {
380 debug!("associated_ty_data {:?}", id); 385 debug!("associated_ty_data {:?}", id);
381 let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(db, id).0; 386 let type_alias: TypeAliasId = from_assoc_type_id(id);
382 let trait_ = match type_alias.lookup(db.upcast()).container { 387 let trait_ = match type_alias.lookup(db.upcast()).container {
383 AssocContainerId::TraitId(t) => t, 388 AssocContainerId::TraitId(t) => t,
384 _ => panic!("associated type not in trait"), 389 _ => panic!("associated type not in trait"),
@@ -391,11 +396,12 @@ 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()
398 .flat_map(|bound| GenericPredicate::from_type_bound(&ctx, bound, self_ty.clone())) 404 .flat_map(|bound| ctx.lower_type_bound(bound, self_ty.clone()))
399 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty)) 405 .filter_map(|pred| generic_predicate_to_inline_bound(db, &pred, &self_ty))
400 .map(|bound| make_binders(bound.shifted_in(&Interner), 0)) 406 .map(|bound| make_binders(bound.shifted_in(&Interner), 0))
401 .collect(); 407 .collect();
@@ -423,7 +429,7 @@ pub(crate) fn trait_datum_query(
423 let generic_params = generics(db.upcast(), trait_.into()); 429 let generic_params = generics(db.upcast(), trait_.into());
424 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST); 430 let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
425 let flags = rust_ir::TraitFlags { 431 let flags = rust_ir::TraitFlags {
426 auto: trait_data.auto, 432 auto: trait_data.is_auto,
427 upstream: trait_.lookup(db.upcast()).container.krate() != krate, 433 upstream: trait_.lookup(db.upcast()).container.krate() != krate,
428 non_enumerable: true, 434 non_enumerable: true,
429 coinductive: false, // only relevant for Chalk testing 435 coinductive: false, // only relevant for Chalk testing
@@ -432,10 +438,8 @@ pub(crate) fn trait_datum_query(
432 fundamental: false, 438 fundamental: false,
433 }; 439 };
434 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars); 440 let where_clauses = convert_where_clauses(db, trait_.into(), &bound_vars);
435 let associated_ty_ids = trait_data 441 let associated_ty_ids =
436 .associated_types() 442 trait_data.associated_types().map(|type_alias| to_assoc_type_id(type_alias)).collect();
437 .map(|type_alias| TypeAliasAsAssocType(type_alias).to_chalk(db))
438 .collect();
439 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses }; 443 let trait_datum_bound = rust_ir::TraitDatumBound { where_clauses };
440 let well_known = 444 let well_known =
441 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name)); 445 lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
@@ -617,7 +621,7 @@ fn type_alias_associated_ty_value(
617 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) }; 621 let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
618 let value = rust_ir::AssociatedTyValue { 622 let value = rust_ir::AssociatedTyValue {
619 impl_id: impl_id.to_chalk(db), 623 impl_id: impl_id.to_chalk(db),
620 associated_ty_id: TypeAliasAsAssocType(assoc_ty).to_chalk(db), 624 associated_ty_id: to_assoc_type_id(assoc_ty),
621 value: make_binders(value_bound, ty.num_binders), 625 value: make_binders(value_bound, ty.num_binders),
622 }; 626 };
623 Arc::new(value) 627 Arc::new(value)
@@ -711,14 +715,14 @@ impl From<crate::db::InternedOpaqueTyId> for OpaqueTyId {
711 } 715 }
712} 716}
713 717
714impl From<chalk_ir::ClosureId<Interner>> for crate::db::ClosureId { 718impl From<chalk_ir::ClosureId<Interner>> for crate::db::InternedClosureId {
715 fn from(id: chalk_ir::ClosureId<Interner>) -> Self { 719 fn from(id: chalk_ir::ClosureId<Interner>) -> Self {
716 Self::from_intern_id(id.0) 720 Self::from_intern_id(id.0)
717 } 721 }
718} 722}
719 723
720impl From<crate::db::ClosureId> for chalk_ir::ClosureId<Interner> { 724impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
721 fn from(id: crate::db::ClosureId) -> Self { 725 fn from(id: crate::db::InternedClosureId) -> Self {
722 chalk_ir::ClosureId(id.as_intern_id()) 726 chalk_ir::ClosureId(id.as_intern_id())
723 } 727 }
724} 728}
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index 54bd1c724..94e94a26d 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -5,6 +5,7 @@ use super::tls;
5use base_db::salsa::InternId; 5use base_db::salsa::InternId;
6use chalk_ir::{GenericArg, Goal, GoalData}; 6use chalk_ir::{GenericArg, Goal, GoalData};
7use hir_def::TypeAliasId; 7use hir_def::TypeAliasId;
8use smallvec::SmallVec;
8use std::{fmt, sync::Arc}; 9use std::{fmt, sync::Arc};
9 10
10#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 11#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
@@ -12,7 +13,6 @@ pub struct Interner;
12 13
13pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>; 14pub(crate) type AssocTypeId = chalk_ir::AssocTypeId<Interner>;
14pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>; 15pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
15pub(crate) type ForeignDefId = chalk_ir::ForeignDefId<Interner>;
16pub(crate) type TraitId = chalk_ir::TraitId<Interner>; 16pub(crate) type TraitId = chalk_ir::TraitId<Interner>;
17pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>; 17pub(crate) type TraitDatum = chalk_solve::rust_ir::TraitDatum<Interner>;
18pub(crate) type AdtId = chalk_ir::AdtId<Interner>; 18pub(crate) type AdtId = chalk_ir::AdtId<Interner>;
@@ -21,7 +21,6 @@ pub(crate) type ImplId = chalk_ir::ImplId<Interner>;
21pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>; 21pub(crate) type ImplDatum = chalk_solve::rust_ir::ImplDatum<Interner>;
22pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>; 22pub(crate) type AssociatedTyValueId = chalk_solve::rust_ir::AssociatedTyValueId<Interner>;
23pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>; 23pub(crate) type AssociatedTyValue = chalk_solve::rust_ir::AssociatedTyValue<Interner>;
24pub(crate) type FnDefId = chalk_ir::FnDefId<Interner>;
25pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>; 24pub(crate) type FnDefDatum = chalk_solve::rust_ir::FnDefDatum<Interner>;
26pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 25pub(crate) type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
27pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>; 26pub(crate) type OpaqueTyDatum = chalk_solve::rust_ir::OpaqueTyDatum<Interner>;
@@ -35,7 +34,7 @@ impl chalk_ir::interner::Interner for Interner {
35 type InternedGenericArg = chalk_ir::GenericArgData<Self>; 34 type InternedGenericArg = chalk_ir::GenericArgData<Self>;
36 type InternedGoal = Arc<GoalData<Self>>; 35 type InternedGoal = Arc<GoalData<Self>>;
37 type InternedGoals = Vec<Goal<Self>>; 36 type InternedGoals = Vec<Goal<Self>>;
38 type InternedSubstitution = Vec<GenericArg<Self>>; 37 type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>;
39 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; 38 type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
40 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; 39 type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
41 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; 40 type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
@@ -267,13 +266,13 @@ impl chalk_ir::interner::Interner for Interner {
267 fn intern_substitution<E>( 266 fn intern_substitution<E>(
268 &self, 267 &self,
269 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, 268 data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
270 ) -> Result<Vec<GenericArg<Self>>, E> { 269 ) -> Result<Self::InternedSubstitution, E> {
271 data.into_iter().collect() 270 data.into_iter().collect()
272 } 271 }
273 272
274 fn substitution_data<'a>( 273 fn substitution_data<'a>(
275 &self, 274 &self,
276 substitution: &'a Vec<GenericArg<Self>>, 275 substitution: &'a Self::InternedSubstitution,
277 ) -> &'a [GenericArg<Self>] { 276 ) -> &'a [GenericArg<Self>] {
278 substitution 277 substitution
279 } 278 }
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index b0415e8b0..6a8b6752e 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -3,10 +3,7 @@
3//! Chalk (in both directions); plus some helper functions for more specialized 3//! Chalk (in both directions); plus some helper functions for more specialized
4//! conversions. 4//! conversions.
5 5
6use chalk_ir::{ 6use chalk_ir::{cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData};
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex,
8 UniverseIndex,
9};
10use chalk_solve::rust_ir; 7use chalk_solve::rust_ir;
11 8
12use base_db::salsa::InternKey; 9use base_db::salsa::InternKey;
@@ -14,10 +11,11 @@ use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId};
14 11
15use crate::{ 12use crate::{
16 db::HirDatabase, 13 db::HirDatabase,
14 from_assoc_type_id,
17 primitive::UintTy, 15 primitive::UintTy,
18 traits::{Canonical, Obligation}, 16 traits::{Canonical, Obligation},
19 AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, 17 AliasTy, CallableDefId, FnPointer, GenericPredicate, InEnvironment, OpaqueTy,
20 OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty, 18 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitRef, Ty,
21}; 19};
22 20
23use super::interner::*; 21use super::interner::*;
@@ -26,71 +24,60 @@ use super::*;
26impl ToChalk for Ty { 24impl ToChalk for Ty {
27 type Chalk = chalk_ir::Ty<Interner>; 25 type Chalk = chalk_ir::Ty<Interner>;
28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 26 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
29 match self { 27 match self.into_inner() {
30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters), 28 TyKind::Ref(m, ty) => ref_to_chalk(db, m, ty),
31 Ty::Array(parameters) => array_to_chalk(db, parameters), 29 TyKind::Array(ty) => array_to_chalk(db, ty),
32 Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => { 30 TyKind::Function(FnPointer { sig, substs, .. }) => {
33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner)); 31 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
34 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 32 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
35 num_binders: 0, 33 num_binders: 0,
36 sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic }, 34 sig,
37 substitution, 35 substitution,
38 }) 36 })
39 .intern(&Interner) 37 .intern(&Interner)
40 } 38 }
41 Ty::AssociatedType(type_alias, substs) => { 39 TyKind::AssociatedType(assoc_type_id, substs) => {
42 let assoc_type = TypeAliasAsAssocType(type_alias);
43 let assoc_type_id = assoc_type.to_chalk(db);
44 let substitution = substs.to_chalk(db); 40 let substitution = substs.to_chalk(db);
45 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner) 41 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
46 } 42 }
47 43
48 Ty::OpaqueType(impl_trait_id, substs) => { 44 TyKind::OpaqueType(id, substs) => {
49 let id = impl_trait_id.to_chalk(db);
50 let substitution = substs.to_chalk(db); 45 let substitution = substs.to_chalk(db);
51 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) 46 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
52 } 47 }
53 48
54 Ty::ForeignType(type_alias) => { 49 TyKind::ForeignType(id) => chalk_ir::TyKind::Foreign(id).intern(&Interner),
55 let foreign_type = TypeAliasAsForeignType(type_alias);
56 let foreign_type_id = foreign_type.to_chalk(db);
57 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
58 }
59 50
60 Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), 51 TyKind::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
61 52
62 Ty::Tuple(cardinality, substs) => { 53 TyKind::Tuple(cardinality, substs) => {
63 let substitution = substs.to_chalk(db); 54 let substitution = substs.to_chalk(db);
64 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 55 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
65 } 56 }
66 Ty::Raw(mutability, substs) => { 57 TyKind::Raw(mutability, ty) => {
67 let ty = substs[0].clone().to_chalk(db); 58 let ty = ty.to_chalk(db);
68 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner) 59 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner)
69 } 60 }
70 Ty::Slice(substs) => { 61 TyKind::Slice(ty) => chalk_ir::TyKind::Slice(ty.to_chalk(db)).intern(&Interner),
71 chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner) 62 TyKind::Str => chalk_ir::TyKind::Str.intern(&Interner),
72 } 63 TyKind::FnDef(id, substs) => {
73 Ty::Str => chalk_ir::TyKind::Str.intern(&Interner),
74 Ty::FnDef(callable_def, substs) => {
75 let id = callable_def.to_chalk(db);
76 let substitution = substs.to_chalk(db); 64 let substitution = substs.to_chalk(db);
77 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) 65 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
78 } 66 }
79 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner), 67 TyKind::Never => chalk_ir::TyKind::Never.intern(&Interner),
80 68
81 Ty::Closure(def, expr, substs) => { 69 TyKind::Closure(closure_id, substs) => {
82 let closure_id = db.intern_closure((def, expr));
83 let substitution = substs.to_chalk(db); 70 let substitution = substs.to_chalk(db);
84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 71 chalk_ir::TyKind::Closure(closure_id, substitution).intern(&Interner)
85 } 72 }
86 73
87 Ty::Adt(adt_id, substs) => { 74 TyKind::Adt(adt_id, substs) => {
88 let substitution = substs.to_chalk(db); 75 let substitution = substs.to_chalk(db);
89 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner) 76 chalk_ir::TyKind::Adt(adt_id, substitution).intern(&Interner)
90 } 77 }
91 Ty::Alias(AliasTy::Projection(proj_ty)) => { 78 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
92 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); 79 let associated_ty_id = proj_ty.associated_ty_id;
93 let substitution = proj_ty.parameters.to_chalk(db); 80 let substitution = proj_ty.substitution.to_chalk(db);
94 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { 81 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
95 associated_ty_id, 82 associated_ty_id,
96 substitution, 83 substitution,
@@ -98,17 +85,17 @@ impl ToChalk for Ty {
98 .cast(&Interner) 85 .cast(&Interner)
99 .intern(&Interner) 86 .intern(&Interner)
100 } 87 }
101 Ty::Placeholder(id) => { 88 TyKind::Alias(AliasTy::Opaque(opaque_ty)) => {
102 let interned_id = db.intern_type_param_id(id); 89 let opaque_ty_id = opaque_ty.opaque_ty_id;
103 PlaceholderIndex { 90 let substitution = opaque_ty.substitution.to_chalk(db);
104 ui: UniverseIndex::ROOT, 91 chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { opaque_ty_id, substitution })
105 idx: interned_id.as_intern_id().as_usize(), 92 .cast(&Interner)
106 } 93 .intern(&Interner)
107 .to_ty::<Interner>(&Interner) 94 }
108 } 95 TyKind::Placeholder(idx) => idx.to_ty::<Interner>(&Interner),
109 Ty::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), 96 TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
110 Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"), 97 TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
111 Ty::Dyn(predicates) => { 98 TyKind::Dyn(predicates) => {
112 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 99 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
113 &Interner, 100 &Interner,
114 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)), 101 predicates.iter().filter(|p| !p.is_error()).cloned().map(|p| p.to_chalk(db)),
@@ -119,43 +106,30 @@ impl ToChalk for Ty {
119 }; 106 };
120 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) 107 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
121 } 108 }
122 Ty::Alias(AliasTy::Opaque(opaque_ty)) => { 109 TyKind::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
123 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
124 let substitution = opaque_ty.parameters.to_chalk(db);
125 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
126 opaque_ty_id,
127 substitution,
128 }))
129 .intern(&Interner)
130 }
131 Ty::Unknown => chalk_ir::TyKind::Error.intern(&Interner),
132 } 110 }
133 } 111 }
134 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 112 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
135 match chalk.data(&Interner).kind.clone() { 113 match chalk.data(&Interner).kind.clone() {
136 chalk_ir::TyKind::Error => Ty::Unknown, 114 chalk_ir::TyKind::Error => TyKind::Unknown,
137 chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))), 115 chalk_ir::TyKind::Array(ty, _size) => TyKind::Array(from_chalk(db, ty)),
138 chalk_ir::TyKind::Placeholder(idx) => { 116 chalk_ir::TyKind::Placeholder(idx) => TyKind::Placeholder(idx),
139 assert_eq!(idx.ui, UniverseIndex::ROOT);
140 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
141 crate::salsa::InternId::from(idx.idx),
142 );
143 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
144 }
145 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => { 117 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(proj)) => {
146 let associated_ty = 118 let associated_ty = proj.associated_ty_id;
147 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
148 let parameters = from_chalk(db, proj.substitution); 119 let parameters = from_chalk(db, proj.substitution);
149 Ty::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters })) 120 TyKind::Alias(AliasTy::Projection(ProjectionTy {
121 associated_ty_id: associated_ty,
122 substitution: parameters,
123 }))
150 } 124 }
151 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 125 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
152 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 126 let opaque_ty_id = opaque_ty.opaque_ty_id;
153 let parameters = from_chalk(db, opaque_ty.substitution); 127 let parameters = from_chalk(db, opaque_ty.substitution);
154 Ty::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters })) 128 TyKind::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id, substitution: parameters }))
155 } 129 }
156 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 130 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
157 num_binders, 131 num_binders,
158 sig: chalk_ir::FnSig { variadic, .. }, 132 sig,
159 substitution, 133 substitution,
160 .. 134 ..
161 }) => { 135 }) => {
@@ -164,14 +138,10 @@ impl ToChalk for Ty {
164 db, 138 db,
165 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 139 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
166 ); 140 );
167 Ty::Function(FnPointer { 141 TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs })
168 num_args: (substs.len() - 1),
169 sig: FnSig { variadic },
170 substs,
171 })
172 } 142 }
173 chalk_ir::TyKind::BoundVar(idx) => Ty::BoundVar(idx), 143 chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
174 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, 144 chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
175 chalk_ir::TyKind::Dyn(where_clauses) => { 145 chalk_ir::TyKind::Dyn(where_clauses) => {
176 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 146 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
177 let predicates = where_clauses 147 let predicates = where_clauses
@@ -180,49 +150,41 @@ impl ToChalk for Ty {
180 .iter(&Interner) 150 .iter(&Interner)
181 .map(|c| from_chalk(db, c.clone())) 151 .map(|c| from_chalk(db, c.clone()))
182 .collect(); 152 .collect();
183 Ty::Dyn(predicates) 153 TyKind::Dyn(predicates)
184 } 154 }
185 155
186 chalk_ir::TyKind::Adt(adt_id, subst) => Ty::Adt(adt_id, from_chalk(db, subst)), 156 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( 157 chalk_ir::TyKind::AssociatedType(type_id, subst) => {
188 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0, 158 TyKind::AssociatedType(type_id, from_chalk(db, subst))
189 from_chalk(db, subst), 159 }
190 ),
191 160
192 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { 161 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
193 Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst)) 162 TyKind::OpaqueType(opaque_type_id, from_chalk(db, subst))
194 } 163 }
195 164
196 chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar), 165 chalk_ir::TyKind::Scalar(scalar) => TyKind::Scalar(scalar),
197 chalk_ir::TyKind::Tuple(cardinality, subst) => { 166 chalk_ir::TyKind::Tuple(cardinality, subst) => {
198 Ty::Tuple(cardinality, from_chalk(db, subst)) 167 TyKind::Tuple(cardinality, from_chalk(db, subst))
199 }
200 chalk_ir::TyKind::Raw(mutability, ty) => {
201 Ty::Raw(mutability, Substs::single(from_chalk(db, ty)))
202 } 168 }
203 chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))), 169 chalk_ir::TyKind::Raw(mutability, ty) => TyKind::Raw(mutability, from_chalk(db, ty)),
170 chalk_ir::TyKind::Slice(ty) => TyKind::Slice(from_chalk(db, ty)),
204 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { 171 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
205 Ty::Ref(mutability, Substs::single(from_chalk(db, ty))) 172 TyKind::Ref(mutability, from_chalk(db, ty))
206 } 173 }
207 chalk_ir::TyKind::Str => Ty::Str, 174 chalk_ir::TyKind::Str => TyKind::Str,
208 chalk_ir::TyKind::Never => Ty::Never, 175 chalk_ir::TyKind::Never => TyKind::Never,
209 176
210 chalk_ir::TyKind::FnDef(fn_def_id, subst) => { 177 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
211 Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst)) 178 TyKind::FnDef(fn_def_id, from_chalk(db, subst))
212 } 179 }
213 180
214 chalk_ir::TyKind::Closure(id, subst) => { 181 chalk_ir::TyKind::Closure(id, subst) => TyKind::Closure(id, from_chalk(db, subst)),
215 let id: crate::db::ClosureId = id.into();
216 let (def, expr) = db.lookup_intern_closure(id);
217 Ty::Closure(def, expr, from_chalk(db, subst))
218 }
219 182
220 chalk_ir::TyKind::Foreign(foreign_def_id) => { 183 chalk_ir::TyKind::Foreign(foreign_def_id) => TyKind::ForeignType(foreign_def_id),
221 Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
222 }
223 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME 184 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
224 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME 185 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
225 } 186 }
187 .intern(&Interner)
226 } 188 }
227} 189}
228 190
@@ -231,17 +193,17 @@ impl ToChalk for Ty {
231fn ref_to_chalk( 193fn ref_to_chalk(
232 db: &dyn HirDatabase, 194 db: &dyn HirDatabase,
233 mutability: chalk_ir::Mutability, 195 mutability: chalk_ir::Mutability,
234 subst: Substs, 196 ty: Ty,
235) -> chalk_ir::Ty<Interner> { 197) -> chalk_ir::Ty<Interner> {
236 let arg = subst[0].clone().to_chalk(db); 198 let arg = ty.to_chalk(db);
237 let lifetime = LifetimeData::Static.intern(&Interner); 199 let lifetime = LifetimeData::Static.intern(&Interner);
238 chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner) 200 chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner)
239} 201}
240 202
241/// We currently don't model constants, but Chalk does. So, we have to insert a 203/// We currently don't model constants, but Chalk does. So, we have to insert a
242/// fake constant here, because Chalks built-in logic may expect it to be there. 204/// fake constant here, because Chalks built-in logic may expect it to be there.
243fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 205fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
244 let arg = subst[0].clone().to_chalk(db); 206 let arg = ty.to_chalk(db);
245 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner); 207 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
246 let const_ = chalk_ir::ConstData { 208 let const_ = chalk_ir::ConstData {
247 ty: usize_ty, 209 ty: usize_ty,
@@ -298,21 +260,6 @@ impl ToChalk for hir_def::TraitId {
298 } 260 }
299} 261}
300 262
301impl ToChalk for OpaqueTyId {
302 type Chalk = chalk_ir::OpaqueTyId<Interner>;
303
304 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::OpaqueTyId<Interner> {
305 db.intern_impl_trait_id(self).into()
306 }
307
308 fn from_chalk(
309 db: &dyn HirDatabase,
310 opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
311 ) -> OpaqueTyId {
312 db.lookup_intern_impl_trait_id(opaque_ty_id.into())
313 }
314}
315
316impl ToChalk for hir_def::ImplId { 263impl ToChalk for hir_def::ImplId {
317 type Chalk = ImplId; 264 type Chalk = ImplId;
318 265
@@ -337,34 +284,6 @@ impl ToChalk for CallableDefId {
337 } 284 }
338} 285}
339 286
340pub(crate) struct TypeAliasAsAssocType(pub(crate) TypeAliasId);
341
342impl ToChalk for TypeAliasAsAssocType {
343 type Chalk = AssocTypeId;
344
345 fn to_chalk(self, _db: &dyn HirDatabase) -> AssocTypeId {
346 chalk_ir::AssocTypeId(self.0.as_intern_id())
347 }
348
349 fn from_chalk(_db: &dyn HirDatabase, assoc_type_id: AssocTypeId) -> TypeAliasAsAssocType {
350 TypeAliasAsAssocType(InternKey::from_intern_id(assoc_type_id.0))
351 }
352}
353
354pub(crate) struct TypeAliasAsForeignType(pub(crate) TypeAliasId);
355
356impl ToChalk for TypeAliasAsForeignType {
357 type Chalk = ForeignDefId;
358
359 fn to_chalk(self, _db: &dyn HirDatabase) -> ForeignDefId {
360 chalk_ir::ForeignDefId(self.0.as_intern_id())
361 }
362
363 fn from_chalk(_db: &dyn HirDatabase, foreign_def_id: ForeignDefId) -> TypeAliasAsForeignType {
364 TypeAliasAsForeignType(InternKey::from_intern_id(foreign_def_id.0))
365 }
366}
367
368pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId); 287pub(crate) struct TypeAliasAsValue(pub(crate) TypeAliasId);
369 288
370impl ToChalk for TypeAliasAsValue { 289impl ToChalk for TypeAliasAsValue {
@@ -446,8 +365,8 @@ impl ToChalk for ProjectionTy {
446 365
447 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> { 366 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
448 chalk_ir::ProjectionTy { 367 chalk_ir::ProjectionTy {
449 associated_ty_id: TypeAliasAsAssocType(self.associated_ty).to_chalk(db), 368 associated_ty_id: self.associated_ty_id,
450 substitution: self.parameters.to_chalk(db), 369 substitution: self.substitution.to_chalk(db),
451 } 370 }
452 } 371 }
453 372
@@ -456,12 +375,8 @@ impl ToChalk for ProjectionTy {
456 projection_ty: chalk_ir::ProjectionTy<Interner>, 375 projection_ty: chalk_ir::ProjectionTy<Interner>,
457 ) -> ProjectionTy { 376 ) -> ProjectionTy {
458 ProjectionTy { 377 ProjectionTy {
459 associated_ty: from_chalk::<TypeAliasAsAssocType, _>( 378 associated_ty_id: projection_ty.associated_ty_id,
460 db, 379 substitution: from_chalk(db, projection_ty.substitution),
461 projection_ty.associated_ty_id,
462 )
463 .0,
464 parameters: from_chalk(db, projection_ty.substitution),
465 } 380 }
466 } 381 }
467} 382}
@@ -611,22 +526,24 @@ pub(super) fn generic_predicate_to_inline_bound(
611 Some(rust_ir::InlineBound::TraitBound(trait_bound)) 526 Some(rust_ir::InlineBound::TraitBound(trait_bound))
612 } 527 }
613 GenericPredicate::Projection(proj) => { 528 GenericPredicate::Projection(proj) => {
614 if &proj.projection_ty.parameters[0] != self_ty { 529 if &proj.projection_ty.substitution[0] != self_ty {
615 return None; 530 return None;
616 } 531 }
617 let trait_ = match proj.projection_ty.associated_ty.lookup(db.upcast()).container { 532 let trait_ = match from_assoc_type_id(proj.projection_ty.associated_ty_id)
533 .lookup(db.upcast())
534 .container
535 {
618 AssocContainerId::TraitId(t) => t, 536 AssocContainerId::TraitId(t) => t,
619 _ => panic!("associated type not in trait"), 537 _ => panic!("associated type not in trait"),
620 }; 538 };
621 let args_no_self = proj.projection_ty.parameters[1..] 539 let args_no_self = proj.projection_ty.substitution[1..]
622 .iter() 540 .iter()
623 .map(|ty| ty.clone().to_chalk(db).cast(&Interner)) 541 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
624 .collect(); 542 .collect();
625 let alias_eq_bound = rust_ir::AliasEqBound { 543 let alias_eq_bound = rust_ir::AliasEqBound {
626 value: proj.ty.clone().to_chalk(db), 544 value: proj.ty.clone().to_chalk(db),
627 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self }, 545 trait_bound: rust_ir::TraitBound { trait_id: trait_.to_chalk(db), args_no_self },
628 associated_ty_id: TypeAliasAsAssocType(proj.projection_ty.associated_ty) 546 associated_ty_id: proj.projection_ty.associated_ty_id,
629 .to_chalk(db),
630 parameters: Vec::new(), // FIXME we don't support generic associated types yet 547 parameters: Vec::new(), // FIXME we don't support generic associated types yet
631 }; 548 };
632 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound)) 549 Some(rust_ir::InlineBound::AliasEqBound(alias_eq_bound))
diff --git a/crates/hir_ty/src/traits/chalk/tls.rs b/crates/hir_ty/src/traits/chalk/tls.rs
index 75b16172e..8892a63a9 100644
--- a/crates/hir_ty/src/traits/chalk/tls.rs
+++ b/crates/hir_ty/src/traits/chalk/tls.rs
@@ -4,8 +4,8 @@ use std::fmt;
4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication}; 4use chalk_ir::{AliasTy, GenericArg, Goal, Goals, Lifetime, ProgramClauseImplication};
5use itertools::Itertools; 5use itertools::Itertools;
6 6
7use super::{from_chalk, Interner, TypeAliasAsAssocType}; 7use super::{from_chalk, Interner};
8use crate::{db::HirDatabase, CallableDefId}; 8use crate::{db::HirDatabase, from_assoc_type_id, CallableDefId};
9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId}; 9use hir_def::{AdtId, AssocContainerId, Lookup, TypeAliasId};
10 10
11pub(crate) use unsafe_tls::{set_current_program, with_current_program}; 11pub(crate) use unsafe_tls::{set_current_program, with_current_program};
@@ -41,7 +41,7 @@ impl DebugContext<'_> {
41 id: super::AssocTypeId, 41 id: super::AssocTypeId,
42 fmt: &mut fmt::Formatter<'_>, 42 fmt: &mut fmt::Formatter<'_>,
43 ) -> Result<(), fmt::Error> { 43 ) -> Result<(), fmt::Error> {
44 let type_alias: TypeAliasId = from_chalk::<TypeAliasAsAssocType, _>(self.0, id).0; 44 let type_alias: TypeAliasId = from_assoc_type_id(id);
45 let type_alias_data = self.0.type_alias_data(type_alias); 45 let type_alias_data = self.0.type_alias_data(type_alias);
46 let trait_ = match type_alias.lookup(self.0.upcast()).container { 46 let trait_ = match type_alias.lookup(self.0.upcast()).container {
47 AssocContainerId::TraitId(t) => t, 47 AssocContainerId::TraitId(t) => t,
@@ -75,8 +75,7 @@ impl DebugContext<'_> {
75 projection_ty: &chalk_ir::ProjectionTy<Interner>, 75 projection_ty: &chalk_ir::ProjectionTy<Interner>,
76 fmt: &mut fmt::Formatter<'_>, 76 fmt: &mut fmt::Formatter<'_>,
77 ) -> Result<(), fmt::Error> { 77 ) -> Result<(), fmt::Error> {
78 let type_alias: TypeAliasId = 78 let type_alias = from_assoc_type_id(projection_ty.associated_ty_id);
79 from_chalk::<TypeAliasAsAssocType, _>(self.0, projection_ty.associated_ty_id).0;
80 let type_alias_data = self.0.type_alias_data(type_alias); 79 let type_alias_data = self.0.type_alias_data(type_alias);
81 let trait_ = match type_alias.lookup(self.0.upcast()).container { 80 let trait_ = match type_alias.lookup(self.0.upcast()).container {
82 AssocContainerId::TraitId(t) => t, 81 AssocContainerId::TraitId(t) => t,