aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
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/src/infer/expr.rs
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/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs238
1 files changed, 95 insertions, 143 deletions
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 }