aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/autoderef.rs11
-rw-r--r--crates/hir_ty/src/db.rs2
-rw-r--r--crates/hir_ty/src/diagnostics.rs29
-rw-r--r--crates/hir_ty/src/diagnostics/decl_check.rs22
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs19
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs10
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs223
-rw-r--r--crates/hir_ty/src/infer.rs46
-rw-r--r--crates/hir_ty/src/infer/coerce.rs92
-rw-r--r--crates/hir_ty/src/infer/expr.rs241
-rw-r--r--crates/hir_ty/src/infer/pat.rs37
-rw-r--r--crates/hir_ty/src/infer/path.rs2
-rw-r--r--crates/hir_ty/src/infer/unify.rs208
-rw-r--r--crates/hir_ty/src/lib.rs615
-rw-r--r--crates/hir_ty/src/lower.rs126
-rw-r--r--crates/hir_ty/src/method_resolution.rs176
-rw-r--r--crates/hir_ty/src/op.rs50
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/tests.rs30
-rw-r--r--crates/hir_ty/src/tests/coercion.rs5
-rw-r--r--crates/hir_ty/src/tests/method_resolution.rs2
-rw-r--r--crates/hir_ty/src/tests/patterns.rs3
-rw-r--r--crates/hir_ty/src/tests/regression.rs7
-rw-r--r--crates/hir_ty/src/tests/simple.rs58
-rw-r--r--crates/hir_ty/src/tests/traits.rs38
-rw-r--r--crates/hir_ty/src/traits.rs25
-rw-r--r--crates/hir_ty/src/traits/chalk.rs55
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs380
-rw-r--r--crates/hir_ty/src/utils.rs2
30 files changed, 1239 insertions, 1441 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index ece68183e..be1fd1f13 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -81,7 +81,7 @@ fn deref_by_trait(
81 81
82 // Now do the assoc type projection 82 // Now do the assoc type projection
83 let projection = super::traits::ProjectionPredicate { 83 let projection = super::traits::ProjectionPredicate {
84 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 84 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())),
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 85 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
86 }; 86 };
87 87
@@ -89,8 +89,10 @@ fn deref_by_trait(
89 89
90 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 90 let in_env = InEnvironment { value: obligation, environment: ty.environment };
91 91
92 let canonical = 92 let canonical = Canonical::new(
93 Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); 93 in_env,
94 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)),
95 );
94 96
95 let solution = db.trait_solve(krate, canonical)?; 97 let solution = db.trait_solve(krate, canonical)?;
96 98
@@ -112,7 +114,8 @@ fn deref_by_trait(
112 // new variables in that case 114 // new variables in that case
113 115
114 for i in 1..vars.0.kinds.len() { 116 for i in 1..vars.0.kinds.len() {
115 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 117 if vars.0.value[i - 1]
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
116 { 119 {
117 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
118 return None; 121 return None;
diff --git a/crates/hir_ty/src/db.rs b/crates/hir_ty/src/db.rs
index b3af82444..06714409f 100644
--- a/crates/hir_ty/src/db.rs
+++ b/crates/hir_ty/src/db.rs
@@ -130,7 +130,7 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
130 ) -> chalk_ir::ProgramClauses<chalk::Interner>; 130 ) -> chalk_ir::ProgramClauses<chalk::Interner>;
131} 131}
132 132
133fn infer_wait(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { 133fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
134 let _p = profile::span("infer:wait").detail(|| match def { 134 let _p = profile::span("infer:wait").detail(|| match def {
135 DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(), 135 DefWithBodyId::FunctionId(it) => db.function_data(it).name.to_string(),
136 DefWithBodyId::StaticId(it) => { 136 DefWithBodyId::StaticId(it) => {
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 6bca7aa0d..86f937e1d 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -706,6 +706,35 @@ fn x(a: S) {
706 } 706 }
707 707
708 #[test] 708 #[test]
709 fn import_extern_crate_clash_with_inner_item() {
710 // This is more of a resolver test, but doesn't really work with the hir_def testsuite.
711
712 check_diagnostics(
713 r#"
714//- /lib.rs crate:lib deps:jwt
715mod permissions;
716
717use permissions::jwt;
718
719fn f() {
720 fn inner() {}
721 jwt::Claims {}; // should resolve to the local one with 0 fields, and not get a diagnostic
722}
723
724//- /permissions.rs
725pub mod jwt {
726 pub struct Claims {}
727}
728
729//- /jwt/lib.rs crate:jwt
730pub struct Claims {
731 field: u8,
732}
733 "#,
734 );
735 }
736
737 #[test]
709 fn break_outside_of_loop() { 738 fn break_outside_of_loop() {
710 check_diagnostics( 739 check_diagnostics(
711 r#" 740 r#"
diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs
index 6773ddea3..3605ca581 100644
--- a/crates/hir_ty/src/diagnostics/decl_check.rs
+++ b/crates/hir_ty/src/diagnostics/decl_check.rs
@@ -28,7 +28,6 @@ use syntax::{
28 ast::{self, NameOwner}, 28 ast::{self, NameOwner},
29 AstNode, AstPtr, 29 AstNode, AstPtr,
30}; 30};
31use test_utils::mark;
32 31
33use crate::{ 32use crate::{
34 db::HirDatabase, 33 db::HirDatabase,
@@ -93,16 +92,21 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
93 fn validate_func(&mut self, func: FunctionId) { 92 fn validate_func(&mut self, func: FunctionId) {
94 let data = self.db.function_data(func); 93 let data = self.db.function_data(func);
95 if data.is_extern { 94 if data.is_extern {
96 mark::hit!(extern_func_incorrect_case_ignored); 95 cov_mark::hit!(extern_func_incorrect_case_ignored);
97 return; 96 return;
98 } 97 }
99 98
100 let body = self.db.body(func.into()); 99 let body = self.db.body(func.into());
101 100
102 // Recursively validate inner scope items, such as static variables and constants. 101 // Recursively validate inner scope items, such as static variables and constants.
103 for (item_id, _) in body.item_scope.values() { 102 let db = self.db;
104 let mut validator = DeclValidator::new(self.db, self.krate, self.sink); 103 for block_def_map in body.block_scopes.iter().filter_map(|block| db.block_def_map(*block)) {
105 validator.validate_item(item_id); 104 for (_, module) in block_def_map.modules() {
105 for (def_id, _) in module.scope.values() {
106 let mut validator = DeclValidator::new(self.db, self.krate, self.sink);
107 validator.validate_item(def_id);
108 }
109 }
106 } 110 }
107 111
108 // Check whether non-snake case identifiers are allowed for this function. 112 // Check whether non-snake case identifiers are allowed for this function.
@@ -625,7 +629,7 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
625 fn validate_static(&mut self, static_id: StaticId) { 629 fn validate_static(&mut self, static_id: StaticId) {
626 let data = self.db.static_data(static_id); 630 let data = self.db.static_data(static_id);
627 if data.is_extern { 631 if data.is_extern {
628 mark::hit!(extern_static_incorrect_case_ignored); 632 cov_mark::hit!(extern_static_incorrect_case_ignored);
629 return; 633 return;
630 } 634 }
631 635
@@ -673,8 +677,6 @@ impl<'a, 'b> DeclValidator<'a, 'b> {
673 677
674#[cfg(test)] 678#[cfg(test)]
675mod tests { 679mod tests {
676 use test_utils::mark;
677
678 use crate::diagnostics::tests::check_diagnostics; 680 use crate::diagnostics::tests::check_diagnostics;
679 681
680 #[test] 682 #[test]
@@ -889,8 +891,8 @@ fn main() {
889 891
890 #[test] 892 #[test]
891 fn ignores_extern_items() { 893 fn ignores_extern_items() {
892 mark::check!(extern_func_incorrect_case_ignored); 894 cov_mark::check!(extern_func_incorrect_case_ignored);
893 mark::check!(extern_static_incorrect_case_ignored); 895 cov_mark::check!(extern_static_incorrect_case_ignored);
894 check_diagnostics( 896 check_diagnostics(
895 r#" 897 r#"
896extern { 898extern {
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index d740b7265..2751cd304 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -2,9 +2,7 @@
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use hir_def::{ 5use hir_def::{expr::Statement, path::path, resolver::HasResolver, AssocItemId, DefWithBodyId};
6 expr::Statement, path::path, resolver::HasResolver, AdtId, AssocItemId, DefWithBodyId,
7};
8use hir_expand::{diagnostics::DiagnosticSink, name}; 6use hir_expand::{diagnostics::DiagnosticSink, name};
9use rustc_hash::FxHashSet; 7use rustc_hash::FxHashSet;
10use syntax::{ast, AstPtr}; 8use syntax::{ast, AstPtr};
@@ -17,7 +15,7 @@ use crate::{
17 MissingPatFields, RemoveThisSemicolon, 15 MissingPatFields, RemoveThisSemicolon,
18 }, 16 },
19 utils::variant_data, 17 utils::variant_data,
20 ApplicationTy, InferenceResult, Ty, TypeCtor, 18 AdtId, InferenceResult, Ty,
21}; 19};
22 20
23pub(crate) use hir_def::{ 21pub(crate) use hir_def::{
@@ -381,14 +379,15 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
381 _ => return, 379 _ => return,
382 }; 380 };
383 381
384 let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); 382 let (params, required) = match mismatch.expected {
385 let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); 383 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
386 384 if enum_id == core_result_enum =>
387 let (params, required) = match &mismatch.expected { 385 {
388 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => {
389 (parameters, "Ok".to_string()) 386 (parameters, "Ok".to_string())
390 } 387 }
391 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { 388 Ty::Adt(AdtId(hir_def::AdtId::EnumId(enum_id)), ref parameters)
389 if enum_id == core_option_enum =>
390 {
392 (parameters, "Some".to_string()) 391 (parameters, "Some".to_string())
393 } 392 }
394 _ => return, 393 _ => return,
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 1c1423fbf..04d39c571 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -222,12 +222,12 @@ use hir_def::{
222 adt::VariantData, 222 adt::VariantData,
223 body::Body, 223 body::Body,
224 expr::{Expr, Literal, Pat, PatId}, 224 expr::{Expr, Literal, Pat, PatId},
225 AdtId, EnumVariantId, StructId, VariantId, 225 EnumVariantId, StructId, VariantId,
226}; 226};
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; 230use crate::{db::HirDatabase, AdtId, InferenceResult, Ty};
231 231
232#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
233/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
@@ -627,14 +627,12 @@ pub(super) fn is_useful(
627 // - `!` type 627 // - `!` type
628 // In those cases, no match arm is useful. 628 // In those cases, no match arm is useful.
629 match cx.infer[cx.match_expr].strip_references() { 629 match cx.infer[cx.match_expr].strip_references() {
630 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { 630 Ty::Adt(AdtId(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::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { 635 Ty::Never => return Ok(Usefulness::NotUseful),
636 return Ok(Usefulness::NotUseful);
637 }
638 _ => (), 636 _ => (),
639 } 637 }
640 638
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 9c506112d..e77a20fea 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,9 +11,7 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{ 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty};
15 db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor,
16};
17 15
18pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(super) struct UnsafeValidator<'a, 'b: 'a> {
19 owner: DefWithBodyId, 17 owner: DefWithBodyId,
@@ -112,7 +110,7 @@ fn walk_unsafe(
112 } 110 }
113 } 111 }
114 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
115 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { 113 if let Ty::Raw(..) = &infer[*expr] {
116 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
117 } 115 }
118 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 271fcbfaf..ab51cb0a6 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -2,17 +2,20 @@
2 2
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{
6 db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate,
7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
8};
9use arrayvec::ArrayVec; 5use arrayvec::ArrayVec;
6use chalk_ir::Mutability;
10use hir_def::{ 7use hir_def::{
11 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, 8 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs,
12 AssocContainerId, HasModule, Lookup, ModuleId, TraitId, 9 AssocContainerId, Lookup, ModuleId, TraitId,
13}; 10};
14use hir_expand::name::Name; 11use hir_expand::name::Name;
15 12
13use crate::{
14 db::HirDatabase, primitive, utils::generics, AdtId, AliasTy, CallableDefId, CallableSig,
15 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs,
16 TraitRef, Ty,
17};
18
16pub struct HirFormatter<'a> { 19pub struct HirFormatter<'a> {
17 pub db: &'a dyn HirDatabase, 20 pub db: &'a dyn HirDatabase,
18 fmt: &'a mut dyn fmt::Write, 21 fmt: &'a mut dyn fmt::Write,
@@ -234,39 +237,79 @@ impl HirDisplay for &Ty {
234 } 237 }
235} 238}
236 239
237impl HirDisplay for ApplicationTy { 240impl HirDisplay for ProjectionTy {
238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 241 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
239 if f.should_truncate() { 242 if f.should_truncate() {
240 return write!(f, "{}", TYPE_HINT_TRUNCATION); 243 return write!(f, "{}", TYPE_HINT_TRUNCATION);
241 } 244 }
242 245
243 match self.ctor { 246 let trait_ = f.db.trait_data(self.trait_(f.db));
244 TypeCtor::Bool => write!(f, "bool")?, 247 let first_parameter = self.parameters[0].into_displayable(
245 TypeCtor::Char => write!(f, "char")?, 248 f.db,
246 TypeCtor::Int(t) => write!(f, "{}", t)?, 249 f.max_size,
247 TypeCtor::Float(t) => write!(f, "{}", t)?, 250 f.omit_verbose_types,
248 TypeCtor::Str => write!(f, "str")?, 251 f.display_target,
249 TypeCtor::Slice => { 252 );
250 let t = self.parameters.as_single(); 253 write!(f, "<{} as {}", first_parameter, trait_.name)?;
254 if self.parameters.len() > 1 {
255 write!(f, "<")?;
256 f.write_joined(&self.parameters[1..], ", ")?;
257 write!(f, ">")?;
258 }
259 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
260 Ok(())
261 }
262}
263
264impl HirDisplay for Ty {
265 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
266 if f.should_truncate() {
267 return write!(f, "{}", TYPE_HINT_TRUNCATION);
268 }
269
270 match self {
271 Ty::Never => write!(f, "!")?,
272 Ty::Str => write!(f, "str")?,
273 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
274 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
275 &Ty::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))?,
277 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
278 Ty::Slice(parameters) => {
279 let t = parameters.as_single();
251 write!(f, "[")?; 280 write!(f, "[")?;
252 t.hir_fmt(f)?; 281 t.hir_fmt(f)?;
253 write!(f, "]")?; 282 write!(f, "]")?;
254 } 283 }
255 TypeCtor::Array => { 284 Ty::Array(parameters) => {
256 let t = self.parameters.as_single(); 285 let t = parameters.as_single();
257 write!(f, "[")?; 286 write!(f, "[")?;
258 t.hir_fmt(f)?; 287 t.hir_fmt(f)?;
259 write!(f, "; _]")?; 288 write!(f, "; _]")?;
260 } 289 }
261 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 290 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => {
262 let t = self.parameters.as_single(); 291 let t = parameters.as_single();
263 let ty_display = 292 let ty_display =
264 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 293 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
265 294
266 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 295 if matches!(self, Ty::Raw(..)) {
267 write!(f, "*{}", m.as_keyword_for_ptr())?; 296 write!(
297 f,
298 "*{}",
299 match m {
300 Mutability::Not => "const ",
301 Mutability::Mut => "mut ",
302 }
303 )?;
268 } else { 304 } else {
269 write!(f, "&{}", m.as_keyword_for_ref())?; 305 write!(
306 f,
307 "&{}",
308 match m {
309 Mutability::Not => "",
310 Mutability::Mut => "mut ",
311 }
312 )?;
270 } 313 }
271 314
272 let datas; 315 let datas;
@@ -274,10 +317,10 @@ impl HirDisplay for ApplicationTy {
274 Ty::Dyn(predicates) if predicates.len() > 1 => { 317 Ty::Dyn(predicates) if predicates.len() > 1 => {
275 Cow::Borrowed(predicates.as_ref()) 318 Cow::Borrowed(predicates.as_ref())
276 } 319 }
277 &Ty::Opaque(OpaqueTy { 320 &Ty::Alias(AliasTy::Opaque(OpaqueTy {
278 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 321 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
279 ref parameters, 322 ref parameters,
280 }) => { 323 })) => {
281 datas = 324 datas =
282 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 325 f.db.return_type_impl_traits(func).expect("impl trait id without data");
283 let data = (*datas) 326 let data = (*datas)
@@ -304,25 +347,24 @@ impl HirDisplay for ApplicationTy {
304 write!(f, "{}", ty_display)?; 347 write!(f, "{}", ty_display)?;
305 } 348 }
306 } 349 }
307 TypeCtor::Never => write!(f, "!")?, 350 Ty::Tuple(_, substs) => {
308 TypeCtor::Tuple { .. } => { 351 if substs.len() == 1 {
309 let ts = &self.parameters;
310 if ts.len() == 1 {
311 write!(f, "(")?; 352 write!(f, "(")?;
312 ts[0].hir_fmt(f)?; 353 substs[0].hir_fmt(f)?;
313 write!(f, ",)")?; 354 write!(f, ",)")?;
314 } else { 355 } else {
315 write!(f, "(")?; 356 write!(f, "(")?;
316 f.write_joined(&*ts.0, ", ")?; 357 f.write_joined(&*substs.0, ", ")?;
317 write!(f, ")")?; 358 write!(f, ")")?;
318 } 359 }
319 } 360 }
320 TypeCtor::FnPtr { is_varargs, .. } => { 361 Ty::Function(fn_ptr) => {
321 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 362 let sig = CallableSig::from_fn_ptr(fn_ptr);
322 sig.hir_fmt(f)?; 363 sig.hir_fmt(f)?;
323 } 364 }
324 TypeCtor::FnDef(def) => { 365 Ty::FnDef(def, parameters) => {
325 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 366 let def = *def;
367 let sig = f.db.callable_item_signature(def).subst(parameters);
326 match def { 368 match def {
327 CallableDefId::FunctionId(ff) => { 369 CallableDefId::FunctionId(ff) => {
328 write!(f, "fn {}", f.db.function_data(ff).name)? 370 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -332,7 +374,7 @@ impl HirDisplay for ApplicationTy {
332 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 374 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
333 } 375 }
334 }; 376 };
335 if self.parameters.len() > 0 { 377 if parameters.len() > 0 {
336 let generics = generics(f.db.upcast(), def.into()); 378 let generics = generics(f.db.upcast(), def.into());
337 let (parent_params, self_param, type_params, _impl_trait_params) = 379 let (parent_params, self_param, type_params, _impl_trait_params) =
338 generics.provenance_split(); 380 generics.provenance_split();
@@ -340,7 +382,7 @@ impl HirDisplay for ApplicationTy {
340 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 382 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
341 if total_len > 0 { 383 if total_len > 0 {
342 write!(f, "<")?; 384 write!(f, "<")?;
343 f.write_joined(&self.parameters.0[..total_len], ", ")?; 385 f.write_joined(&parameters.0[..total_len], ", ")?;
344 write!(f, ">")?; 386 write!(f, ">")?;
345 } 387 }
346 } 388 }
@@ -359,20 +401,20 @@ impl HirDisplay for ApplicationTy {
359 write!(f, " -> {}", ret_display)?; 401 write!(f, " -> {}", ret_display)?;
360 } 402 }
361 } 403 }
362 TypeCtor::Adt(def_id) => { 404 Ty::Adt(AdtId(def_id), parameters) => {
363 match f.display_target { 405 match f.display_target {
364 DisplayTarget::Diagnostics | DisplayTarget::Test => { 406 DisplayTarget::Diagnostics | DisplayTarget::Test => {
365 let name = match def_id { 407 let name = match *def_id {
366 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 408 hir_def::AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
367 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 409 hir_def::AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
368 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), 410 hir_def::AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
369 }; 411 };
370 write!(f, "{}", name)?; 412 write!(f, "{}", name)?;
371 } 413 }
372 DisplayTarget::SourceCode { module_id } => { 414 DisplayTarget::SourceCode { module_id } => {
373 if let Some(path) = find_path::find_path( 415 if let Some(path) = find_path::find_path(
374 f.db.upcast(), 416 f.db.upcast(),
375 ItemInNs::Types(def_id.into()), 417 ItemInNs::Types((*def_id).into()),
376 module_id, 418 module_id,
377 ) { 419 ) {
378 write!(f, "{}", path)?; 420 write!(f, "{}", path)?;
@@ -384,19 +426,18 @@ impl HirDisplay for ApplicationTy {
384 } 426 }
385 } 427 }
386 428
387 if self.parameters.len() > 0 { 429 if parameters.len() > 0 {
388 let parameters_to_write = 430 let parameters_to_write =
389 if f.display_target.is_source_code() || f.omit_verbose_types() { 431 if f.display_target.is_source_code() || f.omit_verbose_types() {
390 match self 432 match self
391 .ctor
392 .as_generic_def() 433 .as_generic_def()
393 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 434 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
394 .filter(|defaults| !defaults.is_empty()) 435 .filter(|defaults| !defaults.is_empty())
395 { 436 {
396 None => self.parameters.0.as_ref(), 437 None => parameters.0.as_ref(),
397 Some(default_parameters) => { 438 Some(default_parameters) => {
398 let mut default_from = 0; 439 let mut default_from = 0;
399 for (i, parameter) in self.parameters.iter().enumerate() { 440 for (i, parameter) in parameters.iter().enumerate() {
400 match (parameter, default_parameters.get(i)) { 441 match (parameter, default_parameters.get(i)) {
401 (&Ty::Unknown, _) | (_, None) => { 442 (&Ty::Unknown, _) | (_, None) => {
402 default_from = i + 1; 443 default_from = i + 1;
@@ -404,18 +445,18 @@ impl HirDisplay for ApplicationTy {
404 (_, Some(default_parameter)) => { 445 (_, Some(default_parameter)) => {
405 let actual_default = default_parameter 446 let actual_default = default_parameter
406 .clone() 447 .clone()
407 .subst(&self.parameters.prefix(i)); 448 .subst(&parameters.prefix(i));
408 if parameter != &actual_default { 449 if parameter != &actual_default {
409 default_from = i + 1; 450 default_from = i + 1;
410 } 451 }
411 } 452 }
412 } 453 }
413 } 454 }
414 &self.parameters.0[0..default_from] 455 &parameters.0[0..default_from]
415 } 456 }
416 } 457 }
417 } else { 458 } else {
418 self.parameters.0.as_ref() 459 parameters.0.as_ref()
419 }; 460 };
420 if !parameters_to_write.is_empty() { 461 if !parameters_to_write.is_empty() {
421 write!(f, "<")?; 462 write!(f, "<")?;
@@ -424,61 +465,54 @@ impl HirDisplay for ApplicationTy {
424 } 465 }
425 } 466 }
426 } 467 }
427 TypeCtor::AssociatedType(type_alias) => { 468 Ty::AssociatedType(type_alias, parameters) => {
428 let trait_ = match type_alias.lookup(f.db.upcast()).container { 469 let trait_ = match type_alias.lookup(f.db.upcast()).container {
429 AssocContainerId::TraitId(it) => it, 470 AssocContainerId::TraitId(it) => it,
430 _ => panic!("not an associated type"), 471 _ => panic!("not an associated type"),
431 }; 472 };
432 let trait_ = f.db.trait_data(trait_); 473 let trait_ = f.db.trait_data(trait_);
433 let type_alias_data = f.db.type_alias_data(type_alias); 474 let type_alias_data = f.db.type_alias_data(*type_alias);
434 475
435 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 476 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
436 if f.display_target.is_test() { 477 if f.display_target.is_test() {
437 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 478 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
438 if self.parameters.len() > 0 { 479 if parameters.len() > 0 {
439 write!(f, "<")?; 480 write!(f, "<")?;
440 f.write_joined(&*self.parameters.0, ", ")?; 481 f.write_joined(&*parameters.0, ", ")?;
441 write!(f, ">")?; 482 write!(f, ">")?;
442 } 483 }
443 } else { 484 } else {
444 let projection_ty = ProjectionTy { 485 let projection_ty =
445 associated_ty: type_alias, 486 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
446 parameters: self.parameters.clone(),
447 };
448 487
449 projection_ty.hir_fmt(f)?; 488 projection_ty.hir_fmt(f)?;
450 } 489 }
451 } 490 }
452 TypeCtor::ForeignType(type_alias) => { 491 Ty::ForeignType(type_alias) => {
453 let type_alias = f.db.type_alias_data(type_alias); 492 let type_alias = f.db.type_alias_data(*type_alias);
454 write!(f, "{}", type_alias.name)?; 493 write!(f, "{}", type_alias.name)?;
455 if self.parameters.len() > 0 {
456 write!(f, "<")?;
457 f.write_joined(&*self.parameters.0, ", ")?;
458 write!(f, ">")?;
459 }
460 } 494 }
461 TypeCtor::OpaqueType(opaque_ty_id) => { 495 Ty::OpaqueType(opaque_ty_id, parameters) => {
462 match opaque_ty_id { 496 match opaque_ty_id {
463 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 497 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
464 let datas = 498 let datas =
465 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 499 f.db.return_type_impl_traits(func).expect("impl trait id without data");
466 let data = (*datas) 500 let data = (*datas)
467 .as_ref() 501 .as_ref()
468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 502 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
469 let bounds = data.subst(&self.parameters); 503 let bounds = data.subst(&parameters);
470 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 504 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
471 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 505 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
472 } 506 }
473 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 507 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
474 write!(f, "impl Future<Output = ")?; 508 write!(f, "impl Future<Output = ")?;
475 self.parameters[0].hir_fmt(f)?; 509 parameters[0].hir_fmt(f)?;
476 write!(f, ">")?; 510 write!(f, ">")?;
477 } 511 }
478 } 512 }
479 } 513 }
480 TypeCtor::Closure { .. } => { 514 Ty::Closure(.., substs) => {
481 let sig = self.parameters[0].callable_sig(f.db); 515 let sig = substs[0].callable_sig(f.db);
482 if let Some(sig) = sig { 516 if let Some(sig) = sig {
483 if sig.params().is_empty() { 517 if sig.params().is_empty() {
484 write!(f, "||")?; 518 write!(f, "||")?;
@@ -501,44 +535,6 @@ impl HirDisplay for ApplicationTy {
501 write!(f, "{{closure}}")?; 535 write!(f, "{{closure}}")?;
502 } 536 }
503 } 537 }
504 }
505 Ok(())
506 }
507}
508
509impl HirDisplay for ProjectionTy {
510 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
511 if f.should_truncate() {
512 return write!(f, "{}", TYPE_HINT_TRUNCATION);
513 }
514
515 let trait_ = f.db.trait_data(self.trait_(f.db));
516 let first_parameter = self.parameters[0].into_displayable(
517 f.db,
518 f.max_size,
519 f.omit_verbose_types,
520 f.display_target,
521 );
522 write!(f, "<{} as {}", first_parameter, trait_.name)?;
523 if self.parameters.len() > 1 {
524 write!(f, "<")?;
525 f.write_joined(&self.parameters[1..], ", ")?;
526 write!(f, ">")?;
527 }
528 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
529 Ok(())
530 }
531}
532
533impl HirDisplay for Ty {
534 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
535 if f.should_truncate() {
536 return write!(f, "{}", TYPE_HINT_TRUNCATION);
537 }
538
539 match self {
540 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
541 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
542 Ty::Placeholder(id) => { 538 Ty::Placeholder(id) => {
543 let generics = generics(f.db.upcast(), id.parent); 539 let generics = generics(f.db.upcast(), id.parent);
544 let param_data = &generics.params.types[id.local_id]; 540 let param_data = &generics.params.types[id.local_id];
@@ -557,11 +553,12 @@ impl HirDisplay for Ty {
557 } 553 }
558 } 554 }
559 } 555 }
560 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 556 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
561 Ty::Dyn(predicates) => { 557 Ty::Dyn(predicates) => {
562 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 558 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
563 } 559 }
564 Ty::Opaque(opaque_ty) => { 560 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
561 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
565 match opaque_ty.opaque_ty_id { 562 match opaque_ty.opaque_ty_id {
566 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 563 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
567 let datas = 564 let datas =
@@ -585,13 +582,13 @@ impl HirDisplay for Ty {
585 } 582 }
586 write!(f, "{{unknown}}")?; 583 write!(f, "{{unknown}}")?;
587 } 584 }
588 Ty::Infer(..) => write!(f, "_")?, 585 Ty::InferenceVar(..) => write!(f, "_")?,
589 } 586 }
590 Ok(()) 587 Ok(())
591 } 588 }
592} 589}
593 590
594impl HirDisplay for FnSig { 591impl HirDisplay for CallableSig {
595 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 592 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
596 write!(f, "fn(")?; 593 write!(f, "fn(")?;
597 f.write_joined(self.params(), ", ")?; 594 f.write_joined(self.params(), ", ")?;
@@ -614,7 +611,7 @@ impl HirDisplay for FnSig {
614} 611}
615 612
616fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = TraitId> { 613fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = TraitId> {
617 let krate = trait_.lookup(db).container.module(db).krate(); 614 let krate = trait_.lookup(db).container.krate();
618 let fn_traits = [ 615 let fn_traits = [
619 db.lang_item(krate, "fn".into()), 616 db.lang_item(krate, "fn".into()),
620 db.lang_item(krate, "fn_mut".into()), 617 db.lang_item(krate, "fn_mut".into()),
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4b683c5a7..4d771a91e 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,6 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::Mutability;
21use hir_def::{ 22use hir_def::{
22 body::Body, 23 body::Body,
23 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -25,7 +26,7 @@ use hir_def::{
25 lang_item::LangItemTarget, 26 lang_item::LangItemTarget,
26 path::{path, Path}, 27 path::{path, Path},
27 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
28 type_ref::{Mutability, TypeRef}, 29 type_ref::TypeRef,
29 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, 30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId,
30 TypeAliasId, VariantId, 31 TypeAliasId, VariantId,
31}; 32};
@@ -36,25 +37,15 @@ use stdx::impl_from;
36use syntax::SmolStr; 37use syntax::SmolStr;
37 38
38use super::{ 39use super::{
39 primitive::{FloatTy, IntTy},
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy,
45}; 45};
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
48 48
49macro_rules! ty_app {
50 ($ctor:pat, $param:pat) => {
51 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
52 };
53 ($ctor:pat) => {
54 ty_app!($ctor, _)
55 };
56}
57
58mod unify; 49mod unify;
59mod path; 50mod path;
60mod expr; 51mod expr;
@@ -97,7 +88,7 @@ impl BindingMode {
97 fn convert(annotation: BindingAnnotation) -> BindingMode { 88 fn convert(annotation: BindingAnnotation) -> BindingMode {
98 match annotation { 89 match annotation {
99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, 90 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), 91 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
101 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), 92 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
102 } 93 }
103 } 94 }
@@ -405,7 +396,7 @@ impl<'a> InferenceContext<'a> {
405 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
406 let ty = self.resolve_ty_as_possible(ty); 397 let ty = self.resolve_ty_as_possible(ty);
407 ty.fold(&mut |ty| match ty { 398 ty.fold(&mut |ty| match ty {
408 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty),
409 _ => ty, 400 _ => ty,
410 }) 401 })
411 } 402 }
@@ -664,30 +655,17 @@ impl<'a> InferenceContext<'a> {
664/// two are used for inference of literal values (e.g. `100` could be one of 655/// two are used for inference of literal values (e.g. `100` could be one of
665/// several integer types). 656/// several integer types).
666#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 657#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
667pub enum InferTy { 658pub struct InferenceVar {
668 TypeVar(unify::TypeVarId), 659 index: u32,
669 IntVar(unify::TypeVarId),
670 FloatVar(unify::TypeVarId),
671 MaybeNeverTypeVar(unify::TypeVarId),
672} 660}
673 661
674impl InferTy { 662impl InferenceVar {
675 fn to_inner(self) -> unify::TypeVarId { 663 fn to_inner(self) -> unify::TypeVarId {
676 match self { 664 unify::TypeVarId(self.index)
677 InferTy::TypeVar(ty)
678 | InferTy::IntVar(ty)
679 | InferTy::FloatVar(ty)
680 | InferTy::MaybeNeverTypeVar(ty) => ty,
681 }
682 } 665 }
683 666
684 fn fallback_value(self) -> Ty { 667 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
685 match self { 668 InferenceVar { index }
686 InferTy::TypeVar(..) => Ty::Unknown,
687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())),
688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())),
689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
690 }
691 } 669 }
692} 670}
693 671
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..7e8846f27 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,12 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use chalk_ir::{Mutability, TyVariableKind};
8use test_utils::mark; 8use hir_def::lang_item::LangItemTarget;
9 9
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 11
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 12use super::{InEnvironment, InferenceContext};
13 13
14impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
15 /// Unify two types, but may coerce the first one to the second one 15 /// Unify two types, but may coerce the first one to the second one
@@ -33,8 +33,8 @@ 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_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 36 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 37 cov_mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 38 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 39 // pointers to have a chance at getting a match. See
40 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916 40 // https://github.com/rust-lang/rust/blob/7b805396bf46dce972692a6846ce2ad8481c5f85/src/librustc_typeck/check/coercion.rs#L877-L916
@@ -44,7 +44,7 @@ impl<'a> InferenceContext<'a> {
44 let ptr_ty2 = Ty::fn_ptr(sig2); 44 let ptr_ty2 = Ty::fn_ptr(sig2);
45 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2) 45 self.coerce_merge_branch(&ptr_ty1, &ptr_ty2)
46 } else { 46 } else {
47 mark::hit!(coerce_merge_fail_fallback); 47 cov_mark::hit!(coerce_merge_fail_fallback);
48 ty1.clone() 48 ty1.clone()
49 } 49 }
50 } 50 }
@@ -53,12 +53,11 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 54 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 55 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 56 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => {
57 let var = self.table.new_maybe_never_type_var(); 57 self.table.type_variable_table.set_diverging(*tv, true);
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
59 return true; 58 return true;
60 } 59 }
61 (ty_app!(TypeCtor::Never), _) => return true, 60 (Ty::Never, _) => return true,
62 61
63 // Trivial cases, this should go after `never` check to 62 // Trivial cases, this should go after `never` check to
64 // avoid infer result type to be never 63 // avoid infer result type to be never
@@ -71,38 +70,33 @@ impl<'a> InferenceContext<'a> {
71 70
72 // Pointer weakening and function to pointer 71 // Pointer weakening and function to pointer
73 match (&mut from_ty, to_ty) { 72 match (&mut from_ty, to_ty) {
74 // `*mut T`, `&mut T, `&T`` -> `*const T` 73 // `*mut T` -> `*const T`
75 // `&mut T` -> `&T` 74 // `&mut T` -> `&T`
76 // `&mut T` -> `*mut T` 75 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 76 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => {
78 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 *m1 = *m2;
79 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) 78 }
80 | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { 79 // `&T` -> `*const T`
81 *c1 = *c2; 80 // `&mut T` -> `*mut T`/`*const T`
81 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..))
82 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => {
83 from_ty = Ty::Raw(m2, substs.clone());
82 } 84 }
83 85
84 // Illegal mutablity conversion 86 // Illegal mutability conversion
85 ( 87 (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 88 | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
87 ty_app!(TypeCtor::RawPtr(Mutability::Mut)),
88 )
89 | (
90 ty_app!(TypeCtor::Ref(Mutability::Shared)),
91 ty_app!(TypeCtor::Ref(Mutability::Mut)),
92 ) => return false,
93 89
94 // `{function_type}` -> `fn()` 90 // `{function_type}` -> `fn()`
95 (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { 91 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
96 match from_ty.callable_sig(self.db) { 92 None => return false,
97 None => return false, 93 Some(sig) => {
98 Some(sig) => { 94 from_ty = Ty::fn_ptr(sig);
99 from_ty = Ty::fn_ptr(sig);
100 }
101 } 95 }
102 } 96 },
103 97
104 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { 98 (Ty::Closure(.., substs), Ty::Function { .. }) => {
105 from_ty = params[0].clone(); 99 from_ty = substs[0].clone();
106 } 100 }
107 101
108 _ => {} 102 _ => {}
@@ -115,9 +109,7 @@ impl<'a> InferenceContext<'a> {
115 // Auto Deref if cannot coerce 109 // Auto Deref if cannot coerce
116 match (&from_ty, to_ty) { 110 match (&from_ty, to_ty) {
117 // FIXME: DerefMut 111 // FIXME: DerefMut
118 (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { 112 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]),
119 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
120 }
121 113
122 // Otherwise, normal unify 114 // Otherwise, normal unify
123 _ => self.unify(&from_ty, to_ty), 115 _ => self.unify(&from_ty, to_ty),
@@ -178,17 +170,17 @@ impl<'a> InferenceContext<'a> {
178 }, 170 },
179 ) { 171 ) {
180 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 172 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
181 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 173 let from_ty = self.resolve_ty_shallow(&derefed_ty);
182 // Stop when constructor matches. 174 // Stop when constructor matches.
183 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 175 if from_ty.equals_ctor(&to_ty) {
184 // It will not recurse to `coerce`. 176 // It will not recurse to `coerce`.
185 return self.table.unify_substs(st1, st2, 0); 177 return match (from_ty.substs(), to_ty.substs()) {
186 } 178 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
187 _ => { 179 (None, None) => true,
188 if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 180 _ => false,
189 return true; 181 };
190 } 182 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
191 } 183 return true;
192 } 184 }
193 } 185 }
194 186
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..262177ffb 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,23 +3,25 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind};
6use hir_def::{ 7use hir_def::{
7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 AdtId, AssocContainerId, FieldId, Lookup, 11 AssocContainerId, FieldId, Lookup,
12}; 12};
13use hir_expand::name::{name, Name}; 13use hir_expand::name::{name, Name};
14use syntax::ast::RangeOp; 14use syntax::ast::RangeOp;
15use test_utils::mark;
16 15
17use crate::{ 16use crate::{
18 autoderef, method_resolution, op, 17 autoderef,
18 lower::lower_to_chalk_mutability,
19 method_resolution, op,
20 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 21 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 22 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 23 AdtId, Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 24 Substs, TraitRef, Ty,
23}; 25};
24 26
25use super::{ 27use super::{
@@ -82,10 +84,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 84 arg_tys.push(arg);
83 } 85 }
84 let parameters = param_builder.build(); 86 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 87 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 88 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 89 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 90
@@ -120,7 +119,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 119 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 120 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 121 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 122 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 123
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 124 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 125 let mut both_arms_diverge = Diverges::Always;
@@ -175,7 +174,7 @@ impl<'a> InferenceContext<'a> {
175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 174 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
176 let inner_ty = self.infer_expr(*body, &Expectation::none()); 175 let inner_ty = self.infer_expr(*body, &Expectation::none());
177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 176 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
178 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 177 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
179 } 178 }
180 Expr::Loop { body, label } => { 179 Expr::Loop { body, label } => {
181 self.breakables.push(BreakableContext { 180 self.breakables.push(BreakableContext {
@@ -193,7 +192,7 @@ impl<'a> InferenceContext<'a> {
193 if ctxt.may_break { 192 if ctxt.may_break {
194 ctxt.break_ty 193 ctxt.break_ty
195 } else { 194 } else {
196 Ty::simple(TypeCtor::Never) 195 Ty::Never
197 } 196 }
198 } 197 }
199 Expr::While { condition, body, label } => { 198 Expr::While { condition, body, label } => {
@@ -203,7 +202,7 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 202 label: label.map(|label| self.body[label].name.clone()),
204 }); 203 });
205 // while let is desugared to a match loop, so this is always simple while 204 // while let is desugared to a match loop, so this is always simple while
206 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 205 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 206 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 207 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 208 // the body may not run, so it diverging doesn't mean we diverge
@@ -250,12 +249,12 @@ impl<'a> InferenceContext<'a> {
250 None => self.table.new_type_var(), 249 None => self.table.new_type_var(),
251 }; 250 };
252 sig_tys.push(ret_ty.clone()); 251 sig_tys.push(ret_ty.clone());
253 let sig_ty = Ty::apply( 252 let sig_ty = Ty::Function(FnPointer {
254 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 253 num_args: sig_tys.len() - 1,
255 Substs(sig_tys.clone().into()), 254 sig: FnSig { variadic: false },
256 ); 255 substs: Substs(sig_tys.clone().into()),
257 let closure_ty = 256 });
258 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 257 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
259 258
260 // Eagerly try to relate the closure type with the expected 259 // Eagerly try to relate the closure type with the expected
261 // type, otherwise we often won't have enough information to 260 // type, otherwise we often won't have enough information to
@@ -306,11 +305,8 @@ impl<'a> InferenceContext<'a> {
306 Expr::Match { expr, arms } => { 305 Expr::Match { expr, arms } => {
307 let input_ty = self.infer_expr(*expr, &Expectation::none()); 306 let input_ty = self.infer_expr(*expr, &Expectation::none());
308 307
309 let mut result_ty = if arms.is_empty() { 308 let mut result_ty =
310 Ty::simple(TypeCtor::Never) 309 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
311 } else {
312 self.table.new_type_var()
313 };
314 310
315 let matchee_diverges = self.diverges; 311 let matchee_diverges = self.diverges;
316 let mut all_arms_diverge = Diverges::Always; 312 let mut all_arms_diverge = Diverges::Always;
@@ -321,7 +317,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 317 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 318 self.infer_expr(
323 guard_expr, 319 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 320 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
325 ); 321 );
326 } 322 }
327 323
@@ -339,7 +335,7 @@ impl<'a> InferenceContext<'a> {
339 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 335 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
340 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 336 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
341 } 337 }
342 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 338 Expr::Continue { .. } => Ty::Never,
343 Expr::Break { expr, label } => { 339 Expr::Break { expr, label } => {
344 let val_ty = if let Some(expr) = expr { 340 let val_ty = if let Some(expr) = expr {
345 self.infer_expr(*expr, &Expectation::none()) 341 self.infer_expr(*expr, &Expectation::none())
@@ -364,8 +360,7 @@ impl<'a> InferenceContext<'a> {
364 expr: tgt_expr, 360 expr: tgt_expr,
365 }); 361 });
366 } 362 }
367 363 Ty::Never
368 Ty::simple(TypeCtor::Never)
369 } 364 }
370 Expr::Return { expr } => { 365 Expr::Return { expr } => {
371 if let Some(expr) = expr { 366 if let Some(expr) = expr {
@@ -374,14 +369,14 @@ impl<'a> InferenceContext<'a> {
374 let unit = Ty::unit(); 369 let unit = Ty::unit();
375 self.coerce(&unit, &self.return_ty.clone()); 370 self.coerce(&unit, &self.return_ty.clone());
376 } 371 }
377 Ty::simple(TypeCtor::Never) 372 Ty::Never
378 } 373 }
379 Expr::Yield { expr } => { 374 Expr::Yield { expr } => {
380 // FIXME: track yield type for coercion 375 // FIXME: track yield type for coercion
381 if let Some(expr) = expr { 376 if let Some(expr) = expr {
382 self.infer_expr(*expr, &Expectation::none()); 377 self.infer_expr(*expr, &Expectation::none());
383 } 378 }
384 Ty::simple(TypeCtor::Never) 379 Ty::Never
385 } 380 }
386 Expr::RecordLit { path, fields, spread } => { 381 Expr::RecordLit { path, fields, spread } => {
387 let (ty, def_id) = self.resolve_variant(path.as_ref()); 382 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -391,7 +386,7 @@ impl<'a> InferenceContext<'a> {
391 386
392 self.unify(&ty, &expected.ty); 387 self.unify(&ty, &expected.ty);
393 388
394 let substs = ty.substs().unwrap_or_else(Substs::empty); 389 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
395 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 390 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
396 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 391 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
397 for (field_idx, field) in fields.iter().enumerate() { 392 for (field_idx, field) in fields.iter().enumerate() {
@@ -430,30 +425,23 @@ impl<'a> InferenceContext<'a> {
430 }, 425 },
431 ) 426 )
432 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 427 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
433 Ty::Apply(a_ty) => match a_ty.ctor { 428 Ty::Tuple(_, substs) => {
434 TypeCtor::Tuple { .. } => name 429 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
435 .as_tuple_index() 430 }
436 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 431 Ty::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
437 TypeCtor::Adt(AdtId::StructId(s)) => { 432 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
438 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 433 let field = FieldId { parent: s.into(), local_id };
439 let field = FieldId { parent: s.into(), local_id }; 434 self.write_field_resolution(tgt_expr, field);
440 self.write_field_resolution(tgt_expr, field); 435 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
441 self.db.field_types(s.into())[field.local_id] 436 })
442 .clone() 437 }
443 .subst(&a_ty.parameters) 438 Ty::Adt(AdtId(hir_def::AdtId::UnionId(u)), parameters) => {
444 }) 439 self.db.union_data(u).variant_data.field(name).map(|local_id| {
445 } 440 let field = FieldId { parent: u.into(), local_id };
446 TypeCtor::Adt(AdtId::UnionId(u)) => { 441 self.write_field_resolution(tgt_expr, field);
447 self.db.union_data(u).variant_data.field(name).map(|local_id| { 442 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
448 let field = FieldId { parent: u.into(), local_id }; 443 })
449 self.write_field_resolution(tgt_expr, field); 444 }
450 self.db.field_types(u.into())[field.local_id]
451 .clone()
452 .subst(&a_ty.parameters)
453 })
454 }
455 _ => None,
456 },
457 _ => None, 445 _ => None,
458 }) 446 })
459 .unwrap_or(Ty::Unknown); 447 .unwrap_or(Ty::Unknown);
@@ -475,10 +463,11 @@ impl<'a> InferenceContext<'a> {
475 cast_ty 463 cast_ty
476 } 464 }
477 Expr::Ref { expr, rawness, mutability } => { 465 Expr::Ref { expr, rawness, mutability } => {
466 let mutability = lower_to_chalk_mutability(*mutability);
478 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 467 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
479 &expected.ty.as_reference_or_ptr() 468 &expected.ty.as_reference_or_ptr()
480 { 469 {
481 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 470 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not {
482 // FIXME: throw type error - expected mut reference but found shared ref, 471 // FIXME: throw type error - expected mut reference but found shared ref,
483 // which cannot be coerced 472 // which cannot be coerced
484 } 473 }
@@ -491,19 +480,24 @@ impl<'a> InferenceContext<'a> {
491 Expectation::none() 480 Expectation::none()
492 }; 481 };
493 let inner_ty = self.infer_expr_inner(*expr, &expectation); 482 let inner_ty = self.infer_expr_inner(*expr, &expectation);
494 let ty = match rawness { 483 match rawness {
495 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 484 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)),
496 Rawness::Ref => TypeCtor::Ref(*mutability), 485 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)),
497 }; 486 }
498 Ty::apply_one(ty, inner_ty)
499 } 487 }
500 Expr::Box { expr } => { 488 Expr::Box { expr } => {
501 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 489 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
502 if let Some(box_) = self.resolve_boxed_box() { 490 if let Some(box_) = self.resolve_boxed_box() {
503 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 491 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
504 sb = sb.push(inner_ty); 492 sb = sb.push(inner_ty);
493 match self.db.generic_defaults(box_.into()).as_ref() {
494 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
495 sb = sb.push(alloc_ty.value.clone());
496 }
497 _ => (),
498 }
505 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 499 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
506 Ty::apply(TypeCtor::Adt(box_), sb.build()) 500 Ty::adt_ty(box_, sb.build())
507 } else { 501 } else {
508 Ty::Unknown 502 Ty::Unknown
509 } 503 }
@@ -533,13 +527,11 @@ impl<'a> InferenceContext<'a> {
533 UnaryOp::Neg => { 527 UnaryOp::Neg => {
534 match &inner_ty { 528 match &inner_ty {
535 // Fast path for builtins 529 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 530 Ty::Scalar(Scalar::Int(_))
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 531 | Ty::Scalar(Scalar::Uint(_))
538 .. 532 | Ty::Scalar(Scalar::Float(_))
539 }) 533 | Ty::InferenceVar(_, TyVariableKind::Integer)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 534 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty,
541 | Ty::Infer(InferTy::IntVar(..))
542 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
543 // Otherwise we resolve via the std::ops::Neg trait 535 // Otherwise we resolve via the std::ops::Neg trait
544 _ => self 536 _ => self
545 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 537 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -548,9 +540,10 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 540 UnaryOp::Not => {
549 match &inner_ty { 541 match &inner_ty {
550 // Fast path for builtins 542 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 543 Ty::Scalar(Scalar::Bool)
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 544 | Ty::Scalar(Scalar::Int(_))
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 545 | Ty::Scalar(Scalar::Uint(_))
546 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 547 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 548 _ => self
556 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 549 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -561,7 +554,7 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 554 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 555 Some(op) => {
563 let lhs_expectation = match op { 556 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 557 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
565 _ => Expectation::none(), 558 _ => Expectation::none(),
566 }; 559 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 560 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -571,7 +564,7 @@ impl<'a> InferenceContext<'a> {
571 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone()); 564 let ret = op::binary_op_return_ty(*op, lhs_ty.clone(), rhs_ty.clone());
572 565
573 if ret == Ty::Unknown { 566 if ret == Ty::Unknown {
574 mark::hit!(infer_expr_inner_binary_operator_overload); 567 cov_mark::hit!(infer_expr_inner_binary_operator_overload);
575 568
576 self.resolve_associated_type_with_params( 569 self.resolve_associated_type_with_params(
577 lhs_ty, 570 lhs_ty,
@@ -592,31 +585,31 @@ impl<'a> InferenceContext<'a> {
592 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 585 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
593 match (range_type, lhs_ty, rhs_ty) { 586 match (range_type, lhs_ty, rhs_ty) {
594 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 587 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
595 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 588 Some(adt) => Ty::adt_ty(adt, Substs::empty()),
596 None => Ty::Unknown, 589 None => Ty::Unknown,
597 }, 590 },
598 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 591 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
599 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 592 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
600 None => Ty::Unknown, 593 None => Ty::Unknown,
601 }, 594 },
602 (RangeOp::Inclusive, None, Some(ty)) => { 595 (RangeOp::Inclusive, None, Some(ty)) => {
603 match self.resolve_range_to_inclusive() { 596 match self.resolve_range_to_inclusive() {
604 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 597 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
605 None => Ty::Unknown, 598 None => Ty::Unknown,
606 } 599 }
607 } 600 }
608 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 601 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
609 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 602 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
610 None => Ty::Unknown, 603 None => Ty::Unknown,
611 }, 604 },
612 (RangeOp::Inclusive, Some(_), Some(ty)) => { 605 (RangeOp::Inclusive, Some(_), Some(ty)) => {
613 match self.resolve_range_inclusive() { 606 match self.resolve_range_inclusive() {
614 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 607 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
615 None => Ty::Unknown, 608 None => Ty::Unknown,
616 } 609 }
617 } 610 }
618 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 611 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
619 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 612 Some(adt) => Ty::adt_ty(adt, Substs::single(ty)),
620 None => Ty::Unknown, 613 None => Ty::Unknown,
621 }, 614 },
622 (RangeOp::Inclusive, _, None) => Ty::Unknown, 615 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -650,7 +643,7 @@ impl<'a> InferenceContext<'a> {
650 } 643 }
651 Expr::Tuple { exprs } => { 644 Expr::Tuple { exprs } => {
652 let mut tys = match &expected.ty { 645 let mut tys = match &expected.ty {
653 ty_app!(TypeCtor::Tuple { .. }, st) => st 646 Ty::Tuple(_, substs) => substs
654 .iter() 647 .iter()
655 .cloned() 648 .cloned()
656 .chain(repeat_with(|| self.table.new_type_var())) 649 .chain(repeat_with(|| self.table.new_type_var()))
@@ -663,15 +656,11 @@ impl<'a> InferenceContext<'a> {
663 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 656 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
664 } 657 }
665 658
666 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 659 Ty::Tuple(tys.len(), Substs(tys.into()))
667 } 660 }
668 Expr::Array(array) => { 661 Expr::Array(array) => {
669 let elem_ty = match &expected.ty { 662 let elem_ty = match &expected.ty {
670 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 663 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
671 #[allow(unreachable_patterns)]
672 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
673 st.as_single().clone()
674 }
675 _ => self.table.new_type_var(), 664 _ => self.table.new_type_var(),
676 }; 665 };
677 666
@@ -688,30 +677,38 @@ impl<'a> InferenceContext<'a> {
688 ); 677 );
689 self.infer_expr( 678 self.infer_expr(
690 *repeat, 679 *repeat,
691 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 680 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
692 ); 681 );
693 } 682 }
694 } 683 }
695 684
696 Ty::apply_one(TypeCtor::Array, elem_ty) 685 Ty::Array(Substs::single(elem_ty))
697 } 686 }
698 Expr::Literal(lit) => match lit { 687 Expr::Literal(lit) => match lit {
699 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 688 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
700 Literal::String(..) => { 689 Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)),
701 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
702 }
703 Literal::ByteString(..) => { 690 Literal::ByteString(..) => {
704 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 691 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
705 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 692 let array_type = Ty::Array(Substs::single(byte_type));
706 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 693 Ty::Ref(Mutability::Not, Substs::single(array_type))
707 } 694 }
708 Literal::Char(..) => Ty::simple(TypeCtor::Char), 695 Literal::Char(..) => Ty::Scalar(Scalar::Char),
709 Literal::Int(_v, ty) => match ty { 696 Literal::Int(_v, ty) => match ty {
710 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 697 Some(int_ty) => {
698 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
699 }
700 None => self.table.new_integer_var(),
701 },
702 Literal::Uint(_v, ty) => match ty {
703 Some(int_ty) => {
704 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
705 }
711 None => self.table.new_integer_var(), 706 None => self.table.new_integer_var(),
712 }, 707 },
713 Literal::Float(_v, ty) => match ty { 708 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 709 Some(float_ty) => {
710 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
711 }
715 None => self.table.new_float_var(), 712 None => self.table.new_float_var(),
716 }, 713 },
717 }, 714 },
@@ -767,7 +764,7 @@ impl<'a> InferenceContext<'a> {
767 // `!`). 764 // `!`).
768 if self.diverges.is_always() { 765 if self.diverges.is_always() {
769 // we don't even make an attempt at coercion 766 // we don't even make an attempt at coercion
770 self.table.new_maybe_never_type_var() 767 self.table.new_maybe_never_var()
771 } else { 768 } else {
772 self.coerce(&Ty::unit(), expected.coercion_target()); 769 self.coerce(&Ty::unit(), expected.coercion_target());
773 Ty::unit() 770 Ty::unit()
@@ -824,7 +821,7 @@ impl<'a> InferenceContext<'a> {
824 // Apply autoref so the below unification works correctly 821 // Apply autoref so the below unification works correctly
825 // FIXME: return correct autorefs from lookup_method 822 // FIXME: return correct autorefs from lookup_method
826 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 823 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
827 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 824 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
828 _ => derefed_receiver_ty, 825 _ => derefed_receiver_ty,
829 }; 826 };
830 self.unify(&expected_receiver_ty, &actual_receiver_ty); 827 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -901,30 +898,26 @@ impl<'a> InferenceContext<'a> {
901 } 898 }
902 899
903 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 900 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
904 if let Ty::Apply(a_ty) = callable_ty { 901 if let &Ty::FnDef(def, ref parameters) = callable_ty {
905 if let TypeCtor::FnDef(def) = a_ty.ctor { 902 let generic_predicates = self.db.generic_predicates(def.into());
906 let generic_predicates = self.db.generic_predicates(def.into()); 903 for predicate in generic_predicates.iter() {
907 for predicate in generic_predicates.iter() { 904 let predicate = predicate.clone().subst(parameters);
908 let predicate = predicate.clone().subst(&a_ty.parameters); 905 if let Some(obligation) = Obligation::from_predicate(predicate) {
909 if let Some(obligation) = Obligation::from_predicate(predicate) { 906 self.obligations.push(obligation);
910 self.obligations.push(obligation);
911 }
912 } 907 }
913 // add obligation for trait implementation, if this is a trait method 908 }
914 match def { 909 // add obligation for trait implementation, if this is a trait method
915 CallableDefId::FunctionId(f) => { 910 match def {
916 if let AssocContainerId::TraitId(trait_) = 911 CallableDefId::FunctionId(f) => {
917 f.lookup(self.db.upcast()).container 912 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
918 { 913 {
919 // construct a TraitDef 914 // construct a TraitDef
920 let substs = a_ty 915 let substs =
921 .parameters 916 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
922 .prefix(generics(self.db.upcast(), trait_.into()).len()); 917 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
923 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
924 }
925 } 918 }
926 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
927 } 919 }
920 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
928 } 921 }
929 } 922 }
930 } 923 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..a0ac8d80f 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -3,17 +3,16 @@
3use std::iter::repeat; 3use std::iter::repeat;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use chalk_ir::Mutability;
6use hir_def::{ 7use hir_def::{
7 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, 8 expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
8 path::Path, 9 path::Path,
9 type_ref::Mutability,
10 FieldId, 10 FieldId,
11}; 11};
12use hir_expand::name::Name; 12use hir_expand::name::Name;
13use test_utils::mark;
14 13
15use super::{BindingMode, Expectation, InferenceContext}; 14use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 15use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty};
17 16
18impl<'a> InferenceContext<'a> { 17impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 18 fn infer_tuple_struct_pat(
@@ -32,7 +31,7 @@ impl<'a> InferenceContext<'a> {
32 } 31 }
33 self.unify(&ty, expected); 32 self.unify(&ty, expected);
34 33
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 34 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 35
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 36 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 37 let (pre, post) = match ellipsis {
@@ -71,7 +70,7 @@ impl<'a> InferenceContext<'a> {
71 70
72 self.unify(&ty, expected); 71 self.unify(&ty, expected);
73 72
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 73 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 74
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 75 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 76 for subpat in subpats {
@@ -103,12 +102,12 @@ impl<'a> InferenceContext<'a> {
103 expected = inner; 102 expected = inner;
104 default_bm = match default_bm { 103 default_bm = match default_bm {
105 BindingMode::Move => BindingMode::Ref(mutability), 104 BindingMode::Move => BindingMode::Ref(mutability),
106 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), 105 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), 106 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability),
108 } 107 }
109 } 108 }
110 } else if let Pat::Ref { .. } = &body[pat] { 109 } else if let Pat::Ref { .. } = &body[pat] {
111 mark::hit!(match_ergonomics_ref); 110 cov_mark::hit!(match_ergonomics_ref);
112 // When you encounter a `&pat` pattern, reset to Move. 111 // When you encounter a `&pat` pattern, reset to Move.
113 // This is so that `w` is by value: `let (_, &w) = &(1, &2);` 112 // This is so that `w` is by value: `let (_, &w) = &(1, &2);`
114 default_bm = BindingMode::Move; 113 default_bm = BindingMode::Move;
@@ -138,10 +137,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 137 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 138 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 139
141 Ty::apply( 140 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into()))
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 141 }
146 Pat::Or(ref pats) => { 142 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 143 if let Some((first_pat, rest)) = pats.split_first() {
@@ -155,9 +151,10 @@ impl<'a> InferenceContext<'a> {
155 } 151 }
156 } 152 }
157 Pat::Ref { pat, mutability } => { 153 Pat::Ref { pat, mutability } => {
154 let mutability = lower_to_chalk_mutability(*mutability);
158 let expectation = match expected.as_reference() { 155 let expectation = match expected.as_reference() {
159 Some((inner_ty, exp_mut)) => { 156 Some((inner_ty, exp_mut)) => {
160 if *mutability != exp_mut { 157 if mutability != exp_mut {
161 // FIXME: emit type error? 158 // FIXME: emit type error?
162 } 159 }
163 inner_ty 160 inner_ty
@@ -165,7 +162,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 162 _ => &Ty::Unknown,
166 }; 163 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 164 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 165 Ty::Ref(mutability, Substs::single(subty))
169 } 166 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 167 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 168 p.as_ref(),
@@ -198,7 +195,7 @@ impl<'a> InferenceContext<'a> {
198 195
199 let bound_ty = match mode { 196 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 197 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 198 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 199 }
203 BindingMode::Move => inner_ty.clone(), 200 BindingMode::Move => inner_ty.clone(),
204 }; 201 };
@@ -207,17 +204,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 204 return inner_ty;
208 } 205 }
209 Pat::Slice { prefix, slice, suffix } => { 206 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 207 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 208 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 209 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 210 _ => (Ty::Slice, Ty::Unknown),
214 }; 211 };
215 212
216 for pat_id in prefix.iter().chain(suffix) { 213 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 214 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 215 }
219 216
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 217 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 218 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 219 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 220 }
@@ -239,7 +236,7 @@ impl<'a> InferenceContext<'a> {
239 }; 236 };
240 237
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 238 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 239 Ty::adt_ty(box_adt, Substs::single(inner_ty))
243 } 240 }
244 None => Ty::Unknown, 241 None => Ty::Unknown,
245 }, 242 },
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs
index 5d541104e..ae3554bac 100644
--- a/crates/hir_ty/src/infer/path.rs
+++ b/crates/hir_ty/src/infer/path.rs
@@ -260,7 +260,7 @@ impl<'a> InferenceContext<'a> {
260 })); 260 }));
261 Some(trait_substs) 261 Some(trait_substs)
262 } 262 }
263 AssocContainerId::ContainerId(_) => None, 263 AssocContainerId::ModuleId(_) => None,
264 }; 264 };
265 265
266 self.write_assoc_resolution(id, item); 266 self.write_assoc_resolution(id, item);
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 76984242e..54fcfed10 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,14 +2,13 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind};
5use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
6 7
7use test_utils::mark;
8
9use super::{InferenceContext, Obligation}; 8use super::{InferenceContext, Obligation};
10use crate::{ 9use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, 10 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar,
12 TyKind, TypeCtor, TypeWalk, 11 Substs, Ty, TypeWalk,
13}; 12};
14 13
15impl<'a> InferenceContext<'a> { 14impl<'a> InferenceContext<'a> {
@@ -26,7 +25,7 @@ where
26 'a: 'b, 25 'a: 'b,
27{ 26{
28 ctx: &'b mut InferenceContext<'a>, 27 ctx: &'b mut InferenceContext<'a>,
29 free_vars: Vec<InferTy>, 28 free_vars: Vec<(InferenceVar, TyVariableKind)>,
30 /// A stack of type variables that is used to detect recursive types (which 29 /// A stack of type variables that is used to detect recursive types (which
31 /// are an error, but we need to protect against them to avoid stack 30 /// are an error, but we need to protect against them to avoid stack
32 /// overflows). 31 /// overflows).
@@ -36,17 +35,14 @@ where
36#[derive(Debug)] 35#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 36pub(super) struct Canonicalized<T> {
38 pub(super) value: Canonical<T>, 37 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 38 free_vars: Vec<(InferenceVar, TyVariableKind)>,
40} 39}
41 40
42impl<'a, 'b> Canonicalizer<'a, 'b> 41impl<'a, 'b> Canonicalizer<'a, 'b> {
43where 42 fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize {
44 'a: 'b, 43 self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| {
45{
46 fn add(&mut self, free_var: InferTy) -> usize {
47 self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| {
48 let next_index = self.free_vars.len(); 44 let next_index = self.free_vars.len();
49 self.free_vars.push(free_var); 45 self.free_vars.push((free_var, kind));
50 next_index 46 next_index
51 }) 47 })
52 } 48 }
@@ -54,11 +50,11 @@ where
54 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 {
55 t.fold_binders( 51 t.fold_binders(
56 &mut |ty, binders| match ty { 52 &mut |ty, binders| match ty {
57 Ty::Infer(tv) => { 53 Ty::InferenceVar(var, kind) => {
58 let inner = tv.to_inner(); 54 let inner = var.to_inner();
59 if self.var_stack.contains(&inner) { 55 if self.var_stack.contains(&inner) {
60 // recursive type 56 // recursive type
61 return tv.fallback_value(); 57 return self.ctx.table.type_variable_table.fallback_value(var, kind);
62 } 58 }
63 if let Some(known_ty) = 59 if let Some(known_ty) =
64 self.ctx.table.var_unification_table.inlined_probe_value(inner).known() 60 self.ctx.table.var_unification_table.inlined_probe_value(inner).known()
@@ -69,14 +65,8 @@ where
69 result 65 result
70 } else { 66 } else {
71 let root = self.ctx.table.var_unification_table.find(inner); 67 let root = self.ctx.table.var_unification_table.find(inner);
72 let free_var = match tv { 68 let position = self.add(InferenceVar::from_inner(root), kind);
73 InferTy::TypeVar(_) => InferTy::TypeVar(root), 69 Ty::BoundVar(BoundVar::new(binders, position))
74 InferTy::IntVar(_) => InferTy::IntVar(root),
75 InferTy::FloatVar(_) => InferTy::FloatVar(root),
76 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root),
77 };
78 let position = self.add(free_var);
79 Ty::Bound(BoundVar::new(binders, position))
80 } 70 }
81 } 71 }
82 _ => ty, 72 _ => ty,
@@ -86,19 +76,7 @@ where
86 } 76 }
87 77
88 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 78 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
89 let kinds = self 79 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect();
90 .free_vars
91 .iter()
92 .map(|v| match v {
93 // mapping MaybeNeverTypeVar to the same kind as general ones
94 // should be fine, because as opposed to int or float type vars,
95 // they don't restrict what kind of type can go into them, they
96 // just affect fallback.
97 InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General,
98 InferTy::IntVar(_) => TyKind::Integer,
99 InferTy::FloatVar(_) => TyKind::Float,
100 })
101 .collect();
102 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 80 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars }
103 } 81 }
104 82
@@ -130,9 +108,10 @@ impl<T> Canonicalized<T> {
130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 108 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 109 ty.walk_mut_binders(
132 &mut |ty, binders| { 110 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 111 if let &mut Ty::BoundVar(bound) = ty {
134 if bound.debruijn >= binders { 112 if bound.debruijn >= binders {
135 *ty = Ty::Infer(self.free_vars[bound.index]); 113 let (v, k) = self.free_vars[bound.index];
114 *ty = Ty::InferenceVar(v, k);
136 } 115 }
137 } 116 }
138 }, 117 },
@@ -152,18 +131,18 @@ impl<T> Canonicalized<T> {
152 .kinds 131 .kinds
153 .iter() 132 .iter()
154 .map(|k| match k { 133 .map(|k| match k {
155 TyKind::General => ctx.table.new_type_var(), 134 TyVariableKind::General => ctx.table.new_type_var(),
156 TyKind::Integer => ctx.table.new_integer_var(), 135 TyVariableKind::Integer => ctx.table.new_integer_var(),
157 TyKind::Float => ctx.table.new_float_var(), 136 TyVariableKind::Float => ctx.table.new_float_var(),
158 }) 137 })
159 .collect(), 138 .collect(),
160 ); 139 );
161 for (i, ty) in solution.value.into_iter().enumerate() { 140 for (i, ty) in solution.value.into_iter().enumerate() {
162 let var = self.free_vars[i]; 141 let (v, k) = self.free_vars[i];
163 // eagerly replace projections in the type; we may be getting types 142 // eagerly replace projections in the type; we may be getting types
164 // e.g. from where clauses where this hasn't happened yet 143 // e.g. from where clauses where this hasn't happened yet
165 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 144 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
166 ctx.table.unify(&Ty::Infer(var), &ty); 145 ctx.table.unify(&Ty::InferenceVar(v, k), &ty);
167 } 146 }
168 } 147 }
169} 148}
@@ -187,7 +166,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
187 // (kind of hacky) 166 // (kind of hacky)
188 for (i, var) in vars.iter().enumerate() { 167 for (i, var) in vars.iter().enumerate() {
189 if &*table.resolve_ty_shallow(var) == var { 168 if &*table.resolve_ty_shallow(var) == var {
190 table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); 169 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)));
191 } 170 }
192 } 171 }
193 Some( 172 Some(
@@ -198,31 +177,73 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
198} 177}
199 178
200#[derive(Clone, Debug)] 179#[derive(Clone, Debug)]
180pub(super) struct TypeVariableTable {
181 inner: Vec<TypeVariableData>,
182}
183
184impl TypeVariableTable {
185 fn push(&mut self, data: TypeVariableData) {
186 self.inner.push(data);
187 }
188
189 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
190 self.inner[iv.to_inner().0 as usize].diverging = diverging;
191 }
192
193 fn is_diverging(&mut self, iv: InferenceVar) -> bool {
194 self.inner[iv.to_inner().0 as usize].diverging
195 }
196
197 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
198 match kind {
199 _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never,
200 TyVariableKind::General => Ty::Unknown,
201 TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)),
202 TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)),
203 }
204 }
205}
206
207#[derive(Copy, Clone, Debug)]
208pub(crate) struct TypeVariableData {
209 diverging: bool,
210}
211
212#[derive(Clone, Debug)]
201pub(crate) struct InferenceTable { 213pub(crate) struct InferenceTable {
202 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 214 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
215 pub(super) type_variable_table: TypeVariableTable,
203} 216}
204 217
205impl InferenceTable { 218impl InferenceTable {
206 pub(crate) fn new() -> Self { 219 pub(crate) fn new() -> Self {
207 InferenceTable { var_unification_table: InPlaceUnificationTable::new() } 220 InferenceTable {
221 var_unification_table: InPlaceUnificationTable::new(),
222 type_variable_table: TypeVariableTable { inner: Vec::new() },
223 }
224 }
225
226 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
227 self.type_variable_table.push(TypeVariableData { diverging });
228 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
229 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
230 Ty::InferenceVar(InferenceVar::from_inner(key), kind)
208 } 231 }
209 232
210 pub(crate) fn new_type_var(&mut self) -> Ty { 233 pub(crate) fn new_type_var(&mut self) -> Ty {
211 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 234 self.new_var(TyVariableKind::General, false)
212 } 235 }
213 236
214 pub(crate) fn new_integer_var(&mut self) -> Ty { 237 pub(crate) fn new_integer_var(&mut self) -> Ty {
215 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 238 self.new_var(TyVariableKind::Integer, false)
216 } 239 }
217 240
218 pub(crate) fn new_float_var(&mut self) -> Ty { 241 pub(crate) fn new_float_var(&mut self) -> Ty {
219 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 242 self.new_var(TyVariableKind::Float, false)
220 } 243 }
221 244
222 pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { 245 pub(crate) fn new_maybe_never_var(&mut self) -> Ty {
223 Ty::Infer(InferTy::MaybeNeverTypeVar( 246 self.new_var(TyVariableKind::General, true)
224 self.var_unification_table.new_key(TypeVarValue::Unknown),
225 ))
226 } 247 }
227 248
228 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 249 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
@@ -257,12 +278,14 @@ impl InferenceTable {
257 // try to resolve type vars first 278 // try to resolve type vars first
258 let ty1 = self.resolve_ty_shallow(ty1); 279 let ty1 = self.resolve_ty_shallow(ty1);
259 let ty2 = self.resolve_ty_shallow(ty2); 280 let ty2 = self.resolve_ty_shallow(ty2);
260 match (&*ty1, &*ty2) { 281 if ty1.equals_ctor(&ty2) {
261 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 282 match (ty1.substs(), ty2.substs()) {
262 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 283 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1),
284 (None, None) => true,
285 _ => false,
263 } 286 }
264 287 } else {
265 _ => self.unify_inner_trivial(&ty1, &ty2, depth), 288 self.unify_inner_trivial(&ty1, &ty2, depth)
266 } 289 }
267 } 290 }
268 291
@@ -281,31 +304,46 @@ impl InferenceTable {
281 true 304 true
282 } 305 }
283 306
284 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) 307 (
285 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) 308 Ty::InferenceVar(tv1, TyVariableKind::General),
286 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) 309 Ty::InferenceVar(tv2, TyVariableKind::General),
310 )
287 | ( 311 | (
288 Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), 312 Ty::InferenceVar(tv1, TyVariableKind::Integer),
289 Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), 313 Ty::InferenceVar(tv2, TyVariableKind::Integer),
290 ) => { 314 )
315 | (
316 Ty::InferenceVar(tv1, TyVariableKind::Float),
317 Ty::InferenceVar(tv2, TyVariableKind::Float),
318 ) if self.type_variable_table.is_diverging(*tv1)
319 == self.type_variable_table.is_diverging(*tv2) =>
320 {
291 // both type vars are unknown since we tried to resolve them 321 // both type vars are unknown since we tried to resolve them
292 self.var_unification_table.union(*tv1, *tv2); 322 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
293 true 323 true
294 } 324 }
295 325
296 // The order of MaybeNeverTypeVar matters here. 326 // The order of MaybeNeverTypeVar matters here.
297 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 327 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
298 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 328 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
299 (Ty::Infer(InferTy::TypeVar(tv)), other) 329 (Ty::InferenceVar(tv, TyVariableKind::General), other)
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 330 | (other, Ty::InferenceVar(tv, TyVariableKind::General))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 331 | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_)))
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 332 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) 333 | (
304 | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) 334 Ty::InferenceVar(tv, TyVariableKind::Integer),
305 | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) 335 other @ Ty::Scalar(Scalar::Uint(_)),
306 | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { 336 )
337 | (
338 other @ Ty::Scalar(Scalar::Uint(_)),
339 Ty::InferenceVar(tv, TyVariableKind::Integer),
340 )
341 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_)))
342 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) =>
343 {
307 // the type var is unknown since we tried to resolve it 344 // the type var is unknown since we tried to resolve it
308 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 345 self.var_unification_table
346 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone()));
309 true 347 true
310 } 348 }
311 349
@@ -347,10 +385,10 @@ impl InferenceTable {
347 // more than once 385 // more than once
348 for i in 0..3 { 386 for i in 0..3 {
349 if i > 0 { 387 if i > 0 {
350 mark::hit!(type_var_resolves_to_int_var); 388 cov_mark::hit!(type_var_resolves_to_int_var);
351 } 389 }
352 match &*ty { 390 match &*ty {
353 Ty::Infer(tv) => { 391 Ty::InferenceVar(tv, _) => {
354 let inner = tv.to_inner(); 392 let inner = tv.to_inner();
355 match self.var_unification_table.inlined_probe_value(inner).known() { 393 match self.var_unification_table.inlined_probe_value(inner).known() {
356 Some(known_ty) => { 394 Some(known_ty) => {
@@ -373,12 +411,12 @@ impl InferenceTable {
373 /// known type. 411 /// known type.
374 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 412 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
375 ty.fold(&mut |ty| match ty { 413 ty.fold(&mut |ty| match ty {
376 Ty::Infer(tv) => { 414 Ty::InferenceVar(tv, kind) => {
377 let inner = tv.to_inner(); 415 let inner = tv.to_inner();
378 if tv_stack.contains(&inner) { 416 if tv_stack.contains(&inner) {
379 mark::hit!(type_var_cycles_resolve_as_possible); 417 cov_mark::hit!(type_var_cycles_resolve_as_possible);
380 // recursive type 418 // recursive type
381 return tv.fallback_value(); 419 return self.type_variable_table.fallback_value(tv, kind);
382 } 420 }
383 if let Some(known_ty) = 421 if let Some(known_ty) =
384 self.var_unification_table.inlined_probe_value(inner).known() 422 self.var_unification_table.inlined_probe_value(inner).known()
@@ -400,12 +438,12 @@ impl InferenceTable {
400 /// replaced by Ty::Unknown. 438 /// replaced by Ty::Unknown.
401 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 439 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
402 ty.fold(&mut |ty| match ty { 440 ty.fold(&mut |ty| match ty {
403 Ty::Infer(tv) => { 441 Ty::InferenceVar(tv, kind) => {
404 let inner = tv.to_inner(); 442 let inner = tv.to_inner();
405 if tv_stack.contains(&inner) { 443 if tv_stack.contains(&inner) {
406 mark::hit!(type_var_cycles_resolve_completely); 444 cov_mark::hit!(type_var_cycles_resolve_completely);
407 // recursive type 445 // recursive type
408 return tv.fallback_value(); 446 return self.type_variable_table.fallback_value(tv, kind);
409 } 447 }
410 if let Some(known_ty) = 448 if let Some(known_ty) =
411 self.var_unification_table.inlined_probe_value(inner).known() 449 self.var_unification_table.inlined_probe_value(inner).known()
@@ -416,7 +454,7 @@ impl InferenceTable {
416 tv_stack.pop(); 454 tv_stack.pop();
417 result 455 result
418 } else { 456 } else {
419 tv.fallback_value() 457 self.type_variable_table.fallback_value(tv, kind)
420 } 458 }
421 } 459 }
422 _ => ty, 460 _ => ty,
@@ -426,7 +464,7 @@ impl InferenceTable {
426 464
427/// The ID of a type variable. 465/// The ID of a type variable.
428#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 466#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
429pub struct TypeVarId(pub(super) u32); 467pub(super) struct TypeVarId(pub(super) u32);
430 468
431impl UnifyKey for TypeVarId { 469impl UnifyKey for TypeVarId {
432 type Value = TypeVarValue; 470 type Value = TypeVarValue;
@@ -447,7 +485,7 @@ impl UnifyKey for TypeVarId {
447/// The value of a type variable: either we already know the type, or we don't 485/// The value of a type variable: either we already know the type, or we don't
448/// know it yet. 486/// know it yet.
449#[derive(Clone, PartialEq, Eq, Debug)] 487#[derive(Clone, PartialEq, Eq, Debug)]
450pub enum TypeVarValue { 488pub(super) enum TypeVarValue {
451 Known(Ty), 489 Known(Ty),
452 Unknown, 490 Unknown,
453} 491}
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 50d248674..e77f24e4e 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -25,32 +25,31 @@ mod test_db;
25 25
26use std::{iter, mem, ops::Deref, sync::Arc}; 26use std::{iter, mem, ops::Deref, sync::Arc};
27 27
28use base_db::{salsa, CrateId}; 28use base_db::salsa;
29use hir_def::{ 29use hir_def::{
30 builtin_type::BuiltinType, 30 builtin_type::BuiltinType, expr::ExprId, type_ref::Rawness, AssocContainerId, DefWithBodyId,
31 expr::ExprId, 31 FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId,
32 type_ref::{Mutability, Rawness}, 32 TypeParamId,
33 AdtId, AssocContainerId, DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId,
34 Lookup, TraitId, TypeAliasId, TypeParamId,
35}; 33};
36use itertools::Itertools; 34use itertools::Itertools;
37 35
38use crate::{ 36use crate::{
39 db::HirDatabase, 37 db::HirDatabase,
40 display::HirDisplay, 38 display::HirDisplay,
41 primitive::{FloatTy, IntTy},
42 utils::{generics, make_mut_slice, Generics}, 39 utils::{generics, make_mut_slice, Generics},
43}; 40};
44 41
45pub use autoderef::autoderef; 42pub use autoderef::autoderef;
46pub use infer::{InferTy, InferenceResult}; 43pub use infer::{InferenceResult, InferenceVar};
47pub use lower::{ 44pub use lower::{
48 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode, 45 associated_type_shorthand_candidates, callable_item_sig, CallableDefId, ImplTraitLoweringMode,
49 TyDefId, TyLoweringContext, ValueTyDefId, 46 TyDefId, TyLoweringContext, ValueTyDefId,
50}; 47};
51pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 48pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
52 49
53pub use chalk_ir::{BoundVar, DebruijnIndex}; 50pub use chalk_ir::{AdtId, BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
51
52pub(crate) use crate::traits::chalk::Interner;
54 53
55#[derive(Clone, PartialEq, Eq, Debug, Hash)] 54#[derive(Clone, PartialEq, Eq, Debug, Hash)]
56pub enum Lifetime { 55pub enum Lifetime {
@@ -58,211 +57,6 @@ pub enum Lifetime {
58 Static, 57 Static,
59} 58}
60 59
61/// A type constructor or type name: this might be something like the primitive
62/// type `bool`, a struct like `Vec`, or things like function pointers or
63/// tuples.
64#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
65pub enum TypeCtor {
66 /// The primitive boolean type. Written as `bool`.
67 Bool,
68
69 /// The primitive character type; holds a Unicode scalar value
70 /// (a non-surrogate code point). Written as `char`.
71 Char,
72
73 /// A primitive integer type. For example, `i32`.
74 Int(IntTy),
75
76 /// A primitive floating-point type. For example, `f64`.
77 Float(FloatTy),
78
79 /// Structures, enumerations and unions.
80 Adt(AdtId),
81
82 /// The pointee of a string slice. Written as `str`.
83 Str,
84
85 /// The pointee of an array slice. Written as `[T]`.
86 Slice,
87
88 /// An array with the given length. Written as `[T; n]`.
89 Array,
90
91 /// A raw pointer. Written as `*mut T` or `*const T`
92 RawPtr(Mutability),
93
94 /// A reference; a pointer with an associated lifetime. Written as
95 /// `&'a mut T` or `&'a T`.
96 Ref(Mutability),
97
98 /// The anonymous type of a function declaration/definition. Each
99 /// function has a unique type, which is output (for a function
100 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
101 ///
102 /// This includes tuple struct / enum variant constructors as well.
103 ///
104 /// For example the type of `bar` here:
105 ///
106 /// ```
107 /// fn foo() -> i32 { 1 }
108 /// let bar = foo; // bar: fn() -> i32 {foo}
109 /// ```
110 FnDef(CallableDefId),
111
112 /// A pointer to a function. Written as `fn() -> i32`.
113 ///
114 /// For example the type of `bar` here:
115 ///
116 /// ```
117 /// fn foo() -> i32 { 1 }
118 /// let bar: fn() -> i32 = foo;
119 /// ```
120 // FIXME make this a Ty variant like in Chalk
121 FnPtr { num_args: u16, is_varargs: bool },
122
123 /// The never type `!`.
124 Never,
125
126 /// A tuple type. For example, `(i32, bool)`.
127 Tuple { cardinality: u16 },
128
129 /// Represents an associated item like `Iterator::Item`. This is used
130 /// when we have tried to normalize a projection like `T::Item` but
131 /// couldn't find a better representation. In that case, we generate
132 /// an **application type** like `(Iterator::Item)<T>`.
133 AssociatedType(TypeAliasId),
134
135 /// This represents a placeholder for an opaque type in situations where we
136 /// don't know the hidden type (i.e. currently almost always). This is
137 /// analogous to the `AssociatedType` type constructor.
138 /// It is also used as the type of async block, with one type parameter
139 /// representing the Future::Output type.
140 OpaqueType(OpaqueTyId),
141
142 /// Represents a foreign type declared in external blocks.
143 ForeignType(TypeAliasId),
144
145 /// The type of a specific closure.
146 ///
147 /// The closure signature is stored in a `FnPtr` type in the first type
148 /// parameter.
149 Closure { def: DefWithBodyId, expr: ExprId },
150}
151
152impl TypeCtor {
153 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
154 match self {
155 TypeCtor::Bool
156 | TypeCtor::Char
157 | TypeCtor::Int(_)
158 | TypeCtor::Float(_)
159 | TypeCtor::Str
160 | TypeCtor::Never => 0,
161 TypeCtor::Slice
162 | TypeCtor::Array
163 | TypeCtor::RawPtr(_)
164 | TypeCtor::Ref(_)
165 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
166 => 1,
167 TypeCtor::Adt(adt) => {
168 let generic_params = generics(db.upcast(), adt.into());
169 generic_params.len()
170 }
171 TypeCtor::FnDef(callable) => {
172 let generic_params = generics(db.upcast(), callable.into());
173 generic_params.len()
174 }
175 TypeCtor::AssociatedType(type_alias) => {
176 let generic_params = generics(db.upcast(), type_alias.into());
177 generic_params.len()
178 }
179 TypeCtor::ForeignType(type_alias) => {
180 let generic_params = generics(db.upcast(), type_alias.into());
181 generic_params.len()
182 }
183 TypeCtor::OpaqueType(opaque_ty_id) => {
184 match opaque_ty_id {
185 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
186 let generic_params = generics(db.upcast(), func.into());
187 generic_params.len()
188 }
189 // 1 param representing Future::Output type.
190 OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1,
191 }
192 }
193 TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1,
194 TypeCtor::Tuple { cardinality } => cardinality as usize,
195 }
196 }
197
198 pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
199 match self {
200 TypeCtor::Bool
201 | TypeCtor::Char
202 | TypeCtor::Int(_)
203 | TypeCtor::Float(_)
204 | TypeCtor::Str
205 | TypeCtor::Never
206 | TypeCtor::Slice
207 | TypeCtor::Array
208 | TypeCtor::RawPtr(_)
209 | TypeCtor::Ref(_)
210 | TypeCtor::FnPtr { .. }
211 | TypeCtor::Tuple { .. } => None,
212 // Closure's krate is irrelevant for coherence I would think?
213 TypeCtor::Closure { .. } => None,
214 TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()),
215 TypeCtor::FnDef(callable) => Some(callable.krate(db)),
216 TypeCtor::AssociatedType(type_alias) => {
217 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
218 }
219 TypeCtor::ForeignType(type_alias) => {
220 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
221 }
222 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
223 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
224 Some(func.lookup(db.upcast()).module(db.upcast()).krate())
225 }
226 OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => {
227 Some(def.module(db.upcast()).krate())
228 }
229 },
230 }
231 }
232
233 pub fn as_generic_def(self) -> Option<GenericDefId> {
234 match self {
235 TypeCtor::Bool
236 | TypeCtor::Char
237 | TypeCtor::Int(_)
238 | TypeCtor::Float(_)
239 | TypeCtor::Str
240 | TypeCtor::Never
241 | TypeCtor::Slice
242 | TypeCtor::Array
243 | TypeCtor::RawPtr(_)
244 | TypeCtor::Ref(_)
245 | TypeCtor::FnPtr { .. }
246 | TypeCtor::Tuple { .. }
247 | TypeCtor::Closure { .. } => None,
248 TypeCtor::Adt(adt) => Some(adt.into()),
249 TypeCtor::FnDef(callable) => Some(callable.into()),
250 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
251 TypeCtor::ForeignType(type_alias) => Some(type_alias.into()),
252 TypeCtor::OpaqueType(_impl_trait_id) => None,
253 }
254 }
255}
256
257/// A nominal type with (maybe 0) type parameters. This might be a primitive
258/// type like `bool`, a struct, tuple, function pointer, reference or
259/// several other things.
260#[derive(Clone, PartialEq, Eq, Debug, Hash)]
261pub struct ApplicationTy {
262 pub ctor: TypeCtor,
263 pub parameters: Substs,
264}
265
266#[derive(Clone, PartialEq, Eq, Debug, Hash)] 60#[derive(Clone, PartialEq, Eq, Debug, Hash)]
267pub struct OpaqueTy { 61pub struct OpaqueTy {
268 pub opaque_ty_id: OpaqueTyId, 62 pub opaque_ty_id: OpaqueTyId,
@@ -305,29 +99,118 @@ impl TypeWalk for ProjectionTy {
305 } 99 }
306} 100}
307 101
308/// A type. 102#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
309/// 103pub struct FnSig {
310/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 104 pub variadic: bool,
311/// the same thing (but in a different way). 105}
312/// 106
313/// This should be cheap to clone.
314#[derive(Clone, PartialEq, Eq, Debug, Hash)] 107#[derive(Clone, PartialEq, Eq, Debug, Hash)]
315pub enum Ty { 108pub struct FnPointer {
316 /// A nominal type with (maybe 0) type parameters. This might be a primitive 109 pub num_args: usize,
317 /// type like `bool`, a struct, tuple, function pointer, reference or 110 pub sig: FnSig,
318 /// several other things. 111 pub substs: Substs,
319 Apply(ApplicationTy), 112}
320 113
114#[derive(Clone, PartialEq, Eq, Debug, Hash)]
115pub enum AliasTy {
321 /// A "projection" type corresponds to an (unnormalized) 116 /// A "projection" type corresponds to an (unnormalized)
322 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 117 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
323 /// trait and all its parameters are fully known. 118 /// trait and all its parameters are fully known.
324 Projection(ProjectionTy), 119 Projection(ProjectionTy),
325
326 /// An opaque type (`impl Trait`). 120 /// An opaque type (`impl Trait`).
327 /// 121 ///
328 /// This is currently only used for return type impl trait; each instance of 122 /// This is currently only used for return type impl trait; each instance of
329 /// `impl Trait` in a return type gets its own ID. 123 /// `impl Trait` in a return type gets its own ID.
330 Opaque(OpaqueTy), 124 Opaque(OpaqueTy),
125}
126
127/// A type.
128///
129/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
130/// the same thing (but in a different way).
131///
132/// This should be cheap to clone.
133#[derive(Clone, PartialEq, Eq, Debug, Hash)]
134pub enum Ty {
135 /// Structures, enumerations and unions.
136 Adt(AdtId<Interner>, Substs),
137
138 /// Represents an associated item like `Iterator::Item`. This is used
139 /// when we have tried to normalize a projection like `T::Item` but
140 /// couldn't find a better representation. In that case, we generate
141 /// an **application type** like `(Iterator::Item)<T>`.
142 AssociatedType(TypeAliasId, Substs),
143
144 /// a scalar type like `bool` or `u32`
145 Scalar(Scalar),
146
147 /// A tuple type. For example, `(i32, bool)`.
148 Tuple(usize, Substs),
149
150 /// An array with the given length. Written as `[T; n]`.
151 Array(Substs),
152
153 /// The pointee of an array slice. Written as `[T]`.
154 Slice(Substs),
155
156 /// A raw pointer. Written as `*mut T` or `*const T`
157 Raw(Mutability, Substs),
158
159 /// A reference; a pointer with an associated lifetime. Written as
160 /// `&'a mut T` or `&'a T`.
161 Ref(Mutability, Substs),
162
163 /// 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
165 /// analogous to the `AssociatedType` type constructor.
166 /// It is also used as the type of async block, with one type parameter
167 /// representing the Future::Output type.
168 OpaqueType(OpaqueTyId, Substs),
169
170 /// The anonymous type of a function declaration/definition. Each
171 /// function has a unique type, which is output (for a function
172 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
173 ///
174 /// This includes tuple struct / enum variant constructors as well.
175 ///
176 /// For example the type of `bar` here:
177 ///
178 /// ```
179 /// fn foo() -> i32 { 1 }
180 /// let bar = foo; // bar: fn() -> i32 {foo}
181 /// ```
182 FnDef(CallableDefId, Substs),
183
184 /// The pointee of a string slice. Written as `str`.
185 Str,
186
187 /// The never type `!`.
188 Never,
189
190 /// The type of a specific closure.
191 ///
192 /// The closure signature is stored in a `FnPtr` type in the first type
193 /// parameter.
194 Closure(DefWithBodyId, ExprId, Substs),
195
196 /// Represents a foreign type declared in external blocks.
197 ForeignType(TypeAliasId),
198
199 /// A pointer to a function. Written as `fn() -> i32`.
200 ///
201 /// For example the type of `bar` here:
202 ///
203 /// ```
204 /// fn foo() -> i32 { 1 }
205 /// let bar: fn() -> i32 = foo;
206 /// ```
207 Function(FnPointer),
208
209 /// An "alias" type represents some form of type alias, such as:
210 /// - An associated type projection like `<T as Iterator>::Item`
211 /// - `impl Trait` types
212 /// - Named type aliases like `type Foo<X> = Vec<X>`
213 Alias(AliasTy),
331 214
332 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 215 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T)
333 /// {}` when we're type-checking the body of that function. In this 216 /// {}` when we're type-checking the body of that function. In this
@@ -340,10 +223,10 @@ pub enum Ty {
340 /// parameters get turned into variables; during trait resolution, inference 223 /// parameters get turned into variables; during trait resolution, inference
341 /// variables get turned into bound variables and back; and in `Dyn` the 224 /// variables get turned into bound variables and back; and in `Dyn` the
342 /// `Self` type is represented with a bound variable as well. 225 /// `Self` type is represented with a bound variable as well.
343 Bound(BoundVar), 226 BoundVar(BoundVar),
344 227
345 /// A type variable used during type checking. 228 /// A type variable used during type checking.
346 Infer(InferTy), 229 InferenceVar(InferenceVar, TyVariableKind),
347 230
348 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). 231 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
349 /// 232 ///
@@ -424,7 +307,7 @@ impl Substs {
424 generic_params 307 generic_params
425 .iter() 308 .iter()
426 .enumerate() 309 .enumerate()
427 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 310 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
428 .collect(), 311 .collect(),
429 ) 312 )
430 } 313 }
@@ -440,10 +323,6 @@ impl Substs {
440 Substs::builder(generic_params.len()) 323 Substs::builder(generic_params.len())
441 } 324 }
442 325
443 pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
444 Substs::builder(type_ctor.num_ty_params(db))
445 }
446
447 fn builder(param_count: usize) -> SubstsBuilder { 326 fn builder(param_count: usize) -> SubstsBuilder {
448 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 327 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
449 } 328 }
@@ -476,7 +355,7 @@ impl SubstsBuilder {
476 } 355 }
477 356
478 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 357 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self {
479 self.fill((starting_from..).map(|idx| Ty::Bound(BoundVar::new(debruijn, idx)))) 358 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx))))
480 } 359 }
481 360
482 pub fn fill_with_unknown(self) -> Self { 361 pub fn fill_with_unknown(self) -> Self {
@@ -656,41 +535,41 @@ impl TypeWalk for GenericPredicate {
656#[derive(Debug, Clone, PartialEq, Eq, Hash)] 535#[derive(Debug, Clone, PartialEq, Eq, Hash)]
657pub struct Canonical<T> { 536pub struct Canonical<T> {
658 pub value: T, 537 pub value: T,
659 pub kinds: Arc<[TyKind]>, 538 pub kinds: Arc<[TyVariableKind]>,
660} 539}
661 540
662impl<T> Canonical<T> { 541impl<T> Canonical<T> {
663 pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { 542 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
664 Self { value, kinds: kinds.into_iter().collect() } 543 Self { value, kinds: kinds.into_iter().collect() }
665 } 544 }
666} 545}
667 546
668#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
669pub enum TyKind {
670 General,
671 Integer,
672 Float,
673}
674
675/// A function signature as seen by type inference: Several parameter types and 547/// A function signature as seen by type inference: Several parameter types and
676/// one return type. 548/// one return type.
677#[derive(Clone, PartialEq, Eq, Debug)] 549#[derive(Clone, PartialEq, Eq, Debug)]
678pub struct FnSig { 550pub struct CallableSig {
679 params_and_return: Arc<[Ty]>, 551 params_and_return: Arc<[Ty]>,
680 is_varargs: bool, 552 is_varargs: bool,
681} 553}
682 554
683/// A polymorphic function signature. 555/// A polymorphic function signature.
684pub type PolyFnSig = Binders<FnSig>; 556pub type PolyFnSig = Binders<CallableSig>;
685 557
686impl FnSig { 558impl CallableSig {
687 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 559 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
688 params.push(ret); 560 params.push(ret);
689 FnSig { params_and_return: params.into(), is_varargs } 561 CallableSig { params_and_return: params.into(), is_varargs }
562 }
563
564 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
565 CallableSig {
566 params_and_return: Arc::clone(&fn_ptr.substs.0),
567 is_varargs: fn_ptr.sig.variadic,
568 }
690 } 569 }
691 570
692 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 571 pub fn from_substs(substs: &Substs) -> CallableSig {
693 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 572 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
694 } 573 }
695 574
696 pub fn params(&self) -> &[Ty] { 575 pub fn params(&self) -> &[Ty] {
@@ -702,7 +581,7 @@ impl FnSig {
702 } 581 }
703} 582}
704 583
705impl TypeWalk for FnSig { 584impl TypeWalk for CallableSig {
706 fn walk(&self, f: &mut impl FnMut(&Ty)) { 585 fn walk(&self, f: &mut impl FnMut(&Ty)) {
707 for t in self.params_and_return.iter() { 586 for t in self.params_and_return.iter() {
708 t.walk(f); 587 t.walk(f);
@@ -721,49 +600,46 @@ impl TypeWalk for FnSig {
721} 600}
722 601
723impl Ty { 602impl Ty {
724 pub fn simple(ctor: TypeCtor) -> Ty {
725 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
726 }
727 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
728 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
729 }
730 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
731 Ty::Apply(ApplicationTy { ctor, parameters })
732 }
733 pub fn unit() -> Self { 603 pub fn unit() -> Self {
734 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 604 Ty::Tuple(0, Substs::empty())
735 } 605 }
736 pub fn fn_ptr(sig: FnSig) -> Self { 606
737 Ty::apply( 607 pub fn adt_ty(adt: hir_def::AdtId, substs: Substs) -> Ty {
738 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 608 Ty::Adt(AdtId(adt), substs)
739 Substs(sig.params_and_return),
740 )
741 } 609 }
742 pub fn builtin(builtin: BuiltinType) -> Self { 610
743 Ty::simple(match builtin { 611 pub fn fn_ptr(sig: CallableSig) -> Self {
744 BuiltinType::Char => TypeCtor::Char, 612 Ty::Function(FnPointer {
745 BuiltinType::Bool => TypeCtor::Bool, 613 num_args: sig.params().len(),
746 BuiltinType::Str => TypeCtor::Str, 614 sig: FnSig { variadic: sig.is_varargs },
747 BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), 615 substs: Substs(sig.params_and_return),
748 BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()),
749 }) 616 })
750 } 617 }
751 618
619 pub fn builtin(builtin: BuiltinType) -> Self {
620 match builtin {
621 BuiltinType::Char => Ty::Scalar(Scalar::Char),
622 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
623 BuiltinType::Str => Ty::Str,
624 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
625 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
626 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
627 }
628 }
629
752 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 630 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
753 match self { 631 match self {
754 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 632 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
755 Some((parameters.as_single(), *mutability))
756 }
757 _ => None, 633 _ => None,
758 } 634 }
759 } 635 }
760 636
761 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 637 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
762 match self { 638 match self {
763 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 639 Ty::Ref(mutability, parameters) => {
764 Some((parameters.as_single(), Rawness::Ref, *mutability)) 640 Some((parameters.as_single(), Rawness::Ref, *mutability))
765 } 641 }
766 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 642 Ty::Raw(mutability, parameters) => {
767 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 643 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
768 } 644 }
769 _ => None, 645 _ => None,
@@ -773,39 +649,69 @@ impl Ty {
773 pub fn strip_references(&self) -> &Ty { 649 pub fn strip_references(&self) -> &Ty {
774 let mut t: &Ty = self; 650 let mut t: &Ty = self;
775 651
776 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 652 while let Ty::Ref(_mutability, parameters) = t {
777 t = parameters.as_single(); 653 t = parameters.as_single();
778 } 654 }
779 655
780 t 656 t
781 } 657 }
782 658
783 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 659 pub fn as_adt(&self) -> Option<(hir_def::AdtId, &Substs)> {
784 match self { 660 match self {
785 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 661 Ty::Adt(AdtId(adt), parameters) => Some((*adt, parameters)),
786 Some((*adt_def, parameters))
787 }
788 _ => None, 662 _ => None,
789 } 663 }
790 } 664 }
791 665
792 pub fn as_tuple(&self) -> Option<&Substs> { 666 pub fn as_tuple(&self) -> Option<&Substs> {
793 match self { 667 match self {
794 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 668 Ty::Tuple(_, substs) => Some(substs),
795 Some(parameters) 669 _ => None,
796 } 670 }
671 }
672
673 pub fn as_generic_def(&self) -> Option<GenericDefId> {
674 match *self {
675 Ty::Adt(AdtId(adt), ..) => Some(adt.into()),
676 Ty::FnDef(callable, ..) => Some(callable.into()),
677 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
678 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
797 _ => None, 679 _ => None,
798 } 680 }
799 } 681 }
800 682
801 pub fn is_never(&self) -> bool { 683 pub fn is_never(&self) -> bool {
802 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 684 matches!(self, Ty::Never)
803 } 685 }
804 686
805 pub fn is_unknown(&self) -> bool { 687 pub fn is_unknown(&self) -> bool {
806 matches!(self, Ty::Unknown) 688 matches!(self, Ty::Unknown)
807 } 689 }
808 690
691 pub fn equals_ctor(&self, other: &Ty) -> bool {
692 match (self, other) {
693 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
694 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
695 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
696 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
697 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
698 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
699 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
700 expr == expr2 && def == def2
701 }
702 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
703 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
704 (
705 Ty::Function(FnPointer { num_args, sig, .. }),
706 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
707 ) => num_args == num_args2 && sig == sig2,
708 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
709 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
710 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
711 _ => false,
712 }
713 }
714
809 /// If this is a `dyn Trait` type, this returns the `Trait` part. 715 /// If this is a `dyn Trait` type, this returns the `Trait` part.
810 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 716 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
811 match self { 717 match self {
@@ -824,41 +730,30 @@ impl Ty {
824 730
825 fn builtin_deref(&self) -> Option<Ty> { 731 fn builtin_deref(&self) -> Option<Ty> {
826 match self { 732 match self {
827 Ty::Apply(a_ty) => match a_ty.ctor { 733 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
828 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 734 Ty::Raw(.., parameters) => Some(Ty::clone(parameters.as_single())),
829 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
830 _ => None,
831 },
832 _ => None, 735 _ => None,
833 } 736 }
834 } 737 }
835 738
836 pub fn as_fn_def(&self) -> Option<FunctionId> { 739 pub fn as_fn_def(&self) -> Option<FunctionId> {
837 match self { 740 match self {
838 &Ty::Apply(ApplicationTy { 741 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
839 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
840 ..
841 }) => Some(func),
842 _ => None, 742 _ => None,
843 } 743 }
844 } 744 }
845 745
846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 746 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
847 match self { 747 match self {
848 Ty::Apply(a_ty) => match a_ty.ctor { 748 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
849 TypeCtor::FnPtr { is_varargs, .. } => { 749 Ty::FnDef(def, parameters) => {
850 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 750 let sig = db.callable_item_signature(*def);
851 } 751 Some(sig.subst(&parameters))
852 TypeCtor::FnDef(def) => { 752 }
853 let sig = db.callable_item_signature(def); 753 Ty::Closure(.., substs) => {
854 Some(sig.subst(&a_ty.parameters)) 754 let sig_param = &substs[0];
855 } 755 sig_param.callable_sig(db)
856 TypeCtor::Closure { .. } => { 756 }
857 let sig_param = &a_ty.parameters[0];
858 sig_param.callable_sig(db)
859 }
860 _ => None,
861 },
862 _ => None, 757 _ => None,
863 } 758 }
864 } 759 }
@@ -867,28 +762,66 @@ impl Ty {