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::Record { .. }
196            | Pat::NotNull
197            | Pat::Missing => true,
198            Pat::Expr(_) => unreachable!(
199                "we don't call pat_guaranteed_to_constitute_read_for_never() with assignments"
200            ),
201        }
202    }
203
204    /// Checks if the pattern contains any `ref` or `ref mut` bindings, and if
205    /// yes whether it contains mutable or just immutables ones.
206    //
207    // FIXME(tschottdorf): this is problematic as the HIR is being scraped, but
208    // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848.
209    fn contains_explicit_ref_binding(&self, pat: PatId) -> bool {
210        if let Pat::Bind { id, .. } = self.store[pat]
211            && matches!(self.store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
212        {
213            return true;
214        }
215
216        let mut result = false;
217        self.store.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
218        result
219    }
220
221    fn is_syntactic_place_expr(&mut self, expr: ExprId) -> bool {
222        match &self.store[expr] {
223            // Lang item paths cannot currently be local variables or statics.
224            Expr::Path(Path::LangItem(_, _)) => false,
225            Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(),
226            Expr::Path(path) => {
227                let guard = self.resolver.update_to_inner_scope(self.db, self.store_owner, expr);
228                let is_place = self
229                    .resolver
230                    .resolve_path_in_value_ns_fully(
231                        self.db,
232                        path,
233                        self.store.expr_path_hygiene(expr),
234                    )
235                    .is_none_or(|res| {
236                        matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))
237                    });
238                self.resolver.reset_to_guard(guard);
239                is_place
240            }
241            Expr::Underscore => true,
242            Expr::UnaryOp { op: UnaryOp::Deref, .. } => true,
243            Expr::Field { .. } | Expr::Index { .. } => true,
244            Expr::Call { .. }
245            | Expr::MethodCall { .. }
246            | Expr::Tuple { .. }
247            | Expr::If { .. }
248            | Expr::Match { .. }
249            | Expr::Closure { .. }
250            | Expr::Block { .. }
251            | Expr::Array(..)
252            | Expr::Break { .. }
253            | Expr::Continue { .. }
254            | Expr::Return { .. }
255            | Expr::Become { .. }
256            | Expr::Let { .. }
257            | Expr::Loop { .. }
258            | Expr::InlineAsm(..)
259            | Expr::OffsetOf(..)
260            | Expr::Literal(..)
261            | Expr::Const(..)
262            | Expr::UnaryOp { .. }
263            | Expr::BinaryOp { .. }
264            | Expr::Assignment { .. }
265            | Expr::Yield { .. }
266            | Expr::Cast { .. }
267            | Expr::Await { .. }
268            | Expr::Ref { .. }
269            | Expr::RecordLit { .. }
270            | Expr::Yeet { .. }
271            | Expr::Missing
272            | Expr::IncludeBytes => false,
273        }
274    }
275
276    pub(crate) fn check_lhs_assignable(&mut self, lhs: ExprId) {
277        if self.is_syntactic_place_expr(lhs) {
278            return;
279        }
280
281        self.push_diagnostic(InferenceDiagnostic::InvalidLhsOfAssignment { lhs });
282    }
283
284    fn infer_expr_coerce_never(
285        &mut self,
286        expr: ExprId,
287        expected: &Expectation<'db>,
288        is_read: ExprIsRead,
289    ) -> Ty<'db> {
290        let ty = self.infer_expr_inner(expr, expected, is_read);
291        // While we don't allow *arbitrary* coercions here, we *do* allow
292        // coercions from `!` to `expected`.
293        if ty.is_never() {
294            if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
295                return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
296                    target.as_ref()
297                } else {
298                    self.err_ty()
299                };
300            }
301
302            if let Some(target) = expected.only_has_type(&mut self.table) {
303                self.coerce(expr, ty, target, AllowTwoPhase::No, ExprIsRead::Yes)
304                    .expect("never-to-any coercion should always succeed")
305            } else {
306                ty
307            }
308        } else {
309            if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
310                _ = self.demand_eqtype(expr.into(), expected_ty, ty);
311            }
312            ty
313        }
314    }
315
316    #[tracing::instrument(level = "debug", skip(self, is_read), ret)]
317    pub(super) fn infer_expr_inner(
318        &mut self,
319        tgt_expr: ExprId,
320        expected: &Expectation<'db>,
321        is_read: ExprIsRead,
322    ) -> Ty<'db> {
323        self.db.unwind_if_revision_cancelled();
324
325        let expr = &self.store[tgt_expr];
326        tracing::trace!(?expr);
327        let ty = match expr {
328            Expr::Missing => self.err_ty(),
329            &Expr::If { condition, then_branch, else_branch } => {
330                let expected = &expected.adjust_for_branches(&mut self.table, tgt_expr.into());
331                self.infer_expr_coerce_never(
332                    condition,
333                    &Expectation::HasType(self.types.types.bool),
334                    ExprIsRead::Yes,
335                );
336
337                let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
338
339                let then_ty = self.infer_expr_inner(then_branch, expected, ExprIsRead::Yes);
340                let then_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
341                let mut coercion_sites = [then_branch, tgt_expr];
342                if let Some(else_branch) = else_branch {
343                    coercion_sites[1] = else_branch;
344                }
345                let mut coerce = CoerceMany::with_coercion_sites(
346                    expected.coercion_target_type(&mut self.table, then_branch.into()),
347                    &coercion_sites,
348                );
349                coerce.coerce(
350                    self,
351                    &ObligationCause::new(then_branch),
352                    then_branch,
353                    then_ty,
354                    ExprIsRead::Yes,
355                );
356                match else_branch {
357                    Some(else_branch) => {
358                        let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes);
359                        let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
360                        coerce.coerce(
361                            self,
362                            &ObligationCause::new(else_branch),
363                            else_branch,
364                            else_ty,
365                            ExprIsRead::Yes,
366                        );
367                        self.diverges = condition_diverges | then_diverges & else_diverges;
368                    }
369                    None => {
370                        coerce.coerce_forced_unit(
371                            self,
372                            tgt_expr,
373                            &ObligationCause::new(tgt_expr),
374                            true,
375                            ExprIsRead::Yes,
376                        );
377                        self.diverges = condition_diverges;
378                    }
379                }
380
381                coerce.complete(self)
382            }
383            &Expr::Let { pat, expr } => {
384                self.infer_let(
385                    self.table.next_ty_var(tgt_expr.into()),
386                    Some(expr),
387                    pat,
388                    PatOrigin::LetExpr,
389                );
390                self.types.types.bool
391            }
392            Expr::Block { statements, tail, label, id: _, unsafe_: _ } => {
393                self.infer_block(tgt_expr, statements, *tail, *label, expected)
394            }
395            Expr::Const(id) => {
396                self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
397                    this.infer_expr(*id, expected, ExprIsRead::Yes)
398                })
399                .1
400            }
401            &Expr::Loop { body, label, source } => {
402                let coerce = match source {
403                    // you can only use break with a value from a normal `loop { }`
404                    LoopSource::Loop => {
405                        Some(expected.coercion_target_type(&mut self.table, body.into()))
406                    }
407                    LoopSource::While | LoopSource::ForLoop => None,
408                };
409                let (breaks, ()) =
410                    self.with_breakable_ctx(BreakableKind::Loop, coerce, label, |this| {
411                        this.infer_expr_suptype_coerce_never(
412                            body,
413                            &Expectation::HasType(this.types.types.unit),
414                            ExprIsRead::Yes,
415                        );
416                    });
417
418                if breaks.may_break {
419                    self.diverges = Diverges::Maybe;
420                } else {
421                    self.diverges = Diverges::Always;
422                }
423                breaks.coerce.map(|c| c.complete(self)).unwrap_or(self.types.types.unit)
424            }
425            Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
426                .infer_closure(
427                    *body,
428                    args,
429                    *ret_type,
430                    arg_types,
431                    *closure_kind,
432                    tgt_expr,
433                    expected,
434                ),
435            Expr::Call { callee, args, .. } => self.infer_call(tgt_expr, *callee, args, expected),
436            Expr::MethodCall { receiver, args, method_name, generic_args } => self
437                .infer_method_call(
438                    tgt_expr,
439                    *receiver,
440                    args,
441                    method_name,
442                    generic_args.as_deref(),
443                    expected,
444                ),
445            Expr::Match { expr, arms } => {
446                let mut scrutinee_is_read = true;
447                let mut contains_ref_bindings = false;
448                for arm in arms {
449                    scrutinee_is_read &= self.pat_guaranteed_to_constitute_read_for_never(arm.pat);
450                    contains_ref_bindings |= self.contains_explicit_ref_binding(arm.pat);
451                }
452                let scrutinee_is_read =
453                    if scrutinee_is_read { ExprIsRead::Yes } else { ExprIsRead::No };
454                let input_ty = self.demand_scrutinee_type(
455                    *expr,
456                    contains_ref_bindings,
457                    arms.is_empty(),
458                    scrutinee_is_read,
459                );
460
461                if arms.is_empty() {
462                    self.diverges = Diverges::Always;
463                    self.types.types.never
464                } else {
465                    let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
466                    let mut all_arms_diverge = Diverges::Always;
467                    for arm in arms.iter() {
468                        self.infer_top_pat(arm.pat, input_ty, PatOrigin::MatchArm);
469                    }
470
471                    let expected = expected.adjust_for_branches(&mut self.table, tgt_expr.into());
472                    let result_ty = match &expected {
473                        // We don't coerce to `()` so that if the match expression is a
474                        // statement it's branches can have any consistent type.
475                        Expectation::HasType(ty) if *ty != self.types.types.unit => *ty,
476                        _ => self.table.next_ty_var((*expr).into()),
477                    };
478                    let mut coerce = CoerceMany::new(result_ty);
479
480                    for arm in arms.iter() {
481                        if let Some(guard_expr) = arm.guard {
482                            self.diverges = Diverges::Maybe;
483                            self.infer_expr_coerce_never(
484                                guard_expr,
485                                &Expectation::HasType(self.types.types.bool),
486                                ExprIsRead::Yes,
487                            );
488                        }
489                        self.diverges = Diverges::Maybe;
490
491                        let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes);
492                        all_arms_diverge &= self.diverges;
493                        coerce.coerce(
494                            self,
495                            &ObligationCause::new(arm.expr),
496                            arm.expr,
497                            arm_ty,
498                            ExprIsRead::Yes,
499                        );
500                    }
501
502                    self.diverges = matchee_diverges | all_arms_diverge;
503
504                    coerce.complete(self)
505                }
506            }
507            Expr::Path(p) => self.infer_expr_path(p, tgt_expr.into(), tgt_expr),
508            &Expr::Continue { label } => {
509                if find_continuable(&self.breakables, label).is_none() {
510                    self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
511                        expr: tgt_expr,
512                        is_break: false,
513                        bad_value_break: false,
514                    });
515                };
516                self.types.types.never
517            }
518            &Expr::Break { expr, label } => {
519                let breakable_idx = find_breakable(&self.breakables, label);
520                let val_ty = if let Some(expr) = expr {
521                    let opt_coerce_to = match breakable_idx {
522                        Some(breakable_idx) => match &self.breakables[breakable_idx].coerce {
523                            Some(coerce) => coerce.expected_ty(),
524                            None => {
525                                self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
526                                    expr: tgt_expr,
527                                    is_break: true,
528                                    bad_value_break: true,
529                                });
530                                self.err_ty()
531                            }
532                        },
533                        None => self.err_ty(),
534                    };
535                    self.infer_expr_inner(
536                        expr,
537                        &Expectation::HasType(opt_coerce_to),
538                        ExprIsRead::Yes,
539                    )
540                } else {
541                    self.types.types.unit
542                };
543
544                match breakable_idx {
545                    Some(breakable_idx) => {
546                        let breakable = &mut self.breakables[breakable_idx];
547
548                        // If we encountered a `break`, then (no surprise) it may be possible to break from the
549                        // loop... unless the value being returned from the loop diverges itself, e.g.
550                        // `break return 5` or `break loop {}`.
551                        breakable.may_break |= !self.diverges.is_always();
552
553                        if let Some(mut coerce) = breakable.coerce.take() {
554                            let expr = expr.unwrap_or(tgt_expr);
555                            coerce.coerce(
556                                self,
557                                &ObligationCause::new(expr),
558                                expr,
559                                val_ty,
560                                ExprIsRead::Yes,
561                            );
562                            self.breakables[breakable_idx].coerce = Some(coerce);
563                        }
564                    }
565                    None => {
566                        self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
567                            expr: tgt_expr,
568                            is_break: true,
569                            bad_value_break: false,
570                        });
571                    }
572                }
573                self.types.types.never
574            }
575            &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr),
576            &Expr::Become { expr } => self.infer_expr_become(tgt_expr, expr),
577            Expr::Yield { expr } => {
578                if let Some((resume_ty, yield_ty)) = self.resume_yield_tys {
579                    if let Some(expr) = expr {
580                        self.infer_expr_coerce(
581                            *expr,
582                            &Expectation::has_type(yield_ty),
583                            ExprIsRead::Yes,
584                        );
585                    } else {
586                        let unit = self.types.types.unit;
587                        let _ = self.coerce(
588                            tgt_expr,
589                            unit,
590                            yield_ty,
591                            AllowTwoPhase::No,
592                            ExprIsRead::Yes,
593                        );
594                    }
595                    resume_ty
596                } else {
597                    self.push_diagnostic(InferenceDiagnostic::YieldOutsideCoroutine {
598                        expr: tgt_expr,
599                    });
600                    self.types.types.error
601                }
602            }
603            Expr::Yeet { expr } => {
604                if let &Some(expr) = expr {
605                    self.infer_expr_no_expect(expr, ExprIsRead::Yes);
606                }
607                self.types.types.never
608            }
609            Expr::RecordLit { path, fields, spread, .. } => {
610                self.infer_record_expr(tgt_expr, expected, path, fields, *spread)
611            }
612            Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected),
613            Expr::Await { expr } => self.infer_await_expr(tgt_expr, *expr),
614            Expr::Cast { expr, type_ref } => {
615                let cast_ty = self.make_ty(*type_ref);
616                let expr_ty =
617                    self.infer_expr(*expr, &Expectation::Castable(cast_ty), ExprIsRead::Yes);
618                self.deferred_cast_checks.push(CastCheck::new(tgt_expr, *expr, expr_ty, cast_ty));
619                cast_ty
620            }
621            Expr::Ref { expr, rawness, mutability } => self.infer_ref_expr(
622                *rawness,
623                lower_mutability(*mutability),
624                *expr,
625                expected,
626                tgt_expr,
627            ),
628            Expr::UnaryOp { expr, op } => self.infer_unop_expr(*op, *expr, expected, tgt_expr),
629            Expr::BinaryOp { lhs, rhs, op } => match op {
630                Some(BinaryOp::Assignment { op: Some(op) }) => {
631                    self.infer_assign_op_expr(tgt_expr, *op, *lhs, *rhs)
632                }
633                Some(op) => self.infer_binop_expr(tgt_expr, *op, *lhs, *rhs),
634                None => self.err_ty(),
635            },
636            &Expr::Assignment { target, value } => {
637                // In ordinary (non-destructuring) assignments, the type of
638                // `lhs` must be inferred first so that the ADT fields
639                // instantiations in RHS can be coerced to it. Note that this
640                // cannot happen in destructuring assignments because of how
641                // they are desugared.
642                let lhs_ty = match &self.store[target] {
643                    // LHS of assignment doesn't constitute reads.
644                    &Pat::Expr(expr) => {
645                        Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No))
646                    }
647                    _ => None,
648                };
649                let is_destructuring_assignment = lhs_ty.is_none();
650
651                if let Some(lhs_ty) = lhs_ty {
652                    self.write_pat_ty(target, lhs_ty);
653                    self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::Yes);
654                } else {
655                    // Let the target pattern constrain the RHS coercion target. In particular,
656                    // this allows a diverging RHS to coerce to the pattern's type.
657                    let expected_ty = self.table.next_ty_var(target.into());
658                    let rhs_ty = self.infer_expr_coerce(
659                        value,
660                        &Expectation::has_type(expected_ty),
661                        ExprIsRead::Yes,
662                    );
663                    self.infer_top_pat(target, rhs_ty, PatOrigin::DestructuringAssignment);
664                }
665                if is_destructuring_assignment && self.diverges.is_always() {
666                    // Ordinary assignments always return `()`, even when they diverge.
667                    // However, rustc lowers destructuring assignments into blocks, and blocks return `!` if they have no tail
668                    // expression and they diverge. Therefore, we have to do the same here, even though we don't lower destructuring
669                    // assignments into blocks.
670                    self.table.new_maybe_never_var(value.into())
671                } else {
672                    self.types.types.unit
673                }
674            }
675            Expr::Index { base, index } => {
676                let base_t = self.infer_expr_no_expect(*base, ExprIsRead::Yes);
677                let idx_t = self.infer_expr_no_expect(*index, ExprIsRead::Yes);
678
679                let base_t = self.structurally_resolve_type((*base).into(), base_t);
680                match self.lookup_indexing(tgt_expr, *base, *index, base_t, idx_t) {
681                    Some((trait_index_ty, trait_element_ty)) => {
682                        // two-phase not needed because index_ty is never mutable
683                        self.demand_coerce(
684                            *index,
685                            idx_t,
686                            trait_index_ty,
687                            AllowTwoPhase::No,
688                            ExprIsRead::Yes,
689                        );
690                        self.table.select_obligations_where_possible();
691                        trait_element_ty
692                    }
693                    None => {
694                        self.push_diagnostic(InferenceDiagnostic::CannotIndexInto {
695                            expr: tgt_expr,
696                            found: base_t.store(),
697                        });
698                        self.types.types.error
699                    }
700                }
701            }
702            Expr::Tuple { exprs, .. } => {
703                let mut tys = match expected
704                    .only_has_type(&mut self.table)
705                    .map(|t| self.table.try_structurally_resolve_type(tgt_expr.into(), t).kind())
706                {
707                    Some(TyKind::Tuple(substs)) => substs
708                        .iter()
709                        .chain(repeat_with(|| self.table.next_ty_var(Span::Dummy)))
710                        .take(exprs.len())
711                        .collect::<Vec<_>>(),
712                    _ => exprs.iter().map(|&expr| self.table.next_ty_var(expr.into())).collect(),
713                };
714
715                for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
716                    *ty =
717                        self.infer_expr_coerce(*expr, &Expectation::has_type(*ty), ExprIsRead::Yes);
718                }
719
720                Ty::new_tup(self.interner(), &tys)
721            }
722            Expr::Array(Array::ElementList { elements }) => {
723                self.infer_array_elements_expr(elements, expected, tgt_expr)
724            }
725            Expr::Array(Array::Repeat { initializer, repeat }) => {
726                self.infer_array_repeat_expr(*initializer, *repeat, expected, tgt_expr)
727            }
728            Expr::Literal(lit) => literal_ty(
729                self.interner(),
730                lit,
731                |_| {
732                    let expected_ty = expected.to_option(&self.table);
733                    tracing::debug!(?expected_ty);
734                    let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
735                        Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
736                        Some(TyKind::Char) => Some(self.types.types.u8),
737                        Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
738                            Some(self.types.types.usize)
739                        }
740                        _ => None,
741                    };
742                    opt_ty.unwrap_or_else(|| self.table.next_int_var())
743                },
744                |_| {
745                    let expected_ty = expected.to_option(&self.table);
746                    let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
747                        Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
748                        Some(TyKind::Char) => Some(self.types.types.u8),
749                        Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
750                            Some(self.types.types.usize)
751                        }
752                        _ => None,
753                    };
754                    opt_ty.unwrap_or_else(|| self.table.next_int_var())
755                },
756                |_| {
757                    let opt_ty = expected
758                        .to_option(&self.table)
759                        .filter(|ty| matches!(ty.kind(), TyKind::Float(_)));
760                    opt_ty.unwrap_or_else(|| self.table.next_float_var())
761                },
762            ),
763            Expr::Underscore => {
764                // Underscore expression is an error, we render a specialized diagnostic
765                // to let the user know what type is expected though.
766                let expected = expected.to_option(&self.table).unwrap_or_else(|| self.err_ty());
767                self.push_diagnostic(InferenceDiagnostic::TypedHole {
768                    expr: tgt_expr,
769                    expected: expected.store(),
770                });
771                expected
772            }
773            Expr::OffsetOf(_) => self.types.types.usize,
774            Expr::InlineAsm(asm) => {
775                let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| {
776                    let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes);
777
778                    // If this is an input value, we require its type to be fully resolved
779                    // at this point. This allows us to provide helpful coercions which help
780                    // pass the type candidate list in a later pass.
781                    //
782                    // We don't require output types to be resolved at this point, which
783                    // allows them to be inferred based on how they are used later in the
784                    // function.
785                    if is_input {
786                        let ty = this.structurally_resolve_type(expr.into(), ty);
787                        match ty.kind() {
788                            TyKind::FnDef(def, parameters) => {
789                                let fnptr_ty = Ty::new_fn_ptr(
790                                    this.interner(),
791                                    this.interner()
792                                        .fn_sig(def)
793                                        .instantiate(this.interner(), parameters)
794                                        .skip_norm_wip(),
795                                );
796                                _ = this.coerce(
797                                    expr,
798                                    ty,
799                                    fnptr_ty,
800                                    AllowTwoPhase::No,
801                                    ExprIsRead::Yes,
802                                );
803                            }
804                            TyKind::Ref(_, base_ty, mutbl) => {
805                                let ptr_ty = Ty::new_ptr(this.interner(), base_ty, mutbl);
806                                _ = this.coerce(
807                                    expr,
808                                    ty,
809                                    ptr_ty,
810                                    AllowTwoPhase::No,
811                                    ExprIsRead::Yes,
812                                );
813                            }
814                            _ => {}
815                        }
816                    }
817                };
818
819                let mut diverge = asm.options.contains(AsmOptions::NORETURN);
820                asm.operands.iter().for_each(|(_, operand)| match *operand {
821                    AsmOperand::In { expr, .. } => check_expr_asm_operand(self, expr, true),
822                    AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
823                        check_expr_asm_operand(self, expr, false)
824                    }
825                    AsmOperand::Out { expr: None, .. } => (),
826                    AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
827                        check_expr_asm_operand(self, in_expr, true);
828                        if let Some(out_expr) = out_expr {
829                            check_expr_asm_operand(self, out_expr, false);
830                        }
831                    }
832                    AsmOperand::Label(expr) => {
833                        let previous_diverges = self.diverges;
834                        // The label blocks should have unit return value or diverge.
835                        let ty = self.infer_expr_inner(
836                            expr,
837                            &Expectation::HasType(self.types.types.unit),
838                            ExprIsRead::No,
839                        );
840                        if !ty.is_never() {
841                            _ = self.demand_suptype(expr.into(), self.types.types.unit, ty);
842                            diverge = false;
843                        }
844                        // We need this to avoid false unreachable warning when a label diverges.
845                        self.diverges = previous_diverges;
846                    }
847                    AsmOperand::Const(expr) => {
848                        self.infer_expr(expr, &Expectation::None, ExprIsRead::No);
849                    }
850                    // FIXME: `sym` should report for things that are not functions or statics.
851                    AsmOperand::Sym(_) => (),
852                });
853                if diverge || asm.kind == InlineAsmKind::NakedAsm {
854                    self.types.types.never
855                } else {
856                    self.types.types.unit
857                }
858            }
859            Expr::IncludeBytes => {
860                let len = self.table.next_const_var(Span::Dummy);
861                let arr = Ty::new_array_with_const_len(self.interner(), self.types.types.u8, len);
862                Ty::new_ref(self.interner(), self.types.regions.statik, arr, Mutability::Not)
863            }
864        };
865        let ty = self.insert_type_vars_shallow(ty);
866        self.write_expr_ty(tgt_expr, ty);
867        if self.table.resolve_vars_with_obligations(ty).is_never()
868            && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read)
869        {
870            // Any expression that produces a value of type `!` must have diverged
871            self.diverges = Diverges::Always;
872        }
873        ty
874    }
875
876    fn infer_ref_expr(
877        &mut self,
878        rawness: Rawness,
879        mutbl: Mutability,
880        oprnd: ExprId,
881        expected: &Expectation<'db>,
882        expr: ExprId,
883    ) -> Ty<'db> {
884        let hint = expected.only_has_type(&mut self.table).map_or(Expectation::None, |ty| {
885            match self.table.resolve_vars_with_obligations(ty).kind() {
886                TyKind::Ref(_, ty, _) | TyKind::RawPtr(ty, _) => {
887                    if self.is_syntactic_place_expr(oprnd) {
888                        // Places may legitimately have unsized types.
889                        // For example, dereferences of a wide pointer and
890                        // the last field of a struct can be unsized.
891                        Expectation::has_type(ty)
892                    } else {
893                        Expectation::rvalue_hint(self, ty)
894                    }
895                }
896                _ => Expectation::None,
897            }
898        });
899        let ty = self.infer_expr_inner(oprnd, &hint, ExprIsRead::No);
900
901        match rawness {
902            Rawness::RawPtr => Ty::new_ptr(self.interner(), ty, mutbl),
903            Rawness::Ref => {
904                // Note: at this point, we cannot say what the best lifetime
905                // is to use for resulting pointer. We want to use the
906                // shortest lifetime possible so as to avoid spurious borrowck
907                // errors. Moreover, the longest lifetime will depend on the
908                // precise details of the value whose address is being taken
909                // (and how long it is valid), which we don't know yet until
910                // type inference is complete.
911                //
912                // Therefore, here we simply generate a region variable. The
913                // region inferencer will then select a suitable value.
914                // Finally, borrowck will infer the value of the region again,
915                // this time with enough precision to check that the value
916                // whose address was taken can actually be made to live as long
917                // as it needs to live.
918                let region = self.table.next_region_var(expr.into());
919                Ty::new_ref(self.interner(), region, ty, mutbl)
920            }
921        }
922    }
923
924    fn infer_await_expr(&mut self, expr: ExprId, awaitee: ExprId) -> Ty<'db> {
925        let awaitee_ty = self.infer_expr_no_expect(awaitee, ExprIsRead::Yes);
926        let (Some(into_future), Some(into_future_output)) =
927            (self.lang_items.IntoFuture, self.lang_items.IntoFutureOutput)
928        else {
929            return self.types.types.error;
930        };
931        self.table.register_bound(awaitee_ty, into_future, ObligationCause::new(expr));
932        self.table.try_structurally_resolve_type(
933            expr.into(),
934            Ty::new_projection(self.interner(), into_future_output.into(), [awaitee_ty]),
935        )
936    }
937
938    fn infer_record_expr(
939        &mut self,
940        expr: ExprId,
941        expected: &Expectation<'db>,
942        path: &Path,
943        fields: &[RecordLitField],
944        base_expr: RecordSpread,
945    ) -> Ty<'db> {
946        // Find the relevant variant
947        let (adt_ty, Some(variant)) = self.resolve_variant(expr.into(), path, false) else {
948            // FIXME: Emit an error.
949            for field in fields {
950                self.infer_expr_no_expect(field.expr, ExprIsRead::Yes);
951            }
952
953            return self.types.types.error;
954        };
955        self.write_variant_resolution(expr.into(), variant);
956
957        // Prohibit struct expressions when non-exhaustive flag is set.
958        if self.has_applicable_non_exhaustive(variant.into()) {
959            self.push_diagnostic(InferenceDiagnostic::NonExhaustiveRecordExpr { expr });
960        }
961
962        self.check_record_expr_fields(adt_ty, expected, expr, variant, fields, base_expr);
963
964        self.require_type_is_sized(adt_ty, expr.into());
965        adt_ty
966    }
967
968    fn check_record_expr_fields(
969        &mut self,
970        adt_ty: Ty<'db>,
971        expected: &Expectation<'db>,
972        expr: ExprId,
973        variant: VariantId,
974        hir_fields: &[RecordLitField],
975        base_expr: RecordSpread,
976    ) {
977        let interner = self.interner();
978
979        let adt_ty = self.table.try_structurally_resolve_type(expr.into(), adt_ty);
980        let adt_ty_hint = expected.only_has_type(&mut self.table).and_then(|expected| {
981            self.infcx()
982                .fudge_inference_if_ok(|| {
983                    let mut ocx = ObligationCtxt::new(self.infcx());
984                    ocx.sup(&ObligationCause::new(expr), self.table.param_env, expected, adt_ty)?;
985                    if !ocx.try_evaluate_obligations().is_empty() {
986                        return Err(TypeError::Mismatch);
987                    }
988                    Ok(self.resolve_vars_if_possible(adt_ty))
989                })
990                .ok()
991        });
992        if let Some(adt_ty_hint) = adt_ty_hint {
993            // re-link the variables that the fudging above can create.
994            _ = self.demand_eqtype(expr.into(), adt_ty_hint, adt_ty);
995        }
996
997        let TyKind::Adt(adt, args) = adt_ty.kind() else {
998            never!("non-ADT passed to check_struct_expr_fields");
999            return;
1000        };
1001        let adt_id = adt.def_id();
1002
1003        let variant_fields = variant.fields(self.db);
1004        let variant_field_tys = self.db.field_types(variant);
1005        let variant_field_vis = VariantFields::field_visibilities(self.db, variant);
1006        let mut remaining_fields = variant_fields
1007            .fields()
1008            .iter()
1009            .map(|(i, field)| (field.name.clone(), i))
1010            .collect::<FxHashMap<_, _>>();
1011
1012        let mut seen_fields = FxHashMap::default();
1013
1014        // Type-check each field.
1015        for field in hir_fields {
1016            let name = &field.name;
1017            let field_type = if let Some(i) = remaining_fields.remove(name) {
1018                seen_fields.insert(name, i);
1019
1020                if !self.resolver.is_visible(self.db, variant_field_vis[i]) {
1021                    self.push_diagnostic(InferenceDiagnostic::NoSuchField {
1022                        field: field.expr.into(),
1023                        private: Some(i),
1024                        variant,
1025                    });
1026                }
1027
1028                variant_field_tys[i].ty().instantiate(interner, args).skip_norm_wip()
1029            } else {
1030                if let Some(field_idx) = seen_fields.get(&name) {
1031                    self.push_diagnostic(InferenceDiagnostic::DuplicateField {
1032                        field: field.expr.into(),
1033                        variant,
1034                    });
1035                    variant_field_tys[*field_idx].ty().instantiate(interner, args).skip_norm_wip()
1036                } else {
1037                    self.push_diagnostic(InferenceDiagnostic::NoSuchField {
1038                        field: field.expr.into(),
1039                        private: None,
1040                        variant,
1041                    });
1042                    self.types.types.error
1043                }
1044            };
1045
1046            // Check that the expected field type is WF. Otherwise, we emit no use-site error
1047            // in the case of coercions for non-WF fields, which leads to incorrect error
1048            // tainting. See issue #126272.
1049            self.table.register_wf_obligation(field_type.into(), ObligationCause::new(field.expr));
1050
1051            // Make sure to give a type to the field even if there's
1052            // an error, so we can continue type-checking.
1053            self.infer_expr_coerce(field.expr, &Expectation::has_type(field_type), ExprIsRead::Yes);
1054        }
1055
1056        // Make sure the programmer specified correct number of fields.
1057        if matches!(adt_id, AdtId::UnionId(_)) && hir_fields.len() != 1 {
1058            self.push_diagnostic(InferenceDiagnostic::UnionExprMustHaveExactlyOneField { expr });
1059        }
1060
1061        match base_expr {
1062            RecordSpread::FieldDefaults => {
1063                let mut missing_mandatory_fields = Vec::new();
1064                let mut missing_optional_fields = Vec::new();
1065                for (field_idx, field) in variant_fields.fields().iter() {
1066                    if remaining_fields.remove(&field.name).is_some() {
1067                        if field.default_value.is_none() {
1068                            missing_mandatory_fields.push(field_idx);
1069                        } else {
1070                            missing_optional_fields.push(field_idx);
1071                        }
1072                    }
1073                }
1074                if !missing_mandatory_fields.is_empty() {
1075                    // FIXME: Emit an error: missing fields.
1076                }
1077            }
1078            RecordSpread::Expr(base_expr) => {
1079                // FIXME: We are currently creating two branches here in order to maintain
1080                // consistency. But they should be merged as much as possible.
1081                if self.features.type_changing_struct_update {
1082                    if matches!(adt_id, AdtId::StructId(_)) {
1083                        // Make some fresh generic parameters for our ADT type.
1084                        let fresh_args = self.table.fresh_args_for_item(expr.into(), adt_id.into());
1085                        // We do subtyping on the FRU fields first, so we can
1086                        // learn exactly what types we expect the base expr
1087                        // needs constrained to be compatible with the struct
1088                        // type we expect from the expectation value.
1089                        for (field_idx, field) in variant_fields.fields().iter() {
1090                            let fru_ty = variant_field_tys[field_idx]
1091                                .ty()
1092                                .instantiate(interner, fresh_args)
1093                                .skip_norm_wip();
1094                            if remaining_fields.remove(&field.name).is_some() {
1095                                let target_ty = variant_field_tys[field_idx]
1096                                    .ty()
1097                                    .instantiate(interner, args)
1098                                    .skip_norm_wip();
1099                                let cause = ObligationCause::new(expr);
1100                                match self.table.at(&cause).sup(target_ty, fru_ty) {
1101                                    Ok(InferOk { obligations, value: () }) => {
1102                                        self.table.register_predicates(obligations)
1103                                    }
1104                                    Err(_) => {
1105                                        never!(
1106                                            "subtyping remaining fields of type changing FRU \
1107                                                failed: {target_ty:?} != {fru_ty:?}: {:?}",
1108                                            field.name,
1109                                        );
1110                                    }
1111                                }
1112                            }
1113                        }
1114                        // The use of fresh args that we have subtyped against
1115                        // our base ADT type's fields allows us to guide inference
1116                        // along so that, e.g.
1117                        // ```
1118                        // MyStruct<'a, F1, F2, const C: usize> {
1119                        //     f: F1,
1120                        //     // Other fields that reference `'a`, `F2`, and `C`
1121                        // }
1122                        //
1123                        // let x = MyStruct {
1124                        //    f: 1usize,
1125                        //    ..other_struct
1126                        // };
1127                        // ```
1128                        // will have the `other_struct` expression constrained to
1129                        // `MyStruct<'a, _, F2, C>`, as opposed to just `_`...
1130                        // This is important to allow coercions to happen in
1131                        // `other_struct` itself. See `coerce-in-base-expr.rs`.
1132                        let fresh_base_ty = Ty::new_adt(self.interner(), adt_id, fresh_args);
1133                        self.infer_expr_suptype_coerce_never(
1134                            base_expr,
1135                            &Expectation::has_type(self.resolve_vars_if_possible(fresh_base_ty)),
1136                            ExprIsRead::Yes,
1137                        );
1138                    } else {
1139                        // Check the base_expr, regardless of a bad expected adt_ty, so we can get
1140                        // type errors on that expression, too.
1141                        self.infer_expr_no_expect(base_expr, ExprIsRead::Yes);
1142                        self.push_diagnostic(
1143                            InferenceDiagnostic::FunctionalRecordUpdateOnNonStruct { base_expr },
1144                        );
1145                    }
1146                } else {
1147                    self.infer_expr_suptype_coerce_never(
1148                        base_expr,
1149                        &Expectation::has_type(adt_ty),
1150                        ExprIsRead::Yes,
1151                    );
1152                    if !matches!(adt_id, AdtId::StructId(_)) {
1153                        self.push_diagnostic(
1154                            InferenceDiagnostic::FunctionalRecordUpdateOnNonStruct { base_expr },
1155                        );
1156                    }
1157                }
1158            }
1159            RecordSpread::None => {
1160                if !matches!(adt_id, AdtId::UnionId(_))
1161                    && !remaining_fields.is_empty()
1162                    //~ non_exhaustive already reported, which will only happen for extern modules
1163                    && !self.has_applicable_non_exhaustive(adt_id.into())
1164                {
1165                    debug!(?remaining_fields);
1166
1167                    // FIXME: Emit an error: missing fields.
1168                }
1169            }
1170        }
1171    }
1172
1173    fn demand_scrutinee_type(
1174        &mut self,
1175        scrut: ExprId,
1176        contains_ref_bindings: bool,
1177        no_arms: bool,
1178        scrutinee_is_read: ExprIsRead,
1179    ) -> Ty<'db> {
1180        // Not entirely obvious: if matches may create ref bindings, we want to
1181        // use the *precise* type of the scrutinee, *not* some supertype, as
1182        // the "scrutinee type" (issue #23116).
1183        //
1184        // arielb1 [writes here in this comment thread][c] that there
1185        // is certainly *some* potential danger, e.g., for an example
1186        // like:
1187        //
1188        // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
1189        //
1190        // ```
1191        // let Foo(x) = f()[0];
1192        // ```
1193        //
1194        // Then if the pattern matches by reference, we want to match
1195        // `f()[0]` as a lexpr, so we can't allow it to be
1196        // coerced. But if the pattern matches by value, `f()[0]` is
1197        // still syntactically a lexpr, but we *do* want to allow
1198        // coercions.
1199        //
1200        // However, *likely* we are ok with allowing coercions to
1201        // happen if there are no explicit ref mut patterns - all
1202        // implicit ref mut patterns must occur behind a reference, so
1203        // they will have the "correct" variance and lifetime.
1204        //
1205        // This does mean that the following pattern would be legal:
1206        //
1207        // ```
1208        // struct Foo(Bar);
1209        // struct Bar(u32);
1210        // impl Deref for Foo {
1211        //     type Target = Bar;
1212        //     fn deref(&self) -> &Bar { &self.0 }
1213        // }
1214        // impl DerefMut for Foo {
1215        //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
1216        // }
1217        // fn foo(x: &mut Foo) {
1218        //     {
1219        //         let Bar(z): &mut Bar = x;
1220        //         *z = 42;
1221        //     }
1222        //     assert_eq!(foo.0.0, 42);
1223        // }
1224        // ```
1225        //
1226        // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
1227        // is problematic as the HIR is being scraped, but ref bindings may be
1228        // implicit after #42640. We need to make sure that pat_adjustments
1229        // (once introduced) is populated by the time we get here.
1230        //
1231        // See #44848.
1232        if contains_ref_bindings || no_arms {
1233            self.infer_expr_no_expect(scrut, scrutinee_is_read)
1234        } else {
1235            // ...but otherwise we want to use any supertype of the
1236            // scrutinee. This is sort of a workaround, see note (*) in
1237            // `check_pat` for some details.
1238            let scrut_ty = self.table.next_ty_var(scrut.into());
1239            self.infer_expr_coerce_never(scrut, &Expectation::HasType(scrut_ty), scrutinee_is_read);
1240            scrut_ty
1241        }
1242    }
1243
1244    fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatIdPacked, scope_id: ExprId) -> Ty<'db> {
1245        let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, scope_id);
1246        let ty = match self.infer_path(path, id) {
1247            Some((_, ty)) => ty,
1248            None => {
1249                if path.mod_path().is_some_and(|mod_path| mod_path.is_ident() || mod_path.is_self())
1250                {
1251                    self.push_diagnostic(InferenceDiagnostic::UnresolvedIdent { id });
1252                }
1253                self.err_ty()
1254            }
1255        };
1256        self.resolver.reset_to_guard(g);
1257        ty
1258    }
1259
1260    fn infer_unop_expr(
1261        &mut self,
1262        unop: UnaryOp,
1263        oprnd: ExprId,
1264        expected: &Expectation<'db>,
1265        expr: ExprId,
1266    ) -> Ty<'db> {
1267        let expected_inner = match unop {
1268            UnaryOp::Not | UnaryOp::Neg => expected,
1269            UnaryOp::Deref => &Expectation::None,
1270        };
1271        let mut oprnd_t = self.infer_expr_inner(oprnd, expected_inner, ExprIsRead::Yes);
1272
1273        oprnd_t = self.structurally_resolve_type(oprnd.into(), oprnd_t);
1274        match unop {
1275            UnaryOp::Deref => {
1276                if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
1277                    oprnd_t = ty;
1278                } else {
1279                    self.push_diagnostic(InferenceDiagnostic::CannotBeDereferenced {
1280                        expr,
1281                        found: oprnd_t.store(),
1282                    });
1283                    oprnd_t = self.types.types.error;
1284                }
1285            }
1286            UnaryOp::Not => {
1287                let result = self.infer_user_unop(expr, oprnd_t, unop);
1288                // If it's builtin, we can reuse the type, this helps inference.
1289                if !(oprnd_t.is_integral() || oprnd_t.kind() == TyKind::Bool) {
1290                    oprnd_t = result;
1291                }
1292            }
1293            UnaryOp::Neg => {
1294                let result = self.infer_user_unop(expr, oprnd_t, unop);
1295                // If it's builtin, we can reuse the type, this helps inference.
1296                if !oprnd_t.is_numeric() {
1297                    oprnd_t = result;
1298                }
1299            }
1300        }
1301        oprnd_t
1302    }
1303
1304    fn infer_array_repeat_expr(
1305        &mut self,
1306        element: ExprId,
1307        count: ExprId,
1308        expected: &Expectation<'db>,
1309        expr: ExprId,
1310    ) -> Ty<'db> {
1311        let interner = self.interner();
1312        let count_ct = self.create_anon_const(count, self.types.types.usize, true);
1313        let count = self.table.try_structurally_resolve_const(count.into(), count_ct);
1314
1315        let uty = match expected {
1316            Expectation::HasType(uty) => uty.builtin_index(),
1317            _ => None,
1318        };
1319
1320        let t = match uty {
1321            Some(uty) => {
1322                self.infer_expr_coerce(element, &Expectation::has_type(uty), ExprIsRead::Yes);
1323                uty
1324            }
1325            None => {
1326                let ty = self.table.next_ty_var(element.into());
1327                self.infer_expr_suptype_coerce_never(
1328                    element,
1329                    &Expectation::has_type(ty),
1330                    ExprIsRead::Yes,
1331                );
1332                ty
1333            }
1334        };
1335
1336        // We defer checking whether the element type is `Copy` as it is possible to have
1337        // an inference variable as a repeat count and it seems unlikely that `Copy` would
1338        // have inference side effects required for type checking to succeed.
1339        // FIXME: Do it here like rustc.
1340        // self.deferred_repeat_expr_checks.borrow_mut().push((element, element_ty, count));
1341
1342        let ty = Ty::new_array_with_const_len(interner, t, count);
1343        self.table.register_wf_obligation(ty.into(), ObligationCause::new(expr));
1344        ty
1345    }
1346
1347    fn infer_array_elements_expr(
1348        &mut self,
1349        args: &[ExprId],
1350        expected: &Expectation<'db>,
1351        expr: ExprId,
1352    ) -> Ty<'db> {
1353        let element_ty = if !args.is_empty() {
1354            let coerce_to = expected
1355                .to_option(&self.table)
1356                .and_then(|uty| {
1357                    self.table
1358                        .resolve_vars_with_obligations(uty)
1359                        .builtin_index()
1360                        // Avoid using the original type variable as the coerce_to type, as it may resolve
1361                        // during the first coercion instead of being the LUB type.
1362                        .filter(|t| !self.table.resolve_vars_with_obligations(*t).is_ty_var())
1363                })
1364                .unwrap_or_else(|| self.table.next_ty_var(expr.into()));
1365            let mut coerce = CoerceMany::with_coercion_sites(coerce_to, args);
1366
1367            for &e in args {
1368                // FIXME: the element expectation should use
1369                // `try_structurally_resolve_and_adjust_for_branches` just like in `if` and `match`.
1370                // While that fixes nested coercion, it will break [some
1371                // code like this](https://github.com/rust-lang/rust/pull/140283#issuecomment-2958776528).
1372                // If we find a way to support recursive tuple coercion, this break can be avoided.
1373                let e_ty =
1374                    self.infer_expr_inner(e, &Expectation::has_type(coerce_to), ExprIsRead::Yes);
1375                let cause = ObligationCause::new(e);
1376                coerce.coerce(self, &cause, e, e_ty, ExprIsRead::Yes);
1377            }
1378            coerce.complete(self)
1379        } else {
1380            self.table.next_ty_var(expr.into())
1381        };
1382        let array_len = args.len() as u64;
1383        Ty::new_array(self.interner(), element_ty, array_len)
1384    }
1385
1386    pub(super) fn infer_return(&mut self, expr: ExprId) {
1387        let ret_ty = self
1388            .return_coercion
1389            .as_mut()
1390            .expect("infer_return called outside function body")
1391            .expected_ty();
1392        let return_expr_ty =
1393            self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1394        let mut coerce_many = self.return_coercion.take().unwrap();
1395        coerce_many.coerce(
1396            self,
1397            &ObligationCause::new(expr),
1398            expr,
1399            return_expr_ty,
1400            ExprIsRead::Yes,
1401        );
1402        self.return_coercion = Some(coerce_many);
1403    }
1404
1405    fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db> {
1406        match self.return_coercion {
1407            Some(_) => {
1408                if let Some(expr) = expr {
1409                    self.infer_return(expr);
1410                } else {
1411                    let mut coerce = self.return_coercion.take().unwrap();
1412                    coerce.coerce_forced_unit(
1413                        self,
1414                        ret,
1415                        &ObligationCause::new(ret),
1416                        true,
1417                        ExprIsRead::Yes,
1418                    );
1419                    self.return_coercion = Some(coerce);
1420                }
1421            }
1422            None => {
1423                self.push_diagnostic(InferenceDiagnostic::ReturnOutsideFunction {
1424                    expr: ret,
1425                    kind: ReturnKind::ReturnExpr,
1426                });
1427                if let Some(expr) = expr {
1428                    self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1429                }
1430            }
1431        }
1432        self.types.types.never
1433    }
1434
1435    fn infer_expr_become(&mut self, tgt_expr: ExprId, expr: ExprId) -> Ty<'db> {
1436        match &self.return_coercion {
1437            Some(return_coercion) => {
1438                let ret_ty = return_coercion.expected_ty();
1439
1440                let call_expr_ty =
1441                    self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1442
1443                // NB: this should *not* coerce.
1444                //     tail calls don't support any coercions except lifetimes ones (like `&'static u8 -> &'a u8`).
1445                _ = self.demand_eqtype(expr.into(), call_expr_ty, ret_ty);
1446            }
1447            None => {
1448                self.push_diagnostic(InferenceDiagnostic::ReturnOutsideFunction {
1449                    expr: tgt_expr,
1450                    kind: ReturnKind::BecomeExpr,
1451                });
1452                self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1453            }
1454        }
1455
1456        self.types.types.never
1457    }
1458
1459    fn infer_block(
1460        &mut self,
1461        expr: ExprId,
1462        statements: &[Statement],
1463        tail: Option<ExprId>,
1464        label: Option<LabelId>,
1465        expected: &Expectation<'db>,
1466    ) -> Ty<'db> {
1467        let prev_diverges = self.diverges;
1468        let coerce_ty = expected.coercion_target_type(&mut self.table, expr.into());
1469        let g = self.resolver.update_to_inner_scope(self.db, self.store_owner, expr);
1470
1471        let (ctxt, tail_expr_ty) =
1472            self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
1473                for stmt in statements {
1474                    match stmt {
1475                        Statement::Let { pat, type_ref, initializer, else_branch } => {
1476                            let decl_ty = type_ref
1477                                .as_ref()
1478                                .map(|&tr| this.make_ty(tr))
1479                                .unwrap_or_else(|| this.table.next_ty_var((*pat).into()));
1480
1481                            this.infer_let(
1482                                decl_ty,
1483                                *initializer,
1484                                *pat,
1485                                PatOrigin::LetStmt { has_else: else_branch.is_some() },
1486                            );
1487                            if let Some(expr) = else_branch {
1488                                let previous_diverges =
1489                                    mem::replace(&mut this.diverges, Diverges::Maybe);
1490                                this.infer_expr_coerce(
1491                                    *expr,
1492                                    &Expectation::HasType(this.types.types.never),
1493                                    ExprIsRead::Yes,
1494                                );
1495                                this.diverges = previous_diverges;
1496                            }
1497                        }
1498                        &Statement::Expr { expr, has_semi } => {
1499                            if has_semi {
1500                                this.infer_expr(expr, &Expectation::none(), ExprIsRead::Yes);
1501                            } else {
1502                                this.infer_expr_coerce(
1503                                    expr,
1504                                    &Expectation::HasType(this.types.types.unit),
1505                                    ExprIsRead::Yes,
1506                                );
1507                            }
1508                        }
1509                        Statement::Item(_) => (),
1510                    }
1511                }
1512
1513                // check the tail expression **without** holding the
1514                // `enclosing_breakables` lock below.
1515                tail.map(|expr| (expr, this.infer_expr_inner(expr, expected, ExprIsRead::Yes)))
1516            });
1517
1518        let mut coerce = ctxt.coerce.unwrap();
1519        if let Some((tail_expr, tail_expr_ty)) = tail_expr_ty {
1520            let cause = ObligationCause::new(tail_expr);
1521            coerce.coerce_inner(
1522                self,
1523                &cause,
1524                tail_expr,
1525                tail_expr_ty,
1526                false,
1527                false,
1528                ExprIsRead::Yes,
1529            );
1530        } else {
1531            // Subtle: if there is no explicit tail expression,
1532            // that is typically equivalent to a tail expression
1533            // of `()` -- except if the block diverges. In that
1534            // case, there is no value supplied from the tail
1535            // expression (assuming there are no other breaks,
1536            // this implies that the type of the block will be
1537            // `!`).
1538            //
1539            // #41425 -- label the implicit `()` as being the
1540            // "found type" here, rather than the "expected type".
1541            if !self.diverges.is_always() {
1542                coerce.coerce_forced_unit(
1543                    self,
1544                    expr,
1545                    &ObligationCause::new(expr),
1546                    false,
1547                    ExprIsRead::Yes,
1548                );
1549            }
1550        }
1551
1552        if ctxt.may_break {
1553            // If we can break from the block, then the block's exit is always reachable
1554            // (... as long as the entry is reachable) - regardless of the tail of the block.
1555            self.diverges = prev_diverges;
1556        }
1557
1558        self.resolver.reset_to_guard(g);
1559
1560        coerce.complete(self)
1561    }
1562
1563    fn infer_let(
1564        &mut self,
1565        decl_ty: Ty<'db>,
1566        initializer: Option<ExprId>,
1567        pat: PatId,
1568        pat_origin: PatOrigin,
1569    ) {
1570        if let Some(expr) = initializer {
1571            // If we have a subpattern that performs a read, we want to consider this
1572            // to diverge for compatibility to support something like `let x: () = *never_ptr;`.
1573            let target_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) {
1574                ExprIsRead::Yes
1575            } else {
1576                ExprIsRead::No
1577            };
1578            if self.contains_explicit_ref_binding(pat) {
1579                self.infer_expr(expr, &Expectation::has_type(decl_ty), target_is_read)
1580            } else {
1581                self.infer_expr_coerce(expr, &Expectation::has_type(decl_ty), target_is_read)
1582            };
1583        };
1584
1585        self.infer_top_pat(pat, decl_ty, pat_origin);
1586    }
1587
1588    fn lookup_field(
1589        &mut self,
1590        field_expr: ExprId,
1591        receiver_ty: Ty<'db>,
1592        name: &Name,
1593    ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment>, bool)> {
1594        let interner = self.interner();
1595        let mut autoderef = self.table.autoderef_with_tracking(receiver_ty, field_expr.into());
1596        let mut private_field = None;
1597        let res = autoderef.by_ref().find_map(|(derefed_ty, _)| {
1598            let (field_id, parameters) = match derefed_ty.kind() {
1599                TyKind::Tuple(substs) => {
1600                    return name.as_tuple_index().and_then(|idx| {
1601                        substs.as_slice().get(idx).copied().map(|ty| {
1602                            (
1603                                Either::Right(TupleFieldId {
1604                                    tuple: TupleId(
1605                                        self.tuple_field_accesses_rev.insert_full(substs).0 as u32,
1606                                    ),
1607                                    index: idx as u32,
1608                                }),
1609                                ty,
1610                            )
1611                        })
1612                    });
1613                }
1614                TyKind::Adt(adt, parameters) => match adt.def_id() {
1615                    hir_def::AdtId::StructId(s) => {
1616                        let local_id = s.fields(self.db).field(name)?;
1617                        let field = FieldId { parent: s.into(), local_id };
1618                        (field, parameters)
1619                    }
1620                    hir_def::AdtId::UnionId(u) => {
1621                        let local_id = u.fields(self.db).field(name)?;
1622                        let field = FieldId { parent: u.into(), local_id };
1623                        (field, parameters)
1624                    }
1625                    hir_def::AdtId::EnumId(_) => return None,
1626                },
1627                _ => return None,
1628            };
1629            let is_visible = VariantFields::field_visibilities(self.db, field_id.parent)
1630                [field_id.local_id]
1631                .is_visible_from(self.db, self.resolver.module());
1632            if !is_visible {
1633                if private_field.is_none() {
1634                    private_field = Some((field_id, parameters));
1635                }
1636                return None;
1637            }
1638            let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1639                .ty()
1640                .instantiate(interner, parameters)
1641                .skip_norm_wip();
1642            Some((Either::Left(field_id), ty))
1643        });
1644
1645        Some(match res {
1646            Some((field_id, ty)) => {
1647                let adjustments =
1648                    self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1649                let ty = self.process_remote_user_written_ty(ty);
1650
1651                (ty, field_id, adjustments, true)
1652            }
1653            None => {
1654                let (field_id, subst) = private_field?;
1655                let adjustments =
1656                    self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1657                let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1658                    .ty()
1659                    .instantiate(self.interner(), subst)
1660                    .skip_norm_wip();
1661                let ty = self.process_remote_user_written_ty(ty);
1662
1663                (ty, Either::Left(field_id), adjustments, false)
1664            }
1665        })
1666    }
1667
1668    fn infer_field_access(
1669        &mut self,
1670        tgt_expr: ExprId,
1671        receiver: ExprId,
1672        name: &Name,
1673        expected: &Expectation<'db>,
1674    ) -> Ty<'db> {
1675        // Field projections don't constitute reads.
1676        let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No);
1677        let receiver_ty = self.structurally_resolve_type(receiver.into(), receiver_ty);
1678
1679        if name.is_missing() {
1680            // Bail out early, don't even try to look up field. Also, we don't issue an unresolved
1681            // field diagnostic because this is a syntax error rather than a semantic error.
1682            return self.err_ty();
1683        }
1684
1685        match self.lookup_field(tgt_expr, receiver_ty, name) {
1686            Some((ty, field_id, adjustments, is_public)) => {
1687                self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1688                self.result.field_resolutions.insert(tgt_expr, field_id);
1689                if !is_public && let Either::Left(field) = field_id {
1690                    // FIXME: Merge this diagnostic into UnresolvedField?
1691                    self.push_diagnostic(InferenceDiagnostic::PrivateField {
1692                        expr: tgt_expr,
1693                        field,
1694                    });
1695                }
1696                ty
1697            }
1698            None => {
1699                // no field found, lets attempt to resolve it like a function so that IDE things
1700                // work out while people are typing
1701                let resolved = self.lookup_method_including_private(
1702                    receiver_ty,
1703                    name.clone(),
1704                    None,
1705                    receiver,
1706                    tgt_expr,
1707                );
1708                self.push_diagnostic(InferenceDiagnostic::UnresolvedField {
1709                    expr: tgt_expr,
1710                    receiver: receiver_ty.store(),
1711                    name: name.clone(),
1712                    method_with_same_name_exists: resolved.is_ok(),
1713                });
1714                match resolved {
1715                    Ok((func, _is_visible)) => {
1716                        self.check_method_call(tgt_expr, &[], func.sig, expected)
1717                    }
1718                    Err(_) => self.err_ty(),
1719                }
1720            }
1721        }
1722    }
1723
1724    fn instantiate_erroneous_method(&mut self, def_id: FunctionId) -> MethodCallee<'db> {
1725        // FIXME: Using fresh infer vars for the method args isn't optimal,
1726        // we can do better by going thorough the full probe/confirm machinery.
1727        let args = self.table.fresh_args_for_item(Span::Dummy, def_id.into());
1728        let sig = self
1729            .db
1730            .callable_item_signature(def_id.into())
1731            .instantiate(self.interner(), args)
1732            .skip_norm_wip();
1733        let sig = self.infcx().instantiate_binder_with_fresh_vars(
1734            Span::Dummy,
1735            BoundRegionConversionTime::FnCall,
1736            sig,
1737        );
1738        MethodCallee { def_id, args, sig }
1739    }
1740
1741    fn infer_method_call_as_call(
1742        &mut self,
1743        tgt_expr: ExprId,
1744        args: &[ExprId],
1745        callee_ty: Ty<'db>,
1746        param_tys: &[Ty<'db>],
1747        ret_ty: Ty<'db>,
1748        indices_to_skip: &[u32],
1749        is_varargs: bool,
1750        expected: &Expectation<'db>,
1751    ) -> Ty<'db> {
1752        if let TyKind::FnDef(def_id, args) = callee_ty.kind() {
1753            let def_id = match def_id.0 {
1754                CallableDefId::FunctionId(it) => it.into(),
1755                CallableDefId::StructId(it) => it.into(),
1756                CallableDefId::EnumVariantId(it) => it.loc(self.db).parent.into(),
1757            };
1758            self.add_required_obligations_for_value_path(tgt_expr.into(), def_id, args);
1759        }
1760
1761        self.check_call_arguments(
1762            tgt_expr,
1763            param_tys,
1764            ret_ty,
1765            expected,
1766            args,
1767            indices_to_skip,
1768            is_varargs,
1769            TupleArgumentsFlag::DontTupleArguments,
1770        );
1771        ret_ty
1772    }
1773
1774    fn infer_method_call(
1775        &mut self,
1776        tgt_expr: ExprId,
1777        receiver: ExprId,
1778        args: &[ExprId],
1779        method_name: &Name,
1780        generic_args: Option<&HirGenericArgs>,
1781        expected: &Expectation<'db>,
1782    ) -> Ty<'db> {
1783        let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes);
1784        let receiver_ty = self.table.try_structurally_resolve_type(receiver.into(), receiver_ty);
1785
1786        let resolved = self.lookup_method_including_private(
1787            receiver_ty,
1788            method_name.clone(),
1789            generic_args,
1790            receiver,
1791            tgt_expr,
1792        );
1793        match resolved {
1794            Ok((func, visible)) => {
1795                if !visible {
1796                    self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem {
1797                        id: tgt_expr.into(),
1798                        item: func.def_id.into(),
1799                    })
1800                }
1801                self.check_method_call(tgt_expr, args, func.sig, expected)
1802            }
1803            // Failed to resolve, report diagnostic and try to resolve as call to field access or
1804            // assoc function
1805            Err(_) => {
1806                let field_with_same_name_exists =
1807                    match self.lookup_field(tgt_expr, receiver_ty, method_name) {
1808                        Some((ty, field_id, adjustments, _public)) => {
1809                            self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1810                            self.result.field_resolutions.insert(tgt_expr, field_id);
1811                            Some(ty)
1812                        }
1813                        None => None,
1814                    };
1815
1816                let assoc_func_with_same_name =
1817                    self.with_method_resolution(tgt_expr.into(), receiver.into(), |ctx| {
1818                        if !matches!(
1819                            receiver_ty.kind(),
1820                            TyKind::Infer(InferTy::TyVar(_)) | TyKind::Error(_)
1821                        ) {
1822                            ctx.probe_for_name(
1823                                method_resolution::Mode::Path,
1824                                method_name.clone(),
1825                                receiver_ty,
1826                            )
1827                        } else {
1828                            Err(MethodError::ErrorReported)
1829                        }
1830                    });
1831                let assoc_func_with_same_name = match assoc_func_with_same_name {
1832                    Ok(method_resolution::Pick {
1833                        item: CandidateId::FunctionId(def_id), ..
1834                    })
1835                    | Err(MethodError::PrivateMatch(method_resolution::Pick {
1836                        item: CandidateId::FunctionId(def_id),
1837                        ..
1838                    })) => Some(self.instantiate_erroneous_method(def_id)),
1839                    _ => None,
1840                };
1841
1842                self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
1843                    expr: tgt_expr,
1844                    receiver: receiver_ty.store(),
1845                    name: method_name.clone(),
1846                    field_with_same_name: field_with_same_name_exists.map(|it| it.store()),
1847                    assoc_func_with_same_name: assoc_func_with_same_name.map(|it| it.def_id),
1848                });
1849
1850                let recovered = match assoc_func_with_same_name {
1851                    Some(it) => Some((
1852                        Ty::new_fn_def(
1853                            self.interner(),
1854                            CallableDefId::FunctionId(it.def_id).into(),
1855                            it.args,
1856                        ),
1857                        it.sig,
1858                        true,
1859                    )),
1860                    None => field_with_same_name_exists.and_then(|field_ty| {
1861                        let callable_sig = field_ty.callable_sig(self.interner())?;
1862                        let callable_sig = self.infcx().instantiate_binder_with_fresh_vars(
1863                            tgt_expr.into(),
1864                            BoundRegionConversionTime::FnCall,
1865                            callable_sig,
1866                        );
1867                        Some((field_ty, callable_sig, false))
1868                    }),
1869                };
1870                match recovered {
1871                    Some((callee_ty, sig, strip_first)) => self.infer_method_call_as_call(
1872                        tgt_expr,
1873                        args,
1874                        callee_ty,
1875                        sig.inputs_and_output.inputs().get(strip_first as usize..).unwrap_or(&[]),
1876                        sig.output(),
1877                        &[],
1878                        true,
1879                        expected,
1880                    ),
1881                    None => {
1882                        for &arg in args.iter() {
1883                            self.infer_expr_no_expect(arg, ExprIsRead::Yes);
1884                        }
1885                        self.err_ty()
1886                    }
1887                }
1888            }
1889        }
1890    }
1891
1892    fn check_method_call(
1893        &mut self,
1894        tgt_expr: ExprId,
1895        args: &[ExprId],
1896        sig: FnSig<'db>,
1897        expected: &Expectation<'db>,
1898    ) -> Ty<'db> {
1899        let param_tys = if !sig.inputs_and_output.inputs().is_empty() {
1900            &sig.inputs_and_output.inputs()[1..]
1901        } else {
1902            &[]
1903        };
1904        let ret_ty = sig.output();
1905
1906        self.check_call_arguments(
1907            tgt_expr,
1908            param_tys,
1909            ret_ty,
1910            expected,
1911            args,
1912            &[],
1913            sig.c_variadic(),
1914            TupleArgumentsFlag::DontTupleArguments,
1915        );
1916        ret_ty
1917    }
1918
1919    /// Generic function that factors out common logic from function calls,
1920    /// method calls and overloaded operators.
1921    pub(super) fn check_call_arguments(
1922        &mut self,
1923        call_expr: ExprId,
1924        // Types (as defined in the *signature* of the target function)
1925        formal_input_tys: &[Ty<'db>],
1926        formal_output: Ty<'db>,
1927        // Expected output from the parent expression or statement
1928        expectation: &Expectation<'db>,
1929        // The expressions for each provided argument
1930        provided_args: &[ExprId],
1931        skip_indices: &[u32],
1932        // Whether the function is variadic, for example when imported from C
1933        c_variadic: bool,
1934        // Whether the arguments have been bundled in a tuple (ex: closures)
1935        tuple_arguments: TupleArgumentsFlag,
1936    ) {
1937        let formal_input_tys: Vec<_> = formal_input_tys
1938            .iter()
1939            .map(|&ty| {
1940                let generalized_ty = self.table.next_ty_var(call_expr.into());
1941                let _ = self.demand_eqtype(call_expr.into(), ty, generalized_ty);
1942                generalized_ty
1943            })
1944            .collect();
1945
1946        // First, let's unify the formal method signature with the expectation eagerly.
1947        // We use this to guide coercion inference; it's output is "fudged" which means
1948        // any remaining type variables are assigned to new, unrelated variables. This
1949        // is because the inference guidance here is only speculative.
1950        let formal_output = self.table.resolve_vars_with_obligations(formal_output);
1951        let expected_input_tys: Option<Vec<_>> = expectation
1952            .only_has_type(&mut self.table)
1953            .and_then(|expected_output| {
1954                self.table
1955                    .infer_ctxt
1956                    .fudge_inference_if_ok(|| {
1957                        let mut ocx = ObligationCtxt::new(&self.table.infer_ctxt);
1958
1959                        // Attempt to apply a subtyping relationship between the formal
1960                        // return type (likely containing type variables if the function
1961                        // is polymorphic) and the expected return type.
1962                        // No argument expectations are produced if unification fails.
1963                        let origin = ObligationCause::new(call_expr);
1964                        ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?;
1965
1966                        for &ty in &formal_input_tys {
1967                            ocx.register_obligation(Obligation::new(
1968                                self.interner(),
1969                                ObligationCause::new(call_expr),
1970                                self.table.param_env,
1971                                ClauseKind::WellFormed(ty.into()),
1972                            ));
1973                        }
1974
1975                        if !ocx.try_evaluate_obligations().is_empty() {
1976                            return Err(TypeError::Mismatch);
1977                        }
1978
1979                        // Record all the argument types, with the args
1980                        // produced from the above subtyping unification.
1981                        Ok(Some(formal_input_tys.clone()))
1982                    })
1983                    .ok()
1984            })
1985            .unwrap_or_default();
1986
1987        // If the arguments should be wrapped in a tuple (ex: closures), unwrap them here
1988        let (formal_input_tys, expected_input_tys) = if tuple_arguments
1989            == TupleArgumentsFlag::TupleArguments
1990        {
1991            let tuple_type = self.structurally_resolve_type(call_expr.into(), formal_input_tys[0]);
1992            match tuple_type.kind() {
1993                // We expected a tuple and got a tuple
1994                TyKind::Tuple(arg_types) => {
1995                    // Argument length differs. The mismatch is reported below by the
1996                    // shared `MismatchedArgCount` push (with `is_fn_trait_call = true`,
1997                    // which the diagnostic surface renders as E0057).
1998                    let expected_input_tys = match expected_input_tys {
1999                        Some(expected_input_tys) => match expected_input_tys.first() {
2000                            Some(ty) => match ty.kind() {
2001                                TyKind::Tuple(tys) => Some(tys.iter().collect()),
2002                                _ => None,
2003                            },
2004                            None => None,
2005                        },
2006                        None => None,
2007                    };
2008                    (arg_types.to_vec(), expected_input_tys)
2009                }
2010                _ => {
2011                    // Otherwise, there's a mismatch, so clear out what we're expecting, and set
2012                    // our input types to err_args so we don't blow up the error messages
2013                    // FIXME: Emit an error.
2014                    (vec![self.types.types.error; provided_args.len()], None)
2015                }
2016            }
2017        } else {
2018            (formal_input_tys, expected_input_tys)
2019        };
2020
2021        // If there are no external expectations at the call site, just use the types from the function defn
2022        let expected_input_tys = if let Some(expected_input_tys) = expected_input_tys {
2023            assert_eq!(expected_input_tys.len(), formal_input_tys.len());
2024            expected_input_tys
2025        } else {
2026            formal_input_tys.clone()
2027        };
2028
2029        let minimum_input_count = expected_input_tys.len();
2030        let provided_arg_count = provided_args.len() - skip_indices.len();
2031
2032        // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
2033        // if the wrong number of arguments were supplied, we CAN'T be satisfied,
2034        // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function
2035        // otherwise, they need to be identical, because rust doesn't currently support variadic functions
2036        let args_count_matches = if c_variadic {
2037            provided_arg_count >= minimum_input_count
2038        } else {
2039            provided_arg_count == minimum_input_count
2040        };
2041
2042        if !args_count_matches {
2043            self.push_diagnostic(InferenceDiagnostic::MismatchedArgCount {
2044                call_expr,
2045                expected: expected_input_tys.len() + skip_indices.len(),
2046                found: provided_args.len(),
2047                is_fn_trait_call: tuple_arguments == TupleArgumentsFlag::TupleArguments,
2048            });
2049        }
2050
2051        // We introduce a helper function to demand that a given argument satisfy a given input
2052        // This is more complicated than just checking type equality, as arguments could be coerced
2053        // This version writes those types back so further type checking uses the narrowed types
2054        let demand_compatible = |this: &mut InferenceContext<'db>, idx| {
2055            let formal_input_ty: Ty<'db> = formal_input_tys[idx];
2056            let expected_input_ty: Ty<'db> = expected_input_tys[idx];
2057            let provided_arg = provided_args[idx];
2058
2059            debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
2060
2061            // We're on the happy path here, so we'll do a more involved check and write back types
2062            // To check compatibility, we'll do 3 things:
2063            // 1. Unify the provided argument with the expected type
2064            let expectation = Expectation::rvalue_hint(this, expected_input_ty);
2065
2066            let checked_ty = this.infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes);
2067
2068            // 2. Coerce to the most detailed type that could be coerced
2069            //    to, which is `expected_ty` if `rvalue_hint` returns an
2070            //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2071            let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
2072
2073            // Cause selection errors caused by resolving a single argument to point at the
2074            // argument and not the call. This lets us customize the span pointed to in the
2075            // fulfillment error to be more accurate.
2076            let coerced_ty = this.table.resolve_vars_with_obligations(coerced_ty);
2077
2078            let coerce_error = this
2079                .coerce(provided_arg, checked_ty, coerced_ty, AllowTwoPhase::Yes, ExprIsRead::Yes)
2080                .err();
2081            if coerce_error.is_some() {
2082                return Err((coerce_error, coerced_ty, checked_ty));
2083            }
2084
2085            // 3. Check if the formal type is actually equal to the checked one
2086            //    and register any such obligations for future type checks.
2087            let formal_ty_error = this
2088                .table
2089                .infer_ctxt
2090                .at(&ObligationCause::new(provided_arg), this.table.param_env)
2091                .eq(formal_input_ty, coerced_ty);
2092
2093            // If neither check failed, the types are compatible
2094            match formal_ty_error {
2095                Ok(InferOk { obligations, value: () }) => {
2096                    this.table.register_predicates(obligations);
2097                    Ok(())
2098                }
2099                Err(err) => Err((Some(err), coerced_ty, checked_ty)),
2100            }
2101        };
2102
2103        // Check the arguments.
2104        // We do this in a pretty awful way: first we type-check any arguments
2105        // that are not closures, then we type-check the closures. This is so
2106        // that we have more information about the types of arguments when we
2107        // type-check the functions. This isn't really the right way to do this.
2108        for check_closures in [false, true] {
2109            // More awful hacks: before we check argument types, try to do
2110            // an "opportunistic" trait resolution of any trait bounds on
2111            // the call. This helps coercions.
2112            if check_closures {
2113                self.table.select_obligations_where_possible();
2114            }
2115
2116            let mut skip_indices = skip_indices.iter().copied();
2117            // Check each argument, to satisfy the input it was provided for
2118            // Visually, we're traveling down the diagonal of the compatibility matrix
2119            for (idx, arg) in provided_args.iter().enumerate() {
2120                if skip_indices.clone().next() == Some(idx as u32) {
2121                    skip_indices.next();
2122                    continue;
2123                }
2124
2125                // For this check, we do *not* want to treat async coroutine closures (async blocks)
2126                // as proper closures. Doing so would regress type inference when feeding
2127                // the return value of an argument-position async block to an argument-position
2128                // closure wrapped in a block.
2129                // See <https://github.com/rust-lang/rust/issues/112225>.
2130                let is_closure = if let Expr::Closure { closure_kind, .. } = self.store[*arg] {
2131                    !matches!(closure_kind, ClosureKind::OldCoroutine(_))
2132                } else {
2133                    false
2134                };
2135                if is_closure != check_closures {
2136                    continue;
2137                }
2138
2139                if idx >= minimum_input_count {
2140                    // Make sure we've checked this expr at least once.
2141                    self.infer_expr_no_expect(*arg, ExprIsRead::Yes);
2142                    continue;
2143                }
2144
2145                if let Err((_error, expected, found)) = demand_compatible(self, idx)
2146                    && args_count_matches
2147                {
2148                    // Don't report type mismatches if there is a mismatch in args count.
2149                    self.emit_type_mismatch((*arg).into(), expected, found);
2150                }
2151            }
2152        }
2153
2154        if !args_count_matches {}
2155    }
2156
2157    pub(super) fn with_breakable_ctx<T>(
2158        &mut self,
2159        kind: BreakableKind,
2160        ty: Option<Ty<'db>>,
2161        label: Option<LabelId>,
2162        cb: impl FnOnce(&mut Self) -> T,
2163    ) -> (BreakableContext<'db>, T) {
2164        self.breakables.push({
2165            BreakableContext { kind, may_break: false, coerce: ty.map(CoerceMany::new), label }
2166        });
2167        let res = cb(self);
2168        let ctx = self.breakables.pop().expect("breakable stack broken");
2169        (ctx, res)
2170    }
2171}
2172
2173/// Controls whether the arguments are tupled. This is used for the call
2174/// operator.
2175///
2176/// Tupling means that all call-side arguments are packed into a tuple and
2177/// passed as a single parameter. For example, if tupling is enabled, this
2178/// function:
2179/// ```
2180/// fn f(x: (isize, isize)) {}
2181/// ```
2182/// Can be called as:
2183/// ```ignore UNSOLVED (can this be done in user code?)
2184/// # fn f(x: (isize, isize)) {}
2185/// f(1, 2);
2186/// ```
2187/// Instead of:
2188/// ```
2189/// # fn f(x: (isize, isize)) {}
2190/// f((1, 2));
2191/// ```
2192#[derive(Copy, Clone, Eq, PartialEq)]
2193pub(super) enum TupleArgumentsFlag {
2194    DontTupleArguments,
2195    TupleArguments,
2196}