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    FieldId, GenericDefId, ItemContainerId, Lookup, TupleFieldId, TupleId,
8    expr_store::path::{GenericArgs as HirGenericArgs, Path},
9    hir::{
10        Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId,
11        LabelId, Literal, Pat, PatId, Statement, UnaryOp,
12    },
13    resolver::ValueNs,
14};
15use hir_def::{FunctionId, hir::ClosureKind};
16use hir_expand::name::Name;
17use rustc_ast_ir::Mutability;
18use rustc_type_ir::{
19    CoroutineArgs, CoroutineArgsParts, InferTy, Interner,
20    inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _},
21};
22use syntax::ast::RangeOp;
23use tracing::debug;
24
25use crate::{
26    Adjust, Adjustment, CallableDefId, DeclContext, DeclOrigin, Rawness,
27    autoderef::InferenceContextAutoderef,
28    consteval,
29    db::InternedCoroutine,
30    generics::generics,
31    infer::{
32        AllowTwoPhase, BreakableKind, coerce::CoerceMany, find_continuable,
33        pat::contains_explicit_ref_binding,
34    },
35    lower::{GenericPredicates, lower_mutability},
36    method_resolution::{self, CandidateId, MethodCallee, MethodError},
37    next_solver::{
38        ErrorGuaranteed, FnSig, GenericArgs, TraitRef, Ty, TyKind, TypeError,
39        infer::{
40            BoundRegionConversionTime, InferOk,
41            traits::{Obligation, ObligationCause},
42        },
43        obligation_ctxt::ObligationCtxt,
44        util::clauses_as_obligations,
45    },
46    traits::FnTrait,
47};
48
49use super::{
50    BreakableContext, Diverges, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch,
51    cast::CastCheck, find_breakable,
52};
53
54#[derive(Clone, Copy, PartialEq, Eq)]
55pub(crate) enum ExprIsRead {
56    Yes,
57    No,
58}
59
60impl<'db> InferenceContext<'_, 'db> {
61    pub(crate) fn infer_expr(
62        &mut self,
63        tgt_expr: ExprId,
64        expected: &Expectation<'db>,
65        is_read: ExprIsRead,
66    ) -> Ty<'db> {
67        let ty = self.infer_expr_inner(tgt_expr, expected, is_read);
68        if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
69            let could_unify = self.unify(ty, expected_ty);
70            if !could_unify {
71                self.result
72                    .type_mismatches
73                    .get_or_insert_default()
74                    .insert(tgt_expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
75            }
76        }
77        ty
78    }
79
80    pub(crate) fn infer_expr_no_expect(
81        &mut self,
82        tgt_expr: ExprId,
83        is_read: ExprIsRead,
84    ) -> Ty<'db> {
85        self.infer_expr_inner(tgt_expr, &Expectation::None, is_read)
86    }
87
88    /// Infer type of expression with possibly implicit coerce to the expected type.
89    /// Return the type after possible coercion.
90    pub(super) fn infer_expr_coerce(
91        &mut self,
92        expr: ExprId,
93        expected: &Expectation<'db>,
94        is_read: ExprIsRead,
95    ) -> Ty<'db> {
96        let ty = self.infer_expr_inner(expr, expected, is_read);
97        if let Some(target) = expected.only_has_type(&mut self.table) {
98            match self.coerce(expr.into(), ty, target, AllowTwoPhase::No, is_read) {
99                Ok(res) => res,
100                Err(_) => {
101                    self.result
102                        .type_mismatches
103                        .get_or_insert_default()
104                        .insert(expr.into(), TypeMismatch { expected: target, actual: ty });
105                    target
106                }
107            }
108        } else {
109            ty
110        }
111    }
112
113    /// Whether this expression constitutes a read of value of the type that
114    /// it evaluates to.
115    ///
116    /// This is used to determine if we should consider the block to diverge
117    /// if the expression evaluates to `!`, and if we should insert a `NeverToAny`
118    /// coercion for values of type `!`.
119    ///
120    /// This function generally returns `false` if the expression is a place
121    /// expression and the *parent* expression is the scrutinee of a match or
122    /// the pointee of an `&` addr-of expression, since both of those parent
123    /// expressions take a *place* and not a value.
124    pub(super) fn expr_guaranteed_to_constitute_read_for_never(
125        &mut self,
126        expr: ExprId,
127        is_read: ExprIsRead,
128    ) -> bool {
129        // rustc does the place expr check first, but since we are feeding
130        // readness of the `expr` as a given value, we just can short-circuit
131        // the place expr check if it's true(see codes and comments below)
132        if is_read == ExprIsRead::Yes {
133            return true;
134        }
135
136        // We only care about place exprs. Anything else returns an immediate
137        // which would constitute a read. We don't care about distinguishing
138        // "syntactic" place exprs since if the base of a field projection is
139        // not a place then it would've been UB to read from it anyways since
140        // that constitutes a read.
141        if !self.is_syntactic_place_expr(expr) {
142            return true;
143        }
144
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        is_read == ExprIsRead::Yes
152    }
153
154    /// Whether this pattern constitutes a read of value of the scrutinee that
155    /// it is matching against. This is used to determine whether we should
156    /// perform `NeverToAny` coercions.
157    fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
158        match &self.body[pat] {
159            // Does not constitute a read.
160            Pat::Wild => false,
161
162            // This is unnecessarily restrictive when the pattern that doesn't
163            // constitute a read is unreachable.
164            //
165            // For example `match *never_ptr { value => {}, _ => {} }` or
166            // `match *never_ptr { _ if false => {}, value => {} }`.
167            //
168            // It is however fine to be restrictive here; only returning `true`
169            // can lead to unsoundness.
170            Pat::Or(subpats) => {
171                subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(*pat))
172            }
173
174            // All of these constitute a read, or match on something that isn't `!`,
175            // which would require a `NeverToAny` coercion.
176            Pat::Bind { .. }
177            | Pat::TupleStruct { .. }
178            | Pat::Path(_)
179            | Pat::Tuple { .. }
180            | Pat::Box { .. }
181            | Pat::Ref { .. }
182            | Pat::Lit(_)
183            | Pat::Range { .. }
184            | Pat::Slice { .. }
185            | Pat::ConstBlock(_)
186            | Pat::Record { .. }
187            | Pat::Missing => true,
188            Pat::Expr(_) => unreachable!(
189                "we don't call pat_guaranteed_to_constitute_read_for_never() with assignments"
190            ),
191        }
192    }
193
194    /// Checks if the pattern contains any `ref` or `ref mut` bindings, and if
195    /// yes whether it contains mutable or just immutables ones.
196    //
197    // FIXME(tschottdorf): this is problematic as the HIR is being scraped, but
198    // ref bindings are be implicit after #42640 (default match binding modes). See issue #44848.
199    fn contains_explicit_ref_binding(&self, pat: PatId) -> bool {
200        if let Pat::Bind { id, .. } = self.body[pat]
201            && matches!(self.body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
202        {
203            return true;
204        }
205
206        let mut result = false;
207        self.body.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
208        result
209    }
210
211    fn is_syntactic_place_expr(&self, expr: ExprId) -> bool {
212        match &self.body[expr] {
213            // Lang item paths cannot currently be local variables or statics.
214            Expr::Path(Path::LangItem(_, _)) => false,
215            Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(),
216            Expr::Path(path) => self
217                .resolver
218                .resolve_path_in_value_ns_fully(self.db, path, self.body.expr_path_hygiene(expr))
219                .is_none_or(|res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))),
220            Expr::Underscore => true,
221            Expr::UnaryOp { op: UnaryOp::Deref, .. } => true,
222            Expr::Field { .. } | Expr::Index { .. } => true,
223            Expr::Call { .. }
224            | Expr::MethodCall { .. }
225            | Expr::Tuple { .. }
226            | Expr::If { .. }
227            | Expr::Match { .. }
228            | Expr::Closure { .. }
229            | Expr::Block { .. }
230            | Expr::Array(..)
231            | Expr::Break { .. }
232            | Expr::Continue { .. }
233            | Expr::Return { .. }
234            | Expr::Become { .. }
235            | Expr::Let { .. }
236            | Expr::Loop { .. }
237            | Expr::InlineAsm(..)
238            | Expr::OffsetOf(..)
239            | Expr::Literal(..)
240            | Expr::Const(..)
241            | Expr::UnaryOp { .. }
242            | Expr::BinaryOp { .. }
243            | Expr::Assignment { .. }
244            | Expr::Yield { .. }
245            | Expr::Cast { .. }
246            | Expr::Async { .. }
247            | Expr::Unsafe { .. }
248            | Expr::Await { .. }
249            | Expr::Ref { .. }
250            | Expr::Range { .. }
251            | Expr::Box { .. }
252            | Expr::RecordLit { .. }
253            | Expr::Yeet { .. }
254            | Expr::Missing => false,
255        }
256    }
257
258    #[expect(clippy::needless_return)]
259    pub(crate) fn check_lhs_assignable(&self, lhs: ExprId) {
260        if self.is_syntactic_place_expr(lhs) {
261            return;
262        }
263
264        // FIXME: Emit diagnostic.
265    }
266
267    fn infer_expr_coerce_never(
268        &mut self,
269        expr: ExprId,
270        expected: &Expectation<'db>,
271        is_read: ExprIsRead,
272    ) -> Ty<'db> {
273        let ty = self.infer_expr_inner(expr, expected, is_read);
274        // While we don't allow *arbitrary* coercions here, we *do* allow
275        // coercions from `!` to `expected`.
276        if ty.is_never() {
277            if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
278                return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
279                    *target
280                } else {
281                    self.err_ty()
282                };
283            }
284
285            if let Some(target) = expected.only_has_type(&mut self.table) {
286                self.coerce(expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes)
287                    .expect("never-to-any coercion should always succeed")
288            } else {
289                ty
290            }
291        } else {
292            if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
293                let could_unify = self.unify(ty, expected_ty);
294                if !could_unify {
295                    self.result
296                        .type_mismatches
297                        .get_or_insert_default()
298                        .insert(expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
299                }
300            }
301            ty
302        }
303    }
304
305    #[tracing::instrument(level = "debug", skip(self, is_read), ret)]
306    fn infer_expr_inner(
307        &mut self,
308        tgt_expr: ExprId,
309        expected: &Expectation<'db>,
310        is_read: ExprIsRead,
311    ) -> Ty<'db> {
312        self.db.unwind_if_revision_cancelled();
313
314        let expr = &self.body[tgt_expr];
315        tracing::trace!(?expr);
316        let ty = match expr {
317            Expr::Missing => self.err_ty(),
318            &Expr::If { condition, then_branch, else_branch } => {
319                let expected = &expected.adjust_for_branches(&mut self.table);
320                self.infer_expr_coerce_never(
321                    condition,
322                    &Expectation::HasType(self.types.bool),
323                    ExprIsRead::Yes,
324                );
325
326                let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
327
328                let then_ty = self.infer_expr_inner(then_branch, expected, ExprIsRead::Yes);
329                let then_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
330                let mut coercion_sites = [then_branch, tgt_expr];
331                if let Some(else_branch) = else_branch {
332                    coercion_sites[1] = else_branch;
333                }
334                let mut coerce = CoerceMany::with_coercion_sites(
335                    expected.coercion_target_type(&mut self.table),
336                    &coercion_sites,
337                );
338                coerce.coerce(self, &ObligationCause::new(), then_branch, then_ty, ExprIsRead::Yes);
339                match else_branch {
340                    Some(else_branch) => {
341                        let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes);
342                        let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
343                        coerce.coerce(
344                            self,
345                            &ObligationCause::new(),
346                            else_branch,
347                            else_ty,
348                            ExprIsRead::Yes,
349                        );
350                        self.diverges = condition_diverges | then_diverges & else_diverges;
351                    }
352                    None => {
353                        coerce.coerce_forced_unit(
354                            self,
355                            tgt_expr,
356                            &ObligationCause::new(),
357                            true,
358                            ExprIsRead::Yes,
359                        );
360                        self.diverges = condition_diverges;
361                    }
362                }
363
364                coerce.complete(self)
365            }
366            &Expr::Let { pat, expr } => {
367                let child_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) {
368                    ExprIsRead::Yes
369                } else {
370                    ExprIsRead::No
371                };
372                let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
373                self.infer_top_pat(
374                    pat,
375                    input_ty,
376                    Some(DeclContext { origin: DeclOrigin::LetExpr }),
377                );
378                self.types.bool
379            }
380            Expr::Block { statements, tail, label, id: _ } => {
381                self.infer_block(tgt_expr, statements, *tail, *label, expected)
382            }
383            Expr::Unsafe { id: _, statements, tail } => {
384                self.infer_block(tgt_expr, statements, *tail, None, expected)
385            }
386            Expr::Const(id) => {
387                self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
388                    this.infer_expr(*id, expected, ExprIsRead::Yes)
389                })
390                .1
391            }
392            Expr::Async { id: _, statements, tail } => {
393                self.infer_async_block(tgt_expr, statements, tail)
394            }
395            &Expr::Loop { body, label } => {
396                // FIXME: should be:
397                // let ty = expected.coercion_target_type(&mut self.table);
398                let ty = self.table.next_ty_var();
399                let (breaks, ()) =
400                    self.with_breakable_ctx(BreakableKind::Loop, Some(ty), label, |this| {
401                        this.infer_expr(
402                            body,
403                            &Expectation::HasType(this.types.unit),
404                            ExprIsRead::Yes,
405                        );
406                    });
407
408                match breaks {
409                    Some(breaks) => {
410                        self.diverges = Diverges::Maybe;
411                        breaks
412                    }
413                    None => self.types.never,
414                }
415            }
416            Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
417                .infer_closure(
418                    *body,
419                    args,
420                    *ret_type,
421                    arg_types,
422                    *closure_kind,
423                    tgt_expr,
424                    expected,
425                ),
426            Expr::Call { callee, args, .. } => self.infer_call(tgt_expr, *callee, args, expected),
427            Expr::MethodCall { receiver, args, method_name, generic_args } => self
428                .infer_method_call(
429                    tgt_expr,
430                    *receiver,
431                    args,
432                    method_name,
433                    generic_args.as_deref(),
434                    expected,
435                ),
436            Expr::Match { expr, arms } => {
437                let mut scrutinee_is_read = true;
438                let mut contains_ref_bindings = false;
439                for arm in arms {
440                    scrutinee_is_read &= self.pat_guaranteed_to_constitute_read_for_never(arm.pat);
441                    contains_ref_bindings |= self.contains_explicit_ref_binding(arm.pat);
442                }
443                let scrutinee_is_read =
444                    if scrutinee_is_read { ExprIsRead::Yes } else { ExprIsRead::No };
445                let input_ty = self.demand_scrutinee_type(
446                    *expr,
447                    contains_ref_bindings,
448                    arms.is_empty(),
449                    scrutinee_is_read,
450                );
451
452                if arms.is_empty() {
453                    self.diverges = Diverges::Always;
454                    self.types.never
455                } else {
456                    let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
457                    let mut all_arms_diverge = Diverges::Always;
458                    for arm in arms.iter() {
459                        self.infer_top_pat(arm.pat, input_ty, None);
460                    }
461
462                    let expected = expected.adjust_for_branches(&mut self.table);
463                    let result_ty = match &expected {
464                        // We don't coerce to `()` so that if the match expression is a
465                        // statement it's branches can have any consistent type.
466                        Expectation::HasType(ty) if *ty != self.types.unit => *ty,
467                        _ => self.table.next_ty_var(),
468                    };
469                    let mut coerce = CoerceMany::new(result_ty);
470
471                    for arm in arms.iter() {
472                        if let Some(guard_expr) = arm.guard {
473                            self.diverges = Diverges::Maybe;
474                            self.infer_expr_coerce_never(
475                                guard_expr,
476                                &Expectation::HasType(self.types.bool),
477                                ExprIsRead::Yes,
478                            );
479                        }
480                        self.diverges = Diverges::Maybe;
481
482                        let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes);
483                        all_arms_diverge &= self.diverges;
484                        coerce.coerce(
485                            self,
486                            &ObligationCause::new(),
487                            arm.expr,
488                            arm_ty,
489                            ExprIsRead::Yes,
490                        );
491                    }
492
493                    self.diverges = matchee_diverges | all_arms_diverge;
494
495                    coerce.complete(self)
496                }
497            }
498            Expr::Path(p) => self.infer_expr_path(p, tgt_expr.into(), tgt_expr),
499            &Expr::Continue { label } => {
500                if find_continuable(&mut self.breakables, label).is_none() {
501                    self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
502                        expr: tgt_expr,
503                        is_break: false,
504                        bad_value_break: false,
505                    });
506                };
507                self.types.never
508            }
509            &Expr::Break { expr, label } => {
510                let val_ty = if let Some(expr) = expr {
511                    let opt_coerce_to = match find_breakable(&mut self.breakables, label) {
512                        Some(ctxt) => match &ctxt.coerce {
513                            Some(coerce) => coerce.expected_ty(),
514                            None => {
515                                self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
516                                    expr: tgt_expr,
517                                    is_break: true,
518                                    bad_value_break: true,
519                                });
520                                self.err_ty()
521                            }
522                        },
523                        None => self.err_ty(),
524                    };
525                    self.infer_expr_inner(
526                        expr,
527                        &Expectation::HasType(opt_coerce_to),
528                        ExprIsRead::Yes,
529                    )
530                } else {
531                    self.types.unit
532                };
533
534                match find_breakable(&mut self.breakables, label) {
535                    Some(ctxt) => match ctxt.coerce.take() {
536                        Some(mut coerce) => {
537                            coerce.coerce(
538                                self,
539                                &ObligationCause::new(),
540                                expr.unwrap_or(tgt_expr),
541                                val_ty,
542                                ExprIsRead::Yes,
543                            );
544
545                            // Avoiding borrowck
546                            let ctxt = find_breakable(&mut self.breakables, label)
547                                .expect("breakable stack changed during coercion");
548                            ctxt.may_break = true;
549                            ctxt.coerce = Some(coerce);
550                        }
551                        None => ctxt.may_break = true,
552                    },
553                    None => {
554                        self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
555                            expr: tgt_expr,
556                            is_break: true,
557                            bad_value_break: false,
558                        });
559                    }
560                }
561                self.types.never
562            }
563            &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr),
564            &Expr::Become { expr } => self.infer_expr_become(expr),
565            Expr::Yield { expr } => {
566                if let Some((resume_ty, yield_ty)) = self.resume_yield_tys {
567                    if let Some(expr) = expr {
568                        self.infer_expr_coerce(
569                            *expr,
570                            &Expectation::has_type(yield_ty),
571                            ExprIsRead::Yes,
572                        );
573                    } else {
574                        let unit = self.types.unit;
575                        let _ = self.coerce(
576                            tgt_expr.into(),
577                            unit,
578                            yield_ty,
579                            AllowTwoPhase::No,
580                            ExprIsRead::Yes,
581                        );
582                    }
583                    resume_ty
584                } else {
585                    // FIXME: report error (yield expr in non-coroutine)
586                    self.types.error
587                }
588            }
589            Expr::Yeet { expr } => {
590                if let &Some(expr) = expr {
591                    self.infer_expr_no_expect(expr, ExprIsRead::Yes);
592                }
593                self.types.never
594            }
595            Expr::RecordLit { path, fields, spread, .. } => {
596                let (ty, def_id) = self.resolve_variant(tgt_expr.into(), path.as_deref(), false);
597
598                if let Some(t) = expected.only_has_type(&mut self.table) {
599                    self.unify(ty, t);
600                }
601
602                let substs = ty.as_adt().map(|(_, s)| s).unwrap_or(self.types.empty_args);
603                if let Some(variant) = def_id {
604                    self.write_variant_resolution(tgt_expr.into(), variant);
605                }
606                match def_id {
607                    _ if fields.is_empty() => {}
608                    Some(def) => {
609                        let field_types = self.db.field_types(def);
610                        let variant_data = def.fields(self.db);
611                        let visibilities = self.db.field_visibilities(def);
612                        for field in fields.iter() {
613                            let field_def = {
614                                match variant_data.field(&field.name) {
615                                    Some(local_id) => {
616                                        if !visibilities[local_id]
617                                            .is_visible_from(self.db, self.resolver.module())
618                                        {
619                                            self.push_diagnostic(
620                                                InferenceDiagnostic::NoSuchField {
621                                                    field: field.expr.into(),
622                                                    private: Some(local_id),
623                                                    variant: def,
624                                                },
625                                            );
626                                        }
627                                        Some(local_id)
628                                    }
629                                    None => {
630                                        self.push_diagnostic(InferenceDiagnostic::NoSuchField {
631                                            field: field.expr.into(),
632                                            private: None,
633                                            variant: def,
634                                        });
635                                        None
636                                    }
637                                }
638                            };
639                            let field_ty = field_def.map_or(self.err_ty(), |it| {
640                                field_types[it].instantiate(self.interner(), &substs)
641                            });
642
643                            // Field type might have some unknown types
644                            // FIXME: we may want to emit a single type variable for all instance of type fields?
645                            let field_ty = self.insert_type_vars(field_ty);
646                            self.infer_expr_coerce(
647                                field.expr,
648                                &Expectation::has_type(field_ty),
649                                ExprIsRead::Yes,
650                            );
651                        }
652                    }
653                    None => {
654                        for field in fields.iter() {
655                            // Field projections don't constitute reads.
656                            self.infer_expr_coerce(field.expr, &Expectation::None, ExprIsRead::No);
657                        }
658                    }
659                }
660                if let Some(expr) = spread {
661                    self.infer_expr(*expr, &Expectation::has_type(ty), ExprIsRead::Yes);
662                }
663                ty
664            }
665            Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected),
666            Expr::Await { expr } => {
667                let inner_ty = self.infer_expr_inner(*expr, &Expectation::none(), ExprIsRead::Yes);
668                self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
669            }
670            Expr::Cast { expr, type_ref } => {
671                let cast_ty = self.make_body_ty(*type_ref);
672                let expr_ty =
673                    self.infer_expr(*expr, &Expectation::Castable(cast_ty), ExprIsRead::Yes);
674                self.deferred_cast_checks.push(CastCheck::new(tgt_expr, *expr, expr_ty, cast_ty));
675                cast_ty
676            }
677            Expr::Ref { expr, rawness, mutability } => {
678                let mutability = lower_mutability(*mutability);
679                let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected
680                    .only_has_type(&mut self.table)
681                    .as_ref()
682                    .and_then(|t| t.as_reference_or_ptr())
683                {
684                    if exp_mutability == Mutability::Mut && mutability == Mutability::Not {
685                        // FIXME: record type error - expected mut reference but found shared ref,
686                        // which cannot be coerced
687                    }
688                    if exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
689                        // FIXME: record type error - expected reference but found ptr,
690                        // which cannot be coerced
691                    }
692                    Expectation::rvalue_hint(self, exp_inner)
693                } else {
694                    Expectation::none()
695                };
696                let inner_ty = self.infer_expr_inner(*expr, &expectation, ExprIsRead::Yes);
697                match rawness {
698                    Rawness::RawPtr => Ty::new_ptr(self.interner(), inner_ty, mutability),
699                    Rawness::Ref => {
700                        let lt = self.table.next_region_var();
701                        Ty::new_ref(self.interner(), lt, inner_ty, mutability)
702                    }
703                }
704            }
705            &Expr::Box { expr } => self.infer_expr_box(expr, expected),
706            Expr::UnaryOp { expr, op } => self.infer_unop_expr(*op, *expr, expected, tgt_expr),
707            Expr::BinaryOp { lhs, rhs, op } => match op {
708                Some(BinaryOp::Assignment { op: Some(op) }) => {
709                    self.infer_assign_op_expr(tgt_expr, *op, *lhs, *rhs)
710                }
711                Some(op) => self.infer_binop_expr(tgt_expr, *op, *lhs, *rhs),
712                None => self.err_ty(),
713            },
714            &Expr::Assignment { target, value } => {
715                // In ordinary (non-destructuring) assignments, the type of
716                // `lhs` must be inferred first so that the ADT fields
717                // instantiations in RHS can be coerced to it. Note that this
718                // cannot happen in destructuring assignments because of how
719                // they are desugared.
720                let lhs_ty = match &self.body[target] {
721                    // LHS of assignment doesn't constitute reads.
722                    &Pat::Expr(expr) => {
723                        Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No))
724                    }
725                    Pat::Path(path) => {
726                        let resolver_guard =
727                            self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
728                        let resolution = self.resolver.resolve_path_in_value_ns_fully(
729                            self.db,
730                            path,
731                            self.body.pat_path_hygiene(target),
732                        );
733                        self.resolver.reset_to_guard(resolver_guard);
734
735                        if matches!(
736                            resolution,
737                            Some(
738                                ValueNs::ConstId(_)
739                                    | ValueNs::StructId(_)
740                                    | ValueNs::EnumVariantId(_)
741                            )
742                        ) {
743                            None
744                        } else {
745                            Some(self.infer_expr_path(path, target.into(), tgt_expr))
746                        }
747                    }
748                    _ => None,
749                };
750                let is_destructuring_assignment = lhs_ty.is_none();
751
752                if let Some(lhs_ty) = lhs_ty {
753                    self.write_pat_ty(target, lhs_ty);
754                    self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::No);
755                } else {
756                    let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
757                    let resolver_guard =
758                        self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
759                    self.inside_assignment = true;
760                    self.infer_top_pat(target, rhs_ty, None);
761                    self.inside_assignment = false;
762                    self.resolver.reset_to_guard(resolver_guard);
763                }
764                if is_destructuring_assignment && self.diverges.is_always() {
765                    // Ordinary assignments always return `()`, even when they diverge.
766                    // However, rustc lowers destructuring assignments into blocks, and blocks return `!` if they have no tail
767                    // expression and they diverge. Therefore, we have to do the same here, even though we don't lower destructuring
768                    // assignments into blocks.
769                    self.table.new_maybe_never_var()
770                } else {
771                    self.types.unit
772                }
773            }
774            Expr::Range { lhs, rhs, range_type } => {
775                let lhs_ty =
776                    lhs.map(|e| self.infer_expr_inner(e, &Expectation::none(), ExprIsRead::Yes));
777                let rhs_expect = lhs_ty.map_or_else(Expectation::none, Expectation::has_type);
778                let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect, ExprIsRead::Yes));
779                let single_arg_adt = |adt, ty: Ty<'db>| {
780                    Ty::new_adt(
781                        self.interner(),
782                        adt,
783                        GenericArgs::new_from_iter(self.interner(), [ty.into()]),
784                    )
785                };
786                match (range_type, lhs_ty, rhs_ty) {
787                    (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
788                        Some(adt) => Ty::new_adt(self.interner(), adt, self.types.empty_args),
789                        None => self.err_ty(),
790                    },
791                    (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
792                        Some(adt) => single_arg_adt(adt, ty),
793                        None => self.err_ty(),
794                    },
795                    (RangeOp::Inclusive, None, Some(ty)) => {
796                        match self.resolve_range_to_inclusive() {
797                            Some(adt) => single_arg_adt(adt, ty),
798                            None => self.err_ty(),
799                        }
800                    }
801                    (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
802                        Some(adt) => single_arg_adt(adt, ty),
803                        None => self.err_ty(),
804                    },
805                    (RangeOp::Inclusive, Some(_), Some(ty)) => {
806                        match self.resolve_range_inclusive() {
807                            Some(adt) => single_arg_adt(adt, ty),
808                            None => self.err_ty(),
809                        }
810                    }
811                    (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
812                        Some(adt) => single_arg_adt(adt, ty),
813                        None => self.err_ty(),
814                    },
815                    (RangeOp::Inclusive, _, None) => self.err_ty(),
816                }
817            }
818            Expr::Index { base, index } => {
819                let base_t = self.infer_expr_no_expect(*base, ExprIsRead::Yes);
820                let idx_t = self.infer_expr_no_expect(*index, ExprIsRead::Yes);
821
822                let base_t = self.table.structurally_resolve_type(base_t);
823                match self.lookup_indexing(tgt_expr, *base, base_t, idx_t) {
824                    Some((trait_index_ty, trait_element_ty)) => {
825                        // two-phase not needed because index_ty is never mutable
826                        self.demand_coerce(
827                            *index,
828                            idx_t,
829                            trait_index_ty,
830                            AllowTwoPhase::No,
831                            ExprIsRead::Yes,
832                        );
833                        self.table.select_obligations_where_possible();
834                        trait_element_ty
835                    }
836                    // FIXME: Report an error.
837                    None => self.types.error,
838                }
839            }
840            Expr::Tuple { exprs, .. } => {
841                let mut tys = match expected
842                    .only_has_type(&mut self.table)
843                    .map(|t| self.table.try_structurally_resolve_type(t).kind())
844                {
845                    Some(TyKind::Tuple(substs)) => substs
846                        .iter()
847                        .chain(repeat_with(|| self.table.next_ty_var()))
848                        .take(exprs.len())
849                        .collect::<Vec<_>>(),
850                    _ => (0..exprs.len()).map(|_| self.table.next_ty_var()).collect(),
851                };
852
853                for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
854                    *ty =
855                        self.infer_expr_coerce(*expr, &Expectation::has_type(*ty), ExprIsRead::Yes);
856                }
857
858                Ty::new_tup(self.interner(), &tys)
859            }
860            Expr::Array(array) => self.infer_expr_array(array, expected),
861            Expr::Literal(lit) => match lit {
862                Literal::Bool(..) => self.types.bool,
863                Literal::String(..) => self.types.static_str_ref,
864                Literal::ByteString(bs) => {
865                    let byte_type = self.types.u8;
866
867                    let len = consteval::usize_const(
868                        self.db,
869                        Some(bs.len() as u128),
870                        self.resolver.krate(),
871                    );
872
873                    let array_type = Ty::new_array_with_const_len(self.interner(), byte_type, len);
874                    Ty::new_ref(self.interner(), self.types.re_static, array_type, Mutability::Not)
875                }
876                Literal::CString(..) => Ty::new_ref(
877                    self.interner(),
878                    self.types.re_static,
879                    self.lang_items.CStr.map_or_else(
880                        || self.err_ty(),
881                        |strukt| Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args),
882                    ),
883                    Mutability::Not,
884                ),
885                Literal::Char(..) => self.types.char,
886                Literal::Int(_v, ty) => match ty {
887                    Some(int_ty) => match int_ty {
888                        hir_def::builtin_type::BuiltinInt::Isize => self.types.isize,
889                        hir_def::builtin_type::BuiltinInt::I8 => self.types.i8,
890                        hir_def::builtin_type::BuiltinInt::I16 => self.types.i16,
891                        hir_def::builtin_type::BuiltinInt::I32 => self.types.i32,
892                        hir_def::builtin_type::BuiltinInt::I64 => self.types.i64,
893                        hir_def::builtin_type::BuiltinInt::I128 => self.types.i128,
894                    },
895                    None => {
896                        let expected_ty = expected.to_option(&mut self.table);
897                        tracing::debug!(?expected_ty);
898                        let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
899                            Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
900                            Some(TyKind::Char) => Some(self.types.u8),
901                            Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
902                                Some(self.types.usize)
903                            }
904                            _ => None,
905                        };
906                        opt_ty.unwrap_or_else(|| self.table.next_int_var())
907                    }
908                },
909                Literal::Uint(_v, ty) => match ty {
910                    Some(int_ty) => match int_ty {
911                        hir_def::builtin_type::BuiltinUint::Usize => self.types.usize,
912                        hir_def::builtin_type::BuiltinUint::U8 => self.types.u8,
913                        hir_def::builtin_type::BuiltinUint::U16 => self.types.u16,
914                        hir_def::builtin_type::BuiltinUint::U32 => self.types.u32,
915                        hir_def::builtin_type::BuiltinUint::U64 => self.types.u64,
916                        hir_def::builtin_type::BuiltinUint::U128 => self.types.u128,
917                    },
918                    None => {
919                        let expected_ty = expected.to_option(&mut self.table);
920                        let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
921                            Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
922                            Some(TyKind::Char) => Some(self.types.u8),
923                            Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
924                                Some(self.types.usize)
925                            }
926                            _ => None,
927                        };
928                        opt_ty.unwrap_or_else(|| self.table.next_int_var())
929                    }
930                },
931                Literal::Float(_v, ty) => match ty {
932                    Some(float_ty) => match float_ty {
933                        hir_def::builtin_type::BuiltinFloat::F16 => self.types.f16,
934                        hir_def::builtin_type::BuiltinFloat::F32 => self.types.f32,
935                        hir_def::builtin_type::BuiltinFloat::F64 => self.types.f64,
936                        hir_def::builtin_type::BuiltinFloat::F128 => self.types.f128,
937                    },
938                    None => {
939                        let opt_ty = expected
940                            .to_option(&mut self.table)
941                            .filter(|ty| matches!(ty.kind(), TyKind::Float(_)));
942                        opt_ty.unwrap_or_else(|| self.table.next_float_var())
943                    }
944                },
945            },
946            Expr::Underscore => {
947                // Underscore expression is an error, we render a specialized diagnostic
948                // to let the user know what type is expected though.
949                let expected = expected.to_option(&mut self.table).unwrap_or_else(|| self.err_ty());
950                self.push_diagnostic(InferenceDiagnostic::TypedHole { expr: tgt_expr, expected });
951                expected
952            }
953            Expr::OffsetOf(_) => self.types.usize,
954            Expr::InlineAsm(asm) => {
955                let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| {
956                    let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes);
957
958                    // If this is an input value, we require its type to be fully resolved
959                    // at this point. This allows us to provide helpful coercions which help
960                    // pass the type candidate list in a later pass.
961                    //
962                    // We don't require output types to be resolved at this point, which
963                    // allows them to be inferred based on how they are used later in the
964                    // function.
965                    if is_input {
966                        let ty = this.table.structurally_resolve_type(ty);
967                        match ty.kind() {
968                            TyKind::FnDef(def, parameters) => {
969                                let fnptr_ty = Ty::new_fn_ptr(
970                                    this.interner(),
971                                    this.interner()
972                                        .fn_sig(def)
973                                        .instantiate(this.interner(), parameters),
974                                );
975                                _ = this.coerce(
976                                    expr.into(),
977                                    ty,
978                                    fnptr_ty,
979                                    AllowTwoPhase::No,
980                                    ExprIsRead::Yes,
981                                );
982                            }
983                            TyKind::Ref(_, base_ty, mutbl) => {
984                                let ptr_ty = Ty::new_ptr(this.interner(), base_ty, mutbl);
985                                _ = this.coerce(
986                                    expr.into(),
987                                    ty,
988                                    ptr_ty,
989                                    AllowTwoPhase::No,
990                                    ExprIsRead::Yes,
991                                );
992                            }
993                            _ => {}
994                        }
995                    }
996                };
997
998                let diverge = asm.options.contains(AsmOptions::NORETURN);
999                asm.operands.iter().for_each(|(_, operand)| match *operand {
1000                    AsmOperand::In { expr, .. } => check_expr_asm_operand(self, expr, true),
1001                    AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
1002                        check_expr_asm_operand(self, expr, false)
1003                    }
1004                    AsmOperand::Out { expr: None, .. } => (),
1005                    AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
1006                        check_expr_asm_operand(self, in_expr, true);
1007                        if let Some(out_expr) = out_expr {
1008                            check_expr_asm_operand(self, out_expr, false);
1009                        }
1010                    }
1011                    AsmOperand::Label(expr) => {
1012                        self.infer_expr(
1013                            expr,
1014                            &Expectation::HasType(self.types.unit),
1015                            ExprIsRead::No,
1016                        );
1017                    }
1018                    AsmOperand::Const(expr) => {
1019                        self.infer_expr(expr, &Expectation::None, ExprIsRead::No);
1020                    }
1021                    // FIXME: `sym` should report for things that are not functions or statics.
1022                    AsmOperand::Sym(_) => (),
1023                });
1024                if diverge { self.types.never } else { self.types.unit }
1025            }
1026        };
1027        // use a new type variable if we got unknown here
1028        let ty = self.insert_type_vars_shallow(ty);
1029        self.write_expr_ty(tgt_expr, ty);
1030        if self.shallow_resolve(ty).is_never()
1031            && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read)
1032        {
1033            // Any expression that produces a value of type `!` must have diverged
1034            self.diverges = Diverges::Always;
1035        }
1036        ty
1037    }
1038
1039    fn demand_scrutinee_type(
1040        &mut self,
1041        scrut: ExprId,
1042        contains_ref_bindings: bool,
1043        no_arms: bool,
1044        scrutinee_is_read: ExprIsRead,
1045    ) -> Ty<'db> {
1046        // Not entirely obvious: if matches may create ref bindings, we want to
1047        // use the *precise* type of the scrutinee, *not* some supertype, as
1048        // the "scrutinee type" (issue #23116).
1049        //
1050        // arielb1 [writes here in this comment thread][c] that there
1051        // is certainly *some* potential danger, e.g., for an example
1052        // like:
1053        //
1054        // [c]: https://github.com/rust-lang/rust/pull/43399#discussion_r130223956
1055        //
1056        // ```
1057        // let Foo(x) = f()[0];
1058        // ```
1059        //
1060        // Then if the pattern matches by reference, we want to match
1061        // `f()[0]` as a lexpr, so we can't allow it to be
1062        // coerced. But if the pattern matches by value, `f()[0]` is
1063        // still syntactically a lexpr, but we *do* want to allow
1064        // coercions.
1065        //
1066        // However, *likely* we are ok with allowing coercions to
1067        // happen if there are no explicit ref mut patterns - all
1068        // implicit ref mut patterns must occur behind a reference, so
1069        // they will have the "correct" variance and lifetime.
1070        //
1071        // This does mean that the following pattern would be legal:
1072        //
1073        // ```
1074        // struct Foo(Bar);
1075        // struct Bar(u32);
1076        // impl Deref for Foo {
1077        //     type Target = Bar;
1078        //     fn deref(&self) -> &Bar { &self.0 }
1079        // }
1080        // impl DerefMut for Foo {
1081        //     fn deref_mut(&mut self) -> &mut Bar { &mut self.0 }
1082        // }
1083        // fn foo(x: &mut Foo) {
1084        //     {
1085        //         let Bar(z): &mut Bar = x;
1086        //         *z = 42;
1087        //     }
1088        //     assert_eq!(foo.0.0, 42);
1089        // }
1090        // ```
1091        //
1092        // FIXME(tschottdorf): don't call contains_explicit_ref_binding, which
1093        // is problematic as the HIR is being scraped, but ref bindings may be
1094        // implicit after #42640. We need to make sure that pat_adjustments
1095        // (once introduced) is populated by the time we get here.
1096        //
1097        // See #44848.
1098        if contains_ref_bindings || no_arms {
1099            self.infer_expr_no_expect(scrut, scrutinee_is_read)
1100        } else {
1101            // ...but otherwise we want to use any supertype of the
1102            // scrutinee. This is sort of a workaround, see note (*) in
1103            // `check_pat` for some details.
1104            let scrut_ty = self.table.next_ty_var();
1105            self.infer_expr_coerce_never(scrut, &Expectation::HasType(scrut_ty), scrutinee_is_read);
1106            scrut_ty
1107        }
1108    }
1109
1110    fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty<'db> {
1111        let g = self.resolver.update_to_inner_scope(self.db, self.owner, scope_id);
1112        let ty = match self.infer_path(path, id) {
1113            Some(ty) => ty,
1114            None => {
1115                if path.mod_path().is_some_and(|mod_path| mod_path.is_ident() || mod_path.is_self())
1116                {
1117                    self.push_diagnostic(InferenceDiagnostic::UnresolvedIdent { id });
1118                }
1119                self.err_ty()
1120            }
1121        };
1122        self.resolver.reset_to_guard(g);
1123        ty
1124    }
1125
1126    fn infer_unop_expr(
1127        &mut self,
1128        unop: UnaryOp,
1129        oprnd: ExprId,
1130        expected: &Expectation<'db>,
1131        expr: ExprId,
1132    ) -> Ty<'db> {
1133        let expected_inner = match unop {
1134            UnaryOp::Not | UnaryOp::Neg => expected,
1135            UnaryOp::Deref => &Expectation::None,
1136        };
1137        let mut oprnd_t = self.infer_expr_inner(oprnd, expected_inner, ExprIsRead::Yes);
1138
1139        oprnd_t = self.table.structurally_resolve_type(oprnd_t);
1140        match unop {
1141            UnaryOp::Deref => {
1142                if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
1143                    oprnd_t = ty;
1144                } else {
1145                    // FIXME: Report an error.
1146                    oprnd_t = self.types.error;
1147                }
1148            }
1149            UnaryOp::Not => {
1150                let result = self.infer_user_unop(expr, oprnd_t, unop);
1151                // If it's builtin, we can reuse the type, this helps inference.
1152                if !(oprnd_t.is_integral() || oprnd_t.kind() == TyKind::Bool) {
1153                    oprnd_t = result;
1154                }
1155            }
1156            UnaryOp::Neg => {
1157                let result = self.infer_user_unop(expr, oprnd_t, unop);
1158                // If it's builtin, we can reuse the type, this helps inference.
1159                if !oprnd_t.is_numeric() {
1160                    oprnd_t = result;
1161                }
1162            }
1163        }
1164        oprnd_t
1165    }
1166
1167    fn infer_async_block(
1168        &mut self,
1169        tgt_expr: ExprId,
1170        statements: &[Statement],
1171        tail: &Option<ExprId>,
1172    ) -> Ty<'db> {
1173        let ret_ty = self.table.next_ty_var();
1174        let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
1175        let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty);
1176        let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(ret_ty));
1177
1178        // FIXME: We should handle async blocks like we handle closures
1179        let expected = &Expectation::has_type(ret_ty);
1180        let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
1181            let ty = this.infer_block(tgt_expr, statements, *tail, None, expected);
1182            if let Some(target) = expected.only_has_type(&mut this.table) {
1183                match this.coerce(tgt_expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes) {
1184                    Ok(res) => res,
1185                    Err(_) => {
1186                        this.result
1187                            .type_mismatches
1188                            .get_or_insert_default()
1189                            .insert(tgt_expr.into(), TypeMismatch { expected: target, actual: ty });
1190                        target
1191                    }
1192                }
1193            } else {
1194                ty
1195            }
1196        });
1197
1198        self.diverges = prev_diverges;
1199        self.return_ty = prev_ret_ty;
1200        self.return_coercion = prev_ret_coercion;
1201
1202        self.lower_async_block_type_impl_trait(inner_ty, tgt_expr)
1203    }
1204
1205    pub(crate) fn lower_async_block_type_impl_trait(
1206        &mut self,
1207        inner_ty: Ty<'db>,
1208        tgt_expr: ExprId,
1209    ) -> Ty<'db> {
1210        let coroutine_id = InternedCoroutine(self.owner, tgt_expr);
1211        let coroutine_id = self.db.intern_coroutine(coroutine_id).into();
1212        let parent_args = GenericArgs::identity_for_item(self.interner(), self.generic_def.into());
1213        Ty::new_coroutine(
1214            self.interner(),
1215            coroutine_id,
1216            CoroutineArgs::new(
1217                self.interner(),
1218                CoroutineArgsParts {
1219                    parent_args,
1220                    kind_ty: self.types.unit,
1221                    // rustc uses a special lang item type for the resume ty. I don't believe this can cause us problems.
1222                    resume_ty: self.types.unit,
1223                    yield_ty: self.types.unit,
1224                    return_ty: inner_ty,
1225                    // FIXME: Infer upvars.
1226                    tupled_upvars_ty: self.types.unit,
1227                },
1228            )
1229            .args,
1230        )
1231    }
1232
1233    pub(crate) fn write_fn_trait_method_resolution(
1234        &mut self,
1235        fn_x: FnTrait,
1236        derefed_callee: Ty<'db>,
1237        adjustments: &mut Vec<Adjustment<'db>>,
1238        callee_ty: Ty<'db>,
1239        params: &[Ty<'db>],
1240        tgt_expr: ExprId,
1241    ) {
1242        match fn_x {
1243            FnTrait::FnOnce | FnTrait::AsyncFnOnce => (),
1244            FnTrait::FnMut | FnTrait::AsyncFnMut => {
1245                if let TyKind::Ref(lt, inner, Mutability::Mut) = derefed_callee.kind() {
1246                    if adjustments
1247                        .last()
1248                        .map(|it| matches!(it.kind, Adjust::Borrow(_)))
1249                        .unwrap_or(true)
1250                    {
1251                        // prefer reborrow to move
1252                        adjustments.push(Adjustment { kind: Adjust::Deref(None), target: inner });
1253                        adjustments.push(Adjustment::borrow(
1254                            self.interner(),
1255                            Mutability::Mut,
1256                            inner,
1257                            lt,
1258                        ))
1259                    }
1260                } else {
1261                    adjustments.push(Adjustment::borrow(
1262                        self.interner(),
1263                        Mutability::Mut,
1264                        derefed_callee,
1265                        self.table.next_region_var(),
1266                    ));
1267                }
1268            }
1269            FnTrait::Fn | FnTrait::AsyncFn => {
1270                if !matches!(derefed_callee.kind(), TyKind::Ref(_, _, Mutability::Not)) {
1271                    adjustments.push(Adjustment::borrow(
1272                        self.interner(),
1273                        Mutability::Not,
1274                        derefed_callee,
1275                        self.table.next_region_var(),
1276                    ));
1277                }
1278            }
1279        }
1280        let Some(trait_) = fn_x.get_id(self.lang_items) else {
1281            return;
1282        };
1283        let trait_data = trait_.trait_items(self.db);
1284        if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) {
1285            let subst = GenericArgs::new_from_iter(
1286                self.interner(),
1287                [
1288                    callee_ty.into(),
1289                    Ty::new_tup_from_iter(self.interner(), params.iter().copied()).into(),
1290                ],
1291            );
1292            self.write_method_resolution(tgt_expr, func, subst);
1293        }
1294    }
1295
1296    fn infer_expr_array(&mut self, array: &Array, expected: &Expectation<'db>) -> Ty<'db> {
1297        let elem_ty = match expected
1298            .to_option(&mut self.table)
1299            .map(|t| self.table.try_structurally_resolve_type(t).kind())
1300        {
1301            Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st,
1302            _ => self.table.next_ty_var(),
1303        };
1304
1305        let krate = self.resolver.krate();
1306
1307        let expected = Expectation::has_type(elem_ty);
1308        let (elem_ty, len) = match array {
1309            Array::ElementList { elements, .. } if elements.is_empty() => {
1310                (elem_ty, consteval::usize_const(self.db, Some(0), krate))
1311            }
1312            Array::ElementList { elements, .. } => {
1313                let mut coerce = CoerceMany::with_coercion_sites(elem_ty, elements);
1314                for &expr in elements.iter() {
1315                    let cur_elem_ty = self.infer_expr_inner(expr, &expected, ExprIsRead::Yes);
1316                    coerce.coerce(
1317                        self,
1318                        &ObligationCause::new(),
1319                        expr,
1320                        cur_elem_ty,
1321                        ExprIsRead::Yes,
1322                    );
1323                }
1324                (
1325                    coerce.complete(self),
1326                    consteval::usize_const(self.db, Some(elements.len() as u128), krate),
1327                )
1328            }
1329            &Array::Repeat { initializer, repeat } => {
1330                self.infer_expr_coerce(
1331                    initializer,
1332                    &Expectation::has_type(elem_ty),
1333                    ExprIsRead::Yes,
1334                );
1335                let usize = self.types.usize;
1336                let len = match self.body[repeat] {
1337                    Expr::Underscore => {
1338                        self.write_expr_ty(repeat, usize);
1339                        self.table.next_const_var()
1340                    }
1341                    _ => {
1342                        self.infer_expr(repeat, &Expectation::HasType(usize), ExprIsRead::Yes);
1343                        consteval::eval_to_const(repeat, self)
1344                    }
1345                };
1346
1347                (elem_ty, len)
1348            }
1349        };
1350        // Try to evaluate unevaluated constant, and insert variable if is not possible.
1351        let len = self.table.insert_const_vars_shallow(len);
1352        Ty::new_array_with_const_len(self.interner(), elem_ty, len)
1353    }
1354
1355    pub(super) fn infer_return(&mut self, expr: ExprId) {
1356        let ret_ty = self
1357            .return_coercion
1358            .as_mut()
1359            .expect("infer_return called outside function body")
1360            .expected_ty();
1361        let return_expr_ty =
1362            self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1363        let mut coerce_many = self.return_coercion.take().unwrap();
1364        coerce_many.coerce(self, &ObligationCause::new(), expr, return_expr_ty, ExprIsRead::Yes);
1365        self.return_coercion = Some(coerce_many);
1366    }
1367
1368    fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db> {
1369        match self.return_coercion {
1370            Some(_) => {
1371                if let Some(expr) = expr {
1372                    self.infer_return(expr);
1373                } else {
1374                    let mut coerce = self.return_coercion.take().unwrap();
1375                    coerce.coerce_forced_unit(
1376                        self,
1377                        ret,
1378                        &ObligationCause::new(),
1379                        true,
1380                        ExprIsRead::Yes,
1381                    );
1382                    self.return_coercion = Some(coerce);
1383                }
1384            }
1385            None => {
1386                // FIXME: diagnose return outside of function
1387                if let Some(expr) = expr {
1388                    self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1389                }
1390            }
1391        }
1392        self.types.never
1393    }
1394
1395    fn infer_expr_become(&mut self, expr: ExprId) -> Ty<'db> {
1396        match &self.return_coercion {
1397            Some(return_coercion) => {
1398                let ret_ty = return_coercion.expected_ty();
1399
1400                let call_expr_ty =
1401                    self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1402
1403                // NB: this should *not* coerce.
1404                //     tail calls don't support any coercions except lifetimes ones (like `&'static u8 -> &'a u8`).
1405                self.unify(call_expr_ty, ret_ty);
1406            }
1407            None => {
1408                // FIXME: diagnose `become` outside of functions
1409                self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1410            }
1411        }
1412
1413        self.types.never
1414    }
1415
1416    fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation<'db>) -> Ty<'db> {
1417        if let Some(box_id) = self.resolve_boxed_box() {
1418            let table = &mut self.table;
1419            let inner_exp = expected
1420                .to_option(table)
1421                .as_ref()
1422                .and_then(|e| e.as_adt())
1423                .filter(|(e_adt, _)| e_adt == &box_id)
1424                .map(|(_, subts)| {
1425                    let g = subts.type_at(0);
1426                    Expectation::rvalue_hint(self, g)
1427                })
1428                .unwrap_or_else(Expectation::none);
1429
1430            let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp, ExprIsRead::Yes);
1431            Ty::new_adt(
1432                self.interner(),
1433                box_id,
1434                GenericArgs::fill_with_defaults(
1435                    self.interner(),
1436                    box_id.into(),
1437                    [inner_ty.into()],
1438                    |_, id, _| self.table.next_var_for_param(id),
1439                ),
1440            )
1441        } else {
1442            self.err_ty()
1443        }
1444    }
1445
1446    fn infer_block(
1447        &mut self,
1448        expr: ExprId,
1449        statements: &[Statement],
1450        tail: Option<ExprId>,
1451        label: Option<LabelId>,
1452        expected: &Expectation<'db>,
1453    ) -> Ty<'db> {
1454        let coerce_ty = expected.coercion_target_type(&mut self.table);
1455        let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr);
1456
1457        let (break_ty, ty) =
1458            self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
1459                for stmt in statements {
1460                    match stmt {
1461                        Statement::Let { pat, type_ref, initializer, else_branch } => {
1462                            let decl_ty = type_ref
1463                                .as_ref()
1464                                .map(|&tr| this.make_body_ty(tr))
1465                                .unwrap_or_else(|| this.table.next_ty_var());
1466
1467                            let ty = if let Some(expr) = initializer {
1468                                // If we have a subpattern that performs a read, we want to consider this
1469                                // to diverge for compatibility to support something like `let x: () = *never_ptr;`.
1470                                let target_is_read =
1471                                    if this.pat_guaranteed_to_constitute_read_for_never(*pat) {
1472                                        ExprIsRead::Yes
1473                                    } else {
1474                                        ExprIsRead::No
1475                                    };
1476                                let ty = if contains_explicit_ref_binding(this.body, *pat) {
1477                                    this.infer_expr(
1478                                        *expr,
1479                                        &Expectation::has_type(decl_ty),
1480                                        target_is_read,
1481                                    )
1482                                } else {
1483                                    this.infer_expr_coerce(
1484                                        *expr,
1485                                        &Expectation::has_type(decl_ty),
1486                                        target_is_read,
1487                                    )
1488                                };
1489                                if type_ref.is_some() { decl_ty } else { ty }
1490                            } else {
1491                                decl_ty
1492                            };
1493
1494                            let decl = DeclContext {
1495                                origin: DeclOrigin::LocalDecl { has_else: else_branch.is_some() },
1496                            };
1497
1498                            this.infer_top_pat(*pat, ty, Some(decl));
1499                            if let Some(expr) = else_branch {
1500                                let previous_diverges =
1501                                    mem::replace(&mut this.diverges, Diverges::Maybe);
1502                                this.infer_expr_coerce(
1503                                    *expr,
1504                                    &Expectation::HasType(this.types.never),
1505                                    ExprIsRead::Yes,
1506                                );
1507                                this.diverges = previous_diverges;
1508                            }
1509                        }
1510                        &Statement::Expr { expr, has_semi } => {
1511                            if has_semi {
1512                                this.infer_expr(expr, &Expectation::none(), ExprIsRead::Yes);
1513                            } else {
1514                                this.infer_expr_coerce(
1515                                    expr,
1516                                    &Expectation::HasType(this.types.unit),
1517                                    ExprIsRead::Yes,
1518                                );
1519                            }
1520                        }
1521                        Statement::Item(_) => (),
1522                    }
1523                }
1524
1525                // FIXME: This should make use of the breakable CoerceMany
1526                if let Some(expr) = tail {
1527                    this.infer_expr_coerce(expr, expected, ExprIsRead::Yes)
1528                } else {
1529                    // Citing rustc: if there is no explicit tail expression,
1530                    // that is typically equivalent to a tail expression
1531                    // of `()` -- except if the block diverges. In that
1532                    // case, there is no value supplied from the tail
1533                    // expression (assuming there are no other breaks,
1534                    // this implies that the type of the block will be
1535                    // `!`).
1536                    if this.diverges.is_always() {
1537                        // we don't even make an attempt at coercion
1538                        this.table.new_maybe_never_var()
1539                    } else if let Some(t) = expected.only_has_type(&mut this.table) {
1540                        if this
1541                            .coerce(
1542                                expr.into(),
1543                                this.types.unit,
1544                                t,
1545                                AllowTwoPhase::No,
1546                                ExprIsRead::Yes,
1547                            )
1548                            .is_err()
1549                        {
1550                            this.result.type_mismatches.get_or_insert_default().insert(
1551                                expr.into(),
1552                                TypeMismatch { expected: t, actual: this.types.unit },
1553                            );
1554                        }
1555                        t
1556                    } else {
1557                        this.types.unit
1558                    }
1559                }
1560            });
1561        self.resolver.reset_to_guard(g);
1562
1563        break_ty.unwrap_or(ty)
1564    }
1565
1566    fn lookup_field(
1567        &mut self,
1568        receiver_ty: Ty<'db>,
1569        name: &Name,
1570    ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment<'db>>, bool)> {
1571        let interner = self.interner();
1572        let mut autoderef = self.table.autoderef_with_tracking(receiver_ty);
1573        let mut private_field = None;
1574        let res = autoderef.by_ref().find_map(|(derefed_ty, _)| {
1575            let (field_id, parameters) = match derefed_ty.kind() {
1576                TyKind::Tuple(substs) => {
1577                    return name.as_tuple_index().and_then(|idx| {
1578                        substs.as_slice().get(idx).copied().map(|ty| {
1579                            (
1580                                Either::Right(TupleFieldId {
1581                                    tuple: TupleId(
1582                                        self.tuple_field_accesses_rev.insert_full(substs).0 as u32,
1583                                    ),
1584                                    index: idx as u32,
1585                                }),
1586                                ty,
1587                            )
1588                        })
1589                    });
1590                }
1591                TyKind::Adt(adt, parameters) => match adt.def_id().0 {
1592                    hir_def::AdtId::StructId(s) => {
1593                        let local_id = s.fields(self.db).field(name)?;
1594                        let field = FieldId { parent: s.into(), local_id };
1595                        (field, parameters)
1596                    }
1597                    hir_def::AdtId::UnionId(u) => {
1598                        let local_id = u.fields(self.db).field(name)?;
1599                        let field = FieldId { parent: u.into(), local_id };
1600                        (field, parameters)
1601                    }
1602                    hir_def::AdtId::EnumId(_) => return None,
1603                },
1604                _ => return None,
1605            };
1606            let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id]
1607                .is_visible_from(self.db, self.resolver.module());
1608            if !is_visible {
1609                if private_field.is_none() {
1610                    private_field = Some((field_id, parameters));
1611                }
1612                return None;
1613            }
1614            let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1615                .instantiate(interner, parameters);
1616            Some((Either::Left(field_id), ty))
1617        });
1618
1619        Some(match res {
1620            Some((field_id, ty)) => {
1621                let adjustments =
1622                    self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1623                let ty = self.process_remote_user_written_ty(ty);
1624
1625                (ty, field_id, adjustments, true)
1626            }
1627            None => {
1628                let (field_id, subst) = private_field?;
1629                let adjustments =
1630                    self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1631                let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1632                    .instantiate(self.interner(), subst);
1633                let ty = self.process_remote_user_written_ty(ty);
1634
1635                (ty, Either::Left(field_id), adjustments, false)
1636            }
1637        })
1638    }
1639
1640    fn infer_field_access(
1641        &mut self,
1642        tgt_expr: ExprId,
1643        receiver: ExprId,
1644        name: &Name,
1645        expected: &Expectation<'db>,
1646    ) -> Ty<'db> {
1647        // Field projections don't constitute reads.
1648        let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No);
1649        let receiver_ty = self.table.structurally_resolve_type(receiver_ty);
1650
1651        if name.is_missing() {
1652            // Bail out early, don't even try to look up field. Also, we don't issue an unresolved
1653            // field diagnostic because this is a syntax error rather than a semantic error.
1654            return self.err_ty();
1655        }
1656
1657        match self.lookup_field(receiver_ty, name) {
1658            Some((ty, field_id, adjustments, is_public)) => {
1659                self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1660                self.result.field_resolutions.insert(tgt_expr, field_id);
1661                if !is_public && let Either::Left(field) = field_id {
1662                    // FIXME: Merge this diagnostic into UnresolvedField?
1663                    self.push_diagnostic(InferenceDiagnostic::PrivateField {
1664                        expr: tgt_expr,
1665                        field,
1666                    });
1667                }
1668                ty
1669            }
1670            None => {
1671                // no field found, lets attempt to resolve it like a function so that IDE things
1672                // work out while people are typing
1673                let resolved = self.lookup_method_including_private(
1674                    receiver_ty,
1675                    name.clone(),
1676                    None,
1677                    receiver,
1678                    tgt_expr,
1679                );
1680                self.push_diagnostic(InferenceDiagnostic::UnresolvedField {
1681                    expr: tgt_expr,
1682                    receiver: receiver_ty,
1683                    name: name.clone(),
1684                    method_with_same_name_exists: resolved.is_ok(),
1685                });
1686                match resolved {
1687                    Ok((func, _is_visible)) => {
1688                        self.check_method_call(tgt_expr, &[], func.sig, receiver_ty, expected)
1689                    }
1690                    Err(_) => self.err_ty(),
1691                }
1692            }
1693        }
1694    }
1695
1696    fn instantiate_erroneous_method(&mut self, def_id: FunctionId) -> MethodCallee<'db> {
1697        // FIXME: Using fresh infer vars for the method args isn't optimal,
1698        // we can do better by going thorough the full probe/confirm machinery.
1699        let args = self.table.fresh_args_for_item(def_id.into());
1700        let sig = self.db.callable_item_signature(def_id.into()).instantiate(self.interner(), args);
1701        let sig =
1702            self.infcx().instantiate_binder_with_fresh_vars(BoundRegionConversionTime::FnCall, sig);
1703        MethodCallee { def_id, args, sig }
1704    }
1705
1706    fn infer_call(
1707        &mut self,
1708        tgt_expr: ExprId,
1709        callee: ExprId,
1710        args: &[ExprId],
1711        expected: &Expectation<'db>,
1712    ) -> Ty<'db> {
1713        let callee_ty = self.infer_expr(callee, &Expectation::none(), ExprIsRead::Yes);
1714        let callee_ty = self.table.try_structurally_resolve_type(callee_ty);
1715        let interner = self.interner();
1716        let mut derefs = InferenceContextAutoderef::new_from_inference_context(self, callee_ty);
1717        let (res, derefed_callee) = loop {
1718            let Some((callee_deref_ty, _)) = derefs.next() else {
1719                break (None, callee_ty);
1720            };
1721            if let Some(res) = derefs.ctx().table.callable_sig(callee_deref_ty, args.len()) {
1722                break (Some(res), callee_deref_ty);
1723            }
1724        };
1725        // if the function is unresolved, we use is_varargs=true to
1726        // suppress the arg count diagnostic here
1727        let is_varargs = derefed_callee.callable_sig(interner).is_some_and(|sig| sig.c_variadic())
1728            || res.is_none();
1729        let (param_tys, ret_ty) = match res {
1730            Some((func, params, ret_ty)) => {
1731                let infer_ok = derefs.adjust_steps_as_infer_ok();
1732                let mut adjustments = self.table.register_infer_ok(infer_ok);
1733                if let Some(fn_x) = func {
1734                    self.write_fn_trait_method_resolution(
1735                        fn_x,
1736                        derefed_callee,
1737                        &mut adjustments,
1738                        callee_ty,
1739                        &params,
1740                        tgt_expr,
1741                    );
1742                }
1743                if let TyKind::Closure(c, _) = self.table.resolve_completely(callee_ty).kind() {
1744                    self.add_current_closure_dependency(c.into());
1745                    self.deferred_closures.entry(c.into()).or_default().push((
1746                        derefed_callee,
1747                        callee_ty,
1748                        params.clone(),
1749                        tgt_expr,
1750                    ));
1751                }
1752                self.write_expr_adj(callee, adjustments.into_boxed_slice());
1753                (params, ret_ty)
1754            }
1755            None => {
1756                self.push_diagnostic(InferenceDiagnostic::ExpectedFunction {
1757                    call_expr: tgt_expr,
1758                    found: callee_ty,
1759                });
1760                (Vec::new(), Ty::new_error(interner, ErrorGuaranteed))
1761            }
1762        };
1763        let indices_to_skip = self.check_legacy_const_generics(derefed_callee, args);
1764        self.check_call(
1765            tgt_expr,
1766            args,
1767            callee_ty,
1768            &param_tys,
1769            ret_ty,
1770            &indices_to_skip,
1771            is_varargs,
1772            expected,
1773        )
1774    }
1775
1776    fn check_call(
1777        &mut self,
1778        tgt_expr: ExprId,
1779        args: &[ExprId],
1780        callee_ty: Ty<'db>,
1781        param_tys: &[Ty<'db>],
1782        ret_ty: Ty<'db>,
1783        indices_to_skip: &[u32],
1784        is_varargs: bool,
1785        expected: &Expectation<'db>,
1786    ) -> Ty<'db> {
1787        self.register_obligations_for_call(callee_ty);
1788
1789        self.check_call_arguments(
1790            tgt_expr,
1791            param_tys,
1792            ret_ty,
1793            expected,
1794            args,
1795            indices_to_skip,
1796            is_varargs,
1797        );
1798        ret_ty
1799    }
1800
1801    fn infer_method_call(
1802        &mut self,
1803        tgt_expr: ExprId,
1804        receiver: ExprId,
1805        args: &[ExprId],
1806        method_name: &Name,
1807        generic_args: Option<&HirGenericArgs>,
1808        expected: &Expectation<'db>,
1809    ) -> Ty<'db> {
1810        let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes);
1811        let receiver_ty = self.table.try_structurally_resolve_type(receiver_ty);
1812
1813        let resolved = self.lookup_method_including_private(
1814            receiver_ty,
1815            method_name.clone(),
1816            generic_args,
1817            receiver,
1818            tgt_expr,
1819        );
1820        match resolved {
1821            Ok((func, visible)) => {
1822                if !visible {
1823                    self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem {
1824                        id: tgt_expr.into(),
1825                        item: func.def_id.into(),
1826                    })
1827                }
1828                self.check_method_call(tgt_expr, args, func.sig, receiver_ty, expected)
1829            }
1830            // Failed to resolve, report diagnostic and try to resolve as call to field access or
1831            // assoc function
1832            Err(_) => {
1833                let field_with_same_name_exists = match self.lookup_field(receiver_ty, method_name)
1834                {
1835                    Some((ty, field_id, adjustments, _public)) => {
1836                        self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1837                        self.result.field_resolutions.insert(tgt_expr, field_id);
1838                        Some(ty)
1839                    }
1840                    None => None,
1841                };
1842
1843                let assoc_func_with_same_name = self.with_method_resolution(|ctx| {
1844                    if !matches!(
1845                        receiver_ty.kind(),
1846                        TyKind::Infer(InferTy::TyVar(_)) | TyKind::Error(_)
1847                    ) {
1848                        ctx.probe_for_name(
1849                            method_resolution::Mode::Path,
1850                            method_name.clone(),
1851                            receiver_ty,
1852                        )
1853                    } else {
1854                        Err(MethodError::ErrorReported)
1855                    }
1856                });
1857                let assoc_func_with_same_name = match assoc_func_with_same_name {
1858                    Ok(method_resolution::Pick {
1859                        item: CandidateId::FunctionId(def_id), ..
1860                    })
1861                    | Err(MethodError::PrivateMatch(method_resolution::Pick {
1862                        item: CandidateId::FunctionId(def_id),
1863                        ..
1864                    })) => Some(self.instantiate_erroneous_method(def_id)),
1865                    _ => None,
1866                };
1867
1868                self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
1869                    expr: tgt_expr,
1870                    receiver: receiver_ty,
1871                    name: method_name.clone(),
1872                    field_with_same_name: field_with_same_name_exists,
1873                    assoc_func_with_same_name: assoc_func_with_same_name.map(|it| it.def_id),
1874                });
1875
1876                let recovered = match assoc_func_with_same_name {
1877                    Some(it) => Some((
1878                        Ty::new_fn_def(
1879                            self.interner(),
1880                            CallableDefId::FunctionId(it.def_id).into(),
1881                            it.args,
1882                        ),
1883                        it.sig,
1884                        true,
1885                    )),
1886                    None => field_with_same_name_exists.and_then(|field_ty| {
1887                        let callable_sig = field_ty.callable_sig(self.interner())?;
1888                        Some((field_ty, callable_sig.skip_binder(), false))
1889                    }),
1890                };
1891                match recovered {
1892                    Some((callee_ty, sig, strip_first)) => self.check_call(
1893                        tgt_expr,
1894                        args,
1895                        callee_ty,
1896                        sig.inputs_and_output.inputs().get(strip_first as usize..).unwrap_or(&[]),
1897                        sig.output(),
1898                        &[],
1899                        true,
1900                        expected,
1901                    ),
1902                    None => {
1903                        for &arg in args.iter() {
1904                            self.infer_expr_no_expect(arg, ExprIsRead::Yes);
1905                        }
1906                        self.err_ty()
1907                    }
1908                }
1909            }
1910        }
1911    }
1912
1913    fn check_method_call(
1914        &mut self,
1915        tgt_expr: ExprId,
1916        args: &[ExprId],
1917        sig: FnSig<'db>,
1918        receiver_ty: Ty<'db>,
1919        expected: &Expectation<'db>,
1920    ) -> Ty<'db> {
1921        let (formal_receiver_ty, param_tys) = if !sig.inputs_and_output.inputs().is_empty() {
1922            (sig.inputs_and_output.as_slice()[0], &sig.inputs_and_output.inputs()[1..])
1923        } else {
1924            (self.types.error, &[] as _)
1925        };
1926        let ret_ty = sig.output();
1927        self.table.unify(formal_receiver_ty, receiver_ty);
1928
1929        self.check_call_arguments(tgt_expr, param_tys, ret_ty, expected, args, &[], sig.c_variadic);
1930        ret_ty
1931    }
1932
1933    /// Generic function that factors out common logic from function calls,
1934    /// method calls and overloaded operators.
1935    pub(in super::super) fn check_call_arguments(
1936        &mut self,
1937        call_expr: ExprId,
1938        // Types (as defined in the *signature* of the target function)
1939        formal_input_tys: &[Ty<'db>],
1940        formal_output: Ty<'db>,
1941        // Expected output from the parent expression or statement
1942        expectation: &Expectation<'db>,
1943        // The expressions for each provided argument
1944        provided_args: &[ExprId],
1945        skip_indices: &[u32],
1946        // Whether the function is variadic, for example when imported from C
1947        c_variadic: bool,
1948    ) {
1949        // First, let's unify the formal method signature with the expectation eagerly.
1950        // We use this to guide coercion inference; it's output is "fudged" which means
1951        // any remaining type variables are assigned to new, unrelated variables. This
1952        // is because the inference guidance here is only speculative.
1953        let formal_output = self.table.resolve_vars_with_obligations(formal_output);
1954        let expected_input_tys: Option<Vec<_>> = expectation
1955            .only_has_type(&mut self.table)
1956            .and_then(|expected_output| {
1957                self.table
1958                    .infer_ctxt
1959                    .fudge_inference_if_ok(|| {
1960                        let mut ocx = ObligationCtxt::new(&self.table.infer_ctxt);
1961
1962                        // Attempt to apply a subtyping relationship between the formal
1963                        // return type (likely containing type variables if the function
1964                        // is polymorphic) and the expected return type.
1965                        // No argument expectations are produced if unification fails.
1966                        let origin = ObligationCause::new();
1967                        ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?;
1968                        if !ocx.try_evaluate_obligations().is_empty() {
1969                            return Err(TypeError::Mismatch);
1970                        }
1971
1972                        // Record all the argument types, with the args
1973                        // produced from the above subtyping unification.
1974                        Ok(Some(
1975                            formal_input_tys
1976                                .iter()
1977                                .map(|&ty| self.table.infer_ctxt.resolve_vars_if_possible(ty))
1978                                .collect(),
1979                        ))
1980                    })
1981                    .ok()
1982            })
1983            .unwrap_or_default();
1984
1985        // If there are no external expectations at the call site, just use the types from the function defn
1986        let expected_input_tys = if let Some(expected_input_tys) = &expected_input_tys {
1987            assert_eq!(expected_input_tys.len(), formal_input_tys.len());
1988            expected_input_tys
1989        } else {
1990            formal_input_tys
1991        };
1992
1993        let minimum_input_count = expected_input_tys.len();
1994        let provided_arg_count = provided_args.len() - skip_indices.len();
1995
1996        // Keep track of whether we *could possibly* be satisfied, i.e. whether we're on the happy path
1997        // if the wrong number of arguments were supplied, we CAN'T be satisfied,
1998        // and if we're c_variadic, the supplied arguments must be >= the minimum count from the function
1999        // otherwise, they need to be identical, because rust doesn't currently support variadic functions
2000        let args_count_matches = if c_variadic {
2001            provided_arg_count >= minimum_input_count
2002        } else {
2003            provided_arg_count == minimum_input_count
2004        };
2005
2006        if !args_count_matches {
2007            self.push_diagnostic(InferenceDiagnostic::MismatchedArgCount {
2008                call_expr,
2009                expected: expected_input_tys.len() + skip_indices.len(),
2010                found: provided_args.len(),
2011            });
2012        }
2013
2014        // We introduce a helper function to demand that a given argument satisfy a given input
2015        // This is more complicated than just checking type equality, as arguments could be coerced
2016        // This version writes those types back so further type checking uses the narrowed types
2017        let demand_compatible = |this: &mut InferenceContext<'_, 'db>, idx| {
2018            let formal_input_ty: Ty<'db> = formal_input_tys[idx];
2019            let expected_input_ty: Ty<'db> = expected_input_tys[idx];
2020            let provided_arg = provided_args[idx];
2021
2022            debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
2023
2024            // We're on the happy path here, so we'll do a more involved check and write back types
2025            // To check compatibility, we'll do 3 things:
2026            // 1. Unify the provided argument with the expected type
2027            let expectation = Expectation::rvalue_hint(this, expected_input_ty);
2028
2029            let checked_ty = this.infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes);
2030
2031            // 2. Coerce to the most detailed type that could be coerced
2032            //    to, which is `expected_ty` if `rvalue_hint` returns an
2033            //    `ExpectHasType(expected_ty)`, or the `formal_ty` otherwise.
2034            let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
2035
2036            // Cause selection errors caused by resolving a single argument to point at the
2037            // argument and not the call. This lets us customize the span pointed to in the
2038            // fulfillment error to be more accurate.
2039            let coerced_ty = this.table.resolve_vars_with_obligations(coerced_ty);
2040
2041            let coerce_error = this
2042                .coerce(
2043                    provided_arg.into(),
2044                    checked_ty,
2045                    coerced_ty,
2046                    AllowTwoPhase::Yes,
2047                    ExprIsRead::Yes,
2048                )
2049                .err();
2050            if coerce_error.is_some() {
2051                return Err((coerce_error, coerced_ty, checked_ty));
2052            }
2053
2054            // 3. Check if the formal type is actually equal to the checked one
2055            //    and register any such obligations for future type checks.
2056            let formal_ty_error = this
2057                .table
2058                .infer_ctxt
2059                .at(&ObligationCause::new(), this.table.param_env)
2060                .eq(formal_input_ty, coerced_ty);
2061
2062            // If neither check failed, the types are compatible
2063            match formal_ty_error {
2064                Ok(InferOk { obligations, value: () }) => {
2065                    this.table.register_predicates(obligations);
2066                    Ok(())
2067                }
2068                Err(err) => Err((Some(err), coerced_ty, checked_ty)),
2069            }
2070        };
2071
2072        // Check the arguments.
2073        // We do this in a pretty awful way: first we type-check any arguments
2074        // that are not closures, then we type-check the closures. This is so
2075        // that we have more information about the types of arguments when we
2076        // type-check the functions. This isn't really the right way to do this.
2077        for check_closures in [false, true] {
2078            // More awful hacks: before we check argument types, try to do
2079            // an "opportunistic" trait resolution of any trait bounds on
2080            // the call. This helps coercions.
2081            if check_closures {
2082                self.table.select_obligations_where_possible();
2083            }
2084
2085            let mut skip_indices = skip_indices.iter().copied();
2086            // Check each argument, to satisfy the input it was provided for
2087            // Visually, we're traveling down the diagonal of the compatibility matrix
2088            for (idx, arg) in provided_args.iter().enumerate() {
2089                if skip_indices.clone().next() == Some(idx as u32) {
2090                    skip_indices.next();
2091                    continue;
2092                }
2093
2094                // For this check, we do *not* want to treat async coroutine closures (async blocks)
2095                // as proper closures. Doing so would regress type inference when feeding
2096                // the return value of an argument-position async block to an argument-position
2097                // closure wrapped in a block.
2098                // See <https://github.com/rust-lang/rust/issues/112225>.
2099                let is_closure = if let Expr::Closure { closure_kind, .. } = self.body[*arg] {
2100                    !matches!(closure_kind, ClosureKind::Coroutine(_))
2101                } else {
2102                    false
2103                };
2104                if is_closure != check_closures {
2105                    continue;
2106                }
2107
2108                if idx >= minimum_input_count {
2109                    // Make sure we've checked this expr at least once.
2110                    self.infer_expr_no_expect(*arg, ExprIsRead::Yes);
2111                    continue;
2112                }
2113
2114                if let Err((_error, expected, found)) = demand_compatible(self, idx)
2115                    && args_count_matches
2116                {
2117                    // Don't report type mismatches if there is a mismatch in args count.
2118                    self.result
2119                        .type_mismatches
2120                        .get_or_insert_default()
2121                        .insert((*arg).into(), TypeMismatch { expected, actual: found });
2122                }
2123            }
2124        }
2125
2126        if !args_count_matches {}
2127    }
2128
2129    fn register_obligations_for_call(&mut self, callable_ty: Ty<'db>) {
2130        let callable_ty = self.table.try_structurally_resolve_type(callable_ty);
2131        if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind() {
2132            let generic_predicates = GenericPredicates::query_all(
2133                self.db,
2134                GenericDefId::from_callable(self.db, fn_def.0),
2135            );
2136            let param_env = self.table.param_env;
2137            self.table.register_predicates(clauses_as_obligations(
2138                generic_predicates.iter_instantiated_copied(self.interner(), parameters.as_slice()),
2139                ObligationCause::new(),
2140                param_env,
2141            ));
2142            // add obligation for trait implementation, if this is a trait method
2143            match fn_def.0 {
2144                CallableDefId::FunctionId(f) => {
2145                    if let ItemContainerId::TraitId(trait_) = f.lookup(self.db).container {
2146                        // construct a TraitRef
2147                        let trait_params_len = generics(self.db, trait_.into()).len();
2148                        let substs = GenericArgs::new_from_iter(
2149                            self.interner(),
2150                            parameters.as_slice()[..trait_params_len].iter().copied(),
2151                        );
2152                        self.table.register_predicate(Obligation::new(
2153                            self.interner(),
2154                            ObligationCause::new(),
2155                            self.table.param_env,
2156                            TraitRef::new(self.interner(), trait_.into(), substs),
2157                        ));
2158                    }
2159                }
2160                CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
2161            }
2162        }
2163    }
2164
2165    /// Returns the argument indices to skip.
2166    fn check_legacy_const_generics(&mut self, callee: Ty<'db>, args: &[ExprId]) -> Box<[u32]> {
2167        let (func, _subst) = match callee.kind() {
2168            TyKind::FnDef(callable, subst) => {
2169                let func = match callable.0 {
2170                    CallableDefId::FunctionId(f) => f,
2171                    _ => return Default::default(),
2172                };
2173                (func, subst)
2174            }
2175            _ => return Default::default(),
2176        };
2177
2178        let data = self.db.function_signature(func);
2179        let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func)
2180        else {
2181            return Default::default();
2182        };
2183        let mut legacy_const_generics_indices = Box::<[u32]>::from(legacy_const_generics_indices);
2184
2185        // only use legacy const generics if the param count matches with them
2186        if data.params.len() + legacy_const_generics_indices.len() != args.len() {
2187            if args.len() <= data.params.len() {
2188                return Default::default();
2189            } else {
2190                // there are more parameters than there should be without legacy
2191                // const params; use them
2192                legacy_const_generics_indices.sort_unstable();
2193                return legacy_const_generics_indices;
2194            }
2195        }
2196
2197        // check legacy const parameters
2198        for arg_idx in legacy_const_generics_indices.iter().copied() {
2199            if arg_idx >= args.len() as u32 {
2200                continue;
2201            }
2202            let expected = Expectation::none(); // FIXME use actual const ty, when that is lowered correctly
2203            self.infer_expr(args[arg_idx as usize], &expected, ExprIsRead::Yes);
2204            // FIXME: evaluate and unify with the const
2205        }
2206        legacy_const_generics_indices.sort_unstable();
2207        legacy_const_generics_indices
2208    }
2209
2210    pub(super) fn with_breakable_ctx<T>(
2211        &mut self,
2212        kind: BreakableKind,
2213        ty: Option<Ty<'db>>,
2214        label: Option<LabelId>,
2215        cb: impl FnOnce(&mut Self) -> T,
2216    ) -> (Option<Ty<'db>>, T) {
2217        self.breakables.push({
2218            BreakableContext { kind, may_break: false, coerce: ty.map(CoerceMany::new), label }
2219        });
2220        let res = cb(self);
2221        let ctx = self.breakables.pop().expect("breakable stack broken");
2222        (if ctx.may_break { ctx.coerce.map(|ctx| ctx.complete(self)) } else { None }, res)
2223    }
2224}