1mod autoderef;
17pub(crate) mod cast;
18pub(crate) mod closure;
19mod coerce;
20pub(crate) mod diagnostics;
21mod expr;
22mod fallback;
23mod mutability;
24mod op;
25mod opaques;
26mod pat;
27mod path;
28mod place_op;
29pub(crate) mod unify;
30
31use std::{cell::OnceCell, convert::identity, iter, ops::Index};
32
33use base_db::Crate;
34use either::Either;
35use hir_def::{
36 AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
37 ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
38 expr_store::{Body, ExpressionStore, HygieneId, path::Path},
39 hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
40 lang_item::LangItems,
41 layout::Integer,
42 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
43 signatures::{ConstSignature, EnumSignature, StaticSignature},
44 type_ref::{ConstRef, LifetimeRefId, TypeRef, TypeRefId},
45};
46use hir_expand::{mod_path::ModPath, name::Name};
47use indexmap::IndexSet;
48use intern::sym;
49use la_arena::ArenaMap;
50use macros::{TypeFoldable, TypeVisitable};
51use rustc_ast_ir::Mutability;
52use rustc_hash::{FxHashMap, FxHashSet};
53use rustc_type_ir::{
54 AliasTyKind, TypeFoldable,
55 inherent::{AdtDef, IntoKind, Region as _, SliceLike, Ty as _},
56};
57use salsa::Update;
58use span::Edition;
59use stdx::never;
60use thin_vec::ThinVec;
61
62use crate::{
63 ImplTraitId, IncorrectGenericsLenKind, PathLoweringDiagnostic, TargetFeatures,
64 collect_type_inference_vars,
65 db::{HirDatabase, InternedClosureId, InternedOpaqueTyId},
66 infer::{
67 coerce::{CoerceMany, DynamicCoerceMany},
68 diagnostics::{Diagnostics, InferenceTyLoweringContext as TyLoweringContext},
69 expr::ExprIsRead,
70 },
71 lower::{
72 ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic,
73 },
74 method_resolution::{CandidateId, MethodResolutionUnstableFeatures},
75 mir::MirSpan,
76 next_solver::{
77 AliasTy, Const, DbInterner, ErrorGuaranteed, GenericArg, GenericArgs, Region, Ty, TyKind,
78 Tys,
79 abi::Safety,
80 infer::{InferCtxt, traits::ObligationCause},
81 },
82 traits::FnTrait,
83 utils::TargetFeatureIsSafeInTarget,
84};
85
86#[allow(unreachable_pub)]
90pub use coerce::could_coerce;
91#[allow(unreachable_pub)]
92pub use unify::{could_unify, could_unify_deeply};
93
94use cast::{CastCheck, CastError};
95pub(crate) use closure::analysis::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
96
97fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {
99 let _p = tracing::info_span!("infer_query").entered();
100 let resolver = def.resolver(db);
101 let body = db.body(def);
102 let mut ctx = InferenceContext::new(db, def, &body, resolver);
103
104 match def {
105 DefWithBodyId::FunctionId(f) => {
106 ctx.collect_fn(f);
107 }
108 DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
109 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
110 DefWithBodyId::VariantId(v) => {
111 ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {
112 hir_def::layout::IntegerType::Pointer(signed) => match signed {
113 true => ctx.types.isize,
114 false => ctx.types.usize,
115 },
116 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
117 true => match size {
118 Integer::I8 => ctx.types.i8,
119 Integer::I16 => ctx.types.i16,
120 Integer::I32 => ctx.types.i32,
121 Integer::I64 => ctx.types.i64,
122 Integer::I128 => ctx.types.i128,
123 },
124 false => match size {
125 Integer::I8 => ctx.types.u8,
126 Integer::I16 => ctx.types.u16,
127 Integer::I32 => ctx.types.u32,
128 Integer::I64 => ctx.types.u64,
129 Integer::I128 => ctx.types.u128,
130 },
131 },
132 };
133 }
134 }
135
136 ctx.infer_body();
137
138 ctx.infer_mut_body();
139
140 ctx.handle_opaque_type_uses();
141
142 ctx.type_inference_fallback();
143
144 let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);
148 for mut cast in cast_checks.into_iter() {
149 if let Err(diag) = cast.check(&mut ctx) {
150 ctx.diagnostics.push(diag);
151 }
152 }
153
154 ctx.table.select_obligations_where_possible();
155
156 ctx.infer_closures();
157
158 ctx.table.select_obligations_where_possible();
159
160 ctx.handle_opaque_type_uses();
161
162 ctx.resolve_all()
163}
164
165fn infer_cycle_result(db: &dyn HirDatabase, _: DefWithBodyId) -> InferenceResult<'_> {
166 InferenceResult {
167 has_errors: true,
168 ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
169 }
170}
171
172#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
175pub enum BindingMode {
176 #[default]
177 Move,
178 Ref(Mutability),
179}
180
181impl BindingMode {
182 fn convert(annotation: BindingAnnotation) -> BindingMode {
183 match annotation {
184 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
185 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
186 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
187 }
188 }
189}
190
191#[derive(Debug, PartialEq, Eq, Clone, Copy)]
192pub enum InferenceTyDiagnosticSource {
193 Body,
195 Signature,
197}
198
199#[derive(Debug, PartialEq, Eq, Clone, Update)]
200pub enum InferenceDiagnostic<'db> {
201 NoSuchField {
202 field: ExprOrPatId,
203 private: Option<LocalFieldId>,
204 variant: VariantId,
205 },
206 PrivateField {
207 expr: ExprId,
208 field: FieldId,
209 },
210 PrivateAssocItem {
211 id: ExprOrPatId,
212 item: AssocItemId,
213 },
214 UnresolvedField {
215 expr: ExprId,
216 receiver: Ty<'db>,
217 name: Name,
218 method_with_same_name_exists: bool,
219 },
220 UnresolvedMethodCall {
221 expr: ExprId,
222 receiver: Ty<'db>,
223 name: Name,
224 field_with_same_name: Option<Ty<'db>>,
226 assoc_func_with_same_name: Option<FunctionId>,
227 },
228 UnresolvedAssocItem {
229 id: ExprOrPatId,
230 },
231 UnresolvedIdent {
232 id: ExprOrPatId,
233 },
234 BreakOutsideOfLoop {
236 expr: ExprId,
237 is_break: bool,
238 bad_value_break: bool,
239 },
240 MismatchedArgCount {
241 call_expr: ExprId,
242 expected: usize,
243 found: usize,
244 },
245 MismatchedTupleStructPatArgCount {
246 pat: ExprOrPatId,
247 expected: usize,
248 found: usize,
249 },
250 ExpectedFunction {
251 call_expr: ExprId,
252 found: Ty<'db>,
253 },
254 TypedHole {
255 expr: ExprId,
256 expected: Ty<'db>,
257 },
258 CastToUnsized {
259 expr: ExprId,
260 cast_ty: Ty<'db>,
261 },
262 InvalidCast {
263 expr: ExprId,
264 error: CastError,
265 expr_ty: Ty<'db>,
266 cast_ty: Ty<'db>,
267 },
268 TyDiagnostic {
269 source: InferenceTyDiagnosticSource,
270 diag: TyLoweringDiagnostic,
271 },
272 PathDiagnostic {
273 node: ExprOrPatId,
274 diag: PathLoweringDiagnostic,
275 },
276 MethodCallIncorrectGenericsLen {
277 expr: ExprId,
278 provided_count: u32,
279 expected_count: u32,
280 kind: IncorrectGenericsLenKind,
281 def: GenericDefId,
282 },
283 MethodCallIncorrectGenericsOrder {
284 expr: ExprId,
285 param_id: GenericParamId,
286 arg_idx: u32,
287 has_self_arg: bool,
289 },
290}
291
292#[derive(Clone, PartialEq, Eq, Debug, Hash, Update)]
294pub struct TypeMismatch<'db> {
295 pub expected: Ty<'db>,
296 pub actual: Ty<'db>,
297}
298
299#[derive(Clone, Debug, PartialEq, Eq, Hash, TypeVisitable, TypeFoldable, Update)]
340pub struct Adjustment<'db> {
341 #[type_visitable(ignore)]
342 #[type_foldable(identity)]
343 pub kind: Adjust,
344 pub target: Ty<'db>,
345}
346
347impl<'db> Adjustment<'db> {
348 pub fn borrow(interner: DbInterner<'db>, m: Mutability, ty: Ty<'db>, lt: Region<'db>) -> Self {
349 let ty = Ty::new_ref(interner, lt, ty, m);
350 Adjustment {
351 kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),
352 target: ty,
353 }
354 }
355}
356
357#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
371pub enum AllowTwoPhase {
372 Yes,
374 No,
375}
376
377#[derive(Clone, Debug, PartialEq, Eq, Hash)]
378pub enum Adjust {
379 NeverToAny,
381 Deref(Option<OverloadedDeref>),
383 Borrow(AutoBorrow),
385 Pointer(PointerCast),
386}
387
388#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
393pub struct OverloadedDeref(pub Option<Mutability>);
394
395#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
396pub enum AutoBorrowMutability {
397 Mut { allow_two_phase_borrow: AllowTwoPhase },
398 Not,
399}
400
401impl AutoBorrowMutability {
402 pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {
406 match mutbl {
407 Mutability::Not => Self::Not,
408 Mutability::Mut => Self::Mut { allow_two_phase_borrow },
409 }
410 }
411}
412
413impl From<AutoBorrowMutability> for Mutability {
414 fn from(m: AutoBorrowMutability) -> Self {
415 match m {
416 AutoBorrowMutability::Mut { .. } => Mutability::Mut,
417 AutoBorrowMutability::Not => Mutability::Not,
418 }
419 }
420}
421
422#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
423pub enum AutoBorrow {
424 Ref(AutoBorrowMutability),
426 RawPtr(Mutability),
428}
429
430impl AutoBorrow {
431 fn mutability(self) -> Mutability {
432 match self {
433 AutoBorrow::Ref(mutbl) => mutbl.into(),
434 AutoBorrow::RawPtr(mutbl) => mutbl,
435 }
436 }
437}
438
439#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
440pub enum PointerCast {
441 ReifyFnPointer,
443
444 UnsafeFnPointer,
446
447 ClosureFnPointer(Safety),
450
451 MutToConstPointer,
453
454 #[allow(dead_code)]
455 ArrayToPointer,
457
458 Unsize,
469}
470
471#[derive(Clone, PartialEq, Eq, Debug, Update)]
477pub struct InferenceResult<'db> {
478 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
480 method_resolutions: FxHashMap<ExprId, (FunctionId, GenericArgs<'db>)>,
481 field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
483 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
485 assoc_resolutions: FxHashMap<ExprOrPatId, (CandidateId, GenericArgs<'db>)>,
487 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
491 tuple_field_access_types: ThinVec<Tys<'db>>,
492
493 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
494 pub(crate) type_of_expr: ArenaMap<ExprId, Ty<'db>>,
495 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
500 pub(crate) type_of_pat: ArenaMap<PatId, Ty<'db>>,
501 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
502 pub(crate) type_of_binding: ArenaMap<BindingId, Ty<'db>>,
503 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
504 pub(crate) type_of_type_placeholder: FxHashMap<TypeRefId, Ty<'db>>,
505 pub(crate) type_of_opaque: FxHashMap<InternedOpaqueTyId, Ty<'db>>,
506
507 pub(crate) type_mismatches: Option<Box<FxHashMap<ExprOrPatId, TypeMismatch<'db>>>>,
508 pub(crate) has_errors: bool,
513 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
515 diagnostics: ThinVec<InferenceDiagnostic<'db>>,
516
517 error_ty: Ty<'db>,
520
521 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
522 pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment<'db>]>>,
523 #[update(unsafe(with(crate::utils::unsafe_update_eq )))]
525 pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty<'db>>>,
526 pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,
540
541 pub(crate) closure_info: FxHashMap<InternedClosureId, (Vec<CapturedItem<'db>>, FnTrait)>,
542 pub mutated_bindings_in_closure: FxHashSet<BindingId>,
544
545 pub(crate) coercion_casts: FxHashSet<ExprId>,
546}
547
548#[salsa::tracked]
549impl<'db> InferenceResult<'db> {
550 #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
551 pub fn for_body(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {
552 infer_query(db, def)
553 }
554}
555
556impl<'db> InferenceResult<'db> {
557 fn new(error_ty: Ty<'db>) -> Self {
558 Self {
559 method_resolutions: Default::default(),
560 field_resolutions: Default::default(),
561 variant_resolutions: Default::default(),
562 assoc_resolutions: Default::default(),
563 tuple_field_access_types: Default::default(),
564 diagnostics: Default::default(),
565 type_of_expr: Default::default(),
566 type_of_pat: Default::default(),
567 type_of_binding: Default::default(),
568 type_of_type_placeholder: Default::default(),
569 type_of_opaque: Default::default(),
570 type_mismatches: Default::default(),
571 has_errors: Default::default(),
572 error_ty,
573 pat_adjustments: Default::default(),
574 binding_modes: Default::default(),
575 expr_adjustments: Default::default(),
576 closure_info: Default::default(),
577 mutated_bindings_in_closure: Default::default(),
578 coercion_casts: Default::default(),
579 }
580 }
581
582 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {
583 self.method_resolutions.get(&expr).copied()
584 }
585 pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
586 self.field_resolutions.get(&expr).copied()
587 }
588 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
589 self.variant_resolutions.get(&id.into()).copied()
590 }
591 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
592 self.variant_resolutions.get(&id.into()).copied()
593 }
594 pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
595 match id {
596 ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
597 ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
598 }
599 }
600 pub fn assoc_resolutions_for_expr(
601 &self,
602 id: ExprId,
603 ) -> Option<(CandidateId, GenericArgs<'db>)> {
604 self.assoc_resolutions.get(&id.into()).copied()
605 }
606 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(CandidateId, GenericArgs<'db>)> {
607 self.assoc_resolutions.get(&id.into()).copied()
608 }
609 pub fn assoc_resolutions_for_expr_or_pat(
610 &self,
611 id: ExprOrPatId,
612 ) -> Option<(CandidateId, GenericArgs<'db>)> {
613 match id {
614 ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
615 ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
616 }
617 }
618 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch<'db>> {
619 self.type_mismatches.as_deref()?.get(&expr.into())
620 }
621 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch<'db>> {
622 self.type_mismatches.as_deref()?.get(&pat.into())
623 }
624 pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch<'db>)> {
625 self.type_mismatches
626 .as_deref()
627 .into_iter()
628 .flatten()
629 .map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch))
630 }
631 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch<'db>)> {
632 self.type_mismatches.as_deref().into_iter().flatten().filter_map(
633 |(expr_or_pat, mismatch)| match *expr_or_pat {
634 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
635 _ => None,
636 },
637 )
638 }
639 pub fn placeholder_types(&self) -> impl Iterator<Item = (TypeRefId, &Ty<'db>)> {
640 self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty))
641 }
642 pub fn type_of_type_placeholder(&self, type_ref: TypeRefId) -> Option<Ty<'db>> {
643 self.type_of_type_placeholder.get(&type_ref).copied()
644 }
645 pub fn closure_info(&self, closure: InternedClosureId) -> &(Vec<CapturedItem<'db>>, FnTrait) {
646 self.closure_info.get(&closure).unwrap()
647 }
648 pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option<Ty<'db>> {
649 match id {
650 ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).copied(),
651 ExprOrPatId::PatId(id) => self.type_of_pat.get(id).copied(),
652 }
653 }
654 pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<Ty<'db>> {
655 match self.expr_adjustments.get(&id).and_then(|adjustments| {
656 adjustments.iter().rfind(|adj| {
657 !matches!(
659 adj,
660 Adjustment {
661 kind: Adjust::NeverToAny,
662 target,
663 } if target.is_never()
664 )
665 })
666 }) {
667 Some(adjustment) => Some(adjustment.target),
668 None => self.type_of_expr.get(id).copied(),
669 }
670 }
671 pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option<Ty<'db>> {
672 match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
673 Some(adjusted) => Some(*adjusted),
674 None => self.type_of_pat.get(id).copied(),
675 }
676 }
677 pub fn is_erroneous(&self) -> bool {
678 self.has_errors && self.type_of_expr.iter().count() == 0
679 }
680
681 pub fn diagnostics(&self) -> &[InferenceDiagnostic<'db>] {
682 &self.diagnostics
683 }
684
685 pub fn tuple_field_access_type(&self, id: TupleId) -> Tys<'db> {
686 self.tuple_field_access_types[id.0 as usize]
687 }
688
689 pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty<'db>]> {
690 self.pat_adjustments.get(&id).map(|it| &**it)
691 }
692
693 pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment<'db>]> {
694 self.expr_adjustments.get(&id).map(|it| &**it)
695 }
696
697 pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {
698 self.binding_modes.get(id).copied()
699 }
700
701 pub fn expression_types(&self) -> impl Iterator<Item = (ExprId, Ty<'db>)> {
703 self.type_of_expr.iter().map(|(k, v)| (k, *v))
704 }
705
706 pub fn pattern_types(&self) -> impl Iterator<Item = (PatId, Ty<'db>)> {
708 self.type_of_pat.iter().map(|(k, v)| (k, *v))
709 }
710
711 pub fn binding_types(&self) -> impl Iterator<Item = (BindingId, Ty<'db>)> {
713 self.type_of_binding.iter().map(|(k, v)| (k, *v))
714 }
715
716 pub fn return_position_impl_trait_types(
718 &self,
719 db: &'db dyn HirDatabase,
720 ) -> impl Iterator<Item = (ImplTraitIdx<'db>, Ty<'db>)> {
721 self.type_of_opaque.iter().filter_map(move |(&id, &ty)| {
722 let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {
723 return None;
724 };
725 Some((rpit_idx, ty))
726 })
727 }
728}
729
730impl<'db> Index<ExprId> for InferenceResult<'db> {
731 type Output = Ty<'db>;
732
733 fn index(&self, expr: ExprId) -> &Ty<'db> {
734 self.type_of_expr.get(expr).unwrap_or(&self.error_ty)
735 }
736}
737
738impl<'db> Index<PatId> for InferenceResult<'db> {
739 type Output = Ty<'db>;
740
741 fn index(&self, pat: PatId) -> &Ty<'db> {
742 self.type_of_pat.get(pat).unwrap_or(&self.error_ty)
743 }
744}
745
746impl<'db> Index<ExprOrPatId> for InferenceResult<'db> {
747 type Output = Ty<'db>;
748
749 fn index(&self, id: ExprOrPatId) -> &Ty<'db> {
750 match id {
751 ExprOrPatId::ExprId(id) => &self[id],
752 ExprOrPatId::PatId(id) => &self[id],
753 }
754 }
755}
756
757impl<'db> Index<BindingId> for InferenceResult<'db> {
758 type Output = Ty<'db>;
759
760 fn index(&self, b: BindingId) -> &Ty<'db> {
761 self.type_of_binding.get(b).unwrap_or(&self.error_ty)
762 }
763}
764
765#[derive(Debug, Clone)]
766struct InternedStandardTypes<'db> {
767 unit: Ty<'db>,
768 never: Ty<'db>,
769 char: Ty<'db>,
770 bool: Ty<'db>,
771 i8: Ty<'db>,
772 i16: Ty<'db>,
773 i32: Ty<'db>,
774 i64: Ty<'db>,
775 i128: Ty<'db>,
776 isize: Ty<'db>,
777 u8: Ty<'db>,
778 u16: Ty<'db>,
779 u32: Ty<'db>,
780 u64: Ty<'db>,
781 u128: Ty<'db>,
782 usize: Ty<'db>,
783 f16: Ty<'db>,
784 f32: Ty<'db>,
785 f64: Ty<'db>,
786 f128: Ty<'db>,
787 static_str_ref: Ty<'db>,
788 error: Ty<'db>,
789
790 re_static: Region<'db>,
791 re_error: Region<'db>,
792 re_erased: Region<'db>,
793
794 empty_args: GenericArgs<'db>,
795}
796
797impl<'db> InternedStandardTypes<'db> {
798 fn new(interner: DbInterner<'db>) -> Self {
799 let str = Ty::new(interner, rustc_type_ir::TyKind::Str);
800 let re_static = Region::new_static(interner);
801 Self {
802 unit: Ty::new_unit(interner),
803 never: Ty::new(interner, TyKind::Never),
804 char: Ty::new(interner, TyKind::Char),
805 bool: Ty::new(interner, TyKind::Bool),
806 i8: Ty::new_int(interner, rustc_type_ir::IntTy::I8),
807 i16: Ty::new_int(interner, rustc_type_ir::IntTy::I16),
808 i32: Ty::new_int(interner, rustc_type_ir::IntTy::I32),
809 i64: Ty::new_int(interner, rustc_type_ir::IntTy::I64),
810 i128: Ty::new_int(interner, rustc_type_ir::IntTy::I128),
811 isize: Ty::new_int(interner, rustc_type_ir::IntTy::Isize),
812 u8: Ty::new_uint(interner, rustc_type_ir::UintTy::U8),
813 u16: Ty::new_uint(interner, rustc_type_ir::UintTy::U16),
814 u32: Ty::new_uint(interner, rustc_type_ir::UintTy::U32),
815 u64: Ty::new_uint(interner, rustc_type_ir::UintTy::U64),
816 u128: Ty::new_uint(interner, rustc_type_ir::UintTy::U128),
817 usize: Ty::new_uint(interner, rustc_type_ir::UintTy::Usize),
818 f16: Ty::new_float(interner, rustc_type_ir::FloatTy::F16),
819 f32: Ty::new_float(interner, rustc_type_ir::FloatTy::F32),
820 f64: Ty::new_float(interner, rustc_type_ir::FloatTy::F64),
821 f128: Ty::new_float(interner, rustc_type_ir::FloatTy::F128),
822 static_str_ref: Ty::new_ref(interner, re_static, str, Mutability::Not),
823 error: Ty::new_error(interner, ErrorGuaranteed),
824
825 re_static,
826 re_error: Region::error(interner),
827 re_erased: Region::new_erased(interner),
828
829 empty_args: GenericArgs::new_from_iter(interner, []),
830 }
831 }
832}
833
834#[derive(Clone, Debug)]
836pub(crate) struct InferenceContext<'body, 'db> {
837 pub(crate) db: &'db dyn HirDatabase,
838 pub(crate) owner: DefWithBodyId,
839 pub(crate) body: &'body Body,
840 pub(crate) resolver: Resolver<'db>,
843 target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,
844 pub(crate) unstable_features: MethodResolutionUnstableFeatures,
845 pub(crate) edition: Edition,
846 pub(crate) generic_def: GenericDefId,
847 pub(crate) table: unify::InferenceTable<'db>,
848 pub(crate) lang_items: &'db LangItems,
849 traits_in_scope: FxHashSet<TraitId>,
851 pub(crate) result: InferenceResult<'db>,
852 tuple_field_accesses_rev:
853 IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
854 return_ty: Ty<'db>,
860 return_coercion: Option<DynamicCoerceMany<'db>>,
864 resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,
866 diverges: Diverges,
867 breakables: Vec<BreakableContext<'db>>,
868 types: InternedStandardTypes<'db>,
869
870 inside_assignment: bool,
872
873 deferred_cast_checks: Vec<CastCheck<'db>>,
874
875 current_captures: Vec<CapturedItemWithoutTy<'db>>,
877 current_capture_span_stack: Vec<MirSpan>,
883 current_closure: Option<InternedClosureId>,
884 closure_dependencies: FxHashMap<InternedClosureId, Vec<InternedClosureId>>,
887 deferred_closures: FxHashMap<InternedClosureId, Vec<(Ty<'db>, Ty<'db>, Vec<Ty<'db>>, ExprId)>>,
888
889 diagnostics: Diagnostics<'db>,
890}
891
892#[derive(Clone, Debug)]
893struct BreakableContext<'db> {
894 may_break: bool,
896 coerce: Option<DynamicCoerceMany<'db>>,
898 label: Option<LabelId>,
900 kind: BreakableKind,
901}
902
903#[derive(Clone, Debug)]
904enum BreakableKind {
905 Block,
906 Loop,
907 Border,
910}
911
912fn find_breakable<'a, 'db>(
913 ctxs: &'a mut [BreakableContext<'db>],
914 label: Option<LabelId>,
915) -> Option<&'a mut BreakableContext<'db>> {
916 let mut ctxs = ctxs
917 .iter_mut()
918 .rev()
919 .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
920 match label {
921 Some(_) => ctxs.find(|ctx| ctx.label == label),
922 None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
923 }
924}
925
926fn find_continuable<'a, 'db>(
927 ctxs: &'a mut [BreakableContext<'db>],
928 label: Option<LabelId>,
929) -> Option<&'a mut BreakableContext<'db>> {
930 match label {
931 Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
932 None => find_breakable(ctxs, label),
933 }
934}
935
936impl<'body, 'db> InferenceContext<'body, 'db> {
937 fn new(
938 db: &'db dyn HirDatabase,
939 owner: DefWithBodyId,
940 body: &'body Body,
941 resolver: Resolver<'db>,
942 ) -> Self {
943 let trait_env = db.trait_environment_for_body(owner);
944 let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner));
945 let types = InternedStandardTypes::new(table.interner());
946 InferenceContext {
947 result: InferenceResult::new(types.error),
948 return_ty: types.error, types,
950 target_features: OnceCell::new(),
951 unstable_features: MethodResolutionUnstableFeatures::from_def_map(
952 resolver.top_level_def_map(),
953 ),
954 lang_items: table.interner().lang_items(),
955 edition: resolver.krate().data(db).edition,
956 table,
957 tuple_field_accesses_rev: Default::default(),
958 resume_yield_tys: None,
959 return_coercion: None,
960 db,
961 owner,
962 generic_def: match owner {
963 DefWithBodyId::FunctionId(it) => it.into(),
964 DefWithBodyId::StaticId(it) => it.into(),
965 DefWithBodyId::ConstId(it) => it.into(),
966 DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
967 },
968 body,
969 traits_in_scope: resolver.traits_in_scope(db),
970 resolver,
971 diverges: Diverges::Maybe,
972 breakables: Vec::new(),
973 deferred_cast_checks: Vec::new(),
974 current_captures: Vec::new(),
975 current_capture_span_stack: Vec::new(),
976 current_closure: None,
977 deferred_closures: FxHashMap::default(),
978 closure_dependencies: FxHashMap::default(),
979 inside_assignment: false,
980 diagnostics: Diagnostics::default(),
981 }
982 }
983
984 #[inline]
985 fn krate(&self) -> Crate {
986 self.resolver.krate()
987 }
988
989 fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {
990 let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {
991 let target_features = match self.owner {
992 DefWithBodyId::FunctionId(id) => TargetFeatures::from_fn(self.db, id),
993 _ => TargetFeatures::default(),
994 };
995 let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {
996 Ok(target) => crate::utils::target_feature_is_safe_in_target(target),
997 Err(_) => TargetFeatureIsSafeInTarget::No,
998 };
999 (target_features, target_feature_is_safe)
1000 });
1001 (target_features, *target_feature_is_safe)
1002 }
1003
1004 #[inline]
1005 fn set_tainted_by_errors(&mut self) {
1006 self.result.has_errors = true;
1007 }
1008
1009 pub(crate) fn fixme_resolve_all_clone(&self) -> InferenceResult<'db> {
1012 let mut ctx = self.clone();
1013
1014 ctx.type_inference_fallback();
1015
1016 let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);
1020 for mut cast in cast_checks.into_iter() {
1021 if let Err(diag) = cast.check(&mut ctx) {
1022 ctx.diagnostics.push(diag);
1023 }
1024 }
1025
1026 ctx.table.select_obligations_where_possible();
1027
1028 ctx.resolve_all()
1029 }
1030
1031 fn resolve_all(self) -> InferenceResult<'db> {
1036 let InferenceContext {
1037 mut table, mut result, tuple_field_accesses_rev, diagnostics, ..
1038 } = self;
1039 let mut diagnostics = diagnostics.finish();
1040 let InferenceResult {
1043 method_resolutions,
1044 field_resolutions: _,
1045 variant_resolutions: _,
1046 assoc_resolutions,
1047 type_of_expr,
1048 type_of_pat,
1049 type_of_binding,
1050 type_of_type_placeholder,
1051 type_of_opaque,
1052 type_mismatches,
1053 has_errors,
1054 error_ty: _,
1055 pat_adjustments,
1056 binding_modes: _,
1057 expr_adjustments,
1058 closure_info: _,
1062 mutated_bindings_in_closure: _,
1063 tuple_field_access_types: _,
1064 coercion_casts: _,
1065 diagnostics: _,
1066 } = &mut result;
1067
1068 for ty in type_of_expr.values_mut() {
1069 *ty = table.resolve_completely(*ty);
1070 *has_errors = *has_errors || ty.references_non_lt_error();
1071 }
1072 type_of_expr.shrink_to_fit();
1073 for ty in type_of_pat.values_mut() {
1074 *ty = table.resolve_completely(*ty);
1075 *has_errors = *has_errors || ty.references_non_lt_error();
1076 }
1077 type_of_pat.shrink_to_fit();
1078 for ty in type_of_binding.values_mut() {
1079 *ty = table.resolve_completely(*ty);
1080 *has_errors = *has_errors || ty.references_non_lt_error();
1081 }
1082 type_of_binding.shrink_to_fit();
1083 for ty in type_of_type_placeholder.values_mut() {
1084 *ty = table.resolve_completely(*ty);
1085 *has_errors = *has_errors || ty.references_non_lt_error();
1086 }
1087 type_of_type_placeholder.shrink_to_fit();
1088 type_of_opaque.shrink_to_fit();
1089
1090 if let Some(type_mismatches) = type_mismatches {
1091 *has_errors = true;
1092 for mismatch in type_mismatches.values_mut() {
1093 mismatch.expected = table.resolve_completely(mismatch.expected);
1094 mismatch.actual = table.resolve_completely(mismatch.actual);
1095 }
1096 type_mismatches.shrink_to_fit();
1097 }
1098 diagnostics.retain_mut(|diagnostic| {
1099 use InferenceDiagnostic::*;
1100 match diagnostic {
1101 ExpectedFunction { found: ty, .. }
1102 | UnresolvedField { receiver: ty, .. }
1103 | UnresolvedMethodCall { receiver: ty, .. } => {
1104 *ty = table.resolve_completely(*ty);
1105 if ty.references_non_lt_error() {
1107 return false;
1108 }
1109
1110 if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic
1111 && let Some(ty) = field_with_same_name
1112 {
1113 *ty = table.resolve_completely(*ty);
1114 if ty.references_non_lt_error() {
1115 *field_with_same_name = None;
1116 }
1117 }
1118 }
1119 TypedHole { expected: ty, .. } => {
1120 *ty = table.resolve_completely(*ty);
1121 }
1122 _ => (),
1123 }
1124 true
1125 });
1126 diagnostics.shrink_to_fit();
1127 for (_, subst) in method_resolutions.values_mut() {
1128 *subst = table.resolve_completely(*subst);
1129 *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error());
1130 }
1131 method_resolutions.shrink_to_fit();
1132 for (_, subst) in assoc_resolutions.values_mut() {
1133 *subst = table.resolve_completely(*subst);
1134 *has_errors = *has_errors || subst.types().any(|ty| ty.references_non_lt_error());
1135 }
1136 assoc_resolutions.shrink_to_fit();
1137 for adjustment in expr_adjustments.values_mut().flatten() {
1138 adjustment.target = table.resolve_completely(adjustment.target);
1139 *has_errors = *has_errors || adjustment.target.references_non_lt_error();
1140 }
1141 expr_adjustments.shrink_to_fit();
1142 for adjustment in pat_adjustments.values_mut().flatten() {
1143 *adjustment = table.resolve_completely(*adjustment);
1144 *has_errors = *has_errors || adjustment.references_non_lt_error();
1145 }
1146 pat_adjustments.shrink_to_fit();
1147 result.tuple_field_access_types = tuple_field_accesses_rev
1148 .into_iter()
1149 .map(|subst| table.resolve_completely(subst))
1150 .inspect(|subst| {
1151 *has_errors = *has_errors || subst.iter().any(|ty| ty.references_non_lt_error());
1152 })
1153 .collect();
1154 result.tuple_field_access_types.shrink_to_fit();
1155
1156 result.diagnostics = diagnostics;
1157
1158 result
1159 }
1160
1161 fn collect_const(&mut self, id: ConstId, data: &ConstSignature) {
1162 let return_ty = self.make_ty(
1163 data.type_ref,
1164 &data.store,
1165 InferenceTyDiagnosticSource::Signature,
1166 LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container),
1167 );
1168
1169 self.return_ty = return_ty;
1170 }
1171
1172 fn collect_static(&mut self, data: &StaticSignature) {
1173 let return_ty = self.make_ty(
1174 data.type_ref,
1175 &data.store,
1176 InferenceTyDiagnosticSource::Signature,
1177 LifetimeElisionKind::Elided(self.types.re_static),
1178 );
1179
1180 self.return_ty = return_ty;
1181 }
1182
1183 fn collect_fn(&mut self, func: FunctionId) {
1184 let data = self.db.function_signature(func);
1185 let mut param_tys = self.with_ty_lowering(
1186 &data.store,
1187 InferenceTyDiagnosticSource::Signature,
1188 LifetimeElisionKind::for_fn_params(&data),
1189 |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),
1190 );
1191
1192 if data.is_varargs() {
1195 let va_list_ty = match self.resolve_va_list() {
1196 Some(va_list) => Ty::new_adt(
1197 self.interner(),
1198 va_list,
1199 GenericArgs::for_item_with_defaults(
1200 self.interner(),
1201 va_list.into(),
1202 |_, id, _| self.table.next_var_for_param(id),
1203 ),
1204 ),
1205 None => self.err_ty(),
1206 };
1207
1208 param_tys.push(va_list_ty);
1209 }
1210 let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.next_ty_var()));
1211 if let Some(self_param) = self.body.self_param
1212 && let Some(ty) = param_tys.next()
1213 {
1214 let ty = self.process_user_written_ty(ty);
1215 self.write_binding_ty(self_param, ty);
1216 }
1217 for (ty, pat) in param_tys.zip(&*self.body.params) {
1218 let ty = self.process_user_written_ty(ty);
1219
1220 self.infer_top_pat(*pat, ty, None);
1221 }
1222 self.return_ty = match data.ret_type {
1223 Some(return_ty) => {
1224 let return_ty = self.with_ty_lowering(
1225 &data.store,
1226 InferenceTyDiagnosticSource::Signature,
1227 LifetimeElisionKind::for_fn_ret(self.interner()),
1228 |ctx| {
1229 ctx.impl_trait_mode(ImplTraitLoweringMode::Opaque);
1230 ctx.lower_ty(return_ty)
1231 },
1232 );
1233 self.process_user_written_ty(return_ty)
1234 }
1235 None => self.types.unit,
1236 };
1237
1238 self.return_coercion = Some(CoerceMany::new(self.return_ty));
1239 }
1240
1241 #[inline]
1242 pub(crate) fn interner(&self) -> DbInterner<'db> {
1243 self.table.interner()
1244 }
1245
1246 #[inline]
1247 pub(crate) fn infcx(&self) -> &InferCtxt<'db> {
1248 &self.table.infer_ctxt
1249 }
1250
1251 fn infer_body(&mut self) {
1252 match self.return_coercion {
1253 Some(_) => self.infer_return(self.body.body_expr),
1254 None => {
1255 _ = self.infer_expr_coerce(
1256 self.body.body_expr,
1257 &Expectation::has_type(self.return_ty),
1258 ExprIsRead::Yes,
1259 )
1260 }
1261 }
1262 }
1263
1264 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {
1265 self.result.type_of_expr.insert(expr, ty);
1266 }
1267
1268 pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment<'db>]>) {
1269 if adjustments.is_empty() {
1270 return;
1271 }
1272 match self.result.expr_adjustments.entry(expr) {
1273 std::collections::hash_map::Entry::Occupied(mut entry) => {
1274 match (&mut entry.get_mut()[..], &adjustments[..]) {
1275 (
1276 [Adjustment { kind: Adjust::NeverToAny, target }],
1277 [.., Adjustment { target: new_target, .. }],
1278 ) => {
1279 *target = *new_target;
1282 }
1283 _ => {
1284 *entry.get_mut() = adjustments;
1285 }
1286 }
1287 }
1288 std::collections::hash_map::Entry::Vacant(entry) => {
1289 entry.insert(adjustments);
1290 }
1291 }
1292 }
1293
1294 fn write_pat_adj(&mut self, pat: PatId, adjustments: Box<[Ty<'db>]>) {
1295 if adjustments.is_empty() {
1296 return;
1297 }
1298 self.result.pat_adjustments.entry(pat).or_default().extend(adjustments);
1299 }
1300
1301 pub(crate) fn write_method_resolution(
1302 &mut self,
1303 expr: ExprId,
1304 func: FunctionId,
1305 subst: GenericArgs<'db>,
1306 ) {
1307 self.result.method_resolutions.insert(expr, (func, subst));
1308 }
1309
1310 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
1311 self.result.variant_resolutions.insert(id, variant);
1312 }
1313
1314 fn write_assoc_resolution(
1315 &mut self,
1316 id: ExprOrPatId,
1317 item: CandidateId,
1318 subs: GenericArgs<'db>,
1319 ) {
1320 self.result.assoc_resolutions.insert(id, (item, subs));
1321 }
1322
1323 fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {
1324 self.result.type_of_pat.insert(pat, ty);
1325 }
1326
1327 fn write_type_placeholder_ty(&mut self, type_ref: TypeRefId, ty: Ty<'db>) {
1328 self.result.type_of_type_placeholder.insert(type_ref, ty);
1329 }
1330
1331 fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {
1332 self.result.type_of_binding.insert(id, ty);
1333 }
1334
1335 pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic<'db>) {
1336 self.diagnostics.push(diagnostic);
1337 }
1338
1339 fn with_ty_lowering<R>(
1340 &mut self,
1341 store: &ExpressionStore,
1342 types_source: InferenceTyDiagnosticSource,
1343 lifetime_elision: LifetimeElisionKind<'db>,
1344 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
1345 ) -> R {
1346 let mut ctx = TyLoweringContext::new(
1347 self.db,
1348 &self.resolver,
1349 store,
1350 &self.diagnostics,
1351 types_source,
1352 self.generic_def,
1353 lifetime_elision,
1354 );
1355 f(&mut ctx)
1356 }
1357
1358 fn with_body_ty_lowering<R>(
1359 &mut self,
1360 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
1361 ) -> R {
1362 self.with_ty_lowering(
1363 self.body,
1364 InferenceTyDiagnosticSource::Body,
1365 LifetimeElisionKind::Infer,
1366 f,
1367 )
1368 }
1369
1370 fn make_ty(
1371 &mut self,
1372 type_ref: TypeRefId,
1373 store: &ExpressionStore,
1374 type_source: InferenceTyDiagnosticSource,
1375 lifetime_elision: LifetimeElisionKind<'db>,
1376 ) -> Ty<'db> {
1377 let ty = self
1378 .with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
1379 let ty = self.process_user_written_ty(ty);
1380
1381 let type_variables = collect_type_inference_vars(&ty);
1384 let mut placeholder_ids = vec![];
1385 TypeRef::walk(type_ref, store, &mut |type_ref_id, type_ref| {
1386 if matches!(type_ref, TypeRef::Placeholder) {
1387 placeholder_ids.push(type_ref_id);
1388 }
1389 });
1390
1391 if placeholder_ids.len() == type_variables.len() {
1392 for (placeholder_id, type_variable) in
1393 placeholder_ids.into_iter().zip(type_variables.into_iter())
1394 {
1395 self.write_type_placeholder_ty(placeholder_id, type_variable);
1396 }
1397 }
1398
1399 ty
1400 }
1401
1402 pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
1403 self.make_ty(
1404 type_ref,
1405 self.body,
1406 InferenceTyDiagnosticSource::Body,
1407 LifetimeElisionKind::Infer,
1408 )
1409 }
1410
1411 pub(crate) fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Const<'db> {
1412 let const_ = self.with_ty_lowering(
1413 self.body,
1414 InferenceTyDiagnosticSource::Body,
1415 LifetimeElisionKind::Infer,
1416 |ctx| ctx.lower_const(const_ref, ty),
1417 );
1418 self.insert_type_vars(const_)
1419 }
1420
1421 pub(crate) fn make_path_as_body_const(&mut self, path: &Path, ty: Ty<'db>) -> Const<'db> {
1422 let const_ = self.with_ty_lowering(
1423 self.body,
1424 InferenceTyDiagnosticSource::Body,
1425 LifetimeElisionKind::Infer,
1426 |ctx| ctx.lower_path_as_const(path, ty),
1427 );
1428 self.insert_type_vars(const_)
1429 }
1430
1431 fn err_ty(&self) -> Ty<'db> {
1432 self.types.error
1433 }
1434
1435 pub(crate) fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
1436 let lt = self.with_ty_lowering(
1437 self.body,
1438 InferenceTyDiagnosticSource::Body,
1439 LifetimeElisionKind::Infer,
1440 |ctx| ctx.lower_lifetime(lifetime_ref),
1441 );
1442 self.insert_type_vars(lt)
1443 }
1444
1445 fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
1447 self.table.insert_type_vars_shallow(ty)
1448 }
1449
1450 fn insert_type_vars<T>(&mut self, ty: T) -> T
1451 where
1452 T: TypeFoldable<DbInterner<'db>>,
1453 {
1454 self.table.insert_type_vars(ty)
1455 }
1456
1457 fn unify(&mut self, ty1: Ty<'db>, ty2: Ty<'db>) -> bool {
1458 self.table.unify(ty1, ty2)
1459 }
1460
1461 fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db> {
1465 self.struct_tail_with_normalize(ty, identity)
1466 }
1467
1468 fn struct_tail_with_normalize(
1476 &mut self,
1477 mut ty: Ty<'db>,
1478 mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
1479 ) -> Ty<'db> {
1480 let recursion_limit = 10;
1482 for iteration in 0.. {
1483 if iteration > recursion_limit {
1484 return self.err_ty();
1485 }
1486 match ty.kind() {
1487 TyKind::Adt(adt_def, substs) => match adt_def.def_id().0 {
1488 AdtId::StructId(struct_id) => {
1489 match self.db.field_types(struct_id.into()).values().next_back().copied() {
1490 Some(field) => {
1491 ty = field.instantiate(self.interner(), substs);
1492 }
1493 None => break,
1494 }
1495 }
1496 _ => break,
1497 },
1498 TyKind::Tuple(substs) => match substs.as_slice().split_last() {
1499 Some((last_ty, _)) => ty = *last_ty,
1500 None => break,
1501 },
1502 TyKind::Alias(..) => {
1503 let normalized = normalize(ty);
1504 if ty == normalized {
1505 return ty;
1506 } else {
1507 ty = normalized;
1508 }
1509 }
1510 _ => break,
1511 }
1512 }
1513 ty
1514 }
1515
1516 fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
1518 self.table.process_user_written_ty(ty)
1519 }
1520
1521 fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
1524 self.table.process_remote_user_written_ty(ty)
1525 }
1526
1527 fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
1528 self.table.shallow_resolve(ty)
1529 }
1530
1531 fn resolve_associated_type(
1532 &mut self,
1533 inner_ty: Ty<'db>,
1534 assoc_ty: Option<TypeAliasId>,
1535 ) -> Ty<'db> {
1536 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
1537 }
1538
1539 fn demand_eqtype(
1540 &mut self,
1541 id: ExprOrPatId,
1542 expected: Ty<'db>,
1543 actual: Ty<'db>,
1544 ) -> Result<(), ()> {
1545 let result = self.demand_eqtype_fixme_no_diag(expected, actual);
1546 if result.is_err() {
1547 self.result
1548 .type_mismatches
1549 .get_or_insert_default()
1550 .insert(id, TypeMismatch { expected, actual });
1551 }
1552 result
1553 }
1554
1555 fn demand_eqtype_fixme_no_diag(
1556 &mut self,
1557 expected: Ty<'db>,
1558 actual: Ty<'db>,
1559 ) -> Result<(), ()> {
1560 let result = self
1561 .table
1562 .at(&ObligationCause::new())
1563 .eq(expected, actual)
1564 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
1565 result.map_err(drop)
1566 }
1567
1568 fn demand_suptype(&mut self, expected: Ty<'db>, actual: Ty<'db>) {
1569 let result = self
1570 .table
1571 .at(&ObligationCause::new())
1572 .sup(expected, actual)
1573 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
1574 if let Err(_err) = result {
1575 }
1577 }
1578
1579 fn demand_coerce(
1580 &mut self,
1581 expr: ExprId,
1582 checked_ty: Ty<'db>,
1583 expected: Ty<'db>,
1584 allow_two_phase: AllowTwoPhase,
1585 expr_is_read: ExprIsRead,
1586 ) -> Ty<'db> {
1587 let result = self.coerce(expr.into(), checked_ty, expected, allow_two_phase, expr_is_read);
1588 if let Err(_err) = result {
1589 }
1591 result.unwrap_or(self.types.error)
1592 }
1593
1594 fn expr_ty(&self, expr: ExprId) -> Ty<'db> {
1595 self.result[expr]
1596 }
1597
1598 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
1599 let mut ty = None;
1600 if let Some(it) = self.result.expr_adjustments.get(&e)
1601 && let Some(it) = it.last()
1602 {
1603 ty = Some(it.target);
1604 }
1605 ty.unwrap_or_else(|| self.expr_ty(e))
1606 }
1607
1608 fn resolve_associated_type_with_params(
1609 &mut self,
1610 inner_ty: Ty<'db>,
1611 assoc_ty: Option<TypeAliasId>,
1612 params: &[GenericArg<'db>],
1615 ) -> Ty<'db> {
1616 match assoc_ty {
1617 Some(res_assoc_ty) => {
1618 let alias = Ty::new_alias(
1619 self.interner(),
1620 AliasTyKind::Projection,
1621 AliasTy::new(
1622 self.interner(),
1623 res_assoc_ty.into(),
1624 iter::once(inner_ty.into()).chain(params.iter().copied()),
1625 ),
1626 );
1627 self.table.try_structurally_resolve_type(alias)
1628 }
1629 None => self.err_ty(),
1630 }
1631 }
1632
1633 fn resolve_variant(
1634 &mut self,
1635 node: ExprOrPatId,
1636 path: Option<&Path>,
1637 value_ns: bool,
1638 ) -> (Ty<'db>, Option<VariantId>) {
1639 let path = match path {
1640 Some(path) => path,
1641 None => return (self.err_ty(), None),
1642 };
1643 let mut ctx = TyLoweringContext::new(
1644 self.db,
1645 &self.resolver,
1646 &self.body.store,
1647 &self.diagnostics,
1648 InferenceTyDiagnosticSource::Body,
1649 self.generic_def,
1650 LifetimeElisionKind::Infer,
1651 );
1652 let mut path_ctx = ctx.at_path(path, node);
1653 let interner = DbInterner::conjure();
1654 let (resolution, unresolved) = if value_ns {
1655 let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
1656 return (self.err_ty(), None);
1657 };
1658 match res {
1659 ResolveValueResult::ValueNs(value, _) => match value {
1660 ValueNs::EnumVariantId(var) => {
1661 let args = path_ctx.substs_from_path(var.into(), true, false);
1662 drop(ctx);
1663 let ty = self
1664 .db
1665 .ty(var.lookup(self.db).parent.into())
1666 .instantiate(interner, args);
1667 let ty = self.insert_type_vars(ty);
1668 return (ty, Some(var.into()));
1669 }
1670 ValueNs::StructId(strukt) => {
1671 let args = path_ctx.substs_from_path(strukt.into(), true, false);
1672 drop(ctx);
1673 let ty = self.db.ty(strukt.into()).instantiate(interner, args);
1674 let ty = self.insert_type_vars(ty);
1675 return (ty, Some(strukt.into()));
1676 }
1677 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
1678 _ => {
1679 drop(ctx);
1680 return (self.err_ty(), None);
1681 }
1682 },
1683 ResolveValueResult::Partial(typens, unresolved, _) => (typens, Some(unresolved)),
1684 }
1685 } else {
1686 match path_ctx.resolve_path_in_type_ns() {
1687 Some((it, idx)) => (it, idx),
1688 None => return (self.err_ty(), None),
1689 }
1690 };
1691 return match resolution {
1692 TypeNs::AdtId(AdtId::StructId(strukt)) => {
1693 let args = path_ctx.substs_from_path(strukt.into(), true, false);
1694 drop(ctx);
1695 let ty = self.db.ty(strukt.into()).instantiate(interner, args);
1696 let ty = self.insert_type_vars(ty);
1697 forbid_unresolved_segments(self, (ty, Some(strukt.into())), unresolved)
1698 }
1699 TypeNs::AdtId(AdtId::UnionId(u)) => {
1700 let args = path_ctx.substs_from_path(u.into(), true, false);
1701 drop(ctx);
1702 let ty = self.db.ty(u.into()).instantiate(interner, args);
1703 let ty = self.insert_type_vars(ty);
1704 forbid_unresolved_segments(self, (ty, Some(u.into())), unresolved)
1705 }
1706 TypeNs::EnumVariantId(var) => {
1707 let args = path_ctx.substs_from_path(var.into(), true, false);
1708 drop(ctx);
1709 let ty = self.db.ty(var.lookup(self.db).parent.into()).instantiate(interner, args);
1710 let ty = self.insert_type_vars(ty);
1711 forbid_unresolved_segments(self, (ty, Some(var.into())), unresolved)
1712 }
1713 TypeNs::SelfType(impl_id) => {
1714 let mut ty = self.db.impl_self_ty(impl_id).instantiate_identity();
1715
1716 let Some(remaining_idx) = unresolved else {
1717 drop(ctx);
1718 let Some(mod_path) = path.mod_path() else {
1719 never!("resolver should always resolve lang item paths");
1720 return (self.err_ty(), None);
1721 };
1722 return self.resolve_variant_on_alias(ty, None, mod_path);
1723 };
1724
1725 let mut remaining_segments = path.segments().skip(remaining_idx);
1726
1727 if remaining_segments.len() >= 2 {
1728 path_ctx.ignore_last_segment();
1729 }
1730
1731 let mut tried_resolving_once = false;
1734 while let Some(current_segment) = remaining_segments.first() {
1735 if let TyKind::Adt(adt_def, _) = ty.kind()
1738 && let AdtId::EnumId(id) = adt_def.def_id().0
1739 {
1740 let enum_data = id.enum_variants(self.db);
1741 if let Some(variant) = enum_data.variant(current_segment.name) {
1742 return if remaining_segments.len() == 1 {
1743 (ty, Some(variant.into()))
1744 } else {
1745 (self.err_ty(), None)
1749 };
1750 }
1751 }
1752
1753 if tried_resolving_once {
1754 break;
1757 }
1758
1759 (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true);
1763 tried_resolving_once = true;
1764
1765 ty = self.table.process_user_written_ty(ty);
1766 if ty.is_ty_error() {
1767 return (self.err_ty(), None);
1768 }
1769
1770 remaining_segments = remaining_segments.skip(1);
1771 }
1772 drop(ctx);
1773
1774 let variant = ty.as_adt().and_then(|(id, _)| match id {
1775 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1776 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1777 AdtId::EnumId(_) => {
1778 None
1780 }
1781 });
1782 (ty, variant)
1783 }
1784 TypeNs::TypeAliasId(it) => {
1785 let Some(mod_path) = path.mod_path() else {
1786 never!("resolver should always resolve lang item paths");
1787 return (self.err_ty(), None);
1788 };
1789 let args = path_ctx.substs_from_path_segment(it.into(), true, None, false);
1790 drop(ctx);
1791 let interner = DbInterner::conjure();
1792 let ty = self.db.ty(it.into()).instantiate(interner, args);
1793 let ty = self.insert_type_vars(ty);
1794
1795 self.resolve_variant_on_alias(ty, unresolved, mod_path)
1796 }
1797 TypeNs::AdtSelfType(_) => {
1798 (self.err_ty(), None)
1800 }
1801 TypeNs::GenericParam(_) => {
1802 (self.err_ty(), None)
1804 }
1805 TypeNs::AdtId(AdtId::EnumId(_))
1806 | TypeNs::BuiltinType(_)
1807 | TypeNs::TraitId(_)
1808 | TypeNs::ModuleId(_) => {
1809 (self.err_ty(), None)
1811 }
1812 };
1813
1814 fn forbid_unresolved_segments<'db>(
1815 ctx: &InferenceContext<'_, 'db>,
1816 result: (Ty<'db>, Option<VariantId>),
1817 unresolved: Option<usize>,
1818 ) -> (Ty<'db>, Option<VariantId>) {
1819 if unresolved.is_none() {
1820 result
1821 } else {
1822 (ctx.types.error, None)
1824 }
1825 }
1826 }
1827
1828 fn resolve_variant_on_alias(
1829 &mut self,
1830 ty: Ty<'db>,
1831 unresolved: Option<usize>,
1832 path: &ModPath,
1833 ) -> (Ty<'db>, Option<VariantId>) {
1834 let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
1835 let ty = self.table.try_structurally_resolve_type(ty);
1836 match remaining {
1837 None => {
1838 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
1839 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1840 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1841 AdtId::EnumId(_) => {
1842 None
1844 }
1845 });
1846 (ty, variant)
1847 }
1848 Some(1) => {
1849 let segment = path.segments().last().unwrap();
1850 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1852 let enum_data = enum_id.enum_variants(self.db);
1853 if let Some(variant) = enum_data.variant(segment) {
1854 return (ty, Some(variant.into()));
1855 }
1856 }
1857 (self.err_ty(), None)
1859 }
1860 Some(_) => {
1861 (self.err_ty(), None)
1863 }
1864 }
1865 }
1866
1867 fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
1868 trait_.trait_items(self.db).associated_type_by_name(&Name::new_symbol_root(sym::Output))
1869 }
1870
1871 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
1872 let ItemContainerId::TraitId(trait_) =
1873 self.lang_items.IntoFutureIntoFuture?.lookup(self.db).container
1874 else {
1875 return None;
1876 };
1877 self.resolve_output_on(trait_)
1878 }
1879
1880 fn resolve_boxed_box(&self) -> Option<AdtId> {
1881 let struct_ = self.lang_items.OwnedBox?;
1882 Some(struct_.into())
1883 }
1884
1885 fn resolve_range_full(&self) -> Option<AdtId> {
1886 let struct_ = self.lang_items.RangeFull?;
1887 Some(struct_.into())
1888 }
1889
1890 fn resolve_range(&self) -> Option<AdtId> {
1891 let struct_ = self.lang_items.Range?;
1892 Some(struct_.into())
1893 }
1894
1895 fn resolve_range_inclusive(&self) -> Option<AdtId> {
1896 let struct_ = self.lang_items.RangeInclusiveStruct?;
1897 Some(struct_.into())
1898 }
1899
1900 fn resolve_range_from(&self) -> Option<AdtId> {
1901 let struct_ = self.lang_items.RangeFrom?;
1902 Some(struct_.into())
1903 }
1904
1905 fn resolve_range_to(&self) -> Option<AdtId> {
1906 let struct_ = self.lang_items.RangeTo?;
1907 Some(struct_.into())
1908 }
1909
1910 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
1911 let struct_ = self.lang_items.RangeToInclusive?;
1912 Some(struct_.into())
1913 }
1914
1915 fn resolve_va_list(&self) -> Option<AdtId> {
1916 let struct_ = self.lang_items.VaList?;
1917 Some(struct_.into())
1918 }
1919
1920 pub(crate) fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
1921 let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
1922 if b_traits.peek().is_some() {
1923 Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
1924 } else {
1925 Either::Right(&self.traits_in_scope)
1926 }
1927 }
1928}
1929
1930#[derive(Clone, PartialEq, Eq, Debug)]
1933pub(crate) enum Expectation<'db> {
1934 None,
1935 HasType(Ty<'db>),
1936 Castable(Ty<'db>),
1937 RValueLikeUnsized(Ty<'db>),
1938}
1939
1940impl<'db> Expectation<'db> {
1941 fn has_type(ty: Ty<'db>) -> Self {
1944 if ty.is_ty_error() {
1945 Expectation::None
1947 } else {
1948 Expectation::HasType(ty)
1949 }
1950 }
1951
1952 fn rvalue_hint(ctx: &mut InferenceContext<'_, 'db>, ty: Ty<'db>) -> Self {
1973 match ctx.struct_tail_without_normalization(ty).kind() {
1974 TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(..) => {
1975 Expectation::RValueLikeUnsized(ty)
1976 }
1977 _ => Expectation::has_type(ty),
1978 }
1979 }
1980
1981 fn none() -> Self {
1983 Expectation::None
1984 }
1985
1986 fn resolve(&self, table: &mut unify::InferenceTable<'db>) -> Expectation<'db> {
1987 match self {
1988 Expectation::None => Expectation::None,
1989 Expectation::HasType(t) => Expectation::HasType(table.shallow_resolve(*t)),
1990 Expectation::Castable(t) => Expectation::Castable(table.shallow_resolve(*t)),
1991 Expectation::RValueLikeUnsized(t) => {
1992 Expectation::RValueLikeUnsized(table.shallow_resolve(*t))
1993 }
1994 }
1995 }
1996
1997 fn to_option(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
1998 match self.resolve(table) {
1999 Expectation::None => None,
2000 Expectation::HasType(t)
2001 | Expectation::Castable(t)
2002 | Expectation::RValueLikeUnsized(t) => Some(t),
2003 }
2004 }
2005
2006 fn only_has_type(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2007 match self {
2008 Expectation::HasType(t) => Some(table.shallow_resolve(*t)),
2009 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2010 None
2011 }
2012 }
2013 }
2014
2015 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'db>) -> Ty<'db> {
2016 self.only_has_type(table).unwrap_or_else(|| table.next_ty_var())
2017 }
2018
2019 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'db>) -> Expectation<'db> {
2037 match *self {
2038 Expectation::HasType(ety) => {
2039 let ety = table.structurally_resolve_type(ety);
2040 if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2041 }
2042 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),
2043 _ => Expectation::None,
2044 }
2045 }
2046}
2047
2048#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2049enum Diverges {
2050 Maybe,
2051 Always,
2052}
2053
2054impl Diverges {
2055 fn is_always(self) -> bool {
2056 self == Diverges::Always
2057 }
2058}
2059
2060impl std::ops::BitAnd for Diverges {
2061 type Output = Self;
2062 fn bitand(self, other: Self) -> Self {
2063 std::cmp::min(self, other)
2064 }
2065}
2066
2067impl std::ops::BitOr for Diverges {
2068 type Output = Self;
2069 fn bitor(self, other: Self) -> Self {
2070 std::cmp::max(self, other)
2071 }
2072}
2073
2074impl std::ops::BitAndAssign for Diverges {
2075 fn bitand_assign(&mut self, other: Self) {
2076 *self = *self & other;
2077 }
2078}
2079
2080impl std::ops::BitOrAssign for Diverges {
2081 fn bitor_assign(&mut self, other: Self) {
2082 *self = *self | other;
2083 }
2084}