Skip to main content

hir_ty/infer/
expr.rs

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