1use std::{iter::repeat_with, mem};
4
5use either::Either;
6use hir_def::{
7 AdtId, FieldId, TupleFieldId, TupleId, VariantId,
8 expr_store::path::{GenericArgs as HirGenericArgs, Path},
9 hir::{
10 Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId,
11 ExprOrPatIdPacked, InlineAsmKind, LabelId, LoopSource, Pat, PatId, RecordLitField,
12 RecordSpread, Statement, UnaryOp,
13 },
14 resolver::ValueNs,
15 signatures::VariantFields,
16};
17use hir_def::{FunctionId, hir::ClosureKind};
18use hir_expand::name::Name;
19use rustc_ast_ir::Mutability;
20use rustc_hash::FxHashMap;
21use rustc_type_ir::{
22 InferTy, Interner,
23 inherent::{GenericArgs as _, IntoKind, Ty as _},
24};
25use stdx::never;
26use syntax::ast::RangeOp;
27use tracing::debug;
28
29use crate::{
30 Adjust, Adjustment, CallableDefId, Rawness, Span,
31 consteval::literal_ty,
32 infer::{AllowTwoPhase, BreakableKind, coerce::CoerceMany, find_continuable, pat::PatOrigin},
33 lower::lower_mutability,
34 method_resolution::{self, CandidateId, MethodCallee, MethodError},
35 next_solver::{
36 ClauseKind, FnSig, GenericArg, GenericArgs, Ty, TyKind, TypeError,
37 infer::{
38 BoundRegionConversionTime, InferOk,
39 traits::{Obligation, ObligationCause},
40 },
41 obligation_ctxt::ObligationCtxt,
42 },
43};
44
45use super::{
46 BreakableContext, Diverges, Expectation, InferenceContext, InferenceDiagnostic, ReturnKind,
47 cast::CastCheck, find_breakable,
48};
49
50#[derive(Clone, Copy, PartialEq, Eq)]
51pub(crate) enum ExprIsRead {
52 Yes,
53 No,
54}
55
56impl<'db> InferenceContext<'db> {
57 pub(crate) fn infer_expr(
58 &mut self,
59 tgt_expr: ExprId,
60 expected: &Expectation<'db>,
61 is_read: ExprIsRead,
62 ) -> Ty<'db> {
63 let ty = self.infer_expr_inner(tgt_expr, expected, is_read);
64 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
65 _ = self.demand_eqtype(tgt_expr.into(), expected_ty, ty);
66 }
67 ty
68 }
69
70 pub(crate) fn infer_expr_suptype_coerce_never(
71 &mut self,
72 expr: ExprId,
73 expected: &Expectation<'db>,
74 is_read: ExprIsRead,
75 ) -> Ty<'db> {
76 let ty = self.infer_expr_inner(expr, expected, is_read);
77 if ty.is_never() {
78 if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
79 return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
80 target.as_ref()
81 } else {
82 self.err_ty()
83 };
84 }
85
86 if let Some(target) = expected.only_has_type(&mut self.table) {
87 self.coerce(expr, ty, target, AllowTwoPhase::No, ExprIsRead::Yes)
88 .expect("never-to-any coercion should always succeed")
89 } else {
90 ty
91 }
92 } else {
93 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
94 _ = self.demand_suptype(expr.into(), expected_ty, ty);
95 }
96 ty
97 }
98 }
99
100 pub(crate) fn infer_expr_no_expect(
101 &mut self,
102 tgt_expr: ExprId,
103 is_read: ExprIsRead,
104 ) -> Ty<'db> {
105 self.infer_expr_inner(tgt_expr, &Expectation::None, is_read)
106 }
107
108 pub(super) fn infer_expr_coerce(
111 &mut self,
112 expr: ExprId,
113 expected: &Expectation<'db>,
114 is_read: ExprIsRead,
115 ) -> Ty<'db> {
116 let ty = self.infer_expr_inner(expr, expected, is_read);
117 if let Some(target) = expected.only_has_type(&mut self.table) {
118 match self.coerce(expr, ty, target, AllowTwoPhase::No, is_read) {
119 Ok(res) => res,
120 Err(_) => {
121 self.emit_type_mismatch(expr.into(), target, ty);
122 target
123 }
124 }
125 } else {
126 ty
127 }
128 }
129
130 pub(super) fn expr_guaranteed_to_constitute_read_for_never(
142 &mut self,
143 expr: ExprId,
144 is_read: ExprIsRead,
145 ) -> bool {
146 is_read == ExprIsRead::Yes
156 || !self.is_syntactic_place_expr(expr)
162 }
163
164 fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
168 match &self.store[pat] {
169 Pat::Wild | Pat::Rest => false,
171
172 Pat::Or(subpats) => {
181 subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(*pat))
182 }
183
184 Pat::Bind { .. }
187 | Pat::TupleStruct { .. }
188 | Pat::Path(_)
189 | Pat::Tuple { .. }
190 | Pat::Box { .. }
191 | Pat::Deref { .. }
192 | Pat::Ref { .. }
193 | Pat::Lit(_)
194 | Pat::Range { .. }
195 | Pat::Slice { .. }
196 | Pat::ConstBlock(_)
197 | Pat::Record { .. }
198 | Pat::NotNull
199 | Pat::Missing => true,
200 Pat::Expr(_) => unreachable!(
201 "we don't call pat_guaranteed_to_constitute_read_for_never() with assignments"
202 ),
203 }
204 }
205
206 fn contains_explicit_ref_binding(&self, pat: PatId) -> bool {
212 if let Pat::Bind { id, .. } = self.store[pat]
213 && matches!(self.store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
214 {
215 return true;
216 }
217
218 let mut result = false;
219 self.store.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
220 result
221 }
222
223 fn is_syntactic_place_expr(&self, expr: ExprId) -> bool {
224 match &self.store[expr] {
225 Expr::Path(Path::LangItem(_, _)) => false,
227 Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(),
228 Expr::Path(path) => self
229 .resolver
230 .resolve_path_in_value_ns_fully(self.db, path, self.store.expr_path_hygiene(expr))
231 .is_none_or(|res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))),
232 Expr::Underscore => true,
233 Expr::UnaryOp { op: UnaryOp::Deref, .. } => true,
234 Expr::Field { .. } | Expr::Index { .. } => true,
235 Expr::Call { .. }
236 | Expr::MethodCall { .. }
237 | Expr::Tuple { .. }
238 | Expr::If { .. }
239 | Expr::Match { .. }
240 | Expr::Closure { .. }
241 | Expr::Block { .. }
242 | Expr::Array(..)
243 | Expr::Break { .. }
244 | Expr::Continue { .. }
245 | Expr::Return { .. }
246 | Expr::Become { .. }
247 | Expr::Let { .. }
248 | Expr::Loop { .. }
249 | Expr::InlineAsm(..)
250 | Expr::OffsetOf(..)
251 | Expr::Literal(..)
252 | Expr::Const(..)
253 | Expr::UnaryOp { .. }
254 | Expr::BinaryOp { .. }
255 | Expr::Assignment { .. }
256 | Expr::Yield { .. }
257 | Expr::Cast { .. }
258 | Expr::Unsafe { .. }
259 | Expr::Await { .. }
260 | Expr::Ref { .. }
261 | Expr::Range { .. }
262 | Expr::Box { .. }
263 | Expr::RecordLit { .. }
264 | Expr::Yeet { .. }
265 | Expr::Missing
266 | Expr::IncludeBytes => false,
267 }
268 }
269
270 pub(crate) fn check_lhs_assignable(&self, lhs: ExprId) {
271 if self.is_syntactic_place_expr(lhs) {
272 return;
273 }
274
275 self.push_diagnostic(InferenceDiagnostic::InvalidLhsOfAssignment { lhs });
276 }
277
278 fn infer_expr_coerce_never(
279 &mut self,
280 expr: ExprId,
281 expected: &Expectation<'db>,
282 is_read: ExprIsRead,
283 ) -> Ty<'db> {
284 let ty = self.infer_expr_inner(expr, expected, is_read);
285 if ty.is_never() {
288 if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
289 return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
290 target.as_ref()
291 } else {
292 self.err_ty()
293 };
294 }
295
296 if let Some(target) = expected.only_has_type(&mut self.table) {
297 self.coerce(expr, ty, target, AllowTwoPhase::No, ExprIsRead::Yes)
298 .expect("never-to-any coercion should always succeed")
299 } else {
300 ty
301 }
302 } else {
303 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
304 _ = self.demand_eqtype(expr.into(), expected_ty, ty);
305 }
306 ty
307 }
308 }
309
310 #[tracing::instrument(level = "debug", skip(self, is_read), ret)]
311 pub(super) fn infer_expr_inner(
312 &mut self,
313 tgt_expr: ExprId,
314 expected: &Expectation<'db>,
315 is_read: ExprIsRead,
316 ) -> Ty<'db> {
317 self.db.unwind_if_revision_cancelled();
318
319 let expr = &self.store[tgt_expr];
320 tracing::trace!(?expr);
321 let ty = match expr {
322 Expr::Missing => self.err_ty(),
323 &Expr::If { condition, then_branch, else_branch } => {
324 let expected = &expected.adjust_for_branches(&mut self.table, tgt_expr.into());
325 self.infer_expr_coerce_never(
326 condition,
327 &Expectation::HasType(self.types.types.bool),
328 ExprIsRead::Yes,
329 );
330
331 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
332
333 let then_ty = self.infer_expr_inner(then_branch, expected, ExprIsRead::Yes);
334 let then_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
335 let mut coercion_sites = [then_branch, tgt_expr];
336 if let Some(else_branch) = else_branch {
337 coercion_sites[1] = else_branch;
338 }
339 let mut coerce = CoerceMany::with_coercion_sites(
340 expected.coercion_target_type(&mut self.table, then_branch.into()),
341 &coercion_sites,
342 );
343 coerce.coerce(
344 self,
345 &ObligationCause::new(then_branch),
346 then_branch,
347 then_ty,
348 ExprIsRead::Yes,
349 );
350 match else_branch {
351 Some(else_branch) => {
352 let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes);
353 let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
354 coerce.coerce(
355 self,
356 &ObligationCause::new(else_branch),
357 else_branch,
358 else_ty,
359 ExprIsRead::Yes,
360 );
361 self.diverges = condition_diverges | then_diverges & else_diverges;
362 }
363 None => {
364 coerce.coerce_forced_unit(
365 self,
366 tgt_expr,
367 &ObligationCause::new(tgt_expr),
368 true,
369 ExprIsRead::Yes,
370 );
371 self.diverges = condition_diverges;
372 }
373 }
374
375 coerce.complete(self)
376 }
377 &Expr::Let { pat, expr } => {
378 let child_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) {
379 ExprIsRead::Yes
380 } else {
381 ExprIsRead::No
382 };
383 let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
384 self.infer_top_pat(pat, input_ty, PatOrigin::LetExpr);
385 self.types.types.bool
386 }
387 Expr::Block { statements, tail, label, id: _ } => {
388 self.infer_block(tgt_expr, statements, *tail, *label, expected)
389 }
390 Expr::Unsafe { id: _, statements, tail } => {
391 self.infer_block(tgt_expr, statements, *tail, None, expected)
392 }
393 Expr::Const(id) => {
394 self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
395 this.infer_expr(*id, expected, ExprIsRead::Yes)
396 })
397 .1
398 }
399 &Expr::Loop { body, label, source } => {
400 let coerce = match source {
401 LoopSource::Loop => {
403 Some(expected.coercion_target_type(&mut self.table, body.into()))
404 }
405 LoopSource::While | LoopSource::ForLoop => None,
406 };
407 let (breaks, ()) =
408 self.with_breakable_ctx(BreakableKind::Loop, coerce, label, |this| {
409 this.infer_expr_suptype_coerce_never(
410 body,
411 &Expectation::HasType(this.types.types.unit),
412 ExprIsRead::Yes,
413 );
414 });
415
416 if breaks.may_break {
417 self.diverges = Diverges::Maybe;
418 } else {
419 self.diverges = Diverges::Always;
420 }
421 breaks.coerce.map(|c| c.complete(self)).unwrap_or(self.types.types.unit)
422 }
423 Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
424 .infer_closure(
425 *body,
426 args,
427 *ret_type,
428 arg_types,
429 *closure_kind,
430 tgt_expr,
431 expected,
432 ),
433 Expr::Call { callee, args, .. } => self.infer_call(tgt_expr, *callee, args, expected),
434 Expr::MethodCall { receiver, args, method_name, generic_args } => self
435 .infer_method_call(
436 tgt_expr,
437 *receiver,
438 args,
439 method_name,
440 generic_args.as_deref(),
441 expected,
442 ),
443 Expr::Match { expr, arms } => {
444 let mut scrutinee_is_read = true;
445 let mut contains_ref_bindings = false;
446 for arm in arms {
447 scrutinee_is_read &= self.pat_guaranteed_to_constitute_read_for_never(arm.pat);
448 contains_ref_bindings |= self.contains_explicit_ref_binding(arm.pat);
449 }
450 let scrutinee_is_read =
451 if scrutinee_is_read { ExprIsRead::Yes } else { ExprIsRead::No };
452 let input_ty = self.demand_scrutinee_type(
453 *expr,
454 contains_ref_bindings,
455 arms.is_empty(),
456 scrutinee_is_read,
457 );
458
459 if arms.is_empty() {
460 self.diverges = Diverges::Always;
461 self.types.types.never
462 } else {
463 let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
464 let mut all_arms_diverge = Diverges::Always;
465 for arm in arms.iter() {
466 self.infer_top_pat(arm.pat, input_ty, PatOrigin::MatchArm);
467 }
468
469 let expected = expected.adjust_for_branches(&mut self.table, tgt_expr.into());
470 let result_ty = match &expected {
471 Expectation::HasType(ty) if *ty != self.types.types.unit => *ty,
474 _ => self.table.next_ty_var((*expr).into()),
475 };
476 let mut coerce = CoerceMany::new(result_ty);
477
478 for arm in arms.iter() {
479 if let Some(guard_expr) = arm.guard {
480 self.diverges = Diverges::Maybe;
481 self.infer_expr_coerce_never(
482 guard_expr,
483 &Expectation::HasType(self.types.types.bool),
484 ExprIsRead::Yes,
485 );
486 }
487 self.diverges = Diverges::Maybe;
488
489 let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes);
490 all_arms_diverge &= self.diverges;
491 coerce.coerce(
492 self,
493 &ObligationCause::new(arm.expr),
494 arm.expr,
495 arm_ty,
496 ExprIsRead::Yes,
497 );
498 }
499
500 self.diverges = matchee_diverges | all_arms_diverge;
501
502 coerce.complete(self)
503 }
504 }
505 Expr::Path(p) => self.infer_expr_path(p, tgt_expr.into(), tgt_expr),
506 &Expr::Continue { label } => {
507 if find_continuable(&mut self.breakables, label).is_none() {
508 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
509 expr: tgt_expr,
510 is_break: false,
511 bad_value_break: false,
512 });
513 };
514 self.types.types.never
515 }
516 &Expr::Break { expr, label } => {
517 let val_ty = if let Some(expr) = expr {
518 let opt_coerce_to = match find_breakable(&mut self.breakables, label) {
519 Some(ctxt) => match &ctxt.coerce {
520 Some(coerce) => coerce.expected_ty(),
521 None => {
522 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
523 expr: tgt_expr,
524 is_break: true,
525 bad_value_break: true,
526 });
527 self.err_ty()
528 }
529 },
530 None => self.err_ty(),
531 };
532 self.infer_expr_inner(
533 expr,
534 &Expectation::HasType(opt_coerce_to),
535 ExprIsRead::Yes,
536 )
537 } else {
538 self.types.types.unit
539 };
540
541 match find_breakable(&mut self.breakables, label) {
542 Some(ctxt) => match ctxt.coerce.take() {
543 Some(mut coerce) => {
544 let expr = expr.unwrap_or(tgt_expr);
545 coerce.coerce(
546 self,
547 &ObligationCause::new(expr),
548 expr,
549 val_ty,
550 ExprIsRead::Yes,
551 );
552
553 let ctxt = find_breakable(&mut self.breakables, label)
555 .expect("breakable stack changed during coercion");
556 ctxt.may_break = true;
557 ctxt.coerce = Some(coerce);
558 }
559 None => ctxt.may_break = true,
560 },
561 None => {
562 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
563 expr: tgt_expr,
564 is_break: true,
565 bad_value_break: false,
566 });
567 }
568 }
569 self.types.types.never
570 }
571 &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr),
572 &Expr::Become { expr } => self.infer_expr_become(tgt_expr, expr),
573 Expr::Yield { expr } => {
574 if let Some((resume_ty, yield_ty)) = self.resume_yield_tys {
575 if let Some(expr) = expr {
576 self.infer_expr_coerce(
577 *expr,
578 &Expectation::has_type(yield_ty),
579 ExprIsRead::Yes,
580 );
581 } else {
582 let unit = self.types.types.unit;
583 let _ = self.coerce(
584 tgt_expr,
585 unit,
586 yield_ty,
587 AllowTwoPhase::No,
588 ExprIsRead::Yes,
589 );
590 }
591 resume_ty
592 } else {
593 self.push_diagnostic(InferenceDiagnostic::YieldOutsideCoroutine {
594 expr: tgt_expr,
595 });
596 self.types.types.error
597 }
598 }
599 Expr::Yeet { expr } => {
600 if let &Some(expr) = expr {
601 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
602 }
603 self.types.types.never
604 }
605 Expr::RecordLit { path, fields, spread, .. } => {
606 self.infer_record_expr(tgt_expr, expected, path, fields, *spread)
607 }
608 Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected),
609 Expr::Await { expr } => self.infer_await_expr(tgt_expr, *expr),
610 Expr::Cast { expr, type_ref } => {
611 let cast_ty = self.make_body_ty(*type_ref);
612 let expr_ty =
613 self.infer_expr(*expr, &Expectation::Castable(cast_ty), ExprIsRead::Yes);
614 self.deferred_cast_checks.push(CastCheck::new(tgt_expr, *expr, expr_ty, cast_ty));
615 cast_ty
616 }
617 Expr::Ref { expr, rawness, mutability } => self.infer_ref_expr(
618 *rawness,
619 lower_mutability(*mutability),
620 *expr,
621 expected,
622 tgt_expr,
623 ),
624 &Expr::Box { expr } => self.infer_expr_box(expr, expected),
625 Expr::UnaryOp { expr, op } => self.infer_unop_expr(*op, *expr, expected, tgt_expr),
626 Expr::BinaryOp { lhs, rhs, op } => match op {
627 Some(BinaryOp::Assignment { op: Some(op) }) => {
628 self.infer_assign_op_expr(tgt_expr, *op, *lhs, *rhs)
629 }
630 Some(op) => self.infer_binop_expr(tgt_expr, *op, *lhs, *rhs),
631 None => self.err_ty(),
632 },
633 &Expr::Assignment { target, value } => {
634 let lhs_ty = match &self.store[target] {
640 &Pat::Expr(expr) => {
642 Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No))
643 }
644 _ => None,
645 };
646 let is_destructuring_assignment = lhs_ty.is_none();
647
648 if let Some(lhs_ty) = lhs_ty {
649 self.write_pat_ty(target, lhs_ty);
650 self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::Yes);
651 } else {
652 let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
653 let resolver_guard =
654 self.resolver.update_to_inner_scope(self.db, self.store_owner, tgt_expr);
655 self.inside_assignment = true;
656 self.infer_top_pat(target, rhs_ty, PatOrigin::DestructuringAssignment);
657 self.inside_assignment = false;
658 self.resolver.reset_to_guard(resolver_guard);
659 }
660 if is_destructuring_assignment && self.diverges.is_always() {
661 self.table.new_maybe_never_var(value.into())
666 } else {
667 self.types.types.unit
668 }
669 }
670 Expr::Range { lhs, rhs, range_type } => {
671 let lhs_ty =
672 lhs.map(|e| self.infer_expr_inner(e, &Expectation::none(), ExprIsRead::Yes));
673 let rhs_expect = lhs_ty.map_or_else(Expectation::none, Expectation::has_type);
674 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect, ExprIsRead::Yes));
675 let single_arg_adt = |adt, ty: Ty<'db>| {
676 Ty::new_adt(
677 self.interner(),
678 adt,
679 GenericArgs::new_from_slice(&[GenericArg::from(ty)]),
680 )
681 };
682 match (range_type, lhs_ty, rhs_ty) {
683 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
684 Some(adt) => {
685 Ty::new_adt(self.interner(), adt, self.types.empty.generic_args)
686 }
687 None => self.err_ty(),
688 },
689 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
690 Some(adt) => single_arg_adt(adt, ty),
691 None => self.err_ty(),
692 },
693 (RangeOp::Inclusive, None, Some(ty)) => {
694 match self.resolve_range_to_inclusive() {
695 Some(adt) => single_arg_adt(adt, ty),
696 None => self.err_ty(),
697 }
698 }
699 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
700 Some(adt) => single_arg_adt(adt, ty),
701 None => self.err_ty(),
702 },
703 (RangeOp::Inclusive, Some(_), Some(ty)) => {
704 match self.resolve_range_inclusive() {
705 Some(adt) => single_arg_adt(adt, ty),
706 None => self.err_ty(),
707 }
708 }
709 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
710 Some(adt) => single_arg_adt(adt, ty),
711 None => self.err_ty(),
712 },
713 (RangeOp::Inclusive, _, None) => self.err_ty(),
714 }
715 }
716 Expr::Index { base, index } => {
717 let base_t = self.infer_expr_no_expect(*base, ExprIsRead::Yes);
718 let idx_t = self.infer_expr_no_expect(*index, ExprIsRead::Yes);
719
720 let base_t = self.structurally_resolve_type((*base).into(), base_t);
721 match self.lookup_indexing(tgt_expr, *base, *index, base_t, idx_t) {
722 Some((trait_index_ty, trait_element_ty)) => {
723 self.demand_coerce(
725 *index,
726 idx_t,
727 trait_index_ty,
728 AllowTwoPhase::No,
729 ExprIsRead::Yes,
730 );
731 self.table.select_obligations_where_possible();
732 trait_element_ty
733 }
734 None => {
735 self.push_diagnostic(InferenceDiagnostic::CannotIndexInto {
736 expr: tgt_expr,
737 found: base_t.store(),
738 });
739 self.types.types.error
740 }
741 }
742 }
743 Expr::Tuple { exprs, .. } => {
744 let mut tys = match expected
745 .only_has_type(&mut self.table)
746 .map(|t| self.table.try_structurally_resolve_type(tgt_expr.into(), t).kind())
747 {
748 Some(TyKind::Tuple(substs)) => substs
749 .iter()
750 .chain(repeat_with(|| self.table.next_ty_var(Span::Dummy)))
751 .take(exprs.len())
752 .collect::<Vec<_>>(),
753 _ => exprs.iter().map(|&expr| self.table.next_ty_var(expr.into())).collect(),
754 };
755
756 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
757 *ty =
758 self.infer_expr_coerce(*expr, &Expectation::has_type(*ty), ExprIsRead::Yes);
759 }
760
761 Ty::new_tup(self.interner(), &tys)
762 }
763 Expr::Array(Array::ElementList { elements }) => {
764 self.infer_array_elements_expr(elements, expected, tgt_expr)
765 }
766 Expr::Array(Array::Repeat { initializer, repeat }) => {
767 self.infer_array_repeat_expr(*initializer, *repeat, expected, tgt_expr)
768 }
769 Expr::Literal(lit) => literal_ty(
770 self.interner(),
771 lit,
772 |_| {
773 let expected_ty = expected.to_option(&self.table);
774 tracing::debug!(?expected_ty);
775 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
776 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
777 Some(TyKind::Char) => Some(self.types.types.u8),
778 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
779 Some(self.types.types.usize)
780 }
781 _ => None,
782 };
783 opt_ty.unwrap_or_else(|| self.table.next_int_var())
784 },
785 |_| {
786 let expected_ty = expected.to_option(&self.table);
787 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
788 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
789 Some(TyKind::Char) => Some(self.types.types.u8),
790 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
791 Some(self.types.types.usize)
792 }
793 _ => None,
794 };
795 opt_ty.unwrap_or_else(|| self.table.next_int_var())
796 },
797 |_| {
798 let opt_ty = expected
799 .to_option(&self.table)
800 .filter(|ty| matches!(ty.kind(), TyKind::Float(_)));
801 opt_ty.unwrap_or_else(|| self.table.next_float_var())
802 },
803 ),
804 Expr::Underscore => {
805 let expected = expected.to_option(&self.table).unwrap_or_else(|| self.err_ty());
808 self.push_diagnostic(InferenceDiagnostic::TypedHole {
809 expr: tgt_expr,
810 expected: expected.store(),
811 });
812 expected
813 }
814 Expr::OffsetOf(_) => self.types.types.usize,
815 Expr::InlineAsm(asm) => {
816 let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| {
817 let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes);
818
819 if is_input {
827 let ty = this.structurally_resolve_type(expr.into(), ty);
828 match ty.kind() {
829 TyKind::FnDef(def, parameters) => {
830 let fnptr_ty = Ty::new_fn_ptr(
831 this.interner(),
832 this.interner()
833 .fn_sig(def)
834 .instantiate(this.interner(), parameters)
835 .skip_norm_wip(),
836 );
837 _ = this.coerce(
838 expr,
839 ty,
840 fnptr_ty,
841 AllowTwoPhase::No,
842 ExprIsRead::Yes,
843 );
844 }
845 TyKind::Ref(_, base_ty, mutbl) => {
846 let ptr_ty = Ty::new_ptr(this.interner(), base_ty, mutbl);
847 _ = this.coerce(
848 expr,
849 ty,
850 ptr_ty,
851 AllowTwoPhase::No,
852 ExprIsRead::Yes,
853 );
854 }
855 _ => {}
856 }
857 }
858 };
859
860 let diverge = asm.options.contains(AsmOptions::NORETURN);
861 asm.operands.iter().for_each(|(_, operand)| match *operand {
862 AsmOperand::In { expr, .. } => check_expr_asm_operand(self, expr, true),
863 AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
864 check_expr_asm_operand(self, expr, false)
865 }
866 AsmOperand::Out { expr: None, .. } => (),
867 AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
868 check_expr_asm_operand(self, in_expr, true);
869 if let Some(out_expr) = out_expr {
870 check_expr_asm_operand(self, out_expr, false);
871 }
872 }
873 AsmOperand::Label(expr) => {
874 self.infer_expr(
875 expr,
876 &Expectation::HasType(self.types.types.unit),
877 ExprIsRead::No,
878 );
879 }
880 AsmOperand::Const(expr) => {
881 self.infer_expr(expr, &Expectation::None, ExprIsRead::No);
882 }
883 AsmOperand::Sym(_) => (),
885 });
886 if diverge || asm.kind == InlineAsmKind::NakedAsm {
887 self.types.types.never
888 } else {
889 self.types.types.unit
890 }
891 }
892 Expr::IncludeBytes => {
893 let len = self.table.next_const_var(Span::Dummy);
894 let arr = Ty::new_array_with_const_len(self.interner(), self.types.types.u8, len);
895 Ty::new_ref(self.interner(), self.types.regions.statik, arr, Mutability::Not)
896 }
897 };
898 let ty = self.insert_type_vars_shallow(ty);
899 self.write_expr_ty(tgt_expr, ty);
900 if self.table.resolve_vars_with_obligations(ty).is_never()
901 && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read)
902 {
903 self.diverges = Diverges::Always;
905 }
906 ty
907 }
908
909 fn infer_ref_expr(
910 &mut self,
911 rawness: Rawness,
912 mutbl: Mutability,
913 oprnd: ExprId,
914 expected: &Expectation<'db>,
915 expr: ExprId,
916 ) -> Ty<'db> {
917 let hint = expected.only_has_type(&mut self.table).map_or(Expectation::None, |ty| {
918 match self.table.resolve_vars_with_obligations(ty).kind() {
919 TyKind::Ref(_, ty, _) | TyKind::RawPtr(ty, _) => {
920 if self.is_syntactic_place_expr(oprnd) {
921 Expectation::has_type(ty)
925 } else {
926 Expectation::rvalue_hint(self, ty)
927 }
928 }
929 _ => Expectation::None,
930 }
931 });
932 let ty = self.infer_expr_inner(oprnd, &hint, ExprIsRead::No);
933
934 match rawness {
935 Rawness::RawPtr => Ty::new_ptr(self.interner(), ty, mutbl),
936 Rawness::Ref => {
937 let region = self.table.next_region_var(expr.into());
952 Ty::new_ref(self.interner(), region, ty, mutbl)
953 }
954 }
955 }
956
957 fn infer_await_expr(&mut self, expr: ExprId, awaitee: ExprId) -> Ty<'db> {
958 let awaitee_ty = self.infer_expr_no_expect(awaitee, ExprIsRead::Yes);
959 let (Some(into_future), Some(into_future_output)) =
960 (self.lang_items.IntoFuture, self.lang_items.IntoFutureOutput)
961 else {
962 return self.types.types.error;
963 };
964 self.table.register_bound(awaitee_ty, into_future, ObligationCause::new(expr));
965 self.table.try_structurally_resolve_type(
966 expr.into(),
967 Ty::new_projection(self.interner(), into_future_output.into(), [awaitee_ty]),
968 )
969 }
970
971 fn infer_record_expr(
972 &mut self,
973 expr: ExprId,
974 expected: &Expectation<'db>,
975 path: &Path,
976 fields: &[RecordLitField],
977 base_expr: RecordSpread,
978 ) -> Ty<'db> {
979 let (adt_ty, Some(variant)) = self.resolve_variant(expr.into(), path, false) else {
981 for field in fields {
983 self.infer_expr_no_expect(field.expr, ExprIsRead::Yes);
984 }
985
986 return self.types.types.error;
987 };
988 self.write_variant_resolution(expr.into(), variant);
989
990 if self.has_applicable_non_exhaustive(variant.into()) {
992 self.push_diagnostic(InferenceDiagnostic::NonExhaustiveRecordExpr { expr });
993 }
994
995 self.check_record_expr_fields(adt_ty, expected, expr, variant, fields, base_expr);
996
997 self.require_type_is_sized(adt_ty, expr.into());
998 adt_ty
999 }
1000
1001 fn check_record_expr_fields(
1002 &mut self,
1003 adt_ty: Ty<'db>,
1004 expected: &Expectation<'db>,
1005 expr: ExprId,
1006 variant: VariantId,
1007 hir_fields: &[RecordLitField],
1008 base_expr: RecordSpread,
1009 ) {
1010 let interner = self.interner();
1011
1012 let adt_ty = self.table.try_structurally_resolve_type(expr.into(), adt_ty);
1013 let adt_ty_hint = expected.only_has_type(&mut self.table).and_then(|expected| {
1014 self.infcx()
1015 .fudge_inference_if_ok(|| {
1016 let mut ocx = ObligationCtxt::new(self.infcx());
1017 ocx.sup(&ObligationCause::new(expr), self.table.param_env, expected, adt_ty)?;
1018 if !ocx.try_evaluate_obligations().is_empty() {
1019 return Err(TypeError::Mismatch);
1020 }
1021 Ok(self.resolve_vars_if_possible(adt_ty))
1022 })
1023 .ok()
1024 });
1025 if let Some(adt_ty_hint) = adt_ty_hint {
1026 _ = self.demand_eqtype(expr.into(), adt_ty_hint, adt_ty);
1028 }
1029
1030 let TyKind::Adt(adt, args) = adt_ty.kind() else {
1031 never!("non-ADT passed to check_struct_expr_fields");
1032 return;
1033 };
1034 let adt_id = adt.def_id();
1035
1036 let variant_fields = variant.fields(self.db);
1037 let variant_field_tys = self.db.field_types(variant);
1038 let variant_field_vis = VariantFields::field_visibilities(self.db, variant);
1039 let mut remaining_fields = variant_fields
1040 .fields()
1041 .iter()
1042 .map(|(i, field)| (field.name.clone(), i))
1043 .collect::<FxHashMap<_, _>>();
1044
1045 let mut seen_fields = FxHashMap::default();
1046
1047 for field in hir_fields {
1049 let name = &field.name;
1050 let field_type = if let Some(i) = remaining_fields.remove(name) {
1051 seen_fields.insert(name, i);
1052
1053 if !self.resolver.is_visible(self.db, variant_field_vis[i]) {
1054 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
1055 field: field.expr.into(),
1056 private: Some(i),
1057 variant,
1058 });
1059 }
1060
1061 variant_field_tys[i].ty().instantiate(interner, args).skip_norm_wip()
1062 } else {
1063 if let Some(field_idx) = seen_fields.get(&name) {
1064 self.push_diagnostic(InferenceDiagnostic::DuplicateField {
1065 field: field.expr.into(),
1066 variant,
1067 });
1068 variant_field_tys[*field_idx].ty().instantiate(interner, args).skip_norm_wip()
1069 } else {
1070 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
1071 field: field.expr.into(),
1072 private: None,
1073 variant,
1074 });
1075 self.types.types.error
1076 }
1077 };
1078
1079 self.table.register_wf_obligation(field_type.into(), ObligationCause::new(field.expr));
1083
1084 self.infer_expr_coerce(field.expr, &Expectation::has_type(field_type), ExprIsRead::Yes);
1087 }
1088
1089 if matches!(adt_id, AdtId::UnionId(_)) && hir_fields.len() != 1 {
1091 self.push_diagnostic(InferenceDiagnostic::UnionExprMustHaveExactlyOneField { expr });
1092 }
1093
1094 match base_expr {
1095 RecordSpread::FieldDefaults => {
1096 let mut missing_mandatory_fields = Vec::new();
1097 let mut missing_optional_fields = Vec::new();
1098 for (field_idx, field) in variant_fields.fields().iter() {
1099 if remaining_fields.remove(&field.name).is_some() {
1100 if field.default_value.is_none() {
1101 missing_mandatory_fields.push(field_idx);
1102 } else {
1103 missing_optional_fields.push(field_idx);
1104 }
1105 }
1106 }
1107 if !missing_mandatory_fields.is_empty() {
1108 }
1110 }
1111 RecordSpread::Expr(base_expr) => {
1112 if self.features.type_changing_struct_update {
1115 if matches!(adt_id, AdtId::StructId(_)) {
1116 let fresh_args = self.table.fresh_args_for_item(expr.into(), adt_id.into());
1118 for (field_idx, field) in variant_fields.fields().iter() {
1123 let fru_ty = variant_field_tys[field_idx]
1124 .ty()
1125 .instantiate(interner, fresh_args)
1126 .skip_norm_wip();
1127 if remaining_fields.remove(&field.name).is_some() {
1128 let target_ty = variant_field_tys[field_idx]
1129 .ty()
1130 .instantiate(interner, args)
1131 .skip_norm_wip();
1132 let cause = ObligationCause::new(expr);
1133 match self.table.at(&cause).sup(target_ty, fru_ty) {
1134 Ok(InferOk { obligations, value: () }) => {
1135 self.table.register_predicates(obligations)
1136 }
1137 Err(_) => {
1138 never!(
1139 "subtyping remaining fields of type changing FRU \
1140 failed: {target_ty:?} != {fru_ty:?}: {:?}",
1141 field.name,
1142 );
1143 }
1144 }
1145 }
1146 }
1147 let fresh_base_ty = Ty::new_adt(self.interner(), adt_id, fresh_args);
1166 self.infer_expr_suptype_coerce_never(
1167 base_expr,
1168 &Expectation::has_type(self.resolve_vars_if_possible(fresh_base_ty)),
1169 ExprIsRead::Yes,
1170 );
1171 } else {
1172 self.infer_expr_no_expect(base_expr, ExprIsRead::Yes);
1175 self.push_diagnostic(
1176 InferenceDiagnostic::FunctionalRecordUpdateOnNonStruct { base_expr },
1177 );
1178 }
1179 } else {
1180 self.infer_expr_suptype_coerce_never(
1181 base_expr,
1182 &Expectation::has_type(adt_ty),
1183 ExprIsRead::Yes,
1184 );
1185 if !matches!(adt_id, AdtId::StructId(_)) {
1186 self.push_diagnostic(
1187 InferenceDiagnostic::FunctionalRecordUpdateOnNonStruct { base_expr },
1188 );
1189 }
1190 }
1191 }
1192 RecordSpread::None => {
1193 if !matches!(adt_id, AdtId::UnionId(_))
1194 && !remaining_fields.is_empty()
1195 && !self.has_applicable_non_exhaustive(adt_id.into())
1197 {
1198 debug!(?remaining_fields);
1199
1200 }
1202 }
1203 }
1204 }
1205
1206 fn demand_scrutinee_type(
1207 &mut self,
1208 scrut: ExprId,
1209 contains_ref_bindings: bool,
1210 no_arms: bool,
1211 scrutinee_is_read: ExprIsRead,
1212 ) -> Ty<'db> {
1213 if contains_ref_bindings || no_arms {
1266 self.infer_expr_no_expect(scrut, scrutinee_is_read)
1267 } else {
1268 let scrut_ty = self.table.next_ty_var(scrut.into());
1272 self.infer_expr_coerce_never(scrut, &Expectation::HasType(scrut_ty), scrutinee_is_read);
1273 scrut_ty
1274 }
1275 }
1276
1277 fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatIdPacked, scope_id: ExprId) -> Ty<'db> {
1278 let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, scope_id);
1279 let ty = match self.infer_path(path, id) {
1280 Some((_, ty)) => ty,
1281 None => {
1282 if path.mod_path().is_some_and(|mod_path| mod_path.is_ident() || mod_path.is_self())
1283 {
1284 self.push_diagnostic(InferenceDiagnostic::UnresolvedIdent { id });
1285 }
1286 self.err_ty()
1287 }
1288 };
1289 self.resolver.reset_to_guard(g);
1290 ty
1291 }
1292
1293 fn infer_unop_expr(
1294 &mut self,
1295 unop: UnaryOp,
1296 oprnd: ExprId,
1297 expected: &Expectation<'db>,
1298 expr: ExprId,
1299 ) -> Ty<'db> {
1300 let expected_inner = match unop {
1301 UnaryOp::Not | UnaryOp::Neg => expected,
1302 UnaryOp::Deref => &Expectation::None,
1303 };
1304 let mut oprnd_t = self.infer_expr_inner(oprnd, expected_inner, ExprIsRead::Yes);
1305
1306 oprnd_t = self.structurally_resolve_type(oprnd.into(), oprnd_t);
1307 match unop {
1308 UnaryOp::Deref => {
1309 if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
1310 oprnd_t = ty;
1311 } else {
1312 self.push_diagnostic(InferenceDiagnostic::CannotBeDereferenced {
1313 expr,
1314 found: oprnd_t.store(),
1315 });
1316 oprnd_t = self.types.types.error;
1317 }
1318 }
1319 UnaryOp::Not => {
1320 let result = self.infer_user_unop(expr, oprnd_t, unop);
1321 if !(oprnd_t.is_integral() || oprnd_t.kind() == TyKind::Bool) {
1323 oprnd_t = result;
1324 }
1325 }
1326 UnaryOp::Neg => {
1327 let result = self.infer_user_unop(expr, oprnd_t, unop);
1328 if !oprnd_t.is_numeric() {
1330 oprnd_t = result;
1331 }
1332 }
1333 }
1334 oprnd_t
1335 }
1336
1337 fn infer_array_repeat_expr(
1338 &mut self,
1339 element: ExprId,
1340 count: ExprId,
1341 expected: &Expectation<'db>,
1342 expr: ExprId,
1343 ) -> Ty<'db> {
1344 let interner = self.interner();
1345 let count_ct = self.create_body_anon_const(count, self.types.types.usize, true);
1346 let count = self.table.try_structurally_resolve_const(count.into(), count_ct);
1347
1348 let uty = match expected {
1349 Expectation::HasType(uty) => uty.builtin_index(),
1350 _ => None,
1351 };
1352
1353 let t = match uty {
1354 Some(uty) => {
1355 self.infer_expr_coerce(element, &Expectation::has_type(uty), ExprIsRead::Yes);
1356 uty
1357 }
1358 None => {
1359 let ty = self.table.next_ty_var(element.into());
1360 self.infer_expr(element, &Expectation::has_type(ty), ExprIsRead::Yes);
1361 ty
1362 }
1363 };
1364
1365 let ty = Ty::new_array_with_const_len(interner, t, count);
1372 self.table.register_wf_obligation(ty.into(), ObligationCause::new(expr));
1373 ty
1374 }
1375
1376 fn infer_array_elements_expr(
1377 &mut self,
1378 args: &[ExprId],
1379 expected: &Expectation<'db>,
1380 expr: ExprId,
1381 ) -> Ty<'db> {
1382 let element_ty = if !args.is_empty() {
1383 let coerce_to = expected
1384 .to_option(&self.table)
1385 .and_then(|uty| {
1386 self.table
1387 .resolve_vars_with_obligations(uty)
1388 .builtin_index()
1389 .filter(|t| !self.table.resolve_vars_with_obligations(*t).is_ty_var())
1392 })
1393 .unwrap_or_else(|| self.table.next_ty_var(expr.into()));
1394 let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
1395
1396 for &e in args {
1397 let e_ty =
1403 self.infer_expr_inner(e, &Expectation::has_type(coerce_to), ExprIsRead::Yes);
1404 let cause = ObligationCause::new(e);
1405 coerce.coerce(self, &cause, e, e_ty, ExprIsRead::Yes);
1406 }
1407 coerce.complete(self)
1408 } else {
1409 self.table.next_ty_var(expr.into())
1410 };
1411 let array_len = args.len() as u128;
1412 Ty::new_array(self.interner(), element_ty, array_len)
1413 }
1414
1415 pub(super) fn infer_return(&mut self, expr: ExprId) {
1416 let ret_ty = self
1417 .return_coercion
1418 .as_mut()
1419 .expect("infer_return called outside function body")
1420 .expected_ty();
1421 let return_expr_ty =
1422 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1423 let mut coerce_many = self.return_coercion.take().unwrap();
1424 coerce_many.coerce(
1425 self,
1426 &ObligationCause::new(expr),
1427 expr,
1428 return_expr_ty,
1429 ExprIsRead::Yes,
1430 );
1431 self.return_coercion = Some(coerce_many);
1432 }
1433
1434 fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db> {
1435 match self.return_coercion {
1436 Some(_) => {
1437 if let Some(expr) = expr {
1438 self.infer_return(expr);
1439 } else {
1440 let mut coerce = self.return_coercion.take().unwrap();
1441 coerce.coerce_forced_unit(
1442 self,
1443 ret,
1444 &ObligationCause::new(ret),
1445 true,
1446 ExprIsRead::Yes,
1447 );
1448 self.return_coercion = Some(coerce);
1449 }
1450 }
1451 None => {
1452 self.push_diagnostic(InferenceDiagnostic::ReturnOutsideFunction {
1453 expr: ret,
1454 kind: ReturnKind::ReturnExpr,
1455 });
1456 if let Some(expr) = expr {
1457 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1458 }
1459 }
1460 }
1461 self.types.types.never
1462 }
1463
1464 fn infer_expr_become(&mut self, tgt_expr: ExprId, expr: ExprId) -> Ty<'db> {
1465 match &self.return_coercion {
1466 Some(return_coercion) => {
1467 let ret_ty = return_coercion.expected_ty();
1468
1469 let call_expr_ty =
1470 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1471
1472 _ = self.demand_eqtype(expr.into(), call_expr_ty, ret_ty);
1475 }
1476 None => {
1477 self.push_diagnostic(InferenceDiagnostic::ReturnOutsideFunction {
1478 expr: tgt_expr,
1479 kind: ReturnKind::BecomeExpr,
1480 });
1481 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1482 }
1483 }
1484
1485 self.types.types.never
1486 }
1487
1488 fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation<'db>) -> Ty<'db> {
1489 if let Some(box_id) = self.resolve_boxed_box() {
1490 let table = &mut self.table;
1491 let inner_exp = expected
1492 .to_option(table)
1493 .as_ref()
1494 .and_then(|e| e.as_adt())
1495 .filter(|(e_adt, _)| e_adt == &box_id)
1496 .map(|(_, subts)| {
1497 let g = subts.type_at(0);
1498 Expectation::rvalue_hint(self, g)
1499 })
1500 .unwrap_or_else(Expectation::none);
1501
1502 let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp, ExprIsRead::Yes);
1503 Ty::new_box(self.interner(), inner_ty)
1504 } else {
1505 self.err_ty()
1506 }
1507 }
1508
1509 fn infer_block(
1510 &mut self,
1511 expr: ExprId,
1512 statements: &[Statement],
1513 tail: Option<ExprId>,
1514 label: Option<LabelId>,
1515 expected: &Expectation<'db>,
1516 ) -> Ty<'db> {
1517 let prev_diverges = self.diverges;
1518 let coerce_ty = expected.coercion_target_type(&mut self.table, expr.into());
1519 let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, expr);
1520
1521 let (ctxt, tail_expr_ty) =
1522 self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
1523 for stmt in statements {
1524 match stmt {
1525 Statement::Let { pat, type_ref, initializer, else_branch } => {
1526 let decl_ty = type_ref
1527 .as_ref()
1528 .map(|&tr| this.make_body_ty(tr))
1529 .unwrap_or_else(|| this.table.next_ty_var((*pat).into()));
1530
1531 let ty = if let Some(expr) = initializer {
1532 let target_is_read =
1535 if this.pat_guaranteed_to_constitute_read_for_never(*pat) {
1536 ExprIsRead::Yes
1537 } else {
1538 ExprIsRead::No
1539 };
1540 let ty = if this.contains_explicit_ref_binding(*pat) {
1541 this.infer_expr(
1542 *expr,
1543 &Expectation::has_type(decl_ty),
1544 target_is_read,
1545 )
1546 } else {
1547 this.infer_expr_coerce(
1548 *expr,
1549 &Expectation::has_type(decl_ty),
1550 target_is_read,
1551 )
1552 };
1553 if type_ref.is_some() { decl_ty } else { ty }
1554 } else {
1555 decl_ty
1556 };
1557
1558 this.infer_top_pat(
1559 *pat,
1560 ty,
1561 PatOrigin::LetStmt { has_else: else_branch.is_some() },
1562 );
1563 if let Some(expr) = else_branch {
1564 let previous_diverges =
1565 mem::replace(&mut this.diverges, Diverges::Maybe);
1566 this.infer_expr_coerce(
1567 *expr,
1568 &Expectation::HasType(this.types.types.never),
1569 ExprIsRead::Yes,
1570 );
1571 this.diverges = previous_diverges;
1572 }
1573 }
1574 &Statement::Expr { expr, has_semi } => {
1575 if has_semi {
1576 this.infer_expr(expr, &Expectation::none(), ExprIsRead::Yes);
1577 } else {
1578 this.infer_expr_coerce(
1579 expr,
1580 &Expectation::HasType(this.types.types.unit),
1581 ExprIsRead::Yes,
1582 );
1583 }
1584 }
1585 Statement::Item(_) => (),
1586 }
1587 }
1588
1589 tail.map(|expr| (expr, this.infer_expr_inner(expr, expected, ExprIsRead::Yes)))
1592 });
1593
1594 let mut coerce = ctxt.coerce.unwrap();
1595 if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
1596 let cause = ObligationCause::new(tail_expr);
1597 coerce.coerce_inner(
1598 self,
1599 &cause,
1600 tail_expr,
1601 tail_expr_ty,
1602 false,
1603 false,
1604 ExprIsRead::Yes,
1605 );
1606 } else {
1607 if !self.diverges.is_always() {
1618 coerce.coerce_forced_unit(
1619 self,
1620 expr,
1621 &ObligationCause::new(expr),
1622 false,
1623 ExprIsRead::Yes,
1624 );
1625 }
1626 }
1627
1628 if ctxt.may_break {
1629 self.diverges = prev_diverges;
1632 }
1633
1634 self.resolver.reset_to_guard(g);
1635
1636 coerce.complete(self)
1637 }
1638
1639 fn lookup_field(
1640 &mut self,
1641 field_expr: ExprId,
1642 receiver_ty: Ty<'db>,
1643 name: &Name,
1644 ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment>, bool)> {
1645 let interner = self.interner();
1646 let mut autoderef = self.table.autoderef_with_tracking(receiver_ty, field_expr.into());
1647 let mut private_field = None;
1648 let res = autoderef.by_ref().find_map(|(derefed_ty, _)| {
1649 let (field_id, parameters) = match derefed_ty.kind() {
1650 TyKind::Tuple(substs) => {
1651 return name.as_tuple_index().and_then(|idx| {
1652 substs.as_slice().get(idx).copied().map(|ty| {
1653 (
1654 Either::Right(TupleFieldId {
1655 tuple: TupleId(
1656 self.tuple_field_accesses_rev.insert_full(substs).0 as u32,
1657 ),
1658 index: idx as u32,
1659 }),
1660 ty,
1661 )
1662 })
1663 });
1664 }
1665 TyKind::Adt(adt, parameters) => match adt.def_id() {
1666 hir_def::AdtId::StructId(s) => {
1667 let local_id = s.fields(self.db).field(name)?;
1668 let field = FieldId { parent: s.into(), local_id };
1669 (field, parameters)
1670 }
1671 hir_def::AdtId::UnionId(u) => {
1672 let local_id = u.fields(self.db).field(name)?;
1673 let field = FieldId { parent: u.into(), local_id };
1674 (field, parameters)
1675 }
1676 hir_def::AdtId::EnumId(_) => return None,
1677 },
1678 _ => return None,
1679 };
1680 let is_visible = VariantFields::field_visibilities(self.db, field_id.parent)
1681 [field_id.local_id]
1682 .is_visible_from(self.db, self.resolver.module());
1683 if !is_visible {
1684 if private_field.is_none() {
1685 private_field = Some((field_id, parameters));
1686 }
1687 return None;
1688 }
1689 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1690 .ty()
1691 .instantiate(interner, parameters)
1692 .skip_norm_wip();
1693 Some((Either::Left(field_id), ty))
1694 });
1695
1696 Some(match res {
1697 Some((field_id, ty)) => {
1698 let adjustments =
1699 self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1700 let ty = self.process_remote_user_written_ty(ty);
1701
1702 (ty, field_id, adjustments, true)
1703 }
1704 None => {
1705 let (field_id, subst) = private_field?;
1706 let adjustments =
1707 self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1708 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1709 .ty()
1710 .instantiate(self.interner(), subst)
1711 .skip_norm_wip();
1712 let ty = self.process_remote_user_written_ty(ty);
1713
1714 (ty, Either::Left(field_id), adjustments, false)
1715 }
1716 })
1717 }
1718
1719 fn infer_field_access(
1720 &mut self,
1721 tgt_expr: ExprId,
1722 receiver: ExprId,
1723 name: &Name,
1724 expected: &Expectation<'db>,
1725 ) -> Ty<'db> {
1726 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No);
1728 let receiver_ty = self.structurally_resolve_type(receiver.into(), receiver_ty);
1729
1730 if name.is_missing() {
1731 return self.err_ty();
1734 }
1735
1736 match self.lookup_field(tgt_expr, receiver_ty, name) {
1737 Some((ty, field_id, adjustments, is_public)) => {
1738 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1739 self.result.field_resolutions.insert(tgt_expr, field_id);
1740 if !is_public && let Either::Left(field) = field_id {
1741 self.push_diagnostic(InferenceDiagnostic::PrivateField {
1743 expr: tgt_expr,
1744 field,
1745 });
1746 }
1747 ty
1748 }
1749 None => {
1750 let resolved = self.lookup_method_including_private(
1753 receiver_ty,
1754 name.clone(),
1755 None,
1756 receiver,
1757 tgt_expr,
1758 );
1759 self.push_diagnostic(InferenceDiagnostic::UnresolvedField {
1760 expr: tgt_expr,
1761 receiver: receiver_ty.store(),
1762 name: name.clone(),
1763 method_with_same_name_exists: resolved.is_ok(),
1764 });
1765 match resolved {
1766 Ok((func, _is_visible)) => {
1767 self.check_method_call(tgt_expr, &[], func.sig, expected)
1768 }
1769 Err(_) => self.err_ty(),
1770 }
1771 }
1772 }
1773 }
1774
1775 fn instantiate_erroneous_method(&mut self, def_id: FunctionId) -> MethodCallee<'db> {
1776 let args = self.table.fresh_args_for_item(Span::Dummy, def_id.into());
1779 let sig = self
1780 .db
1781 .callable_item_signature(def_id.into())
1782 .instantiate(self.interner(), args)
1783 .skip_norm_wip();
1784 let sig = self.infcx().instantiate_binder_with_fresh_vars(
1785 Span::Dummy,
1786 BoundRegionConversionTime::FnCall,
1787 sig,
1788 );
1789 MethodCallee { def_id, args, sig }
1790 }
1791
1792 fn infer_method_call_as_call(
1793 &mut self,
1794 tgt_expr: ExprId,
1795 args: &[ExprId],
1796 callee_ty: Ty<'db>,
1797 param_tys: &[Ty<'db>],
1798 ret_ty: Ty<'db>,
1799 indices_to_skip: &[u32],
1800 is_varargs: bool,
1801 expected: &Expectation<'db>,
1802 ) -> Ty<'db> {
1803 if let TyKind::FnDef(def_id, args) = callee_ty.kind() {
1804 let def_id = match def_id.0 {
1805 CallableDefId::FunctionId(it) => it.into(),
1806 CallableDefId::StructId(it) => it.into(),
1807 CallableDefId::EnumVariantId(it) => it.loc(self.db).parent.into(),
1808 };
1809 self.add_required_obligations_for_value_path(tgt_expr.into(), def_id, args);
1810 }
1811
1812 self.check_call_arguments(
1813 tgt_expr,
1814 param_tys,
1815 ret_ty,
1816 expected,
1817 args,
1818 indices_to_skip,
1819 is_varargs,
1820 TupleArgumentsFlag::DontTupleArguments,
1821 );
1822 ret_ty
1823 }
1824
1825 fn infer_method_call(
1826 &mut self,
1827 tgt_expr: ExprId,
1828 receiver: ExprId,
1829 args: &[ExprId],
1830 method_name: &Name,
1831 generic_args: Option<&HirGenericArgs>,
1832 expected: &Expectation<'db>,
1833 ) -> Ty<'db> {
1834 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes);
1835 let receiver_ty = self.table.try_structurally_resolve_type(receiver.into(), receiver_ty);
1836
1837 let resolved = self.lookup_method_including_private(
1838 receiver_ty,
1839 method_name.clone(),
1840 generic_args,
1841 receiver,
1842 tgt_expr,
1843 );
1844 match resolved {
1845 Ok((func, visible)) => {
1846 if !visible {
1847 self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem {
1848 id: tgt_expr.into(),
1849 item: func.def_id.into(),
1850 })
1851 }
1852 self.check_method_call(tgt_expr, args, func.sig, expected)
1853 }
1854 Err(_) => {
1857 let field_with_same_name_exists =
1858 match self.lookup_field(tgt_expr, receiver_ty, method_name) {
1859 Some((ty, field_id, adjustments, _public)) => {
1860 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1861 self.result.field_resolutions.insert(tgt_expr, field_id);
1862 Some(ty)
1863 }
1864 None => None,
1865 };
1866
1867 let assoc_func_with_same_name =
1868 self.with_method_resolution(tgt_expr.into(), receiver.into(), |ctx| {
1869 if !matches!(
1870 receiver_ty.kind(),
1871 TyKind::Infer(InferTy::TyVar(_)) | TyKind::Error(_)
1872 ) {
1873 ctx.probe_for_name(
1874 method_resolution::Mode::Path,
1875 method_name.clone(),
1876 receiver_ty,
1877 )
1878 } else {
1879 Err(MethodError::ErrorReported)
1880 }
1881 });
1882 let assoc_func_with_same_name = match assoc_func_with_same_name {
1883 Ok(method_resolution::Pick {
1884 item: CandidateId::FunctionId(def_id), ..
1885 })
1886 | Err(MethodError::PrivateMatch(method_resolution::Pick {
1887 item: CandidateId::FunctionId(def_id),
1888 ..
1889 })) => Some(self.instantiate_erroneous_method(def_id)),
1890 _ => None,
1891 };
1892
1893 self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
1894 expr: tgt_expr,
1895 receiver: receiver_ty.store(),
1896 name: method_name.clone(),
1897 field_with_same_name: field_with_same_name_exists.map(|it| it.store()),
1898 assoc_func_with_same_name: assoc_func_with_same_name.map(|it| it.def_id),
1899 });
1900
1901 let recovered = match assoc_func_with_same_name {
1902 Some(it) => Some((
1903 Ty::new_fn_def(
1904 self.interner(),
1905 CallableDefId::FunctionId(it.def_id).into(),
1906 it.args,
1907 ),
1908 it.sig,
1909 true,
1910 )),
1911 None => field_with_same_name_exists.and_then(|field_ty| {
1912 let callable_sig = field_ty.callable_sig(self.interner())?;
1913 Some((field_ty, callable_sig.skip_binder(), false))
1914 }),
1915 };
1916 match recovered {
1917 Some((callee_ty, sig, strip_first)) => self.infer_method_call_as_call(
1918 tgt_expr,
1919 args,
1920 callee_ty,
1921 sig.inputs_and_output.inputs().get(strip_first as usize..).unwrap_or(&[]),
1922 sig.output(),
1923 &[],
1924 true,
1925 expected,
1926 ),
1927 None => {
1928 for &arg in args.iter() {
1929 self.infer_expr_no_expect(arg, ExprIsRead::Yes);
1930 }
1931 self.err_ty()
1932 }
1933 }
1934 }
1935 }
1936 }
1937
1938 fn check_method_call(
1939 &mut self,
1940 tgt_expr: ExprId,
1941 args: &[ExprId],
1942 sig: FnSig<'db>,
1943 expected: &Expectation<'db>,
1944 ) -> Ty<'db> {
1945 let param_tys = if !sig.inputs_and_output.inputs().is_empty() {
1946 &sig.inputs_and_output.inputs()[1..]
1947 } else {
1948 &[]
1949 };
1950 let ret_ty = sig.output();
1951
1952 self.check_call_arguments(
1953 tgt_expr,
1954 param_tys,
1955 ret_ty,
1956 expected,
1957 args,
1958 &[],
1959 sig.c_variadic(),
1960 TupleArgumentsFlag::DontTupleArguments,
1961 );
1962 ret_ty
1963 }
1964
1965 pub(super) fn check_call_arguments(
1968 &mut self,
1969 call_expr: ExprId,
1970 formal_input_tys: &[Ty<'db>],
1972 formal_output: Ty<'db>,
1973 expectation: &Expectation<'db>,
1975 provided_args: &[ExprId],
1977 skip_indices: &[u32],
1978 c_variadic: bool,
1980 tuple_arguments: TupleArgumentsFlag,
1982 ) {
1983 let formal_input_tys: Vec<_> = formal_input_tys
1984 .iter()
1985 .map(|&ty| {
1986 let generalized_ty = self.table.next_ty_var(call_expr.into());
1987 let _ = self.demand_eqtype(call_expr.into(), ty, generalized_ty);
1988 generalized_ty
1989 })
1990 .collect();
1991
1992 let formal_output = self.table.resolve_vars_with_obligations(formal_output);
1997 let expected_input_tys: Option<Vec<_>> = expectation
1998 .only_has_type(&mut self.table)
1999 .and_then(|expected_output| {
2000 self.table
2001 .infer_ctxt
2002 .fudge_inference_if_ok(|| {
2003 let mut ocx = ObligationCtxt::new(&self.table.infer_ctxt);
2004
2005 let origin = ObligationCause::new(call_expr);
2010 ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?;
2011
2012 for &ty in &formal_input_tys {
2013 ocx.register_obligation(Obligation::new(
2014 self.interner(),
2015 ObligationCause::new(call_expr),
2016 self.table.param_env,
2017 ClauseKind::WellFormed(ty.into()),
2018 ));
2019 }
2020
2021 if !ocx.try_evaluate_obligations().is_empty() {
2022 return Err(TypeError::Mismatch);
2023 }
2024
2025 Ok(Some(formal_input_tys.clone()))
2028 })
2029 .ok()
2030 })
2031 .unwrap_or_default();
2032
2033 let (formal_input_tys, expected_input_tys) = if tuple_arguments
2035 == TupleArgumentsFlag::TupleArguments
2036 {
2037 let tuple_type = self.structurally_resolve_type(call_expr.into(), formal_input_tys[0]);
2038 match tuple_type.kind() {
2039 TyKind::Tuple(arg_types) => {
2041 if arg_types.len() != provided_args.len() {
2043 }
2045 let expected_input_tys = match expected_input_tys {
2046 Some(expected_input_tys) => match expected_input_tys.first() {
2047 Some(ty) => match ty.kind() {
2048 TyKind::Tuple(tys) => Some(tys.iter().collect()),
2049 _ => None,
2050 },
2051 None => None,
2052 },
2053 None => None,
2054 };
2055 (arg_types.to_vec(), expected_input_tys)
2056 }
2057 _ => {
2058 (vec![self.types.types.error; provided_args.len()], None)
2062 }
2063 }
2064 } else {
2065 (formal_input_tys, expected_input_tys)
2066 };
2067
2068 let expected_input_tys = if let Some(expected_input_tys) = expected_input_tys {
2070 assert_eq!(expected_input_tys.len(), formal_input_tys.len());
2071 expected_input_tys
2072 } else {
2073 formal_input_tys.clone()
2074 };
2075
2076 let minimum_input_count = expected_input_tys.len();
2077 let provided_arg_count = provided_args.len() - skip_indices.len();
2078
2079 let args_count_matches = if c_variadic {
2084 provided_arg_count >= minimum_input_count
2085 } else {
2086 provided_arg_count == minimum_input_count
2087 };
2088
2089 if !args_count_matches {
2090 self.push_diagnostic(InferenceDiagnostic::MismatchedArgCount {
2091 call_expr,
2092 expected: expected_input_tys.len() + skip_indices.len(),
2093 found: provided_args.len(),
2094 });
2095 }
2096
2097 let demand_compatible = |this: &mut InferenceContext<'db>, idx| {
2101 let formal_input_ty: Ty<'db> = formal_input_tys[idx];
2102 let expected_input_ty: Ty<'db> = expected_input_tys[idx];
2103 let provided_arg = provided_args[idx];
2104
2105 debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
2106
2107 let expectation = Expectation::rvalue_hint(this, expected_input_ty);
2111
2112 let checked_ty = this.infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes);
2113
2114 let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
2118
2119 let coerced_ty = this.table.resolve_vars_with_obligations(coerced_ty);
2123
2124 let coerce_error = this
2125 .coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, ExprIsRead::Yes)
2126 .err();
2127 if coerce_error.is_some() {
2128 return Err((coerce_error, coerced_ty, checked_ty));
2129 }
2130
2131 let formal_ty_error = this
2134 .table
2135 .infer_ctxt
2136 .at(&ObligationCause::new(provided_arg), this.table.param_env)
2137 .eq(formal_input_ty, coerced_ty);
2138
2139 match formal_ty_error {
2141 Ok(InferOk { obligations, value: () }) => {
2142 this.table.register_predicates(obligations);
2143 Ok(())
2144 }
2145 Err(err) => Err((Some(err), coerced_ty, checked_ty)),
2146 }
2147 };
2148
2149 for check_closures in [false, true] {
2155 if check_closures {
2159 self.table.select_obligations_where_possible();
2160 }
2161
2162 let mut skip_indices = skip_indices.iter().copied();
2163 for (idx, arg) in provided_args.iter().enumerate() {
2166 if skip_indices.clone().next() == Some(idx as u32) {
2167 skip_indices.next();
2168 continue;
2169 }
2170
2171 let is_closure = if let Expr::Closure { closure_kind, .. } = self.store[*arg] {
2177 !matches!(closure_kind, ClosureKind::OldCoroutine(_))
2178 } else {
2179 false
2180 };
2181 if is_closure != check_closures {
2182 continue;
2183 }
2184
2185 if idx >= minimum_input_count {
2186 self.infer_expr_no_expect(*arg, ExprIsRead::Yes);
2188 continue;
2189 }
2190
2191 if let Err((_error, expected, found)) = demand_compatible(self, idx)
2192 && args_count_matches
2193 {
2194 self.emit_type_mismatch((*arg).into(), expected, found);
2196 }
2197 }
2198 }
2199
2200 if !args_count_matches {}
2201 }
2202
2203 pub(super) fn with_breakable_ctx<T>(
2204 &mut self,
2205 kind: BreakableKind,
2206 ty: Option<Ty<'db>>,
2207 label: Option<LabelId>,
2208 cb: impl FnOnce(&mut Self) -> T,
2209 ) -> (BreakableContext<'db>, T) {
2210 self.breakables.push({
2211 BreakableContext { kind, may_break: false, coerce: ty.map(CoerceMany::new), label }
2212 });
2213 let res = cb(self);
2214 let ctx = self.breakables.pop().expect("breakable stack broken");
2215 (ctx, res)
2216 }
2217}
2218
2219#[derive(Copy, Clone, Eq, PartialEq)]
2239pub(super) enum TupleArgumentsFlag {
2240 DontTupleArguments,
2241 TupleArguments,
2242}