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