aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/infer/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r--crates/hir_ty/src/infer/expr.rs280
1 files changed, 143 insertions, 137 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 9bf3b51b0..cf1f1038a 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -3,8 +3,8 @@
3use std::iter::{repeat, repeat_with}; 3use std::iter::{repeat, repeat_with};
4use std::{mem, sync::Arc}; 4use std::{mem, sync::Arc};
5 5
6use chalk_ir::{Mutability, TyVariableKind};
6use hir_def::{ 7use hir_def::{
7 builtin_type::Signedness,
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
@@ -15,11 +15,14 @@ use syntax::ast::RangeOp;
15use test_utils::mark; 15use test_utils::mark;
16 16
17use crate::{ 17use crate::{
18 autoderef, method_resolution, op, 18 autoderef,
19 lower::lower_to_chalk_mutability,
20 method_resolution, op,
21 primitive::{self, UintTy},
19 traits::{FnTrait, InEnvironment}, 22 traits::{FnTrait, InEnvironment},
20 utils::{generics, variant_data, Generics}, 23 utils::{generics, variant_data, Generics},
21 ApplicationTy, Binders, CallableDefId, InferTy, IntTy, Mutability, Obligation, OpaqueTyId, 24 Binders, CallableDefId, FnPointer, FnSig, Obligation, OpaqueTyId, Rawness, Scalar, Substs,
22 Rawness, Substs, TraitRef, Ty, TypeCtor, 25 TraitRef, Ty,
23}; 26};
24 27
25use super::{ 28use super::{
@@ -82,10 +85,7 @@ impl<'a> InferenceContext<'a> {
82 arg_tys.push(arg); 85 arg_tys.push(arg);
83 } 86 }
84 let parameters = param_builder.build(); 87 let parameters = param_builder.build();
85 let arg_ty = Ty::Apply(ApplicationTy { 88 let arg_ty = Ty::Tuple(num_args, parameters);
86 ctor: TypeCtor::Tuple { cardinality: num_args as u16 },
87 parameters,
88 });
89 let substs = 89 let substs =
90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build(); 90 Substs::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
91 91
@@ -120,7 +120,7 @@ impl<'a> InferenceContext<'a> {
120 Expr::Missing => Ty::Unknown, 120 Expr::Missing => Ty::Unknown,
121 Expr::If { condition, then_branch, else_branch } => { 121 Expr::If { condition, then_branch, else_branch } => {
122 // if let is desugared to match, so this is always simple if 122 // if let is desugared to match, so this is always simple if
123 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 123 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
124 124
125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe); 125 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
126 let mut both_arms_diverge = Diverges::Always; 126 let mut both_arms_diverge = Diverges::Always;
@@ -137,24 +137,33 @@ impl<'a> InferenceContext<'a> {
137 137
138 self.coerce_merge_branch(&then_ty, &else_ty) 138 self.coerce_merge_branch(&then_ty, &else_ty)
139 } 139 }
140 Expr::Block { statements, tail, label } => match label { 140 Expr::Block { statements, tail, label, id: _ } => {
141 Some(_) => { 141 let old_resolver = mem::replace(
142 let break_ty = self.table.new_type_var(); 142 &mut self.resolver,
143 self.breakables.push(BreakableContext { 143 resolver_for_expr(self.db.upcast(), self.owner, tgt_expr),
144 may_break: false, 144 );
145 break_ty: break_ty.clone(), 145 let ty = match label {
146 label: label.map(|label| self.body[label].name.clone()), 146 Some(_) => {
147 }); 147 let break_ty = self.table.new_type_var();
148 let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); 148 self.breakables.push(BreakableContext {
149 let ctxt = self.breakables.pop().expect("breakable stack broken"); 149 may_break: false,
150 if ctxt.may_break { 150 break_ty: break_ty.clone(),
151 ctxt.break_ty 151 label: label.map(|label| self.body[label].name.clone()),
152 } else { 152 });
153 ty 153 let ty =
154 self.infer_block(statements, *tail, &Expectation::has_type(break_ty));
155 let ctxt = self.breakables.pop().expect("breakable stack broken");
156 if ctxt.may_break {
157 ctxt.break_ty
158 } else {
159 ty
160 }
154 } 161 }
155 } 162 None => self.infer_block(statements, *tail, expected),
156 None => self.infer_block(statements, *tail, expected), 163 };
157 }, 164 self.resolver = old_resolver;
165 ty
166 }
158 Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected), 167 Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
159 Expr::TryBlock { body } => { 168 Expr::TryBlock { body } => {
160 let _inner = self.infer_expr(*body, expected); 169 let _inner = self.infer_expr(*body, expected);
@@ -166,7 +175,7 @@ impl<'a> InferenceContext<'a> {
166 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> 175 // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType>
167 let inner_ty = self.infer_expr(*body, &Expectation::none()); 176 let inner_ty = self.infer_expr(*body, &Expectation::none());
168 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); 177 let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body);
169 Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) 178 Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty))
170 } 179 }
171 Expr::Loop { body, label } => { 180 Expr::Loop { body, label } => {
172 self.breakables.push(BreakableContext { 181 self.breakables.push(BreakableContext {
@@ -184,7 +193,7 @@ impl<'a> InferenceContext<'a> {
184 if ctxt.may_break { 193 if ctxt.may_break {
185 ctxt.break_ty 194 ctxt.break_ty
186 } else { 195 } else {
187 Ty::simple(TypeCtor::Never) 196 Ty::Never
188 } 197 }
189 } 198 }
190 Expr::While { condition, body, label } => { 199 Expr::While { condition, body, label } => {
@@ -194,7 +203,7 @@ impl<'a> InferenceContext<'a> {
194 label: label.map(|label| self.body[label].name.clone()), 203 label: label.map(|label| self.body[label].name.clone()),
195 }); 204 });
196 // while let is desugared to a match loop, so this is always simple while 205 // while let is desugared to a match loop, so this is always simple while
197 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); 206 self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool)));
198 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 207 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
199 let _ctxt = self.breakables.pop().expect("breakable stack broken"); 208 let _ctxt = self.breakables.pop().expect("breakable stack broken");
200 // the body may not run, so it diverging doesn't mean we diverge 209 // the body may not run, so it diverging doesn't mean we diverge
@@ -241,12 +250,12 @@ impl<'a> InferenceContext<'a> {
241 None => self.table.new_type_var(), 250 None => self.table.new_type_var(),
242 }; 251 };
243 sig_tys.push(ret_ty.clone()); 252 sig_tys.push(ret_ty.clone());
244 let sig_ty = Ty::apply( 253 let sig_ty = Ty::Function(FnPointer {
245 TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, 254 num_args: sig_tys.len() - 1,
246 Substs(sig_tys.clone().into()), 255 sig: FnSig { variadic: false },
247 ); 256 substs: Substs(sig_tys.clone().into()),
248 let closure_ty = 257 });
249 Ty::apply_one(TypeCtor::Closure { def: self.owner, expr: tgt_expr }, sig_ty); 258 let closure_ty = Ty::Closure(self.owner, tgt_expr, Substs::single(sig_ty));
250 259
251 // Eagerly try to relate the closure type with the expected 260 // Eagerly try to relate the closure type with the expected
252 // type, otherwise we often won't have enough information to 261 // type, otherwise we often won't have enough information to
@@ -297,11 +306,8 @@ impl<'a> InferenceContext<'a> {
297 Expr::Match { expr, arms } => { 306 Expr::Match { expr, arms } => {
298 let input_ty = self.infer_expr(*expr, &Expectation::none()); 307 let input_ty = self.infer_expr(*expr, &Expectation::none());
299 308
300 let mut result_ty = if arms.is_empty() { 309 let mut result_ty =
301 Ty::simple(TypeCtor::Never) 310 if arms.is_empty() { Ty::Never } else { self.table.new_type_var() };
302 } else {
303 self.table.new_type_var()
304 };
305 311
306 let matchee_diverges = self.diverges; 312 let matchee_diverges = self.diverges;
307 let mut all_arms_diverge = Diverges::Always; 313 let mut all_arms_diverge = Diverges::Always;
@@ -312,7 +318,7 @@ impl<'a> InferenceContext<'a> {
312 if let Some(guard_expr) = arm.guard { 318 if let Some(guard_expr) = arm.guard {
313 self.infer_expr( 319 self.infer_expr(
314 guard_expr, 320 guard_expr,
315 &Expectation::has_type(Ty::simple(TypeCtor::Bool)), 321 &Expectation::has_type(Ty::Scalar(Scalar::Bool)),
316 ); 322 );
317 } 323 }
318 324
@@ -330,7 +336,7 @@ impl<'a> InferenceContext<'a> {
330 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr); 336 let resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
331 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) 337 self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown)
332 } 338 }
333 Expr::Continue { .. } => Ty::simple(TypeCtor::Never), 339 Expr::Continue { .. } => Ty::Never,
334 Expr::Break { expr, label } => { 340 Expr::Break { expr, label } => {
335 let val_ty = if let Some(expr) = expr { 341 let val_ty = if let Some(expr) = expr {
336 self.infer_expr(*expr, &Expectation::none()) 342 self.infer_expr(*expr, &Expectation::none())
@@ -355,8 +361,7 @@ impl<'a> InferenceContext<'a> {
355 expr: tgt_expr, 361 expr: tgt_expr,
356 }); 362 });
357 } 363 }
358 364 Ty::Never
359 Ty::simple(TypeCtor::Never)
360 } 365 }
361 Expr::Return { expr } => { 366 Expr::Return { expr } => {
362 if let Some(expr) = expr { 367 if let Some(expr) = expr {
@@ -365,14 +370,14 @@ impl<'a> InferenceContext<'a> {
365 let unit = Ty::unit(); 370 let unit = Ty::unit();
366 self.coerce(&unit, &self.return_ty.clone()); 371 self.coerce(&unit, &self.return_ty.clone());
367 } 372 }
368 Ty::simple(TypeCtor::Never) 373 Ty::Never
369 } 374 }
370 Expr::Yield { expr } => { 375 Expr::Yield { expr } => {
371 // FIXME: track yield type for coercion 376 // FIXME: track yield type for coercion
372 if let Some(expr) = expr { 377 if let Some(expr) = expr {
373 self.infer_expr(*expr, &Expectation::none()); 378 self.infer_expr(*expr, &Expectation::none());
374 } 379 }
375 Ty::simple(TypeCtor::Never) 380 Ty::Never
376 } 381 }
377 Expr::RecordLit { path, fields, spread } => { 382 Expr::RecordLit { path, fields, spread } => {
378 let (ty, def_id) = self.resolve_variant(path.as_ref()); 383 let (ty, def_id) = self.resolve_variant(path.as_ref());
@@ -382,7 +387,7 @@ impl<'a> InferenceContext<'a> {
382 387
383 self.unify(&ty, &expected.ty); 388 self.unify(&ty, &expected.ty);
384 389
385 let substs = ty.substs().unwrap_or_else(Substs::empty); 390 let substs = ty.substs().cloned().unwrap_or_else(Substs::empty);
386 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); 391 let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default();
387 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); 392 let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it));
388 for (field_idx, field) in fields.iter().enumerate() { 393 for (field_idx, field) in fields.iter().enumerate() {
@@ -421,30 +426,23 @@ impl<'a> InferenceContext<'a> {
421 }, 426 },
422 ) 427 )
423 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { 428 .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) {
424 Ty::Apply(a_ty) => match a_ty.ctor { 429 Ty::Tuple(_, substs) => {
425 TypeCtor::Tuple { .. } => name 430 name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned())
426 .as_tuple_index() 431 }
427 .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), 432 Ty::Adt(AdtId::StructId(s), parameters) => {
428 TypeCtor::Adt(AdtId::StructId(s)) => { 433 self.db.struct_data(s).variant_data.field(name).map(|local_id| {
429 self.db.struct_data(s).variant_data.field(name).map(|local_id| { 434 let field = FieldId { parent: s.into(), local_id };
430 let field = FieldId { parent: s.into(), local_id }; 435 self.write_field_resolution(tgt_expr, field);
431 self.write_field_resolution(tgt_expr, field); 436 self.db.field_types(s.into())[field.local_id].clone().subst(&parameters)
432 self.db.field_types(s.into())[field.local_id] 437 })
433 .clone() 438 }
434 .subst(&a_ty.parameters) 439 Ty::Adt(AdtId::UnionId(u), parameters) => {
435 }) 440 self.db.union_data(u).variant_data.field(name).map(|local_id| {
436 } 441 let field = FieldId { parent: u.into(), local_id };
437 TypeCtor::Adt(AdtId::UnionId(u)) => { 442 self.write_field_resolution(tgt_expr, field);
438 self.db.union_data(u).variant_data.field(name).map(|local_id| { 443 self.db.field_types(u.into())[field.local_id].clone().subst(&parameters)
439 let field = FieldId { parent: u.into(), local_id }; 444 })
440 self.write_field_resolution(tgt_expr, field); 445 }
441 self.db.field_types(u.into())[field.local_id]
442 .clone()
443 .subst(&a_ty.parameters)
444 })
445 }
446 _ => None,
447 },
448 _ => None, 446 _ => None,
449 }) 447 })
450 .unwrap_or(Ty::Unknown); 448 .unwrap_or(Ty::Unknown);
@@ -466,10 +464,11 @@ impl<'a> InferenceContext<'a> {
466 cast_ty 464 cast_ty
467 } 465 }
468 Expr::Ref { expr, rawness, mutability } => { 466 Expr::Ref { expr, rawness, mutability } => {
467 let mutability = lower_to_chalk_mutability(*mutability);
469 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = 468 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) =
470 &expected.ty.as_reference_or_ptr() 469 &expected.ty.as_reference_or_ptr()
471 { 470 {
472 if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { 471 if *exp_mutability == Mutability::Mut && mutability == Mutability::Not {
473 // FIXME: throw type error - expected mut reference but found shared ref, 472 // FIXME: throw type error - expected mut reference but found shared ref,
474 // which cannot be coerced 473 // which cannot be coerced
475 } 474 }
@@ -482,16 +481,24 @@ impl<'a> InferenceContext<'a> {
482 Expectation::none() 481 Expectation::none()
483 }; 482 };
484 let inner_ty = self.infer_expr_inner(*expr, &expectation); 483 let inner_ty = self.infer_expr_inner(*expr, &expectation);
485 let ty = match rawness { 484 match rawness {
486 Rawness::RawPtr => TypeCtor::RawPtr(*mutability), 485 Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)),
487 Rawness::Ref => TypeCtor::Ref(*mutability), 486 Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)),
488 }; 487 }
489 Ty::apply_one(ty, inner_ty)
490 } 488 }
491 Expr::Box { expr } => { 489 Expr::Box { expr } => {
492 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); 490 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
493 if let Some(box_) = self.resolve_boxed_box() { 491 if let Some(box_) = self.resolve_boxed_box() {
494 Ty::apply_one(TypeCtor::Adt(box_), inner_ty) 492 let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len());
493 sb = sb.push(inner_ty);
494 match self.db.generic_defaults(box_.into()).as_ref() {
495 [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
496 sb = sb.push(alloc_ty.value.clone());
497 }
498 _ => (),
499 }
500 sb = sb.fill(repeat_with(|| self.table.new_type_var()));
501 Ty::Adt(box_, sb.build())
495 } else { 502 } else {
496 Ty::Unknown 503 Ty::Unknown
497 } 504 }
@@ -521,13 +528,11 @@ impl<'a> InferenceContext<'a> {
521 UnaryOp::Neg => { 528 UnaryOp::Neg => {
522 match &inner_ty { 529 match &inner_ty {
523 // Fast path for builtins 530 // Fast path for builtins
524 Ty::Apply(ApplicationTy { 531 Ty::Scalar(Scalar::Int(_))
525 ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), 532 | Ty::Scalar(Scalar::Uint(_))
526 .. 533 | Ty::Scalar(Scalar::Float(_))
527 }) 534 | Ty::InferenceVar(_, TyVariableKind::Integer)
528 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) 535 | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty,
529 | Ty::Infer(InferTy::IntVar(..))
530 | Ty::Infer(InferTy::FloatVar(..)) => inner_ty,
531 // Otherwise we resolve via the std::ops::Neg trait 536 // Otherwise we resolve via the std::ops::Neg trait
532 _ => self 537 _ => self
533 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), 538 .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()),
@@ -536,9 +541,10 @@ impl<'a> InferenceContext<'a> {
536 UnaryOp::Not => { 541 UnaryOp::Not => {
537 match &inner_ty { 542 match &inner_ty {
538 // Fast path for builtins 543 // Fast path for builtins
539 Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) 544 Ty::Scalar(Scalar::Bool)
540 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) 545 | Ty::Scalar(Scalar::Int(_))
541 | Ty::Infer(InferTy::IntVar(..)) => inner_ty, 546 | Ty::Scalar(Scalar::Uint(_))
547 | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty,
542 // Otherwise we resolve via the std::ops::Not trait 548 // Otherwise we resolve via the std::ops::Not trait
543 _ => self 549 _ => self
544 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), 550 .resolve_associated_type(inner_ty, self.resolve_ops_not_output()),
@@ -549,7 +555,7 @@ impl<'a> InferenceContext<'a> {
549 Expr::BinaryOp { lhs, rhs, op } => match op { 555 Expr::BinaryOp { lhs, rhs, op } => match op {
550 Some(op) => { 556 Some(op) => {
551 let lhs_expectation = match op { 557 let lhs_expectation = match op {
552 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), 558 BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)),
553 _ => Expectation::none(), 559 _ => Expectation::none(),
554 }; 560 };
555 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); 561 let lhs_ty = self.infer_expr(*lhs, &lhs_expectation);
@@ -580,31 +586,31 @@ impl<'a> InferenceContext<'a> {
580 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect)); 586 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect));
581 match (range_type, lhs_ty, rhs_ty) { 587 match (range_type, lhs_ty, rhs_ty) {
582 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { 588 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
583 Some(adt) => Ty::simple(TypeCtor::Adt(adt)), 589 Some(adt) => Ty::Adt(adt, Substs::empty()),
584 None => Ty::Unknown, 590 None => Ty::Unknown,
585 }, 591 },
586 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { 592 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
587 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 593 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
588 None => Ty::Unknown, 594 None => Ty::Unknown,
589 }, 595 },
590 (RangeOp::Inclusive, None, Some(ty)) => { 596 (RangeOp::Inclusive, None, Some(ty)) => {
591 match self.resolve_range_to_inclusive() { 597 match self.resolve_range_to_inclusive() {
592 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 598 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
593 None => Ty::Unknown, 599 None => Ty::Unknown,
594 } 600 }
595 } 601 }
596 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { 602 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
597 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 603 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
598 None => Ty::Unknown, 604 None => Ty::Unknown,
599 }, 605 },
600 (RangeOp::Inclusive, Some(_), Some(ty)) => { 606 (RangeOp::Inclusive, Some(_), Some(ty)) => {
601 match self.resolve_range_inclusive() { 607 match self.resolve_range_inclusive() {
602 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 608 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
603 None => Ty::Unknown, 609 None => Ty::Unknown,
604 } 610 }
605 } 611 }
606 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { 612 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
607 Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), 613 Some(adt) => Ty::Adt(adt, Substs::single(ty)),
608 None => Ty::Unknown, 614 None => Ty::Unknown,
609 }, 615 },
610 (RangeOp::Inclusive, _, None) => Ty::Unknown, 616 (RangeOp::Inclusive, _, None) => Ty::Unknown,
@@ -638,7 +644,7 @@ impl<'a> InferenceContext<'a> {
638 } 644 }
639 Expr::Tuple { exprs } => { 645 Expr::Tuple { exprs } => {
640 let mut tys = match &expected.ty { 646 let mut tys = match &expected.ty {
641 ty_app!(TypeCtor::Tuple { .. }, st) => st 647 Ty::Tuple(_, substs) => substs
642 .iter() 648 .iter()
643 .cloned() 649 .cloned()
644 .chain(repeat_with(|| self.table.new_type_var())) 650 .chain(repeat_with(|| self.table.new_type_var()))
@@ -651,15 +657,11 @@ impl<'a> InferenceContext<'a> {
651 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); 657 self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
652 } 658 }
653 659
654 Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) 660 Ty::Tuple(tys.len(), Substs(tys.into()))
655 } 661 }
656 Expr::Array(array) => { 662 Expr::Array(array) => {
657 let elem_ty = match &expected.ty { 663 let elem_ty = match &expected.ty {
658 // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed 664 Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(),
659 #[allow(unreachable_patterns)]
660 ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => {
661 st.as_single().clone()
662 }
663 _ => self.table.new_type_var(), 665 _ => self.table.new_type_var(),
664 }; 666 };
665 667
@@ -676,30 +678,38 @@ impl<'a> InferenceContext<'a> {
676 ); 678 );
677 self.infer_expr( 679 self.infer_expr(
678 *repeat, 680 *repeat,
679 &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), 681 &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))),
680 ); 682 );
681 } 683 }
682 } 684 }
683 685
684 Ty::apply_one(TypeCtor::Array, elem_ty) 686 Ty::Array(Substs::single(elem_ty))
685 } 687 }
686 Expr::Literal(lit) => match lit { 688 Expr::Literal(lit) => match lit {
687 Literal::Bool(..) => Ty::simple(TypeCtor::Bool), 689 Literal::Bool(..) => Ty::Scalar(Scalar::Bool),
688 Literal::String(..) => { 690 Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)),
689 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str))
690 }
691 Literal::ByteString(..) => { 691 Literal::ByteString(..) => {
692 let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); 692 let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8));
693 let array_type = Ty::apply_one(TypeCtor::Array, byte_type); 693 let array_type = Ty::Array(Substs::single(byte_type));
694 Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) 694 Ty::Ref(Mutability::Not, Substs::single(array_type))
695 } 695 }
696 Literal::Char(..) => Ty::simple(TypeCtor::Char), 696 Literal::Char(..) => Ty::Scalar(Scalar::Char),
697 Literal::Int(_v, ty) => match ty { 697 Literal::Int(_v, ty) => match ty {
698 Some(int_ty) => Ty::simple(TypeCtor::Int((*int_ty).into())), 698 Some(int_ty) => {
699 Ty::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
700 }
701 None => self.table.new_integer_var(),
702 },
703 Literal::Uint(_v, ty) => match ty {
704 Some(int_ty) => {
705 Ty::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
706 }
699 None => self.table.new_integer_var(), 707 None => self.table.new_integer_var(),
700 }, 708 },
701 Literal::Float(_v, ty) => match ty { 709 Literal::Float(_v, ty) => match ty {
702 Some(float_ty) => Ty::simple(TypeCtor::Float((*float_ty).into())), 710 Some(float_ty) => {
711 Ty::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
712 }
703 None => self.table.new_float_var(), 713 None => self.table.new_float_var(),
704 }, 714 },
705 }, 715 },
@@ -755,7 +765,7 @@ impl<'a> InferenceContext<'a> {
755 // `!`). 765 // `!`).
756 if self.diverges.is_always() { 766 if self.diverges.is_always() {
757 // we don't even make an attempt at coercion 767 // we don't even make an attempt at coercion
758 self.table.new_maybe_never_type_var() 768 self.table.new_maybe_never_var()
759 } else { 769 } else {
760 self.coerce(&Ty::unit(), expected.coercion_target()); 770 self.coerce(&Ty::unit(), expected.coercion_target());
761 Ty::unit() 771 Ty::unit()
@@ -812,7 +822,7 @@ impl<'a> InferenceContext<'a> {
812 // Apply autoref so the below unification works correctly 822 // Apply autoref so the below unification works correctly
813 // FIXME: return correct autorefs from lookup_method 823 // FIXME: return correct autorefs from lookup_method
814 let actual_receiver_ty = match expected_receiver_ty.as_reference() { 824 let actual_receiver_ty = match expected_receiver_ty.as_reference() {
815 Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), 825 Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)),
816 _ => derefed_receiver_ty, 826 _ => derefed_receiver_ty,
817 }; 827 };
818 self.unify(&expected_receiver_ty, &actual_receiver_ty); 828 self.unify(&expected_receiver_ty, &actual_receiver_ty);
@@ -889,30 +899,26 @@ impl<'a> InferenceContext<'a> {
889 } 899 }
890 900
891 fn register_obligations_for_call(&mut self, callable_ty: &Ty) { 901 fn register_obligations_for_call(&mut self, callable_ty: &Ty) {
892 if let Ty::Apply(a_ty) = callable_ty { 902 if let &Ty::FnDef(def, ref parameters) = callable_ty {
893 if let TypeCtor::FnDef(def) = a_ty.ctor { 903 let generic_predicates = self.db.generic_predicates(def.into());
894 let generic_predicates = self.db.generic_predicates(def.into()); 904 for predicate in generic_predicates.iter() {
895 for predicate in generic_predicates.iter() { 905 let predicate = predicate.clone().subst(parameters);
896 let predicate = predicate.clone().subst(&a_ty.parameters); 906 if let Some(obligation) = Obligation::from_predicate(predicate) {
897 if let Some(obligation) = Obligation::from_predicate(predicate) { 907 self.obligations.push(obligation);
898 self.obligations.push(obligation);
899 }
900 } 908 }
901 // add obligation for trait implementation, if this is a trait method 909 }
902 match def { 910 // add obligation for trait implementation, if this is a trait method
903 CallableDefId::FunctionId(f) => { 911 match def {
904 if let AssocContainerId::TraitId(trait_) = 912 CallableDefId::FunctionId(f) => {
905 f.lookup(self.db.upcast()).container 913 if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container
906 { 914 {
907 // construct a TraitDef 915 // construct a TraitDef
908 let substs = a_ty 916 let substs =
909 .parameters 917 parameters.prefix(generics(self.db.upcast(), trait_.into()).len());
910 .prefix(generics(self.db.upcast(), trait_.into()).len()); 918 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
911 self.obligations.push(Obligation::Trait(TraitRef { trait_, substs }));
912 }
913 } 919 }
914 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
915 } 920 }
921 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
916 } 922 }
917 } 923 }
918 } 924 }