diff options
Diffstat (limited to 'crates/hir_ty/src/infer/expr.rs')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 236 |
1 files changed, 115 insertions, 121 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index cb59a6937..cf1f1038a 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | use std::iter::{repeat, repeat_with}; | 3 | use std::iter::{repeat, repeat_with}; |
4 | use std::{mem, sync::Arc}; | 4 | use std::{mem, sync::Arc}; |
5 | 5 | ||
6 | use chalk_ir::{Mutability, TyVariableKind}; | ||
6 | use hir_def::{ | 7 | use 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; | |||
15 | use test_utils::mark; | 15 | use test_utils::mark; |
16 | 16 | ||
17 | use crate::{ | 17 | use 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 | ||
25 | use super::{ | 28 | use 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; |
@@ -175,7 +175,7 @@ impl<'a> InferenceContext<'a> { | |||
175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> | 175 | // existenail type AsyncBlockImplTrait<InnerType>: Future<Output = InnerType> |
176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); | 176 | let inner_ty = self.infer_expr(*body, &Expectation::none()); |
177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); | 177 | let opaque_ty_id = OpaqueTyId::AsyncBlockTypeImplTrait(self.owner, *body); |
178 | Ty::apply_one(TypeCtor::OpaqueType(opaque_ty_id), inner_ty) | 178 | Ty::OpaqueType(opaque_ty_id, Substs::single(inner_ty)) |
179 | } | 179 | } |
180 | Expr::Loop { body, label } => { | 180 | Expr::Loop { body, label } => { |
181 | self.breakables.push(BreakableContext { | 181 | self.breakables.push(BreakableContext { |
@@ -193,7 +193,7 @@ impl<'a> InferenceContext<'a> { | |||
193 | if ctxt.may_break { | 193 | if ctxt.may_break { |
194 | ctxt.break_ty | 194 | ctxt.break_ty |
195 | } else { | 195 | } else { |
196 | Ty::simple(TypeCtor::Never) | 196 | Ty::Never |
197 | } | 197 | } |
198 | } | 198 | } |
199 | Expr::While { condition, body, label } => { | 199 | Expr::While { condition, body, label } => { |
@@ -203,7 +203,7 @@ impl<'a> InferenceContext<'a> { | |||
203 | label: label.map(|label| self.body[label].name.clone()), | 203 | label: label.map(|label| self.body[label].name.clone()), |
204 | }); | 204 | }); |
205 | // 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 |
206 | self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool))); | 206 | self.infer_expr(*condition, &Expectation::has_type(Ty::Scalar(Scalar::Bool))); |
207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 207 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); | 208 | let _ctxt = self.breakables.pop().expect("breakable stack broken"); |
209 | // 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 |
@@ -250,12 +250,12 @@ impl<'a> InferenceContext<'a> { | |||
250 | None => self.table.new_type_var(), | 250 | None => self.table.new_type_var(), |
251 | }; | 251 | }; |
252 | sig_tys.push(ret_ty.clone()); | 252 | sig_tys.push(ret_ty.clone()); |
253 | let sig_ty = Ty::apply( | 253 | let sig_ty = Ty::Function(FnPointer { |
254 | TypeCtor::FnPtr { num_args: sig_tys.len() as u16 - 1, is_varargs: false }, | 254 | num_args: sig_tys.len() - 1, |
255 | Substs(sig_tys.clone().into()), | 255 | sig: FnSig { variadic: false }, |
256 | ); | 256 | substs: Substs(sig_tys.clone().into()), |
257 | let closure_ty = | 257 | }); |
258 | 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)); |
259 | 259 | ||
260 | // Eagerly try to relate the closure type with the expected | 260 | // Eagerly try to relate the closure type with the expected |
261 | // type, otherwise we often won't have enough information to | 261 | // type, otherwise we often won't have enough information to |
@@ -306,11 +306,8 @@ impl<'a> InferenceContext<'a> { | |||
306 | Expr::Match { expr, arms } => { | 306 | Expr::Match { expr, arms } => { |
307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); | 307 | let input_ty = self.infer_expr(*expr, &Expectation::none()); |
308 | 308 | ||
309 | let mut result_ty = if arms.is_empty() { | 309 | let mut result_ty = |
310 | Ty::simple(TypeCtor::Never) | 310 | if arms.is_empty() { Ty::Never } else { self.table.new_type_var() }; |
311 | } else { | ||
312 | self.table.new_type_var() | ||
313 | }; | ||
314 | 311 | ||
315 | let matchee_diverges = self.diverges; | 312 | let matchee_diverges = self.diverges; |
316 | let mut all_arms_diverge = Diverges::Always; | 313 | let mut all_arms_diverge = Diverges::Always; |
@@ -321,7 +318,7 @@ impl<'a> InferenceContext<'a> { | |||
321 | if let Some(guard_expr) = arm.guard { | 318 | if let Some(guard_expr) = arm.guard { |
322 | self.infer_expr( | 319 | self.infer_expr( |
323 | guard_expr, | 320 | guard_expr, |
324 | &Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 321 | &Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
325 | ); | 322 | ); |
326 | } | 323 | } |
327 | 324 | ||
@@ -339,7 +336,7 @@ impl<'a> InferenceContext<'a> { | |||
339 | 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); |
340 | 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) |
341 | } | 338 | } |
342 | Expr::Continue { .. } => Ty::simple(TypeCtor::Never), | 339 | Expr::Continue { .. } => Ty::Never, |
343 | Expr::Break { expr, label } => { | 340 | Expr::Break { expr, label } => { |
344 | let val_ty = if let Some(expr) = expr { | 341 | let val_ty = if let Some(expr) = expr { |
345 | self.infer_expr(*expr, &Expectation::none()) | 342 | self.infer_expr(*expr, &Expectation::none()) |
@@ -364,8 +361,7 @@ impl<'a> InferenceContext<'a> { | |||
364 | expr: tgt_expr, | 361 | expr: tgt_expr, |
365 | }); | 362 | }); |
366 | } | 363 | } |
367 | 364 | Ty::Never | |
368 | Ty::simple(TypeCtor::Never) | ||
369 | } | 365 | } |
370 | Expr::Return { expr } => { | 366 | Expr::Return { expr } => { |
371 | if let Some(expr) = expr { | 367 | if let Some(expr) = expr { |
@@ -374,14 +370,14 @@ impl<'a> InferenceContext<'a> { | |||
374 | let unit = Ty::unit(); | 370 | let unit = Ty::unit(); |
375 | self.coerce(&unit, &self.return_ty.clone()); | 371 | self.coerce(&unit, &self.return_ty.clone()); |
376 | } | 372 | } |
377 | Ty::simple(TypeCtor::Never) | 373 | Ty::Never |
378 | } | 374 | } |
379 | Expr::Yield { expr } => { | 375 | Expr::Yield { expr } => { |
380 | // FIXME: track yield type for coercion | 376 | // FIXME: track yield type for coercion |
381 | if let Some(expr) = expr { | 377 | if let Some(expr) = expr { |
382 | self.infer_expr(*expr, &Expectation::none()); | 378 | self.infer_expr(*expr, &Expectation::none()); |
383 | } | 379 | } |
384 | Ty::simple(TypeCtor::Never) | 380 | Ty::Never |
385 | } | 381 | } |
386 | Expr::RecordLit { path, fields, spread } => { | 382 | Expr::RecordLit { path, fields, spread } => { |
387 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 383 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
@@ -391,7 +387,7 @@ impl<'a> InferenceContext<'a> { | |||
391 | 387 | ||
392 | self.unify(&ty, &expected.ty); | 388 | self.unify(&ty, &expected.ty); |
393 | 389 | ||
394 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 390 | let substs = ty.substs().cloned().unwrap_or_else(Substs::empty); |
395 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); | 391 | let field_types = def_id.map(|it| self.db.field_types(it)).unwrap_or_default(); |
396 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); | 392 | let variant_data = def_id.map(|it| variant_data(self.db.upcast(), it)); |
397 | for (field_idx, field) in fields.iter().enumerate() { | 393 | for (field_idx, field) in fields.iter().enumerate() { |
@@ -430,30 +426,23 @@ impl<'a> InferenceContext<'a> { | |||
430 | }, | 426 | }, |
431 | ) | 427 | ) |
432 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { | 428 | .find_map(|derefed_ty| match canonicalized.decanonicalize_ty(derefed_ty.value) { |
433 | Ty::Apply(a_ty) => match a_ty.ctor { | 429 | Ty::Tuple(_, substs) => { |
434 | TypeCtor::Tuple { .. } => name | 430 | name.as_tuple_index().and_then(|idx| substs.0.get(idx).cloned()) |
435 | .as_tuple_index() | 431 | } |
436 | .and_then(|idx| a_ty.parameters.0.get(idx).cloned()), | 432 | Ty::Adt(AdtId::StructId(s), parameters) => { |
437 | TypeCtor::Adt(AdtId::StructId(s)) => { | 433 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { |
438 | self.db.struct_data(s).variant_data.field(name).map(|local_id| { | 434 | let field = FieldId { parent: s.into(), local_id }; |
439 | let field = FieldId { parent: s.into(), local_id }; | 435 | self.write_field_resolution(tgt_expr, field); |
440 | self.write_field_resolution(tgt_expr, field); | 436 | self.db.field_types(s.into())[field.local_id].clone().subst(¶meters) |
441 | self.db.field_types(s.into())[field.local_id] | 437 | }) |
442 | .clone() | 438 | } |
443 | .subst(&a_ty.parameters) | 439 | Ty::Adt(AdtId::UnionId(u), parameters) => { |
444 | }) | 440 | self.db.union_data(u).variant_data.field(name).map(|local_id| { |
445 | } | 441 | let field = FieldId { parent: u.into(), local_id }; |
446 | TypeCtor::Adt(AdtId::UnionId(u)) => { | 442 | self.write_field_resolution(tgt_expr, field); |
447 | self.db.union_data(u).variant_data.field(name).map(|local_id| { | 443 | self.db.field_types(u.into())[field.local_id].clone().subst(¶meters) |
448 | let field = FieldId { parent: u.into(), local_id }; | 444 | }) |
449 | self.write_field_resolution(tgt_expr, field); | 445 | } |
450 | self.db.field_types(u.into())[field.local_id] | ||
451 | .clone() | ||
452 | .subst(&a_ty.parameters) | ||
453 | }) | ||
454 | } | ||
455 | _ => None, | ||
456 | }, | ||
457 | _ => None, | 446 | _ => None, |
458 | }) | 447 | }) |
459 | .unwrap_or(Ty::Unknown); | 448 | .unwrap_or(Ty::Unknown); |
@@ -475,10 +464,11 @@ impl<'a> InferenceContext<'a> { | |||
475 | cast_ty | 464 | cast_ty |
476 | } | 465 | } |
477 | Expr::Ref { expr, rawness, mutability } => { | 466 | Expr::Ref { expr, rawness, mutability } => { |
467 | let mutability = lower_to_chalk_mutability(*mutability); | ||
478 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = | 468 | let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = |
479 | &expected.ty.as_reference_or_ptr() | 469 | &expected.ty.as_reference_or_ptr() |
480 | { | 470 | { |
481 | if *exp_mutability == Mutability::Mut && *mutability == Mutability::Shared { | 471 | if *exp_mutability == Mutability::Mut && mutability == Mutability::Not { |
482 | // FIXME: throw type error - expected mut reference but found shared ref, | 472 | // FIXME: throw type error - expected mut reference but found shared ref, |
483 | // which cannot be coerced | 473 | // which cannot be coerced |
484 | } | 474 | } |
@@ -491,19 +481,24 @@ impl<'a> InferenceContext<'a> { | |||
491 | Expectation::none() | 481 | Expectation::none() |
492 | }; | 482 | }; |
493 | let inner_ty = self.infer_expr_inner(*expr, &expectation); | 483 | let inner_ty = self.infer_expr_inner(*expr, &expectation); |
494 | let ty = match rawness { | 484 | match rawness { |
495 | Rawness::RawPtr => TypeCtor::RawPtr(*mutability), | 485 | Rawness::RawPtr => Ty::Raw(mutability, Substs::single(inner_ty)), |
496 | Rawness::Ref => TypeCtor::Ref(*mutability), | 486 | Rawness::Ref => Ty::Ref(mutability, Substs::single(inner_ty)), |
497 | }; | 487 | } |
498 | Ty::apply_one(ty, inner_ty) | ||
499 | } | 488 | } |
500 | Expr::Box { expr } => { | 489 | Expr::Box { expr } => { |
501 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 490 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
502 | if let Some(box_) = self.resolve_boxed_box() { | 491 | if let Some(box_) = self.resolve_boxed_box() { |
503 | let mut sb = Substs::build_for_type_ctor(self.db, TypeCtor::Adt(box_)); | 492 | let mut sb = Substs::builder(generics(self.db.upcast(), box_.into()).len()); |
504 | sb = sb.push(inner_ty); | 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 | } | ||
505 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); | 500 | sb = sb.fill(repeat_with(|| self.table.new_type_var())); |
506 | Ty::apply(TypeCtor::Adt(box_), sb.build()) | 501 | Ty::Adt(box_, sb.build()) |
507 | } else { | 502 | } else { |
508 | Ty::Unknown | 503 | Ty::Unknown |
509 | } | 504 | } |
@@ -533,13 +528,11 @@ impl<'a> InferenceContext<'a> { | |||
533 | UnaryOp::Neg => { | 528 | UnaryOp::Neg => { |
534 | match &inner_ty { | 529 | match &inner_ty { |
535 | // Fast path for builtins | 530 | // Fast path for builtins |
536 | Ty::Apply(ApplicationTy { | 531 | Ty::Scalar(Scalar::Int(_)) |
537 | ctor: TypeCtor::Int(IntTy { signedness: Signedness::Signed, .. }), | 532 | | Ty::Scalar(Scalar::Uint(_)) |
538 | .. | 533 | | Ty::Scalar(Scalar::Float(_)) |
539 | }) | 534 | | Ty::InferenceVar(_, TyVariableKind::Integer) |
540 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Float(_), .. }) | 535 | | Ty::InferenceVar(_, TyVariableKind::Float) => inner_ty, |
541 | | Ty::Infer(InferTy::IntVar(..)) | ||
542 | | Ty::Infer(InferTy::FloatVar(..)) => inner_ty, | ||
543 | // Otherwise we resolve via the std::ops::Neg trait | 536 | // Otherwise we resolve via the std::ops::Neg trait |
544 | _ => self | 537 | _ => self |
545 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), | 538 | .resolve_associated_type(inner_ty, self.resolve_ops_neg_output()), |
@@ -548,9 +541,10 @@ impl<'a> InferenceContext<'a> { | |||
548 | UnaryOp::Not => { | 541 | UnaryOp::Not => { |
549 | match &inner_ty { | 542 | match &inner_ty { |
550 | // Fast path for builtins | 543 | // Fast path for builtins |
551 | Ty::Apply(ApplicationTy { ctor: TypeCtor::Bool, .. }) | 544 | Ty::Scalar(Scalar::Bool) |
552 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::Int(_), .. }) | 545 | | Ty::Scalar(Scalar::Int(_)) |
553 | | Ty::Infer(InferTy::IntVar(..)) => inner_ty, | 546 | | Ty::Scalar(Scalar::Uint(_)) |
547 | | Ty::InferenceVar(_, TyVariableKind::Integer) => inner_ty, | ||
554 | // Otherwise we resolve via the std::ops::Not trait | 548 | // Otherwise we resolve via the std::ops::Not trait |
555 | _ => self | 549 | _ => self |
556 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), | 550 | .resolve_associated_type(inner_ty, self.resolve_ops_not_output()), |
@@ -561,7 +555,7 @@ impl<'a> InferenceContext<'a> { | |||
561 | Expr::BinaryOp { lhs, rhs, op } => match op { | 555 | Expr::BinaryOp { lhs, rhs, op } => match op { |
562 | Some(op) => { | 556 | Some(op) => { |
563 | let lhs_expectation = match op { | 557 | let lhs_expectation = match op { |
564 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::simple(TypeCtor::Bool)), | 558 | BinaryOp::LogicOp(..) => Expectation::has_type(Ty::Scalar(Scalar::Bool)), |
565 | _ => Expectation::none(), | 559 | _ => Expectation::none(), |
566 | }; | 560 | }; |
567 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); | 561 | let lhs_ty = self.infer_expr(*lhs, &lhs_expectation); |
@@ -592,31 +586,31 @@ impl<'a> InferenceContext<'a> { | |||
592 | 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)); |
593 | match (range_type, lhs_ty, rhs_ty) { | 587 | match (range_type, lhs_ty, rhs_ty) { |
594 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { | 588 | (RangeOp::Exclusive, None, None) => match self.resolve_range_full() { |
595 | Some(adt) => Ty::simple(TypeCtor::Adt(adt)), | 589 | Some(adt) => Ty::Adt(adt, Substs::empty()), |
596 | None => Ty::Unknown, | 590 | None => Ty::Unknown, |
597 | }, | 591 | }, |
598 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { | 592 | (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() { |
599 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 593 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
600 | None => Ty::Unknown, | 594 | None => Ty::Unknown, |
601 | }, | 595 | }, |
602 | (RangeOp::Inclusive, None, Some(ty)) => { | 596 | (RangeOp::Inclusive, None, Some(ty)) => { |
603 | match self.resolve_range_to_inclusive() { | 597 | match self.resolve_range_to_inclusive() { |
604 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 598 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
605 | None => Ty::Unknown, | 599 | None => Ty::Unknown, |
606 | } | 600 | } |
607 | } | 601 | } |
608 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { | 602 | (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() { |
609 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 603 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
610 | None => Ty::Unknown, | 604 | None => Ty::Unknown, |
611 | }, | 605 | }, |
612 | (RangeOp::Inclusive, Some(_), Some(ty)) => { | 606 | (RangeOp::Inclusive, Some(_), Some(ty)) => { |
613 | match self.resolve_range_inclusive() { | 607 | match self.resolve_range_inclusive() { |
614 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 608 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
615 | None => Ty::Unknown, | 609 | None => Ty::Unknown, |
616 | } | 610 | } |
617 | } | 611 | } |
618 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { | 612 | (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() { |
619 | Some(adt) => Ty::apply_one(TypeCtor::Adt(adt), ty), | 613 | Some(adt) => Ty::Adt(adt, Substs::single(ty)), |
620 | None => Ty::Unknown, | 614 | None => Ty::Unknown, |
621 | }, | 615 | }, |
622 | (RangeOp::Inclusive, _, None) => Ty::Unknown, | 616 | (RangeOp::Inclusive, _, None) => Ty::Unknown, |
@@ -650,7 +644,7 @@ impl<'a> InferenceContext<'a> { | |||
650 | } | 644 | } |
651 | Expr::Tuple { exprs } => { | 645 | Expr::Tuple { exprs } => { |
652 | let mut tys = match &expected.ty { | 646 | let mut tys = match &expected.ty { |
653 | ty_app!(TypeCtor::Tuple { .. }, st) => st | 647 | Ty::Tuple(_, substs) => substs |
654 | .iter() | 648 | .iter() |
655 | .cloned() | 649 | .cloned() |
656 | .chain(repeat_with(|| self.table.new_type_var())) | 650 | .chain(repeat_with(|| self.table.new_type_var())) |
@@ -663,15 +657,11 @@ impl<'a> InferenceContext<'a> { | |||
663 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); | 657 | self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone())); |
664 | } | 658 | } |
665 | 659 | ||
666 | Ty::apply(TypeCtor::Tuple { cardinality: tys.len() as u16 }, Substs(tys.into())) | 660 | Ty::Tuple(tys.len(), Substs(tys.into())) |
667 | } | 661 | } |
668 | Expr::Array(array) => { | 662 | Expr::Array(array) => { |
669 | let elem_ty = match &expected.ty { | 663 | let elem_ty = match &expected.ty { |
670 | // FIXME: remove when https://github.com/rust-lang/rust/issues/80501 is fixed | 664 | Ty::Array(st) | Ty::Slice(st) => st.as_single().clone(), |
671 | #[allow(unreachable_patterns)] | ||
672 | ty_app!(TypeCtor::Array, st) | ty_app!(TypeCtor::Slice, st) => { | ||
673 | st.as_single().clone() | ||
674 | } | ||
675 | _ => self.table.new_type_var(), | 665 | _ => self.table.new_type_var(), |
676 | }; | 666 | }; |
677 | 667 | ||
@@ -688,30 +678,38 @@ impl<'a> InferenceContext<'a> { | |||
688 | ); | 678 | ); |
689 | self.infer_expr( | 679 | self.infer_expr( |
690 | *repeat, | 680 | *repeat, |
691 | &Expectation::has_type(Ty::simple(TypeCtor::Int(IntTy::usize()))), | 681 | &Expectation::has_type(Ty::Scalar(Scalar::Uint(UintTy::Usize))), |
692 | ); | 682 | ); |
693 | } | 683 | } |
694 | } | 684 | } |
695 | 685 | ||
696 | Ty::apply_one(TypeCtor::Array, elem_ty) | 686 | Ty::Array(Substs::single(elem_ty)) |
697 | } | 687 | } |
698 | Expr::Literal(lit) => match lit { | 688 | Expr::Literal(lit) => match lit { |
699 | Literal::Bool(..) => Ty::simple(TypeCtor::Bool), | 689 | Literal::Bool(..) => Ty::Scalar(Scalar::Bool), |
700 | Literal::String(..) => { | 690 | Literal::String(..) => Ty::Ref(Mutability::Not, Substs::single(Ty::Str)), |
701 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), Ty::simple(TypeCtor::Str)) | ||
702 | } | ||
703 | Literal::ByteString(..) => { | 691 | Literal::ByteString(..) => { |
704 | let byte_type = Ty::simple(TypeCtor::Int(IntTy::u8())); | 692 | let byte_type = Ty::Scalar(Scalar::Uint(UintTy::U8)); |
705 | let array_type = Ty::apply_one(TypeCtor::Array, byte_type); | 693 | let array_type = Ty::Array(Substs::single(byte_type)); |
706 | Ty::apply_one(TypeCtor::Ref(Mutability::Shared), array_type) | 694 | Ty::Ref(Mutability::Not, Substs::single(array_type)) |
707 | } | 695 | } |
708 | Literal::Char(..) => Ty::simple(TypeCtor::Char), | 696 | Literal::Char(..) => Ty::Scalar(Scalar::Char), |
709 | Literal::Int(_v, ty) => match ty { | 697 | Literal::Int(_v, ty) => match ty { |
710 | 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 | } | ||
711 | None => self.table.new_integer_var(), | 707 | None => self.table.new_integer_var(), |
712 | }, | 708 | }, |
713 | Literal::Float(_v, ty) => match ty { | 709 | Literal::Float(_v, ty) => match ty { |
714 | 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 | } | ||
715 | None => self.table.new_float_var(), | 713 | None => self.table.new_float_var(), |
716 | }, | 714 | }, |
717 | }, | 715 | }, |
@@ -767,7 +765,7 @@ impl<'a> InferenceContext<'a> { | |||
767 | // `!`). | 765 | // `!`). |
768 | if self.diverges.is_always() { | 766 | if self.diverges.is_always() { |
769 | // we don't even make an attempt at coercion | 767 | // we don't even make an attempt at coercion |
770 | self.table.new_maybe_never_type_var() | 768 | self.table.new_maybe_never_var() |
771 | } else { | 769 | } else { |
772 | self.coerce(&Ty::unit(), expected.coercion_target()); | 770 | self.coerce(&Ty::unit(), expected.coercion_target()); |
773 | Ty::unit() | 771 | Ty::unit() |
@@ -824,7 +822,7 @@ impl<'a> InferenceContext<'a> { | |||
824 | // Apply autoref so the below unification works correctly | 822 | // Apply autoref so the below unification works correctly |
825 | // FIXME: return correct autorefs from lookup_method | 823 | // FIXME: return correct autorefs from lookup_method |
826 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { | 824 | let actual_receiver_ty = match expected_receiver_ty.as_reference() { |
827 | Some((_, mutability)) => Ty::apply_one(TypeCtor::Ref(mutability), derefed_receiver_ty), | 825 | Some((_, mutability)) => Ty::Ref(mutability, Substs::single(derefed_receiver_ty)), |
828 | _ => derefed_receiver_ty, | 826 | _ => derefed_receiver_ty, |
829 | }; | 827 | }; |
830 | self.unify(&expected_receiver_ty, &actual_receiver_ty); | 828 | self.unify(&expected_receiver_ty, &actual_receiver_ty); |
@@ -901,30 +899,26 @@ impl<'a> InferenceContext<'a> { | |||
901 | } | 899 | } |
902 | 900 | ||
903 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 901 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
904 | if let Ty::Apply(a_ty) = callable_ty { | 902 | if let &Ty::FnDef(def, ref parameters) = callable_ty { |
905 | if let TypeCtor::FnDef(def) = a_ty.ctor { | 903 | let generic_predicates = self.db.generic_predicates(def.into()); |
906 | let generic_predicates = self.db.generic_predicates(def.into()); | 904 | for predicate in generic_predicates.iter() { |
907 | for predicate in generic_predicates.iter() { | 905 | let predicate = predicate.clone().subst(parameters); |
908 | let predicate = predicate.clone().subst(&a_ty.parameters); | 906 | if let Some(obligation) = Obligation::from_predicate(predicate) { |
909 | if let Some(obligation) = Obligation::from_predicate(predicate) { | 907 | self.obligations.push(obligation); |
910 | self.obligations.push(obligation); | ||
911 | } | ||
912 | } | 908 | } |
913 | // add obligation for trait implementation, if this is a trait method | 909 | } |
914 | match def { | 910 | // add obligation for trait implementation, if this is a trait method |
915 | CallableDefId::FunctionId(f) => { | 911 | match def { |
916 | if let AssocContainerId::TraitId(trait_) = | 912 | CallableDefId::FunctionId(f) => { |
917 | f.lookup(self.db.upcast()).container | 913 | if let AssocContainerId::TraitId(trait_) = f.lookup(self.db.upcast()).container |
918 | { | 914 | { |
919 | // construct a TraitDef | 915 | // construct a TraitDef |
920 | let substs = a_ty | 916 | let substs = |
921 | .parameters | 917 | parameters.prefix(generics(self.db.upcast(), trait_.into()).len()); |
922 | .prefix(generics(self.db.upcast(), trait_.into()).len()); | 918 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
923 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); | ||
924 | } | ||
925 | } | 919 | } |
926 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
927 | } | 920 | } |
921 | CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {} | ||
928 | } | 922 | } |
929 | } | 923 | } |
930 | } | 924 | } |