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