aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-02-28 19:16:51 +0000
committerGitHub <[email protected]>2021-02-28 19:16:51 +0000
commit2fc137b70f9d455676cc99a1a5c7e6e10c3e7cc2 (patch)
treeb9bc6434404e99a0829d01b08285d37f6faa3d2d /crates/hir_ty
parent0a913fd11194faff9c0100bc78f2d4fe682075aa (diff)
parentfaf2dd49e4845e1437b704a28bb5603be5fd605b (diff)
Merge #7813
7813: Inline TypeCtor into Ty r=flodiebold a=Veykril This removes the `ApplicationTy` variant from `Ty` bringing the representation a lot closer to chalk's `TyKind`. Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_ty')
-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.rs175
-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.rs238
-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.rs490
-rw-r--r--crates/hir_ty/src/lower.rs33
-rw-r--r--crates/hir_ty/src/method_resolution.rs126
-rw-r--r--crates/hir_ty/src/op.rs39
-rw-r--r--crates/hir_ty/src/traits/chalk.rs9
-rw-r--r--crates/hir_ty/src/traits/chalk/mapping.rs189
15 files changed, 648 insertions, 837 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..cd9dcf6c0 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, FnSig, GenericPredicate, Lifetime,
7 GenericPredicate, Lifetime, Obligation, OpaqueTy, OpaqueTyId, ProjectionTy, Scalar, Substs, 7 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::FnPtr { is_varargs, substs, .. } => {
325 let sig = FnSig::from_fn_ptr_substs(&self.parameters, is_varargs); 345 let sig = FnSig::from_fn_ptr_substs(&substs, *is_varargs);
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,59 @@ 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, parameters) => {
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 { 477 if parameters.len() > 0 {
460 write!(f, "<")?; 478 write!(f, "<")?;
461 f.write_joined(&*self.parameters.0, ", ")?; 479 f.write_joined(&*parameters.0, ", ")?;
462 write!(f, ">")?; 480 write!(f, ">")?;
463 } 481 }
464 } 482 }
465 TypeCtor::OpaqueType(opaque_ty_id) => { 483 Ty::OpaqueType(opaque_ty_id, parameters) => {
466 match opaque_ty_id { 484 match opaque_ty_id {
467 OpaqueTyId::ReturnTypeImplTrait(func, idx) => { 485 &OpaqueTyId::ReturnTypeImplTrait(func, idx) => {
468 let datas = 486 let datas =
469 f.db.return_type_impl_traits(func).expect("impl trait id without data"); 487 f.db.return_type_impl_traits(func).expect("impl trait id without data");
470 let data = (*datas) 488 let data = (*datas)
471 .as_ref() 489 .as_ref()
472 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 490 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
473 let bounds = data.subst(&self.parameters); 491 let bounds = data.subst(&parameters);
474 write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?; 492 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 493 // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
476 } 494 }
477 OpaqueTyId::AsyncBlockTypeImplTrait(..) => { 495 OpaqueTyId::AsyncBlockTypeImplTrait(..) => {
478 write!(f, "impl Future<Output = ")?; 496 write!(f, "impl Future<Output = ")?;
479 self.parameters[0].hir_fmt(f)?; 497 parameters[0].hir_fmt(f)?;
480 write!(f, ">")?; 498 write!(f, ">")?;
481 } 499 }
482 } 500 }
483 } 501 }
484 TypeCtor::Closure { .. } => { 502 Ty::Closure { substs, .. } => {
485 let sig = self.parameters[0].callable_sig(f.db); 503 let sig = substs[0].callable_sig(f.db);
486 if let Some(sig) = sig { 504 if let Some(sig) = sig {
487 if sig.params().is_empty() { 505 if sig.params().is_empty() {
488 write!(f, "||")?; 506 write!(f, "||")?;
@@ -505,43 +523,6 @@ impl HirDisplay for ApplicationTy {
505 write!(f, "{{closure}}")?; 523 write!(f, "{{closure}}")?;
506 } 524 }
507 } 525 }
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)?, 526 Ty::Projection(p_ty) => p_ty.hir_fmt(f)?,
546 Ty::Placeholder(id) => { 527 Ty::Placeholder(id) => {
547 let generics = generics(f.db.upcast(), id.parent); 528 let generics = generics(f.db.upcast(), id.parent);
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..cd5fb3252 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::FnPtr { .. }) => 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::FnPtr { .. }) => {
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..2369c9bef 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, InferTy, Mutability, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
22 Scalar, Substs, TraitRef, Ty, TypeCtor, 22 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 { cardinality: num_args as u16, substs: 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,13 @@ 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::FnPtr {
260 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 251 num_args: sig_tys.len() as u16 - 1,
261 Substs(sig_tys.clone().into()), 252 is_varargs: false,
262 ); 253 substs: Substs(sig_tys.clone().into()),
254 };
263 let closure_ty = 255 let closure_ty =
264 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 256 Ty::Closure { def: self.owner, expr: tgt_expr, substs: Substs::single(sig_ty) };
265 257
266 // Eagerly try to relate the closure type with the expected 258 // Eagerly try to relate the closure type with the expected
267 // type, otherwise we often won't have enough information to 259 // type, otherwise we often won't have enough information to
@@ -312,11 +304,8 @@ impl<'a> InferenceContext<'a> {
312 Expr::Match { expr, arms } => { 304 Expr::Match { expr, arms } => {
313 let input_ty = self.infer_expr(*expr, &Expectation::none()); 305 let input_ty = self.infer_expr(*expr, &Expectation::none());
314 306
315 let mut result_ty = if arms.is_empty() { 307 let mut result_ty =
316 Ty::simple(TypeCtor::Never) 308 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
317 } else {
318 self.table.new_type_var()
319 };
320 309
321 let matchee_diverges = self.diverges; 310 let matchee_diverges = self.diverges;
322 let mut all_arms_diverge = Diverges::Always; 311 let mut all_arms_diverge = Diverges::Always;
@@ -327,7 +316,7 @@ impl<'a> InferenceContext<'a> {
327 if let Some(guard_expr) = arm.guard { 316 if let Some(guard_expr) = arm.guard {
328 self.infer_expr( 317 self.infer_expr(
329 guard_expr, 318 guard_expr,
330 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool))), 319 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
331 ); 320 );
332 } 321 }
333 322
@@ -345,7 +334,7 @@ impl<'a> InferenceContext<'a> {
345 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 334 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
346 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 335 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
347 } 336 }
348 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 337 Expr::Continue { .. } => Ty::Never,
349 Expr::Break { expr, label } => { 338 Expr::Break { expr, label } => {
350 let val_ty = if let Some(expr) = expr { 339 let val_ty = if let Some(expr) = expr {
351 self.infer_expr(*expr, &Expectation::none()) 340 self.infer_expr(*expr, &Expectation::none())
@@ -370,8 +359,7 @@ impl<'a> InferenceContext<'a> {
370 expr: tgt_expr, 359 expr: tgt_expr,
371 }); 360 });
372 } 361 }
373 362 Ty::Never
374 Ty::simple(TypeCtor::Never)
375 } 363 }
376 Expr::Return { expr } => { 364 Expr::Return { expr } => {
377 if let Some(expr) = expr { 365 if let Some(expr) = expr {
@@ -380,14 +368,14 @@ impl<'a> InferenceContext<'a> {
380 let unit = Ty::unit(); 368 let unit = Ty::unit();
381 self.coerce(&unit, &self.return_ty.clone()); 369 self.coerce(&unit, &self.return_ty.clone());
382 } 370 }
383 Ty::simple(TypeCtor::Never) 371 Ty::Never
384 } 372 }
385 Expr::Yield { expr } => { 373 Expr::Yield { expr } => {
386 // FIXME: track yield type for coercion 374 // FIXME: track yield type for coercion
387 if let Some(expr) = expr { 375 if let Some(expr) = expr {
388 self.infer_expr(*expr, &Expectation::none()); 376 self.infer_expr(*expr, &Expectation::none());
389 } 377 }
390 Ty::simple(TypeCtor::Never) 378 Ty::Never
391 } 379 }
392 Expr::RecordLit { path, fields, spread } => { 380 Expr::RecordLit { path, fields, spread } => {
393 let (ty, def_id) = self.resolve_variant(path.as_ref()); 381 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -397,7 +385,7 @@ impl<'a> InferenceContext<'a> {
397 385
398 self.unify(&ty, &expected.ty); 386 self.unify(&ty, &expected.ty);
399 387
400 let substs = ty.substs().unwrap_or_else(Substs::empty); 388 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(); 389 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)); 390 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
403 for (field_idx, field) in fields.iter().enumerate() { 391 for (field_idx, field) in fields.iter().enumerate() {
@@ -436,30 +424,23 @@ impl<'a> InferenceContext<'a> {
436 }, 424 },
437 ) 425 )
438 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 426 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
439 Ty::Apply(a_ty) => match a_ty.ctor { 427 Ty::Tuple { substs, .. } => {
440 TypeCtor::Tuple { .. } => name 428 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
441 .as_tuple_index() 429 }
442 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 430 Ty::Adt(AdtId::StructId(s), parameters) => {
443 TypeCtor::Adt(AdtId::StructId(s)) => { 431 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| { 432 let field = FieldId { parent: s.into(), local_id };
445 let field = FieldId { parent: s.into(), local_id }; 433 self.write_field_resolution(tgt_expr, field);
446 self.write_field_resolution(tgt_expr, field); 434 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
447 self.db.field_types(s.into())[field.local_id] 435 })
448 .clone() 436 }
449 .subst(&a_ty.parameters) 437 Ty::Adt(AdtId::UnionId(u), parameters) => {
450 }) 438 self.db.union_data(u).variant_data.field(name).map(|local_id| {
451 } 439 let field = FieldId { parent: u.into(), local_id };
452 TypeCtor::Adt(AdtId::UnionId(u)) => { 440 self.write_field_resolution(tgt_expr, field);
453 self.db.union_data(u).variant_data.field(name).map(|local_id| { 441 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
454 let field = FieldId { parent: u.into(), local_id }; 442 })
455 self.write_field_resolution(tgt_expr, field); 443 }
456 self.db.field_types(u.into())[field.local_id]
457 .clone()
458 .subst(&a_ty.parameters)
459 })
460 }
461 _ => None,
462 },
463 _ => None, 444 _ => None,
464 }) 445 })
465 .unwrap_or(Ty::Unknown); 446 .unwrap_or(Ty::Unknown);
@@ -497,19 +478,18 @@ impl<'a> InferenceContext<'a> {
497 Expectation::none() 478 Expectation::none()
498 }; 479 };
499 let inner_ty = self.infer_expr_inner(*expr, &expectation); 480 let inner_ty = self.infer_expr_inner(*expr, &expectation);
500 let ty = match rawness { 481 match rawness {
501 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 482 Rawness::RawPtr => Ty::RawPtr(*mutability, Substs::single(inner_ty)),
502 Rawness::Ref => TypeCtor::Ref(*mutability), 483 Rawness::Ref => Ty::Ref(*mutability, Substs::single(inner_ty)),
503 }; 484 }
504 Ty::apply_one(ty, inner_ty)
505 } 485 }
506 Expr::Box { expr } => { 486 Expr::Box { expr } => {
507 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 487 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
508 if let Some(box_) = self.resolve_boxed_box() { 488 if let Some(box_) = self.resolve_boxed_box() {
509 let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); 489 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
510 sb = sb.push(inner_ty); 490 sb = sb.push(inner_ty);
511 sb = sb.fill(repeat_with(|| self.table.new_type_var())); 491 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
512 Ty::apply(TypeCtor::Adt(box_), sb.build()) 492 Ty::Adt(box_, sb.build())
513 } else { 493 } else {
514 Ty::Unknown 494 Ty::Unknown
515 } 495 }
@@ -539,14 +519,9 @@ impl<'a> InferenceContext<'a> {
539 UnaryOp::Neg => { 519 UnaryOp::Neg => {
540 match &inner_ty { 520 match &inner_ty {
541 // Fast path for builtins 521 // Fast path for builtins
542 Ty::Apply(ApplicationTy { 522 Ty::Scalar(Scalar::Int(_))
543 ctor: TypeCtor::Scalar(Scalar::Int(_)), 523 | Ty::Scalar(Scalar::Uint(_))
544 .. 524 | Ty::Scalar(Scalar::Float(_))
545 })
546 | Ty::Apply(ApplicationTy {
547 ctor: TypeCtor::Scalar(Scalar::Float(_)),
548 ..
549 })
550 | Ty::Infer(InferTy::IntVar(..)) 525 | Ty::Infer(InferTy::IntVar(..))
551 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, 526 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
552 // Otherwise we resolve via the std::ops::Neg trait 527 // Otherwise we resolve via the std::ops::Neg trait
@@ -557,18 +532,9 @@ impl<'a> InferenceContext<'a> {
557 UnaryOp::Not => { 532 UnaryOp::Not => {
558 match &inner_ty { 533 match &inner_ty {
559 // Fast path for builtins 534 // Fast path for builtins
560 Ty::Apply(ApplicationTy { 535 Ty::Scalar(Scalar::Bool)
561 ctor: TypeCtor::Scalar(Scalar::Bool), 536 | Ty::Scalar(Scalar::Int(_))
562 .. 537 | 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, 538 | Ty::Infer(InferTy::IntVar(..)) => inner_ty,
573 // Otherwise we resolve via the std::ops::Not trait 539 // Otherwise we resolve via the std::ops::Not trait
574 _ => self 540 _ => self
@@ -580,9 +546,7 @@ impl<'a> InferenceContext<'a> {
580 Expr::BinaryOp { lhs, rhs, op } => match op { 546 Expr::BinaryOp { lhs, rhs, op } => match op {
581 Some(op) => { 547 Some(op) => {
582 let lhs_expectation = match op { 548 let lhs_expectation = match op {
583 BinaryOp::LogicOp(..) => { 549 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
584 Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Bool)))
585 }
586 _ => Expectation::none(), 550 _ => Expectation::none(),
587 }; 551 };
588 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 552 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -613,31 +577,31 @@ impl<'a> InferenceContext<'a> {
613 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 577 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
614 match (range_type, lhs_ty, rhs_ty) { 578 match (range_type, lhs_ty, rhs_ty) {
615 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 579 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
616 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 580 Some(adt) => Ty::Adt(adt, Substs::empty()),
617 None => Ty::Unknown, 581 None => Ty::Unknown,
618 }, 582 },
619 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 583 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
620 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 584 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
621 None => Ty::Unknown, 585 None => Ty::Unknown,
622 }, 586 },
623 (RangeOp::Inclusive, None, Some(ty)) => { 587 (RangeOp::Inclusive, None, Some(ty)) => {
624 match self.resolve_range_to_inclusive() { 588 match self.resolve_range_to_inclusive() {
625 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 589 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
626 None => Ty::Unknown, 590 None => Ty::Unknown,
627 } 591 }
628 } 592 }
629 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 593 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
630 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 594 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
631 None => Ty::Unknown, 595 None => Ty::Unknown,
632 }, 596 },
633 (RangeOp::Inclusive, Some(_), Some(ty)) => { 597 (RangeOp::Inclusive, Some(_), Some(ty)) => {
634 match self.resolve_range_inclusive() { 598 match self.resolve_range_inclusive() {
635 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 599 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
636 None => Ty::Unknown, 600 None => Ty::Unknown,
637 } 601 }
638 } 602 }
639 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 603 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
640 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 604 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
641 None => Ty::Unknown, 605 None => Ty::Unknown,
642 }, 606 },
643 (RangeOp::Inclusive, _, None) => Ty::Unknown, 607 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -671,7 +635,7 @@ impl<'a> InferenceContext<'a> {
671 } 635 }
672 Expr::Tuple { exprs } => { 636 Expr::Tuple { exprs } => {
673 let mut tys = match &expected.ty { 637 let mut tys = match &expected.ty {
674 ty_app!(TypeCtor::Tuple { .. }, st) => st 638 Ty::Tuple { substs, .. } => substs
675 .iter() 639 .iter()
676 .cloned() 640 .cloned()
677 .chain(repeat_with(|| self.table.new_type_var())) 641 .chain(repeat_with(|| self.table.new_type_var()))
@@ -684,15 +648,11 @@ impl<'a> InferenceContext<'a> {
684 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 648 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
685 } 649 }
686 650
687 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 651 Ty::Tuple { cardinality: tys.len() as u16, substs: Substs(tys.into()) }
688 } 652 }
689 Expr::Array(array) => { 653 Expr::Array(array) => {
690 let elem_ty = match &expected.ty { 654 let elem_ty = match &expected.ty {
691 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 655 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(), 656 _ => self.table.new_type_var(),
697 }; 657 };
698 658
@@ -709,42 +669,38 @@ impl<'a> InferenceContext<'a> {
709 ); 669 );
710 self.infer_expr( 670 self.infer_expr(
711 *repeat, 671 *repeat,
712 &Expectation::has_type(Ty::simple(TypeCtor::Scalar(Scalar::Uint( 672 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
713 UintTy::Usize,
714 )))),
715 ); 673 );
716 } 674 }
717 } 675 }
718 676
719 Ty::apply_one(TypeCtor::Array, elem_ty) 677 Ty::Array(Substs::single(elem_ty))
720 } 678 }
721 Expr::Literal(lit) => match lit { 679 Expr::Literal(lit) => match lit {
722 Literal::Bool(..) => Ty::simple(TypeCtor::Scalar(Scalar::Bool)), 680 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
723 Literal::String(..) => { 681 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(..) => { 682 Literal::ByteString(..) => {
727 let byte_type = Ty::simple(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))); 683 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
728 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 684 let array_type = Ty::Array(Substs::single(byte_type));
729 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 685 Ty::Ref(Mutability::Shared, Substs::single(array_type))
730 } 686 }
731 Literal::Char(..) => Ty::simple(TypeCtor::Scalar(Scalar::Char)), 687 Literal::Char(..) => Ty::Scalar(Scalar::Char),
732 Literal::Int(_v, ty) => match ty { 688 Literal::Int(_v, ty) => match ty {
733 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Int( 689 Some(int_ty) => {
734 primitive::int_ty_from_builtin(*int_ty), 690 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
735 ))), 691 }
736 None => self.table.new_integer_var(), 692 None => self.table.new_integer_var(),
737 }, 693 },
738 Literal::Uint(_v, ty) => match ty { 694 Literal::Uint(_v, ty) => match ty {
739 Some(int_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Uint( 695 Some(int_ty) => {
740 primitive::uint_ty_from_builtin(*int_ty), 696 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
741 ))), 697 }
742 None => self.table.new_integer_var(), 698 None => self.table.new_integer_var(),
743 }, 699 },
744 Literal::Float(_v, ty) => match ty { 700 Literal::Float(_v, ty) => match ty {
745 Some(float_ty) => Ty::simple(TypeCtor::Scalar(Scalar::Float( 701 Some(float_ty) => {
746 primitive::float_ty_from_builtin(*float_ty), 702 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
747 ))), 703 }
748 None => self.table.new_float_var(), 704 None => self.table.new_float_var(),
749 }, 705 },
750 }, 706 },
@@ -857,7 +813,7 @@ impl<'a> InferenceContext<'a> {
857 // Apply autoref so the below unification works correctly 813 // Apply autoref so the below unification works correctly
858 // FIXME: return correct autorefs from lookup_method 814 // FIXME: return correct autorefs from lookup_method
859 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 815 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
860 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 816 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
861 _ => derefed_receiver_ty, 817 _ => derefed_receiver_ty,
862 }; 818 };
863 self.unify(&expected_receiver_ty, &actual_receiver_ty); 819 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -934,30 +890,26 @@ impl<'a> InferenceContext<'a> {
934 } 890 }
935 891
936 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 892 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
937 if let Ty::Apply(a_ty) = callable_ty { 893 if let &Ty::FnDef(def, ref parameters) = callable_ty {
938 if let TypeCtor::FnDef(def) = a_ty.ctor { 894 let generic_predicates = self.db.generic_predicates(def.into());
939 let generic_predicates = self.db.generic_predicates(def.into()); 895 for predicate in generic_predicates.iter() {
940 for predicate in generic_predicates.iter() { 896 let predicate = predicate.clone().subst(parameters);
941 let predicate = predicate.clone().subst(&a_ty.parameters); 897 if let Some(obligation) = Obligation::from_predicate(predicate) {
942 if let Some(obligation) = Obligation::from_predicate(predicate) { 898 self.obligations.push(obligation);
943 self.obligations.push(obligation);
944 }
945 } 899 }
946 // add obligation for trait implementation, if this is a trait method 900 }
947 match def { 901 // add obligation for trait implementation, if this is a trait method
948 CallableDefId::FunctionId(f) => { 902 match def {
949 if let AssocContainerId::TraitId(trait_) = 903 CallableDefId::FunctionId(f) => {
950 f.lookup(self.db.upcast()).container 904 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
951 { 905 {
952 // construct a TraitDef 906 // construct a TraitDef
953 let substs = a_ty 907 let substs =
954 .parameters 908 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
955 .prefix(generics(self.db.upcast(), trait_.into()).len()); 909 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
956 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
957 }
958 } 910 }
959 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
960 } 911 }
912 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
961 } 913 }
962 } 914 }
963 } 915 }
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b..e96e08c3c 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 { cardinality: inner_tys.len() as u16, substs: 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..117d69f01 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,
@@ -293,10 +107,80 @@ impl TypeWalk for ProjectionTy {
293/// This should be cheap to clone. 107/// This should be cheap to clone.
294#[derive(Clone, PartialEq, Eq, Debug, Hash)] 108#[derive(Clone, PartialEq, Eq, Debug, Hash)]
295pub enum Ty { 109pub enum Ty {
296 /// A nominal type with (maybe 0) type parameters. This might be a primitive 110 /// Structures, enumerations and unions.
297 /// type like `bool`, a struct, tuple, function pointer, reference or 111 Adt(AdtId, Substs),
298 /// several other things. 112
299 Apply(ApplicationTy), 113 /// Represents an associated item like `Iterator::Item`. This is used
114 /// when we have tried to normalize a projection like `T::Item` but
115 /// couldn't find a better representation. In that case, we generate
116 /// an **application type** like `(Iterator::Item)<T>`.
117 AssociatedType(TypeAliasId, Substs),
118
119 /// a scalar type like `bool` or `u32`
120 Scalar(Scalar),
121
122 /// A tuple type. For example, `(i32, bool)`.
123 Tuple { cardinality: u16, substs: Substs },
124
125 /// An array with the given length. Written as `[T; n]`.
126 Array(Substs),
127
128 /// The pointee of an array slice. Written as `[T]`.
129 Slice(Substs),
130
131 /// A raw pointer. Written as `*mut T` or `*const T`
132 RawPtr(Mutability, Substs),
133
134 /// A reference; a pointer with an associated lifetime. Written as
135 /// `&'a mut T` or `&'a T`.
136 Ref(Mutability, Substs),
137
138 /// This represents a placeholder for an opaque type in situations where we
139 /// don't know the hidden type (i.e. currently almost always). This is
140 /// analogous to the `AssociatedType` type constructor.
141 /// It is also used as the type of async block, with one type parameter
142 /// representing the Future::Output type.
143 OpaqueType(OpaqueTyId, Substs),
144
145 /// The anonymous type of a function declaration/definition. Each
146 /// function has a unique type, which is output (for a function
147 /// named `foo` returning an `i32`) as `fn() -> i32 {foo}`.
148 ///
149 /// This includes tuple struct / enum variant constructors as well.
150 ///
151 /// For example the type of `bar` here:
152 ///
153 /// ```
154 /// fn foo() -> i32 { 1 }
155 /// let bar = foo; // bar: fn() -> i32 {foo}
156 /// ```
157 FnDef(CallableDefId, Substs),
158
159 /// The pointee of a string slice. Written as `str`.
160 Str,
161
162 /// The never type `!`.
163 Never,
164
165 /// The type of a specific closure.
166 ///
167 /// The closure signature is stored in a `FnPtr` type in the first type
168 /// parameter.
169 Closure { def: DefWithBodyId, expr: ExprId, substs: Substs },
170
171 /// Represents a foreign type declared in external blocks.
172 ForeignType(TypeAliasId, Substs),
173
174 /// A pointer to a function. Written as `fn() -> i32`.
175 ///
176 /// For example the type of `bar` here:
177 ///
178 /// ```
179 /// fn foo() -> i32 { 1 }
180 /// let bar: fn() -> i32 = foo;
181 /// ```
182 // FIXME make this a Ty variant like in Chalk
183 FnPtr { num_args: u16, is_varargs: bool, substs: Substs },
300 184
301 /// A "projection" type corresponds to an (unnormalized) 185 /// A "projection" type corresponds to an (unnormalized)
302 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the 186 /// projection like `<P0 as Trait<P1..Pn>>::Foo`. Note that the
@@ -420,10 +304,6 @@ impl Substs {
420 Substs::builder(generic_params.len()) 304 Substs::builder(generic_params.len())
421 } 305 }
422 306
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 { 307 fn builder(param_count: usize) -> SubstsBuilder {
428 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count } 308 SubstsBuilder { vec: Vec::with_capacity(param_count), param_count }
429 } 309 }
@@ -701,54 +581,42 @@ impl TypeWalk for FnSig {
701} 581}
702 582
703impl Ty { 583impl 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 { 584 pub fn unit() -> Self {
714 Ty::apply(TypeCtor::Tuple { cardinality: 0 }, Substs::empty()) 585 Ty::Tuple { cardinality: 0, substs: Substs::empty() }
715 } 586 }
587
716 pub fn fn_ptr(sig: FnSig) -> Self { 588 pub fn fn_ptr(sig: FnSig) -> Self {
717 Ty::apply( 589 Ty::FnPtr {
718 TypeCtor::FnPtr { num_args: sig.params().len() as u16, is_varargs: sig.is_varargs }, 590 num_args: sig.params().len() as u16,
719 Substs(sig.params_and_return), 591 is_varargs: sig.is_varargs,
720 ) 592 substs: Substs(sig.params_and_return),
593 }
721 } 594 }
595
722 pub fn builtin(builtin: BuiltinType) -> Self { 596 pub fn builtin(builtin: BuiltinType) -> Self {
723 Ty::simple(match builtin { 597 match builtin {
724 BuiltinType::Char => TypeCtor::Scalar(Scalar::Char), 598 BuiltinType::Char => Ty::Scalar(Scalar::Char),
725 BuiltinType::Bool => TypeCtor::Scalar(Scalar::Bool), 599 BuiltinType::Bool => Ty::Scalar(Scalar::Bool),
726 BuiltinType::Str => TypeCtor::Str, 600 BuiltinType::Str => Ty::Str,
727 BuiltinType::Int(t) => TypeCtor::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))), 601 BuiltinType::Int(t) => Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(t))),
728 BuiltinType::Uint(t) => { 602 BuiltinType::Uint(t) => Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))),
729 TypeCtor::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(t))) 603 BuiltinType::Float(t) => Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t))),
730 } 604 }
731 BuiltinType::Float(t) => {
732 TypeCtor::Scalar(Scalar::Float(primitive::float_ty_from_builtin(t)))
733 }
734 })
735 } 605 }
736 606
737 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 607 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
738 match self { 608 match self {
739 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 609 Ty::Ref(mutability, parameters) => Some((parameters.as_single(), *mutability)),
740 Some((parameters.as_single(), *mutability))
741 }
742 _ => None, 610 _ => None,
743 } 611 }
744 } 612 }
745 613
746 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> { 614 pub fn as_reference_or_ptr(&self) -> Option<(&Ty, Rawness, Mutability)> {
747 match self { 615 match self {
748 Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(mutability), parameters }) => { 616 Ty::Ref(mutability, parameters) => {
749 Some((parameters.as_single(), Rawness::Ref, *mutability)) 617 Some((parameters.as_single(), Rawness::Ref, *mutability))
750 } 618 }
751 Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(mutability), parameters }) => { 619 Ty::RawPtr(mutability, parameters) => {
752 Some((parameters.as_single(), Rawness::RawPtr, *mutability)) 620 Some((parameters.as_single(), Rawness::RawPtr, *mutability))
753 } 621 }
754 _ => None, 622 _ => None,
@@ -758,7 +626,7 @@ impl Ty {
758 pub fn strip_references(&self) -> &Ty { 626 pub fn strip_references(&self) -> &Ty {
759 let mut t: &Ty = self; 627 let mut t: &Ty = self;
760 628
761 while let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_mutability), parameters }) = t { 629 while let Ty::Ref(_mutability, parameters) = t {
762 t = parameters.as_single(); 630 t = parameters.as_single();
763 } 631 }
764 632
@@ -767,30 +635,64 @@ impl Ty {
767 635
768 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> { 636 pub fn as_adt(&self) -> Option<(AdtId, &Substs)> {
769 match self { 637 match self {
770 Ty::Apply(ApplicationTy { ctor: TypeCtor::Adt(adt_def), parameters }) => { 638 Ty::Adt(adt_def, parameters) => Some((*adt_def, parameters)),
771 Some((*adt_def, parameters))
772 }
773 _ => None, 639 _ => None,
774 } 640 }
775 } 641 }
776 642
777 pub fn as_tuple(&self) -> Option<&Substs> { 643 pub fn as_tuple(&self) -> Option<&Substs> {
778 match self { 644 match self {
779 Ty::Apply(ApplicationTy { ctor: TypeCtor::Tuple { .. }, parameters }) => { 645 Ty::Tuple { substs: parameters, .. } => Some(parameters),
780 Some(parameters) 646 _ => None,
781 } 647 }
648 }
649
650 pub fn as_generic_def(&self) -> Option<GenericDefId> {
651 match *self {
652 Ty::Adt(adt, ..) => Some(adt.into()),
653 Ty::FnDef(callable, ..) => Some(callable.into()),
654 Ty::AssociatedType(type_alias, ..) => Some(type_alias.into()),
655 Ty::ForeignType(type_alias, ..) => Some(type_alias.into()),
782 _ => None, 656 _ => None,
783 } 657 }
784 } 658 }
785 659
786 pub fn is_never(&self) -> bool { 660 pub fn is_never(&self) -> bool {
787 matches!(self, Ty::Apply(ApplicationTy { ctor: TypeCtor::Never, .. })) 661 matches!(self, Ty::Never)
788 } 662 }
789 663
790 pub fn is_unknown(&self) -> bool { 664 pub fn is_unknown(&self) -> bool {
791 matches!(self, Ty::Unknown) 665 matches!(self, Ty::Unknown)
792 } 666 }
793 667
668 pub fn equals_ctor(&self, other: &Ty) -> bool {
669 match (self, other) {
670 (Ty::Adt(adt, ..), Ty::Adt(adt2, ..)) => adt == adt2,
671 (Ty::Slice(_), Ty::Slice(_)) | (Ty::Array(_), Ty::Array(_)) => true,
672 (Ty::FnDef(def_id, ..), Ty::FnDef(def_id2, ..)) => def_id == def_id2,
673 (Ty::OpaqueType(ty_id, ..), Ty::OpaqueType(ty_id2, ..)) => ty_id == ty_id2,
674 (Ty::AssociatedType(ty_id, ..), Ty::AssociatedType(ty_id2, ..))
675 | (Ty::ForeignType(ty_id, ..), Ty::ForeignType(ty_id2, ..)) => ty_id == ty_id2,
676 (Ty::Closure { def, expr, .. }, Ty::Closure { def: def2, expr: expr2, .. }) => {
677 expr == expr2 && def == def2
678 }
679 (Ty::Ref(mutability, ..), Ty::Ref(mutability2, ..))
680 | (Ty::RawPtr(mutability, ..), Ty::RawPtr(mutability2, ..)) => {
681 mutability == mutability2
682 }
683 (
684 Ty::FnPtr { num_args, is_varargs, .. },
685 Ty::FnPtr { num_args: num_args2, is_varargs: is_varargs2, .. },
686 ) => num_args == num_args2 && is_varargs == is_varargs2,
687 (Ty::Tuple { cardinality, .. }, Ty::Tuple { cardinality: cardinality2, .. }) => {
688 cardinality == cardinality2
689 }
690 (Ty::Str, Ty::Str) | (Ty::Never, Ty::Never) => true,
691 (Ty::Scalar(scalar), Ty::Scalar(scalar2)) => scalar == scalar2,
692 _ => false,
693 }
694 }
695
794 /// If this is a `dyn Trait` type, this returns the `Trait` part. 696 /// If this is a `dyn Trait` type, this returns the `Trait` part.
795 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> { 697 pub fn dyn_trait_ref(&self) -> Option<&TraitRef> {
796 match self { 698 match self {
@@ -809,41 +711,32 @@ impl Ty {
809 711
810 fn builtin_deref(&self) -> Option<Ty> { 712 fn builtin_deref(&self) -> Option<Ty> {
811 match self { 713 match self {
812 Ty::Apply(a_ty) => match a_ty.ctor { 714 Ty::Ref(.., parameters) => Some(Ty::clone(parameters.as_single())),
813 TypeCtor::Ref(..) => Some(Ty::clone(a_ty.parameters.as_single())), 715 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, 716 _ => None,
818 } 717 }
819 } 718 }
820 719
821 pub fn as_fn_def(&self) -> Option<FunctionId> { 720 pub fn as_fn_def(&self) -> Option<FunctionId> {
822 match self { 721 match self {
823 &Ty::Apply(ApplicationTy { 722 &Ty::FnDef(CallableDefId::FunctionId(func), ..) => Some(func),
824 ctor: TypeCtor::FnDef(CallableDefId::FunctionId(func)),
825 ..
826 }) => Some(func),
827 _ => None, 723 _ => None,
828 } 724 }
829 } 725 }
830 726
831 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> { 727 pub fn callable_sig(&self, db: &dyn HirDatabase) -> Option<FnSig> {
832 match self { 728 match self {
833 Ty::Apply(a_ty) => match a_ty.ctor { 729 Ty::FnPtr { is_varargs, substs: parameters, .. } => {
834 TypeCtor::FnPtr { is_varargs, .. } => { 730 Some(FnSig::from_fn_ptr_substs(&parameters, *is_varargs))
835 Some(FnSig::from_fn_ptr_substs(&a_ty.parameters, is_varargs)) 731 }
836 } 732 Ty::FnDef(def, parameters) => {
837 TypeCtor::FnDef(def) => { 733 let sig = db.callable_item_signature(*def);
838 let sig = db.callable_item_signature(def); 734 Some(sig.subst(&parameters))
839 Some(sig.subst(&a_ty.parameters)) 735 }
840 } 736 Ty::Closure { substs: parameters, .. } => {
841 TypeCtor::Closure { .. } => { 737 let sig_param = &parameters[0];
842 let sig_param = &a_ty.parameters[0]; 738 sig_param.callable_sig(db)
843 sig_param.callable_sig(db) 739 }
844 }
845 _ => None,
846 },
847 _ => None, 740 _ => None,
848 } 741 }
849 } 742 }
@@ -852,28 +745,69 @@ impl Ty {
852 /// the `Substs` for these type parameters with the given ones. (So e.g. if 745 /// 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 746 /// `self` is `Option<_>` and the substs contain `u32`, we'll have
854 /// `Option<u32>` afterwards.) 747 /// `Option<u32>` afterwards.)
855 pub fn apply_substs(self, substs: Substs) -> Ty { 748 pub fn apply_substs(mut self, new_substs: Substs) -> Ty {
856 match self { 749 match &mut self {
857 Ty::Apply(ApplicationTy { ctor, parameters: previous_substs }) => { 750 Ty::Adt(_, substs)
858 assert_eq!(previous_substs.len(), substs.len()); 751 | Ty::Slice(substs)
859 Ty::Apply(ApplicationTy { ctor, parameters: substs }) 752 | Ty::Array(substs)
753 | Ty::RawPtr(_, substs)
754 | Ty::Ref(_, substs)
755 | Ty::FnDef(_, substs)
756 | Ty::FnPtr { substs, .. }
757 | Ty::Tuple { substs, .. }
758 | Ty::OpaqueType(_, substs)
759 | Ty::AssociatedType(_, substs)
760 | Ty::ForeignType(_, substs)
761 | Ty::Closure { substs, .. } => {
762 assert_eq!(substs.len(), new_substs.len());
763 *substs = new_substs;
860 } 764 }
861 _ => self, 765 _ => (),
862 } 766 }
767 self
863 } 768 }
864 769
865 /// Returns the type parameters of this type if it has some (i.e. is an ADT 770 /// 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`. 771 /// or function); so if `self` is `Option<u32>`, this returns the `u32`.
867 pub fn substs(&self) -> Option<Substs> { 772 pub fn substs(&self) -> Option<&Substs> {
773 match self {
774 Ty::Adt(_, substs)
775 | Ty::Slice(substs)
776 | Ty::Array(substs)
777 | Ty::RawPtr(_, substs)
778 | Ty::Ref(_, substs)
779 | Ty::FnDef(_, substs)
780 | Ty::FnPtr { substs, .. }
781 | Ty::Tuple { substs, .. }
782 | Ty::OpaqueType(_, substs)
783 | Ty::AssociatedType(_, substs)
784 | Ty::ForeignType(_, substs)
785 | Ty::Closure { substs, .. } => Some(substs),
786 _ => None,
787 }
788 }
789
790 pub fn substs_mut(&mut self) -> Option<&mut Substs> {
868 match self { 791 match self {
869 Ty::Apply(ApplicationTy { parameters, .. }) => Some(parameters.clone()), 792 Ty::Adt(_, substs)
793 | Ty::Slice(substs)
794 | Ty::Array(substs)
795 | Ty::RawPtr(_, substs)
796 | Ty::Ref(_, substs)
797 | Ty::FnDef(_, substs)
798 | Ty::FnPtr { substs, .. }
799 | Ty::Tuple { substs, .. }
800 | Ty::OpaqueType(_, substs)
801 | Ty::AssociatedType(_, substs)
802 | Ty::ForeignType(_, substs)
803 | Ty::Closure { substs, .. } => Some(substs),
870 _ => None, 804 _ => None,
871 } 805 }
872 } 806 }
873 807
874 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> { 808 pub fn impl_trait_bounds(&self, db: &dyn HirDatabase) -> Option<Vec<GenericPredicate>> {
875 match self { 809 match self {
876 Ty::Apply(ApplicationTy { ctor: TypeCtor::OpaqueType(opaque_ty_id), .. }) => { 810 Ty::OpaqueType(opaque_ty_id, ..) => {
877 match opaque_ty_id { 811 match opaque_ty_id {
878 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => { 812 OpaqueTyId::AsyncBlockTypeImplTrait(def, _expr) => {
879 let krate = def.module(db.upcast()).krate(); 813 let krate = def.module(db.upcast()).krate();
@@ -934,7 +868,7 @@ impl Ty {
934 868
935 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> { 869 pub fn associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<TraitId> {
936 match self { 870 match self {
937 Ty::Apply(ApplicationTy { ctor: TypeCtor::AssociatedType(type_alias_id), .. }) => { 871 Ty::AssociatedType(type_alias_id, ..) => {
938 match type_alias_id.lookup(db.upcast()).container { 872 match type_alias_id.lookup(db.upcast()).container {
939 AssocContainerId::TraitId(trait_id) => Some(trait_id), 873 AssocContainerId::TraitId(trait_id) => Some(trait_id),
940 _ => None, 874 _ => None,
@@ -1049,11 +983,6 @@ pub trait TypeWalk {
1049impl TypeWalk for Ty { 983impl TypeWalk for Ty {
1050 fn walk(&self, f: &mut impl FnMut(&Ty)) { 984 fn walk(&self, f: &mut impl FnMut(&Ty)) {
1051 match self { 985 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) => { 986 Ty::Projection(p_ty) => {
1058 for t in p_ty.parameters.iter() { 987 for t in p_ty.parameters.iter() {
1059 t.walk(f); 988 t.walk(f);
@@ -1069,7 +998,13 @@ impl TypeWalk for Ty {
1069 t.walk(f); 998 t.walk(f);
1070 } 999 }
1071 } 1000 }
1072 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1001 _ => {
1002 if let Some(substs) = self.substs() {
1003 for t in substs.iter() {
1004 t.walk(f);
1005 }
1006 }
1007 }
1073 } 1008 }
1074 f(self); 1009 f(self);
1075 } 1010 }
@@ -1080,9 +1015,6 @@ impl TypeWalk for Ty {
1080 binders: DebruijnIndex, 1015 binders: DebruijnIndex,
1081 ) { 1016 ) {
1082 match self { 1017 match self {
1083 Ty::Apply(a_ty) => {
1084 a_ty.parameters.walk_mut_binders(f, binders);
1085 }
1086 Ty::Projection(p_ty) => { 1018 Ty::Projection(p_ty) => {
1087 p_ty.parameters.walk_mut_binders(f, binders); 1019 p_ty.parameters.walk_mut_binders(f, binders);
1088 } 1020 }
@@ -1094,7 +1026,11 @@ impl TypeWalk for Ty {
1094 Ty::Opaque(o_ty) => { 1026 Ty::Opaque(o_ty) => {
1095 o_ty.parameters.walk_mut_binders(f, binders); 1027 o_ty.parameters.walk_mut_binders(f, binders);
1096 } 1028 }
1097 Ty::Placeholder { .. } | Ty::Bound(_) | Ty::Infer(_) | Ty::Unknown => {} 1029 _ => {
1030 if let Some(substs) = self.substs_mut() {
1031 substs.walk_mut_binders(f, binders);
1032 }
1033 }
1098 } 1034 }
1099 f(self, binders); 1035 f(self, binders);
1100 } 1036 }
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 99b0ecf3b..6b919a09e 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -33,7 +33,7 @@ use crate::{
33 }, 33 },
34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig, 34 Binders, BoundVar, DebruijnIndex, FnSig, GenericPredicate, OpaqueTy, OpaqueTyId, PolyFnSig,
35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs, 35 ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ReturnTypeImplTraits, Substs,
36 TraitEnvironment, TraitRef, Ty, TypeCtor, TypeWalk, 36 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 { cardinality: inner_tys.len() as u16, substs: 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,24 @@ 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 sig = Substs(params.iter().map(|tr| Ty::from_hir(ctx, tr)).collect());
180 Ty::apply( 177 Ty::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs, substs: sig }
181 TypeCtor::FnPtr { num_args: sig.len() as u16 - 1, is_varargs: *is_varargs },
182 sig,
183 )
184 } 178 }
185 TypeRef::DynTrait(bounds) => { 179 TypeRef::DynTrait(bounds) => {
186 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0)); 180 let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
@@ -414,7 +408,6 @@ impl Ty {
414 // FIXME: report error 408 // FIXME: report error
415 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None), 409 TypeNs::EnumVariantId(_) => return (Ty::Unknown, None),
416 }; 410 };
417
418 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments) 411 Ty::from_type_relative_path(ctx, ty, Some(resolution), remaining_segments)
419 } 412 }
420 413
@@ -1025,7 +1018,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> PolyFnSig {
1025fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> { 1018fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
1026 let generics = generics(db.upcast(), def.into()); 1019 let generics = generics(db.upcast(), def.into());
1027 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1020 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1028 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1021 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1029} 1022}
1030 1023
1031/// Build the declared type of a const. 1024/// Build the declared type of a const.
@@ -1068,7 +1061,7 @@ fn type_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> Binders<T
1068 } 1061 }
1069 let generics = generics(db.upcast(), def.into()); 1062 let generics = generics(db.upcast(), def.into());
1070 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1063 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1071 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1064 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1072} 1065}
1073 1066
1074fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig { 1067fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -> PolyFnSig {
@@ -1093,13 +1086,13 @@ fn type_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId) -
1093 } 1086 }
1094 let generics = generics(db.upcast(), def.parent.into()); 1087 let generics = generics(db.upcast(), def.parent.into());
1095 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1088 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1096 Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs)) 1089 Binders::new(substs.len(), Ty::FnDef(def.into(), substs))
1097} 1090}
1098 1091
1099fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> { 1092fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
1100 let generics = generics(db.upcast(), adt.into()); 1093 let generics = generics(db.upcast(), adt.into());
1101 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1094 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1102 Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs)) 1095 Binders::new(substs.len(), Ty::Adt(adt, substs))
1103} 1096}
1104 1097
1105fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> { 1098fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
@@ -1109,7 +1102,7 @@ fn type_for_type_alias(db: &dyn HirDatabase, t: TypeAliasId) -> Binders<Ty> {
1109 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable); 1102 TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
1110 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST); 1103 let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
1111 if db.type_alias_data(t).is_extern { 1104 if db.type_alias_data(t).is_extern {
1112 Binders::new(substs.len(), Ty::apply(TypeCtor::ForeignType(t), substs)) 1105 Binders::new(substs.len(), Ty::ForeignType(t, substs))
1113 } else { 1106 } else {
1114 let type_ref = &db.type_alias_data(t).type_ref; 1107 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)); 1108 let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 66d8de959..087b67935 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, InEnvironment, Scalar, Substs, TraitEnvironment, TraitRef, Ty,
22 TraitRef, Ty, TyKind, TypeCtor, TypeWalk, 22 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 { cardinality: u16 },
37 ForeignType(TypeAliasId),
38 FnPtr { num_args: u16, is_varargs: bool },
30} 39}
31 40
32impl TyFingerprint { 41impl TyFingerprint {
@@ -34,32 +43,44 @@ 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: u16, .. } => TyFingerprint::Tuple { cardinality: u16 },
54 &Ty::RawPtr(mutability, ..) => TyFingerprint::RawPtr(mutability),
55 &Ty::ForeignType(alias_id, ..) => TyFingerprint::ForeignType(alias_id),
56 &Ty::FnPtr { num_args, is_varargs, .. } => {
57 TyFingerprint::FnPtr { num_args, is_varargs }
58 }
59 Ty::Dyn(_) => ty.dyn_trait().map(|trait_| TyFingerprint::Dyn(trait_))?,
60 _ => return None,
61 };
62 Some(fp)
42 } 63 }
43} 64}
44 65
45pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [ 66pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
46 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I8))), 67 TyFingerprint::Scalar(Scalar::Int(IntTy::I8)),
47 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I16))), 68 TyFingerprint::Scalar(Scalar::Int(IntTy::I16)),
48 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I32))), 69 TyFingerprint::Scalar(Scalar::Int(IntTy::I32)),
49 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I64))), 70 TyFingerprint::Scalar(Scalar::Int(IntTy::I64)),
50 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::I128))), 71 TyFingerprint::Scalar(Scalar::Int(IntTy::I128)),
51 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Int(IntTy::Isize))), 72 TyFingerprint::Scalar(Scalar::Int(IntTy::Isize)),
52 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U8))), 73 TyFingerprint::Scalar(Scalar::Uint(UintTy::U8)),
53 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U16))), 74 TyFingerprint::Scalar(Scalar::Uint(UintTy::U16)),
54 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U32))), 75 TyFingerprint::Scalar(Scalar::Uint(UintTy::U32)),
55 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U64))), 76 TyFingerprint::Scalar(Scalar::Uint(UintTy::U64)),
56 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::U128))), 77 TyFingerprint::Scalar(Scalar::Uint(UintTy::U128)),
57 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Uint(UintTy::Usize))), 78 TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
58]; 79];
59 80
60pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [ 81pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
61 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F32))), 82 TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
62 TyFingerprint::Apply(TypeCtor::Scalar(Scalar::Float(FloatTy::F64))), 83 TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
63]; 84];
64 85
65/// Trait impls defined or available in some crate. 86/// Trait impls defined or available in some crate.
@@ -211,32 +232,29 @@ impl Ty {
211 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect()); 232 let mod_to_crate_ids = |module: ModuleId| Some(std::iter::once(module.krate()).collect());
212 233
213 let lang_item_targets = match self { 234 let lang_item_targets = match self {
214 Ty::Apply(a_ty) => match a_ty.ctor { 235 Ty::Adt(def_id, _) => {
215 TypeCtor::Adt(def_id) => { 236 return mod_to_crate_ids(def_id.module(db.upcast()));
216 return mod_to_crate_ids(def_id.module(db.upcast())); 237 }
217 } 238 Ty::ForeignType(type_alias_id, _) => {
218 TypeCtor::ForeignType(type_alias_id) => { 239 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())); 240 }
220 } 241 Ty::Scalar(Scalar::Bool) => lang_item_crate!("bool"),
221 TypeCtor::Scalar(Scalar::Bool) => lang_item_crate!("bool"), 242 Ty::Scalar(Scalar::Char) => lang_item_crate!("char"),
222 TypeCtor::Scalar(Scalar::Char) => lang_item_crate!("char"), 243 Ty::Scalar(Scalar::Float(f)) => match f {
223 TypeCtor::Scalar(Scalar::Float(f)) => match f { 244 // 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) 245 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"),
225 FloatTy::F32 => lang_item_crate!("f32", "f32_runtime"), 246 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 }, 247 },
248 &Ty::Scalar(Scalar::Int(t)) => {
249 lang_item_crate!(primitive::int_ty_to_string(t))
250 }
251 &Ty::Scalar(Scalar::Uint(t)) => {
252 lang_item_crate!(primitive::uint_ty_to_string(t))
253 }
254 Ty::Str => lang_item_crate!("str_alloc", "str"),
255 Ty::Slice(_) => lang_item_crate!("slice_alloc", "slice"),
256 Ty::RawPtr(Mutability::Shared, _) => lang_item_crate!("const_ptr"),
257 Ty::RawPtr(Mutability::Mut, _) => lang_item_crate!("mut_ptr"),
240 Ty::Dyn(_) => { 258 Ty::Dyn(_) => {
241 return self.dyn_trait().and_then(|trait_| { 259 return self.dyn_trait().and_then(|trait_| {
242 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast())) 260 mod_to_crate_ids(GenericDefId::TraitId(trait_).module(db.upcast()))
@@ -413,7 +431,7 @@ fn iterate_method_candidates_with_autoref(
413 } 431 }
414 let refed = Canonical { 432 let refed = Canonical {
415 kinds: deref_chain[0].kinds.clone(), 433 kinds: deref_chain[0].kinds.clone(),
416 value: Ty::apply_one(TypeCtor::Ref(Mutability::Shared), deref_chain[0].value.clone()), 434 value: Ty::Ref(Mutability::Shared, Substs::single(deref_chain[0].value.clone())),
417 }; 435 };
418 if iterate_method_candidates_by_receiver( 436 if iterate_method_candidates_by_receiver(
419 &refed, 437 &refed,
@@ -429,7 +447,7 @@ fn iterate_method_candidates_with_autoref(
429 } 447 }
430 let ref_muted = Canonical { 448 let ref_muted = Canonical {
431 kinds: deref_chain[0].kinds.clone(), 449 kinds: deref_chain[0].kinds.clone(),
432 value: Ty::apply_one(TypeCtor::Ref(Mutability::Mut), deref_chain[0].value.clone()), 450 value: Ty::Ref(Mutability::Mut, Substs::single(deref_chain[0].value.clone())),
433 }; 451 };
434 if iterate_method_candidates_by_receiver( 452 if iterate_method_candidates_by_receiver(
435 &ref_muted, 453 &ref_muted,
@@ -756,11 +774,9 @@ fn autoderef_method_receiver(
756) -> Vec<Canonical<Ty>> { 774) -> Vec<Canonical<Ty>> {
757 let mut deref_chain: Vec<_> = autoderef::autoderef(db, Some(krate), ty).collect(); 775 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!) 776 // 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 })) = 777 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(); 778 let kinds = deref_chain.last().unwrap().kinds.clone();
763 let unsized_ty = Ty::apply(TypeCtor::Slice, parameters.clone()); 779 let unsized_ty = Ty::Slice(parameters.clone());
764 deref_chain.push(Canonical { value: unsized_ty, kinds }) 780 deref_chain.push(Canonical { value: unsized_ty, kinds })
765 } 781 }
766 deref_chain 782 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/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index d74c83737..c53e327da 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -20,7 +20,7 @@ use crate::{
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, DebruijnIndex, FnSig, 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,
@@ -489,10 +489,11 @@ pub(crate) fn struct_datum_query(
489 struct_id: AdtId, 489 struct_id: AdtId,
490) -> Arc<StructDatum> { 490) -> Arc<StructDatum> {
491 debug!("struct_datum {:?}", struct_id); 491 debug!("struct_datum {:?}", struct_id);
492 let type_ctor = TypeCtor::Adt(from_chalk(db, struct_id)); 492 let adt_id = from_chalk(db, struct_id);
493 let type_ctor = Ty::Adt(adt_id, Substs::empty());
493 debug!("struct {:?} = {:?}", struct_id, type_ctor); 494 debug!("struct {:?} = {:?}", struct_id, type_ctor);
494 let num_params = type_ctor.num_ty_params(db); 495 let num_params = generics(db.upcast(), adt_id.into()).len();
495 let upstream = type_ctor.krate(db) != Some(krate); 496 let upstream = adt_id.module(db.upcast()).krate() != krate;
496 let where_clauses = type_ctor 497 let where_clauses = type_ctor
497 .as_generic_def() 498 .as_generic_def()
498 .map(|generic_def| { 499 .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..297ddeabd 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, GenericPredicate, InEnvironment, OpaqueTy, OpaqueTyId, ProjectionPredicate,
20 ProjectionPredicate, ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind, 20 ProjectionTy, Scalar, Substs, TraitEnvironment, TraitRef, Ty, TyKind,
21 TypeCtor,
22}; 21};
23 22
24use super::interner::*; 23use super::interner::*;
@@ -28,75 +27,71 @@ 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::FnPtr { num_args: _, is_varargs, 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 {
38 num_binders: 0, 37 abi: (),
39 sig: chalk_ir::FnSig { 38 safety: chalk_ir::Safety::Safe,
40 abi: (), 39 variadic: is_varargs,
41 safety: chalk_ir::Safety::Safe, 40 },
42 variadic: is_varargs, 41 substitution,
43 }, 42 })
44 substitution, 43 .intern(&Interner)
45 }) 44 }
46 .intern(&Interner) 45 Ty::AssociatedType(type_alias, substs) => {
47 } 46 let assoc_type = TypeAliasAsAssocType(type_alias);
48 TypeCtor::AssociatedType(type_alias) => { 47 let assoc_type_id = assoc_type.to_chalk(db);
49 let assoc_type = TypeAliasAsAssocType(type_alias); 48 let substitution = substs.to_chalk(db);
50 let assoc_type_id = assoc_type.to_chalk(db); 49 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
51 let substitution = apply_ty.parameters.to_chalk(db); 50 }
52 chalk_ir::TyKind::AssociatedType(assoc_type_id, substitution).intern(&Interner)
53 }
54 51
55 TypeCtor::OpaqueType(impl_trait_id) => { 52 Ty::OpaqueType(impl_trait_id, substs) => {
56 let id = impl_trait_id.to_chalk(db); 53 let id = impl_trait_id.to_chalk(db);
57 let substitution = apply_ty.parameters.to_chalk(db); 54 let substitution = substs.to_chalk(db);
58 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner) 55 chalk_ir::TyKind::OpaqueType(id, substitution).intern(&Interner)
59 } 56 }
60 57
61 TypeCtor::ForeignType(type_alias) => { 58 Ty::ForeignType(type_alias, _) => {
62 let foreign_type = TypeAliasAsForeignType(type_alias); 59 let foreign_type = TypeAliasAsForeignType(type_alias);
63 let foreign_type_id = foreign_type.to_chalk(db); 60 let foreign_type_id = foreign_type.to_chalk(db);
64 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner) 61 chalk_ir::TyKind::Foreign(foreign_type_id).intern(&Interner)
65 } 62 }
66 63
67 TypeCtor::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner), 64 Ty::Scalar(scalar) => chalk_ir::TyKind::Scalar(scalar).intern(&Interner),
68 65
69 TypeCtor::Tuple { cardinality } => { 66 Ty::Tuple { cardinality, substs } => {
70 let substitution = apply_ty.parameters.to_chalk(db); 67 let substitution = substs.to_chalk(db);
71 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner) 68 chalk_ir::TyKind::Tuple(cardinality.into(), substitution).intern(&Interner)
72 } 69 }
73 TypeCtor::RawPtr(mutability) => { 70 Ty::RawPtr(mutability, substs) => {
74 let ty = apply_ty.parameters[0].clone().to_chalk(db); 71 let ty = substs[0].clone().to_chalk(db);
75 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner) 72 chalk_ir::TyKind::Raw(mutability.to_chalk(db), ty).intern(&Interner)
76 } 73 }
77 TypeCtor::Slice => { 74 Ty::Slice(substs) => {
78 chalk_ir::TyKind::Slice(apply_ty.parameters[0].clone().to_chalk(db)) 75 chalk_ir::TyKind::Slice(substs[0].clone().to_chalk(db)).intern(&Interner)
79 .intern(&Interner) 76 }
80 } 77 Ty::Str => chalk_ir::TyKind::Str.intern(&Interner),
81 TypeCtor::Str => chalk_ir::TyKind::Str.intern(&Interner), 78 Ty::FnDef(callable_def, substs) => {
82 TypeCtor::FnDef(callable_def) => { 79 let id = callable_def.to_chalk(db);
83 let id = callable_def.to_chalk(db); 80 let substitution = substs.to_chalk(db);
84 let substitution = apply_ty.parameters.to_chalk(db); 81 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner)
85 chalk_ir::TyKind::FnDef(id, substitution).intern(&Interner) 82 }
86 } 83 Ty::Never => chalk_ir::TyKind::Never.intern(&Interner),
87 TypeCtor::Never => chalk_ir::TyKind::Never.intern(&Interner),
88 84
89 TypeCtor::Closure { def, expr } => { 85 Ty::Closure { def, expr, substs } => {
90 let closure_id = db.intern_closure((def, expr)); 86 let closure_id = db.intern_closure((def, expr));
91 let substitution = apply_ty.parameters.to_chalk(db); 87 let substitution = substs.to_chalk(db);
92 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner) 88 chalk_ir::TyKind::Closure(closure_id.into(), substitution).intern(&Interner)
93 } 89 }
94 90
95 TypeCtor::Adt(adt_id) => { 91 Ty::Adt(adt_id, substs) => {
96 let substitution = apply_ty.parameters.to_chalk(db); 92 let substitution = substs.to_chalk(db);
97 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner) 93 chalk_ir::TyKind::Adt(chalk_ir::AdtId(adt_id), substitution).intern(&Interner)
98 } 94 }
99 },
100 Ty::Projection(proj_ty) => { 95 Ty::Projection(proj_ty) => {
101 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db); 96 let associated_ty_id = TypeAliasAsAssocType(proj_ty.associated_ty).to_chalk(db);
102 let substitution = proj_ty.parameters.to_chalk(db); 97 let substitution = proj_ty.parameters.to_chalk(db);
@@ -143,9 +138,7 @@ impl ToChalk for Ty {
143 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self { 138 fn from_chalk(db: &dyn HirDatabase, chalk: chalk_ir::Ty<Interner>) -> Self {
144 match chalk.data(&Interner).kind.clone() { 139 match chalk.data(&Interner).kind.clone() {
145 chalk_ir::TyKind::Error => Ty::Unknown, 140 chalk_ir::TyKind::Error => Ty::Unknown,
146 chalk_ir::TyKind::Array(ty, _size) => { 141 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) => { 142 chalk_ir::TyKind::Placeholder(idx) => {
150 assert_eq!(idx.ui, UniverseIndex::ROOT); 143 assert_eq!(idx.ui, UniverseIndex::ROOT);
151 let interned_id = crate::db::GlobalTypeParamId::from_intern_id( 144 let interned_id = crate::db::GlobalTypeParamId::from_intern_id(
@@ -175,13 +168,11 @@ impl ToChalk for Ty {
175 db, 168 db,
176 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"), 169 substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
177 ); 170 );
178 Ty::Apply(ApplicationTy { 171 Ty::FnPtr {
179 ctor: TypeCtor::FnPtr { 172 num_args: (parameters.len() - 1) as u16,
180 num_args: (parameters.len() - 1) as u16, 173 is_varargs: variadic,
181 is_varargs: variadic, 174 substs: parameters,
182 }, 175 }
183 parameters,
184 })
185 } 176 }
186 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx), 177 chalk_ir::TyKind::BoundVar(idx) => Ty::Bound(idx),
187 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown, 178 chalk_ir::TyKind::InferenceVar(_iv, _kind) => Ty::Unknown,
@@ -196,60 +187,50 @@ impl ToChalk for Ty {
196 Ty::Dyn(predicates) 187 Ty::Dyn(predicates)
197 } 188 }
198 189
199 chalk_ir::TyKind::Adt(struct_id, subst) => { 190 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) 191 chalk_ir::TyKind::AssociatedType(type_id, subst) => Ty::AssociatedType(
201 } 192 from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0,
202 chalk_ir::TyKind::AssociatedType(type_id, subst) => apply_ty_from_chalk( 193 from_chalk(db, subst),
203 db,
204 TypeCtor::AssociatedType(from_chalk::<TypeAliasAsAssocType, _>(db, type_id).0),
205 subst,
206 ), 194 ),
195
207 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => { 196 chalk_ir::TyKind::OpaqueType(opaque_type_id, subst) => {
208 apply_ty_from_chalk(db, TypeCtor::OpaqueType(from_chalk(db, opaque_type_id)), subst) 197 Ty::OpaqueType(from_chalk(db, opaque_type_id), from_chalk(db, subst))
209 } 198 }
210 199
211 chalk_ir::TyKind::Scalar(scalar) => Ty::simple(TypeCtor::Scalar(scalar)), 200 chalk_ir::TyKind::Scalar(scalar) => Ty::Scalar(scalar),
212 chalk_ir::TyKind::Tuple(cardinality, subst) => { 201 chalk_ir::TyKind::Tuple(cardinality, subst) => {
213 apply_ty_from_chalk(db, TypeCtor::Tuple { cardinality: cardinality as u16 }, subst) 202 Ty::Tuple { cardinality: cardinality as u16, substs: from_chalk(db, subst) }
214 } 203 }
215 chalk_ir::TyKind::Raw(mutability, ty) => { 204 chalk_ir::TyKind::Raw(mutability, ty) => {
216 Ty::apply_one(TypeCtor::RawPtr(from_chalk(db, mutability)), from_chalk(db, ty)) 205 Ty::RawPtr(from_chalk(db, mutability), Substs::single(from_chalk(db, ty)))
217 } 206 }
218 chalk_ir::TyKind::Slice(ty) => Ty::apply_one(TypeCtor::Slice, from_chalk(db, ty)), 207 chalk_ir::TyKind::Slice(ty) => Ty::Slice(Substs::single(from_chalk(db, ty))),
219 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => { 208 chalk_ir::TyKind::Ref(mutability, _lifetime, ty) => {
220 Ty::apply_one(TypeCtor::Ref(from_chalk(db, mutability)), from_chalk(db, ty)) 209 Ty::Ref(from_chalk(db, mutability), Substs::single(from_chalk(db, ty)))
221 } 210 }
222 chalk_ir::TyKind::Str => Ty::simple(TypeCtor::Str), 211 chalk_ir::TyKind::Str => Ty::Str,
223 chalk_ir::TyKind::Never => Ty::simple(TypeCtor::Never), 212 chalk_ir::TyKind::Never => Ty::Never,
224 213
225 chalk_ir::TyKind::FnDef(fn_def_id, subst) => { 214 chalk_ir::TyKind::FnDef(fn_def_id, subst) => {
226 let callable_def = from_chalk(db, fn_def_id); 215 Ty::FnDef(from_chalk(db, fn_def_id), from_chalk(db, subst))
227 apply_ty_from_chalk(db, TypeCtor::FnDef(callable_def), subst)
228 } 216 }
229 217
230 chalk_ir::TyKind::Closure(id, subst) => { 218 chalk_ir::TyKind::Closure(id, subst) => {
231 let id: crate::db::ClosureId = id.into(); 219 let id: crate::db::ClosureId = id.into();
232 let (def, expr) = db.lookup_intern_closure(id); 220 let (def, expr) = db.lookup_intern_closure(id);
233 apply_ty_from_chalk(db, TypeCtor::Closure { def, expr }, subst) 221 Ty::Closure { def, expr, substs: from_chalk(db, subst) }
234 } 222 }
235 223
236 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::simple(TypeCtor::ForeignType( 224 chalk_ir::TyKind::Foreign(foreign_def_id) => Ty::ForeignType(
237 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0, 225 from_chalk::<TypeAliasAsForeignType, _>(db, foreign_def_id).0,
238 )), 226 Substs::empty(),
227 ),
239 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME 228 chalk_ir::TyKind::Generator(_, _) => unimplemented!(), // FIXME
240 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME 229 chalk_ir::TyKind::GeneratorWitness(_, _) => unimplemented!(), // FIXME
241 } 230 }
242 } 231 }
243} 232}
244 233
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 234/// 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. 235/// fake lifetime here, because Chalks built-in logic may expect it to be there.
255fn ref_to_chalk( 236fn ref_to_chalk(