Skip to main content

hir_ty/infer/
expr.rs

1//! Type inference for expressions.
2
3use 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    /// Infer type of expression with possibly implicit coerce to the expected type.
108    /// Return the type after possible coercion.
109    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    /// Whether this expression constitutes a read of value of the type that
130    /// it evaluates to.
131    ///
132    /// This is used to determine if we should consider the block to diverge
133    /// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
134    /// coercion for values of type `!`.
135    ///
136    /// This function generally returns `false` if the expression is a place
137    /// expression and the *parent* expression is the scrutinee of a match or
138    /// the pointee of an `&` addr-of expression, since both of those parent
139    /// expressions take a *place* and not a value.
140    pub(super) fn expr_guaranteed_to_constitute_read_for_never(
141        &mut self,
142        expr: ExprId,
143        is_read: ExprIsRead,
144    ) -> bool {
145        // rustc queries parent hir node of `expr` here and determine whether
146        // the current `expr` is read of value per its parent.
147        // But since we don't have hir node, we cannot follow such "bottom-up"
148        // method.
149        // So, we pass down such readness from the parent expression through the
150        // recursive `infer_expr*` calls in a "top-down" manner.
151        // rustc does the place expr check first, but since we are feeding
152        // readness of the `expr` as a given value, we just can short-circuit
153        // the place expr check if it's true(see codes and comments below)
154        is_read == ExprIsRead::Yes
155            // We only care about place exprs. Anything else returns an immediate
156            // which would constitute a read. We don't care about distinguishing
157            // "syntactic" place exprs since if the base of a field projection is
158            // not a place then it would've been UB to read from it anyways since
159            // that constitutes a read.
160            || !self.is_syntactic_place_expr(expr)
161    }
162
163    /// Whether this pattern constitutes a read of value of the scrutinee that
164    /// it is matching against. This is used to determine whether we should
165    /// perform `NeverToAny` coercions.
166    fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
167        match &self.store[pat] {
168            // Does not constitute a read.
169            Pat::Wild | Pat::Rest => false,
170
171            // This is unnecessarily restrictive when the pattern that doesn't
172            // constitute a read is unreachable.
173            //
174            // For example `match *never_ptr { value => {}, _ => {} }` or
175            // `match *never_ptr { _ if false => {}, value => {} }`.
176            //
177            // It is however fine to be restrictive here; only returning `true`
178            // can lead to unsoundness.
179            Pat::Or(subpats) => {
180                subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(*pat))
181            }
182
183            // All of these constitute a read, or match on something that isn't `!`,
184            // which would require a `NeverToAny` coercion.
185            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    /// Checks if the pattern contains any `ref` or `ref mut` bindings, and if
206    /// yes whether it contains mutable or just immutables ones.
207    //
208    // FIXME(tschottdorf): this is problematic as the HIR is being scraped, but
209    // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848.
210    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            // Lang item paths cannot currently be local variables or statics.
225            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        // While we don't allow *arbitrary* coercions here, we *do* allow
294        // coercions from `!` to `expected`.
295        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                    // you can only use break with a value from a normal `loop { }`
409                    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                        // We don't coerce to `()` so that if the match expression is a
479                        // statement it's branches can have any consistent type.
480                        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                        // If we encountered a `break`, then (no surprise) it may be possible to break from the
554                        // loop... unless the value being returned from the loop diverges itself, e.g.
555                        // `break return 5` or `break loop {}`.
556                        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                // In ordinary (non-destructuring) assignments, the type of
643                // `lhs` must be inferred first so that the ADT fields
644                // instantiations in RHS can be coerced to it. Note that this
645                // cannot happen in destructuring assignments because of how
646                // they are desugared.
647                let lhs_ty = match &self.store[target] {
648                    // LHS of assignment doesn't constitute reads.
649                    &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 the target pattern constrain the RHS coercion target. In particular,
661                    // this allows a diverging RHS to coerce to the pattern's type.
662                    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                    // Ordinary assignments always return `()`, even when they diverge.
672                    // However, rustc lowers destructuring assignments into blocks, and blocks return `!` if they have no tail
673                    // expression and they diverge. Therefore, we have to do the same here, even though we don't lower destructuring
674                    // assignments into blocks.
675                    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                        // two-phase not needed because index_ty is never mutable
688                        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                // Underscore expression is an error, we render a specialized diagnostic
770                // to let the user know what type is expected though.
771                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 this is an input value, we require its type to be fully resolved
784                    // at this point. This allows us to provide helpful coercions which help
785                    // pass the type candidate list in a later pass.
786                    //
787                    // We don't require output types to be resolved at this point, which
788                    // allows them to be inferred based on how they are used later in the
789                    // function.
790                    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                        // The label blocks should have unit return value or diverge.
840                        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                        // We need this to avoid false unreachable warning when a label diverges.
850                        self.diverges = previous_diverges;
851                    }
852                    AsmOperand::Const(expr) => {
853                        self.infer_expr(expr, &Expectation::None, ExprIsRead::No);
854                    }
855                    // FIXME: `sym` should report for things that are not functions or statics.
856                    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            // Any expression that produces a value of type `!` must have diverged
876            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                        // Places may legitimately have unsized types.
894                        // For example, dereferences of a wide pointer and
895                        // the last field of a struct can be unsized.
896                        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                // Note: at this point, we cannot say what the best lifetime
910                // is to use for resulting pointer. We want to use the
911                // shortest lifetime possible so as to avoid spurious borrowck
912                // errors. Moreover, the longest lifetime will depend on the
913                // precise details of the value whose address is being taken
914                // (and how long it is valid), which we don't know yet until
915                // type inference is complete.
916                //
917                // Therefore, here we simply generate a region variable. The
918                // region inferencer will then select a suitable value.
919                // Finally, borrowck will infer the value of the region again,
920                // this time with enough precision to check that the value
921                // whose address was taken can actually be made to live as long
922                // as it needs to live.
923                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        // Find the relevant variant
952        let (adt_ty, Some(variant)) = self.resolve_variant(expr.into(), path, false) else {
953            // FIXME: Emit an error.
954            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        // Prohibit struct expressions when non-exhaustive flag is set.
963        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            // re-link the variables that the fudging above can create.
999            _ = 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        // Type-check each field.
1020        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            // Check that the expected field type is WF. Otherwise, we emit no use-site error
1052            // in the case of coercions for non-WF fields, which leads to incorrect error
1053            // tainting. See issue #126272.
1054            self.table.register_wf_obligation(field_type.into(), ObligationCause::new(field.expr));
1055
1056            // Make sure to give a type to the field even if there's
1057            // an error, so we can continue type-checking.
1058            self.infer_expr_coerce(field.expr, &Expectation::has_type(field_type), ExprIsRead::Yes);
1059        }
1060
1061        // Make sure the programmer specified correct number of fields.
1062        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                    // FIXME: Emit an error: missing fields.
1081                }
1082            }
1083            RecordSpread::Expr(base_expr) => {
1084                // FIXME: We are currently creating two branches here in order to maintain
1085                // consistency. But they should be merged as much as possible.
1086                if self.features.type_changing_struct_update {
1087                    if matches!(adt_id, AdtId::StructId(_)) {
1088                        // Make some fresh generic parameters for our ADT type.
1089                        let fresh_args = self.table.fresh_args_for_item(expr.into(), adt_id.into());
1090                        // We do subtyping on the FRU fields first, so we can
1091                        // learn exactly what types we expect the base expr
1092                        // needs constrained to be compatible with the struct
1093                        // type we expect from the expectation value.
1094                        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                        // The use of fresh args that we have subtyped against
1120                        // our base ADT type's fields allows us to guide inference
1121                        // along so that, e.g.
1122                        // ```
1123                        // MyStruct<'a, F1, F2, const C: usize> {
1124                        //     f: F1,
1125                        //     // Other fields that reference `'a`, `F2`, and `C`
1126                        // }
1127                        //
1128                        // let x = MyStruct {
1129                        //    f: 1usize,
1130                        //    ..other_struct
1131                        // };
1132                        // ```
1133                        // will have the `other_struct` expression constrained to
1134                        // `MyStruct<'a, _, F2, C>`, as opposed to just `_`...
1135                        // This is important to allow coercions to happen in
1136                        // `other_struct` itself. See `coerce-in-base-expr.rs`.
1137                        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                        // Check the base_expr, regardless of a bad expected adt_ty, so we can get
1145                        // type errors on that expression, too.
1146                        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                    //~ non_exhaustive already reported, which will only happen for extern modules
1168                    && !self.has_applicable_non_exhaustive(adt_id.into())
1169                {
1170                    debug!(?remaining_fields);
1171
1172                    // FIXME: Emit an error: missing fields.
1173                }
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        // Not entirely obvious: if matches may create ref bindings, we want to
1186        // use the *precise* type of the scrutinee, *not* some supertype, as
1187        // the "scrutinee type" (issue #23116).
1188        //
1189        // arielb1 [writes here in this comment thread][c] that there
1190        // is certainly *some* potential danger, e.g., for an example
1191        // like:
1192        //
1193        // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
1194        //
1195        // ```
1196        // let Foo(x) = f()[0];
1197        // ```
1198        //
1199        // Then if the pattern matches by reference, we want to match
1200        // `f()[0]` as a lexpr, so we can't allow it to be
1201        // coerced. But if the pattern matches by value, `f()[0]` is
1202        // still syntactically a lexpr, but we *do* want to allow
1203        // coercions.
1204        //
1205        // However, *likely* we are ok with allowing coercions to
1206        // happen if there are no explicit ref mut patterns - all
1207        // implicit ref mut patterns must occur behind a reference, so
1208        // they will have the "correct" variance and lifetime.
1209        //
1210        // This does mean that the following pattern would be legal:
1211        //
1212        // ```
1213        // struct Foo(Bar);
1214        // struct Bar(u32);
1215        // impl Deref for Foo {
1216        //     type Target = Bar;
1217        //     fn deref(&self) -> &Bar { &self.0 }
1218        // }
1219        // impl DerefMut for Foo {
1220        //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
1221        // }
1222        // fn foo(x: &mut Foo) {
1223        //     {
1224        //         let Bar(z): &mut Bar = x;
1225        //         *z = 42;
1226        //     }
1227        //     assert_eq!(foo.0.0, 42);
1228        // }
1229        // ```
1230        //
1231        // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
1232        // is problematic as the HIR is being scraped, but ref bindings may be
1233        // implicit after #42640. We need to make sure that pat_adjustments
1234        // (once introduced) is populated by the time we get here.
1235        //
1236        // See #44848.
1237        if contains_ref_bindings || no_arms {
1238            self.infer_expr_no_expect(scrut, scrutinee_is_read)
1239        } else {
1240            // ...but otherwise we want to use any supertype of the
1241            // scrutinee. This is sort of a workaround, see note (*) in
1242            // `check_pat` for some details.
1243            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 it's builtin, we can reuse the type, this helps inference.
1294                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 it's builtin, we can reuse the type, this helps inference.
1301                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        // We defer checking whether the element type is `Copy` as it is possible to have
1338        // an inference variable as a repeat count and it seems unlikely that `Copy` would
1339        // have inference side effects required for type checking to succeed.
1340        // FIXME: Do it here like rustc.
1341        // self.deferred_repeat_expr_checks.borrow_mut().push((element, element_ty, count));
1342
1343        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                        // Avoid using the original type variable as the coerce_to type, as it may resolve
1362                        // during the first coercion instead of being the LUB type.
1363                        .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                // FIXME: the element expectation should use
1370                // `try_structurally_resolve_and_adjust_for_branches` just like in `if` and `match`.
1371                // While that fixes nested coercion, it will break [some
1372                // code like this](https://github.com/rust-lang/rust/pull/140283#issuecomment-2958776528).
1373                // If we find a way to support recursive tuple coercion, this break can be avoided.
1374                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                // NB: this should *not* coerce.
1445                //     tail calls don't support any coercions except lifetimes ones (like `&'static u8 -> &'a u8`).
1446                _ = 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                // check the tail expression **without** holding the
1515                // `enclosing_breakables` lock below.
1516                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            // Subtle: if there is no explicit tail expression,
1533            // that is typically equivalent to a tail expression
1534            // of `()` -- except if the block diverges. In that
1535            // case, there is no value supplied from the tail
1536            // expression (assuming there are no other breaks,
1537            // this implies that the type of the block will be
1538            // `!`).
1539            //
1540            // #41425 -- label the implicit `()` as being the
1541            // "found type" here, rather than the "expected type".
1542            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            // If we can break from the block, then the block's exit is always reachable
1555            // (... as long as the entry is reachable) - regardless of the tail of the block.
1556            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            // If we have a subpattern that performs a read, we want to consider this
1573            // to diverge for compatibility to support something like `let x: () = *never_ptr;`.
1574            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        // Field projections don't constitute reads.
1677        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            // Bail out early, don't even try to look up field. Also, we don't issue an unresolved
1682            // field diagnostic because this is a syntax error rather than a semantic error.
1683            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                    // FIXME: Merge this diagnostic into UnresolvedField?
1692                    self.push_diagnostic(InferenceDiagnostic::PrivateField {
1693                        expr: tgt_expr,
1694                        field,
1695                    });
1696                }
1697                ty
1698            }
1699            None => {
1700                // no field found, lets attempt to resolve it like a function so that IDE things
1701                // work out while people are typing
1702                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        // FIXME: Using fresh infer vars for the method args isn't optimal,
1727        // we can do better by going thorough the full probe/confirm machinery.
1728        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            // Failed to resolve, report diagnostic and try to resolve as call to field access or
1805            // assoc function
1806            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    /// Generic function that factors out common logic from function calls,
1921    /// method calls and overloaded operators.
1922    pub(super) fn check_call_arguments(
1923        &mut self,
1924        call_expr: ExprId,
1925        // Types (as defined in the *signature* of the target function)
1926        formal_input_tys: &[Ty<'db>],
1927        formal_output: Ty<'db>,
1928        // Expected output from the parent expression or statement
1929        expectation: &Expectation<'db>,
1930        // The expressions for each provided argument
1931        provided_args: &[ExprId],
1932        skip_indices: &[u32],
1933        // Whether the function is variadic, for example when imported from C
1934        c_variadic: bool,
1935        // Whether the arguments have been bundled in a tuple (ex: closures)
1936        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        // First, let's unify the formal method signature with the expectation eagerly.
1948        // We use this to guide coercion inference; it's output is "fudged" which means
1949        // any remaining type variables are assigned to new, unrelated variables. This
1950        // is because the inference guidance here is only speculative.
1951        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                        // Attempt to apply a subtyping relationship between the formal
1961                        // return type (likely containing type variables if the function
1962                        // is polymorphic) and the expected return type.
1963                        // No argument expectations are produced if unification fails.
1964                        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                        // Record all the argument types, with the args
1981                        // produced from the above subtyping unification.
1982                        Ok(Some(formal_input_tys.clone()))
1983                    })
1984                    .ok()
1985            })
1986            .unwrap_or_default();
1987
1988        // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
1989        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                // We expected a tuple and got a tuple
1995                TyKind::Tuple(arg_types) => {
1996                    // Argument length differs. The mismatch is reported below by the
1997                    // shared `MismatchedArgCount` push (with `is_fn_trait_call = true`,
1998                    // which the diagnostic surface renders as E0057).
1999                    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                    // Otherwise, there's a mismatch, so clear out what we're expecting, and set
2013                    // our input types to err_args so we don't blow up the error messages
2014                    // FIXME: Emit an error.
2015                    (vec![self.types.types.error; provided_args.len()], None)
2016                }
2017            }
2018        } else {
2019            (formal_input_tys, expected_input_tys)
2020        };
2021
2022        // If there are no external expectations at the call site, just use the types from the function defn
2023        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        // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
2034        // if the wrong number of arguments were supplied, we CAN'T be satisfied,
2035        // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function
2036        // otherwise, they need to be identical, because rust doesn't currently support variadic functions
2037        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        // We introduce a helper function to demand that a given argument satisfy a given input
2053        // This is more complicated than just checking type equality, as arguments could be coerced
2054        // This version writes those types back so further type checking uses the narrowed types
2055        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            // We're on the happy path here, so we'll do a more involved check and write back types
2063            // To check compatibility, we'll do 3 things:
2064            // 1. Unify the provided argument with the expected type
2065            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            // 2. Coerce to the most detailed type that could be coerced
2070            //    to, which is `expected_ty` if `rvalue_hint` returns an
2071            //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2072            let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
2073
2074            // Cause selection errors caused by resolving a single argument to point at the
2075            // argument and not the call. This lets us customize the span pointed to in the
2076            // fulfillment error to be more accurate.
2077            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            // 3. Check if the formal type is actually equal to the checked one
2087            //    and register any such obligations for future type checks.
2088            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            // If neither check failed, the types are compatible
2095            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        // Check the arguments.
2105        // We do this in a pretty awful way: first we type-check any arguments
2106        // that are not closures, then we type-check the closures. This is so
2107        // that we have more information about the types of arguments when we
2108        // type-check the functions. This isn't really the right way to do this.
2109        for check_closures in [false, true] {
2110            // More awful hacks: before we check argument types, try to do
2111            // an "opportunistic" trait resolution of any trait bounds on
2112            // the call. This helps coercions.
2113            if check_closures {
2114                self.table.select_obligations_where_possible();
2115            }
2116
2117            let mut skip_indices = skip_indices.iter().copied();
2118            // Check each argument, to satisfy the input it was provided for
2119            // Visually, we're traveling down the diagonal of the compatibility matrix
2120            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                // For this check, we do *not* want to treat async coroutine closures (async blocks)
2127                // as proper closures. Doing so would regress type inference when feeding
2128                // the return value of an argument-position async block to an argument-position
2129                // closure wrapped in a block.
2130                // See <https://github.com/rust-lang/rust/issues/112225>.
2131                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                    // Make sure we've checked this expr at least once.
2142                    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                    // Don't report type mismatches if there is a mismatch in args count.
2150                    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/// Controls whether the arguments are tupled. This is used for the call
2175/// operator.
2176///
2177/// Tupling means that all call-side arguments are packed into a tuple and
2178/// passed as a single parameter. For example, if tupling is enabled, this
2179/// function:
2180/// ```
2181/// fn f(x: (isize, isize)) {}
2182/// ```
2183/// Can be called as:
2184/// ```ignore UNSOLVED (can this be done in user code?)
2185/// # fn f(x: (isize, isize)) {}
2186/// f(1, 2);
2187/// ```
2188/// Instead of:
2189/// ```
2190/// # fn f(x: (isize, isize)) {}
2191/// f((1, 2));
2192/// ```
2193#[derive(Copy, Clone, Eq, PartialEq)]
2194pub(super) enum TupleArgumentsFlag {
2195    DontTupleArguments,
2196    TupleArguments,
2197}