aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/autoderef.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/expr.rs11
-rw-r--r--crates/hir_ty/src/diagnostics/match_check.rs8
-rw-r--r--crates/hir_ty/src/diagnostics/unsafe_check.rs6
-rw-r--r--crates/hir_ty/src/display.rs206
-rw-r--r--crates/hir_ty/src/infer.rs46
-rw-r--r--crates/hir_ty/src/infer/coerce.rs87
-rw-r--r--crates/hir_ty/src/infer/expr.rs236
-rw-r--r--crates/hir_ty/src/infer/pat.rs34
-rw-r--r--crates/hir_ty/src/infer/unify.rs200
-rw-r--r--crates/hir_ty/src/lib.rs607
-rw-r--r--crates/hir_ty/src/lower.rs88
-rw-r--r--crates/hir_ty/src/method_resolution.rs167
-rw-r--r--crates/hir_ty/src/op.rs50
-rw-r--r--crates/hir_ty/src/primitive.rs160
-rw-r--r--crates/hir_ty/src/tests/simple.rs55
-rw-r--r--crates/hir_ty/src/traits.rs2
-rw-r--r--crates/hir_ty/src/traits/chalk.rs24
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs332
20 files changed, 1048 insertions, 1288 deletions
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index 6ef9d1e7e..d1302d749 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.58", default-features = false } 20chalk-solve = { version = "0.59", default-features = false }
21chalk-ir = "0.58" 21chalk-ir = "0.59"
22chalk-recursive = "0.58" 22chalk-recursive = "0.59"
23la-arena = { version = "0.2.0", path = "../../lib/arena" } 23la-arena = { version = "0.2.0", path = "../../lib/arena" }
24 24
25stdx = { path = "../stdx", version = "0.0.0" } 25stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs
index ece68183e..be1fd1f13 100644
--- a/crates/hir_ty/src/autoderef.rs
+++ b/crates/hir_ty/src/autoderef.rs
@@ -81,7 +81,7 @@ fn deref_by_trait(
81 81
82 // Now do the assoc type projection 82 // Now do the assoc type projection
83 let projection = super::traits::ProjectionPredicate { 83 let projection = super::traits::ProjectionPredicate {
84 ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())), 84 ty: Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())),
85 projection_ty: super::ProjectionTy { associated_ty: target, parameters }, 85 projection_ty: super::ProjectionTy { associated_ty: target, parameters },
86 }; 86 };
87 87
@@ -89,8 +89,10 @@ fn deref_by_trait(
89 89
90 let in_env = InEnvironment { value: obligation, environment: ty.environment }; 90 let in_env = InEnvironment { value: obligation, environment: ty.environment };
91 91
92 let canonical = 92 let canonical = Canonical::new(
93 Canonical::new(in_env, ty.value.kinds.iter().copied().chain(Some(super::TyKind::General))); 93 in_env,
94 ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)),
95 );
94 96
95 let solution = db.trait_solve(krate, canonical)?; 97 let solution = db.trait_solve(krate, canonical)?;
96 98
@@ -112,7 +114,8 @@ fn deref_by_trait(
112 // new variables in that case 114 // new variables in that case
113 115
114 for i in 1..vars.0.kinds.len() { 116 for i in 1..vars.0.kinds.len() {
115 if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) 117 if vars.0.value[i - 1]
118 != Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
116 { 119 {
117 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); 120 warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
118 return None; 121 return None;
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs
index d740b7265..66a88e2b6 100644
--- a/crates/hir_ty/src/diagnostics/expr.rs
+++ b/crates/hir_ty/src/diagnostics/expr.rs
@@ -17,7 +17,7 @@ use crate::{
17 MissingPatFields, RemoveThisSemicolon, 17 MissingPatFields, RemoveThisSemicolon,
18 }, 18 },
19 utils::variant_data, 19 utils::variant_data,
20 ApplicationTy, InferenceResult, Ty, TypeCtor, 20 InferenceResult, Ty,
21}; 21};
22 22
23pub(crate) use hir_def::{ 23pub(crate) use hir_def::{
@@ -381,14 +381,11 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
381 _ => return, 381 _ => return,
382 }; 382 };
383 383
384 let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); 384 let (params, required) = match mismatch.expected {
385 let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); 385 Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_result_enum => {
386
387 let (params, required) = match &mismatch.expected {
388 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => {
389 (parameters, "Ok".to_string()) 386 (parameters, "Ok".to_string())
390 } 387 }
391 Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { 388 Ty::Adt(AdtId::EnumId(enum_id), ref parameters) if enum_id == core_option_enum => {
392 (parameters, "Some".to_string()) 389 (parameters, "Some".to_string())
393 } 390 }
394 _ => return, 391 _ => return,
diff --git a/crates/hir_ty/src/diagnostics/match_check.rs b/crates/hir_ty/src/diagnostics/match_check.rs
index 1c1423fbf..86fee0050 100644
--- a/crates/hir_ty/src/diagnostics/match_check.rs
+++ b/crates/hir_ty/src/diagnostics/match_check.rs
@@ -227,7 +227,7 @@ use hir_def::{
227use la_arena::Idx; 227use la_arena::Idx;
228use smallvec::{smallvec, SmallVec}; 228use smallvec::{smallvec, SmallVec};
229 229
230use crate::{db::HirDatabase, ApplicationTy, InferenceResult, Ty, TypeCtor}; 230use crate::{db::HirDatabase, InferenceResult, Ty};
231 231
232#[derive(Debug, Clone, Copy)] 232#[derive(Debug, Clone, Copy)]
233/// Either a pattern from the source code being analyzed, represented as 233/// Either a pattern from the source code being analyzed, represented as
@@ -627,14 +627,12 @@ pub(super) fn is_useful(
627 // - `!` type 627 // - `!` type
628 // In those cases, no match arm is useful. 628 // In those cases, no match arm is useful.
629 match cx.infer[cx.match_expr].strip_references() { 629 match cx.infer[cx.match_expr].strip_references() {
630 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(AdtId::EnumId(enum_id)), .. }) => { 630 Ty::Adt(AdtId::EnumId(enum_id), ..) => {
631 if cx.db.enum_data(*enum_id).variants.is_empty() { 631 if cx.db.enum_data(*enum_id).variants.is_empty() {
632 return Ok(Usefulness::NotUseful); 632 return Ok(Usefulness::NotUseful);
633 } 633 }
634 } 634 }
635 Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. }) => { 635 Ty::Never => return Ok(Usefulness::NotUseful),
636 return Ok(Usefulness::NotUseful);
637 }
638 _ => (), 636 _ => (),
639 } 637 }
640 638
diff --git a/crates/hir_ty/src/diagnostics/unsafe_check.rs b/crates/hir_ty/src/diagnostics/unsafe_check.rs
index 9c506112d..e77a20fea 100644
--- a/crates/hir_ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir_ty/src/diagnostics/unsafe_check.rs
@@ -11,9 +11,7 @@ use hir_def::{
11}; 11};
12use hir_expand::diagnostics::DiagnosticSink; 12use hir_expand::diagnostics::DiagnosticSink;
13 13
14use crate::{ 14use crate::{db::HirDatabase, diagnostics::MissingUnsafe, InferenceResult, Ty};
15 db::HirDatabase, diagnostics::MissingUnsafe, ApplicationTy, InferenceResult, Ty, TypeCtor,
16};
17 15
18pub(super) struct UnsafeValidator<'a, 'b: 'a> { 16pub(super) struct UnsafeValidator<'a, 'b: 'a> {
19 owner: DefWithBodyId, 17 owner: DefWithBodyId,
@@ -112,7 +110,7 @@ fn walk_unsafe(
112 } 110 }
113 } 111 }
114 Expr::UnaryOp { expr, op: UnaryOp::Deref } => { 112 Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
115 if let Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. }) = &infer[*expr] { 113 if let Ty::Raw(..) = &infer[*expr] {
116 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block }); 114 unsafe_exprs.push(UnsafeExpr { expr: current, inside_unsafe_block });
117 } 115 }
118 } 116 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 271fcbfaf..d4a8b48e6 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,10 +3,12 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate, 6 db::HirDatabase, primitive, utils::generics, AliasTy, CallableDefId, CallableSig,
7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs,
8 TraitRef, Ty,
8}; 9};
9use arrayvec::ArrayVec; 10use arrayvec::ArrayVec;
11use chalk_ir::Mutability;
10use hir_def::{ 12use hir_def::{
11 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, 13 db::DefDatabase, find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId,
12 AssocContainerId, HasModule, Lookup, ModuleId, TraitId, 14 AssocContainerId, HasModule, Lookup, ModuleId, TraitId,
@@ -234,39 +236,79 @@ impl HirDisplay for &Ty {
234 } 236 }
235} 237}
236 238
237impl HirDisplay for ApplicationTy { 239impl HirDisplay for ProjectionTy {
238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 240 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
239 if f.should_truncate() { 241 if f.should_truncate() {
240 return write!(f, "{}", TYPE_HINT_TRUNCATION); 242 return write!(f, "{}", TYPE_HINT_TRUNCATION);
241 } 243 }
242 244
243 match self.ctor { 245 let trait_ = f.db.trait_data(self.trait_(f.db));
244 TypeCtor::Bool => write!(f, "bool")?, 246 let first_parameter = self.parameters[0].into_displayable(
245 TypeCtor::Char => write!(f, "char")?, 247 f.db,
246 TypeCtor::Int(t) => write!(f, "{}", t)?, 248 f.max_size,
247 TypeCtor::Float(t) => write!(f, "{}", t)?, 249 f.omit_verbose_types,
248 TypeCtor::Str => write!(f, "str")?, 250 f.display_target,
249 TypeCtor::Slice => { 251 );
250 let t = self.parameters.as_single(); 252 write!(f, "<{} as {}", first_parameter, trait_.name)?;
253 if self.parameters.len() > 1 {
254 write!(f, "<")?;
255 f.write_joined(&self.parameters[1..], ", ")?;
256 write!(f, ">")?;
257 }
258 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
259 Ok(())
260 }
261}
262
263impl HirDisplay for Ty {
264 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
265 if f.should_truncate() {
266 return write!(f, "{}", TYPE_HINT_TRUNCATION);
267 }
268
269 match self {
270 Ty::Never => write!(f, "!")?,
271 Ty::Str => write!(f, "str")?,
272 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
273 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
274 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
275 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
276 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
277 Ty::Slice(parameters) => {
278 let t = parameters.as_single();
251 write!(f, "[")?; 279 write!(f, "[")?;
252 t.hir_fmt(f)?; 280 t.hir_fmt(f)?;
253 write!(f, "]")?; 281 write!(f, "]")?;
254 } 282 }
255 TypeCtor::Array => { 283 Ty::Array(parameters) => {
256 let t = self.parameters.as_single(); 284 let t = parameters.as_single();
257 write!(f, "[")?; 285 write!(f, "[")?;
258 t.hir_fmt(f)?; 286 t.hir_fmt(f)?;
259 write!(f, "; _]")?; 287 write!(f, "; _]")?;
260 } 288 }
261 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 289 Ty::Raw(m, parameters) | Ty::Ref(m, parameters) => {
262 let t = self.parameters.as_single(); 290 let t = parameters.as_single();
263 let ty_display = 291 let ty_display =
264 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 292 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
265 293
266 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 294 if matches!(self, Ty::Raw(..)) {
267 write!(f, "*{}", m.as_keyword_for_ptr())?; 295 write!(
296 f,
297 "*{}",
298 match m {
299 Mutability::Not => "const ",
300 Mutability::Mut => "mut ",
301 }
302 )?;
268 } else { 303 } else {
269 write!(f, "&{}", m.as_keyword_for_ref())?; 304 write!(
305 f,
306 "&{}",
307 match m {
308 Mutability::Not => "",
309 Mutability::Mut => "mut ",
310 }
311 )?;
270 } 312 }
271 313
272 let datas; 314 let datas;
@@ -274,10 +316,10 @@ impl HirDisplay for ApplicationTy {
274 Ty::Dyn(predicates) if predicates.len() > 1 => { 316 Ty::Dyn(predicates) if predicates.len() > 1 => {
275 Cow::Borrowed(predicates.as_ref()) 317 Cow::Borrowed(predicates.as_ref())
276 } 318 }
277 &Ty::Opaque(OpaqueTy { 319 &Ty::Alias(AliasTy::Opaque(OpaqueTy {
278 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx), 320 opaque_ty_id: OpaqueTyId::ReturnTypeImplTrait(func, idx),
279 ref parameters, 321 ref parameters,
280 }) => { 322 })) => {
281 datas = 323 datas =
282 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 324 f.db.return_type_impl_traits(func).expect("impl trait id without data");
283 let data = (*datas) 325 let data = (*datas)
@@ -304,25 +346,24 @@ impl HirDisplay for ApplicationTy {
304 write!(f, "{}", ty_display)?; 346 write!(f, "{}", ty_display)?;
305 } 347 }
306 } 348 }
307 TypeCtor::Never => write!(f, "!")?, 349 Ty::Tuple(_, substs) => {
308 TypeCtor::Tuple { .. } => { 350 if substs.len() == 1 {
309 let ts = &self.parameters;
310 if ts.len() == 1 {
311 write!(f, "(")?; 351 write!(f, "(")?;
312 ts[0].hir_fmt(f)?; 352 substs[0].hir_fmt(f)?;
313 write!(f, ",)")?; 353 write!(f, ",)")?;
314 } else { 354 } else {
315 write!(f, "(")?; 355 write!(f, "(")?;
316 f.write_joined(&*ts.0, ", ")?; 356 f.write_joined(&*substs.0, ", ")?;
317 write!(f, ")")?; 357 write!(f, ")")?;
318 } 358 }
319 } 359 }
320 TypeCtor::FnPtr { is_varargs, .. } => { 360 Ty::Function(fn_ptr) => {
321 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 361 let sig = CallableSig::from_fn_ptr(fn_ptr);
322 sig.hir_fmt(f)?; 362 sig.hir_fmt(f)?;
323 } 363 }
324 TypeCtor::FnDef(def) => { 364 Ty::FnDef(def, parameters) => {
325 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 365 let def = *def;
366 let sig = f.db.callable_item_signature(def).subst(parameters);
326 match def { 367 match def {
327 CallableDefId::FunctionId(ff) => { 368 CallableDefId::FunctionId(ff) => {
328 write!(f, "fn {}", f.db.function_data(ff).name)? 369 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -332,7 +373,7 @@ impl HirDisplay for ApplicationTy {
332 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 373 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
333 } 374 }
334 }; 375 };
335 if self.parameters.len() > 0 { 376 if parameters.len() > 0 {
336 let generics = generics(f.db.upcast(), def.into()); 377 let generics = generics(f.db.upcast(), def.into());
337 let (parent_params, self_param, type_params, _impl_trait_params) = 378 let (parent_params, self_param, type_params, _impl_trait_params) =
338 generics.provenance_split(); 379 generics.provenance_split();
@@ -340,7 +381,7 @@ impl HirDisplay for ApplicationTy {
340 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 381 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
341 if total_len > 0 { 382 if total_len > 0 {
342 write!(f, "<")?; 383 write!(f, "<")?;
343 f.write_joined(&self.parameters.0[..total_len], ", ")?; 384 f.write_joined(&parameters.0[..total_len], ", ")?;
344 write!(f, ">")?; 385 write!(f, ">")?;
345 } 386 }
346 } 387 }
@@ -359,10 +400,10 @@ impl HirDisplay for ApplicationTy {
359 write!(f, " -> {}", ret_display)?; 400 write!(f, " -> {}", ret_display)?;
360 } 401 }
361 } 402 }
362 TypeCtor::Adt(def_id) => { 403 Ty::Adt(def_id, parameters) => {
363 match f.display_target { 404 match f.display_target {
364 DisplayTarget::Diagnostics | DisplayTarget::Test => { 405 DisplayTarget::Diagnostics | DisplayTarget::Test => {
365 let name = match def_id { 406 let name = match *def_id {
366 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 407 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
367 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 408 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
368 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), 409 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
@@ -372,7 +413,7 @@ impl HirDisplay for ApplicationTy {
372 DisplayTarget::SourceCode { module_id } => { 413 DisplayTarget::SourceCode { module_id } => {
373 if let Some(path) = find_path::find_path( 414 if let Some(path) = find_path::find_path(
374 f.db.upcast(), 415 f.db.upcast(),
375 ItemInNs::Types(def_id.into()), 416 ItemInNs::Types((*def_id).into()),
376 module_id, 417 module_id,
377 ) { 418 ) {
378 write!(f, "{}", path)?; 419 write!(f, "{}", path)?;
@@ -384,19 +425,18 @@ impl HirDisplay for ApplicationTy {
384 } 425 }
385 } 426 }
386 427
387 if self.parameters.len() > 0 { 428 if parameters.len() > 0 {
388 let parameters_to_write = 429 let parameters_to_write =
389 if f.display_target.is_source_code() || f.omit_verbose_types() { 430 if f.display_target.is_source_code() || f.omit_verbose_types() {
390 match self 431 match self
391 .ctor
392 .as_generic_def() 432 .as_generic_def()
393 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 433 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
394 .filter(|defaults| !defaults.is_empty()) 434 .filter(|defaults| !defaults.is_empty())
395 { 435 {
396 None => self.parameters.0.as_ref(), 436 None => parameters.0.as_ref(),
397 Some(default_parameters) => { 437 Some(default_parameters) => {
398 let mut default_from = 0; 438 let mut default_from = 0;
399 for (i, parameter) in self.parameters.iter().enumerate() { 439 for (i, parameter) in parameters.iter().enumerate() {
400 match (parameter, default_parameters.get(i)) { 440 match (parameter, default_parameters.get(i)) {
401 (&Ty::Unknown, _) | (_, None) => { 441 (&Ty::Unknown, _) | (_, None) => {
402 default_from = i + 1; 442 default_from = i + 1;
@@ -404,18 +444,18 @@ impl HirDisplay for ApplicationTy {
404 (_, Some(default_parameter)) => { 444 (_, Some(default_parameter)) => {
405 let actual_default = default_parameter 445 let actual_default = default_parameter
406 .clone() 446 .clone()
407 .subst(&self.parameters.prefix(i)); 447 .subst(&parameters.prefix(i));
408 if parameter != &actual_default { 448 if parameter != &actual_default {
409 default_from = i + 1; 449 default_from = i + 1;
410 } 450 }
411 } 451 }
412 } 452 }
413 } 453 }
414 &self.parameters.0[0..default_from] 454 &parameters.0[0..default_from]
415 } 455 }
416 } 456 }
417 } else { 457 } else {
418 self.parameters.0.as_ref() 458 parameters.0.as_ref()
419 }; 459 };
420 if !parameters_to_write.is_empty() { 460 if !parameters_to_write.is_empty() {
421 write!(f, "<")?; 461 write!(f, "<")?;
@@ -424,61 +464,54 @@ impl HirDisplay for ApplicationTy {
424 } 464 }
425 } 465 }
426 } 466 }
427 TypeCtor::AssociatedType(type_alias) => { 467 Ty::AssociatedType(type_alias, parameters) => {
428 let trait_ = match type_alias.lookup(f.db.upcast()).container { 468 let trait_ = match type_alias.lookup(f.db.upcast()).container {
429 AssocContainerId::TraitId(it) => it, 469 AssocContainerId::TraitId(it) => it,
430 _ => panic!("not an associated type"), 470 _ => panic!("not an associated type"),
431 }; 471 };
432 let trait_ = f.db.trait_data(trait_); 472 let trait_ = f.db.trait_data(trait_);
433 let type_alias_data = f.db.type_alias_data(type_alias); 473 let type_alias_data = f.db.type_alias_data(*type_alias);
434 474
435 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 475 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
436 if f.display_target.is_test() { 476 if f.display_target.is_test() {
437 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 477 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
438 if self.parameters.len() > 0 { 478 if parameters.len() > 0 {
439 write!(f, "<")?; 479 write!(f, "<")?;
440 f.write_joined(&*self.parameters.0, ", ")?; 480 f.write_joined(&*parameters.0, ", ")?;
441 write!(f, ">")?; 481 write!(f, ">")?;
442 } 482 }
443 } else { 483 } else {
444 let projection_ty = ProjectionTy { 484 let projection_ty =
445 associated_ty: type_alias, 485 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
446 parameters: self.parameters.clone(),
447 };
448 486
449 projection_ty.hir_fmt(f)?; 487 projection_ty.hir_fmt(f)?;
450 } 488 }
451 } 489 }
452 TypeCtor::ForeignType(type_alias) => { 490 Ty::ForeignType(type_alias) => {
453 let type_alias = f.db.type_alias_data(type_alias); 491 let type_alias = f.db.type_alias_data(*type_alias);
454 write!(f, "{}", type_alias.name)?; 492 write!(f, "{}", type_alias.name)?;
455 if self.parameters.len() > 0 {
456 write!(f, "<")?;
457 f.write_joined(&*self.parameters.0, ", ")?;
458 write!(f, ">")?;
459 }
460 } 493 }
461 TypeCtor::OpaqueType(opaque_ty_id) => { 494 Ty::OpaqueType(opaque_ty_id, parameters) => {
462 match opaque_ty_id { 495 match opaque_ty_id {
463 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 496 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
464 let datas = 497 let datas =
465 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 498 f.db.return_type_impl_traits(func).expect("impl trait id without data");
466 let data = (*datas) 499 let data = (*datas)
467 .as_ref() 500 .as_ref()
468 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 501 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
469 let bounds = data.subst(&self.parameters); 502 let bounds = data.subst(&parameters);
470 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 503 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
471 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 504 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
472 } 505 }
473 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 506 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
474 write!(f, "impl Future<Output = ")?; 507 write!(f, "impl Future<Output = ")?;
475 self.parameters[0].hir_fmt(f)?; 508 parameters[0].hir_fmt(f)?;
476 write!(f, ">")?; 509 write!(f, ">")?;
477 } 510 }
478 } 511 }
479 } 512 }
480 TypeCtor::Closure { .. } => { 513 Ty::Closure(.., substs) => {
481 let sig = self.parameters[0].callable_sig(f.db); 514 let sig = substs[0].callable_sig(f.db);
482 if let Some(sig) = sig { 515 if let Some(sig) = sig {
483 if sig.params().is_empty() { 516 if sig.params().is_empty() {
484 write!(f, "||")?; 517 write!(f, "||")?;
@@ -501,44 +534,6 @@ impl HirDisplay for ApplicationTy {
501 write!(f, "{{closure}}")?; 534 write!(f, "{{closure}}")?;
502 } 535 }
503 } 536 }
504 }
505 Ok(())
506 }
507}
508
509impl HirDisplay for ProjectionTy {
510 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
511 if f.should_truncate() {
512 return write!(f, "{}", TYPE_HINT_TRUNCATION);
513 }
514
515 let trait_ = f.db.trait_data(self.trait_(f.db));
516 let first_parameter = self.parameters[0].into_displayable(
517 f.db,
518 f.max_size,
519 f.omit_verbose_types,
520 f.display_target,
521 );
522 write!(f, "<{} as {}", first_parameter, trait_.name)?;
523 if self.parameters.len() > 1 {
524 write!(f, "<")?;
525 f.write_joined(&self.parameters[1..], ", ")?;
526 write!(f, ">")?;
527 }
528 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
529 Ok(())
530 }
531}
532
533impl HirDisplay for Ty {
534 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
535 if f.should_truncate() {
536 return write!(f, "{}", TYPE_HINT_TRUNCATION);
537 }
538
539 match self {
540 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
541 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
542 Ty::Placeholder(id) => { 537 Ty::Placeholder(id) => {
543 let generics = generics(f.db.upcast(), id.parent); 538 let generics = generics(f.db.upcast(), id.parent);
544 let param_data = &generics.params.types[id.local_id]; 539 let param_data = &generics.params.types[id.local_id];
@@ -557,11 +552,12 @@ impl HirDisplay for Ty {
557 } 552 }
558 } 553 }
559 } 554 }
560 Ty::Bound(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?, 555 Ty::BoundVar(idx) => write!(f, "?{}.{}", idx.debruijn.depth(), idx.index)?,
561 Ty::Dyn(predicates) => { 556 Ty::Dyn(predicates) => {
562 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?; 557 write_bounds_like_dyn_trait_with_prefix("dyn", predicates, f)?;
563 } 558 }
564 Ty::Opaque(opaque_ty) => { 559 Ty::Alias(AliasTy::Projection(p_ty)) => p_ty.hir_fmt(f)?,
560 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
565 match opaque_ty.opaque_ty_id { 561 match opaque_ty.opaque_ty_id {
566 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 562 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
567 let datas = 563 let datas =
@@ -585,13 +581,13 @@ impl HirDisplay for Ty {
585 } 581 }
586 write!(f, "{{unknown}}")?; 582 write!(f, "{{unknown}}")?;
587 } 583 }
588 Ty::Infer(..) => write!(f, "_")?, 584 Ty::InferenceVar(..) => write!(f, "_")?,
589 } 585 }
590 Ok(()) 586 Ok(())
591 } 587 }
592} 588}
593 589
594impl HirDisplay for FnSig { 590impl HirDisplay for CallableSig {
595 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 591 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
596 write!(f, "fn(")?; 592 write!(f, "fn(")?;
597 f.write_joined(self.params(), ", ")?; 593 f.write_joined(self.params(), ", ")?;
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 4b683c5a7..4d771a91e 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -18,6 +18,7 @@ use std::mem;
18use std::ops::Index; 18use std::ops::Index;
19use std::sync::Arc; 19use std::sync::Arc;
20 20
21use chalk_ir::Mutability;
21use hir_def::{ 22use hir_def::{
22 body::Body, 23 body::Body,
23 data::{ConstData, FunctionData, StaticData}, 24 data::{ConstData, FunctionData, StaticData},
@@ -25,7 +26,7 @@ use hir_def::{
25 lang_item::LangItemTarget, 26 lang_item::LangItemTarget,
26 path::{path, Path}, 27 path::{path, Path},
27 resolver::{HasResolver, Resolver, TypeNs}, 28 resolver::{HasResolver, Resolver, TypeNs},
28 type_ref::{Mutability, TypeRef}, 29 type_ref::TypeRef,
29 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId, 30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, Lookup, TraitId,
30 TypeAliasId, VariantId, 31 TypeAliasId, VariantId,
31}; 32};
@@ -36,25 +37,15 @@ use stdx::impl_from;
36use syntax::SmolStr; 37use syntax::SmolStr;
37 38
38use super::{ 39use super::{
39 primitive::{FloatTy, IntTy},
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, AliasTy,
45}; 45};
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
48 48
49macro_rules! ty_app {
50 ($ctor:pat, $param:pat) => {
51 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
52 };
53 ($ctor:pat) => {
54 ty_app!($ctor, _)
55 };
56}
57
58mod unify; 49mod unify;
59mod path; 50mod path;
60mod expr; 51mod expr;
@@ -97,7 +88,7 @@ impl BindingMode {
97 fn convert(annotation: BindingAnnotation) -> BindingMode { 88 fn convert(annotation: BindingAnnotation) -> BindingMode {
98 match annotation { 89 match annotation {
99 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move, 90 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
100 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Shared), 91 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
101 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut), 92 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
102 } 93 }
103 } 94 }
@@ -405,7 +396,7 @@ impl<'a> InferenceContext<'a> {
405 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty { 396 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
406 let ty = self.resolve_ty_as_possible(ty); 397 let ty = self.resolve_ty_as_possible(ty);
407 ty.fold(&mut |ty| match ty { 398 ty.fold(&mut |ty| match ty {
408 Ty::Projection(proj_ty) => self.normalize_projection_ty(proj_ty), 399 Ty::Alias(AliasTy::Projection(proj_ty)) => self.normalize_projection_ty(proj_ty),
409 _ => ty, 400 _ => ty,
410 }) 401 })
411 } 402 }
@@ -664,30 +655,17 @@ impl<'a> InferenceContext<'a> {
664/// two are used for inference of literal values (e.g. `100` could be one of 655/// two are used for inference of literal values (e.g. `100` could be one of
665/// several integer types). 656/// several integer types).
666#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] 657#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
667pub enum InferTy { 658pub struct InferenceVar {
668 TypeVar(unify::TypeVarId), 659 index: u32,
669 IntVar(unify::TypeVarId),
670 FloatVar(unify::TypeVarId),
671 MaybeNeverTypeVar(unify::TypeVarId),
672} 660}
673 661
674impl InferTy { 662impl InferenceVar {
675 fn to_inner(self) -> unify::TypeVarId { 663 fn to_inner(self) -> unify::TypeVarId {
676 match self { 664 unify::TypeVarId(self.index)
677 InferTy::TypeVar(ty)
678 | InferTy::IntVar(ty)
679 | InferTy::FloatVar(ty)
680 | InferTy::MaybeNeverTypeVar(ty) => ty,
681 }
682 } 665 }
683 666
684 fn fallback_value(self) -> Ty { 667 fn from_inner(unify::TypeVarId(index): unify::TypeVarId) -> Self {
685 match self { 668 InferenceVar { index }
686 InferTy::TypeVar(..) => Ty::Unknown,
687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Int(IntTy::i32())),
688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Float(FloatTy::f64())),
689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never),
690 }
691 } 669 }
692} 670}
693 671
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..cf0a3add4 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -4,12 +4,13 @@
4//! 4//!
5//! See: https://doc.rust-lang.org/nomicon/coercions.html 5//! See: https://doc.rust-lang.org/nomicon/coercions.html
6 6
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use chalk_ir::{Mutability, TyVariableKind};
8use hir_def::lang_item::LangItemTarget;
8use test_utils::mark; 9use test_utils::mark;
9 10
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 11use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 12
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 13use super::{InEnvironment, InferenceContext};
13 14
14impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
15 /// Unify two types, but may coerce the first one to the second one 16 /// Unify two types, but may coerce the first one to the second one
@@ -33,7 +34,7 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 34 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 35 ty1.clone()
35 } else { 36 } else {
36 if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 37 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 38 mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 39 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 40 // pointers to have a chance at getting a match. See
@@ -53,12 +54,11 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 54 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 55 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 56 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 57 (Ty::Never, Ty::InferenceVar(tv, TyVariableKind::General)) => {
57 let var = self.table.new_maybe_never_type_var(); 58 self.table.type_variable_table.set_diverging(*tv, true);
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var));
59 return true; 59 return true;
60 } 60 }
61 (ty_app!(TypeCtor::Never), _) => return true, 61 (Ty::Never, _) => return true,
62 62
63 // Trivial cases, this should go after `never` check to 63 // Trivial cases, this should go after `never` check to
64 // avoid infer result type to be never 64 // avoid infer result type to be never
@@ -71,38 +71,33 @@ impl<'a> InferenceContext<'a> {
71 71
72 // Pointer weakening and function to pointer 72 // Pointer weakening and function to pointer
73 match (&mut from_ty, to_ty) { 73 match (&mut from_ty, to_ty) {
74 // `*mut T`, `&mut T, `&T`` -> `*const T` 74 // `*mut T` -> `*const T`
75 // `&mut T` -> `&T` 75 // `&mut T` -> `&T`
76 // `&mut T` -> `*mut T` 76 (Ty::Raw(m1, ..), Ty::Raw(m2 @ Mutability::Not, ..))
77 (ty_app!(c1@TypeCtor::RawPtr(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 77 | (Ty::Ref(m1, ..), Ty::Ref(m2 @ Mutability::Not, ..)) => {
78 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::RawPtr(Mutability::Shared))) 78 *m1 = *m2;
79 | (ty_app!(c1@TypeCtor::Ref(_)), ty_app!(c2@TypeCtor::Ref(Mutability::Shared))) 79 }
80 | (ty_app!(c1@TypeCtor::Ref(Mutability::Mut)), ty_app!(c2@TypeCtor::RawPtr(_))) => { 80 // `&T` -> `*const T`
81 *c1 = *c2; 81 // `&mut T` -> `*mut T`/`*const T`
82 (Ty::Ref(.., substs), &Ty::Raw(m2 @ Mutability::Not, ..))
83 | (Ty::Ref(Mutability::Mut, substs), &Ty::Raw(m2, ..)) => {
84 from_ty = Ty::Raw(m2, substs.clone());
82 } 85 }
83 86
84 // Illegal mutablity conversion 87 // Illegal mutability conversion
85 ( 88 (Ty::Raw(Mutability::Not, ..), Ty::Raw(Mutability::Mut, ..))
86 ty_app!(TypeCtor::RawPtr(Mutability::Shared)), 89 | (Ty::Ref(Mutability::Not, ..), Ty::Ref(Mutability::Mut, ..)) => return false,
87 ty_app!(TypeCtor::RawPtr(Mutability::Mut)),
88 )
89 | (
90 ty_app!(TypeCtor::Ref(Mutability::Shared)),
91 ty_app!(TypeCtor::Ref(Mutability::Mut)),
92 ) => return false,
93 90
94 // `{function_type}` -> `fn()` 91 // `{function_type}` -> `fn()`
95 (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnPtr { .. })) => { 92 (Ty::FnDef(..), Ty::Function { .. }) => match from_ty.callable_sig(self.db) {
96 match from_ty.callable_sig(self.db) { 93 None => return false,
97 None => return false, 94 Some(sig) => {
98 Some(sig) => { 95 from_ty = Ty::fn_ptr(sig);
99 from_ty = Ty::fn_ptr(sig);
100 }
101 } 96 }
102 } 97 },
103 98
104 (ty_app!(TypeCtor::Closure { .. }, params), ty_app!(TypeCtor::FnPtr { .. })) => { 99 (Ty::Closure(.., substs), Ty::Function { .. }) => {
105 from_ty = params[0].clone(); 100 from_ty = substs[0].clone();
106 } 101 }
107 102
108 _ => {} 103 _ => {}
@@ -115,9 +110,7 @@ impl<'a> InferenceContext<'a> {
115 // Auto Deref if cannot coerce 110 // Auto Deref if cannot coerce
116 match (&from_ty, to_ty) { 111 match (&from_ty, to_ty) {
117 // FIXME: DerefMut 112 // FIXME: DerefMut
118 (ty_app!(TypeCtor::Ref(_), st1), ty_app!(TypeCtor::Ref(_), st2)) => { 113 (Ty::Ref(_, st1), Ty::Ref(_, st2)) => self.unify_autoderef_behind_ref(&st1[0], &st2[0]),
119 self.unify_autoderef_behind_ref(&st1[0], &st2[0])
120 }
121 114
122 // Otherwise, normal unify 115 // Otherwise, normal unify
123 _ => self.unify(&from_ty, to_ty), 116 _ => self.unify(&from_ty, to_ty),
@@ -178,17 +171,17 @@ impl<'a> InferenceContext<'a> {
178 }, 171 },
179 ) { 172 ) {
180 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value); 173 let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
181 match (&*self.resolve_ty_shallow(&derefed_ty), &*to_ty) { 174 let from_ty = self.resolve_ty_shallow(&derefed_ty);
182 // Stop when constructor matches. 175 // Stop when constructor matches.
183 (ty_app!(from_ctor, st1), ty_app!(to_ctor, st2)) if from_ctor == to_ctor => { 176 if from_ty.equals_ctor(&to_ty) {
184 // It will not recurse to `coerce`. 177 // It will not recurse to `coerce`.
185 return self.table.unify_substs(st1, st2, 0); 178 return match (from_ty.substs(), to_ty.substs()) {
186 } 179 (Some(st1), Some(st2)) => self.table.unify_substs(st1, st2, 0),
187 _ => { 180 (None, None) => true,
188 if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) { 181 _ => false,
189 return true; 182 };
190 } 183 } else if self.table.unify_inner_trivial(&derefed_ty, &to_ty, 0) {
191 } 184 return true;
192 } 185 }
193 } 186 }
194 187
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index cb59a6937..cf1f1038a 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,8 +3,8 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind};
6use hir_def::{ 7use hir_def::{
7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
@@ -15,11 +15,14 @@ use syntax::ast::RangeOp;
15use test_utils::mark; 15use test_utils::mark;
16 16
17use crate::{ 17use crate::{
18 autoderef, method_resolution, op, 18 autoderef,
19 lower::lower_to_chalk_mutability,
20 method_resolution, op,
21 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 22 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 24 Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 25 TraitRef, Ty,
23}; 26};
24 27
25use super::{ 28use super::{
@@ -82,10 +85,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 85 arg_tys.push(arg);
83 } 86 }
84 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 88 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 89 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 120 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 121 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 122 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 123 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 124
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 126 let mut both_arms_diverge = Diverges::Always;
@@ -175,7 +175,7 @@ impl<'a> InferenceContext<'a> {
175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
176 let inner_ty = self.infer_expr(*body, &Expectation::none()); 176 let inner_ty = self.infer_expr(*body, &Expectation::none());
177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
178 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 178 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
179 } 179 }
180 Expr::Loop { body, label } => { 180 Expr::Loop { body, label } => {
181 self.breakables.push(BreakableContext { 181 self.breakables.push(BreakableContext {
@@ -193,7 +193,7 @@ impl<'a> InferenceContext<'a> {
193 if ctxt.may_break { 193 if ctxt.may_break {
194 ctxt.break_ty 194 ctxt.break_ty
195 } else { 195 } else {
196 Ty::simple(TypeCtor::Never) 196 Ty::Never
197 } 197 }
198 } 198 }
199 Expr::While { condition, body, label } => { 199 Expr::While { condition, body, label } => {
@@ -203,7 +203,7 @@ impl<'a> InferenceContext<'a> {
203 label: label.map(|label| self.body[label].name.clone()), 203 label: label.map(|label| self.body[label].name.clone()),
204 }); 204 });
205 // while let is desugared to a match loop, so this is always simple while 205 // while let is desugared to a match loop, so this is always simple while
206 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 206 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
207 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 207 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
208 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 208 let _ctxt = self.breakables.pop().expect("breakable stack broken");
209 // the body may not run, so it diverging doesn't mean we diverge 209 // the body may not run, so it diverging doesn't mean we diverge
@@ -250,12 +250,12 @@ impl<'a> InferenceContext<'a> {
250 None => self.table.new_type_var(), 250 None => self.table.new_type_var(),
251 }; 251 };
252 sig_tys.push(ret_ty.clone()); 252 sig_tys.push(ret_ty.clone());
253 let sig_ty = Ty::apply( 253 let sig_ty = Ty::Function(FnPointer {
254 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 254 num_args: sig_tys.len() - 1,
255 Substs(sig_tys.clone().into()), 255 sig: FnSig { variadic: false },
256 ); 256 substs: Substs(sig_tys.clone().into()),
257 let closure_ty = 257 });
258 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 258 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
259 259
260 // Eagerly try to relate the closure type with the expected 260 // Eagerly try to relate the closure type with the expected
261 // type, otherwise we often won't have enough information to 261 // type, otherwise we often won't have enough information to
@@ -306,11 +306,8 @@ impl<'a> InferenceContext<'a> {
306 Expr::Match { expr, arms } => { 306 Expr::Match { expr, arms } => {
307 let input_ty = self.infer_expr(*expr, &Expectation::none()); 307 let input_ty = self.infer_expr(*expr, &Expectation::none());
308 308
309 let mut result_ty = if arms.is_empty() { 309 let mut result_ty =
310 Ty::simple(TypeCtor::Never) 310 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
311 } else {
312 self.table.new_type_var()
313 };
314 311
315 let matchee_diverges = self.diverges; 312 let matchee_diverges = self.diverges;
316 let mut all_arms_diverge = Diverges::Always; 313 let mut all_arms_diverge = Diverges::Always;
@@ -321,7 +318,7 @@ impl<'a> InferenceContext<'a> {
321 if let Some(guard_expr) = arm.guard { 318 if let Some(guard_expr) = arm.guard {
322 self.infer_expr( 319 self.infer_expr(
323 guard_expr, 320 guard_expr,
324 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 321 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
325 ); 322 );
326 } 323 }
327 324
@@ -339,7 +336,7 @@ impl<'a> InferenceContext<'a> {
339 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 336 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
340 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 337 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
341 } 338 }
342 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 339 Expr::Continue { .. } => Ty::Never,
343 Expr::Break { expr, label } => { 340 Expr::Break { expr, label } => {
344 let val_ty = if let Some(expr) = expr { 341 let val_ty = if let Some(expr) = expr {
345 self.infer_expr(*expr, &Expectation::none()) 342 self.infer_expr(*expr, &Expectation::none())
@@ -364,8 +361,7 @@ impl<'a> InferenceContext<'a> {
364 expr: tgt_expr, 361 expr: tgt_expr,
365 }); 362 });
366 } 363 }
367 364 Ty::Never
368 Ty::simple(TypeCtor::Never)
369 } 365 }
370 Expr::Return { expr } => { 366 Expr::Return { expr } => {
371 if let Some(expr) = expr { 367 if let Some(expr) = expr {
@@ -374,14 +370,14 @@ impl<'a> InferenceContext<'a> {
374 let unit = Ty::unit(); 370 let unit = Ty::unit();
375 self.coerce(&unit, &self.return_ty.clone()); 371 self.coerce(&unit, &self.return_ty.clone());
376 } 372 }
377 Ty::simple(TypeCtor::Never) 373 Ty::Never
378 } 374 }
379 Expr::Yield { expr } => { 375 Expr::Yield { expr } => {
380 // FIXME: track yield type for coercion 376 // FIXME: track yield type for coercion
381 if let Some(expr) = expr { 377 if let Some(expr) = expr {
382 self.infer_expr(*expr, &Expectation::none()); 378 self.infer_expr(*expr, &Expectation::none());
383 } 379 }
384 Ty::simple(TypeCtor::Never) 380 Ty::Never
385 } 381 }
386 Expr::RecordLit { path, fields, spread } => { 382 Expr::RecordLit { path, fields, spread } => {
387 let (ty, def_id) = self.resolve_variant(path.as_ref()); 383 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -391,7 +387,7 @@ impl<'a> InferenceContext<'a> {
391 387
392 self.unify(&ty, &expected.ty); 388 self.unify(&ty, &expected.ty);
393 389
394 let substs = ty.substs().unwrap_or_else(Substs::empty); 390 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
395 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 391 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
396 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 392 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
397 for (field_idx, field) in fields.iter().enumerate() { 393 for (field_idx, field) in fields.iter().enumerate() {
@@ -430,30 +426,23 @@ impl<'a> InferenceContext<'a> {
430 }, 426 },
431 ) 427 )
432 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 428 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
433 Ty::Apply(a_ty) => match a_ty.ctor { 429 Ty::Tuple(_, substs) => {
434 TypeCtor::Tuple { .. } => name 430 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
435 .as_tuple_index() 431 }
436 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 432 Ty::Adt(AdtId::StructId(s), parameters) => {
437 TypeCtor::Adt(AdtId::StructId(s)) => { 433 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
438 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 434 let field = FieldId { parent: s.into(), local_id };
439 let field = FieldId { parent: s.into(), local_id }; 435 self.write_field_resolution(tgt_expr, field);
440 self.write_field_resolution(tgt_expr, field); 436 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
441 self.db.field_types(s.into())[field.local_id] 437 })
442 .clone() 438 }
443 .subst(&a_ty.parameters) 439 Ty::Adt(AdtId::UnionId(u), parameters) => {
444 }) 440 self.db.union_data(u).variant_data.field(name).map(|local_id| {
445 } 441 let field = FieldId { parent: u.into(), local_id };
446 TypeCtor::Adt(AdtId::UnionId(u)) => { 442 self.write_field_resolution(tgt_expr, field);
447 self.db.union_data(u).variant_data.field(name).map(|local_id| { 443 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
448 let field = FieldId { parent: u.into(), local_id }; 444 })
449 self.write_field_resolution(tgt_expr, field); 445 }
450 self.db.field_types(u.into())[field.local_id]
451 .clone()
452 .subst(&a_ty.parameters)
453 })
454 }
455 _ => None,
456 },
457 _ => None, 446 _ => None,
458 }) 447 })
459 .unwrap_or(Ty::Unknown); 448 .unwrap_or(Ty::Unknown);
@@ -475,10 +464,11 @@ impl<'a> InferenceContext<'a> {
475 cast_ty 464 cast_ty
476 } 465 }
477 Expr::Ref { expr, rawness, mutability } => { 466 Expr::Ref { expr, rawness, mutability } => {
467 let mutability = lower_to_chalk_mutability(*mutability);
478 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 468 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
479 &expected.ty.as_reference_or_ptr() 469 &expected.ty.as_reference_or_ptr()
480 { 470 {
481 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 471 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not {
482 // FIXME: throw type error - expected mut reference but found shared ref, 472 // FIXME: throw type error - expected mut reference but found shared ref,
483 // which cannot be coerced 473 // which cannot be coerced
484 } 474 }
@@ -491,19 +481,24 @@ impl<'a> InferenceContext<'a> {
491 Expectation::none() 481 Expectation::none()
492 }; 482 };
493 let inner_ty = self.infer_expr_inner(*expr, &expectation); 483 let inner_ty = self.infer_expr_inner(*expr, &expectation);
494 let ty = match rawness { 484 match rawness {
495 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 485 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)),
496 Rawness::Ref => TypeCtor::Ref(*mutability), 486 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)),
497 }; 487 }
498 Ty::apply_one(ty, inner_ty)
499 } 488 }
500 Expr::Box { expr } => { 489 Expr::Box { expr } => {
501 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 490 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
502 if let Some(box_) = self.resolve_boxed_box() { 491 if let Some(box_) = self.resolve_boxed_box() {
503 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 492 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
504 sb = sb.push(inner_ty); 493 sb = sb.push(inner_ty);
494 match self.db.generic_defaults(box_.into()).as_ref() {
495 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
496 sb = sb.push(alloc_ty.value.clone());
497 }
498 _ => (),
499 }
505 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 500 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
506 Ty::apply(TypeCtor::Adt(box_), sb.build()) 501 Ty::Adt(box_, sb.build())
507 } else { 502 } else {
508 Ty::Unknown 503 Ty::Unknown
509 } 504 }
@@ -533,13 +528,11 @@ impl<'a> InferenceContext<'a> {
533 UnaryOp::Neg => { 528 UnaryOp::Neg => {
534 match &inner_ty { 529 match &inner_ty {
535 // Fast path for builtins 530 // Fast path for builtins
536 Ty::Apply(ApplicationTy { 531 Ty::Scalar(Scalar::Int(_))
537 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 532 | Ty::Scalar(Scalar::Uint(_))
538 .. 533 | Ty::Scalar(Scalar::Float(_))
539 }) 534 | Ty::InferenceVar(_, TyVariableKind::Integer)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 535 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty,
541 | Ty::Infer(InferTy::IntVar(..))
542 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
543 // Otherwise we resolve via the std::ops::Neg trait 536 // Otherwise we resolve via the std::ops::Neg trait
544 _ => self 537 _ => self
545 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 538 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -548,9 +541,10 @@ impl<'a> InferenceContext<'a> {
548 UnaryOp::Not => { 541 UnaryOp::Not => {
549 match &inner_ty { 542 match &inner_ty {
550 // Fast path for builtins 543 // Fast path for builtins
551 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 544 Ty::Scalar(Scalar::Bool)
552 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 545 | Ty::Scalar(Scalar::Int(_))
553 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 546 | Ty::Scalar(Scalar::Uint(_))
547 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
554 // Otherwise we resolve via the std::ops::Not trait 548 // Otherwise we resolve via the std::ops::Not trait
555 _ => self 549 _ => self
556 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 550 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -561,7 +555,7 @@ impl<'a> InferenceContext<'a> {
561 Expr::BinaryOp { lhs, rhs, op } => match op { 555 Expr::BinaryOp { lhs, rhs, op } => match op {
562 Some(op) => { 556 Some(op) => {
563 let lhs_expectation = match op { 557 let lhs_expectation = match op {
564 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 558 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
565 _ => Expectation::none(), 559 _ => Expectation::none(),
566 }; 560 };
567 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 561 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -592,31 +586,31 @@ impl<'a> InferenceContext<'a> {
592 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 586 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
593 match (range_type, lhs_ty, rhs_ty) { 587 match (range_type, lhs_ty, rhs_ty) {
594 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 588 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
595 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 589 Some(adt) => Ty::Adt(adt, Substs::empty()),
596 None => Ty::Unknown, 590 None => Ty::Unknown,
597 }, 591 },
598 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 592 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
599 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 593 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
600 None => Ty::Unknown, 594 None => Ty::Unknown,
601 }, 595 },
602 (RangeOp::Inclusive, None, Some(ty)) => { 596 (RangeOp::Inclusive, None, Some(ty)) => {
603 match self.resolve_range_to_inclusive() { 597 match self.resolve_range_to_inclusive() {
604 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 598 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
605 None => Ty::Unknown, 599 None => Ty::Unknown,
606 } 600 }
607 } 601 }
608 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 602 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
609 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 603 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
610 None => Ty::Unknown, 604 None => Ty::Unknown,
611 }, 605 },
612 (RangeOp::Inclusive, Some(_), Some(ty)) => { 606 (RangeOp::Inclusive, Some(_), Some(ty)) => {
613 match self.resolve_range_inclusive() { 607 match self.resolve_range_inclusive() {
614 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 608 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
615 None => Ty::Unknown, 609 None => Ty::Unknown,
616 } 610 }
617 } 611 }
618 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 612 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
619 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 613 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
620 None => Ty::Unknown, 614 None => Ty::Unknown,
621 }, 615 },
622 (RangeOp::Inclusive, _, None) => Ty::Unknown, 616 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -650,7 +644,7 @@ impl<'a> InferenceContext<'a> {
650 } 644 }
651 Expr::Tuple { exprs } => { 645 Expr::Tuple { exprs } => {
652 let mut tys = match &expected.ty { 646 let mut tys = match &expected.ty {
653 ty_app!(TypeCtor::Tuple { .. }, st) => st 647 Ty::Tuple(_, substs) => substs
654 .iter() 648 .iter()
655 .cloned() 649 .cloned()
656 .chain(repeat_with(|| self.table.new_type_var())) 650 .chain(repeat_with(|| self.table.new_type_var()))
@@ -663,15 +657,11 @@ impl<'a> InferenceContext<'a> {
663 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 657 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
664 } 658 }
665 659
666 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 660 Ty::Tuple(tys.len(), Substs(tys.into()))
667 } 661 }
668 Expr::Array(array) => { 662 Expr::Array(array) => {
669 let elem_ty = match &expected.ty { 663 let elem_ty = match &expected.ty {
670 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 664 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
671 #[allow(unreachable_patterns)]
672 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
673 st.as_single().clone()
674 }
675 _ => self.table.new_type_var(), 665 _ => self.table.new_type_var(),
676 }; 666 };
677 667
@@ -688,30 +678,38 @@ impl<'a> InferenceContext<'a> {
688 ); 678 );
689 self.infer_expr( 679 self.infer_expr(
690 *repeat, 680 *repeat,
691 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 681 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
692 ); 682 );
693 } 683 }
694 } 684 }
695 685
696 Ty::apply_one(TypeCtor::Array, elem_ty) 686 Ty::Array(Substs::single(elem_ty))
697 } 687 }
698 Expr::Literal(lit) => match lit { 688 Expr::Literal(lit) => match lit {
699 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 689 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
700 Literal::String(..) => { 690 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(..) => { 691 Literal::ByteString(..) => {
704 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 692 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
705 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 693 let array_type = Ty::Array(Substs::single(byte_type));
706 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 694 Ty::Ref(Mutability::Not, Substs::single(array_type))
707 } 695 }
708 Literal::Char(..) => Ty::simple(TypeCtor::Char), 696 Literal::Char(..) => Ty::Scalar(Scalar::Char),
709 Literal::Int(_v, ty) => match ty { 697 Literal::Int(_v, ty) => match ty {
710 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 698 Some(int_ty) => {
699 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
700 }
701 None => self.table.new_integer_var(),
702 },
703 Literal::Uint(_v, ty) => match ty {
704 Some(int_ty) => {
705 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
706 }
711 None => self.table.new_integer_var(), 707 None => self.table.new_integer_var(),
712 }, 708 },
713 Literal::Float(_v, ty) => match ty { 709 Literal::Float(_v, ty) => match ty {
714 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 710 Some(float_ty) => {
711 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
712 }
715 None => self.table.new_float_var(), 713 None => self.table.new_float_var(),
716 }, 714 },
717 }, 715 },
@@ -767,7 +765,7 @@ impl<'a> InferenceContext<'a> {
767 // `!`). 765 // `!`).
768 if self.diverges.is_always() { 766 if self.diverges.is_always() {
769 // we don't even make an attempt at coercion 767 // we don't even make an attempt at coercion
770 self.table.new_maybe_never_type_var() 768 self.table.new_maybe_never_var()
771 } else { 769 } else {
772 self.coerce(&Ty::unit(), expected.coercion_target()); 770 self.coerce(&Ty::unit(), expected.coercion_target());
773 Ty::unit() 771 Ty::unit()
@@ -824,7 +822,7 @@ impl<'a> InferenceContext<'a> {
824 // Apply autoref so the below unification works correctly 822 // Apply autoref so the below unification works correctly
825 // FIXME: return correct autorefs from lookup_method 823 // FIXME: return correct autorefs from lookup_method
826 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 824 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
827 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 825 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
828 _ => derefed_receiver_ty, 826 _ => derefed_receiver_ty,
829 }; 827 };
830 self.unify(&expected_receiver_ty, &actual_receiver_ty); 828 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -901,30 +899,26 @@ impl<'a> InferenceContext<'a> {
901 } 899 }
902 900
903 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 901 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
904 if let Ty::Apply(a_ty) = callable_ty { 902 if let &Ty::FnDef(def, ref parameters) = callable_ty {
905 if let TypeCtor::FnDef(def) = a_ty.ctor { 903 let generic_predicates = self.db.generic_predicates(def.into());
906 let generic_predicates = self.db.generic_predicates(def.into()); 904 for predicate in generic_predicates.iter() {
907 for predicate in generic_predicates.iter() { 905 let predicate = predicate.clone().subst(parameters);
908 let predicate = predicate.clone().subst(&a_ty.parameters); 906 if let Some(obligation) = Obligation::from_predicate(predicate) {
909 if let Some(obligation) = Obligation::from_predicate(predicate) { 907 self.obligations.push(obligation);
910 self.obligations.push(obligation);
911 }
912 } 908 }
913 // add obligation for trait implementation, if this is a trait method 909 }
914 match def { 910 // add obligation for trait implementation, if this is a trait method
915 CallableDefId::FunctionId(f) => { 911 match def {
916 if let AssocContainerId::TraitId(trait_) = 912 CallableDefId::FunctionId(f) => {
917 f.lookup(self.db.upcast()).container 913 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
918 { 914 {
919 // construct a TraitDef 915 // construct a TraitDef
920 let substs = a_ty 916 let substs =
921 .parameters 917 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
922 .prefix(generics(self.db.upcast(), trait_.into()).len()); 918 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
923 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
924 }
925 } 919 }
926 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
927 } 920 }
921 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
928 } 922 }
929 } 923 }
930 } 924 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..eb099311c 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -3,17 +3,17 @@
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; 13use test_utils::mark;
14 14
15use super::{BindingMode, Expectation, InferenceContext}; 15use super::{BindingMode, Expectation, InferenceContext};
16use crate::{utils::variant_data, Substs, Ty, TypeCtor}; 16use crate::{lower::lower_to_chalk_mutability, utils::variant_data, Substs, Ty};
17 17
18impl<'a> InferenceContext<'a> { 18impl<'a> InferenceContext<'a> {
19 fn infer_tuple_struct_pat( 19 fn infer_tuple_struct_pat(
@@ -32,7 +32,7 @@ impl<'a> InferenceContext<'a> {
32 } 32 }
33 self.unify(&ty, expected); 33 self.unify(&ty, expected);
34 34
35 let substs = ty.substs().unwrap_or_else(Substs::empty); 35 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
36 36
37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 37 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
38 let (pre, post) = match ellipsis { 38 let (pre, post) = match ellipsis {
@@ -71,7 +71,7 @@ impl<'a> InferenceContext<'a> {
71 71
72 self.unify(&ty, expected); 72 self.unify(&ty, expected);
73 73
74 let substs = ty.substs().unwrap_or_else(Substs::empty); 74 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
75 75
76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); 76 let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default();
77 for subpat in subpats { 77 for subpat in subpats {
@@ -103,7 +103,7 @@ impl<'a> InferenceContext<'a> {
103 expected = inner; 103 expected = inner;
104 default_bm = match default_bm { 104 default_bm = match default_bm {
105 BindingMode::Move => BindingMode::Ref(mutability), 105 BindingMode::Move => BindingMode::Ref(mutability),
106 BindingMode::Ref(Mutability::Shared) => BindingMode::Ref(Mutability::Shared), 106 BindingMode::Ref(Mutability::Not) => BindingMode::Ref(Mutability::Not),
107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability), 107 BindingMode::Ref(Mutability::Mut) => BindingMode::Ref(mutability),
108 } 108 }
109 } 109 }
@@ -138,10 +138,7 @@ impl<'a> InferenceContext<'a> {
138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned()); 138 inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat)); 139 inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
140 140
141 Ty::apply( 141 Ty::Tuple(inner_tys.len(), Substs(inner_tys.into()))
142 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
143 Substs(inner_tys.into()),
144 )
145 } 142 }
146 Pat::Or(ref pats) => { 143 Pat::Or(ref pats) => {
147 if let Some((first_pat, rest)) = pats.split_first() { 144 if let Some((first_pat, rest)) = pats.split_first() {
@@ -155,9 +152,10 @@ impl<'a> InferenceContext<'a> {
155 } 152 }
156 } 153 }
157 Pat::Ref { pat, mutability } => { 154 Pat::Ref { pat, mutability } => {
155 let mutability = lower_to_chalk_mutability(*mutability);
158 let expectation = match expected.as_reference() { 156 let expectation = match expected.as_reference() {
159 Some((inner_ty, exp_mut)) => { 157 Some((inner_ty, exp_mut)) => {
160 if *mutability != exp_mut { 158 if mutability != exp_mut {
161 // FIXME: emit type error? 159 // FIXME: emit type error?
162 } 160 }
163 inner_ty 161 inner_ty
@@ -165,7 +163,7 @@ impl<'a> InferenceContext<'a> {
165 _ => &Ty::Unknown, 163 _ => &Ty::Unknown,
166 }; 164 };
167 let subty = self.infer_pat(*pat, expectation, default_bm); 165 let subty = self.infer_pat(*pat, expectation, default_bm);
168 Ty::apply_one(TypeCtor::Ref(*mutability), subty) 166 Ty::Ref(mutability, Substs::single(subty))
169 } 167 }
170 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat( 168 Pat::TupleStruct { path: p, args: subpats, ellipsis } => self.infer_tuple_struct_pat(
171 p.as_ref(), 169 p.as_ref(),
@@ -198,7 +196,7 @@ impl<'a> InferenceContext<'a> {
198 196
199 let bound_ty = match mode { 197 let bound_ty = match mode {
200 BindingMode::Ref(mutability) => { 198 BindingMode::Ref(mutability) => {
201 Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) 199 Ty::Ref(mutability, Substs::single(inner_ty.clone()))
202 } 200 }
203 BindingMode::Move => inner_ty.clone(), 201 BindingMode::Move => inner_ty.clone(),
204 }; 202 };
@@ -207,17 +205,17 @@ impl<'a> InferenceContext<'a> {
207 return inner_ty; 205 return inner_ty;
208 } 206 }
209 Pat::Slice { prefix, slice, suffix } => { 207 Pat::Slice { prefix, slice, suffix } => {
210 let (container_ty, elem_ty) = match &expected { 208 let (container_ty, elem_ty): (fn(_) -> _, _) = match &expected {
211 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), 209 Ty::Array(st) => (Ty::Array, st.as_single().clone()),
212 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), 210 Ty::Slice(st) => (Ty::Slice, st.as_single().clone()),
213 _ => (TypeCtor::Slice, Ty::Unknown), 211 _ => (Ty::Slice, Ty::Unknown),
214 }; 212 };
215 213
216 for pat_id in prefix.iter().chain(suffix) { 214 for pat_id in prefix.iter().chain(suffix) {
217 self.infer_pat(*pat_id, &elem_ty, default_bm); 215 self.infer_pat(*pat_id, &elem_ty, default_bm);
218 } 216 }
219 217
220 let pat_ty = Ty::apply_one(container_ty, elem_ty); 218 let pat_ty = container_ty(Substs::single(elem_ty));
221 if let Some(slice_pat_id) = slice { 219 if let Some(slice_pat_id) = slice {
222 self.infer_pat(*slice_pat_id, &pat_ty, default_bm); 220 self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
223 } 221 }
@@ -239,7 +237,7 @@ impl<'a> InferenceContext<'a> {
239 }; 237 };
240 238
241 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm); 239 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
242 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty) 240 Ty::Adt(box_adt, Substs::single(inner_ty))
243 } 241 }
244 None => Ty::Unknown, 242 None => Ty::Unknown,
245 }, 243 },
diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs
index 76984242e..99a89a7f3 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -2,14 +2,15 @@
2 2
3use std::borrow::Cow; 3use std::borrow::Cow;
4 4
5use chalk_ir::{FloatTy, IntTy, TyVariableKind};
5use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; 6use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue};
6 7
7use test_utils::mark; 8use test_utils::mark;
8 9
9use super::{InferenceContext, Obligation}; 10use super::{InferenceContext, Obligation};
10use crate::{ 11use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Substs, Ty, 12 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferenceVar, Scalar,
12 TyKind, TypeCtor, TypeWalk, 13 Substs, Ty, TypeWalk,
13}; 14};
14 15
15impl<'a> InferenceContext<'a> { 16impl<'a> InferenceContext<'a> {
@@ -26,7 +27,7 @@ where
26 'a: 'b, 27 'a: 'b,
27{ 28{
28 ctx: &'b mut InferenceContext<'a>, 29 ctx: &'b mut InferenceContext<'a>,
29 free_vars: Vec<InferTy>, 30 free_vars: Vec<(InferenceVar, TyVariableKind)>,
30 /// A stack of type variables that is used to detect recursive types (which 31 /// A stack of type variables that is used to detect recursive types (which
31 /// are an error, but we need to protect against them to avoid stack 32 /// are an error, but we need to protect against them to avoid stack
32 /// overflows). 33 /// overflows).
@@ -36,17 +37,14 @@ where
36#[derive(Debug)] 37#[derive(Debug)]
37pub(super) struct Canonicalized<T> { 38pub(super) struct Canonicalized<T> {
38 pub(super) value: Canonical<T>, 39 pub(super) value: Canonical<T>,
39 free_vars: Vec<InferTy>, 40 free_vars: Vec<(InferenceVar, TyVariableKind)>,
40} 41}
41 42
42impl<'a, 'b> Canonicalizer<'a, 'b> 43impl<'a, 'b> Canonicalizer<'a, 'b> {
43where 44 fn add(&mut self, free_var: InferenceVar, kind: TyVariableKind) -> usize {
44 'a: 'b, 45 self.free_vars.iter().position(|&(v, _)| v == free_var).unwrap_or_else(|| {
45{
46 fn add(&mut self, free_var: InferTy) -> usize {
47 self.free_vars.iter().position(|&v| v == free_var).unwrap_or_else(|| {
48 let next_index = self.free_vars.len(); 46 let next_index = self.free_vars.len();
49 self.free_vars.push(free_var); 47 self.free_vars.push((free_var, kind));
50 next_index 48 next_index
51 }) 49 })
52 } 50 }
@@ -54,11 +52,11 @@ where
54 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T { 52 fn do_canonicalize<T: TypeWalk>(&mut self, t: T, binders: DebruijnIndex) -> T {
55 t.fold_binders( 53 t.fold_binders(
56 &mut |ty, binders| match ty { 54 &mut |ty, binders| match ty {
57 Ty::Infer(tv) => { 55 Ty::InferenceVar(var, kind) => {
58 let inner = tv.to_inner(); 56 let inner = var.to_inner();
59 if self.var_stack.contains(&inner) { 57 if self.var_stack.contains(&inner) {
60 // recursive type 58 // recursive type
61 return tv.fallback_value(); 59 return self.ctx.table.type_variable_table.fallback_value(var, kind);
62 } 60 }
63 if let Some(known_ty) = 61 if let Some(known_ty) =
64 self.ctx.table.var_unification_table.inlined_probe_value(inner).known() 62 self.ctx.table.var_unification_table.inlined_probe_value(inner).known()
@@ -69,14 +67,8 @@ where
69 result 67 result
70 } else { 68 } else {
71 let root = self.ctx.table.var_unification_table.find(inner); 69 let root = self.ctx.table.var_unification_table.find(inner);
72 let free_var = match tv { 70 let position = self.add(InferenceVar::from_inner(root), kind);
73 InferTy::TypeVar(_) => InferTy::TypeVar(root), 71 Ty::BoundVar(BoundVar::new(binders, position))
74 InferTy::IntVar(_) => InferTy::IntVar(root),
75 InferTy::FloatVar(_) => InferTy::FloatVar(root),
76 InferTy::MaybeNeverTypeVar(_) => InferTy::MaybeNeverTypeVar(root),
77 };
78 let position = self.add(free_var);
79 Ty::Bound(BoundVar::new(binders, position))
80 } 72 }
81 } 73 }
82 _ => ty, 74 _ => ty,
@@ -86,19 +78,7 @@ where
86 } 78 }
87 79
88 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> { 80 fn into_canonicalized<T>(self, result: T) -> Canonicalized<T> {
89 let kinds = self 81 let kinds = self.free_vars.iter().map(|&(_, k)| k).collect();
90 .free_vars
91 .iter()
92 .map(|v| match v {
93 // mapping MaybeNeverTypeVar to the same kind as general ones
94 // should be fine, because as opposed to int or float type vars,
95 // they don't restrict what kind of type can go into them, they
96 // just affect fallback.
97 InferTy::TypeVar(_) | InferTy::MaybeNeverTypeVar(_) => TyKind::General,
98 InferTy::IntVar(_) => TyKind::Integer,
99 InferTy::FloatVar(_) => TyKind::Float,
100 })
101 .collect();
102 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } 82 Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars }
103 } 83 }
104 84
@@ -130,9 +110,10 @@ impl<T> Canonicalized<T> {
130 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty { 110 pub(super) fn decanonicalize_ty(&self, mut ty: Ty) -> Ty {
131 ty.walk_mut_binders( 111 ty.walk_mut_binders(
132 &mut |ty, binders| { 112 &mut |ty, binders| {
133 if let &mut Ty::Bound(bound) = ty { 113 if let &mut Ty::BoundVar(bound) = ty {
134 if bound.debruijn >= binders { 114 if bound.debruijn >= binders {
135 *ty = Ty::Infer(self.free_vars[bound.index]); 115 let (v, k) = self.free_vars[bound.index];
116 *ty = Ty::InferenceVar(v, k);
136 } 117 }
137 } 118 }
138 }, 119 },
@@ -152,18 +133,18 @@ impl<T> Canonicalized<T> {
152 .kinds 133 .kinds
153 .iter() 134 .iter()
154 .map(|k| match k { 135 .map(|k| match k {
155 TyKind::General => ctx.table.new_type_var(), 136 TyVariableKind::General => ctx.table.new_type_var(),
156 TyKind::Integer => ctx.table.new_integer_var(), 137 TyVariableKind::Integer => ctx.table.new_integer_var(),
157 TyKind::Float => ctx.table.new_float_var(), 138 TyVariableKind::Float => ctx.table.new_float_var(),
158 }) 139 })
159 .collect(), 140 .collect(),
160 ); 141 );
161 for (i, ty) in solution.value.into_iter().enumerate() { 142 for (i, ty) in solution.value.into_iter().enumerate() {
162 let var = self.free_vars[i]; 143 let (v, k) = self.free_vars[i];
163 // eagerly replace projections in the type; we may be getting types 144 // eagerly replace projections in the type; we may be getting types
164 // e.g. from where clauses where this hasn't happened yet 145 // e.g. from where clauses where this hasn't happened yet
165 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars)); 146 let ty = ctx.normalize_associated_types_in(ty.clone().subst_bound_vars(&new_vars));
166 ctx.table.unify(&Ty::Infer(var), &ty); 147 ctx.table.unify(&Ty::InferenceVar(v, k), &ty);
167 } 148 }
168 } 149 }
169} 150}
@@ -187,7 +168,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
187 // (kind of hacky) 168 // (kind of hacky)
188 for (i, var) in vars.iter().enumerate() { 169 for (i, var) in vars.iter().enumerate() {
189 if &*table.resolve_ty_shallow(var) == var { 170 if &*table.resolve_ty_shallow(var) == var {
190 table.unify(var, &Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i))); 171 table.unify(var, &Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i)));
191 } 172 }
192 } 173 }
193 Some( 174 Some(
@@ -198,31 +179,73 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option<Substs> {
198} 179}
199 180
200#[derive(Clone, Debug)] 181#[derive(Clone, Debug)]
182pub(super) struct TypeVariableTable {
183 inner: Vec<TypeVariableData>,
184}
185
186impl TypeVariableTable {
187 fn push(&mut self, data: TypeVariableData) {
188 self.inner.push(data);
189 }
190
191 pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
192 self.inner[iv.to_inner().0 as usize].diverging = diverging;
193 }
194
195 fn is_diverging(&mut self, iv: InferenceVar) -> bool {
196 self.inner[iv.to_inner().0 as usize].diverging
197 }
198
199 fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
200 match kind {
201 _ if self.inner[iv.to_inner().0 as usize].diverging => Ty::Never,
202 TyVariableKind::General => Ty::Unknown,
203 TyVariableKind::Integer => Ty::Scalar(Scalar::Int(IntTy::I32)),
204 TyVariableKind::Float => Ty::Scalar(Scalar::Float(FloatTy::F64)),
205 }
206 }
207}
208
209#[derive(Copy, Clone, Debug)]
210pub(crate) struct TypeVariableData {
211 diverging: bool,
212}
213
214#[derive(Clone, Debug)]
201pub(crate) struct InferenceTable { 215pub(crate) struct InferenceTable {
202 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>, 216 pub(super) var_unification_table: InPlaceUnificationTable<TypeVarId>,
217 pub(super) type_variable_table: TypeVariableTable,
203} 218}
204 219
205impl InferenceTable { 220impl InferenceTable {
206 pub(crate) fn new() -> Self { 221 pub(crate) fn new() -> Self {
207 InferenceTable { var_unification_table: InPlaceUnificationTable::new() } 222 InferenceTable {
223 var_unification_table: InPlaceUnificationTable::new(),
224 type_variable_table: TypeVariableTable { inner: Vec::new() },
225 }
226 }
227
228 fn new_var(&mut self, kind: TyVariableKind, diverging: bool) -> Ty {
229 self.type_variable_table.push(TypeVariableData { diverging });
230 let key = self.var_unification_table.new_key(TypeVarValue::Unknown);
231 assert_eq!(key.0 as usize, self.type_variable_table.inner.len() - 1);
232 Ty::InferenceVar(InferenceVar::from_inner(key), kind)
208 } 233 }
209 234
210 pub(crate) fn new_type_var(&mut self) -> Ty { 235 pub(crate) fn new_type_var(&mut self) -> Ty {
211 Ty::Infer(InferTy::TypeVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 236 self.new_var(TyVariableKind::General, false)
212 } 237 }
213 238
214 pub(crate) fn new_integer_var(&mut self) -> Ty { 239 pub(crate) fn new_integer_var(&mut self) -> Ty {
215 Ty::Infer(InferTy::IntVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 240 self.new_var(TyVariableKind::Integer, false)
216 } 241 }
217 242
218 pub(crate) fn new_float_var(&mut self) -> Ty { 243 pub(crate) fn new_float_var(&mut self) -> Ty {
219 Ty::Infer(InferTy::FloatVar(self.var_unification_table.new_key(TypeVarValue::Unknown))) 244 self.new_var(TyVariableKind::Float, false)
220 } 245 }
221 246
222 pub(crate) fn new_maybe_never_type_var(&mut self) -> Ty { 247 pub(crate) fn new_maybe_never_var(&mut self) -> Ty {
223 Ty::Infer(InferTy::MaybeNeverTypeVar( 248 self.new_var(TyVariableKind::General, true)
224 self.var_unification_table.new_key(TypeVarValue::Unknown),
225 ))
226 } 249 }
227 250
228 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { 251 pub(crate) fn resolve_ty_completely(&mut self, ty: Ty) -> Ty {
@@ -257,12 +280,14 @@ impl InferenceTable {
257 // try to resolve type vars first 280 // try to resolve type vars first
258 let ty1 = self.resolve_ty_shallow(ty1); 281 let ty1 = self.resolve_ty_shallow(ty1);
259 let ty2 = self.resolve_ty_shallow(ty2); 282 let ty2 = self.resolve_ty_shallow(ty2);
260 match (&*ty1, &*ty2) { 283 if ty1.equals_ctor(&ty2) {
261 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 284 match (ty1.substs(), ty2.substs()) {
262 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 285 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1),
286 (None, None) => true,
287 _ => false,
263 } 288 }
264 289 } else {
265 _ => self.unify_inner_trivial(&ty1, &ty2, depth), 290 self.unify_inner_trivial(&ty1, &ty2, depth)
266 } 291 }
267 } 292 }
268 293
@@ -281,31 +306,46 @@ impl InferenceTable {
281 true 306 true
282 } 307 }
283 308
284 (Ty::Infer(InferTy::TypeVar(tv1)), Ty::Infer(InferTy::TypeVar(tv2))) 309 (
285 | (Ty::Infer(InferTy::IntVar(tv1)), Ty::Infer(InferTy::IntVar(tv2))) 310 Ty::InferenceVar(tv1, TyVariableKind::General),
286 | (Ty::Infer(InferTy::FloatVar(tv1)), Ty::Infer(InferTy::FloatVar(tv2))) 311 Ty::InferenceVar(tv2, TyVariableKind::General),
312 )
287 | ( 313 | (
288 Ty::Infer(InferTy::MaybeNeverTypeVar(tv1)), 314 Ty::InferenceVar(tv1, TyVariableKind::Integer),
289 Ty::Infer(InferTy::MaybeNeverTypeVar(tv2)), 315 Ty::InferenceVar(tv2, TyVariableKind::Integer),
290 ) => { 316 )
317 | (
318 Ty::InferenceVar(tv1, TyVariableKind::Float),
319 Ty::InferenceVar(tv2, TyVariableKind::Float),
320 ) if self.type_variable_table.is_diverging(*tv1)
321 == self.type_variable_table.is_diverging(*tv2) =>
322 {
291 // both type vars are unknown since we tried to resolve them 323 // both type vars are unknown since we tried to resolve them
292 self.var_unification_table.union(*tv1, *tv2); 324 self.var_unification_table.union(tv1.to_inner(), tv2.to_inner());
293 true 325 true
294 } 326 }
295 327
296 // The order of MaybeNeverTypeVar matters here. 328 // The order of MaybeNeverTypeVar matters here.
297 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar. 329 // Unifying MaybeNeverTypeVar and TypeVar will let the latter become MaybeNeverTypeVar.
298 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it. 330 // Unifying MaybeNeverTypeVar and other concrete type will let the former become it.
299 (Ty::Infer(InferTy::TypeVar(tv)), other) 331 (Ty::InferenceVar(tv, TyVariableKind::General), other)
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 332 | (other, Ty::InferenceVar(tv, TyVariableKind::General))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 333 | (Ty::InferenceVar(tv, TyVariableKind::Integer), other @ Ty::Scalar(Scalar::Int(_)))
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 334 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::InferenceVar(tv, TyVariableKind::Integer))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Int(_))) 335 | (
304 | (other @ ty_app!(TypeCtor::Int(_)), Ty::Infer(InferTy::IntVar(tv))) 336 Ty::InferenceVar(tv, TyVariableKind::Integer),
305 | (Ty::Infer(InferTy::FloatVar(tv)), other @ ty_app!(TypeCtor::Float(_))) 337 other @ Ty::Scalar(Scalar::Uint(_)),
306 | (other @ ty_app!(TypeCtor::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => { 338 )
339 | (
340 other @ Ty::Scalar(Scalar::Uint(_)),
341 Ty::InferenceVar(tv, TyVariableKind::Integer),
342 )
343 | (Ty::InferenceVar(tv, TyVariableKind::Float), other @ Ty::Scalar(Scalar::Float(_)))
344 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::InferenceVar(tv, TyVariableKind::Float)) =>
345 {
307 // the type var is unknown since we tried to resolve it 346 // the type var is unknown since we tried to resolve it
308 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 347 self.var_unification_table
348 .union_value(tv.to_inner(), TypeVarValue::Known(other.clone()));
309 true 349 true
310 } 350 }
311 351
@@ -350,7 +390,7 @@ impl InferenceTable {
350 mark::hit!(type_var_resolves_to_int_var); 390 mark::hit!(type_var_resolves_to_int_var);
351 } 391 }
352 match &*ty { 392 match &*ty {
353 Ty::Infer(tv) => { 393 Ty::InferenceVar(tv, _) => {
354 let inner = tv.to_inner(); 394 let inner = tv.to_inner();
355 match self.var_unification_table.inlined_probe_value(inner).known() { 395 match self.var_unification_table.inlined_probe_value(inner).known() {
356 Some(known_ty) => { 396 Some(known_ty) => {
@@ -373,12 +413,12 @@ impl InferenceTable {
373 /// known type. 413 /// known type.
374 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 414 fn resolve_ty_as_possible_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
375 ty.fold(&mut |ty| match ty { 415 ty.fold(&mut |ty| match ty {
376 Ty::Infer(tv) => { 416 Ty::InferenceVar(tv, kind) => {
377 let inner = tv.to_inner(); 417 let inner = tv.to_inner();
378 if tv_stack.contains(&inner) { 418 if tv_stack.contains(&inner) {
379 mark::hit!(type_var_cycles_resolve_as_possible); 419 mark::hit!(type_var_cycles_resolve_as_possible);
380 // recursive type 420 // recursive type
381 return tv.fallback_value(); 421 return self.type_variable_table.fallback_value(tv, kind);
382 } 422 }
383 if let Some(known_ty) = 423 if let Some(known_ty) =
384 self.var_unification_table.inlined_probe_value(inner).known() 424 self.var_unification_table.inlined_probe_value(inner).known()
@@ -400,12 +440,12 @@ impl InferenceTable {
400 /// replaced by Ty::Unknown. 440 /// replaced by Ty::Unknown.
401 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty { 441 fn resolve_ty_completely_inner(&mut self, tv_stack: &mut Vec<TypeVarId>, ty: Ty) -> Ty {
402 ty.fold(&mut |ty| match ty { 442 ty.fold(&mut |ty| match ty {
403 Ty::Infer(tv) => { 443 Ty::InferenceVar(tv, kind) => {
404 let inner = tv.to_inner(); 444 let inner = tv.to_inner();
405 if tv_stack.contains(&inner) { 445 if tv_stack.contains(&inner) {
406 mark::hit!(type_var_cycles_resolve_completely); 446 mark::hit!(type_var_cycles_resolve_completely);
407 // recursive type 447 // recursive type
408 return tv.fallback_value(); 448 return self.type_variable_table.fallback_value(tv, kind);
409 } 449 }
410 if let Some(known_ty) = 450 if let Some(known_ty) =
411 self.var_unification_table.inlined_probe_value(inner).known() 451 self.var_unification_table.inlined_probe_value(inner).known()
@@ -416,7 +456,7 @@ impl InferenceTable {
416 tv_stack.pop(); 456 tv_stack.pop();
417 result 457 result
418 } else { 458 } else {
419 tv.fallback_value() 459 self.type_variable_table.fallback_value(tv, kind)
420 } 460 }
421 } 461 }
422 _ => ty, 462 _ => ty,
@@ -426,7 +466,7 @@ impl InferenceTable {
426 466
427/// The ID of a type variable. 467/// The ID of a type variable.
428#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] 468#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
429pub struct TypeVarId(pub(super) u32); 469pub(super) struct TypeVarId(pub(super) u32);
430 470
431impl UnifyKey for TypeVarId { 471impl UnifyKey for TypeVarId {
432 type Value = TypeVarValue; 472 type Value = TypeVarValue;
@@ -447,7 +487,7 @@ impl UnifyKey for TypeVarId {
447/// The value of a type variable: either we already know the type, or we don't 487/// The value of a type variable: either we already know the type, or we don't
448/// know it yet. 488/// know it yet.
449#[derive(Clone, PartialEq, Eq, Debug)] 489#[derive(Clone, PartialEq, Eq, Debug)]
450pub enum TypeVarValue { 490pub(super) enum TypeVarValue {
451 Known(Ty), 491 Known(Ty),
452 Unknown, 492 Unknown,
453} 493}
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 50d248674..c2a20c480 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -25,32 +25,29 @@ 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, AdtId, AssocContainerId,
31 expr::ExprId, 31 DefWithBodyId, FunctionId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId,
32 type_ref::{Mutability, Rawness}, 32 TypeAliasId, 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::{BoundVar, DebruijnIndex, Mutability, Scalar, TyVariableKind};
54 51
55#[derive(Clone, PartialEq, Eq, Debug, Hash)] 52#[derive(Clone, PartialEq, Eq, Debug, Hash)]
56pub enum Lifetime { 53pub enum Lifetime {
@@ -58,211 +55,6 @@ pub enum Lifetime {
58 Static, 55 Static,
59} 56}
60 57
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)] 58#[derive(Clone, PartialEq, Eq, Debug, Hash)]
267pub struct OpaqueTy { 59pub struct OpaqueTy {
268 pub opaque_ty_id: OpaqueTyId, 60 pub opaque_ty_id: OpaqueTyId,
@@ -305,29 +97,118 @@ impl TypeWalk for ProjectionTy {
305 } 97 }
306} 98}
307 99
308/// A type. 100#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
309/// 101pub struct FnSig {
310/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 102 pub variadic: bool,
311/// the same thing (but in a different way). 103}
312/// 104
313/// This should be cheap to clone.
314#[derive(Clone, PartialEq, Eq, Debug, Hash)] 105#[derive(Clone, PartialEq, Eq, Debug, Hash)]
315pub enum Ty { 106pub struct FnPointer {
316 /// A nominal type with (maybe 0) type parameters. This might be a primitive 107 pub num_args: usize,
317 /// type like `bool`, a struct, tuple, function pointer, reference or 108 pub sig: FnSig,
318 /// several other things. 109 pub substs: Substs,
319 Apply(ApplicationTy), 110}
320 111
112#[derive(Clone, PartialEq, Eq, Debug, Hash)]
113pub enum AliasTy {
321 /// A "projection" type corresponds to an (unnormalized) 114 /// A "projection" type corresponds to an (unnormalized)
322 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 115 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
323 /// trait and all its parameters are fully known. 116 /// trait and all its parameters are fully known.
324 Projection(ProjectionTy), 117 Projection(ProjectionTy),
325
326 /// An opaque type (`impl Trait`). 118 /// An opaque type (`impl Trait`).
327 /// 119 ///
328 /// This is currently only used for return type impl trait; each instance of 120 /// This is currently only used for return type impl trait; each instance of
329 /// `impl Trait` in a return type gets its own ID. 121 /// `impl Trait` in a return type gets its own ID.
330 Opaque(OpaqueTy), 122 Opaque(OpaqueTy),
123}
124
125/// A type.
126///
127/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
128/// the same thing (but in a different way).
129///
130/// This should be cheap to clone.
131#[derive(Clone, PartialEq, Eq, Debug, Hash)]
132pub enum Ty {
133 /// Structures, enumerations and unions.
134 Adt(AdtId, Substs),
135
136 /// Represents an associated item like `Iterator::Item`. This is used
137 /// when we have tried to normalize a projection like `T::Item` but
138 /// couldn't find a better representation. In that case, we generate
139 /// an **application type** like `(Iterator::Item)<T>`.
140 AssociatedType(TypeAliasId, Substs),
141
142 /// a scalar type like `bool` or `u32`
143 Scalar(Scalar),
144
145 /// A tuple type. For example, `(i32, bool)`.
146 Tuple(usize, Substs),
147
148 /// An array with the given length. Written as `[T; n]`.
149 Array(Substs),
150
151 /// The pointee of an array slice. Written as `[T]`.
152 Slice(Substs),
153
154 /// A raw pointer. Written as `*mut T` or `*const T`
155 Raw(Mutability, Substs),
156
157 /// A reference; a pointer with an associated lifetime. Written as
158 /// `&'a mut T` or `&'a T`.
159 Ref(Mutability, Substs),
160
161 /// This represents a placeholder for an opaque type in situations where we
162 /// don't know the hidden type (i.e. currently almost always). This is
163 /// analogous to the `AssociatedType` type constructor.
164 /// It is also used as the type of async block, with one type parameter
165 /// representing the Future::Output type.
166 OpaqueType(OpaqueTyId, Substs),
167
168 /// The anonymous type of a function declaration/definition. Each
169 /// function has a unique type, which is output (for a function
170 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
171 ///
172 /// This includes tuple struct / enum variant constructors as well.
173 ///
174 /// For example the type of `bar` here:
175 ///
176 /// ```
177 /// fn foo() -> i32 { 1 }
178 /// let bar = foo; // bar: fn() -> i32 {foo}
179 /// ```
180 FnDef(CallableDefId, Substs),
181
182 /// The pointee of a string slice. Written as `str`.
183 Str,
184
185 /// The never type `!`.
186 Never,
187
188 /// The type of a specific closure.
189 ///
190 /// The closure signature is stored in a `FnPtr` type in the first type
191 /// parameter.
192 Closure(DefWithBodyId, ExprId, Substs),
193
194 /// Represents a foreign type declared in external blocks.
195 ForeignType(TypeAliasId),
196
197 /// A pointer to a function. Written as `fn() -> i32`.
198 ///
199 /// For example the type of `bar` here:
200 ///
201 /// ```
202 /// fn foo() -> i32 { 1 }
203 /// let bar: fn() -> i32 = foo;
204 /// ```
205 Function(FnPointer),
206
207 /// An "alias" type represents some form of type alias, such as:
208 /// - An associated type projection like `<T as Iterator>::Item`
209 /// - `impl Trait` types
210 /// - Named type aliases like `type Foo<X> = Vec<X>`
211 Alias(AliasTy),
331 212
332 /// A placeholder for a type parameter; for example, `T` in `fn f<T>(x: T) 213 /// 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 214 /// {}` when we're type-checking the body of that function. In this
@@ -340,10 +221,10 @@ pub enum Ty {
340 /// parameters get turned into variables; during trait resolution, inference 221 /// parameters get turned into variables; during trait resolution, inference
341 /// variables get turned into bound variables and back; and in `Dyn` the 222 /// variables get turned into bound variables and back; and in `Dyn` the
342 /// `Self` type is represented with a bound variable as well. 223 /// `Self` type is represented with a bound variable as well.
343 Bound(BoundVar), 224 BoundVar(BoundVar),
344 225
345 /// A type variable used during type checking. 226 /// A type variable used during type checking.
346 Infer(InferTy), 227 InferenceVar(InferenceVar, TyVariableKind),
347 228
348 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust). 229 /// A trait object (`dyn Trait` or bare `Trait` in pre-2018 Rust).
349 /// 230 ///
@@ -424,7 +305,7 @@ impl Substs {
424 generic_params 305 generic_params
425 .iter() 306 .iter()
426 .enumerate() 307 .enumerate()
427 .map(|(idx, _)| Ty::Bound(BoundVar::new(debruijn, idx))) 308 .map(|(idx, _)| Ty::BoundVar(BoundVar::new(debruijn, idx)))
428 .collect(), 309 .collect(),
429 ) 310 )
430 } 311 }
@@ -440,10 +321,6 @@ impl Substs {
440 Substs::builder(generic_params.len()) 321 Substs::builder(generic_params.len())
441 } 322 }
442 323
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 { 324 fn builder(param_count: usize) -> SubstsBuilder {
448 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 325 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
449 } 326 }
@@ -476,7 +353,7 @@ impl SubstsBuilder {
476 } 353 }
477 354
478 pub fn fill_with_bound_vars(self, debruijn: DebruijnIndex, starting_from: usize) -> Self { 355 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)))) 356 self.fill((starting_from..).map(|idx| Ty::BoundVar(BoundVar::new(debruijn, idx))))
480 } 357 }
481 358
482 pub fn fill_with_unknown(self) -> Self { 359 pub fn fill_with_unknown(self) -> Self {
@@ -656,41 +533,41 @@ impl TypeWalk for GenericPredicate {
656#[derive(Debug, Clone, PartialEq, Eq, Hash)] 533#[derive(Debug, Clone, PartialEq, Eq, Hash)]
657pub struct Canonical<T> { 534pub struct Canonical<T> {
658 pub value: T, 535 pub value: T,
659 pub kinds: Arc<[TyKind]>, 536 pub kinds: Arc<[TyVariableKind]>,
660} 537}
661 538
662impl<T> Canonical<T> { 539impl<T> Canonical<T> {
663 pub fn new(value: T, kinds: impl IntoIterator<Item = TyKind>) -> Self { 540 pub fn new(value: T, kinds: impl IntoIterator<Item = TyVariableKind>) -> Self {
664 Self { value, kinds: kinds.into_iter().collect() } 541 Self { value, kinds: kinds.into_iter().collect() }
665 } 542 }
666} 543}
667 544
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 545/// A function signature as seen by type inference: Several parameter types and
676/// one return type. 546/// one return type.
677#[derive(Clone, PartialEq, Eq, Debug)] 547#[derive(Clone, PartialEq, Eq, Debug)]
678pub struct FnSig { 548pub struct CallableSig {
679 params_and_return: Arc<[Ty]>, 549 params_and_return: Arc<[Ty]>,
680 is_varargs: bool, 550 is_varargs: bool,
681} 551}
682 552
683/// A polymorphic function signature. 553/// A polymorphic function signature.
684pub type PolyFnSig = Binders<FnSig>; 554pub type PolyFnSig = Binders<CallableSig>;
685 555
686impl FnSig { 556impl CallableSig {
687 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 557 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
688 params.push(ret); 558 params.push(ret);
689 FnSig { params_and_return: params.into(), is_varargs } 559 CallableSig { params_and_return: params.into(), is_varargs }
690 } 560 }
691 561
692 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 562 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
693 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 563 CallableSig {
564 params_and_return: Arc::clone(&fn_ptr.substs.0),
565 is_varargs: fn_ptr.sig.variadic,
566 }
567 }
568
569 pub fn from_substs(substs: &Substs) -> CallableSig {
570 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
694 } 571 }
695 572
696 pub fn params(&self) -> &[Ty] { 573 pub fn params(&self) -> &[Ty] {
@@ -702,7 +579,7 @@ impl FnSig {
702 } 579 }
703} 580}
704 581
705impl TypeWalk for FnSig { 582impl TypeWalk for CallableSig {
706 fn walk(&self, f: &mut impl FnMut(&Ty)) { 583 fn walk(&self, f: &mut impl FnMut(&Ty)) {
707 for t in self.params_and_return.iter() { 584 for t in self.params_and_return.iter() {
708 t.walk(f); 585 t.walk(f);
@@ -721,49 +598,42 @@ impl TypeWalk for FnSig {
721} 598}
722 599
723impl Ty { 600impl 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 { 601 pub fn unit() -> Self {
734 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 602 Ty::Tuple(0, Substs::empty())
735 } 603 }
736 pub fn fn_ptr(sig: FnSig) -> Self { 604
737 Ty::apply( 605 pub fn fn_ptr(sig: CallableSig) -> Self {
738 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 606 Ty::Function(FnPointer {
739 Substs(sig.params_and_return), 607 num_args: sig.params().len(),
740 ) 608 sig: FnSig { variadic: sig.is_varargs },
609 substs: Substs(sig.params_and_return),
610 })
741 } 611 }
612
742 pub fn builtin(builtin: BuiltinType) -> Self { 613 pub fn builtin(builtin: BuiltinType) -> Self {
743 Ty::simple(match builtin { 614 match builtin {
744 BuiltinType::Char => TypeCtor::Char, 615 BuiltinType::Char => Ty::Scalar(Scalar::Char),
745 BuiltinType::Bool => TypeCtor::Bool, 616 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
746 BuiltinType::Str => TypeCtor::Str, 617 BuiltinType::Str => Ty::Str,
747 BuiltinType::Int(t) => TypeCtor::Int(IntTy::from(t).into()), 618 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
748 BuiltinType::Float(t) => TypeCtor::Float(FloatTy::from(t).into()), 619 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
749 }) 620 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
621 }
750 } 622 }
751 623
752 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 624 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
753 match self { 625 match self {
754 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 626 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
755 Some((parameters.as_single(), *mutability))
756 }
757 _ => None, 627 _ => None,
758 } 628 }
759 } 629 }
760 630
761 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 631 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
762 match self { 632 match self {
763 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 633 Ty::Ref(mutability, parameters) => {
764 Some((parameters.as_single(), Rawness::Ref, *mutability)) 634 Some((parameters.as_single(), Rawness::Ref, *mutability))
765 } 635 }
766 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 636 Ty::Raw(mutability, parameters) => {
767 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 637 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
768 } 638 }
769 _ => None, 639 _ => None,
@@ -773,7 +643,7 @@ impl Ty {
773 pub fn strip_references(&self) -> &Ty { 643 pub fn strip_references(&self) -> &Ty {
774 let mut t: &Ty = self; 644 let mut t: &Ty = self;
775 645
776 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 646 while let Ty::Ref(_mutability, parameters) = t {
777 t = parameters.as_single(); 647 t = parameters.as_single();
778 } 648 }
779 649
@@ -782,30 +652,60 @@ impl Ty {
782 652
783 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 653 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
784 match self { 654 match self {
785 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 655 Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)),
786 Some((*adt_def, parameters))
787 }
788 _ => None, 656 _ => None,
789 } 657 }
790 } 658 }
791 659
792 pub fn as_tuple(&self) -> Option<&Substs> { 660 pub fn as_tuple(&self) -> Option<&Substs> {
793 match self { 661 match self {
794 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 662 Ty::Tuple(_, substs) => Some(substs),
795 Some(parameters) 663 _ => None,
796 } 664 }
665 }
666
667 pub fn as_generic_def(&self) -> Option<GenericDefId> {
668 match *self {
669 Ty::Adt(adt, ..) => Some(adt.into()),
670 Ty::FnDef(callable, ..) => Some(callable.into()),
671 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
672 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
797 _ => None, 673 _ => None,
798 } 674 }
799 } 675 }
800 676
801 pub fn is_never(&self) -> bool { 677 pub fn is_never(&self) -> bool {
802 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 678 matches!(self, Ty::Never)
803 } 679 }
804 680
805 pub fn is_unknown(&self) -> bool { 681 pub fn is_unknown(&self) -> bool {
806 matches!(self, Ty::Unknown) 682 matches!(self, Ty::Unknown)
807 } 683 }
808 684
685 pub fn equals_ctor(&self, other: &Ty) -> bool {
686 match (self, other) {
687 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
688 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
689 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
690 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
691 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
692 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
693 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
694 expr == expr2 && def == def2
695 }
696 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
697 | (Ty::Raw(mutability, ..), Ty::Raw(mutability2, ..)) => mutability == mutability2,
698 (
699 Ty::Function(FnPointer { num_args, sig, .. }),
700 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
701 ) => num_args == num_args2 && sig == sig2,
702 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
703 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
704 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
705 _ => false,
706 }
707 }
708
809 /// If this is a `dyn Trait` type, this returns the `Trait` part. 709 /// If this is a `dyn Trait` type, this returns the `Trait` part.
810 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 710 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
811 match self { 711 match self {
@@ -824,41 +724,30 @@ impl Ty {
824 724
825 fn builtin_deref(&self) -> Option<Ty> { 725 fn builtin_deref(&self) -> Option<Ty> {
826 match self { 726 match self {
827 Ty::Apply(a_ty) => match a_ty.ctor { 727 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
828 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 728 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, 729 _ => None,
833 } 730 }
834 } 731 }
835 732
836 pub fn as_fn_def(&self) -> Option<FunctionId> { 733 pub fn as_fn_def(&self) -> Option<FunctionId> {
837 match self { 734 match self {
838 &Ty::Apply(ApplicationTy { 735 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
839 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
840 ..
841 }) => Some(func),
842 _ => None, 736 _ => None,
843 } 737 }
844 } 738 }
845 739
846 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 740 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
847 match self { 741 match self {
848 Ty::Apply(a_ty) => match a_ty.ctor { 742 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
849 TypeCtor::FnPtr { is_varargs, .. } => { 743 Ty::FnDef(def, parameters) => {
850 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 744 let sig = db.callable_item_signature(*def);
851 } 745 Some(sig.subst(&parameters))
852 TypeCtor::FnDef(def) => { 746 }
853 let sig = db.callable_item_signature(def); 747 Ty::Closure(.., substs) => {
854 Some(sig.subst(&a_ty.parameters)) 748 let sig_param = &substs[0];
855 } 749 sig_param.callable_sig(db)
856 TypeCtor::Closure { .. } => { 750 }
857 let sig_param = &a_ty.parameters[0];
858 sig_param.callable_sig(db)
859 }
860 _ => None,
861 },
862 _ => None, 751 _ => None,
863 } 752 }
864 } 753 }
@@ -867,28 +756,66 @@ impl Ty {
867 /// the `Substs` for these type parameters with the given ones. (So e.g. if 756 /// the `Substs` for these type parameters with the given ones. (So e.g. if
868 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 757 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
869 /// `Option<u32>` afterwards.) 758 /// `Option<u32>` afterwards.)
870 pub fn apply_substs(self, substs: Substs) -> Ty { 759 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
871 match self { 760 match &mut self {
872 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 761 Ty::Adt(_, substs)
873 assert_eq!(previous_substs.len(), substs.len()); 762 | Ty::Slice(substs)
874 Ty::Apply(ApplicationTy { ctor, parameters: substs }) 763 | Ty::Array(substs)
764 | Ty::Raw(_, substs)
765 | Ty::Ref(_, substs)
766 | Ty::FnDef(_, substs)
767 | Ty::Function(FnPointer { substs, .. })
768 | Ty::Tuple(_, substs)
769 | Ty::OpaqueType(_, substs)
770 | Ty::AssociatedType(_, substs)
771 | Ty::Closure(.., substs) => {
772 assert_eq!(substs.len(), new_substs.len());
773 *substs = new_substs;
875 } 774 }
876 _ => self, 775 _ => (),
877 } 776 }
777 self
878 } 778 }
879 779
880 /// Returns the type parameters of this type if it has some (i.e. is an ADT 780 /// Returns the type parameters of this type if it has some (i.e. is an ADT
881 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 781 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
882 pub fn substs(&self) -> Option<Substs> { 782 pub fn substs(&self) -> Option<&Substs> {
883 match self { 783 match self {
884 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 784 Ty::Adt(_, substs)
785 | Ty::Slice(substs)
786 | Ty::Array(substs)
787 | Ty::Raw(_, substs)
788 | Ty::Ref(_, substs)
789 | Ty::FnDef(_, substs)
790 | Ty::Function(FnPointer { substs, .. })
791 | Ty::Tuple(_, substs)
792 | Ty::OpaqueType(_, substs)
793 | Ty::AssociatedType(_, substs)
794 | Ty::Closure(.., substs) => Some(substs),
795 _ => None,
796 }
797 }
798
799 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
800 match self {
801 Ty::Adt(_, substs)
802 | Ty::Slice(substs)
803 | Ty::Array(substs)
804 | Ty::Raw(_, substs)
805 | Ty::Ref(_, substs)
806 | Ty::FnDef(_, substs)
807 | Ty::Function(FnPointer { substs, .. })
808 | Ty::Tuple(_, substs)
809 | Ty::OpaqueType(_, substs)
810 | Ty::AssociatedType(_, substs)
811 | Ty::Closure(.., substs) => Some(substs),
885 _ => None, 812 _ => None,
886 } 813 }
887 } 814 }
888 815
889 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 816 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
890 match self { 817 match self {
891 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 818 Ty::OpaqueType(opaque_ty_id, ..) => {
892 match opaque_ty_id { 819 match opaque_ty_id {
893 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 820 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
894 let krate = def.module(db.upcast()).krate(); 821 let krate = def.module(db.upcast()).krate();
@@ -911,7 +838,7 @@ impl Ty {
911 OpaqueTyId::ReturnTypeImplTrait(..) => None, 838 OpaqueTyId::ReturnTypeImplTrait(..) => None,
912 } 839 }
913 } 840 }
914 Ty::Opaque(opaque_ty) => { 841 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
915 let predicates = match opaque_ty.opaque_ty_id { 842 let predicates = match opaque_ty.opaque_ty_id {
916 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 843 OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
917 db.return_type_impl_traits(func).map(|it| { 844 db.return_type_impl_traits(func).map(|it| {
@@ -949,13 +876,13 @@ impl Ty {
949 876
950 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 877 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
951 match self { 878 match self {
952 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 879 Ty::AssociatedType(type_alias_id, ..) => {
953 match type_alias_id.lookup(db.upcast()).container { 880 match type_alias_id.lookup(db.upcast()).container {
954 AssocContainerId::TraitId(trait_id) => Some(trait_id), 881 AssocContainerId::TraitId(trait_id) => Some(trait_id),
955 _ => None, 882 _ => None,
956 } 883 }
957 } 884 }
958 Ty::Projection(projection_ty) => { 885 Ty::Alias(AliasTy::Projection(projection_ty)) => {
959 match projection_ty.associated_ty.lookup(db.upcast()).container { 886 match projection_ty.associated_ty.lookup(db.upcast()).container {
960 AssocContainerId::TraitId(trait_id) => Some(trait_id), 887 AssocContainerId::TraitId(trait_id) => Some(trait_id),
961 _ => None, 888 _ => None,
@@ -1033,7 +960,7 @@ pub trait TypeWalk {
1033 { 960 {
1034 self.walk_mut_binders( 961 self.walk_mut_binders(
1035 &mut |ty, binders| { 962 &mut |ty, binders| {
1036 if let &mut Ty::Bound(bound) = ty { 963 if let &mut Ty::BoundVar(bound) = ty {
1037 if bound.debruijn >= binders { 964 if bound.debruijn >= binders {
1038 *ty = substs.0[bound.index].clone().shift_bound_vars(binders); 965 *ty = substs.0[bound.index].clone().shift_bound_vars(binders);
1039 } 966 }
@@ -1051,8 +978,8 @@ pub trait TypeWalk {
1051 { 978 {
1052 self.fold_binders( 979 self.fold_binders(
1053 &mut |ty, binders| match ty { 980 &mut |ty, binders| match ty {
1054 Ty::Bound(bound) if bound.debruijn >= binders => { 981 Ty::BoundVar(bound) if bound.debruijn >= binders => {
1055 Ty::Bound(bound.shifted_in_from(n)) 982 Ty::BoundVar(bound.shifted_in_from(n))
1056 } 983 }
1057 ty => ty, 984 ty => ty,
1058 }, 985 },
@@ -1064,13 +991,13 @@ pub trait TypeWalk {
1064impl TypeWalk for Ty { 991impl TypeWalk for Ty {
1065 fn walk(&self, f: &mut impl FnMut(&Ty)) { 992 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1066 match self { 993 match self {
1067 Ty::Apply(a_ty) => { 994 Ty::Alias(AliasTy::Projection(p_ty)) => {
1068 for t in a_ty.parameters.iter() { 995 for t in p_ty.parameters.iter() {
1069 t.walk(f); 996 t.walk(f);
1070 } 997 }
1071 } 998 }
1072 Ty::Projection(p_ty) => { 999 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1073 for t in p_ty.parameters.iter() { 1000 for t in o_ty.parameters.iter() {
1074 t.walk(f); 1001 t.walk(f);
1075 } 1002 }
1076 } 1003 }
@@ -1079,12 +1006,13 @@ impl TypeWalk for Ty {
1079 p.walk(f); 1006 p.walk(f);
1080 } 1007 }
1081 } 1008 }
1082 Ty::Opaque(o_ty) => { 1009 _ => {
1083 for t in o_ty.parameters.iter() { 1010 if let Some(substs) = self.substs() {
1084 t.walk(f); 1011 for t in substs.iter() {
1012 t.walk(f);
1013 }
1085 } 1014 }
1086 } 1015 }
1087 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {}
1088 } 1016 }
1089 f(self); 1017 f(self);
1090 } 1018 }
@@ -1095,10 +1023,7 @@ impl TypeWalk for Ty {
1095 binders: DebruijnIndex, 1023 binders: DebruijnIndex,
1096 ) { 1024 ) {
1097 match self { 1025 match self {
1098 Ty::Apply(a_ty) => { 1026 Ty::Alias(AliasTy::Projection(p_ty)) => {
1099 a_ty.parameters.walk_mut_binders(f, binders);
1100 }
1101 Ty::Projection(p_ty) => {
1102 p_ty.parameters.walk_mut_binders(f, binders); 1027 p_ty.parameters.walk_mut_binders(f, binders);
1103 } 1028 }
1104 Ty::Dyn(predicates) => { 1029 Ty::Dyn(predicates) => {
@@ -1106,10 +1031,14 @@ impl TypeWalk for Ty {
1106 p.walk_mut_binders(f, binders.shifted_in()); 1031 p.walk_mut_binders(f, binders.shifted_in());
1107 } 1032 }
1108 } 1033 }
1109 Ty::Opaque(o_ty) => { 1034 Ty::Alias(AliasTy::Opaque(o_ty)) => {
1110 o_ty.parameters.walk_mut_binders(f, binders); 1035 o_ty.parameters.walk_mut_binders(f, binders);
1111 } 1036 }
1112 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1037 _ => {
1038 if let Some(substs) = self.substs_mut() {
1039 substs.walk_mut_binders(f, binders);
1040 }
1041 }
1113 } 1042 }
1114 f(self, binders); 1043 f(self, binders);
1115 } 1044 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 99b0ecf3b..1b5843d48 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -8,6 +8,7 @@
8use std::{iter, sync::Arc}; 8use std::{iter, sync::Arc};
9 9
10use base_db::CrateId; 10use base_db::CrateId;
11use chalk_ir::Mutability;
11use hir_def::{ 12use hir_def::{
12 adt::StructKind, 13 adt::StructKind,
13 builtin_type::BuiltinType, 14 builtin_type::BuiltinType,
@@ -31,9 +32,9 @@ use crate::{
31 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 32 all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
32 make_mut_slice, variant_data, 33 make_mut_slice, variant_data,
33 }, 34 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, 35 AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, 36 OpaqueTy, OpaqueTyId, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
36 TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 37 ReturnTypeImplTraits, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
37}; 38};
38 39
39#[derive(Debug)] 40#[derive(Debug)]
@@ -145,13 +146,10 @@ impl Ty {
145 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) { 146 pub fn from_hir_ext(ctx: &TyLoweringContext<'_>, type_ref: &TypeRef) -> (Self, Option<TypeNs>) {
146 let mut res = None; 147 let mut res = None;
147 let ty = match type_ref { 148 let ty = match type_ref {
148 TypeRef::Never => Ty::simple(TypeCtor::Never), 149 TypeRef::Never => Ty::Never,
149 TypeRef::Tuple(inner) => { 150 TypeRef::Tuple(inner) => {
150 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect(); 151 let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| Ty::from_hir(ctx, tr)).collect();
151 Ty::apply( 152 Ty::Tuple(inner_tys.len(), Substs(inner_tys))
152 TypeCtor::Tuple { cardinality: inner_tys.len() as u16 },
153 Substs(inner_tys),
154 )
155 } 153 }
156 TypeRef::Path(path) => { 154 TypeRef::Path(path) => {
157 let (ty, res_) = Ty::from_hir_path(ctx, path); 155 let (ty, res_) = Ty::from_hir_path(ctx, path);
@@ -160,30 +158,31 @@ impl Ty {
160 } 158 }
161 TypeRef::RawPtr(inner, mutability) => { 159 TypeRef::RawPtr(inner, mutability) => {
162 let inner_ty = Ty::from_hir(ctx, inner); 160 let inner_ty = Ty::from_hir(ctx, inner);
163 Ty::apply_one(TypeCtor::RawPtr(*mutability), inner_ty) 161 Ty::Raw(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
164 } 162 }
165 TypeRef::Array(inner) => { 163 TypeRef::Array(inner) => {
166 let inner_ty = Ty::from_hir(ctx, inner); 164 let inner_ty = Ty::from_hir(ctx, inner);
167 Ty::apply_one(TypeCtor::Array, inner_ty) 165 Ty::Array(Substs::single(inner_ty))
168 } 166 }
169 TypeRef::Slice(inner) => { 167 TypeRef::Slice(inner) => {
170 let inner_ty = Ty::from_hir(ctx, inner); 168 let inner_ty = Ty::from_hir(ctx, inner);
171 Ty::apply_one(TypeCtor::Slice, inner_ty) 169 Ty::Slice(Substs::single(inner_ty))
172 } 170 }
173 TypeRef::Reference(inner, _, mutability) => { 171 TypeRef::Reference(inner, _, mutability) => {
174 let inner_ty = Ty::from_hir(ctx, inner); 172 let inner_ty = Ty::from_hir(ctx, inner);
175 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty) 173 Ty::Ref(lower_to_chalk_mutability(*mutability), Substs::single(inner_ty))
176 } 174 }
177 TypeRef::Placeholder => Ty::Unknown, 175 TypeRef::Placeholder => Ty::Unknown,
178 TypeRef::Fn(params, is_varargs) => { 176 TypeRef::Fn(params, is_varargs) => {
179 let sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect()); 177 let substs = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
180 Ty::apply( 178 Ty::Function(FnPointer {
181 TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs }, 179 num_args: substs.len() - 1,
182 sig, 180 sig: FnSig { variadic: *is_varargs },
183 ) 181 substs,
182 })
184 } 183 }
185 TypeRef::DynTrait(bounds) => { 184 TypeRef::DynTrait(bounds) => {
186 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 185 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0));
187 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 186 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
188 bounds 187 bounds
189 .iter() 188 .iter()
@@ -227,7 +226,10 @@ impl Ty {
227 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx); 226 let impl_trait_id = OpaqueTyId::ReturnTypeImplTrait(func, idx);
228 let generics = generics(ctx.db.upcast(), func.into()); 227 let generics = generics(ctx.db.upcast(), func.into());
229 let parameters = Substs::bound_vars(&generics, ctx.in_binders); 228 let parameters = Substs::bound_vars(&generics, ctx.in_binders);
230 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 229 Ty::Alias(AliasTy::Opaque(OpaqueTy {
230 opaque_ty_id: impl_trait_id,
231 parameters,
232 }))
231 } 233 }
232 ImplTraitLoweringMode::Param => { 234 ImplTraitLoweringMode::Param => {
233 let idx = ctx.impl_trait_counter.get(); 235 let idx = ctx.impl_trait_counter.get();
@@ -258,7 +260,7 @@ impl Ty {
258 } else { 260 } else {
259 (0, 0, 0, 0) 261 (0, 0, 0, 0)
260 }; 262 };
261 Ty::Bound(BoundVar::new( 263 Ty::BoundVar(BoundVar::new(
262 ctx.in_binders, 264 ctx.in_binders,
263 idx as usize + parent_params + self_params + list_params, 265 idx as usize + parent_params + self_params + list_params,
264 )) 266 ))
@@ -330,7 +332,7 @@ impl Ty {
330 TypeNs::TraitId(trait_) => { 332 TypeNs::TraitId(trait_) => {
331 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there 333 // if this is a bare dyn Trait, we'll directly put the required ^0 for the self type in there
332 let self_ty = if remaining_segments.len() == 0 { 334 let self_ty = if remaining_segments.len() == 0 {
333 Some(Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0))) 335 Some(Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)))
334 } else { 336 } else {
335 None 337 None
336 }; 338 };
@@ -346,10 +348,10 @@ impl Ty {
346 match found { 348 match found {
347 Some((super_trait_ref, associated_ty)) => { 349 Some((super_trait_ref, associated_ty)) => {
348 // FIXME handle type parameters on the segment 350 // FIXME handle type parameters on the segment
349 Ty::Projection(ProjectionTy { 351 Ty::Alias(AliasTy::Projection(ProjectionTy {
350 associated_ty, 352 associated_ty,
351 parameters: super_trait_ref.substs, 353 parameters: super_trait_ref.substs,
352 }) 354 }))
353 } 355 }
354 None => { 356 None => {
355 // FIXME: report error (associated type not found) 357 // FIXME: report error (associated type not found)
@@ -373,7 +375,7 @@ impl Ty {
373 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 375 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
374 TypeParamLoweringMode::Variable => { 376 TypeParamLoweringMode::Variable => {
375 let idx = generics.param_idx(param_id).expect("matching generics"); 377 let idx = generics.param_idx(param_id).expect("matching generics");
376 Ty::Bound(BoundVar::new(ctx.in_binders, idx)) 378 Ty::BoundVar(BoundVar::new(ctx.in_binders, idx))
377 } 379 }
378 } 380 }
379 } 381 }
@@ -414,7 +416,6 @@ impl Ty {
414 // FIXME: report error 416 // FIXME: report error
415 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 417 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
416 }; 418 };
417
418 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 419 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments)
419 } 420 }
420 421
@@ -472,10 +473,10 @@ impl Ty {
472 // associated_type_shorthand_candidates does not do that 473 // associated_type_shorthand_candidates does not do that
473 let substs = substs.shift_bound_vars(ctx.in_binders); 474 let substs = substs.shift_bound_vars(ctx.in_binders);
474 // FIXME handle type parameters on the segment 475 // FIXME handle type parameters on the segment
475 return Some(Ty::Projection(ProjectionTy { 476 return Some(Ty::Alias(AliasTy::Projection(ProjectionTy {
476 associated_ty, 477 associated_ty,
477 parameters: substs, 478 parameters: substs,
478 })); 479 })));
479 } 480 }
480 481
481 None 482 None
@@ -676,7 +677,7 @@ impl GenericPredicate {
676 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id), 677 TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
677 TypeParamLoweringMode::Variable => { 678 TypeParamLoweringMode::Variable => {
678 let idx = generics.param_idx(param_id).expect("matching generics"); 679 let idx = generics.param_idx(param_id).expect("matching generics");
679 Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx)) 680 Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
680 } 681 }
681 } 682 }
682 } 683 }
@@ -750,7 +751,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
750 preds.extend(GenericPredicate::from_type_bound( 751 preds.extend(GenericPredicate::from_type_bound(
751 ctx, 752 ctx,
752 bound, 753 bound,
753 Ty::Projection(projection_ty.clone()), 754 Ty::Alias(AliasTy::Projection(projection_ty.clone())),
754 )); 755 ));
755 } 756 }
756 preds 757 preds
@@ -760,7 +761,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
760impl ReturnTypeImplTrait { 761impl ReturnTypeImplTrait {
761 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self { 762 fn from_hir(ctx: &TyLoweringContext, bounds: &[TypeBound]) -> Self {
762 mark::hit!(lower_rpit); 763 mark::hit!(lower_rpit);
763 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 764 let self_ty = Ty::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0));
764 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| { 765 let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
765 bounds 766 bounds
766 .iter() 767 .iter()
@@ -984,7 +985,7 @@ pub(crate) fn generic_defaults_query(
984 // Each default can only refer to previous parameters. 985 // Each default can only refer to previous parameters.
985 ty.walk_mut_binders( 986 ty.walk_mut_binders(
986 &mut |ty, binders| match ty { 987 &mut |ty, binders| match ty {
987 Ty::Bound(BoundVar { debruijn, index }) if *debruijn == binders => { 988 Ty::BoundVar(BoundVar { debruijn, index }) if *debruijn == binders => {
988 if *index >= idx { 989 if *index >= idx {
989 // type variable default referring to parameter coming 990 // type variable default referring to parameter coming
990 // after it. This is forbidden (FIXME: report 991 // after it. This is forbidden (FIXME: report
@@ -1017,7 +1018,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1017 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1018 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1018 let generics = generics(db.upcast(), def.into()); 1019 let generics = generics(db.upcast(), def.into());
1019 let num_binders = generics.len(); 1020 let num_binders = generics.len();
1020 Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) 1021 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
1021} 1022}
1022 1023
1023/// Build the declared type of a function. This should not need to look at the 1024/// Build the declared type of a function. This should not need to look at the
@@ -1025,7 +1026,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1026fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1026 let generics = generics(db.upcast(), def.into()); 1027 let generics = generics(db.upcast(), def.into());
1027 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1028 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1028 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1029 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1029} 1030}
1030 1031
1031/// Build the declared type of a const. 1032/// Build the declared type of a const.
@@ -1057,7 +1058,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1057 let params = 1058 let params =
1058 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1059 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1059 let ret = type_for_adt(db, def.into()); 1060 let ret = type_for_adt(db, def.into());
1060 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1061 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1061} 1062}
1062 1063
1063/// Build the type of a tuple struct constructor. 1064/// Build the type of a tuple struct constructor.
@@ -1068,7 +1069,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1068 } 1069 }
1069 let generics = generics(db.upcast(), def.into()); 1070 let generics = generics(db.upcast(), def.into());
1070 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1071 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1071 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1072 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1072} 1073}
1073 1074
1074fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1075fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1081,7 +1082,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1081 let params = 1082 let params =
1082 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1083 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1083 let ret = type_for_adt(db, def.parent.into()); 1084 let ret = type_for_adt(db, def.parent.into());
1084 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1085 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1085} 1086}
1086 1087
1087/// Build the type of a tuple enum variant constructor. 1088/// Build the type of a tuple enum variant constructor.
@@ -1093,13 +1094,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1093 } 1094 }
1094 let generics = generics(db.upcast(), def.parent.into()); 1095 let generics = generics(db.upcast(), def.parent.into());
1095 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1096 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1096 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1097 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1097} 1098}
1098 1099
1099fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1100fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1100 let generics = generics(db.upcast(), adt.into()); 1101 let generics = generics(db.upcast(), adt.into());
1101 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1102 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1102 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) 1103 Binders::new(substs.len(), Ty::Adt(adt, substs))
1103} 1104}
1104 1105
1105fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1106fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1107,10 +1108,10 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1107 let resolver = t.resolver(db.upcast()); 1108 let resolver = t.resolver(db.upcast());
1108 let ctx = 1109 let ctx =
1109 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1110 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1111 if db.type_alias_data(t).is_extern { 1111 if db.type_alias_data(t).is_extern {
1112 Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) 1112 Binders::new(0, Ty::ForeignType(t))
1113 } else { 1113 } else {
1114 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1114 let type_ref = &db.type_alias_data(t).type_ref; 1115 let type_ref = &db.type_alias_data(t).type_ref;
1115 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error)); 1116 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
1116 Binders::new(substs.len(), inner) 1117 Binders::new(substs.len(), inner)
@@ -1259,3 +1260,10 @@ pub(crate) fn return_type_impl_traits(
1259 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits))) 1260 Some(Arc::new(Binders::new(num_binders, return_type_impl_traits)))
1260 } 1261 }
1261} 1262}
1263
1264pub(crate) fn lower_to_chalk_mutability(m: hir_def::type_ref::Mutability) -> Mutability {
1265 match m {
1266 hir_def::type_ref::Mutability::Shared => Mutability::Not,
1267 hir_def::type_ref::Mutability::Mut => Mutability::Mut,
1268 }
1269}
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index b3d1fe9a4..f301a8477 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -6,12 +6,10 @@ use std::{iter, sync::Arc};
6 6
7use arrayvec::ArrayVec; 7use arrayvec::ArrayVec;
8use base_db::CrateId; 8use base_db::CrateId;
9use chalk_ir::Mutability;
9use hir_def::{ 10use hir_def::{
10 builtin_type::{IntBitness, Signedness}, 11 lang_item::LangItemTarget, AdtId, AssocContainerId, AssocItemId, FunctionId, GenericDefId,
11 lang_item::LangItemTarget, 12 HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId,
12 type_ref::Mutability,
13 AssocContainerId, AssocItemId, FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId,
14 TraitId,
15}; 13};
16use hir_expand::name::Name; 14use hir_expand::name::Name;
17use rustc_hash::{FxHashMap, FxHashSet}; 15use rustc_hash::{FxHashMap, FxHashSet};
@@ -19,17 +17,26 @@ use rustc_hash::{FxHashMap, FxHashSet};
19use crate::{ 17use crate::{
20 autoderef, 18 autoderef,
21 db::HirDatabase, 19 db::HirDatabase,
22 primitive::{FloatBitness, FloatTy, IntTy}, 20 primitive::{self, FloatTy, IntTy, UintTy},
23 utils::all_super_traits, 21 utils::all_super_traits,
24 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Substs, TraitEnvironment, TraitRef, Ty, 22 Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment,
25 TyKind, TypeCtor, TypeWalk, 23 TraitRef, Ty, TypeWalk,
26}; 24};
27 25
28/// This is used as a key for indexing impls. 26/// This is used as a key for indexing impls.
29#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 27#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30pub enum TyFingerprint { 28pub enum TyFingerprint {
31 Apply(TypeCtor), 29 Str,
30 Slice,
31 Array,
32 Never,
33 RawPtr(Mutability),
34 Scalar(Scalar),
35 Adt(AdtId),
32 Dyn(TraitId), 36 Dyn(TraitId),
37 Tuple(usize),
38 ForeignType(TypeAliasId),
39 FnPtr(usize, FnSig),
33} 40}
34 41
35impl TyFingerprint { 42impl TyFingerprint {
@@ -37,68 +44,42 @@ impl TyFingerprint {
37 /// have impls: if we have some `struct S`, we can have an `impl S`, but not 44 /// have impls: if we have some `struct S`, we can have an `impl S`, but not
38 /// `impl &S`. Hence, this will return `None` for reference types and such. 45 /// `impl &S`. Hence, this will return `None` for reference types and such.
39 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 46 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
40 match ty { 47 let fp = match ty {
41 Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), 48 &Ty::Str => TyFingerprint::Str,
42 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), 49 &Ty::Never => TyFingerprint::Never,
43 _ => None, 50 &Ty::Slice(..) => TyFingerprint::Slice,
44 } 51 &Ty::Array(..) => TyFingerprint::Array,
52 &Ty::Scalar(scalar) => TyFingerprint::Scalar(scalar),
53 &Ty::Adt(adt, _) => TyFingerprint::Adt(adt),
54 &Ty::Tuple(cardinality, _) => TyFingerprint::Tuple(cardinality),
55 &Ty::Raw(mutability, ..) => TyFingerprint::RawPtr(mutability),
56 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
57 &Ty::Function(FnPointer { num_args, sig, .. }) => TyFingerprint::FnPtr(num_args, sig),
58 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
59 _ => return None,
60 };
61 Some(fp)
45 } 62 }
46} 63}
47 64
48pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 65pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
49 TyFingerprint::Apply(TypeCtor::Int(IntTy { 66 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
50 signedness: Signedness::Unsigned, 67 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
51 bitness: IntBitness::X8, 68 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
52 })), 69 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
53 TyFingerprint::Apply(TypeCtor::Int(IntTy { 70 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
54 signedness: Signedness::Unsigned, 71 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
55 bitness: IntBitness::X16, 72 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
56 })), 73 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
57 TyFingerprint::Apply(TypeCtor::Int(IntTy { 74 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
58 signedness: Signedness::Unsigned, 75 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
59 bitness: IntBitness::X32, 76 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
60 })), 77 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
61 TyFingerprint::Apply(TypeCtor::Int(IntTy {
62 signedness: Signedness::Unsigned,
63 bitness: IntBitness::X64,
64 })),
65 TyFingerprint::Apply(TypeCtor::Int(IntTy {
66 signedness: Signedness::Unsigned,
67 bitness: IntBitness::X128,
68 })),
69 TyFingerprint::Apply(TypeCtor::Int(IntTy {
70 signedness: Signedness::Unsigned,
71 bitness: IntBitness::Xsize,
72 })),
73 TyFingerprint::Apply(TypeCtor::Int(IntTy {
74 signedness: Signedness::Signed,
75 bitness: IntBitness::X8,
76 })),
77 TyFingerprint::Apply(TypeCtor::Int(IntTy {
78 signedness: Signedness::Signed,
79 bitness: IntBitness::X16,
80 })),
81 TyFingerprint::Apply(TypeCtor::Int(IntTy {
82 signedness: Signedness::Signed,
83 bitness: IntBitness::X32,
84 })),
85 TyFingerprint::Apply(TypeCtor::Int(IntTy {
86 signedness: Signedness::Signed,
87 bitness: IntBitness::X64,
88 })),
89 TyFingerprint::Apply(TypeCtor::Int(IntTy {
90 signedness: Signedness::Signed,
91 bitness: IntBitness::X128,
92 })),
93 TyFingerprint::Apply(TypeCtor::Int(IntTy {
94 signedness: Signedness::Signed,
95 bitness: IntBitness::Xsize,
96 })),
97]; 78];
98 79
99pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 80pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
100 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 })), 81 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
101 TyFingerprint::Apply(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 })), 82 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
102]; 83];
103 84
104/// Trait impls defined or available in some crate. 85/// Trait impls defined or available in some crate.
@@ -250,27 +231,29 @@ impl Ty {
250 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 231 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
251 232
252 let lang_item_targets = match self { 233 let lang_item_targets = match self {
253 Ty::Apply(a_ty) => match a_ty.ctor { 234 Ty::Adt(def_id, _) => {
254 TypeCtor::Adt(def_id) => { 235 return mod_to_crate_ids(def_id.module(db.upcast()));
255 return mod_to_crate_ids(def_id.module(db.upcast())); 236 }
256 } 237 Ty::ForeignType(type_alias_id) => {
257 TypeCtor::ForeignType(type_alias_id) => { 238 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
258 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 239 }
259 } 240 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
260 TypeCtor::Bool => lang_item_crate!("bool"), 241 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"),
261 TypeCtor::Char => lang_item_crate!("char"), 242 Ty::Scalar(Scalar::Float(f)) => match f {
262 TypeCtor::Float(f) => match f.bitness { 243 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
263 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 244 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
264 FloatBitness::X32 => lang_item_crate!("f32", "f32_runtime"), 245 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
265 FloatBitness::X64 => lang_item_crate!("f64", "f64_runtime"),
266 },
267 TypeCtor::Int(i) => lang_item_crate!(i.ty_to_string()),
268 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
269 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
270 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
271 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
272 _ => return None,
273 }, 246 },
247 &Ty::Scalar(Scalar::Int(t)) => {
248 lang_item_crate!(primitive::int_ty_to_string(t))
249 }
250 &Ty::Scalar(Scalar::Uint(t)) => {
251 lang_item_crate!(primitive::uint_ty_to_string(t))
252 }
253 Ty::Str => lang_item_crate!("str_alloc", "str"),
254 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
255 Ty::Raw(Mutability::Not, _) => lang_item_crate!("const_ptr"),
256 Ty::Raw(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
274 Ty::Dyn(_) => { 257 Ty::Dyn(_) => {
275 return self.dyn_trait().and_then(|trait_| { 258 return self.dyn_trait().and_then(|trait_| {
276 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 259 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
@@ -447,7 +430,7 @@ fn iterate_method_candidates_with_autoref(
447 } 430 }
448 let refed = Canonical { 431 let refed = Canonical {
449 kinds: deref_chain[0].kinds.clone(), 432 kinds: deref_chain[0].kinds.clone(),
450 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), 433 value: Ty::Ref(Mutability::Not, Substs::single(deref_chain[0].value.clone())),
451 }; 434 };
452 if iterate_method_candidates_by_receiver( 435 if iterate_method_candidates_by_receiver(
453 &refed, 436 &refed,
@@ -463,7 +446,7 @@ fn iterate_method_candidates_with_autoref(
463 } 446 }
464 let ref_muted = Canonical { 447 let ref_muted = Canonical {
465 kinds: deref_chain[0].kinds.clone(), 448 kinds: deref_chain[0].kinds.clone(),
466 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), 449 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())),
467 }; 450 };
468 if iterate_method_candidates_by_receiver( 451 if iterate_method_candidates_by_receiver(
469 &ref_muted, 452 &ref_muted,
@@ -685,7 +668,7 @@ pub(crate) fn inherent_impl_substs(
685 .build(); 668 .build();
686 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 669 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
687 let mut kinds = self_ty.kinds.to_vec(); 670 let mut kinds = self_ty.kinds.to_vec();
688 kinds.extend(iter::repeat(TyKind::General).take(vars.len())); 671 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(vars.len()));
689 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) }; 672 let tys = Canonical { kinds: kinds.into(), value: (self_ty_with_vars, self_ty.value.clone()) };
690 let substs = super::infer::unify(&tys); 673 let substs = super::infer::unify(&tys);
691 // We only want the substs for the vars we added, not the ones from self_ty. 674 // We only want the substs for the vars we added, not the ones from self_ty.
@@ -701,7 +684,7 @@ pub(crate) fn inherent_impl_substs(
701fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs { 684fn fallback_bound_vars(s: Substs, num_vars_to_keep: usize) -> Substs {
702 s.fold_binders( 685 s.fold_binders(
703 &mut |ty, binders| { 686 &mut |ty, binders| {
704 if let Ty::Bound(bound) = &ty { 687 if let Ty::BoundVar(bound) = &ty {
705 if bound.index >= num_vars_to_keep && bound.debruijn >= binders { 688 if bound.index >= num_vars_to_keep && bound.debruijn >= binders {
706 Ty::Unknown 689 Ty::Unknown
707 } else { 690 } else {
@@ -777,7 +760,7 @@ fn generic_implements_goal(
777 .push(self_ty.value) 760 .push(self_ty.value)
778 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 761 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
779 .build(); 762 .build();
780 kinds.extend(iter::repeat(TyKind::General).take(substs.len() - 1)); 763 kinds.extend(iter::repeat(chalk_ir::TyVariableKind::General).take(substs.len() - 1));
781 let trait_ref = TraitRef { trait_, substs }; 764 let trait_ref = TraitRef { trait_, substs };
782 let obligation = super::Obligation::Trait(trait_ref); 765 let obligation = super::Obligation::Trait(trait_ref);
783 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) } 766 Canonical { kinds: kinds.into(), value: InEnvironment::new(env, obligation) }
@@ -790,11 +773,9 @@ fn autoderef_method_receiver(
790) -> Vec<Canonical<Ty>> { 773) -> Vec<Canonical<Ty>> {
791 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 774 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect();
792 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!) 775 // As a last step, we can do array unsizing (that's the only unsizing that rustc does for method receivers!)
793 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = 776 if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) {
794 deref_chain.last().map(|ty| &ty.value)
795 {
796 let kinds = deref_chain.last().unwrap().kinds.clone(); 777 let kinds = deref_chain.last().unwrap().kinds.clone();
797 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 778 let unsized_ty = Ty::Slice(parameters.clone());
798 deref_chain.push(Canonical { value: unsized_ty, kinds }) 779 deref_chain.push(Canonical { value: unsized_ty, kinds })
799 } 780 }
800 deref_chain 781 deref_chain
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index 0870874fc..bb9b8bbfc 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -1,27 +1,27 @@
1//! Helper functions for binary operator type inference. 1//! Helper functions for binary operator type inference.
2use chalk_ir::TyVariableKind;
2use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 3use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
3 4
4use super::{InferTy, Ty, TypeCtor}; 5use crate::{Scalar, Ty};
5use crate::ApplicationTy;
6 6
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 8 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Bool), 9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool),
10 BinaryOp::Assignment { .. } => Ty::unit(), 10 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { 11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 12 Ty::Scalar(Scalar::Int(_))
13 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, 13 | Ty::Scalar(Scalar::Uint(_))
14 _ => Ty::Unknown, 14 | Ty::Scalar(Scalar::Float(_)) => lhs_ty,
15 }, 15 Ty::InferenceVar(_, TyVariableKind::Integer)
16 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 16 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
17 _ => Ty::Unknown, 17 _ => Ty::Unknown,
18 }, 18 },
19 BinaryOp::ArithOp(_) => match rhs_ty { 19 BinaryOp::ArithOp(_) => match rhs_ty {
20 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 20 Ty::Scalar(Scalar::Int(_))
21 TypeCtor::Int(..) | TypeCtor::Float(..) => rhs_ty, 21 | Ty::Scalar(Scalar::Uint(_))
22 _ => Ty::Unknown, 22 | Ty::Scalar(Scalar::Float(_)) => rhs_ty,
23 }, 23 Ty::InferenceVar(_, TyVariableKind::Integer)
24 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 24 | Ty::InferenceVar(_, TyVariableKind::Float) => rhs_ty,
25 _ => Ty::Unknown, 25 _ => Ty::Unknown,
26 }, 26 },
27 } 27 }
@@ -29,29 +29,23 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
29 29
30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 30pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
31 match op { 31 match op {
32 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Bool), 32 BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool),
33 BinaryOp::Assignment { op: None } => lhs_ty, 33 BinaryOp::Assignment { op: None } => lhs_ty,
34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 34 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty {
35 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 35 Ty::Scalar(_) | Ty::Str => lhs_ty,
36 TypeCtor::Int(..) 36 Ty::InferenceVar(_, TyVariableKind::Integer)
37 | TypeCtor::Float(..) 37 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
38 | TypeCtor::Str
39 | TypeCtor::Char
40 | TypeCtor::Bool => lhs_ty,
41 _ => Ty::Unknown,
42 },
43 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
44 _ => Ty::Unknown, 38 _ => Ty::Unknown,
45 }, 39 },
46 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown, 40 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => Ty::Unknown,
47 BinaryOp::CmpOp(CmpOp::Ord { .. }) 41 BinaryOp::CmpOp(CmpOp::Ord { .. })
48 | BinaryOp::Assignment { op: Some(_) } 42 | BinaryOp::Assignment { op: Some(_) }
49 | BinaryOp::ArithOp(_) => match lhs_ty { 43 | BinaryOp::ArithOp(_) => match lhs_ty {
50 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 44 Ty::Scalar(Scalar::Int(_))
51 TypeCtor::Int(..) | TypeCtor::Float(..) => lhs_ty, 45 | Ty::Scalar(Scalar::Uint(_))
52 _ => Ty::Unknown, 46 | Ty::Scalar(Scalar::Float(_)) => lhs_ty,
53 }, 47 Ty::InferenceVar(_, TyVariableKind::Integer)
54 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 48 | Ty::InferenceVar(_, TyVariableKind::Float) => lhs_ty,
55 _ => Ty::Unknown, 49 _ => Ty::Unknown,
56 }, 50 },
57 } 51 }
diff --git a/crates/hir_ty/src/primitive.rs b/crates/hir_ty/src/primitive.rs
index 37966b709..2449addfb 100644
--- a/crates/hir_ty/src/primitive.rs
+++ b/crates/hir_ty/src/primitive.rs
@@ -3,137 +3,63 @@
3//! * during type inference, they can be uncertain (ie, `let x = 92;`) 3//! * during type inference, they can be uncertain (ie, `let x = 92;`)
4//! * they don't belong to any particular crate. 4//! * they don't belong to any particular crate.
5 5
6use std::fmt; 6pub use chalk_ir::{FloatTy, IntTy, UintTy};
7 7pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint};
8pub use hir_def::builtin_type::{BuiltinFloat, BuiltinInt, FloatBitness, IntBitness, Signedness}; 8
9 9pub fn int_ty_to_string(ty: IntTy) -> &'static str {
10#[derive(Copy, Clone, Eq, PartialEq, Hash)] 10 match ty {
11pub struct IntTy { 11 IntTy::Isize => "isize",
12 pub signedness: Signedness, 12 IntTy::I8 => "i8",
13 pub bitness: IntBitness, 13 IntTy::I16 => "i16",
14} 14 IntTy::I32 => "i32",
15 15 IntTy::I64 => "i64",
16impl fmt::Debug for IntTy { 16 IntTy::I128 => "i128",
17 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18 fmt::Display::fmt(self, f)
19 }
20}
21
22impl fmt::Display for IntTy {
23 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
24 write!(f, "{}", self.ty_to_string())
25 }
26}
27
28impl IntTy {
29 pub fn isize() -> IntTy {
30 IntTy { signedness: Signedness::Signed, bitness: IntBitness::Xsize }
31 }
32
33 pub fn i8() -> IntTy {
34 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X8 }
35 }
36
37 pub fn i16() -> IntTy {
38 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X16 }
39 }
40
41 pub fn i32() -> IntTy {
42 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X32 }
43 }
44
45 pub fn i64() -> IntTy {
46 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X64 }
47 }
48
49 pub fn i128() -> IntTy {
50 IntTy { signedness: Signedness::Signed, bitness: IntBitness::X128 }
51 } 17 }
52
53 pub fn usize() -> IntTy {
54 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::Xsize }
55 }
56
57 pub fn u8() -> IntTy {
58 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X8 }
59 }
60
61 pub fn u16() -> IntTy {
62 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X16 }
63 }
64
65 pub fn u32() -> IntTy {
66 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X32 }
67 }
68
69 pub fn u64() -> IntTy {
70 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X64 }
71 }
72
73 pub fn u128() -> IntTy {
74 IntTy { signedness: Signedness::Unsigned, bitness: IntBitness::X128 }
75 }
76
77 pub fn ty_to_string(self) -> &'static str {
78 match (self.signedness, self.bitness) {
79 (Signedness::Signed, IntBitness::Xsize) => "isize",
80 (Signedness::Signed, IntBitness::X8) => "i8",
81 (Signedness::Signed, IntBitness::X16) => "i16",
82 (Signedness::Signed, IntBitness::X32) => "i32",
83 (Signedness::Signed, IntBitness::X64) => "i64",
84 (Signedness::Signed, IntBitness::X128) => "i128",
85 (Signedness::Unsigned, IntBitness::Xsize) => "usize",
86 (Signedness::Unsigned, IntBitness::X8) => "u8",
87 (Signedness::Unsigned, IntBitness::X16) => "u16",
88 (Signedness::Unsigned, IntBitness::X32) => "u32",
89 (Signedness::Unsigned, IntBitness::X64) => "u64",
90 (Signedness::Unsigned, IntBitness::X128) => "u128",
91 }
92 }
93}
94
95#[derive(Copy, Clone, PartialEq, Eq, Hash)]
96pub struct FloatTy {
97 pub bitness: FloatBitness,
98} 18}
99 19
100impl fmt::Debug for FloatTy { 20pub fn uint_ty_to_string(ty: UintTy) -> &'static str {
101 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 21 match ty {
102 fmt::Display::fmt(self, f) 22 UintTy::Usize => "usize",
23 UintTy::U8 => "u8",
24 UintTy::U16 => "u16",
25 UintTy::U32 => "u32",
26 UintTy::U64 => "u64",
27 UintTy::U128 => "u128",
103 } 28 }
104} 29}
105 30
106impl fmt::Display for FloatTy { 31pub fn float_ty_to_string(ty: FloatTy) -> &'static str {
107 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 32 match ty {
108 write!(f, "{}", self.ty_to_string()) 33 FloatTy::F32 => "f32",
34 FloatTy::F64 => "f64",
109 } 35 }
110} 36}
111 37
112impl FloatTy { 38pub(super) fn int_ty_from_builtin(t: BuiltinInt) -> IntTy {
113 pub fn f32() -> FloatTy { 39 match t {
114 FloatTy { bitness: FloatBitness::X32 } 40 BuiltinInt::Isize => IntTy::Isize,
115 } 41 BuiltinInt::I8 => IntTy::I8,
116 42 BuiltinInt::I16 => IntTy::I16,
117 pub fn f64() -> FloatTy { 43 BuiltinInt::I32 => IntTy::I32,
118 FloatTy { bitness: FloatBitness::X64 } 44 BuiltinInt::I64 => IntTy::I64,
119 } 45 BuiltinInt::I128 => IntTy::I128,
120
121 pub fn ty_to_string(self) -> &'static str {
122 match self.bitness {
123 FloatBitness::X32 => "f32",
124 FloatBitness::X64 => "f64",
125 }
126 } 46 }
127} 47}
128 48
129impl From<BuiltinInt> for IntTy { 49pub(super) fn uint_ty_from_builtin(t: BuiltinUint) -> UintTy {
130 fn from(t: BuiltinInt) -> Self { 50 match t {
131 IntTy { signedness: t.signedness, bitness: t.bitness } 51 BuiltinUint::Usize => UintTy::Usize,
52 BuiltinUint::U8 => UintTy::U8,
53 BuiltinUint::U16 => UintTy::U16,
54 BuiltinUint::U32 => UintTy::U32,
55 BuiltinUint::U64 => UintTy::U64,
56 BuiltinUint::U128 => UintTy::U128,
132 } 57 }
133} 58}
134 59
135impl From<BuiltinFloat> for FloatTy { 60pub(super) fn float_ty_from_builtin(t: BuiltinFloat) -> FloatTy {
136 fn from(t: BuiltinFloat) -> Self { 61 match t {
137 FloatTy { bitness: t.bitness } 62 BuiltinFloat::F32 => FloatTy::F32,
63 BuiltinFloat::F64 => FloatTy::F64,
138 } 64 }
139} 65}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 12ec4657b..2947857a5 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -2491,3 +2491,58 @@ fn inner_use_enum_rename() {
2491 "#]], 2491 "#]],
2492 ) 2492 )
2493} 2493}
2494
2495#[test]
2496fn box_into_vec() {
2497 check_infer(
2498 r#"
2499#[lang = "sized"]
2500pub trait Sized {}
2501
2502#[lang = "unsize"]
2503pub trait Unsize<T: ?Sized> {}
2504
2505#[lang = "coerce_unsized"]
2506pub trait CoerceUnsized<T> {}
2507
2508pub unsafe trait Allocator {}
2509
2510pub struct Global;
2511unsafe impl Allocator for Global {}
2512
2513#[lang = "owned_box"]
2514#[fundamental]
2515pub struct Box<T: ?Sized, A: Allocator = Global>;
2516
2517impl<T: ?Sized + Unsize<U>, U: ?Sized, A: Allocator> CoerceUnsized<Box<U, A>> for Box<T, A> {}
2518
2519pub struct Vec<T, A: Allocator = Global> {}
2520
2521#[lang = "slice"]
2522impl<T> [T] {}
2523
2524#[lang = "slice_alloc"]
2525impl<T> [T] {
2526 pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
2527 unimplemented!()
2528 }
2529}
2530
2531fn test() {
2532 let vec = <[_]>::into_vec(box [1i32]);
2533}
2534"#,
2535 expect![[r#"
2536 569..573 'self': Box<[T], A>
2537 602..634 '{ ... }': Vec<T, A>
2538 612..628 'unimpl...ted!()': Vec<T, A>
2539 648..694 '{ ...2]); }': ()
2540 658..661 'vec': Vec<i32, Global>
2541 664..679 '<[_]>::into_vec': fn into_vec<i32, Global>(Box<[i32], Global>) -> Vec<i32, Global>
2542 664..691 '<[_]>:...1i32])': Vec<i32, Global>
2543 680..690 'box [1i32]': Box<[i32; _], Global>
2544 684..690 '[1i32]': [i32; _]
2545 685..689 '1i32': i32
2546 "#]],
2547 )
2548}
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index dfa51896b..e4cdb6d53 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -129,7 +129,7 @@ pub(crate) fn trait_solve_query(
129 log::info!("trait_solve_query({})", goal.value.value.display(db)); 129 log::info!("trait_solve_query({})", goal.value.value.display(db));
130 130
131 if let Obligation::Projection(pred) = &goal.value.value { 131 if let Obligation::Projection(pred) = &goal.value.value {
132 if let Ty::Bound(_) = &pred.projection_ty.parameters[0] { 132 if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] {
133 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 133 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
134 return Some(Solution::Ambig(Guidance::Unknown)); 134 return Some(Solution::Ambig(Guidance::Unknown));
135 } 135 }
diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index d74c83737..e513fa8f4 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -19,8 +19,8 @@ use crate::{
19 display::HirDisplay, 19 display::HirDisplay,
20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS}, 20 method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
21 utils::generics, 21 utils::generics,
22 BoundVar, CallableDefId, DebruijnIndex, FnSig, GenericPredicate, ProjectionPredicate, 22 BoundVar, CallableDefId, CallableSig, DebruijnIndex, GenericPredicate, ProjectionPredicate,
23 ProjectionTy, Substs, TraitRef, Ty, TypeCtor, 23 ProjectionTy, Substs, TraitRef, Ty,
24}; 24};
25use mapping::{ 25use mapping::{
26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType, 26 convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsAssocType,
@@ -90,7 +90,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
90 ty: &Ty, 90 ty: &Ty,
91 binders: &CanonicalVarKinds<Interner>, 91 binders: &CanonicalVarKinds<Interner>,
92 ) -> Option<chalk_ir::TyVariableKind> { 92 ) -> Option<chalk_ir::TyVariableKind> {
93 if let Ty::Bound(bv) = ty { 93 if let Ty::BoundVar(bv) = ty {
94 let binders = binders.as_slice(&Interner); 94 let binders = binders.as_slice(&Interner);
95 if bv.debruijn == DebruijnIndex::INNERMOST { 95 if bv.debruijn == DebruijnIndex::INNERMOST {
96 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind { 96 if let chalk_ir::VariableKind::Ty(tk) = binders[bv.index].kind {
@@ -220,18 +220,18 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
220 let impl_bound = GenericPredicate::Implemented(TraitRef { 220 let impl_bound = GenericPredicate::Implemented(TraitRef {
221 trait_: future_trait, 221 trait_: future_trait,
222 // Self type as the first parameter. 222 // Self type as the first parameter.
223 substs: Substs::single(Ty::Bound(BoundVar { 223 substs: Substs::single(Ty::BoundVar(BoundVar {
224 debruijn: DebruijnIndex::INNERMOST, 224 debruijn: DebruijnIndex::INNERMOST,
225 index: 0, 225 index: 0,
226 })), 226 })),
227 }); 227 });
228 let proj_bound = GenericPredicate::Projection(ProjectionPredicate { 228 let proj_bound = GenericPredicate::Projection(ProjectionPredicate {
229 // The parameter of the opaque type. 229 // The parameter of the opaque type.
230 ty: Ty::Bound(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }), 230 ty: Ty::BoundVar(BoundVar { debruijn: DebruijnIndex::ONE, index: 0 }),
231 projection_ty: ProjectionTy { 231 projection_ty: ProjectionTy {
232 associated_ty: future_output, 232 associated_ty: future_output,
233 // Self type as the first parameter. 233 // Self type as the first parameter.
234 parameters: Substs::single(Ty::Bound(BoundVar::new( 234 parameters: Substs::single(Ty::BoundVar(BoundVar::new(
235 DebruijnIndex::INNERMOST, 235 DebruijnIndex::INNERMOST,
236 0, 236 0,
237 ))), 237 ))),
@@ -286,9 +286,8 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
286 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> { 286 ) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
287 let sig_ty: Ty = 287 let sig_ty: Ty =
288 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone()); 288 from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
289 let sig = FnSig::from_fn_ptr_substs( 289 let sig = CallableSig::from_substs(
290 &sig_ty.substs().expect("first closure param should be fn ptr"), 290 &sig_ty.substs().expect("first closure param should be fn ptr"),
291 false,
292 ); 291 );
293 let io = rust_ir::FnDefInputsAndOutputDatum { 292 let io = rust_ir::FnDefInputsAndOutputDatum {
294 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(), 293 argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
@@ -393,7 +392,7 @@ pub(crate) fn associated_ty_data_query(
393 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast()); 392 let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
394 let ctx = crate::TyLoweringContext::new(db, &resolver) 393 let ctx = crate::TyLoweringContext::new(db, &resolver)
395 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable); 394 .with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
396 let self_ty = Ty::Bound(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0)); 395 let self_ty = Ty::BoundVar(crate::BoundVar::new(crate::DebruijnIndex::INNERMOST, 0));
397 let bounds = type_alias_data 396 let bounds = type_alias_data
398 .bounds 397 .bounds
399 .iter() 398 .iter()
@@ -489,10 +488,11 @@ pub(crate) fn struct_datum_query(
489 struct_id: AdtId, 488 struct_id: AdtId,
490) -> Arc<StructDatum> { 489) -> Arc<StructDatum> {
491 debug!("struct_datum {:?}", struct_id); 490 debug!("struct_datum {:?}", struct_id);
492 let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id)); 491 let adt_id = from_chalk(db, struct_id);
492 let type_ctor = Ty::Adt(adt_id, Substs::empty());
493 debug!("struct {:?} = {:?}", struct_id, type_ctor); 493 debug!("struct {:?} = {:?}", struct_id, type_ctor);
494 let num_params = type_ctor.num_ty_params(db); 494 let num_params = generics(db.upcast(), adt_id.into()).len();
495 let upstream = type_ctor.krate(db) != Some(krate); 495 let upstream = adt_id.module(db.upcast()).krate() != krate;
496 let where_clauses = type_ctor 496 let where_clauses = type_ctor
497 .as_generic_def() 497 .as_generic_def()
498 .map(|generic_def| { 498 .map(|generic_def| {
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index 8700d664e..db1760e6c 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -4,20 +4,20 @@
4//! conversions. 4//! conversions.
5 5
6use chalk_ir::{ 6use chalk_ir::{
7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex, Scalar, 7 cast::Cast, fold::shift::Shift, interner::HasInterner, LifetimeData, PlaceholderIndex,
8 UniverseIndex, 8 UniverseIndex,
9}; 9};
10use chalk_solve::rust_ir; 10use chalk_solve::rust_ir;
11 11
12use base_db::salsa::InternKey; 12use base_db::salsa::InternKey;
13use hir_def::{type_ref::Mutability, AssocContainerId, GenericDefId, Lookup, TypeAliasId}; 13use hir_def::{AssocContainerId, GenericDefId, Lookup, TypeAliasId};
14 14
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::{FloatBitness, FloatTy, IntBitness, IntTy, Signedness}, 17 primitive::UintTy,
18 traits::{Canonical, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 19 AliasTy, CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy,
20 ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TyKind, TypeCtor, 20 OpaqueTyId, ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty,
21}; 21};
22 22
23use super::interner::*; 23use super::interner::*;
@@ -27,88 +27,68 @@ impl ToChalk for Ty {
27 type Chalk = chalk_ir::Ty<Interner>; 27 type Chalk = chalk_ir::Ty<Interner>;
28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
29 match self { 29 match self {
30 Ty::Apply(apply_ty) => match apply_ty.ctor { 30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters),
31 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), 31 Ty::Array(parameters) => array_to_chalk(db, parameters),
32 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), 32 Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => {
33 TypeCtor::FnPtr { num_args: _, is_varargs } => { 33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
34 let substitution = 34 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
35 chalk_ir::FnSubst(apply_ty.parameters.to_chalk(db).shifted_in(&Interner)); 35 num_binders: 0,
36 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 36 sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic },
37 num_binders: 0, 37 substitution,
38 sig: chalk_ir::FnSig { 38 })
39 abi: (), 39 .intern(&Interner)
40 safety: chalk_ir::Safety::Safe, 40 }
41 variadic: is_varargs, 41 Ty::AssociatedType(type_alias, substs) => {
42 }, 42 let assoc_type = TypeAliasAsAssocType(type_alias);
43 substitution, 43 let assoc_type_id = assoc_type.to_chalk(db);
44 }) 44 let substitution = substs.to_chalk(db);
45 .intern(&Interner) 45 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
46 } 46 }
47 TypeCtor::AssociatedType(type_alias) => {
48 let assoc_type = TypeAliasAsAssocType(type_alias);
49 let assoc_type_id = assoc_type.to_chalk(db);
50 let substitution = apply_ty.parameters.to_chalk(db);
51 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
52 }
53 47
54 TypeCtor::OpaqueType(impl_trait_id) => { 48 Ty::OpaqueType(impl_trait_id, substs) => {
55 let id = impl_trait_id.to_chalk(db); 49 let id = impl_trait_id.to_chalk(db);
56 let substitution = apply_ty.parameters.to_chalk(db); 50 let substitution = substs.to_chalk(db);
57 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) 51 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
58 } 52 }
59 53
60 TypeCtor::ForeignType(type_alias) => { 54 Ty::ForeignType(type_alias) => {
61 let foreign_type = TypeAliasAsForeignType(type_alias); 55 let foreign_type = TypeAliasAsForeignType(type_alias);
62 let foreign_type_id = foreign_type.to_chalk(db); 56 let foreign_type_id = foreign_type.to_chalk(db);
63 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) 57 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
64 } 58 }
65 59
66 TypeCtor::Bool => chalk_ir::TyKind::Scalar(Scalar::Bool).intern(&Interner), 60 Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
67 TypeCtor::Char => chalk_ir::TyKind::Scalar(Scalar::Char).intern(&Interner),
68 TypeCtor::Int(int_ty) => {
69 chalk_ir::TyKind::Scalar(int_ty_to_chalk(int_ty)).intern(&Interner)
70 }
71 TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }) => {
72 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32))
73 .intern(&Interner)
74 }
75 TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }) => {
76 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64))
77 .intern(&Interner)
78 }
79 61
80 TypeCtor::Tuple { cardinality } => { 62 Ty::Tuple(cardinality, substs) => {
81 let substitution = apply_ty.parameters.to_chalk(db); 63 let substitution = substs.to_chalk(db);
82 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 64 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
83 } 65 }
84 TypeCtor::RawPtr(mutability) => { 66 Ty::Raw(mutability, substs) => {
85 let ty = apply_ty.parameters[0].clone().to_chalk(db); 67 let ty = substs[0].clone().to_chalk(db);
86 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) 68 chalk_ir::TyKind::Raw(mutability, ty).intern(&Interner)
87 } 69 }
88 TypeCtor::Slice => { 70 Ty::Slice(substs) => {
89 chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db)) 71 chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner)
90 .intern(&Interner) 72 }
91 } 73 Ty::Str => chalk_ir::TyKind::Str.intern(&Interner),
92 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), 74 Ty::FnDef(callable_def, substs) => {
93 TypeCtor::FnDef(callable_def) => { 75 let id = callable_def.to_chalk(db);
94 let id = callable_def.to_chalk(db); 76 let substitution = substs.to_chalk(db);
95 let substitution = apply_ty.parameters.to_chalk(db); 77 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
96 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) 78 }
97 } 79 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner),
98 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
99 80
100 TypeCtor::Closure { def, expr } => { 81 Ty::Closure(def, expr, substs) => {
101 let closure_id = db.intern_closure((def, expr)); 82 let closure_id = db.intern_closure((def, expr));
102 let substitution = apply_ty.parameters.to_chalk(db); 83 let substitution = substs.to_chalk(db);
103 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
104 } 85 }
105 86
106 TypeCtor::Adt(adt_id) => { 87 Ty::Adt(adt_id, substs) => {
107 let substitution = apply_ty.parameters.to_chalk(db); 88 let substitution = substs.to_chalk(db);
108 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) 89 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner)
109 } 90 }
110 }, 91 Ty::Alias(AliasTy::Projection(proj_ty)) => {
111 Ty::Projection(proj_ty) => {
112 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); 92 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db);
113 let substitution = proj_ty.parameters.to_chalk(db); 93 let substitution = proj_ty.parameters.to_chalk(db);
114 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { 94 chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
@@ -126,8 +106,8 @@ impl ToChalk for Ty {
126 } 106 }
127 .to_ty::<Interner>(&Interner) 107 .to_ty::<Interner>(&Interner)
128 } 108 }
129 Ty::Bound(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner), 109 Ty::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
130 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 110 Ty::InferenceVar(..) => panic!("uncanonicalized infer ty"),
131 Ty::Dyn(predicates) => { 111 Ty::Dyn(predicates) => {
132 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter( 112 let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
133 &Interner, 113 &Interner,
@@ -139,7 +119,7 @@ impl ToChalk for Ty {
139 }; 119 };
140 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner) 120 chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
141 } 121 }
142 Ty::Opaque(opaque_ty) => { 122 Ty::Alias(AliasTy::Opaque(opaque_ty)) => {
143 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db); 123 let opaque_ty_id = opaque_ty.opaque_ty_id.to_chalk(db);
144 let substitution = opaque_ty.parameters.to_chalk(db); 124 let substitution = opaque_ty.parameters.to_chalk(db);
145 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { 125 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy {
@@ -154,9 +134,7 @@ impl ToChalk for Ty {
154 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 134 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
155 match chalk.data(&Interner).kind.clone() { 135 match chalk.data(&Interner).kind.clone() {
156 chalk_ir::TyKind::Error => Ty::Unknown, 136 chalk_ir::TyKind::Error => Ty::Unknown,
157 chalk_ir::TyKind::Array(ty, _size) => { 137 chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))),
158 Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty)))
159 }
160 chalk_ir::TyKind::Placeholder(idx) => { 138 chalk_ir::TyKind::Placeholder(idx) => {
161 assert_eq!(idx.ui, UniverseIndex::ROOT); 139 assert_eq!(idx.ui, UniverseIndex::ROOT);
162 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 140 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
@@ -168,12 +146,12 @@ impl ToChalk for Ty {
168 let associated_ty = 146 let associated_ty =
169 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0; 147 from_chalk::<TypeAliasAsAssocType, _>(db, proj.associated_ty_id).0;
170 let parameters = from_chalk(db, proj.substitution); 148 let parameters = from_chalk(db, proj.substitution);
171 Ty::Projection(ProjectionTy { associated_ty, parameters }) 149 Ty::Alias(AliasTy::Projection(ProjectionTy { associated_ty, parameters }))
172 } 150 }
173 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => { 151 chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(opaque_ty)) => {
174 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id); 152 let impl_trait_id = from_chalk(db, opaque_ty.opaque_ty_id);
175 let parameters = from_chalk(db, opaque_ty.substitution); 153 let parameters = from_chalk(db, opaque_ty.substitution);
176 Ty::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }) 154 Ty::Alias(AliasTy::Opaque(OpaqueTy { opaque_ty_id: impl_trait_id, parameters }))
177 } 155 }
178 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 156 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
179 num_binders, 157 num_binders,
@@ -182,19 +160,17 @@ impl ToChalk for Ty {
182 .. 160 ..
183 }) => { 161 }) => {
184 assert_eq!(num_binders, 0); 162 assert_eq!(num_binders, 0);
185 let parameters: Substs = from_chalk( 163 let substs: Substs = from_chalk(
186 db, 164 db,
187 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 165 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
188 ); 166 );
189 Ty::Apply(ApplicationTy { 167 Ty::Function(FnPointer {
190 ctor: TypeCtor::FnPtr { 168 num_args: (substs.len() - 1),
191 num_args: (parameters.len() - 1) as u16, 169 sig: FnSig { variadic },
192 is_varargs: variadic, 170 substs,
193 },
194 parameters,
195 }) 171 })
196 } 172 }
197 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), 173 chalk_ir::TyKind::BoundVar(idx) => Ty::BoundVar(idx),
198 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, 174 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
199 chalk_ir::TyKind::Dyn(where_clauses) => { 175 chalk_ir::TyKind::Dyn(where_clauses) => {
200 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1); 176 assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
@@ -207,93 +183,66 @@ impl ToChalk for Ty {
207 Ty::Dyn(predicates) 183 Ty::Dyn(predicates)
208 } 184 }
209 185
210 chalk_ir::TyKind::Adt(struct_id, subst) => { 186 chalk_ir::TyKind::Adt(struct_id, subst) => Ty::Adt(struct_id.0, from_chalk(db, subst)),
211 apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst) 187 chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType(
212 } 188 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0,
213 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( 189 from_chalk(db, subst),
214 db,
215 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
216 subst,
217 ), 190 ),
191
218 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { 192 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
219 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) 193 Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst))
220 } 194 }
221 195
222 chalk_ir::TyKind::Scalar(Scalar::Bool) => Ty::simple(TypeCtor::Bool), 196 chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar),
223 chalk_ir::TyKind::Scalar(Scalar::Char) => Ty::simple(TypeCtor::Char),
224 chalk_ir::TyKind::Scalar(Scalar::Int(int_ty)) => Ty::simple(TypeCtor::Int(IntTy {
225 signedness: Signedness::Signed,
226 bitness: bitness_from_chalk_int(int_ty),
227 })),
228 chalk_ir::TyKind::Scalar(Scalar::Uint(uint_ty)) => Ty::simple(TypeCtor::Int(IntTy {
229 signedness: Signedness::Unsigned,
230 bitness: bitness_from_chalk_uint(uint_ty),
231 })),
232 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F32)) => {
233 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X32 }))
234 }
235 chalk_ir::TyKind::Scalar(Scalar::Float(chalk_ir::FloatTy::F64)) => {
236 Ty::simple(TypeCtor::Float(FloatTy { bitness: FloatBitness::X64 }))
237 }
238 chalk_ir::TyKind::Tuple(cardinality, subst) => { 197 chalk_ir::TyKind::Tuple(cardinality, subst) => {
239 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) 198 Ty::Tuple(cardinality, from_chalk(db, subst))
240 } 199 }
241 chalk_ir::TyKind::Raw(mutability, ty) => { 200 chalk_ir::TyKind::Raw(mutability, ty) => {
242 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) 201 Ty::Raw(mutability, Substs::single(from_chalk(db, ty)))
243 } 202 }
244 chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)), 203 chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))),
245 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { 204 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
246 Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty)) 205 Ty::Ref(mutability, Substs::single(from_chalk(db, ty)))
247 } 206 }
248 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), 207 chalk_ir::TyKind::Str => Ty::Str,
249 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), 208 chalk_ir::TyKind::Never => Ty::Never,
250 209
251 chalk_ir::TyKind::FnDef(fn_def_id, subst) => { 210 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
252 let callable_def = from_chalk(db, fn_def_id); 211 Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst))
253 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
254 } 212 }
255 213
256 chalk_ir::TyKind::Closure(id, subst) => { 214 chalk_ir::TyKind::Closure(id, subst) => {
257 let id: crate::db::ClosureId = id.into(); 215 let id: crate::db::ClosureId = id.into();
258 let (def, expr) = db.lookup_intern_closure(id); 216 let (def, expr) = db.lookup_intern_closure(id);
259 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) 217 Ty::Closure(def, expr, from_chalk(db, subst))
260 } 218 }
261 219
262 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( 220 chalk_ir::TyKind::Foreign(foreign_def_id) => {
263 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, 221 Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
264 )), 222 }
265 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME 223 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
266 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME 224 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
267 } 225 }
268 } 226 }
269} 227}
270 228
271fn apply_ty_from_chalk(
272 db: &dyn HirDatabase,
273 ctor: TypeCtor,
274 subst: chalk_ir::Substitution<Interner>,
275) -> Ty {
276 Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) })
277}
278
279/// We currently don't model lifetimes, but Chalk does. So, we have to insert a 229/// We currently don't model lifetimes, but Chalk does. So, we have to insert a
280/// fake lifetime here, because Chalks built-in logic may expect it to be there. 230/// fake lifetime here, because Chalks built-in logic may expect it to be there.
281fn ref_to_chalk( 231fn ref_to_chalk(
282 db: &dyn HirDatabase, 232 db: &dyn HirDatabase,
283 mutability: Mutability, 233 mutability: chalk_ir::Mutability,
284 subst: Substs, 234 subst: Substs,
285) -> chalk_ir::Ty<Interner> { 235) -> chalk_ir::Ty<Interner> {
286 let arg = subst[0].clone().to_chalk(db); 236 let arg = subst[0].clone().to_chalk(db);
287 let lifetime = LifetimeData::Static.intern(&Interner); 237 let lifetime = LifetimeData::Static.intern(&Interner);
288 chalk_ir::TyKind::Ref(mutability.to_chalk(db), lifetime, arg).intern(&Interner) 238 chalk_ir::TyKind::Ref(mutability, lifetime, arg).intern(&Interner)
289} 239}
290 240
291/// We currently don't model constants, but Chalk does. So, we have to insert a 241/// We currently don't model constants, but Chalk does. So, we have to insert a
292/// fake constant here, because Chalks built-in logic may expect it to be there. 242/// fake constant here, because Chalks built-in logic may expect it to be there.
293fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> { 243fn array_to_chalk(db: &dyn HirDatabase, subst: Substs) -> chalk_ir::Ty<Interner> {
294 let arg = subst[0].clone().to_chalk(db); 244 let arg = subst[0].clone().to_chalk(db);
295 let usize_ty = 245 let usize_ty = chalk_ir::TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner);
296 chalk_ir::TyKind::Scalar(Scalar::Uint(chalk_ir::UintTy::Usize)).intern(&Interner);
297 let const_ = chalk_ir::ConstData { 246 let const_ = chalk_ir::ConstData {
298 ty: usize_ty, 247 ty: usize_ty,
299 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }), 248 value: chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: () }),
@@ -364,71 +313,6 @@ impl ToChalk for OpaqueTyId {
364 } 313 }
365} 314}
366 315
367fn bitness_from_chalk_uint(uint_ty: chalk_ir::UintTy) -> IntBitness {
368 use chalk_ir::UintTy;
369
370 match uint_ty {
371 UintTy::Usize => IntBitness::Xsize,
372 UintTy::U8 => IntBitness::X8,
373 UintTy::U16 => IntBitness::X16,
374 UintTy::U32 => IntBitness::X32,
375 UintTy::U64 => IntBitness::X64,
376 UintTy::U128 => IntBitness::X128,
377 }
378}
379
380fn bitness_from_chalk_int(int_ty: chalk_ir::IntTy) -> IntBitness {
381 use chalk_ir::IntTy;
382
383 match int_ty {
384 IntTy::Isize => IntBitness::Xsize,
385 IntTy::I8 => IntBitness::X8,
386 IntTy::I16 => IntBitness::X16,
387 IntTy::I32 => IntBitness::X32,
388 IntTy::I64 => IntBitness::X64,
389 IntTy::I128 => IntBitness::X128,
390 }
391}
392
393fn int_ty_to_chalk(int_ty: IntTy) -> Scalar {
394 use chalk_ir::{IntTy, UintTy};
395
396 match int_ty.signedness {
397 Signedness::Signed => Scalar::Int(match int_ty.bitness {
398 IntBitness::Xsize => IntTy::Isize,
399 IntBitness::X8 => IntTy::I8,
400 IntBitness::X16 => IntTy::I16,
401 IntBitness::X32 => IntTy::I32,
402 IntBitness::X64 => IntTy::I64,
403 IntBitness::X128 => IntTy::I128,
404 }),
405 Signedness::Unsigned => Scalar::Uint(match int_ty.bitness {
406 IntBitness::Xsize => UintTy::Usize,
407 IntBitness::X8 => UintTy::U8,
408 IntBitness::X16 => UintTy::U16,
409 IntBitness::X32 => UintTy::U32,
410 IntBitness::X64 => UintTy::U64,
411 IntBitness::X128 => UintTy::U128,
412 }),
413 }
414}
415
416impl ToChalk for Mutability {
417 type Chalk = chalk_ir::Mutability;
418 fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk {
419 match self {
420 Mutability::Shared => chalk_ir::Mutability::Not,
421 Mutability::Mut => chalk_ir::Mutability::Mut,
422 }
423 }
424 fn from_chalk(_db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
425 match chalk {
426 chalk_ir::Mutability::Mut => Mutability::Mut,
427 chalk_ir::Mutability::Not => Mutability::Shared,
428 }
429 }
430}
431
432impl ToChalk for hir_def::ImplId { 316impl ToChalk for hir_def::ImplId {
433 type Chalk = ImplId; 317 type Chalk = ImplId;
434 318
@@ -632,20 +516,12 @@ where
632 type Chalk = chalk_ir::Canonical<T::Chalk>; 516 type Chalk = chalk_ir::Canonical<T::Chalk>;
633 517
634 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> { 518 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
635 let kinds = self 519 let kinds = self.kinds.iter().map(|&tk| {
636 .kinds 520 chalk_ir::CanonicalVarKind::new(
637 .iter() 521 chalk_ir::VariableKind::Ty(tk),
638 .map(|k| match k { 522 chalk_ir::UniverseIndex::ROOT,
639 TyKind::General => chalk_ir::TyVariableKind::General, 523 )
640 TyKind::Integer => chalk_ir::TyVariableKind::Integer, 524 });
641 TyKind::Float => chalk_ir::TyVariableKind::Float,
642 })
643 .map(|tk| {
644 chalk_ir::CanonicalVarKind::new(
645 chalk_ir::VariableKind::Ty(tk),
646 chalk_ir::UniverseIndex::ROOT,
647 )
648 });
649 let value = self.value.to_chalk(db); 525 let value = self.value.to_chalk(db);
650 chalk_ir::Canonical { 526 chalk_ir::Canonical {
651 value, 527 value,
@@ -658,17 +534,13 @@ where
658 .binders 534 .binders
659 .iter(&Interner) 535 .iter(&Interner)
660 .map(|k| match k.kind { 536 .map(|k| match k.kind {
661 chalk_ir::VariableKind::Ty(tk) => match tk { 537 chalk_ir::VariableKind::Ty(tk) => tk,
662 chalk_ir::TyVariableKind::General => TyKind::General,
663 chalk_ir::TyVariableKind::Integer => TyKind::Integer,
664 chalk_ir::TyVariableKind::Float => TyKind::Float,
665 },
666 // HACK: Chalk can sometimes return new lifetime variables. We 538 // HACK: Chalk can sometimes return new lifetime variables. We
667 // want to just skip them, but to not mess up the indices of 539 // want to just skip them, but to not mess up the indices of
668 // other variables, we'll just create a new type variable in 540 // other variables, we'll just create a new type variable in
669 // their place instead. This should not matter (we never see the 541 // their place instead. This should not matter (we never see the
670 // actual *uses* of the lifetime variable). 542 // actual *uses* of the lifetime variable).
671 chalk_ir::VariableKind::Lifetime => TyKind::General, 543 chalk_ir::VariableKind::Lifetime => chalk_ir::TyVariableKind::General,
672 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"), 544 chalk_ir::VariableKind::Const(_) => panic!("unexpected const from Chalk"),
673 }) 545 })
674 .collect(); 546 .collect();