1use std::{iter::repeat_with, mem};
4
5use either::Either;
6use hir_def::{
7 FieldId, GenericDefId, ItemContainerId, Lookup, TupleFieldId, TupleId,
8 expr_store::path::{GenericArgs as HirGenericArgs, Path},
9 hir::{
10 Array, AsmOperand, AsmOptions, BinaryOp, BindingAnnotation, Expr, ExprId, ExprOrPatId,
11 LabelId, Literal, Pat, PatId, Statement, UnaryOp,
12 },
13 resolver::ValueNs,
14};
15use hir_def::{FunctionId, hir::ClosureKind};
16use hir_expand::name::Name;
17use rustc_ast_ir::Mutability;
18use rustc_type_ir::{
19 CoroutineArgs, CoroutineArgsParts, InferTy, Interner,
20 inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike, Ty as _},
21};
22use syntax::ast::RangeOp;
23use tracing::debug;
24
25use crate::{
26 Adjust, Adjustment, CallableDefId, DeclContext, DeclOrigin, Rawness,
27 autoderef::InferenceContextAutoderef,
28 consteval,
29 db::InternedCoroutine,
30 generics::generics,
31 infer::{
32 AllowTwoPhase, BreakableKind, coerce::CoerceMany, find_continuable,
33 pat::contains_explicit_ref_binding,
34 },
35 lower::{GenericPredicates, lower_mutability},
36 method_resolution::{self, CandidateId, MethodCallee, MethodError},
37 next_solver::{
38 ErrorGuaranteed, FnSig, GenericArgs, TraitRef, Ty, TyKind, TypeError,
39 infer::{
40 BoundRegionConversionTime, InferOk,
41 traits::{Obligation, ObligationCause},
42 },
43 obligation_ctxt::ObligationCtxt,
44 util::clauses_as_obligations,
45 },
46 traits::FnTrait,
47};
48
49use super::{
50 BreakableContext, Diverges, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch,
51 cast::CastCheck, find_breakable,
52};
53
54#[derive(Clone, Copy, PartialEq, Eq)]
55pub(crate) enum ExprIsRead {
56 Yes,
57 No,
58}
59
60impl<'db> InferenceContext<'_, 'db> {
61 pub(crate) fn infer_expr(
62 &mut self,
63 tgt_expr: ExprId,
64 expected: &Expectation<'db>,
65 is_read: ExprIsRead,
66 ) -> Ty<'db> {
67 let ty = self.infer_expr_inner(tgt_expr, expected, is_read);
68 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
69 let could_unify = self.unify(ty, expected_ty);
70 if !could_unify {
71 self.result
72 .type_mismatches
73 .get_or_insert_default()
74 .insert(tgt_expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
75 }
76 }
77 ty
78 }
79
80 pub(crate) fn infer_expr_no_expect(
81 &mut self,
82 tgt_expr: ExprId,
83 is_read: ExprIsRead,
84 ) -> Ty<'db> {
85 self.infer_expr_inner(tgt_expr, &Expectation::None, is_read)
86 }
87
88 pub(super) fn infer_expr_coerce(
91 &mut self,
92 expr: ExprId,
93 expected: &Expectation<'db>,
94 is_read: ExprIsRead,
95 ) -> Ty<'db> {
96 let ty = self.infer_expr_inner(expr, expected, is_read);
97 if let Some(target) = expected.only_has_type(&mut self.table) {
98 match self.coerce(expr.into(), ty, target, AllowTwoPhase::No, is_read) {
99 Ok(res) => res,
100 Err(_) => {
101 self.result
102 .type_mismatches
103 .get_or_insert_default()
104 .insert(expr.into(), TypeMismatch { expected: target, actual: ty });
105 target
106 }
107 }
108 } else {
109 ty
110 }
111 }
112
113 pub(super) fn expr_guaranteed_to_constitute_read_for_never(
125 &mut self,
126 expr: ExprId,
127 is_read: ExprIsRead,
128 ) -> bool {
129 if is_read == ExprIsRead::Yes {
133 return true;
134 }
135
136 if !self.is_syntactic_place_expr(expr) {
142 return true;
143 }
144
145 is_read == ExprIsRead::Yes
152 }
153
154 fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
158 match &self.body[pat] {
159 Pat::Wild => false,
161
162 Pat::Or(subpats) => {
171 subpats.iter().all(|pat| self.pat_guaranteed_to_constitute_read_for_never(*pat))
172 }
173
174 Pat::Bind { .. }
177 | Pat::TupleStruct { .. }
178 | Pat::Path(_)
179 | Pat::Tuple { .. }
180 | Pat::Box { .. }
181 | Pat::Ref { .. }
182 | Pat::Lit(_)
183 | Pat::Range { .. }
184 | Pat::Slice { .. }
185 | Pat::ConstBlock(_)
186 | Pat::Record { .. }
187 | Pat::Missing => true,
188 Pat::Expr(_) => unreachable!(
189 "we don't call pat_guaranteed_to_constitute_read_for_never() with assignments"
190 ),
191 }
192 }
193
194 fn contains_explicit_ref_binding(&self, pat: PatId) -> bool {
200 if let Pat::Bind { id, .. } = self.body[pat]
201 && matches!(self.body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
202 {
203 return true;
204 }
205
206 let mut result = false;
207 self.body.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
208 result
209 }
210
211 fn is_syntactic_place_expr(&self, expr: ExprId) -> bool {
212 match &self.body[expr] {
213 Expr::Path(Path::LangItem(_, _)) => false,
215 Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(),
216 Expr::Path(path) => self
217 .resolver
218 .resolve_path_in_value_ns_fully(self.db, path, self.body.expr_path_hygiene(expr))
219 .is_none_or(|res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))),
220 Expr::Underscore => true,
221 Expr::UnaryOp { op: UnaryOp::Deref, .. } => true,
222 Expr::Field { .. } | Expr::Index { .. } => true,
223 Expr::Call { .. }
224 | Expr::MethodCall { .. }
225 | Expr::Tuple { .. }
226 | Expr::If { .. }
227 | Expr::Match { .. }
228 | Expr::Closure { .. }
229 | Expr::Block { .. }
230 | Expr::Array(..)
231 | Expr::Break { .. }
232 | Expr::Continue { .. }
233 | Expr::Return { .. }
234 | Expr::Become { .. }
235 | Expr::Let { .. }
236 | Expr::Loop { .. }
237 | Expr::InlineAsm(..)
238 | Expr::OffsetOf(..)
239 | Expr::Literal(..)
240 | Expr::Const(..)
241 | Expr::UnaryOp { .. }
242 | Expr::BinaryOp { .. }
243 | Expr::Assignment { .. }
244 | Expr::Yield { .. }
245 | Expr::Cast { .. }
246 | Expr::Async { .. }
247 | Expr::Unsafe { .. }
248 | Expr::Await { .. }
249 | Expr::Ref { .. }
250 | Expr::Range { .. }
251 | Expr::Box { .. }
252 | Expr::RecordLit { .. }
253 | Expr::Yeet { .. }
254 | Expr::Missing => false,
255 }
256 }
257
258 #[expect(clippy::needless_return)]
259 pub(crate) fn check_lhs_assignable(&self, lhs: ExprId) {
260 if self.is_syntactic_place_expr(lhs) {
261 return;
262 }
263
264 }
266
267 fn infer_expr_coerce_never(
268 &mut self,
269 expr: ExprId,
270 expected: &Expectation<'db>,
271 is_read: ExprIsRead,
272 ) -> Ty<'db> {
273 let ty = self.infer_expr_inner(expr, expected, is_read);
274 if ty.is_never() {
277 if let Some(adjustments) = self.result.expr_adjustments.get(&expr) {
278 return if let [Adjustment { kind: Adjust::NeverToAny, target }] = &**adjustments {
279 *target
280 } else {
281 self.err_ty()
282 };
283 }
284
285 if let Some(target) = expected.only_has_type(&mut self.table) {
286 self.coerce(expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes)
287 .expect("never-to-any coercion should always succeed")
288 } else {
289 ty
290 }
291 } else {
292 if let Some(expected_ty) = expected.only_has_type(&mut self.table) {
293 let could_unify = self.unify(ty, expected_ty);
294 if !could_unify {
295 self.result
296 .type_mismatches
297 .get_or_insert_default()
298 .insert(expr.into(), TypeMismatch { expected: expected_ty, actual: ty });
299 }
300 }
301 ty
302 }
303 }
304
305 #[tracing::instrument(level = "debug", skip(self, is_read), ret)]
306 fn infer_expr_inner(
307 &mut self,
308 tgt_expr: ExprId,
309 expected: &Expectation<'db>,
310 is_read: ExprIsRead,
311 ) -> Ty<'db> {
312 self.db.unwind_if_revision_cancelled();
313
314 let expr = &self.body[tgt_expr];
315 tracing::trace!(?expr);
316 let ty = match expr {
317 Expr::Missing => self.err_ty(),
318 &Expr::If { condition, then_branch, else_branch } => {
319 let expected = &expected.adjust_for_branches(&mut self.table);
320 self.infer_expr_coerce_never(
321 condition,
322 &Expectation::HasType(self.types.bool),
323 ExprIsRead::Yes,
324 );
325
326 let condition_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
327
328 let then_ty = self.infer_expr_inner(then_branch, expected, ExprIsRead::Yes);
329 let then_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
330 let mut coercion_sites = [then_branch, tgt_expr];
331 if let Some(else_branch) = else_branch {
332 coercion_sites[1] = else_branch;
333 }
334 let mut coerce = CoerceMany::with_coercion_sites(
335 expected.coercion_target_type(&mut self.table),
336 &coercion_sites,
337 );
338 coerce.coerce(self, &ObligationCause::new(), then_branch, then_ty, ExprIsRead::Yes);
339 match else_branch {
340 Some(else_branch) => {
341 let else_ty = self.infer_expr_inner(else_branch, expected, ExprIsRead::Yes);
342 let else_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
343 coerce.coerce(
344 self,
345 &ObligationCause::new(),
346 else_branch,
347 else_ty,
348 ExprIsRead::Yes,
349 );
350 self.diverges = condition_diverges | then_diverges & else_diverges;
351 }
352 None => {
353 coerce.coerce_forced_unit(
354 self,
355 tgt_expr,
356 &ObligationCause::new(),
357 true,
358 ExprIsRead::Yes,
359 );
360 self.diverges = condition_diverges;
361 }
362 }
363
364 coerce.complete(self)
365 }
366 &Expr::Let { pat, expr } => {
367 let child_is_read = if self.pat_guaranteed_to_constitute_read_for_never(pat) {
368 ExprIsRead::Yes
369 } else {
370 ExprIsRead::No
371 };
372 let input_ty = self.infer_expr(expr, &Expectation::none(), child_is_read);
373 self.infer_top_pat(
374 pat,
375 input_ty,
376 Some(DeclContext { origin: DeclOrigin::LetExpr }),
377 );
378 self.types.bool
379 }
380 Expr::Block { statements, tail, label, id: _ } => {
381 self.infer_block(tgt_expr, statements, *tail, *label, expected)
382 }
383 Expr::Unsafe { id: _, statements, tail } => {
384 self.infer_block(tgt_expr, statements, *tail, None, expected)
385 }
386 Expr::Const(id) => {
387 self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
388 this.infer_expr(*id, expected, ExprIsRead::Yes)
389 })
390 .1
391 }
392 Expr::Async { id: _, statements, tail } => {
393 self.infer_async_block(tgt_expr, statements, tail)
394 }
395 &Expr::Loop { body, label } => {
396 let ty = self.table.next_ty_var();
399 let (breaks, ()) =
400 self.with_breakable_ctx(BreakableKind::Loop, Some(ty), label, |this| {
401 this.infer_expr(
402 body,
403 &Expectation::HasType(this.types.unit),
404 ExprIsRead::Yes,
405 );
406 });
407
408 match breaks {
409 Some(breaks) => {
410 self.diverges = Diverges::Maybe;
411 breaks
412 }
413 None => self.types.never,
414 }
415 }
416 Expr::Closure { body, args, ret_type, arg_types, closure_kind, capture_by: _ } => self
417 .infer_closure(
418 *body,
419 args,
420 *ret_type,
421 arg_types,
422 *closure_kind,
423 tgt_expr,
424 expected,
425 ),
426 Expr::Call { callee, args, .. } => self.infer_call(tgt_expr, *callee, args, expected),
427 Expr::MethodCall { receiver, args, method_name, generic_args } => self
428 .infer_method_call(
429 tgt_expr,
430 *receiver,
431 args,
432 method_name,
433 generic_args.as_deref(),
434 expected,
435 ),
436 Expr::Match { expr, arms } => {
437 let mut scrutinee_is_read = true;
438 let mut contains_ref_bindings = false;
439 for arm in arms {
440 scrutinee_is_read &= self.pat_guaranteed_to_constitute_read_for_never(arm.pat);
441 contains_ref_bindings |= self.contains_explicit_ref_binding(arm.pat);
442 }
443 let scrutinee_is_read =
444 if scrutinee_is_read { ExprIsRead::Yes } else { ExprIsRead::No };
445 let input_ty = self.demand_scrutinee_type(
446 *expr,
447 contains_ref_bindings,
448 arms.is_empty(),
449 scrutinee_is_read,
450 );
451
452 if arms.is_empty() {
453 self.diverges = Diverges::Always;
454 self.types.never
455 } else {
456 let matchee_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
457 let mut all_arms_diverge = Diverges::Always;
458 for arm in arms.iter() {
459 self.infer_top_pat(arm.pat, input_ty, None);
460 }
461
462 let expected = expected.adjust_for_branches(&mut self.table);
463 let result_ty = match &expected {
464 Expectation::HasType(ty) if *ty != self.types.unit => *ty,
467 _ => self.table.next_ty_var(),
468 };
469 let mut coerce = CoerceMany::new(result_ty);
470
471 for arm in arms.iter() {
472 if let Some(guard_expr) = arm.guard {
473 self.diverges = Diverges::Maybe;
474 self.infer_expr_coerce_never(
475 guard_expr,
476 &Expectation::HasType(self.types.bool),
477 ExprIsRead::Yes,
478 );
479 }
480 self.diverges = Diverges::Maybe;
481
482 let arm_ty = self.infer_expr_inner(arm.expr, &expected, ExprIsRead::Yes);
483 all_arms_diverge &= self.diverges;
484 coerce.coerce(
485 self,
486 &ObligationCause::new(),
487 arm.expr,
488 arm_ty,
489 ExprIsRead::Yes,
490 );
491 }
492
493 self.diverges = matchee_diverges | all_arms_diverge;
494
495 coerce.complete(self)
496 }
497 }
498 Expr::Path(p) => self.infer_expr_path(p, tgt_expr.into(), tgt_expr),
499 &Expr::Continue { label } => {
500 if find_continuable(&mut self.breakables, label).is_none() {
501 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
502 expr: tgt_expr,
503 is_break: false,
504 bad_value_break: false,
505 });
506 };
507 self.types.never
508 }
509 &Expr::Break { expr, label } => {
510 let val_ty = if let Some(expr) = expr {
511 let opt_coerce_to = match find_breakable(&mut self.breakables, label) {
512 Some(ctxt) => match &ctxt.coerce {
513 Some(coerce) => coerce.expected_ty(),
514 None => {
515 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
516 expr: tgt_expr,
517 is_break: true,
518 bad_value_break: true,
519 });
520 self.err_ty()
521 }
522 },
523 None => self.err_ty(),
524 };
525 self.infer_expr_inner(
526 expr,
527 &Expectation::HasType(opt_coerce_to),
528 ExprIsRead::Yes,
529 )
530 } else {
531 self.types.unit
532 };
533
534 match find_breakable(&mut self.breakables, label) {
535 Some(ctxt) => match ctxt.coerce.take() {
536 Some(mut coerce) => {
537 coerce.coerce(
538 self,
539 &ObligationCause::new(),
540 expr.unwrap_or(tgt_expr),
541 val_ty,
542 ExprIsRead::Yes,
543 );
544
545 let ctxt = find_breakable(&mut self.breakables, label)
547 .expect("breakable stack changed during coercion");
548 ctxt.may_break = true;
549 ctxt.coerce = Some(coerce);
550 }
551 None => ctxt.may_break = true,
552 },
553 None => {
554 self.push_diagnostic(InferenceDiagnostic::BreakOutsideOfLoop {
555 expr: tgt_expr,
556 is_break: true,
557 bad_value_break: false,
558 });
559 }
560 }
561 self.types.never
562 }
563 &Expr::Return { expr } => self.infer_expr_return(tgt_expr, expr),
564 &Expr::Become { expr } => self.infer_expr_become(expr),
565 Expr::Yield { expr } => {
566 if let Some((resume_ty, yield_ty)) = self.resume_yield_tys {
567 if let Some(expr) = expr {
568 self.infer_expr_coerce(
569 *expr,
570 &Expectation::has_type(yield_ty),
571 ExprIsRead::Yes,
572 );
573 } else {
574 let unit = self.types.unit;
575 let _ = self.coerce(
576 tgt_expr.into(),
577 unit,
578 yield_ty,
579 AllowTwoPhase::No,
580 ExprIsRead::Yes,
581 );
582 }
583 resume_ty
584 } else {
585 self.types.error
587 }
588 }
589 Expr::Yeet { expr } => {
590 if let &Some(expr) = expr {
591 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
592 }
593 self.types.never
594 }
595 Expr::RecordLit { path, fields, spread, .. } => {
596 let (ty, def_id) = self.resolve_variant(tgt_expr.into(), path.as_deref(), false);
597
598 if let Some(t) = expected.only_has_type(&mut self.table) {
599 self.unify(ty, t);
600 }
601
602 let substs = ty.as_adt().map(|(_, s)| s).unwrap_or(self.types.empty_args);
603 if let Some(variant) = def_id {
604 self.write_variant_resolution(tgt_expr.into(), variant);
605 }
606 match def_id {
607 _ if fields.is_empty() => {}
608 Some(def) => {
609 let field_types = self.db.field_types(def);
610 let variant_data = def.fields(self.db);
611 let visibilities = self.db.field_visibilities(def);
612 for field in fields.iter() {
613 let field_def = {
614 match variant_data.field(&field.name) {
615 Some(local_id) => {
616 if !visibilities[local_id]
617 .is_visible_from(self.db, self.resolver.module())
618 {
619 self.push_diagnostic(
620 InferenceDiagnostic::NoSuchField {
621 field: field.expr.into(),
622 private: Some(local_id),
623 variant: def,
624 },
625 );
626 }
627 Some(local_id)
628 }
629 None => {
630 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
631 field: field.expr.into(),
632 private: None,
633 variant: def,
634 });
635 None
636 }
637 }
638 };
639 let field_ty = field_def.map_or(self.err_ty(), |it| {
640 field_types[it].instantiate(self.interner(), &substs)
641 });
642
643 let field_ty = self.insert_type_vars(field_ty);
646 self.infer_expr_coerce(
647 field.expr,
648 &Expectation::has_type(field_ty),
649 ExprIsRead::Yes,
650 );
651 }
652 }
653 None => {
654 for field in fields.iter() {
655 self.infer_expr_coerce(field.expr, &Expectation::None, ExprIsRead::No);
657 }
658 }
659 }
660 if let Some(expr) = spread {
661 self.infer_expr(*expr, &Expectation::has_type(ty), ExprIsRead::Yes);
662 }
663 ty
664 }
665 Expr::Field { expr, name } => self.infer_field_access(tgt_expr, *expr, name, expected),
666 Expr::Await { expr } => {
667 let inner_ty = self.infer_expr_inner(*expr, &Expectation::none(), ExprIsRead::Yes);
668 self.resolve_associated_type(inner_ty, self.resolve_future_future_output())
669 }
670 Expr::Cast { expr, type_ref } => {
671 let cast_ty = self.make_body_ty(*type_ref);
672 let expr_ty =
673 self.infer_expr(*expr, &Expectation::Castable(cast_ty), ExprIsRead::Yes);
674 self.deferred_cast_checks.push(CastCheck::new(tgt_expr, *expr, expr_ty, cast_ty));
675 cast_ty
676 }
677 Expr::Ref { expr, rawness, mutability } => {
678 let mutability = lower_mutability(*mutability);
679 let expectation = if let Some((exp_inner, exp_rawness, exp_mutability)) = expected
680 .only_has_type(&mut self.table)
681 .as_ref()
682 .and_then(|t| t.as_reference_or_ptr())
683 {
684 if exp_mutability == Mutability::Mut && mutability == Mutability::Not {
685 }
688 if exp_rawness == Rawness::Ref && *rawness == Rawness::RawPtr {
689 }
692 Expectation::rvalue_hint(self, exp_inner)
693 } else {
694 Expectation::none()
695 };
696 let inner_ty = self.infer_expr_inner(*expr, &expectation, ExprIsRead::Yes);
697 match rawness {
698 Rawness::RawPtr => Ty::new_ptr(self.interner(), inner_ty, mutability),
699 Rawness::Ref => {
700 let lt = self.table.next_region_var();
701 Ty::new_ref(self.interner(), lt, inner_ty, mutability)
702 }
703 }
704 }
705 &Expr::Box { expr } => self.infer_expr_box(expr, expected),
706 Expr::UnaryOp { expr, op } => self.infer_unop_expr(*op, *expr, expected, tgt_expr),
707 Expr::BinaryOp { lhs, rhs, op } => match op {
708 Some(BinaryOp::Assignment { op: Some(op) }) => {
709 self.infer_assign_op_expr(tgt_expr, *op, *lhs, *rhs)
710 }
711 Some(op) => self.infer_binop_expr(tgt_expr, *op, *lhs, *rhs),
712 None => self.err_ty(),
713 },
714 &Expr::Assignment { target, value } => {
715 let lhs_ty = match &self.body[target] {
721 &Pat::Expr(expr) => {
723 Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No))
724 }
725 Pat::Path(path) => {
726 let resolver_guard =
727 self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
728 let resolution = self.resolver.resolve_path_in_value_ns_fully(
729 self.db,
730 path,
731 self.body.pat_path_hygiene(target),
732 );
733 self.resolver.reset_to_guard(resolver_guard);
734
735 if matches!(
736 resolution,
737 Some(
738 ValueNs::ConstId(_)
739 | ValueNs::StructId(_)
740 | ValueNs::EnumVariantId(_)
741 )
742 ) {
743 None
744 } else {
745 Some(self.infer_expr_path(path, target.into(), tgt_expr))
746 }
747 }
748 _ => None,
749 };
750 let is_destructuring_assignment = lhs_ty.is_none();
751
752 if let Some(lhs_ty) = lhs_ty {
753 self.write_pat_ty(target, lhs_ty);
754 self.infer_expr_coerce(value, &Expectation::has_type(lhs_ty), ExprIsRead::No);
755 } else {
756 let rhs_ty = self.infer_expr(value, &Expectation::none(), ExprIsRead::Yes);
757 let resolver_guard =
758 self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
759 self.inside_assignment = true;
760 self.infer_top_pat(target, rhs_ty, None);
761 self.inside_assignment = false;
762 self.resolver.reset_to_guard(resolver_guard);
763 }
764 if is_destructuring_assignment && self.diverges.is_always() {
765 self.table.new_maybe_never_var()
770 } else {
771 self.types.unit
772 }
773 }
774 Expr::Range { lhs, rhs, range_type } => {
775 let lhs_ty =
776 lhs.map(|e| self.infer_expr_inner(e, &Expectation::none(), ExprIsRead::Yes));
777 let rhs_expect = lhs_ty.map_or_else(Expectation::none, Expectation::has_type);
778 let rhs_ty = rhs.map(|e| self.infer_expr(e, &rhs_expect, ExprIsRead::Yes));
779 let single_arg_adt = |adt, ty: Ty<'db>| {
780 Ty::new_adt(
781 self.interner(),
782 adt,
783 GenericArgs::new_from_iter(self.interner(), [ty.into()]),
784 )
785 };
786 match (range_type, lhs_ty, rhs_ty) {
787 (RangeOp::Exclusive, None, None) => match self.resolve_range_full() {
788 Some(adt) => Ty::new_adt(self.interner(), adt, self.types.empty_args),
789 None => self.err_ty(),
790 },
791 (RangeOp::Exclusive, None, Some(ty)) => match self.resolve_range_to() {
792 Some(adt) => single_arg_adt(adt, ty),
793 None => self.err_ty(),
794 },
795 (RangeOp::Inclusive, None, Some(ty)) => {
796 match self.resolve_range_to_inclusive() {
797 Some(adt) => single_arg_adt(adt, ty),
798 None => self.err_ty(),
799 }
800 }
801 (RangeOp::Exclusive, Some(_), Some(ty)) => match self.resolve_range() {
802 Some(adt) => single_arg_adt(adt, ty),
803 None => self.err_ty(),
804 },
805 (RangeOp::Inclusive, Some(_), Some(ty)) => {
806 match self.resolve_range_inclusive() {
807 Some(adt) => single_arg_adt(adt, ty),
808 None => self.err_ty(),
809 }
810 }
811 (RangeOp::Exclusive, Some(ty), None) => match self.resolve_range_from() {
812 Some(adt) => single_arg_adt(adt, ty),
813 None => self.err_ty(),
814 },
815 (RangeOp::Inclusive, _, None) => self.err_ty(),
816 }
817 }
818 Expr::Index { base, index } => {
819 let base_t = self.infer_expr_no_expect(*base, ExprIsRead::Yes);
820 let idx_t = self.infer_expr_no_expect(*index, ExprIsRead::Yes);
821
822 let base_t = self.table.structurally_resolve_type(base_t);
823 match self.lookup_indexing(tgt_expr, *base, base_t, idx_t) {
824 Some((trait_index_ty, trait_element_ty)) => {
825 self.demand_coerce(
827 *index,
828 idx_t,
829 trait_index_ty,
830 AllowTwoPhase::No,
831 ExprIsRead::Yes,
832 );
833 self.table.select_obligations_where_possible();
834 trait_element_ty
835 }
836 None => self.types.error,
838 }
839 }
840 Expr::Tuple { exprs, .. } => {
841 let mut tys = match expected
842 .only_has_type(&mut self.table)
843 .map(|t| self.table.try_structurally_resolve_type(t).kind())
844 {
845 Some(TyKind::Tuple(substs)) => substs
846 .iter()
847 .chain(repeat_with(|| self.table.next_ty_var()))
848 .take(exprs.len())
849 .collect::<Vec<_>>(),
850 _ => (0..exprs.len()).map(|_| self.table.next_ty_var()).collect(),
851 };
852
853 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
854 *ty =
855 self.infer_expr_coerce(*expr, &Expectation::has_type(*ty), ExprIsRead::Yes);
856 }
857
858 Ty::new_tup(self.interner(), &tys)
859 }
860 Expr::Array(array) => self.infer_expr_array(array, expected),
861 Expr::Literal(lit) => match lit {
862 Literal::Bool(..) => self.types.bool,
863 Literal::String(..) => self.types.static_str_ref,
864 Literal::ByteString(bs) => {
865 let byte_type = self.types.u8;
866
867 let len = consteval::usize_const(
868 self.db,
869 Some(bs.len() as u128),
870 self.resolver.krate(),
871 );
872
873 let array_type = Ty::new_array_with_const_len(self.interner(), byte_type, len);
874 Ty::new_ref(self.interner(), self.types.re_static, array_type, Mutability::Not)
875 }
876 Literal::CString(..) => Ty::new_ref(
877 self.interner(),
878 self.types.re_static,
879 self.lang_items.CStr.map_or_else(
880 || self.err_ty(),
881 |strukt| Ty::new_adt(self.interner(), strukt.into(), self.types.empty_args),
882 ),
883 Mutability::Not,
884 ),
885 Literal::Char(..) => self.types.char,
886 Literal::Int(_v, ty) => match ty {
887 Some(int_ty) => match int_ty {
888 hir_def::builtin_type::BuiltinInt::Isize => self.types.isize,
889 hir_def::builtin_type::BuiltinInt::I8 => self.types.i8,
890 hir_def::builtin_type::BuiltinInt::I16 => self.types.i16,
891 hir_def::builtin_type::BuiltinInt::I32 => self.types.i32,
892 hir_def::builtin_type::BuiltinInt::I64 => self.types.i64,
893 hir_def::builtin_type::BuiltinInt::I128 => self.types.i128,
894 },
895 None => {
896 let expected_ty = expected.to_option(&mut self.table);
897 tracing::debug!(?expected_ty);
898 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
899 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
900 Some(TyKind::Char) => Some(self.types.u8),
901 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
902 Some(self.types.usize)
903 }
904 _ => None,
905 };
906 opt_ty.unwrap_or_else(|| self.table.next_int_var())
907 }
908 },
909 Literal::Uint(_v, ty) => match ty {
910 Some(int_ty) => match int_ty {
911 hir_def::builtin_type::BuiltinUint::Usize => self.types.usize,
912 hir_def::builtin_type::BuiltinUint::U8 => self.types.u8,
913 hir_def::builtin_type::BuiltinUint::U16 => self.types.u16,
914 hir_def::builtin_type::BuiltinUint::U32 => self.types.u32,
915 hir_def::builtin_type::BuiltinUint::U64 => self.types.u64,
916 hir_def::builtin_type::BuiltinUint::U128 => self.types.u128,
917 },
918 None => {
919 let expected_ty = expected.to_option(&mut self.table);
920 let opt_ty = match expected_ty.as_ref().map(|it| it.kind()) {
921 Some(TyKind::Int(_) | TyKind::Uint(_)) => expected_ty,
922 Some(TyKind::Char) => Some(self.types.u8),
923 Some(TyKind::RawPtr(..) | TyKind::FnDef(..) | TyKind::FnPtr(..)) => {
924 Some(self.types.usize)
925 }
926 _ => None,
927 };
928 opt_ty.unwrap_or_else(|| self.table.next_int_var())
929 }
930 },
931 Literal::Float(_v, ty) => match ty {
932 Some(float_ty) => match float_ty {
933 hir_def::builtin_type::BuiltinFloat::F16 => self.types.f16,
934 hir_def::builtin_type::BuiltinFloat::F32 => self.types.f32,
935 hir_def::builtin_type::BuiltinFloat::F64 => self.types.f64,
936 hir_def::builtin_type::BuiltinFloat::F128 => self.types.f128,
937 },
938 None => {
939 let opt_ty = expected
940 .to_option(&mut self.table)
941 .filter(|ty| matches!(ty.kind(), TyKind::Float(_)));
942 opt_ty.unwrap_or_else(|| self.table.next_float_var())
943 }
944 },
945 },
946 Expr::Underscore => {
947 let expected = expected.to_option(&mut self.table).unwrap_or_else(|| self.err_ty());
950 self.push_diagnostic(InferenceDiagnostic::TypedHole { expr: tgt_expr, expected });
951 expected
952 }
953 Expr::OffsetOf(_) => self.types.usize,
954 Expr::InlineAsm(asm) => {
955 let check_expr_asm_operand = |this: &mut Self, expr, is_input: bool| {
956 let ty = this.infer_expr_no_expect(expr, ExprIsRead::Yes);
957
958 if is_input {
966 let ty = this.table.structurally_resolve_type(ty);
967 match ty.kind() {
968 TyKind::FnDef(def, parameters) => {
969 let fnptr_ty = Ty::new_fn_ptr(
970 this.interner(),
971 this.interner()
972 .fn_sig(def)
973 .instantiate(this.interner(), parameters),
974 );
975 _ = this.coerce(
976 expr.into(),
977 ty,
978 fnptr_ty,
979 AllowTwoPhase::No,
980 ExprIsRead::Yes,
981 );
982 }
983 TyKind::Ref(_, base_ty, mutbl) => {
984 let ptr_ty = Ty::new_ptr(this.interner(), base_ty, mutbl);
985 _ = this.coerce(
986 expr.into(),
987 ty,
988 ptr_ty,
989 AllowTwoPhase::No,
990 ExprIsRead::Yes,
991 );
992 }
993 _ => {}
994 }
995 }
996 };
997
998 let diverge = asm.options.contains(AsmOptions::NORETURN);
999 asm.operands.iter().for_each(|(_, operand)| match *operand {
1000 AsmOperand::In { expr, .. } => check_expr_asm_operand(self, expr, true),
1001 AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
1002 check_expr_asm_operand(self, expr, false)
1003 }
1004 AsmOperand::Out { expr: None, .. } => (),
1005 AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
1006 check_expr_asm_operand(self, in_expr, true);
1007 if let Some(out_expr) = out_expr {
1008 check_expr_asm_operand(self, out_expr, false);
1009 }
1010 }
1011 AsmOperand::Label(expr) => {
1012 self.infer_expr(
1013 expr,
1014 &Expectation::HasType(self.types.unit),
1015 ExprIsRead::No,
1016 );
1017 }
1018 AsmOperand::Const(expr) => {
1019 self.infer_expr(expr, &Expectation::None, ExprIsRead::No);
1020 }
1021 AsmOperand::Sym(_) => (),
1023 });
1024 if diverge { self.types.never } else { self.types.unit }
1025 }
1026 };
1027 let ty = self.insert_type_vars_shallow(ty);
1029 self.write_expr_ty(tgt_expr, ty);
1030 if self.shallow_resolve(ty).is_never()
1031 && self.expr_guaranteed_to_constitute_read_for_never(tgt_expr, is_read)
1032 {
1033 self.diverges = Diverges::Always;
1035 }
1036 ty
1037 }
1038
1039 fn demand_scrutinee_type(
1040 &mut self,
1041 scrut: ExprId,
1042 contains_ref_bindings: bool,
1043 no_arms: bool,
1044 scrutinee_is_read: ExprIsRead,
1045 ) -> Ty<'db> {
1046 if contains_ref_bindings || no_arms {
1099 self.infer_expr_no_expect(scrut, scrutinee_is_read)
1100 } else {
1101 let scrut_ty = self.table.next_ty_var();
1105 self.infer_expr_coerce_never(scrut, &Expectation::HasType(scrut_ty), scrutinee_is_read);
1106 scrut_ty
1107 }
1108 }
1109
1110 fn infer_expr_path(&mut self, path: &Path, id: ExprOrPatId, scope_id: ExprId) -> Ty<'db> {
1111 let g = self.resolver.update_to_inner_scope(self.db, self.owner, scope_id);
1112 let ty = match self.infer_path(path, id) {
1113 Some(ty) => ty,
1114 None => {
1115 if path.mod_path().is_some_and(|mod_path| mod_path.is_ident() || mod_path.is_self())
1116 {
1117 self.push_diagnostic(InferenceDiagnostic::UnresolvedIdent { id });
1118 }
1119 self.err_ty()
1120 }
1121 };
1122 self.resolver.reset_to_guard(g);
1123 ty
1124 }
1125
1126 fn infer_unop_expr(
1127 &mut self,
1128 unop: UnaryOp,
1129 oprnd: ExprId,
1130 expected: &Expectation<'db>,
1131 expr: ExprId,
1132 ) -> Ty<'db> {
1133 let expected_inner = match unop {
1134 UnaryOp::Not | UnaryOp::Neg => expected,
1135 UnaryOp::Deref => &Expectation::None,
1136 };
1137 let mut oprnd_t = self.infer_expr_inner(oprnd, expected_inner, ExprIsRead::Yes);
1138
1139 oprnd_t = self.table.structurally_resolve_type(oprnd_t);
1140 match unop {
1141 UnaryOp::Deref => {
1142 if let Some(ty) = self.lookup_derefing(expr, oprnd, oprnd_t) {
1143 oprnd_t = ty;
1144 } else {
1145 oprnd_t = self.types.error;
1147 }
1148 }
1149 UnaryOp::Not => {
1150 let result = self.infer_user_unop(expr, oprnd_t, unop);
1151 if !(oprnd_t.is_integral() || oprnd_t.kind() == TyKind::Bool) {
1153 oprnd_t = result;
1154 }
1155 }
1156 UnaryOp::Neg => {
1157 let result = self.infer_user_unop(expr, oprnd_t, unop);
1158 if !oprnd_t.is_numeric() {
1160 oprnd_t = result;
1161 }
1162 }
1163 }
1164 oprnd_t
1165 }
1166
1167 fn infer_async_block(
1168 &mut self,
1169 tgt_expr: ExprId,
1170 statements: &[Statement],
1171 tail: &Option<ExprId>,
1172 ) -> Ty<'db> {
1173 let ret_ty = self.table.next_ty_var();
1174 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
1175 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty);
1176 let prev_ret_coercion = self.return_coercion.replace(CoerceMany::new(ret_ty));
1177
1178 let expected = &Expectation::has_type(ret_ty);
1180 let (_, inner_ty) = self.with_breakable_ctx(BreakableKind::Border, None, None, |this| {
1181 let ty = this.infer_block(tgt_expr, statements, *tail, None, expected);
1182 if let Some(target) = expected.only_has_type(&mut this.table) {
1183 match this.coerce(tgt_expr.into(), ty, target, AllowTwoPhase::No, ExprIsRead::Yes) {
1184 Ok(res) => res,
1185 Err(_) => {
1186 this.result
1187 .type_mismatches
1188 .get_or_insert_default()
1189 .insert(tgt_expr.into(), TypeMismatch { expected: target, actual: ty });
1190 target
1191 }
1192 }
1193 } else {
1194 ty
1195 }
1196 });
1197
1198 self.diverges = prev_diverges;
1199 self.return_ty = prev_ret_ty;
1200 self.return_coercion = prev_ret_coercion;
1201
1202 self.lower_async_block_type_impl_trait(inner_ty, tgt_expr)
1203 }
1204
1205 pub(crate) fn lower_async_block_type_impl_trait(
1206 &mut self,
1207 inner_ty: Ty<'db>,
1208 tgt_expr: ExprId,
1209 ) -> Ty<'db> {
1210 let coroutine_id = InternedCoroutine(self.owner, tgt_expr);
1211 let coroutine_id = self.db.intern_coroutine(coroutine_id).into();
1212 let parent_args = GenericArgs::identity_for_item(self.interner(), self.generic_def.into());
1213 Ty::new_coroutine(
1214 self.interner(),
1215 coroutine_id,
1216 CoroutineArgs::new(
1217 self.interner(),
1218 CoroutineArgsParts {
1219 parent_args,
1220 kind_ty: self.types.unit,
1221 resume_ty: self.types.unit,
1223 yield_ty: self.types.unit,
1224 return_ty: inner_ty,
1225 tupled_upvars_ty: self.types.unit,
1227 },
1228 )
1229 .args,
1230 )
1231 }
1232
1233 pub(crate) fn write_fn_trait_method_resolution(
1234 &mut self,
1235 fn_x: FnTrait,
1236 derefed_callee: Ty<'db>,
1237 adjustments: &mut Vec<Adjustment<'db>>,
1238 callee_ty: Ty<'db>,
1239 params: &[Ty<'db>],
1240 tgt_expr: ExprId,
1241 ) {
1242 match fn_x {
1243 FnTrait::FnOnce | FnTrait::AsyncFnOnce => (),
1244 FnTrait::FnMut | FnTrait::AsyncFnMut => {
1245 if let TyKind::Ref(lt, inner, Mutability::Mut) = derefed_callee.kind() {
1246 if adjustments
1247 .last()
1248 .map(|it| matches!(it.kind, Adjust::Borrow(_)))
1249 .unwrap_or(true)
1250 {
1251 adjustments.push(Adjustment { kind: Adjust::Deref(None), target: inner });
1253 adjustments.push(Adjustment::borrow(
1254 self.interner(),
1255 Mutability::Mut,
1256 inner,
1257 lt,
1258 ))
1259 }
1260 } else {
1261 adjustments.push(Adjustment::borrow(
1262 self.interner(),
1263 Mutability::Mut,
1264 derefed_callee,
1265 self.table.next_region_var(),
1266 ));
1267 }
1268 }
1269 FnTrait::Fn | FnTrait::AsyncFn => {
1270 if !matches!(derefed_callee.kind(), TyKind::Ref(_, _, Mutability::Not)) {
1271 adjustments.push(Adjustment::borrow(
1272 self.interner(),
1273 Mutability::Not,
1274 derefed_callee,
1275 self.table.next_region_var(),
1276 ));
1277 }
1278 }
1279 }
1280 let Some(trait_) = fn_x.get_id(self.lang_items) else {
1281 return;
1282 };
1283 let trait_data = trait_.trait_items(self.db);
1284 if let Some(func) = trait_data.method_by_name(&fn_x.method_name()) {
1285 let subst = GenericArgs::new_from_iter(
1286 self.interner(),
1287 [
1288 callee_ty.into(),
1289 Ty::new_tup_from_iter(self.interner(), params.iter().copied()).into(),
1290 ],
1291 );
1292 self.write_method_resolution(tgt_expr, func, subst);
1293 }
1294 }
1295
1296 fn infer_expr_array(&mut self, array: &Array, expected: &Expectation<'db>) -> Ty<'db> {
1297 let elem_ty = match expected
1298 .to_option(&mut self.table)
1299 .map(|t| self.table.try_structurally_resolve_type(t).kind())
1300 {
1301 Some(TyKind::Array(st, _) | TyKind::Slice(st)) => st,
1302 _ => self.table.next_ty_var(),
1303 };
1304
1305 let krate = self.resolver.krate();
1306
1307 let expected = Expectation::has_type(elem_ty);
1308 let (elem_ty, len) = match array {
1309 Array::ElementList { elements, .. } if elements.is_empty() => {
1310 (elem_ty, consteval::usize_const(self.db, Some(0), krate))
1311 }
1312 Array::ElementList { elements, .. } => {
1313 let mut coerce = CoerceMany::with_coercion_sites(elem_ty, elements);
1314 for &expr in elements.iter() {
1315 let cur_elem_ty = self.infer_expr_inner(expr, &expected, ExprIsRead::Yes);
1316 coerce.coerce(
1317 self,
1318 &ObligationCause::new(),
1319 expr,
1320 cur_elem_ty,
1321 ExprIsRead::Yes,
1322 );
1323 }
1324 (
1325 coerce.complete(self),
1326 consteval::usize_const(self.db, Some(elements.len() as u128), krate),
1327 )
1328 }
1329 &Array::Repeat { initializer, repeat } => {
1330 self.infer_expr_coerce(
1331 initializer,
1332 &Expectation::has_type(elem_ty),
1333 ExprIsRead::Yes,
1334 );
1335 let usize = self.types.usize;
1336 let len = match self.body[repeat] {
1337 Expr::Underscore => {
1338 self.write_expr_ty(repeat, usize);
1339 self.table.next_const_var()
1340 }
1341 _ => {
1342 self.infer_expr(repeat, &Expectation::HasType(usize), ExprIsRead::Yes);
1343 consteval::eval_to_const(repeat, self)
1344 }
1345 };
1346
1347 (elem_ty, len)
1348 }
1349 };
1350 let len = self.table.insert_const_vars_shallow(len);
1352 Ty::new_array_with_const_len(self.interner(), elem_ty, len)
1353 }
1354
1355 pub(super) fn infer_return(&mut self, expr: ExprId) {
1356 let ret_ty = self
1357 .return_coercion
1358 .as_mut()
1359 .expect("infer_return called outside function body")
1360 .expected_ty();
1361 let return_expr_ty =
1362 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1363 let mut coerce_many = self.return_coercion.take().unwrap();
1364 coerce_many.coerce(self, &ObligationCause::new(), expr, return_expr_ty, ExprIsRead::Yes);
1365 self.return_coercion = Some(coerce_many);
1366 }
1367
1368 fn infer_expr_return(&mut self, ret: ExprId, expr: Option<ExprId>) -> Ty<'db> {
1369 match self.return_coercion {
1370 Some(_) => {
1371 if let Some(expr) = expr {
1372 self.infer_return(expr);
1373 } else {
1374 let mut coerce = self.return_coercion.take().unwrap();
1375 coerce.coerce_forced_unit(
1376 self,
1377 ret,
1378 &ObligationCause::new(),
1379 true,
1380 ExprIsRead::Yes,
1381 );
1382 self.return_coercion = Some(coerce);
1383 }
1384 }
1385 None => {
1386 if let Some(expr) = expr {
1388 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1389 }
1390 }
1391 }
1392 self.types.never
1393 }
1394
1395 fn infer_expr_become(&mut self, expr: ExprId) -> Ty<'db> {
1396 match &self.return_coercion {
1397 Some(return_coercion) => {
1398 let ret_ty = return_coercion.expected_ty();
1399
1400 let call_expr_ty =
1401 self.infer_expr_inner(expr, &Expectation::HasType(ret_ty), ExprIsRead::Yes);
1402
1403 self.unify(call_expr_ty, ret_ty);
1406 }
1407 None => {
1408 self.infer_expr_no_expect(expr, ExprIsRead::Yes);
1410 }
1411 }
1412
1413 self.types.never
1414 }
1415
1416 fn infer_expr_box(&mut self, inner_expr: ExprId, expected: &Expectation<'db>) -> Ty<'db> {
1417 if let Some(box_id) = self.resolve_boxed_box() {
1418 let table = &mut self.table;
1419 let inner_exp = expected
1420 .to_option(table)
1421 .as_ref()
1422 .and_then(|e| e.as_adt())
1423 .filter(|(e_adt, _)| e_adt == &box_id)
1424 .map(|(_, subts)| {
1425 let g = subts.type_at(0);
1426 Expectation::rvalue_hint(self, g)
1427 })
1428 .unwrap_or_else(Expectation::none);
1429
1430 let inner_ty = self.infer_expr_inner(inner_expr, &inner_exp, ExprIsRead::Yes);
1431 Ty::new_adt(
1432 self.interner(),
1433 box_id,
1434 GenericArgs::fill_with_defaults(
1435 self.interner(),
1436 box_id.into(),
1437 [inner_ty.into()],
1438 |_, id, _| self.table.next_var_for_param(id),
1439 ),
1440 )
1441 } else {
1442 self.err_ty()
1443 }
1444 }
1445
1446 fn infer_block(
1447 &mut self,
1448 expr: ExprId,
1449 statements: &[Statement],
1450 tail: Option<ExprId>,
1451 label: Option<LabelId>,
1452 expected: &Expectation<'db>,
1453 ) -> Ty<'db> {
1454 let coerce_ty = expected.coercion_target_type(&mut self.table);
1455 let g = self.resolver.update_to_inner_scope(self.db, self.owner, expr);
1456
1457 let (break_ty, ty) =
1458 self.with_breakable_ctx(BreakableKind::Block, Some(coerce_ty), label, |this| {
1459 for stmt in statements {
1460 match stmt {
1461 Statement::Let { pat, type_ref, initializer, else_branch } => {
1462 let decl_ty = type_ref
1463 .as_ref()
1464 .map(|&tr| this.make_body_ty(tr))
1465 .unwrap_or_else(|| this.table.next_ty_var());
1466
1467 let ty = if let Some(expr) = initializer {
1468 let target_is_read =
1471 if this.pat_guaranteed_to_constitute_read_for_never(*pat) {
1472 ExprIsRead::Yes
1473 } else {
1474 ExprIsRead::No
1475 };
1476 let ty = if contains_explicit_ref_binding(this.body, *pat) {
1477 this.infer_expr(
1478 *expr,
1479 &Expectation::has_type(decl_ty),
1480 target_is_read,
1481 )
1482 } else {
1483 this.infer_expr_coerce(
1484 *expr,
1485 &Expectation::has_type(decl_ty),
1486 target_is_read,
1487 )
1488 };
1489 if type_ref.is_some() { decl_ty } else { ty }
1490 } else {
1491 decl_ty
1492 };
1493
1494 let decl = DeclContext {
1495 origin: DeclOrigin::LocalDecl { has_else: else_branch.is_some() },
1496 };
1497
1498 this.infer_top_pat(*pat, ty, Some(decl));
1499 if let Some(expr) = else_branch {
1500 let previous_diverges =
1501 mem::replace(&mut this.diverges, Diverges::Maybe);
1502 this.infer_expr_coerce(
1503 *expr,
1504 &Expectation::HasType(this.types.never),
1505 ExprIsRead::Yes,
1506 );
1507 this.diverges = previous_diverges;
1508 }
1509 }
1510 &Statement::Expr { expr, has_semi } => {
1511 if has_semi {
1512 this.infer_expr(expr, &Expectation::none(), ExprIsRead::Yes);
1513 } else {
1514 this.infer_expr_coerce(
1515 expr,
1516 &Expectation::HasType(this.types.unit),
1517 ExprIsRead::Yes,
1518 );
1519 }
1520 }
1521 Statement::Item(_) => (),
1522 }
1523 }
1524
1525 if let Some(expr) = tail {
1527 this.infer_expr_coerce(expr, expected, ExprIsRead::Yes)
1528 } else {
1529 if this.diverges.is_always() {
1537 this.table.new_maybe_never_var()
1539 } else if let Some(t) = expected.only_has_type(&mut this.table) {
1540 if this
1541 .coerce(
1542 expr.into(),
1543 this.types.unit,
1544 t,
1545 AllowTwoPhase::No,
1546 ExprIsRead::Yes,
1547 )
1548 .is_err()
1549 {
1550 this.result.type_mismatches.get_or_insert_default().insert(
1551 expr.into(),
1552 TypeMismatch { expected: t, actual: this.types.unit },
1553 );
1554 }
1555 t
1556 } else {
1557 this.types.unit
1558 }
1559 }
1560 });
1561 self.resolver.reset_to_guard(g);
1562
1563 break_ty.unwrap_or(ty)
1564 }
1565
1566 fn lookup_field(
1567 &mut self,
1568 receiver_ty: Ty<'db>,
1569 name: &Name,
1570 ) -> Option<(Ty<'db>, Either<FieldId, TupleFieldId>, Vec<Adjustment<'db>>, bool)> {
1571 let interner = self.interner();
1572 let mut autoderef = self.table.autoderef_with_tracking(receiver_ty);
1573 let mut private_field = None;
1574 let res = autoderef.by_ref().find_map(|(derefed_ty, _)| {
1575 let (field_id, parameters) = match derefed_ty.kind() {
1576 TyKind::Tuple(substs) => {
1577 return name.as_tuple_index().and_then(|idx| {
1578 substs.as_slice().get(idx).copied().map(|ty| {
1579 (
1580 Either::Right(TupleFieldId {
1581 tuple: TupleId(
1582 self.tuple_field_accesses_rev.insert_full(substs).0 as u32,
1583 ),
1584 index: idx as u32,
1585 }),
1586 ty,
1587 )
1588 })
1589 });
1590 }
1591 TyKind::Adt(adt, parameters) => match adt.def_id().0 {
1592 hir_def::AdtId::StructId(s) => {
1593 let local_id = s.fields(self.db).field(name)?;
1594 let field = FieldId { parent: s.into(), local_id };
1595 (field, parameters)
1596 }
1597 hir_def::AdtId::UnionId(u) => {
1598 let local_id = u.fields(self.db).field(name)?;
1599 let field = FieldId { parent: u.into(), local_id };
1600 (field, parameters)
1601 }
1602 hir_def::AdtId::EnumId(_) => return None,
1603 },
1604 _ => return None,
1605 };
1606 let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id]
1607 .is_visible_from(self.db, self.resolver.module());
1608 if !is_visible {
1609 if private_field.is_none() {
1610 private_field = Some((field_id, parameters));
1611 }
1612 return None;
1613 }
1614 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1615 .instantiate(interner, parameters);
1616 Some((Either::Left(field_id), ty))
1617 });
1618
1619 Some(match res {
1620 Some((field_id, ty)) => {
1621 let adjustments =
1622 self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1623 let ty = self.process_remote_user_written_ty(ty);
1624
1625 (ty, field_id, adjustments, true)
1626 }
1627 None => {
1628 let (field_id, subst) = private_field?;
1629 let adjustments =
1630 self.table.register_infer_ok(autoderef.adjust_steps_as_infer_ok());
1631 let ty = self.db.field_types(field_id.parent)[field_id.local_id]
1632 .instantiate(self.interner(), subst);
1633 let ty = self.process_remote_user_written_ty(ty);
1634
1635 (ty, Either::Left(field_id), adjustments, false)
1636 }
1637 })
1638 }
1639
1640 fn infer_field_access(
1641 &mut self,
1642 tgt_expr: ExprId,
1643 receiver: ExprId,
1644 name: &Name,
1645 expected: &Expectation<'db>,
1646 ) -> Ty<'db> {
1647 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::No);
1649 let receiver_ty = self.table.structurally_resolve_type(receiver_ty);
1650
1651 if name.is_missing() {
1652 return self.err_ty();
1655 }
1656
1657 match self.lookup_field(receiver_ty, name) {
1658 Some((ty, field_id, adjustments, is_public)) => {
1659 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1660 self.result.field_resolutions.insert(tgt_expr, field_id);
1661 if !is_public && let Either::Left(field) = field_id {
1662 self.push_diagnostic(InferenceDiagnostic::PrivateField {
1664 expr: tgt_expr,
1665 field,
1666 });
1667 }
1668 ty
1669 }
1670 None => {
1671 let resolved = self.lookup_method_including_private(
1674 receiver_ty,
1675 name.clone(),
1676 None,
1677 receiver,
1678 tgt_expr,
1679 );
1680 self.push_diagnostic(InferenceDiagnostic::UnresolvedField {
1681 expr: tgt_expr,
1682 receiver: receiver_ty,
1683 name: name.clone(),
1684 method_with_same_name_exists: resolved.is_ok(),
1685 });
1686 match resolved {
1687 Ok((func, _is_visible)) => {
1688 self.check_method_call(tgt_expr, &[], func.sig, receiver_ty, expected)
1689 }
1690 Err(_) => self.err_ty(),
1691 }
1692 }
1693 }
1694 }
1695
1696 fn instantiate_erroneous_method(&mut self, def_id: FunctionId) -> MethodCallee<'db> {
1697 let args = self.table.fresh_args_for_item(def_id.into());
1700 let sig = self.db.callable_item_signature(def_id.into()).instantiate(self.interner(), args);
1701 let sig =
1702 self.infcx().instantiate_binder_with_fresh_vars(BoundRegionConversionTime::FnCall, sig);
1703 MethodCallee { def_id, args, sig }
1704 }
1705
1706 fn infer_call(
1707 &mut self,
1708 tgt_expr: ExprId,
1709 callee: ExprId,
1710 args: &[ExprId],
1711 expected: &Expectation<'db>,
1712 ) -> Ty<'db> {
1713 let callee_ty = self.infer_expr(callee, &Expectation::none(), ExprIsRead::Yes);
1714 let callee_ty = self.table.try_structurally_resolve_type(callee_ty);
1715 let interner = self.interner();
1716 let mut derefs = InferenceContextAutoderef::new_from_inference_context(self, callee_ty);
1717 let (res, derefed_callee) = loop {
1718 let Some((callee_deref_ty, _)) = derefs.next() else {
1719 break (None, callee_ty);
1720 };
1721 if let Some(res) = derefs.ctx().table.callable_sig(callee_deref_ty, args.len()) {
1722 break (Some(res), callee_deref_ty);
1723 }
1724 };
1725 let is_varargs = derefed_callee.callable_sig(interner).is_some_and(|sig| sig.c_variadic())
1728 || res.is_none();
1729 let (param_tys, ret_ty) = match res {
1730 Some((func, params, ret_ty)) => {
1731 let infer_ok = derefs.adjust_steps_as_infer_ok();
1732 let mut adjustments = self.table.register_infer_ok(infer_ok);
1733 if let Some(fn_x) = func {
1734 self.write_fn_trait_method_resolution(
1735 fn_x,
1736 derefed_callee,
1737 &mut adjustments,
1738 callee_ty,
1739 ¶ms,
1740 tgt_expr,
1741 );
1742 }
1743 if let TyKind::Closure(c, _) = self.table.resolve_completely(callee_ty).kind() {
1744 self.add_current_closure_dependency(c.into());
1745 self.deferred_closures.entry(c.into()).or_default().push((
1746 derefed_callee,
1747 callee_ty,
1748 params.clone(),
1749 tgt_expr,
1750 ));
1751 }
1752 self.write_expr_adj(callee, adjustments.into_boxed_slice());
1753 (params, ret_ty)
1754 }
1755 None => {
1756 self.push_diagnostic(InferenceDiagnostic::ExpectedFunction {
1757 call_expr: tgt_expr,
1758 found: callee_ty,
1759 });
1760 (Vec::new(), Ty::new_error(interner, ErrorGuaranteed))
1761 }
1762 };
1763 let indices_to_skip = self.check_legacy_const_generics(derefed_callee, args);
1764 self.check_call(
1765 tgt_expr,
1766 args,
1767 callee_ty,
1768 ¶m_tys,
1769 ret_ty,
1770 &indices_to_skip,
1771 is_varargs,
1772 expected,
1773 )
1774 }
1775
1776 fn check_call(
1777 &mut self,
1778 tgt_expr: ExprId,
1779 args: &[ExprId],
1780 callee_ty: Ty<'db>,
1781 param_tys: &[Ty<'db>],
1782 ret_ty: Ty<'db>,
1783 indices_to_skip: &[u32],
1784 is_varargs: bool,
1785 expected: &Expectation<'db>,
1786 ) -> Ty<'db> {
1787 self.register_obligations_for_call(callee_ty);
1788
1789 self.check_call_arguments(
1790 tgt_expr,
1791 param_tys,
1792 ret_ty,
1793 expected,
1794 args,
1795 indices_to_skip,
1796 is_varargs,
1797 );
1798 ret_ty
1799 }
1800
1801 fn infer_method_call(
1802 &mut self,
1803 tgt_expr: ExprId,
1804 receiver: ExprId,
1805 args: &[ExprId],
1806 method_name: &Name,
1807 generic_args: Option<&HirGenericArgs>,
1808 expected: &Expectation<'db>,
1809 ) -> Ty<'db> {
1810 let receiver_ty = self.infer_expr_inner(receiver, &Expectation::none(), ExprIsRead::Yes);
1811 let receiver_ty = self.table.try_structurally_resolve_type(receiver_ty);
1812
1813 let resolved = self.lookup_method_including_private(
1814 receiver_ty,
1815 method_name.clone(),
1816 generic_args,
1817 receiver,
1818 tgt_expr,
1819 );
1820 match resolved {
1821 Ok((func, visible)) => {
1822 if !visible {
1823 self.push_diagnostic(InferenceDiagnostic::PrivateAssocItem {
1824 id: tgt_expr.into(),
1825 item: func.def_id.into(),
1826 })
1827 }
1828 self.check_method_call(tgt_expr, args, func.sig, receiver_ty, expected)
1829 }
1830 Err(_) => {
1833 let field_with_same_name_exists = match self.lookup_field(receiver_ty, method_name)
1834 {
1835 Some((ty, field_id, adjustments, _public)) => {
1836 self.write_expr_adj(receiver, adjustments.into_boxed_slice());
1837 self.result.field_resolutions.insert(tgt_expr, field_id);
1838 Some(ty)
1839 }
1840 None => None,
1841 };
1842
1843 let assoc_func_with_same_name = self.with_method_resolution(|ctx| {
1844 if !matches!(
1845 receiver_ty.kind(),
1846 TyKind::Infer(InferTy::TyVar(_)) | TyKind::Error(_)
1847 ) {
1848 ctx.probe_for_name(
1849 method_resolution::Mode::Path,
1850 method_name.clone(),
1851 receiver_ty,
1852 )
1853 } else {
1854 Err(MethodError::ErrorReported)
1855 }
1856 });
1857 let assoc_func_with_same_name = match assoc_func_with_same_name {
1858 Ok(method_resolution::Pick {
1859 item: CandidateId::FunctionId(def_id), ..
1860 })
1861 | Err(MethodError::PrivateMatch(method_resolution::Pick {
1862 item: CandidateId::FunctionId(def_id),
1863 ..
1864 })) => Some(self.instantiate_erroneous_method(def_id)),
1865 _ => None,
1866 };
1867
1868 self.push_diagnostic(InferenceDiagnostic::UnresolvedMethodCall {
1869 expr: tgt_expr,
1870 receiver: receiver_ty,
1871 name: method_name.clone(),
1872 field_with_same_name: field_with_same_name_exists,
1873 assoc_func_with_same_name: assoc_func_with_same_name.map(|it| it.def_id),
1874 });
1875
1876 let recovered = match assoc_func_with_same_name {
1877 Some(it) => Some((
1878 Ty::new_fn_def(
1879 self.interner(),
1880 CallableDefId::FunctionId(it.def_id).into(),
1881 it.args,
1882 ),
1883 it.sig,
1884 true,
1885 )),
1886 None => field_with_same_name_exists.and_then(|field_ty| {
1887 let callable_sig = field_ty.callable_sig(self.interner())?;
1888 Some((field_ty, callable_sig.skip_binder(), false))
1889 }),
1890 };
1891 match recovered {
1892 Some((callee_ty, sig, strip_first)) => self.check_call(
1893 tgt_expr,
1894 args,
1895 callee_ty,
1896 sig.inputs_and_output.inputs().get(strip_first as usize..).unwrap_or(&[]),
1897 sig.output(),
1898 &[],
1899 true,
1900 expected,
1901 ),
1902 None => {
1903 for &arg in args.iter() {
1904 self.infer_expr_no_expect(arg, ExprIsRead::Yes);
1905 }
1906 self.err_ty()
1907 }
1908 }
1909 }
1910 }
1911 }
1912
1913 fn check_method_call(
1914 &mut self,
1915 tgt_expr: ExprId,
1916 args: &[ExprId],
1917 sig: FnSig<'db>,
1918 receiver_ty: Ty<'db>,
1919 expected: &Expectation<'db>,
1920 ) -> Ty<'db> {
1921 let (formal_receiver_ty, param_tys) = if !sig.inputs_and_output.inputs().is_empty() {
1922 (sig.inputs_and_output.as_slice()[0], &sig.inputs_and_output.inputs()[1..])
1923 } else {
1924 (self.types.error, &[] as _)
1925 };
1926 let ret_ty = sig.output();
1927 self.table.unify(formal_receiver_ty, receiver_ty);
1928
1929 self.check_call_arguments(tgt_expr, param_tys, ret_ty, expected, args, &[], sig.c_variadic);
1930 ret_ty
1931 }
1932
1933 pub(in super::super) fn check_call_arguments(
1936 &mut self,
1937 call_expr: ExprId,
1938 formal_input_tys: &[Ty<'db>],
1940 formal_output: Ty<'db>,
1941 expectation: &Expectation<'db>,
1943 provided_args: &[ExprId],
1945 skip_indices: &[u32],
1946 c_variadic: bool,
1948 ) {
1949 let formal_output = self.table.resolve_vars_with_obligations(formal_output);
1954 let expected_input_tys: Option<Vec<_>> = expectation
1955 .only_has_type(&mut self.table)
1956 .and_then(|expected_output| {
1957 self.table
1958 .infer_ctxt
1959 .fudge_inference_if_ok(|| {
1960 let mut ocx = ObligationCtxt::new(&self.table.infer_ctxt);
1961
1962 let origin = ObligationCause::new();
1967 ocx.sup(&origin, self.table.param_env, expected_output, formal_output)?;
1968 if !ocx.try_evaluate_obligations().is_empty() {
1969 return Err(TypeError::Mismatch);
1970 }
1971
1972 Ok(Some(
1975 formal_input_tys
1976 .iter()
1977 .map(|&ty| self.table.infer_ctxt.resolve_vars_if_possible(ty))
1978 .collect(),
1979 ))
1980 })
1981 .ok()
1982 })
1983 .unwrap_or_default();
1984
1985 let expected_input_tys = if let Some(expected_input_tys) = &expected_input_tys {
1987 assert_eq!(expected_input_tys.len(), formal_input_tys.len());
1988 expected_input_tys
1989 } else {
1990 formal_input_tys
1991 };
1992
1993 let minimum_input_count = expected_input_tys.len();
1994 let provided_arg_count = provided_args.len() - skip_indices.len();
1995
1996 let args_count_matches = if c_variadic {
2001 provided_arg_count >= minimum_input_count
2002 } else {
2003 provided_arg_count == minimum_input_count
2004 };
2005
2006 if !args_count_matches {
2007 self.push_diagnostic(InferenceDiagnostic::MismatchedArgCount {
2008 call_expr,
2009 expected: expected_input_tys.len() + skip_indices.len(),
2010 found: provided_args.len(),
2011 });
2012 }
2013
2014 let demand_compatible = |this: &mut InferenceContext<'_, 'db>, idx| {
2018 let formal_input_ty: Ty<'db> = formal_input_tys[idx];
2019 let expected_input_ty: Ty<'db> = expected_input_tys[idx];
2020 let provided_arg = provided_args[idx];
2021
2022 debug!("checking argument {}: {:?} = {:?}", idx, provided_arg, formal_input_ty);
2023
2024 let expectation = Expectation::rvalue_hint(this, expected_input_ty);
2028
2029 let checked_ty = this.infer_expr_inner(provided_arg, &expectation, ExprIsRead::Yes);
2030
2031 let coerced_ty = expectation.only_has_type(&mut this.table).unwrap_or(formal_input_ty);
2035
2036 let coerced_ty = this.table.resolve_vars_with_obligations(coerced_ty);
2040
2041 let coerce_error = this
2042 .coerce(
2043 provided_arg.into(),
2044 checked_ty,
2045 coerced_ty,
2046 AllowTwoPhase::Yes,
2047 ExprIsRead::Yes,
2048 )
2049 .err();
2050 if coerce_error.is_some() {
2051 return Err((coerce_error, coerced_ty, checked_ty));
2052 }
2053
2054 let formal_ty_error = this
2057 .table
2058 .infer_ctxt
2059 .at(&ObligationCause::new(), this.table.param_env)
2060 .eq(formal_input_ty, coerced_ty);
2061
2062 match formal_ty_error {
2064 Ok(InferOk { obligations, value: () }) => {
2065 this.table.register_predicates(obligations);
2066 Ok(())
2067 }
2068 Err(err) => Err((Some(err), coerced_ty, checked_ty)),
2069 }
2070 };
2071
2072 for check_closures in [false, true] {
2078 if check_closures {
2082 self.table.select_obligations_where_possible();
2083 }
2084
2085 let mut skip_indices = skip_indices.iter().copied();
2086 for (idx, arg) in provided_args.iter().enumerate() {
2089 if skip_indices.clone().next() == Some(idx as u32) {
2090 skip_indices.next();
2091 continue;
2092 }
2093
2094 let is_closure = if let Expr::Closure { closure_kind, .. } = self.body[*arg] {
2100 !matches!(closure_kind, ClosureKind::Coroutine(_))
2101 } else {
2102 false
2103 };
2104 if is_closure != check_closures {
2105 continue;
2106 }
2107
2108 if idx >= minimum_input_count {
2109 self.infer_expr_no_expect(*arg, ExprIsRead::Yes);
2111 continue;
2112 }
2113
2114 if let Err((_error, expected, found)) = demand_compatible(self, idx)
2115 && args_count_matches
2116 {
2117 self.result
2119 .type_mismatches
2120 .get_or_insert_default()
2121 .insert((*arg).into(), TypeMismatch { expected, actual: found });
2122 }
2123 }
2124 }
2125
2126 if !args_count_matches {}
2127 }
2128
2129 fn register_obligations_for_call(&mut self, callable_ty: Ty<'db>) {
2130 let callable_ty = self.table.try_structurally_resolve_type(callable_ty);
2131 if let TyKind::FnDef(fn_def, parameters) = callable_ty.kind() {
2132 let generic_predicates = GenericPredicates::query_all(
2133 self.db,
2134 GenericDefId::from_callable(self.db, fn_def.0),
2135 );
2136 let param_env = self.table.param_env;
2137 self.table.register_predicates(clauses_as_obligations(
2138 generic_predicates.iter_instantiated_copied(self.interner(), parameters.as_slice()),
2139 ObligationCause::new(),
2140 param_env,
2141 ));
2142 match fn_def.0 {
2144 CallableDefId::FunctionId(f) => {
2145 if let ItemContainerId::TraitId(trait_) = f.lookup(self.db).container {
2146 let trait_params_len = generics(self.db, trait_.into()).len();
2148 let substs = GenericArgs::new_from_iter(
2149 self.interner(),
2150 parameters.as_slice()[..trait_params_len].iter().copied(),
2151 );
2152 self.table.register_predicate(Obligation::new(
2153 self.interner(),
2154 ObligationCause::new(),
2155 self.table.param_env,
2156 TraitRef::new(self.interner(), trait_.into(), substs),
2157 ));
2158 }
2159 }
2160 CallableDefId::StructId(_) | CallableDefId::EnumVariantId(_) => {}
2161 }
2162 }
2163 }
2164
2165 fn check_legacy_const_generics(&mut self, callee: Ty<'db>, args: &[ExprId]) -> Box<[u32]> {
2167 let (func, _subst) = match callee.kind() {
2168 TyKind::FnDef(callable, subst) => {
2169 let func = match callable.0 {
2170 CallableDefId::FunctionId(f) => f,
2171 _ => return Default::default(),
2172 };
2173 (func, subst)
2174 }
2175 _ => return Default::default(),
2176 };
2177
2178 let data = self.db.function_signature(func);
2179 let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func)
2180 else {
2181 return Default::default();
2182 };
2183 let mut legacy_const_generics_indices = Box::<[u32]>::from(legacy_const_generics_indices);
2184
2185 if data.params.len() + legacy_const_generics_indices.len() != args.len() {
2187 if args.len() <= data.params.len() {
2188 return Default::default();
2189 } else {
2190 legacy_const_generics_indices.sort_unstable();
2193 return legacy_const_generics_indices;
2194 }
2195 }
2196
2197 for arg_idx in legacy_const_generics_indices.iter().copied() {
2199 if arg_idx >= args.len() as u32 {
2200 continue;
2201 }
2202 let expected = Expectation::none(); self.infer_expr(args[arg_idx as usize], &expected, ExprIsRead::Yes);
2204 }
2206 legacy_const_generics_indices.sort_unstable();
2207 legacy_const_generics_indices
2208 }
2209
2210 pub(super) fn with_breakable_ctx<T>(
2211 &mut self,
2212 kind: BreakableKind,
2213 ty: Option<Ty<'db>>,
2214 label: Option<LabelId>,
2215 cb: impl FnOnce(&mut Self) -> T,
2216 ) -> (Option<Ty<'db>>, T) {
2217 self.breakables.push({
2218 BreakableContext { kind, may_break: false, coerce: ty.map(CoerceMany::new), label }
2219 });
2220 let res = cb(self);
2221 let ctx = self.breakables.pop().expect("breakable stack broken");
2222 (if ctx.may_break { ctx.coerce.map(|ctx| ctx.complete(self)) } else { None }, res)
2223 }
2224}