aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src')
-rw-r--r--crates/hir_ty/src/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.rs178
-rw-r--r--crates/hir_ty/src/infer.rs17
-rw-r--r--crates/hir_ty/src/infer/coerce.rs79
-rw-r--r--crates/hir_ty/src/infer/expr.rs245
-rw-r--r--crates/hir_ty/src/infer/pat.rs27
-rw-r--r--crates/hir_ty/src/infer/unify.rs38
-rw-r--r--crates/hir_ty/src/lib.rs521
-rw-r--r--crates/hir_ty/src/lower.rs51
-rw-r--r--crates/hir_ty/src/method_resolution.rs124
-rw-r--r--crates/hir_ty/src/op.rs39
-rw-r--r--crates/hir_ty/src/tests/simple.rs55
-rw-r--r--crates/hir_ty/src/traits/chalk.rs14
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs184
16 files changed, 735 insertions, 862 deletions
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..b439915c7 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::RawPtr(..) = &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 b4801cb21..179f7ff44 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -3,9 +3,8 @@
3use std::{borrow::Cow, fmt}; 3use std::{borrow::Cow, fmt};
4 4
5use crate::{ 5use crate::{
6 db::HirDatabase, primitive, utils::generics, ApplicationTy, CallableDefId, FnSig, 6 db::HirDatabase, primitive, utils::generics, CallableDefId, CallableSig, GenericPredicate,
7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 7 Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, TraitRef, Ty,
8 TraitRef, Ty, TypeCtor,
9}; 8};
10use arrayvec::ArrayVec; 9use arrayvec::ArrayVec;
11use hir_def::{ 10use hir_def::{
@@ -235,39 +234,62 @@ impl HirDisplay for &Ty {
235 } 234 }
236} 235}
237 236
238impl HirDisplay for ApplicationTy { 237impl HirDisplay for ProjectionTy {
239 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 238 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
240 if f.should_truncate() { 239 if f.should_truncate() {
241 return write!(f, "{}", TYPE_HINT_TRUNCATION); 240 return write!(f, "{}", TYPE_HINT_TRUNCATION);
242 } 241 }
243 242
244 match self.ctor { 243 let trait_ = f.db.trait_data(self.trait_(f.db));
245 TypeCtor::Scalar(Scalar::Bool) => write!(f, "bool")?, 244 let first_parameter = self.parameters[0].into_displayable(
246 TypeCtor::Scalar(Scalar::Char) => write!(f, "char")?, 245 f.db,
247 TypeCtor::Scalar(Scalar::Float(t)) => { 246 f.max_size,
248 write!(f, "{}", primitive::float_ty_to_string(t))? 247 f.omit_verbose_types,
249 } 248 f.display_target,
250 TypeCtor::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?, 249 );
251 TypeCtor::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?, 250 write!(f, "<{} as {}", first_parameter, trait_.name)?;
252 TypeCtor::Str => write!(f, "str")?, 251 if self.parameters.len() > 1 {
253 TypeCtor::Slice => { 252 write!(f, "<")?;
254 let t = self.parameters.as_single(); 253 f.write_joined(&self.parameters[1..], ", ")?;
254 write!(f, ">")?;
255 }
256 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
257 Ok(())
258 }
259}
260
261impl HirDisplay for Ty {
262 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
263 if f.should_truncate() {
264 return write!(f, "{}", TYPE_HINT_TRUNCATION);
265 }
266
267 match self {
268 Ty::Never => write!(f, "!")?,
269 Ty::Str => write!(f, "str")?,
270 Ty::Scalar(Scalar::Bool) => write!(f, "bool")?,
271 Ty::Scalar(Scalar::Char) => write!(f, "char")?,
272 &Ty::Scalar(Scalar::Float(t)) => write!(f, "{}", primitive::float_ty_to_string(t))?,
273 &Ty::Scalar(Scalar::Int(t)) => write!(f, "{}", primitive::int_ty_to_string(t))?,
274 &Ty::Scalar(Scalar::Uint(t)) => write!(f, "{}", primitive::uint_ty_to_string(t))?,
275 Ty::Slice(parameters) => {
276 let t = parameters.as_single();
255 write!(f, "[")?; 277 write!(f, "[")?;
256 t.hir_fmt(f)?; 278 t.hir_fmt(f)?;
257 write!(f, "]")?; 279 write!(f, "]")?;
258 } 280 }
259 TypeCtor::Array => { 281 Ty::Array(parameters) => {
260 let t = self.parameters.as_single(); 282 let t = parameters.as_single();
261 write!(f, "[")?; 283 write!(f, "[")?;
262 t.hir_fmt(f)?; 284 t.hir_fmt(f)?;
263 write!(f, "; _]")?; 285 write!(f, "; _]")?;
264 } 286 }
265 TypeCtor::RawPtr(m) | TypeCtor::Ref(m) => { 287 Ty::RawPtr(m, parameters) | Ty::Ref(m, parameters) => {
266 let t = self.parameters.as_single(); 288 let t = parameters.as_single();
267 let ty_display = 289 let ty_display =
268 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target); 290 t.into_displayable(f.db, f.max_size, f.omit_verbose_types, f.display_target);
269 291
270 if matches!(self.ctor, TypeCtor::RawPtr(_)) { 292 if matches!(self, Ty::RawPtr(..)) {
271 write!(f, "*{}", m.as_keyword_for_ptr())?; 293 write!(f, "*{}", m.as_keyword_for_ptr())?;
272 } else { 294 } else {
273 write!(f, "&{}", m.as_keyword_for_ref())?; 295 write!(f, "&{}", m.as_keyword_for_ref())?;
@@ -308,25 +330,24 @@ impl HirDisplay for ApplicationTy {
308 write!(f, "{}", ty_display)?; 330 write!(f, "{}", ty_display)?;
309 } 331 }
310 } 332 }
311 TypeCtor::Never => write!(f, "!")?, 333 Ty::Tuple(_, substs) => {
312 TypeCtor::Tuple { .. } => { 334 if substs.len() == 1 {
313 let ts = &self.parameters;
314 if ts.len() == 1 {
315 write!(f, "(")?; 335 write!(f, "(")?;
316 ts[0].hir_fmt(f)?; 336 substs[0].hir_fmt(f)?;
317 write!(f, ",)")?; 337 write!(f, ",)")?;
318 } else { 338 } else {
319 write!(f, "(")?; 339 write!(f, "(")?;
320 f.write_joined(&*ts.0, ", ")?; 340 f.write_joined(&*substs.0, ", ")?;
321 write!(f, ")")?; 341 write!(f, ")")?;
322 } 342 }
323 } 343 }
324 TypeCtor::FnPtr { is_varargs, .. } => { 344 Ty::Function(fn_ptr) => {
325 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 345 let sig = CallableSig::from_fn_ptr(fn_ptr);
326 sig.hir_fmt(f)?; 346 sig.hir_fmt(f)?;
327 } 347 }
328 TypeCtor::FnDef(def) => { 348 Ty::FnDef(def, parameters) => {
329 let sig = f.db.callable_item_signature(def).subst(&self.parameters); 349 let def = *def;
350 let sig = f.db.callable_item_signature(def).subst(parameters);
330 match def { 351 match def {
331 CallableDefId::FunctionId(ff) => { 352 CallableDefId::FunctionId(ff) => {
332 write!(f, "fn {}", f.db.function_data(ff).name)? 353 write!(f, "fn {}", f.db.function_data(ff).name)?
@@ -336,7 +357,7 @@ impl HirDisplay for ApplicationTy {
336 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)? 357 write!(f, "{}", f.db.enum_data(e.parent).variants[e.local_id].name)?
337 } 358 }
338 }; 359 };
339 if self.parameters.len() > 0 { 360 if parameters.len() > 0 {
340 let generics = generics(f.db.upcast(), def.into()); 361 let generics = generics(f.db.upcast(), def.into());
341 let (parent_params, self_param, type_params, _impl_trait_params) = 362 let (parent_params, self_param, type_params, _impl_trait_params) =
342 generics.provenance_split(); 363 generics.provenance_split();
@@ -344,7 +365,7 @@ impl HirDisplay for ApplicationTy {
344 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? 365 // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
345 if total_len > 0 { 366 if total_len > 0 {
346 write!(f, "<")?; 367 write!(f, "<")?;
347 f.write_joined(&self.parameters.0[..total_len], ", ")?; 368 f.write_joined(&parameters.0[..total_len], ", ")?;
348 write!(f, ">")?; 369 write!(f, ">")?;
349 } 370 }
350 } 371 }
@@ -363,10 +384,10 @@ impl HirDisplay for ApplicationTy {
363 write!(f, " -> {}", ret_display)?; 384 write!(f, " -> {}", ret_display)?;
364 } 385 }
365 } 386 }
366 TypeCtor::Adt(def_id) => { 387 Ty::Adt(def_id, parameters) => {
367 match f.display_target { 388 match f.display_target {
368 DisplayTarget::Diagnostics | DisplayTarget::Test => { 389 DisplayTarget::Diagnostics | DisplayTarget::Test => {
369 let name = match def_id { 390 let name = match *def_id {
370 AdtId::StructId(it) => f.db.struct_data(it).name.clone(), 391 AdtId::StructId(it) => f.db.struct_data(it).name.clone(),
371 AdtId::UnionId(it) => f.db.union_data(it).name.clone(), 392 AdtId::UnionId(it) => f.db.union_data(it).name.clone(),
372 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(), 393 AdtId::EnumId(it) => f.db.enum_data(it).name.clone(),
@@ -376,7 +397,7 @@ impl HirDisplay for ApplicationTy {
376 DisplayTarget::SourceCode { module_id } => { 397 DisplayTarget::SourceCode { module_id } => {
377 if let Some(path) = find_path::find_path( 398 if let Some(path) = find_path::find_path(
378 f.db.upcast(), 399 f.db.upcast(),
379 ItemInNs::Types(def_id.into()), 400 ItemInNs::Types((*def_id).into()),
380 module_id, 401 module_id,
381 ) { 402 ) {
382 write!(f, "{}", path)?; 403 write!(f, "{}", path)?;
@@ -388,19 +409,18 @@ impl HirDisplay for ApplicationTy {
388 } 409 }
389 } 410 }
390 411
391 if self.parameters.len() > 0 { 412 if parameters.len() > 0 {
392 let parameters_to_write = 413 let parameters_to_write =
393 if f.display_target.is_source_code() || f.omit_verbose_types() { 414 if f.display_target.is_source_code() || f.omit_verbose_types() {
394 match self 415 match self
395 .ctor
396 .as_generic_def() 416 .as_generic_def()
397 .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) 417 .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
398 .filter(|defaults| !defaults.is_empty()) 418 .filter(|defaults| !defaults.is_empty())
399 { 419 {
400 None => self.parameters.0.as_ref(), 420 None => parameters.0.as_ref(),
401 Some(default_parameters) => { 421 Some(default_parameters) => {
402 let mut default_from = 0; 422 let mut default_from = 0;
403 for (i, parameter) in self.parameters.iter().enumerate() { 423 for (i, parameter) in parameters.iter().enumerate() {
404 match (parameter, default_parameters.get(i)) { 424 match (parameter, default_parameters.get(i)) {
405 (&Ty::Unknown, _) | (_, None) => { 425 (&Ty::Unknown, _) | (_, None) => {
406 default_from = i + 1; 426 default_from = i + 1;
@@ -408,18 +428,18 @@ impl HirDisplay for ApplicationTy {
408 (_, Some(default_parameter)) => { 428 (_, Some(default_parameter)) => {
409 let actual_default = default_parameter 429 let actual_default = default_parameter
410 .clone() 430 .clone()
411 .subst(&self.parameters.prefix(i)); 431 .subst(&parameters.prefix(i));
412 if parameter != &actual_default { 432 if parameter != &actual_default {
413 default_from = i + 1; 433 default_from = i + 1;
414 } 434 }
415 } 435 }
416 } 436 }
417 } 437 }
418 &self.parameters.0[0..default_from] 438 &parameters.0[0..default_from]
419 } 439 }
420 } 440 }
421 } else { 441 } else {
422 self.parameters.0.as_ref() 442 parameters.0.as_ref()
423 }; 443 };
424 if !parameters_to_write.is_empty() { 444 if !parameters_to_write.is_empty() {
425 write!(f, "<")?; 445 write!(f, "<")?;
@@ -428,61 +448,54 @@ impl HirDisplay for ApplicationTy {
428 } 448 }
429 } 449 }
430 } 450 }
431 TypeCtor::AssociatedType(type_alias) => { 451 Ty::AssociatedType(type_alias, parameters) => {
432 let trait_ = match type_alias.lookup(f.db.upcast()).container { 452 let trait_ = match type_alias.lookup(f.db.upcast()).container {
433 AssocContainerId::TraitId(it) => it, 453 AssocContainerId::TraitId(it) => it,
434 _ => panic!("not an associated type"), 454 _ => panic!("not an associated type"),
435 }; 455 };
436 let trait_ = f.db.trait_data(trait_); 456 let trait_ = f.db.trait_data(trait_);
437 let type_alias_data = f.db.type_alias_data(type_alias); 457 let type_alias_data = f.db.type_alias_data(*type_alias);
438 458
439 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types) 459 // Use placeholder associated types when the target is test (https://rust-lang.github.io/chalk/book/clauses/type_equality.html#placeholder-associated-types)
440 if f.display_target.is_test() { 460 if f.display_target.is_test() {
441 write!(f, "{}::{}", trait_.name, type_alias_data.name)?; 461 write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
442 if self.parameters.len() > 0 { 462 if parameters.len() > 0 {
443 write!(f, "<")?; 463 write!(f, "<")?;
444 f.write_joined(&*self.parameters.0, ", ")?; 464 f.write_joined(&*parameters.0, ", ")?;
445 write!(f, ">")?; 465 write!(f, ">")?;
446 } 466 }
447 } else { 467 } else {
448 let projection_ty = ProjectionTy { 468 let projection_ty =
449 associated_ty: type_alias, 469 ProjectionTy { associated_ty: *type_alias, parameters: parameters.clone() };
450 parameters: self.parameters.clone(),
451 };
452 470
453 projection_ty.hir_fmt(f)?; 471 projection_ty.hir_fmt(f)?;
454 } 472 }
455 } 473 }
456 TypeCtor::ForeignType(type_alias) => { 474 Ty::ForeignType(type_alias) => {
457 let type_alias = f.db.type_alias_data(type_alias); 475 let type_alias = f.db.type_alias_data(*type_alias);
458 write!(f, "{}", type_alias.name)?; 476 write!(f, "{}", type_alias.name)?;
459 if self.parameters.len() > 0 {
460 write!(f, "<")?;
461 f.write_joined(&*self.parameters.0, ", ")?;
462 write!(f, ">")?;
463 }
464 } 477 }
465 TypeCtor::OpaqueType(opaque_ty_id) => { 478 Ty::OpaqueType(opaque_ty_id, parameters) => {
466 match opaque_ty_id { 479 match opaque_ty_id {
467 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 480 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
468 let datas = 481 let datas =
469 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 482 f.db.return_type_impl_traits(func).expect("impl trait id without data");
470 let data = (*datas) 483 let data = (*datas)
471 .as_ref() 484 .as_ref()
472 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 485 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
473 let bounds = data.subst(&self.parameters); 486 let bounds = data.subst(&parameters);
474 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 487 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
475 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution 488 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
476 } 489 }
477 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 490 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
478 write!(f, "impl Future<Output = ")?; 491 write!(f, "impl Future<Output = ")?;
479 self.parameters[0].hir_fmt(f)?; 492 parameters[0].hir_fmt(f)?;
480 write!(f, ">")?; 493 write!(f, ">")?;
481 } 494 }
482 } 495 }
483 } 496 }
484 TypeCtor::Closure { .. } => { 497 Ty::Closure(.., substs) => {
485 let sig = self.parameters[0].callable_sig(f.db); 498 let sig = substs[0].callable_sig(f.db);
486 if let Some(sig) = sig { 499 if let Some(sig) = sig {
487 if sig.params().is_empty() { 500 if sig.params().is_empty() {
488 write!(f, "||")?; 501 write!(f, "||")?;
@@ -505,43 +518,6 @@ impl HirDisplay for ApplicationTy {
505 write!(f, "{{closure}}")?; 518 write!(f, "{{closure}}")?;
506 } 519 }
507 } 520 }
508 }
509 Ok(())
510 }
511}
512
513impl HirDisplay for ProjectionTy {
514 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
515 if f.should_truncate() {
516 return write!(f, "{}", TYPE_HINT_TRUNCATION);
517 }
518
519 let trait_ = f.db.trait_data(self.trait_(f.db));
520 let first_parameter = self.parameters[0].into_displayable(
521 f.db,
522 f.max_size,
523 f.omit_verbose_types,
524 f.display_target,
525 );
526 write!(f, "<{} as {}", first_parameter, trait_.name)?;
527 if self.parameters.len() > 1 {
528 write!(f, "<")?;
529 f.write_joined(&self.parameters[1..], ", ")?;
530 write!(f, ">")?;
531 }
532 write!(f, ">::{}", f.db.type_alias_data(self.associated_ty).name)?;
533 Ok(())
534 }
535}
536
537impl HirDisplay for Ty {
538 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
539 if f.should_truncate() {
540 return write!(f, "{}", TYPE_HINT_TRUNCATION);
541 }
542
543 match self {
544 Ty::Apply(a_ty) => a_ty.hir_fmt(f)?,
545 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?, 521 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
546 Ty::Placeholder(id) => { 522 Ty::Placeholder(id) => {
547 let generics = generics(f.db.upcast(), id.parent); 523 let generics = generics(f.db.upcast(), id.parent);
@@ -595,7 +571,7 @@ impl HirDisplay for Ty {
595 } 571 }
596} 572}
597 573
598impl HirDisplay for FnSig { 574impl HirDisplay for CallableSig {
599 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { 575 fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
600 write!(f, "fn(")?; 576 write!(f, "fn(")?;
601 f.write_joined(self.params(), ", ")?; 577 f.write_joined(self.params(), ", ")?;
diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs
index 657f011d2..a1769729f 100644
--- a/crates/hir_ty/src/infer.rs
+++ b/crates/hir_ty/src/infer.rs
@@ -38,7 +38,7 @@ use syntax::SmolStr;
38use super::{ 38use super::{
39 primitive::{FloatTy, IntTy}, 39 primitive::{FloatTy, IntTy},
40 traits::{Guidance, Obligation, ProjectionPredicate, Solution}, 40 traits::{Guidance, Obligation, ProjectionPredicate, Solution},
41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 41 InEnvironment, ProjectionTy, Substs, TraitEnvironment, TraitRef, Ty, TypeWalk,
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar, 44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, Scalar,
@@ -46,15 +46,6 @@ use crate::{
46 46
47pub(crate) use unify::unify; 47pub(crate) use unify::unify;
48 48
49macro_rules! ty_app {
50 ($ctor:pat, $param:pat) => {
51 crate::Ty::Apply(crate::ApplicationTy { ctor: $ctor, parameters: $param })
52 };
53 ($ctor:pat) => {
54 ty_app!($ctor, _)
55 };
56}
57
58mod unify; 49mod unify;
59mod path; 50mod path;
60mod expr; 51mod expr;
@@ -684,9 +675,9 @@ impl InferTy {
684 fn fallback_value(self) -> Ty { 675 fn fallback_value(self) -> Ty {
685 match self { 676 match self {
686 InferTy::TypeVar(..) => Ty::Unknown, 677 InferTy::TypeVar(..) => Ty::Unknown,
687 InferTy::IntVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), 678 InferTy::IntVar(..) => Ty::Scalar(Scalar::Int(IntTy::I32)),
688 InferTy::FloatVar(..) => Ty::simple(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), 679 InferTy::FloatVar(..) => Ty::Scalar(Scalar::Float(FloatTy::F64)),
689 InferTy::MaybeNeverTypeVar(..) => Ty::simple(TypeCtor::Never), 680 InferTy::MaybeNeverTypeVar(..) => Ty::Never,
690 } 681 }
691 } 682 }
692} 683}
diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs
index 32c7c57cd..4cca35904 100644
--- a/crates/hir_ty/src/infer/coerce.rs
+++ b/crates/hir_ty/src/infer/coerce.rs
@@ -7,7 +7,7 @@
7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability}; 7use hir_def::{lang_item::LangItemTarget, type_ref::Mutability};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty, TypeCtor}; 10use crate::{autoderef, traits::Solution, Obligation, Substs, TraitRef, Ty};
11 11
12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext}; 12use super::{unify::TypeVarValue, InEnvironment, InferTy, InferenceContext};
13 13
@@ -33,7 +33,7 @@ impl<'a> InferenceContext<'a> {
33 } else if self.coerce(ty2, ty1) { 33 } else if self.coerce(ty2, ty1) {
34 ty1.clone() 34 ty1.clone()
35 } else { 35 } else {
36 if let (ty_app!(TypeCtor::FnDef(_)), ty_app!(TypeCtor::FnDef(_))) = (ty1, ty2) { 36 if let (Ty::FnDef(..), Ty::FnDef(..)) = (ty1, ty2) {
37 mark::hit!(coerce_fn_reification); 37 mark::hit!(coerce_fn_reification);
38 // Special case: two function types. Try to coerce both to 38 // Special case: two function types. Try to coerce both to
39 // pointers to have a chance at getting a match. See 39 // pointers to have a chance at getting a match. See
@@ -53,12 +53,12 @@ impl<'a> InferenceContext<'a> {
53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool { 53 fn coerce_inner(&mut self, mut from_ty: Ty, to_ty: &Ty) -> bool {
54 match (&from_ty, to_ty) { 54 match (&from_ty, to_ty) {
55 // Never type will make type variable to fallback to Never Type instead of Unknown. 55 // Never type will make type variable to fallback to Never Type instead of Unknown.
56 (ty_app!(TypeCtor::Never), Ty::Infer(InferTy::TypeVar(tv))) => { 56 (Ty::Never, Ty::Infer(InferTy::TypeVar(tv))) => {
57 let var = self.table.new_maybe_never_type_var(); 57 let var = self.table.new_maybe_never_type_var();
58 self.table.var_unification_table.union_value(*tv, TypeVarValue::Known(var)); 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::RawPtr(m1, ..), Ty::RawPtr(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::RawPtr(m2 @ Mutability::Shared, ..))
83 | (Ty::Ref(Mutability::Mut, substs), &Ty::RawPtr(m2, ..)) => {
84 from_ty = Ty::RawPtr(m2, substs.clone());
82 } 85 }
83 86
84 // Illegal mutablity conversion 87 // Illegal mutability conversion
85 ( 88 (Ty::RawPtr(Mutability::Shared, ..), Ty::RawPtr(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 3fec0e431..23d4ac8ef 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -18,8 +18,8 @@ use crate::{
18 primitive::{self, UintTy}, 18 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 19 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 20 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, 21 Binders, CallableDefId, FnPointer, FnSig, InferTy, Mutability, Obligation, OpaqueTyId, Rawness,
22 Scalar, Substs, TraitRef, Ty, TypeCtor, 22 Scalar, Substs, TraitRef, Ty,
23}; 23};
24 24
25use super::{ 25use super::{
@@ -82,10 +82,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 82 arg_tys.push(arg);
83 } 83 }
84 let parameters = param_builder.build(); 84 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 85 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 86 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 87 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 88
@@ -120,10 +117,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 117 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 118 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 119 // if let is desugared to match, so this is always simple if
123 self.infer_expr( 120 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 *condition,
125 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
126 );
127 121
128 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 122 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
129 let mut both_arms_diverge = Diverges::Always; 123 let mut both_arms_diverge = Diverges::Always;
@@ -178,7 +172,7 @@ impl<'a> InferenceContext<'a> {
178 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 172 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
179 let inner_ty = self.infer_expr(*body, &Expectation::none()); 173 let inner_ty = self.infer_expr(*body, &Expectation::none());
180 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 174 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
181 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 175 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
182 } 176 }
183 Expr::Loop { body, label } => { 177 Expr::Loop { body, label } => {
184 self.breakables.push(BreakableContext { 178 self.breakables.push(BreakableContext {
@@ -196,7 +190,7 @@ impl<'a> InferenceContext<'a> {
196 if ctxt.may_break { 190 if ctxt.may_break {
197 ctxt.break_ty 191 ctxt.break_ty
198 } else { 192 } else {
199 Ty::simple(TypeCtor::Never) 193 Ty::Never
200 } 194 }
201 } 195 }
202 Expr::While { condition, body, label } => { 196 Expr::While { condition, body, label } => {
@@ -206,10 +200,7 @@ impl<'a> InferenceContext<'a> {
206 label: label.map(|label| self.body[label].name.clone()), 200 label: label.map(|label| self.body[label].name.clone()),
207 }); 201 });
208 // while let is desugared to a match loop, so this is always simple while 202 // while let is desugared to a match loop, so this is always simple while
209 self.infer_expr( 203 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
210 *condition,
211 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))),
212 );
213 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 204 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
214 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 205 let _ctxt = self.breakables.pop().expect("breakable stack broken");
215 // the body may not run, so it diverging doesn't mean we diverge 206 // the body may not run, so it diverging doesn't mean we diverge
@@ -256,12 +247,12 @@ impl<'a> InferenceContext<'a> {
256 None => self.table.new_type_var(), 247 None => self.table.new_type_var(),
257 }; 248 };
258 sig_tys.push(ret_ty.clone()); 249 sig_tys.push(ret_ty.clone());
259 let sig_ty = Ty::apply( 250 let sig_ty = Ty::Function(FnPointer {
260 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 251 num_args: sig_tys.len() - 1,
261 Substs(sig_tys.clone().into()), 252 sig: FnSig { variadic: false },
262 ); 253 substs: Substs(sig_tys.clone().into()),
263 let closure_ty = 254 });
264 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 255 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
265 256
266 // Eagerly try to relate the closure type with the expected 257 // Eagerly try to relate the closure type with the expected
267 // type, otherwise we often won't have enough information to 258 // type, otherwise we often won't have enough information to
@@ -312,11 +303,8 @@ impl<'a> InferenceContext<'a> {
312 Expr::Match { expr, arms } => { 303 Expr::Match { expr, arms } => {
313 let input_ty = self.infer_expr(*expr, &Expectation::none()); 304 let input_ty = self.infer_expr(*expr, &Expectation::none());
314 305
315 let mut result_ty = if arms.is_empty() { 306 let mut result_ty =
316 Ty::simple(TypeCtor::Never) 307 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
317 } else {
318 self.table.new_type_var()
319 };
320 308
321 let matchee_diverges = self.diverges; 309 let matchee_diverges = self.diverges;
322 let mut all_arms_diverge = Diverges::Always; 310 let mut all_arms_diverge = Diverges::Always;
@@ -327,7 +315,7 @@ impl<'a> InferenceContext<'a> {
327 if let Some(guard_expr) = arm.guard { 315 if let Some(guard_expr) = arm.guard {
328 self.infer_expr( 316 self.infer_expr(
329 guard_expr, 317 guard_expr,
330 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), 318 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
331 ); 319 );
332 } 320 }
333 321
@@ -345,7 +333,7 @@ impl<'a> InferenceContext<'a> {
345 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 333 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
346 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 334 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
347 } 335 }
348 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 336 Expr::Continue { .. } => Ty::Never,
349 Expr::Break { expr, label } => { 337 Expr::Break { expr, label } => {
350 let val_ty = if let Some(expr) = expr { 338 let val_ty = if let Some(expr) = expr {
351 self.infer_expr(*expr, &Expectation::none()) 339 self.infer_expr(*expr, &Expectation::none())
@@ -370,8 +358,7 @@ impl<'a> InferenceContext<'a> {
370 expr: tgt_expr, 358 expr: tgt_expr,
371 }); 359 });
372 } 360 }
373 361 Ty::Never
374 Ty::simple(TypeCtor::Never)
375 } 362 }
376 Expr::Return { expr } => { 363 Expr::Return { expr } => {
377 if let Some(expr) = expr { 364 if let Some(expr) = expr {
@@ -380,14 +367,14 @@ impl<'a> InferenceContext<'a> {
380 let unit = Ty::unit(); 367 let unit = Ty::unit();
381 self.coerce(&unit, &self.return_ty.clone()); 368 self.coerce(&unit, &self.return_ty.clone());
382 } 369 }
383 Ty::simple(TypeCtor::Never) 370 Ty::Never
384 } 371 }
385 Expr::Yield { expr } => { 372 Expr::Yield { expr } => {
386 // FIXME: track yield type for coercion 373 // FIXME: track yield type for coercion
387 if let Some(expr) = expr { 374 if let Some(expr) = expr {
388 self.infer_expr(*expr, &Expectation::none()); 375 self.infer_expr(*expr, &Expectation::none());
389 } 376 }
390 Ty::simple(TypeCtor::Never) 377 Ty::Never
391 } 378 }
392 Expr::RecordLit { path, fields, spread } => { 379 Expr::RecordLit { path, fields, spread } => {
393 let (ty, def_id) = self.resolve_variant(path.as_ref()); 380 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -397,7 +384,7 @@ impl<'a> InferenceContext<'a> {
397 384
398 self.unify(&ty, &expected.ty); 385 self.unify(&ty, &expected.ty);
399 386
400 let substs = ty.substs().unwrap_or_else(Substs::empty); 387 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
401 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 388 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
402 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 389 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
403 for (field_idx, field) in fields.iter().enumerate() { 390 for (field_idx, field) in fields.iter().enumerate() {
@@ -436,30 +423,23 @@ impl<'a> InferenceContext<'a> {
436 }, 423 },
437 ) 424 )
438 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 425 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
439 Ty::Apply(a_ty) => match a_ty.ctor { 426 Ty::Tuple(_, substs) => {
440 TypeCtor::Tuple { .. } => name 427 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
441 .as_tuple_index() 428 }
442 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 429 Ty::Adt(AdtId::StructId(s), parameters) => {
443 TypeCtor::Adt(AdtId::StructId(s)) => { 430 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
444 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 431 let field = FieldId { parent: s.into(), local_id };
445 let field = FieldId { parent: s.into(), local_id }; 432 self.write_field_resolution(tgt_expr, field);
446 self.write_field_resolution(tgt_expr, field); 433 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
447 self.db.field_types(s.into())[field.local_id] 434 })
448 .clone() 435 }
449 .subst(&a_ty.parameters) 436 Ty::Adt(AdtId::UnionId(u), parameters) => {
450 }) 437 self.db.union_data(u).variant_data.field(name).map(|local_id| {
451 } 438 let field = FieldId { parent: u.into(), local_id };
452 TypeCtor::Adt(AdtId::UnionId(u)) => { 439 self.write_field_resolution(tgt_expr, field);
453 self.db.union_data(u).variant_data.field(name).map(|local_id| { 440 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
454 let field = FieldId { parent: u.into(), local_id }; 441 })
455 self.write_field_resolution(tgt_expr, field); 442 }
456 self.db.field_types(u.into())[field.local_id]
457 .clone()
458 .subst(&a_ty.parameters)
459 })
460 }
461 _ => None,
462 },
463 _ => None, 443 _ => None,
464 }) 444 })
465 .unwrap_or(Ty::Unknown); 445 .unwrap_or(Ty::Unknown);
@@ -497,19 +477,24 @@ impl<'a> InferenceContext<'a> {
497 Expectation::none() 477 Expectation::none()
498 }; 478 };
499 let inner_ty = self.infer_expr_inner(*expr, &expectation); 479 let inner_ty = self.infer_expr_inner(*expr, &expectation);
500 let ty = match rawness { 480 match rawness {
501 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 481 Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)),
502 Rawness::Ref => TypeCtor::Ref(*mutability), 482 Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)),
503 }; 483 }
504 Ty::apply_one(ty, inner_ty)
505 } 484 }
506 Expr::Box { expr } => { 485 Expr::Box { expr } => {
507 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 486 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
508 if let Some(box_) = self.resolve_boxed_box() { 487 if let Some(box_) = self.resolve_boxed_box() {
509 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 488 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
510 sb = sb.push(inner_ty); 489 sb = sb.push(inner_ty);
490 match self.db.generic_defaults(box_.into()).as_ref() {
491 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
492 sb = sb.push(alloc_ty.value.clone());
493 }
494 _ => (),
495 }
511 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 496 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
512 Ty::apply(TypeCtor::Adt(box_), sb.build()) 497 Ty::Adt(box_, sb.build())
513 } else { 498 } else {
514 Ty::Unknown 499 Ty::Unknown
515 } 500 }
@@ -539,14 +524,9 @@ impl<'a> InferenceContext<'a> {
539 UnaryOp::Neg => { 524 UnaryOp::Neg => {
540 match &inner_ty { 525 match &inner_ty {
541 // Fast path for builtins 526 // Fast path for builtins
542 Ty::Apply(ApplicationTy { 527 Ty::Scalar(Scalar::Int(_))
543 ctor: TypeCtor::Scalar(Scalar::Int(_)), 528 | Ty::Scalar(Scalar::Uint(_))
544 .. 529 | Ty::Scalar(Scalar::Float(_))
545 })
546 | Ty::Apply(ApplicationTy {
547 ctor: TypeCtor::Scalar(Scalar::Float(_)),
548 ..
549 })
550 | Ty::Infer(InferTy::IntVar(..)) 530 | Ty::Infer(InferTy::IntVar(..))
551 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, 531 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
552 // Otherwise we resolve via the std::ops::Neg trait 532 // Otherwise we resolve via the std::ops::Neg trait
@@ -557,18 +537,9 @@ impl<'a> InferenceContext<'a> {
557 UnaryOp::Not => { 537 UnaryOp::Not => {
558 match &inner_ty { 538 match &inner_ty {
559 // Fast path for builtins 539 // Fast path for builtins
560 Ty::Apply(ApplicationTy { 540 Ty::Scalar(Scalar::Bool)
561 ctor: TypeCtor::Scalar(Scalar::Bool), 541 | Ty::Scalar(Scalar::Int(_))
562 .. 542 | Ty::Scalar(Scalar::Uint(_))
563 })
564 | Ty::Apply(ApplicationTy {
565 ctor: TypeCtor::Scalar(Scalar::Int(_)),
566 ..
567 })
568 | Ty::Apply(ApplicationTy {
569 ctor: TypeCtor::Scalar(Scalar::Uint(_)),
570 ..
571 })
572 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 543 | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
573 // Otherwise we resolve via the std::ops::Not trait 544 // Otherwise we resolve via the std::ops::Not trait
574 _ => self 545 _ => self
@@ -580,9 +551,7 @@ impl<'a> InferenceContext<'a> {
580 Expr::BinaryOp { lhs, rhs, op } => match op { 551 Expr::BinaryOp { lhs, rhs, op } => match op {
581 Some(op) => { 552 Some(op) => {
582 let lhs_expectation = match op { 553 let lhs_expectation = match op {
583 BinaryOp::LogicOp(..) => { 554 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
584 Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool)))
585 }
586 _ => Expectation::none(), 555 _ => Expectation::none(),
587 }; 556 };
588 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 557 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -613,31 +582,31 @@ impl<'a> InferenceContext<'a> {
613 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 582 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
614 match (range_type, lhs_ty, rhs_ty) { 583 match (range_type, lhs_ty, rhs_ty) {
615 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 584 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
616 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 585 Some(adt) => Ty::Adt(adt, Substs::empty()),
617 None => Ty::Unknown, 586 None => Ty::Unknown,
618 }, 587 },
619 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 588 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
620 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 589 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
621 None => Ty::Unknown, 590 None => Ty::Unknown,
622 }, 591 },
623 (RangeOp::Inclusive, None, Some(ty)) => { 592 (RangeOp::Inclusive, None, Some(ty)) => {
624 match self.resolve_range_to_inclusive() { 593 match self.resolve_range_to_inclusive() {
625 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 594 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
626 None => Ty::Unknown, 595 None => Ty::Unknown,
627 } 596 }
628 } 597 }
629 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 598 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
630 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 599 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
631 None => Ty::Unknown, 600 None => Ty::Unknown,
632 }, 601 },
633 (RangeOp::Inclusive, Some(_), Some(ty)) => { 602 (RangeOp::Inclusive, Some(_), Some(ty)) => {
634 match self.resolve_range_inclusive() { 603 match self.resolve_range_inclusive() {
635 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 604 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
636 None => Ty::Unknown, 605 None => Ty::Unknown,
637 } 606 }
638 } 607 }
639 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 608 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
640 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 609 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
641 None => Ty::Unknown, 610 None => Ty::Unknown,
642 }, 611 },
643 (RangeOp::Inclusive, _, None) => Ty::Unknown, 612 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -671,7 +640,7 @@ impl<'a> InferenceContext<'a> {
671 } 640 }
672 Expr::Tuple { exprs } => { 641 Expr::Tuple { exprs } => {
673 let mut tys = match &expected.ty { 642 let mut tys = match &expected.ty {
674 ty_app!(TypeCtor::Tuple { .. }, st) => st 643 Ty::Tuple(_, substs) => substs
675 .iter() 644 .iter()
676 .cloned() 645 .cloned()
677 .chain(repeat_with(|| self.table.new_type_var())) 646 .chain(repeat_with(|| self.table.new_type_var()))
@@ -684,15 +653,11 @@ impl<'a> InferenceContext<'a> {
684 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 653 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
685 } 654 }
686 655
687 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 656 Ty::Tuple(tys.len(), Substs(tys.into()))
688 } 657 }
689 Expr::Array(array) => { 658 Expr::Array(array) => {
690 let elem_ty = match &expected.ty { 659 let elem_ty = match &expected.ty {
691 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 660 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
692 #[allow(unreachable_patterns)]
693 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
694 st.as_single().clone()
695 }
696 _ => self.table.new_type_var(), 661 _ => self.table.new_type_var(),
697 }; 662 };
698 663
@@ -709,42 +674,38 @@ impl<'a> InferenceContext<'a> {
709 ); 674 );
710 self.infer_expr( 675 self.infer_expr(
711 *repeat, 676 *repeat,
712 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( 677 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
713 UintTy::Usize,
714 )))),
715 ); 678 );
716 } 679 }
717 } 680 }
718 681
719 Ty::apply_one(TypeCtor::Array, elem_ty) 682 Ty::Array(Substs::single(elem_ty))
720 } 683 }
721 Expr::Literal(lit) => match lit { 684 Expr::Literal(lit) => match lit {
722 Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), 685 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
723 Literal::String(..) => { 686 Literal::String(..) => Ty::Ref(Mutability::Shared, Substs::single(Ty::Str)),
724 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
725 }
726 Literal::ByteString(..) => { 687 Literal::ByteString(..) => {
727 let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); 688 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
728 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 689 let array_type = Ty::Array(Substs::single(byte_type));
729 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 690 Ty::Ref(Mutability::Shared, Substs::single(array_type))
730 } 691 }
731 Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), 692 Literal::Char(..) => Ty::Scalar(Scalar::Char),
732 Literal::Int(_v, ty) => match ty { 693 Literal::Int(_v, ty) => match ty {
733 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( 694 Some(int_ty) => {
734 primitive::int_ty_from_builtin(*int_ty), 695 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
735 ))), 696 }
736 None => self.table.new_integer_var(), 697 None => self.table.new_integer_var(),
737 }, 698 },
738 Literal::Uint(_v, ty) => match ty { 699 Literal::Uint(_v, ty) => match ty {
739 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( 700 Some(int_ty) => {
740 primitive::uint_ty_from_builtin(*int_ty), 701 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
741 ))), 702 }
742 None => self.table.new_integer_var(), 703 None => self.table.new_integer_var(),
743 }, 704 },
744 Literal::Float(_v, ty) => match ty { 705 Literal::Float(_v, ty) => match ty {
745 Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( 706 Some(float_ty) => {
746 primitive::float_ty_from_builtin(*float_ty), 707 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
747 ))), 708 }
748 None => self.table.new_float_var(), 709 None => self.table.new_float_var(),
749 }, 710 },
750 }, 711 },
@@ -857,7 +818,7 @@ impl<'a> InferenceContext<'a> {
857 // Apply autoref so the below unification works correctly 818 // Apply autoref so the below unification works correctly
858 // FIXME: return correct autorefs from lookup_method 819 // FIXME: return correct autorefs from lookup_method
859 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 820 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
860 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 821 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
861 _ => derefed_receiver_ty, 822 _ => derefed_receiver_ty,
862 }; 823 };
863 self.unify(&expected_receiver_ty, &actual_receiver_ty); 824 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -934,30 +895,26 @@ impl<'a> InferenceContext<'a> {
934 } 895 }
935 896
936 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 897 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
937 if let Ty::Apply(a_ty) = callable_ty { 898 if let &Ty::FnDef(def, ref parameters) = callable_ty {
938 if let TypeCtor::FnDef(def) = a_ty.ctor { 899 let generic_predicates = self.db.generic_predicates(def.into());
939 let generic_predicates = self.db.generic_predicates(def.into()); 900 for predicate in generic_predicates.iter() {
940 for predicate in generic_predicates.iter() { 901 let predicate = predicate.clone().subst(parameters);
941 let predicate = predicate.clone().subst(&a_ty.parameters); 902 if let Some(obligation) = Obligation::from_predicate(predicate) {
942 if let Some(obligation) = Obligation::from_predicate(predicate) { 903 self.obligations.push(obligation);
943 self.obligations.push(obligation);
944 }
945 } 904 }
946 // add obligation for trait implementation, if this is a trait method 905 }
947 match def { 906 // add obligation for trait implementation, if this is a trait method
948 CallableDefId::FunctionId(f) => { 907 match def {
949 if let AssocContainerId::TraitId(trait_) = 908 CallableDefId::FunctionId(f) => {
950 f.lookup(self.db.upcast()).container 909 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
951 { 910 {
952 // construct a TraitDef 911 // construct a TraitDef
953 let substs = a_ty 912 let substs =
954 .parameters 913 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
955 .prefix(generics(self.db.upcast(), trait_.into()).len()); 914 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
956 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
957 }
958 } 915 }
959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
960 } 916 }
917 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
961 } 918 }
962 } 919 }
963 } 920 }
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 57eb8cede..2852ad5bf 100644
--- a/crates/hir_ty/src/infer/unify.rs
+++ b/crates/hir_ty/src/infer/unify.rs
@@ -9,7 +9,7 @@ use test_utils::mark;
9use super::{InferenceContext, Obligation}; 9use super::{InferenceContext, Obligation};
10use crate::{ 10use crate::{
11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs, 11 BoundVar, Canonical, DebruijnIndex, GenericPredicate, InEnvironment, InferTy, Scalar, Substs,
12 Ty, TyKind, TypeCtor, TypeWalk, 12 Ty, TyKind, TypeWalk,
13}; 13};
14 14
15impl<'a> InferenceContext<'a> { 15impl<'a> InferenceContext<'a> {
@@ -257,12 +257,14 @@ impl InferenceTable {
257 // try to resolve type vars first 257 // try to resolve type vars first
258 let ty1 = self.resolve_ty_shallow(ty1); 258 let ty1 = self.resolve_ty_shallow(ty1);
259 let ty2 = self.resolve_ty_shallow(ty2); 259 let ty2 = self.resolve_ty_shallow(ty2);
260 match (&*ty1, &*ty2) { 260 if ty1.equals_ctor(&ty2) {
261 (Ty::Apply(a_ty1), Ty::Apply(a_ty2)) if a_ty1.ctor == a_ty2.ctor => { 261 match (ty1.substs(), ty2.substs()) {
262 self.unify_substs(&a_ty1.parameters, &a_ty2.parameters, depth + 1) 262 (Some(st1), Some(st2)) => self.unify_substs(st1, st2, depth + 1),
263 (None, None) => true,
264 _ => false,
263 } 265 }
264 266 } else {
265 _ => self.unify_inner_trivial(&ty1, &ty2, depth), 267 self.unify_inner_trivial(&ty1, &ty2, depth)
266 } 268 }
267 } 269 }
268 270
@@ -300,24 +302,12 @@ impl InferenceTable {
300 | (other, Ty::Infer(InferTy::TypeVar(tv))) 302 | (other, Ty::Infer(InferTy::TypeVar(tv)))
301 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other) 303 | (Ty::Infer(InferTy::MaybeNeverTypeVar(tv)), other)
302 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv))) 304 | (other, Ty::Infer(InferTy::MaybeNeverTypeVar(tv)))
303 | (Ty::Infer(InferTy::IntVar(tv)), other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_)))) 305 | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Int(_)))
304 | (other @ ty_app!(TypeCtor::Scalar(Scalar::Int(_))), Ty::Infer(InferTy::IntVar(tv))) 306 | (other @ Ty::Scalar(Scalar::Int(_)), Ty::Infer(InferTy::IntVar(tv)))
305 | ( 307 | (Ty::Infer(InferTy::IntVar(tv)), other @ Ty::Scalar(Scalar::Uint(_)))
306 Ty::Infer(InferTy::IntVar(tv)), 308 | (other @ Ty::Scalar(Scalar::Uint(_)), Ty::Infer(InferTy::IntVar(tv)))
307 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))), 309 | (Ty::Infer(InferTy::FloatVar(tv)), other @ Ty::Scalar(Scalar::Float(_)))
308 ) 310 | (other @ Ty::Scalar(Scalar::Float(_)), Ty::Infer(InferTy::FloatVar(tv))) => {
309 | (
310 other @ ty_app!(TypeCtor::Scalar(Scalar::Uint(_))),
311 Ty::Infer(InferTy::IntVar(tv)),
312 )
313 | (
314 Ty::Infer(InferTy::FloatVar(tv)),
315 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
316 )
317 | (
318 other @ ty_app!(TypeCtor::Scalar(Scalar::Float(_))),
319 Ty::Infer(InferTy::FloatVar(tv)),
320 ) => {
321 // the type var is unknown since we tried to resolve it 311 // the type var is unknown since we tried to resolve it
322 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone())); 312 self.var_unification_table.union_value(*tv, TypeVarValue::Known(other.clone()));
323 true 313 true
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 676519594..1abb0440f 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,
@@ -57,192 +57,6 @@ pub enum Lifetime {
57 Static, 57 Static,
58} 58}
59 59
60/// A type constructor or type name: this might be something like the primitive
61/// type `bool`, a struct like `Vec`, or things like function pointers or
62/// tuples.
63#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
64pub enum TypeCtor {
65 /// a scalar type like `bool` or `u32`
66 Scalar(Scalar),
67
68 /// Structures, enumerations and unions.
69 Adt(AdtId),
70
71 /// The pointee of a string slice. Written as `str`.
72 Str,
73
74 /// The pointee of an array slice. Written as `[T]`.
75 Slice,
76
77 /// An array with the given length. Written as `[T; n]`.
78 Array,
79
80 /// A raw pointer. Written as `*mut T` or `*const T`
81 RawPtr(Mutability),
82
83 /// A reference; a pointer with an associated lifetime. Written as
84 /// `&'a mut T` or `&'a T`.
85 Ref(Mutability),
86
87 /// The anonymous type of a function declaration/definition. Each
88 /// function has a unique type, which is output (for a function
89 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
90 ///
91 /// This includes tuple struct / enum variant constructors as well.
92 ///
93 /// For example the type of `bar` here:
94 ///
95 /// ```
96 /// fn foo() -> i32 { 1 }
97 /// let bar = foo; // bar: fn() -> i32 {foo}
98 /// ```
99 FnDef(CallableDefId),
100
101 /// A pointer to a function. Written as `fn() -> i32`.
102 ///
103 /// For example the type of `bar` here:
104 ///
105 /// ```
106 /// fn foo() -> i32 { 1 }
107 /// let bar: fn() -> i32 = foo;
108 /// ```
109 // FIXME make this a Ty variant like in Chalk
110 FnPtr { num_args: u16, is_varargs: bool },
111
112 /// The never type `!`.
113 Never,
114
115 /// A tuple type. For example, `(i32, bool)`.
116 Tuple { cardinality: u16 },
117
118 /// Represents an associated item like `Iterator::Item`. This is used
119 /// when we have tried to normalize a projection like `T::Item` but
120 /// couldn't find a better representation. In that case, we generate
121 /// an **application type** like `(Iterator::Item)<T>`.
122 AssociatedType(TypeAliasId),
123
124 /// This represents a placeholder for an opaque type in situations where we
125 /// don't know the hidden type (i.e. currently almost always). This is
126 /// analogous to the `AssociatedType` type constructor.
127 /// It is also used as the type of async block, with one type parameter
128 /// representing the Future::Output type.
129 OpaqueType(OpaqueTyId),
130
131 /// Represents a foreign type declared in external blocks.
132 ForeignType(TypeAliasId),
133
134 /// The type of a specific closure.
135 ///
136 /// The closure signature is stored in a `FnPtr` type in the first type
137 /// parameter.
138 Closure { def: DefWithBodyId, expr: ExprId },
139}
140
141impl TypeCtor {
142 pub fn num_ty_params(self, db: &dyn HirDatabase) -> usize {
143 match self {
144 TypeCtor::Scalar(_)
145 | TypeCtor::Str
146 | TypeCtor::Never => 0,
147 TypeCtor::Slice
148 | TypeCtor::Array
149 | TypeCtor::RawPtr(_)
150 | TypeCtor::Ref(_)
151 | TypeCtor::Closure { .. } // 1 param representing the signature of the closure
152 => 1,
153 TypeCtor::Adt(adt) => {
154 let generic_params = generics(db.upcast(), adt.into());
155 generic_params.len()
156 }
157 TypeCtor::FnDef(callable) => {
158 let generic_params = generics(db.upcast(), callable.into());
159 generic_params.len()
160 }
161 TypeCtor::AssociatedType(type_alias) => {
162 let generic_params = generics(db.upcast(), type_alias.into());
163 generic_params.len()
164 }
165 TypeCtor::ForeignType(type_alias) => {
166 let generic_params = generics(db.upcast(), type_alias.into());
167 generic_params.len()
168 }
169 TypeCtor::OpaqueType(opaque_ty_id) => {
170 match opaque_ty_id {
171 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
172 let generic_params = generics(db.upcast(), func.into());
173 generic_params.len()
174 }
175 // 1 param representing Future::Output type.
176 OpaqueTyId::AsyncBlockTypeImplTrait(..) => 1,
177 }
178 }
179 TypeCtor::FnPtr { num_args, is_varargs: _ } => num_args as usize + 1,
180 TypeCtor::Tuple { cardinality } => cardinality as usize,
181 }
182 }
183
184 pub fn krate(self, db: &dyn HirDatabase) -> Option<CrateId> {
185 match self {
186 TypeCtor::Scalar(_)
187 | TypeCtor::Str
188 | TypeCtor::Never
189 | TypeCtor::Slice
190 | TypeCtor::Array
191 | TypeCtor::RawPtr(_)
192 | TypeCtor::Ref(_)
193 | TypeCtor::FnPtr { .. }
194 | TypeCtor::Tuple { .. } => None,
195 // Closure's krate is irrelevant for coherence I would think?
196 TypeCtor::Closure { .. } => None,
197 TypeCtor::Adt(adt) => Some(adt.module(db.upcast()).krate()),
198 TypeCtor::FnDef(callable) => Some(callable.krate(db)),
199 TypeCtor::AssociatedType(type_alias) => {
200 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
201 }
202 TypeCtor::ForeignType(type_alias) => {
203 Some(type_alias.lookup(db.upcast()).module(db.upcast()).krate())
204 }
205 TypeCtor::OpaqueType(opaque_ty_id) => match opaque_ty_id {
206 OpaqueTyId::ReturnTypeImplTrait(func, _) => {
207 Some(func.lookup(db.upcast()).module(db.upcast()).krate())
208 }
209 OpaqueTyId::AsyncBlockTypeImplTrait(def, _) => {
210 Some(def.module(db.upcast()).krate())
211 }
212 },
213 }
214 }
215
216 pub fn as_generic_def(self) -> Option<GenericDefId> {
217 match self {
218 TypeCtor::Scalar(_)
219 | TypeCtor::Str
220 | TypeCtor::Never
221 | TypeCtor::Slice
222 | TypeCtor::Array
223 | TypeCtor::RawPtr(_)
224 | TypeCtor::Ref(_)
225 | TypeCtor::FnPtr { .. }
226 | TypeCtor::Tuple { .. }
227 | TypeCtor::Closure { .. } => None,
228 TypeCtor::Adt(adt) => Some(adt.into()),
229 TypeCtor::FnDef(callable) => Some(callable.into()),
230 TypeCtor::AssociatedType(type_alias) => Some(type_alias.into()),
231 TypeCtor::ForeignType(type_alias) => Some(type_alias.into()),
232 TypeCtor::OpaqueType(_impl_trait_id) => None,
233 }
234 }
235}
236
237/// A nominal type with (maybe 0) type parameters. This might be a primitive
238/// type like `bool`, a struct, tuple, function pointer, reference or
239/// several other things.
240#[derive(Clone, PartialEq, Eq, Debug, Hash)]
241pub struct ApplicationTy {
242 pub ctor: TypeCtor,
243 pub parameters: Substs,
244}
245
246#[derive(Clone, PartialEq, Eq, Debug, Hash)] 60#[derive(Clone, PartialEq, Eq, Debug, Hash)]
247pub struct OpaqueTy { 61pub struct OpaqueTy {
248 pub opaque_ty_id: OpaqueTyId, 62 pub opaque_ty_id: OpaqueTyId,
@@ -285,6 +99,18 @@ impl TypeWalk for ProjectionTy {
285 } 99 }
286} 100}
287 101
102#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
103pub struct FnSig {
104 pub variadic: bool,
105}
106
107#[derive(Clone, PartialEq, Eq, Debug, Hash)]
108pub struct FnPointer {
109 pub num_args: usize,
110 pub sig: FnSig,
111 pub substs: Substs,
112}
113
288/// A type. 114/// A type.
289/// 115///
290/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents 116/// See also the `TyKind` enum in rustc (librustc/ty/sty.rs), which represents
@@ -293,10 +119,79 @@ impl TypeWalk for ProjectionTy {
293/// This should be cheap to clone. 119/// This should be cheap to clone.
294#[derive(Clone, PartialEq, Eq, Debug, Hash)] 120#[derive(Clone, PartialEq, Eq, Debug, Hash)]
295pub enum Ty { 121pub enum Ty {
296 /// A nominal type with (maybe 0) type parameters. This might be a primitive 122 /// Structures, enumerations and unions.
297 /// type like `bool`, a struct, tuple, function pointer, reference or 123 Adt(AdtId, Substs),
298 /// several other things. 124
299 Apply(ApplicationTy), 125 /// Represents an associated item like `Iterator::Item`. This is used
126 /// when we have tried to normalize a projection like `T::Item` but
127 /// couldn't find a better representation. In that case, we generate
128 /// an **application type** like `(Iterator::Item)<T>`.
129 AssociatedType(TypeAliasId, Substs),
130
131 /// a scalar type like `bool` or `u32`
132 Scalar(Scalar),
133
134 /// A tuple type. For example, `(i32, bool)`.
135 Tuple(usize, Substs),
136
137 /// An array with the given length. Written as `[T; n]`.
138 Array(Substs),
139
140 /// The pointee of an array slice. Written as `[T]`.
141 Slice(Substs),
142
143 /// A raw pointer. Written as `*mut T` or `*const T`
144 RawPtr(Mutability, Substs),
145
146 /// A reference; a pointer with an associated lifetime. Written as
147 /// `&'a mut T` or `&'a T`.
148 Ref(Mutability, Substs),
149
150 /// This represents a placeholder for an opaque type in situations where we
151 /// don't know the hidden type (i.e. currently almost always). This is
152 /// analogous to the `AssociatedType` type constructor.
153 /// It is also used as the type of async block, with one type parameter
154 /// representing the Future::Output type.
155 OpaqueType(OpaqueTyId, Substs),
156
157 /// The anonymous type of a function declaration/definition. Each
158 /// function has a unique type, which is output (for a function
159 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
160 ///
161 /// This includes tuple struct / enum variant constructors as well.
162 ///
163 /// For example the type of `bar` here:
164 ///
165 /// ```
166 /// fn foo() -> i32 { 1 }
167 /// let bar = foo; // bar: fn() -> i32 {foo}
168 /// ```
169 FnDef(CallableDefId, Substs),
170
171 /// The pointee of a string slice. Written as `str`.
172 Str,
173
174 /// The never type `!`.
175 Never,
176
177 /// The type of a specific closure.
178 ///
179 /// The closure signature is stored in a `FnPtr` type in the first type
180 /// parameter.
181 Closure(DefWithBodyId, ExprId, Substs),
182
183 /// Represents a foreign type declared in external blocks.
184 ForeignType(TypeAliasId),
185
186 /// A pointer to a function. Written as `fn() -> i32`.
187 ///
188 /// For example the type of `bar` here:
189 ///
190 /// ```
191 /// fn foo() -> i32 { 1 }
192 /// let bar: fn() -> i32 = foo;
193 /// ```
194 Function(FnPointer),
300 195
301 /// A "projection" type corresponds to an (unnormalized) 196 /// A "projection" type corresponds to an (unnormalized)
302 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 197 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
@@ -420,10 +315,6 @@ impl Substs {
420 Substs::builder(generic_params.len()) 315 Substs::builder(generic_params.len())
421 } 316 }
422 317
423 pub fn build_for_type_ctor(db: &dyn HirDatabase, type_ctor: TypeCtor) -> SubstsBuilder {
424 Substs::builder(type_ctor.num_ty_params(db))
425 }
426
427 fn builder(param_count: usize) -> SubstsBuilder { 318 fn builder(param_count: usize) -> SubstsBuilder {
428 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 319 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
429 } 320 }
@@ -655,22 +546,29 @@ pub enum TyKind {
655/// A function signature as seen by type inference: Several parameter types and 546/// A function signature as seen by type inference: Several parameter types and
656/// one return type. 547/// one return type.
657#[derive(Clone, PartialEq, Eq, Debug)] 548#[derive(Clone, PartialEq, Eq, Debug)]
658pub struct FnSig { 549pub struct CallableSig {
659 params_and_return: Arc<[Ty]>, 550 params_and_return: Arc<[Ty]>,
660 is_varargs: bool, 551 is_varargs: bool,
661} 552}
662 553
663/// A polymorphic function signature. 554/// A polymorphic function signature.
664pub type PolyFnSig = Binders<FnSig>; 555pub type PolyFnSig = Binders<CallableSig>;
665 556
666impl FnSig { 557impl CallableSig {
667 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> FnSig { 558 pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) -> CallableSig {
668 params.push(ret); 559 params.push(ret);
669 FnSig { params_and_return: params.into(), is_varargs } 560 CallableSig { params_and_return: params.into(), is_varargs }
670 } 561 }
671 562
672 pub fn from_fn_ptr_substs(substs: &Substs, is_varargs: bool) -> FnSig { 563 pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
673 FnSig { params_and_return: Arc::clone(&substs.0), is_varargs } 564 CallableSig {
565 params_and_return: Arc::clone(&fn_ptr.substs.0),
566 is_varargs: fn_ptr.sig.variadic,
567 }
568 }
569
570 pub fn from_substs(substs: &Substs) -> CallableSig {
571 CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false }
674 } 572 }
675 573
676 pub fn params(&self) -> &[Ty] { 574 pub fn params(&self) -> &[Ty] {
@@ -682,7 +580,7 @@ impl FnSig {
682 } 580 }
683} 581}
684 582
685impl TypeWalk for FnSig { 583impl TypeWalk for CallableSig {
686 fn walk(&self, f: &mut impl FnMut(&Ty)) { 584 fn walk(&self, f: &mut impl FnMut(&Ty)) {
687 for t in self.params_and_return.iter() { 585 for t in self.params_and_return.iter() {
688 t.walk(f); 586 t.walk(f);
@@ -701,54 +599,42 @@ impl TypeWalk for FnSig {
701} 599}
702 600
703impl Ty { 601impl Ty {
704 pub fn simple(ctor: TypeCtor) -> Ty {
705 Ty::Apply(ApplicationTy { ctor, parameters: Substs::empty() })
706 }
707 pub fn apply_one(ctor: TypeCtor, param: Ty) -> Ty {
708 Ty::Apply(ApplicationTy { ctor, parameters: Substs::single(param) })
709 }
710 pub fn apply(ctor: TypeCtor, parameters: Substs) -> Ty {
711 Ty::Apply(ApplicationTy { ctor, parameters })
712 }
713 pub fn unit() -> Self { 602 pub fn unit() -> Self {
714 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 603 Ty::Tuple(0, Substs::empty())
715 } 604 }
716 pub fn fn_ptr(sig: FnSig) -> Self { 605
717 Ty::apply( 606 pub fn fn_ptr(sig: CallableSig) -> Self {
718 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 607 Ty::Function(FnPointer {
719 Substs(sig.params_and_return), 608 num_args: sig.params().len(),
720 ) 609 sig: FnSig { variadic: sig.is_varargs },
610 substs: Substs(sig.params_and_return),
611 })
721 } 612 }
613
722 pub fn builtin(builtin: BuiltinType) -> Self { 614 pub fn builtin(builtin: BuiltinType) -> Self {
723 Ty::simple(match builtin { 615 match builtin {
724 BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), 616 BuiltinType::Char => Ty::Scalar(Scalar::Char),
725 BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), 617 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
726 BuiltinType::Str => TypeCtor::Str, 618 BuiltinType::Str => Ty::Str,
727 BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), 619 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
728 BuiltinType::Uint(t) => { 620 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
729 TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))) 621 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
730 } 622 }
731 BuiltinType::Float(t) => {
732 TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t)))
733 }
734 })
735 } 623 }
736 624
737 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 625 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
738 match self { 626 match self {
739 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 627 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
740 Some((parameters.as_single(), *mutability))
741 }
742 _ => None, 628 _ => None,
743 } 629 }
744 } 630 }
745 631
746 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 632 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
747 match self { 633 match self {
748 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 634 Ty::Ref(mutability, parameters) => {
749 Some((parameters.as_single(), Rawness::Ref, *mutability)) 635 Some((parameters.as_single(), Rawness::Ref, *mutability))
750 } 636 }
751 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 637 Ty::RawPtr(mutability, parameters) => {
752 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 638 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
753 } 639 }
754 _ => None, 640 _ => None,
@@ -758,7 +644,7 @@ impl Ty {
758 pub fn strip_references(&self) -> &Ty { 644 pub fn strip_references(&self) -> &Ty {
759 let mut t: &Ty = self; 645 let mut t: &Ty = self;
760 646
761 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 647 while let Ty::Ref(_mutability, parameters) = t {
762 t = parameters.as_single(); 648 t = parameters.as_single();
763 } 649 }
764 650
@@ -767,30 +653,62 @@ impl Ty {
767 653
768 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 654 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
769 match self { 655 match self {
770 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 656 Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)),
771 Some((*adt_def, parameters))
772 }
773 _ => None, 657 _ => None,
774 } 658 }
775 } 659 }
776 660
777 pub fn as_tuple(&self) -> Option<&Substs> { 661 pub fn as_tuple(&self) -> Option<&Substs> {
778 match self { 662 match self {
779 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 663 Ty::Tuple(_, substs) => Some(substs),
780 Some(parameters) 664 _ => None,
781 } 665 }
666 }
667
668 pub fn as_generic_def(&self) -> Option<GenericDefId> {
669 match *self {
670 Ty::Adt(adt, ..) => Some(adt.into()),
671 Ty::FnDef(callable, ..) => Some(callable.into()),
672 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
673 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
782 _ => None, 674 _ => None,
783 } 675 }
784 } 676 }
785 677
786 pub fn is_never(&self) -> bool { 678 pub fn is_never(&self) -> bool {
787 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 679 matches!(self, Ty::Never)
788 } 680 }
789 681
790 pub fn is_unknown(&self) -> bool { 682 pub fn is_unknown(&self) -> bool {
791 matches!(self, Ty::Unknown) 683 matches!(self, Ty::Unknown)
792 } 684 }
793 685
686 pub fn equals_ctor(&self, other: &Ty) -> bool {
687 match (self, other) {
688 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
689 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
690 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
691 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
692 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
693 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
694 (Ty::Closure(def, expr, _), Ty::Closure(def2, expr2, _)) => {
695 expr == expr2 && def == def2
696 }
697 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
698 | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => {
699 mutability == mutability2
700 }
701 (
702 Ty::Function(FnPointer { num_args, sig, .. }),
703 Ty::Function(FnPointer { num_args: num_args2, sig: sig2, .. }),
704 ) => num_args == num_args2 && sig == sig2,
705 (Ty::Tuple(cardinality, _), Ty::Tuple(cardinality2, _)) => cardinality == cardinality2,
706 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
707 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
708 _ => false,
709 }
710 }
711
794 /// If this is a `dyn Trait` type, this returns the `Trait` part. 712 /// If this is a `dyn Trait` type, this returns the `Trait` part.
795 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 713 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
796 match self { 714 match self {
@@ -809,41 +727,30 @@ impl Ty {
809 727
810 fn builtin_deref(&self) -> Option<Ty> { 728 fn builtin_deref(&self) -> Option<Ty> {
811 match self { 729 match self {
812 Ty::Apply(a_ty) => match a_ty.ctor { 730 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
813 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 731 Ty::RawPtr(.., parameters) => Some(Ty::clone(parameters.as_single())),
814 TypeCtor::RawPtr(..) => Some(Ty::clone(a_ty.parameters.as_single())),
815 _ => None,
816 },
817 _ => None, 732 _ => None,
818 } 733 }
819 } 734 }
820 735
821 pub fn as_fn_def(&self) -> Option<FunctionId> { 736 pub fn as_fn_def(&self) -> Option<FunctionId> {
822 match self { 737 match self {
823 &Ty::Apply(ApplicationTy { 738 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
824 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
825 ..
826 }) => Some(func),
827 _ => None, 739 _ => None,
828 } 740 }
829 } 741 }
830 742
831 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 743 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
832 match self { 744 match self {
833 Ty::Apply(a_ty) => match a_ty.ctor { 745 Ty::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
834 TypeCtor::FnPtr { is_varargs, .. } => { 746 Ty::FnDef(def, parameters) => {
835 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 747 let sig = db.callable_item_signature(*def);
836 } 748 Some(sig.subst(&parameters))
837 TypeCtor::FnDef(def) => { 749 }
838 let sig = db.callable_item_signature(def); 750 Ty::Closure(.., substs) => {
839 Some(sig.subst(&a_ty.parameters)) 751 let sig_param = &substs[0];
840 } 752 sig_param.callable_sig(db)
841 TypeCtor::Closure { .. } => { 753 }
842 let sig_param = &a_ty.parameters[0];
843 sig_param.callable_sig(db)
844 }
845 _ => None,
846 },
847 _ => None, 754 _ => None,
848 } 755 }
849 } 756 }
@@ -852,28 +759,66 @@ impl Ty {
852 /// the `Substs` for these type parameters with the given ones. (So e.g. if 759 /// the `Substs` for these type parameters with the given ones. (So e.g. if
853 /// `self` is `Option<_>` and the substs contain `u32`, we'll have 760 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
854 /// `Option<u32>` afterwards.) 761 /// `Option<u32>` afterwards.)
855 pub fn apply_substs(self, substs: Substs) -> Ty { 762 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
856 match self { 763 match &mut self {
857 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 764 Ty::Adt(_, substs)
858 assert_eq!(previous_substs.len(), substs.len()); 765 | Ty::Slice(substs)
859 Ty::Apply(ApplicationTy { ctor, parameters: substs }) 766 | Ty::Array(substs)
767 | Ty::RawPtr(_, substs)
768 | Ty::Ref(_, substs)
769 | Ty::FnDef(_, substs)
770 | Ty::Function(FnPointer { substs, .. })
771 | Ty::Tuple(_, substs)
772 | Ty::OpaqueType(_, substs)
773 | Ty::AssociatedType(_, substs)
774 | Ty::Closure(.., substs) => {
775 assert_eq!(substs.len(), new_substs.len());
776 *substs = new_substs;
860 } 777 }
861 _ => self, 778 _ => (),
862 } 779 }
780 self
863 } 781 }
864 782
865 /// Returns the type parameters of this type if it has some (i.e. is an ADT 783 /// Returns the type parameters of this type if it has some (i.e. is an ADT
866 /// or function); so if `self` is `Option<u32>`, this returns the `u32`. 784 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
867 pub fn substs(&self) -> Option<Substs> { 785 pub fn substs(&self) -> Option<&Substs> {
868 match self { 786 match self {
869 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 787 Ty::Adt(_, substs)
788 | Ty::Slice(substs)
789 | Ty::Array(substs)
790 | Ty::RawPtr(_, substs)
791 | Ty::Ref(_, substs)
792 | Ty::FnDef(_, substs)
793 | Ty::Function(FnPointer { substs, .. })
794 | Ty::Tuple(_, substs)
795 | Ty::OpaqueType(_, substs)
796 | Ty::AssociatedType(_, substs)
797 | Ty::Closure(.., substs) => Some(substs),
798 _ => None,
799 }
800 }
801
802 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
803 match self {
804 Ty::Adt(_, substs)
805 | Ty::Slice(substs)
806 | Ty::Array(substs)
807 | Ty::RawPtr(_, substs)
808 | Ty::Ref(_, substs)
809 | Ty::FnDef(_, substs)
810 | Ty::Function(FnPointer { substs, .. })
811 | Ty::Tuple(_, substs)
812 | Ty::OpaqueType(_, substs)
813 | Ty::AssociatedType(_, substs)
814 | Ty::Closure(.., substs) => Some(substs),
870 _ => None, 815 _ => None,
871 } 816 }
872 } 817 }
873 818
874 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 819 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
875 match self { 820 match self {
876 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 821 Ty::OpaqueType(opaque_ty_id, ..) => {
877 match opaque_ty_id { 822 match opaque_ty_id {
878 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 823 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
879 let krate = def.module(db.upcast()).krate(); 824 let krate = def.module(db.upcast()).krate();
@@ -934,7 +879,7 @@ impl Ty {
934 879
935 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 880 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
936 match self { 881 match self {
937 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 882 Ty::AssociatedType(type_alias_id, ..) => {
938 match type_alias_id.lookup(db.upcast()).container { 883 match type_alias_id.lookup(db.upcast()).container {
939 AssocContainerId::TraitId(trait_id) => Some(trait_id), 884 AssocContainerId::TraitId(trait_id) => Some(trait_id),
940 _ => None, 885 _ => None,
@@ -1049,11 +994,6 @@ pub trait TypeWalk {
1049impl TypeWalk for Ty { 994impl TypeWalk for Ty {
1050 fn walk(&self, f: &mut impl FnMut(&Ty)) { 995 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1051 match self { 996 match self {
1052 Ty::Apply(a_ty) => {
1053 for t in a_ty.parameters.iter() {
1054 t.walk(f);
1055 }
1056 }
1057 Ty::Projection(p_ty) => { 997 Ty::Projection(p_ty) => {
1058 for t in p_ty.parameters.iter() { 998 for t in p_ty.parameters.iter() {
1059 t.walk(f); 999 t.walk(f);
@@ -1069,7 +1009,13 @@ impl TypeWalk for Ty {
1069 t.walk(f); 1009 t.walk(f);
1070 } 1010 }
1071 } 1011 }
1072 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1012 _ => {
1013 if let Some(substs) = self.substs() {
1014 for t in substs.iter() {
1015 t.walk(f);
1016 }
1017 }
1018 }
1073 } 1019 }
1074 f(self); 1020 f(self);
1075 } 1021 }
@@ -1080,9 +1026,6 @@ impl TypeWalk for Ty {
1080 binders: DebruijnIndex, 1026 binders: DebruijnIndex,
1081 ) { 1027 ) {
1082 match self { 1028 match self {
1083 Ty::Apply(a_ty) => {
1084 a_ty.parameters.walk_mut_binders(f, binders);
1085 }
1086 Ty::Projection(p_ty) => { 1029 Ty::Projection(p_ty) => {
1087 p_ty.parameters.walk_mut_binders(f, binders); 1030 p_ty.parameters.walk_mut_binders(f, binders);
1088 } 1031 }
@@ -1094,7 +1037,11 @@ impl TypeWalk for Ty {
1094 Ty::Opaque(o_ty) => { 1037 Ty::Opaque(o_ty) => {
1095 o_ty.parameters.walk_mut_binders(f, binders); 1038 o_ty.parameters.walk_mut_binders(f, binders);
1096 } 1039 }
1097 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1040 _ => {
1041 if let Some(substs) = self.substs_mut() {
1042 substs.walk_mut_binders(f, binders);
1043 }
1044 }
1098 } 1045 }
1099 f(self, binders); 1046 f(self, binders);
1100 } 1047 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 99b0ecf3b..44bd95a9a 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 Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, OpaqueTy,
35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, 35 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,27 +157,28 @@ 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::RawPtr(*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::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
@@ -414,7 +412,6 @@ impl Ty {
414 // FIXME: report error 412 // FIXME: report error
415 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 413 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
416 }; 414 };
417
418 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 415 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments)
419 } 416 }
420 417
@@ -1017,7 +1014,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1017 let ret = Ty::from_hir(&ctx_ret, &data.ret_type); 1014 let ret = Ty::from_hir(&ctx_ret, &data.ret_type);
1018 let generics = generics(db.upcast(), def.into()); 1015 let generics = generics(db.upcast(), def.into());
1019 let num_binders = generics.len(); 1016 let num_binders = generics.len();
1020 Binders::new(num_binders, FnSig::from_params_and_return(params, ret, data.is_varargs)) 1017 Binders::new(num_binders, CallableSig::from_params_and_return(params, ret, data.is_varargs))
1021} 1018}
1022 1019
1023/// Build the declared type of a function. This should not need to look at the 1020/// Build the declared type of a function. This should not need to look at the
@@ -1025,7 +1022,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1022fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1026 let generics = generics(db.upcast(), def.into()); 1023 let generics = generics(db.upcast(), def.into());
1027 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1024 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1028 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1025 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1029} 1026}
1030 1027
1031/// Build the declared type of a const. 1028/// Build the declared type of a const.
@@ -1057,7 +1054,7 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
1057 let params = 1054 let params =
1058 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1055 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1059 let ret = type_for_adt(db, def.into()); 1056 let ret = type_for_adt(db, def.into());
1060 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1057 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1061} 1058}
1062 1059
1063/// Build the type of a tuple struct constructor. 1060/// Build the type of a tuple struct constructor.
@@ -1068,7 +1065,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1068 } 1065 }
1069 let generics = generics(db.upcast(), def.into()); 1066 let generics = generics(db.upcast(), def.into());
1070 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1067 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1071 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1068 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1072} 1069}
1073 1070
1074fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1071fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1081,7 +1078,7 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
1081 let params = 1078 let params =
1082 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>(); 1079 fields.iter().map(|(_, field)| Ty::from_hir(&ctx, &field.type_ref)).collect::<Vec<_>>();
1083 let ret = type_for_adt(db, def.parent.into()); 1080 let ret = type_for_adt(db, def.parent.into());
1084 Binders::new(ret.num_binders, FnSig::from_params_and_return(params, ret.value, false)) 1081 Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
1085} 1082}
1086 1083
1087/// Build the type of a tuple enum variant constructor. 1084/// Build the type of a tuple enum variant constructor.
@@ -1093,13 +1090,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1093 } 1090 }
1094 let generics = generics(db.upcast(), def.parent.into()); 1091 let generics = generics(db.upcast(), def.parent.into());
1095 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1092 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1096 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1093 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1097} 1094}
1098 1095
1099fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1096fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1100 let generics = generics(db.upcast(), adt.into()); 1097 let generics = generics(db.upcast(), adt.into());
1101 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1098 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1102 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) 1099 Binders::new(substs.len(), Ty::Adt(adt, substs))
1103} 1100}
1104 1101
1105fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1102fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1107,10 +1104,10 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1107 let resolver = t.resolver(db.upcast()); 1104 let resolver = t.resolver(db.upcast());
1108 let ctx = 1105 let ctx =
1109 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1106 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 { 1107 if db.type_alias_data(t).is_extern {
1112 Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) 1108 Binders::new(0, Ty::ForeignType(t))
1113 } else { 1109 } else {
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1114 let type_ref = &db.type_alias_data(t).type_ref; 1111 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)); 1112 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
1116 Binders::new(substs.len(), inner) 1113 Binders::new(substs.len(), inner)
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 66d8de959..c8a0ad5f1 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -7,8 +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 lang_item::LangItemTarget, type_ref::Mutability, AssocContainerId, AssocItemId, FunctionId, 10 lang_item::LangItemTarget, type_ref::Mutability, AdtId, AssocContainerId, AssocItemId,
11 GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, 11 FunctionId, GenericDefId, HasModule, ImplId, Lookup, ModuleId, TraitId, TypeAliasId,
12}; 12};
13use hir_expand::name::Name; 13use hir_expand::name::Name;
14use rustc_hash::{FxHashMap, FxHashSet}; 14use rustc_hash::{FxHashMap, FxHashSet};
@@ -18,15 +18,24 @@ use crate::{
18 db::HirDatabase, 18 db::HirDatabase,
19 primitive::{self, FloatTy, IntTy, UintTy}, 19 primitive::{self, FloatTy, IntTy, UintTy},
20 utils::all_super_traits, 20 utils::all_super_traits,
21 ApplicationTy, Canonical, DebruijnIndex, InEnvironment, Scalar, Substs, TraitEnvironment, 21 Canonical, DebruijnIndex, FnPointer, FnSig, InEnvironment, Scalar, Substs, TraitEnvironment,
22 TraitRef, Ty, TyKind, TypeCtor, TypeWalk, 22 TraitRef, Ty, TyKind, TypeWalk,
23}; 23};
24 24
25/// This is used as a key for indexing impls. 25/// This is used as a key for indexing impls.
26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] 26#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
27pub enum TyFingerprint { 27pub enum TyFingerprint {
28 Apply(TypeCtor), 28 Str,
29 Slice,
30 Array,
31 Never,
32 RawPtr(Mutability),
33 Scalar(Scalar),
34 Adt(AdtId),
29 Dyn(TraitId), 35 Dyn(TraitId),
36 Tuple(usize),
37 ForeignType(TypeAliasId),
38 FnPtr(usize, FnSig),
30} 39}
31 40
32impl TyFingerprint { 41impl TyFingerprint {
@@ -34,32 +43,42 @@ impl TyFingerprint {
34 /// 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
35 /// `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.
36 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> { 45 pub(crate) fn for_impl(ty: &Ty) -> Option<TyFingerprint> {
37 match ty { 46 let fp = match ty {
38 Ty::Apply(a_ty) => Some(TyFingerprint::Apply(a_ty.ctor)), 47 &Ty::Str => TyFingerprint::Str,
39 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_)), 48 &Ty::Never => TyFingerprint::Never,
40 _ => None, 49 &Ty::Slice(..) => TyFingerprint::Slice,
41 } 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::RawPtr(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)
42 } 61 }
43} 62}
44 63
45pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 64pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
46 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), 65 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
47 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), 66 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
48 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), 67 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
49 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), 68 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
50 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), 69 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
51 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), 70 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
52 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), 71 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
53 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), 72 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
54 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), 73 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
55 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), 74 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
56 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), 75 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
57 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), 76 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
58]; 77];
59 78
60pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 79pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
61 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), 80 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
62 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), 81 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
63]; 82];
64 83
65/// Trait impls defined or available in some crate. 84/// Trait impls defined or available in some crate.
@@ -211,32 +230,29 @@ impl Ty {
211 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());
212 231
213 let lang_item_targets = match self { 232 let lang_item_targets = match self {
214 Ty::Apply(a_ty) => match a_ty.ctor { 233 Ty::Adt(def_id, _) => {
215 TypeCtor::Adt(def_id) => { 234 return mod_to_crate_ids(def_id.module(db.upcast()));
216 return mod_to_crate_ids(def_id.module(db.upcast())); 235 }
217 } 236 Ty::ForeignType(type_alias_id) => {
218 TypeCtor::ForeignType(type_alias_id) => { 237 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast()));
219 return mod_to_crate_ids(type_alias_id.lookup(db.upcast()).module(db.upcast())); 238 }
220 } 239 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
221 TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 240 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"),
222 TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), 241 Ty::Scalar(Scalar::Float(f)) => match f {
223 TypeCtor::Scalar(Scalar::Float(f)) => match f { 242 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime)
224 // There are two lang items: one in libcore (fXX) and one in libstd (fXX_runtime) 243 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
225 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 244 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
226 FloatTy::F64 => lang_item_crate!("f64", "f64_runtime"),
227 },
228 TypeCtor::Scalar(Scalar::Int(t)) => {
229 lang_item_crate!(primitive::int_ty_to_string(t))
230 }
231 TypeCtor::Scalar(Scalar::Uint(t)) => {
232 lang_item_crate!(primitive::uint_ty_to_string(t))
233 }
234 TypeCtor::Str => lang_item_crate!("str_alloc", "str"),
235 TypeCtor::Slice => lang_item_crate!("slice_alloc", "slice"),
236 TypeCtor::RawPtr(Mutability::Shared) => lang_item_crate!("const_ptr"),
237 TypeCtor::RawPtr(Mutability::Mut) => lang_item_crate!("mut_ptr"),
238 _ => return None,
239 }, 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::RawPtr(Mutability::Shared, _) => lang_item_crate!("const_ptr"),
255 Ty::RawPtr(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
240 Ty::Dyn(_) => { 256 Ty::Dyn(_) => {
241 return self.dyn_trait().and_then(|trait_| { 257 return self.dyn_trait().and_then(|trait_| {
242 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 258 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
@@ -413,7 +429,7 @@ fn iterate_method_candidates_with_autoref(
413 } 429 }
414 let refed = Canonical { 430 let refed = Canonical {
415 kinds: deref_chain[0].kinds.clone(), 431 kinds: deref_chain[0].kinds.clone(),
416 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())),
417 }; 433 };
418 if iterate_method_candidates_by_receiver( 434 if iterate_method_candidates_by_receiver(
419 &refed, 435 &refed,
@@ -429,7 +445,7 @@ fn iterate_method_candidates_with_autoref(
429 } 445 }
430 let ref_muted = Canonical { 446 let ref_muted = Canonical {
431 kinds: deref_chain[0].kinds.clone(), 447 kinds: deref_chain[0].kinds.clone(),
432 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())),
433 }; 449 };
434 if iterate_method_candidates_by_receiver( 450 if iterate_method_candidates_by_receiver(
435 &ref_muted, 451 &ref_muted,
@@ -756,11 +772,9 @@ fn autoderef_method_receiver(
756) -> Vec<Canonical<Ty>> { 772) -> Vec<Canonical<Ty>> {
757 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();
758 // 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!)
759 if let Some(Ty::Apply(ApplicationTy { ctor: TypeCtor::Array, parameters })) = 775 if let Some(Ty::Array(parameters)) = deref_chain.last().map(|ty| &ty.value) {
760 deref_chain.last().map(|ty| &ty.value)
761 {
762 let kinds = deref_chain.last().unwrap().kinds.clone(); 776 let kinds = deref_chain.last().unwrap().kinds.clone();
763 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 777 let unsized_ty = Ty::Slice(parameters.clone());
764 deref_chain.push(Canonical { value: unsized_ty, kinds }) 778 deref_chain.push(Canonical { value: unsized_ty, kinds })
765 } 779 }
766 deref_chain 780 deref_chain
diff --git a/crates/hir_ty/src/op.rs b/crates/hir_ty/src/op.rs
index a4999c51d..1c01a67ad 100644
--- a/crates/hir_ty/src/op.rs
+++ b/crates/hir_ty/src/op.rs
@@ -1,30 +1,23 @@
1//! Helper functions for binary operator type inference. 1//! Helper functions for binary operator type inference.
2use hir_def::expr::{ArithOp, BinaryOp, CmpOp}; 2use hir_def::expr::{ArithOp, BinaryOp, CmpOp};
3 3
4use super::{InferTy, Ty, TypeCtor}; 4use crate::{InferTy, Scalar, Ty};
5use crate::{ApplicationTy, Scalar};
6 5
7pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty { 6pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
8 match op { 7 match op {
9 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), 8 BinaryOp::LogicOp(_) | BinaryOp::CmpOp(_) => Ty::Scalar(Scalar::Bool),
10 BinaryOp::Assignment { .. } => Ty::unit(), 9 BinaryOp::Assignment { .. } => Ty::unit(),
11 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty { 10 BinaryOp::ArithOp(ArithOp::Shl) | BinaryOp::ArithOp(ArithOp::Shr) => match lhs_ty {
12 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 11 Ty::Scalar(Scalar::Int(_))
13 TypeCtor::Scalar(Scalar::Int(_)) 12 | Ty::Scalar(Scalar::Uint(_))
14 | TypeCtor::Scalar(Scalar::Uint(_)) 13 | Ty::Scalar(Scalar::Float(_)) => lhs_ty,
15 | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty,
16 _ => Ty::Unknown,
17 },
18 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 14 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
19 _ => Ty::Unknown, 15 _ => Ty::Unknown,
20 }, 16 },
21 BinaryOp::ArithOp(_) => match rhs_ty { 17 BinaryOp::ArithOp(_) => match rhs_ty {
22 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 18 Ty::Scalar(Scalar::Int(_))
23 TypeCtor::Scalar(Scalar::Int(_)) 19 | Ty::Scalar(Scalar::Uint(_))
24 | TypeCtor::Scalar(Scalar::Uint(_)) 20 | Ty::Scalar(Scalar::Float(_)) => rhs_ty,
25 | TypeCtor::Scalar(Scalar::Float(_)) => rhs_ty,
26 _ => Ty::Unknown,
27 },
28 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty, 21 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => rhs_ty,
29 _ => Ty::Unknown, 22 _ => Ty::Unknown,
30 }, 23 },
@@ -33,13 +26,10 @@ pub(super) fn binary_op_return_ty(op: BinaryOp, lhs_ty: Ty, rhs_ty: Ty) -> Ty {
33 26
34pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty { 27pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
35 match op { 28 match op {
36 BinaryOp::LogicOp(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), 29 BinaryOp::LogicOp(..) => Ty::Scalar(Scalar::Bool),
37 BinaryOp::Assignment { op: None } => lhs_ty, 30 BinaryOp::Assignment { op: None } => lhs_ty,
38 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty { 31 BinaryOp::CmpOp(CmpOp::Eq { .. }) => match lhs_ty {
39 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 32 Ty::Scalar(_) | Ty::Str => lhs_ty,
40 TypeCtor::Scalar(_) | TypeCtor::Str => lhs_ty,
41 _ => Ty::Unknown,
42 },
43 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 33 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
44 _ => Ty::Unknown, 34 _ => Ty::Unknown,
45 }, 35 },
@@ -47,12 +37,9 @@ pub(super) fn binary_op_rhs_expectation(op: BinaryOp, lhs_ty: Ty) -> Ty {
47 BinaryOp::CmpOp(CmpOp::Ord { .. }) 37 BinaryOp::CmpOp(CmpOp::Ord { .. })
48 | BinaryOp::Assignment { op: Some(_) } 38 | BinaryOp::Assignment { op: Some(_) }
49 | BinaryOp::ArithOp(_) => match lhs_ty { 39 | BinaryOp::ArithOp(_) => match lhs_ty {
50 Ty::Apply(ApplicationTy { ctor, .. }) => match ctor { 40 Ty::Scalar(Scalar::Int(_))
51 TypeCtor::Scalar(Scalar::Int(_)) 41 | Ty::Scalar(Scalar::Uint(_))
52 | TypeCtor::Scalar(Scalar::Uint(_)) 42 | Ty::Scalar(Scalar::Float(_)) => lhs_ty,
53 | TypeCtor::Scalar(Scalar::Float(_)) => lhs_ty,
54 _ => Ty::Unknown,
55 },
56 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty, 43 Ty::Infer(InferTy::IntVar(..)) | Ty::Infer(InferTy::FloatVar(..)) => lhs_ty,
57 _ => Ty::Unknown, 44 _ => Ty::Unknown,
58 }, 45 },
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/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index d74c83737..3f5f5091f 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,
@@ -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(),
@@ -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 5a3cb7906..60d74e21a 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -16,9 +16,8 @@ use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 primitive::UintTy, 17 primitive::UintTy,
18 traits::{Canonical, Obligation}, 18 traits::{Canonical, Obligation},
19 ApplicationTy, CallableDefId, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, 19 CallableDefId, FnPointer, FnSig, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId,
20 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, 20 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind,
21 TypeCtor,
22}; 21};
23 22
24use super::interner::*; 23use super::interner::*;
@@ -28,75 +27,67 @@ impl ToChalk for Ty {
28 type Chalk = chalk_ir::Ty<Interner>; 27 type Chalk = chalk_ir::Ty<Interner>;
29 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> { 28 fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Ty<Interner> {
30 match self { 29 match self {
31 Ty::Apply(apply_ty) => match apply_ty.ctor { 30 Ty::Ref(m, parameters) => ref_to_chalk(db, m, parameters),
32 TypeCtor::Ref(m) => ref_to_chalk(db, m, apply_ty.parameters), 31 Ty::Array(parameters) => array_to_chalk(db, parameters),
33 TypeCtor::Array => array_to_chalk(db, apply_ty.parameters), 32 Ty::Function(FnPointer { sig: FnSig { variadic }, substs, .. }) => {
34 TypeCtor::FnPtr { num_args: _, is_varargs } => { 33 let substitution = chalk_ir::FnSubst(substs.to_chalk(db).shifted_in(&Interner));
35 let substitution = 34 chalk_ir::TyKind::Function(chalk_ir::FnPointer {
36 chalk_ir::FnSubst(apply_ty.parameters.to_chalk(db).shifted_in(&Interner)); 35 num_binders: 0,
37 chalk_ir::TyKind::Function(chalk_ir::FnPointer { 36 sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic },
38 num_binders: 0, 37 substitution,
39 sig: chalk_ir::FnSig { 38 })
40 abi: (), 39 .intern(&Interner)
41 safety: chalk_ir::Safety::Safe, 40 }
42 variadic: is_varargs, 41 Ty::AssociatedType(type_alias, substs) => {
43 }, 42 let assoc_type = TypeAliasAsAssocType(type_alias);
44 substitution, 43 let assoc_type_id = assoc_type.to_chalk(db);
45 }) 44 let substitution = substs.to_chalk(db);
46 .intern(&Interner) 45 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
47 } 46 }
48 TypeCtor::AssociatedType(type_alias) => {
49 let assoc_type = TypeAliasAsAssocType(type_alias);
50 let assoc_type_id = assoc_type.to_chalk(db);
51 let substitution = apply_ty.parameters.to_chalk(db);
52 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
53 }
54 47
55 TypeCtor::OpaqueType(impl_trait_id) => { 48 Ty::OpaqueType(impl_trait_id, substs) => {
56 let id = impl_trait_id.to_chalk(db); 49 let id = impl_trait_id.to_chalk(db);
57 let substitution = apply_ty.parameters.to_chalk(db); 50 let substitution = substs.to_chalk(db);
58 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) 51 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
59 } 52 }
60 53
61 TypeCtor::ForeignType(type_alias) => { 54 Ty::ForeignType(type_alias) => {
62 let foreign_type = TypeAliasAsForeignType(type_alias); 55 let foreign_type = TypeAliasAsForeignType(type_alias);
63 let foreign_type_id = foreign_type.to_chalk(db); 56 let foreign_type_id = foreign_type.to_chalk(db);
64 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) 57 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
65 } 58 }
66 59
67 TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), 60 Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
68 61
69 TypeCtor::Tuple { cardinality } => { 62 Ty::Tuple(cardinality, substs) => {
70 let substitution = apply_ty.parameters.to_chalk(db); 63 let substitution = substs.to_chalk(db);
71 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 64 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
72 } 65 }
73 TypeCtor::RawPtr(mutability) => { 66 Ty::RawPtr(mutability, substs) => {
74 let ty = apply_ty.parameters[0].clone().to_chalk(db); 67 let ty = substs[0].clone().to_chalk(db);
75 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) 68 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner)
76 } 69 }
77 TypeCtor::Slice => { 70 Ty::Slice(substs) => {
78 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)
79 .intern(&Interner) 72 }
80 } 73 Ty::Str => chalk_ir::TyKind::Str.intern(&Interner),
81 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), 74 Ty::FnDef(callable_def, substs) => {
82 TypeCtor::FnDef(callable_def) => { 75 let id = callable_def.to_chalk(db);
83 let id = callable_def.to_chalk(db); 76 let substitution = substs.to_chalk(db);
84 let substitution = apply_ty.parameters.to_chalk(db); 77 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
85 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) 78 }
86 } 79 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner),
87 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
88 80
89 TypeCtor::Closure { def, expr } => { 81 Ty::Closure(def, expr, substs) => {
90 let closure_id = db.intern_closure((def, expr)); 82 let closure_id = db.intern_closure((def, expr));
91 let substitution = apply_ty.parameters.to_chalk(db); 83 let substitution = substs.to_chalk(db);
92 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 84 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
93 } 85 }
94 86
95 TypeCtor::Adt(adt_id) => { 87 Ty::Adt(adt_id, substs) => {
96 let substitution = apply_ty.parameters.to_chalk(db); 88 let substitution = substs.to_chalk(db);
97 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)
98 } 90 }
99 },
100 Ty::Projection(proj_ty) => { 91 Ty::Projection(proj_ty) => {
101 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);
102 let substitution = proj_ty.parameters.to_chalk(db); 93 let substitution = proj_ty.parameters.to_chalk(db);
@@ -143,9 +134,7 @@ impl ToChalk for Ty {
143 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 {
144 match chalk.data(&Interner).kind.clone() { 135 match chalk.data(&Interner).kind.clone() {
145 chalk_ir::TyKind::Error => Ty::Unknown, 136 chalk_ir::TyKind::Error => Ty::Unknown,
146 chalk_ir::TyKind::Array(ty, _size) => { 137 chalk_ir::TyKind::Array(ty, _size) => Ty::Array(Substs::single(from_chalk(db, ty))),
147 Ty::apply(TypeCtor::Array, Substs::single(from_chalk(db, ty)))
148 }
149 chalk_ir::TyKind::Placeholder(idx) => { 138 chalk_ir::TyKind::Placeholder(idx) => {
150 assert_eq!(idx.ui, UniverseIndex::ROOT); 139 assert_eq!(idx.ui, UniverseIndex::ROOT);
151 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 140 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
@@ -171,16 +160,14 @@ impl ToChalk for Ty {
171 .. 160 ..
172 }) => { 161 }) => {
173 assert_eq!(num_binders, 0); 162 assert_eq!(num_binders, 0);
174 let parameters: Substs = from_chalk( 163 let substs: Substs = from_chalk(
175 db, 164 db,
176 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"),
177 ); 166 );
178 Ty::Apply(ApplicationTy { 167 Ty::Function(FnPointer {
179 ctor: TypeCtor::FnPtr { 168 num_args: (substs.len() - 1),
180 num_args: (parameters.len() - 1) as u16, 169 sig: FnSig { variadic },
181 is_varargs: variadic, 170 substs,
182 },
183 parameters,
184 }) 171 })
185 } 172 }
186 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), 173 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
@@ -196,60 +183,49 @@ impl ToChalk for Ty {
196 Ty::Dyn(predicates) 183 Ty::Dyn(predicates)
197 } 184 }
198 185
199 chalk_ir::TyKind::Adt(struct_id, subst) => { 186 chalk_ir::TyKind::Adt(struct_id, subst) => Ty::Adt(struct_id.0, from_chalk(db, subst)),
200 apply_ty_from_chalk(db, TypeCtor::Adt(struct_id.0), subst) 187 chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType(
201 } 188 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0,
202 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( 189 from_chalk(db, subst),
203 db,
204 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
205 subst,
206 ), 190 ),
191
207 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { 192 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
208 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))
209 } 194 }
210 195
211 chalk_ir::TyKind::Scalar(scalar) => Ty::simple(TypeCtor::Scalar(scalar)), 196 chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar),
212 chalk_ir::TyKind::Tuple(cardinality, subst) => { 197 chalk_ir::TyKind::Tuple(cardinality, subst) => {
213 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) 198 Ty::Tuple(cardinality, from_chalk(db, subst))
214 } 199 }
215 chalk_ir::TyKind::Raw(mutability, ty) => { 200 chalk_ir::TyKind::Raw(mutability, ty) => {
216 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) 201 Ty::RawPtr(from_chalk(db, mutability), Substs::single(from_chalk(db, ty)))
217 } 202 }
218 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))),
219 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { 204 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
220 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)))
221 } 206 }
222 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), 207 chalk_ir::TyKind::Str => Ty::Str,
223 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), 208 chalk_ir::TyKind::Never => Ty::Never,
224 209
225 chalk_ir::TyKind::FnDef(fn_def_id, subst) => { 210 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
226 let callable_def = from_chalk(db, fn_def_id); 211 Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst))
227 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
228 } 212 }
229 213
230 chalk_ir::TyKind::Closure(id, subst) => { 214 chalk_ir::TyKind::Closure(id, subst) => {
231 let id: crate::db::ClosureId = id.into(); 215 let id: crate::db::ClosureId = id.into();
232 let (def, expr) = db.lookup_intern_closure(id); 216 let (def, expr) = db.lookup_intern_closure(id);
233 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) 217 Ty::Closure(def, expr, from_chalk(db, subst))
234 } 218 }
235 219
236 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( 220 chalk_ir::TyKind::Foreign(foreign_def_id) => {
237 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, 221 Ty::ForeignType(from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0)
238 )), 222 }
239 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME 223 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
240 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME 224 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
241 } 225 }
242 } 226 }
243} 227}
244 228
245fn apply_ty_from_chalk(
246 db: &dyn HirDatabase,
247 ctor: TypeCtor,
248 subst: chalk_ir::Substitution<Interner>,
249) -> Ty {
250 Ty::Apply(ApplicationTy { ctor, parameters: from_chalk(db, subst) })
251}
252
253/// 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
254/// 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.
255fn ref_to_chalk( 231fn ref_to_chalk(