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