1mod autoderef;
19mod callee;
20pub(crate) mod cast;
21pub(crate) mod closure;
22mod coerce;
23pub(crate) mod diagnostics;
24mod expr;
25mod fallback;
26mod mutability;
27mod op;
28mod opaques;
29mod pat;
30mod path;
31mod place_op;
32pub(crate) mod unify;
33
34use std::{
35 cell::{OnceCell, RefCell},
36 cmp,
37 convert::identity,
38 fmt,
39 hash::Hash,
40 ops::Deref,
41};
42
43use base_db::{Crate, FxIndexMap};
44use either::Either;
45use hir_def::{
46 AdtId, AssocItemId, AttrDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId,
47 GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId,
48 VariantId,
49 attrs::AttrFlags,
50 expr_store::{Body, ExpressionStore, HygieneId, body::Param, path::Path},
51 hir::{BindingId, Expr, ExprId, ExprOrPatId, ExprOrPatIdPacked, LabelId, PatId, UnaryOp},
52 lang_item::LangItems,
53 layout::Integer,
54 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
55 signatures::EnumSignature,
56 type_ref::{LifetimeRefId, TypeRefId},
57 unstable_features::UnstableFeatures,
58};
59use hir_expand::{mod_path::ModPath, name::Name};
60use indexmap::IndexSet;
61use la_arena::ArenaMap;
62use macros::{TypeFoldable, TypeVisitable};
63use rustc_abi::TargetDataLayout;
64use rustc_ast_ir::Mutability;
65use rustc_hash::{FxHashMap, FxHashSet};
66use rustc_type_ir::{
67 AliasTyKind, TypeFoldable, TypeVisitableExt,
68 inherent::{GenericArgs as _, IntoKind, Ty as _},
69};
70use salsa::SalsaValue;
71use smallvec::SmallVec;
72use span::Edition;
73use stdx::never;
74use thin_vec::ThinVec;
75
76use crate::{
77 ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,
78 TargetFeatures, ThinFxHashMap, ThinFxHashSet, ValueTyDefId,
79 closure_analysis::PlaceBase,
80 consteval::{create_anon_const, path_to_const},
81 db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},
82 generics::Generics,
83 infer::{
84 callee::DeferredCallResolution,
85 closure::analysis::{
86 BorrowKind,
87 expr_use_visitor::{FakeReadCause, Place},
88 },
89 coerce::{CoerceMany, DynamicCoerceMany},
90 diagnostics::{
91 Diagnostics, InferenceTyLoweringContext as TyLoweringContext,
92 InferenceTyLoweringVarsCtx,
93 },
94 expr::ExprIsRead,
95 pat::PatOrigin,
96 unify::resolve_completely::WriteBackCtxt,
97 },
98 lower::{
99 ImplTraitIdx, LifetimeElisionKind, LifetimeLoweringMode, LoweringMode,
100 diagnostics::TyLoweringDiagnostic,
101 },
102 method_resolution::CandidateId,
103 next_solver::{
104 AliasTy, Const, ConstKind, DbInterner, GenericArgs, Region, StoredFnSig, StoredGenericArg,
105 StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,
106 abi::Safety,
107 default_types,
108 infer::{InferCtxt, ObligationInspector, traits::ObligationCause},
109 },
110 solver_errors::SolverDiagnostic,
111 utils::TargetFeatureIsSafeInTarget,
112};
113
114pub use coerce::could_coerce;
115pub use unify::{could_unify, could_unify_deeply};
116
117use cast::{CastCheck, CastError};
118
119fn infer_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {
121 infer_query_with_inspect(db, def, None, LoweringMode::Analysis)
122}
123
124pub fn infer_query_with_inspect<'db>(
125 db: &'db dyn HirDatabase,
126 def: DefWithBodyId,
127 inspect: Option<ObligationInspector<'db>>,
128 lowering_mode: LoweringMode,
129) -> InferenceResult<'db> {
130 let _p = tracing::info_span!("infer_query").entered();
131 let resolver = def.resolver(db);
132 let body = Body::of(db, def);
133 let mut ctx = InferenceContext::new(
134 db,
135 InferBodyId::DefWithBodyId(def),
136 ExpressionStoreOwnerId::Body(def),
137 def.generic_def(db),
138 &body.store,
139 resolver,
140 true,
141 lowering_mode,
142 );
143
144 if let Some(inspect) = inspect {
145 ctx.table.infer_ctxt.attach_obligation_inspector(inspect);
146 }
147
148 match def {
149 DefWithBodyId::FunctionId(f) => {
150 ctx.collect_fn(f, body.self_param.map(|param| param.formal), &body.params)
151 }
152 DefWithBodyId::ConstId(c) => ctx.collect_const_or_static(c.into()),
153 DefWithBodyId::StaticId(s) => ctx.collect_const_or_static(s.into()),
154 DefWithBodyId::VariantId(v) => {
155 ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {
156 hir_def::layout::IntegerType::Pointer(signed) => match signed {
157 true => ctx.types.types.isize,
158 false => ctx.types.types.usize,
159 },
160 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
161 true => match size {
162 Integer::I8 => ctx.types.types.i8,
163 Integer::I16 => ctx.types.types.i16,
164 Integer::I32 => ctx.types.types.i32,
165 Integer::I64 => ctx.types.types.i64,
166 Integer::I128 => ctx.types.types.i128,
167 },
168 false => match size {
169 Integer::I8 => ctx.types.types.u8,
170 Integer::I16 => ctx.types.types.u16,
171 Integer::I32 => ctx.types.types.u32,
172 Integer::I64 => ctx.types.types.u64,
173 Integer::I128 => ctx.types.types.u128,
174 },
175 },
176 };
177 }
178 }
179
180 ctx.infer_body(body.root_expr());
181
182 ctx.infer_mut_body(body.root_expr());
183
184 infer_finalize(ctx)
185}
186
187fn infer_cycle_result<'db>(
188 _: &'db dyn HirDatabase,
189 _: salsa::Id,
190 _: DefWithBodyId,
191) -> InferenceResult<'db> {
192 InferenceResult { has_errors: true, ..InferenceResult::new() }
193}
194
195fn infer_anon_const_query<'db>(
197 db: &'db dyn HirDatabase,
198 def: AnonConstId<'db>,
199) -> InferenceResult<'db> {
200 let _p = tracing::info_span!("infer_anon_const_query").entered();
201 let loc = def.loc(db);
202 let store_owner = loc.owner;
203 let store = ExpressionStore::of(db, store_owner);
204
205 let resolver = store_owner.resolver(db);
206
207 let mut ctx = InferenceContext::new(
208 db,
209 InferBodyId::AnonConstId(def),
210 store_owner,
211 loc.owner.generic_def(db),
212 store,
213 resolver,
214 loc.allow_using_generic_params,
215 LoweringMode::Analysis,
216 );
217
218 ctx.infer_expr(
219 loc.expr,
220 &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),
221 ExprIsRead::Yes,
222 );
223
224 infer_finalize(ctx)
225}
226
227fn infer_anon_const_cycle_result<'db>(
228 _: &'db dyn HirDatabase,
229 _: salsa::Id,
230 _: AnonConstId<'db>,
231) -> InferenceResult<'db> {
232 InferenceResult { has_errors: true, ..InferenceResult::new() }
233}
234
235fn infer_finalize<'db>(mut ctx: InferenceContext<'db>) -> InferenceResult<'db> {
236 ctx.handle_opaque_type_uses();
237
238 ctx.type_inference_fallback();
239
240 let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);
244 for mut cast in cast_checks.into_iter() {
245 if let Err(diag) = cast.check(&mut ctx) {
246 ctx.diagnostics.push(diag);
247 }
248 }
249
250 ctx.table.select_obligations_where_possible();
251
252 ctx.closure_analyze();
255 assert!(ctx.deferred_call_resolutions.is_empty());
256
257 ctx.table.select_obligations_where_possible();
258
259 ctx.handle_opaque_type_uses();
260
261 ctx.merge_anon_consts();
262
263 ctx.resolve_all()
264}
265
266#[derive(Clone, Copy, Debug, Eq, PartialEq)]
267pub enum ByRef {
268 Yes(Mutability),
269 No,
270}
271
272#[derive(Copy, Clone, Debug, Eq, PartialEq)]
278pub struct BindingMode(pub ByRef, pub Mutability);
279
280#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]
281pub enum InferenceDiagnostic {
282 NoSuchField {
283 #[type_visitable(ignore)]
284 field: ExprOrPatIdPacked,
285 #[type_visitable(ignore)]
286 private: Option<LocalFieldId>,
287 #[type_visitable(ignore)]
288 variant: VariantId,
289 },
290 MismatchedArrayPatLen {
291 #[type_visitable(ignore)]
292 pat: PatId,
293 #[type_visitable(ignore)]
294 expected: u64,
295 #[type_visitable(ignore)]
296 found: u64,
297 #[type_visitable(ignore)]
298 has_rest: bool,
299 },
300 ArrayPatternWithoutFixedLength {
301 #[type_visitable(ignore)]
302 pat: PatId,
303 },
304 ExpectedArrayOrSlicePat {
305 #[type_visitable(ignore)]
306 pat: PatId,
307 found: StoredTy,
308 },
309 InvalidRangePatType {
310 #[type_visitable(ignore)]
311 pat: PatId,
312 },
313 DuplicateField {
314 #[type_visitable(ignore)]
315 field: ExprOrPatIdPacked,
316 #[type_visitable(ignore)]
317 variant: VariantId,
318 },
319 PrivateField {
320 #[type_visitable(ignore)]
321 expr: ExprId,
322 #[type_visitable(ignore)]
323 field: FieldId,
324 },
325 PrivateAssocItem {
326 #[type_visitable(ignore)]
327 id: ExprOrPatIdPacked,
328 #[type_visitable(ignore)]
329 item: AssocItemId,
330 },
331 UnresolvedField {
332 #[type_visitable(ignore)]
333 expr: ExprId,
334 receiver: StoredTy,
335 #[type_visitable(ignore)]
336 name: Name,
337 #[type_visitable(ignore)]
338 method_with_same_name_exists: bool,
339 },
340 UnresolvedMethodCall {
341 #[type_visitable(ignore)]
342 expr: ExprId,
343 receiver: StoredTy,
344 #[type_visitable(ignore)]
345 name: Name,
346 field_with_same_name: Option<StoredTy>,
348 #[type_visitable(ignore)]
349 assoc_func_with_same_name: Option<FunctionId>,
350 },
351 UnresolvedAssocItem {
352 #[type_visitable(ignore)]
353 id: ExprOrPatIdPacked,
354 },
355 UnresolvedIdent {
356 #[type_visitable(ignore)]
357 id: ExprOrPatIdPacked,
358 },
359 BreakOutsideOfLoop {
361 #[type_visitable(ignore)]
362 expr: ExprId,
363 #[type_visitable(ignore)]
364 is_break: bool,
365 #[type_visitable(ignore)]
366 bad_value_break: bool,
367 },
368 NonExhaustiveRecordExpr {
369 #[type_visitable(ignore)]
370 expr: ExprId,
371 },
372 NonExhaustiveRecordPat {
373 #[type_visitable(ignore)]
374 pat: PatId,
375 #[type_visitable(ignore)]
376 variant: VariantId,
377 },
378 UnionPatMustHaveExactlyOneField {
379 #[type_visitable(ignore)]
380 pat: PatId,
381 },
382 UnionPatHasRest {
383 #[type_visitable(ignore)]
384 pat: PatId,
385 },
386 FunctionalRecordUpdateOnNonStruct {
387 #[type_visitable(ignore)]
388 base_expr: ExprId,
389 },
390 MismatchedArgCount {
391 #[type_visitable(ignore)]
392 call_expr: ExprId,
393 #[type_visitable(ignore)]
394 expected: usize,
395 #[type_visitable(ignore)]
396 found: usize,
397 #[type_visitable(ignore)]
401 is_fn_trait_call: bool,
402 },
403 MismatchedTupleStructPatArgCount {
404 #[type_visitable(ignore)]
405 pat: PatId,
406 #[type_visitable(ignore)]
407 expected: usize,
408 #[type_visitable(ignore)]
409 found: usize,
410 },
411 ExpectedFunction {
412 #[type_visitable(ignore)]
413 call_expr: ExprId,
414 found: StoredTy,
415 },
416 CannotBeDereferenced {
417 #[type_visitable(ignore)]
418 expr: ExprId,
419 found: StoredTy,
420 },
421 UnaryOperatorCannotBeApplied {
422 #[type_visitable(ignore)]
423 expr: ExprId,
424 #[type_visitable(ignore)]
425 op: UnaryOp,
426 found: StoredTy,
427 },
428 MutRefInImmRefPat {
429 #[type_visitable(ignore)]
430 pat: PatId,
431 },
432 CannotImplicitlyDerefTraitObject {
433 #[type_visitable(ignore)]
434 pat: PatId,
435 found: StoredTy,
436 },
437 CannotIndexInto {
438 #[type_visitable(ignore)]
439 expr: ExprId,
440 found: StoredTy,
441 },
442 TypedHole {
443 #[type_visitable(ignore)]
444 expr: ExprId,
445 expected: StoredTy,
446 },
447 CastToUnsized {
448 #[type_visitable(ignore)]
449 expr: ExprId,
450 cast_ty: StoredTy,
451 },
452 InvalidCast {
453 #[type_visitable(ignore)]
454 expr: ExprId,
455 #[type_visitable(ignore)]
456 error: CastError,
457 expr_ty: StoredTy,
458 cast_ty: StoredTy,
459 },
460 TyDiagnostic {
461 #[type_visitable(ignore)]
462 diag: TyLoweringDiagnostic,
463 },
464 PathDiagnostic {
465 #[type_visitable(ignore)]
466 node: ExprOrPatIdPacked,
467 #[type_visitable(ignore)]
468 diag: PathLoweringDiagnostic,
469 },
470 MethodCallIncorrectGenericsLen {
471 #[type_visitable(ignore)]
472 expr: ExprId,
473 #[type_visitable(ignore)]
474 provided_count: u32,
475 #[type_visitable(ignore)]
476 expected_count: u32,
477 #[type_visitable(ignore)]
478 kind: IncorrectGenericsLenKind,
479 #[type_visitable(ignore)]
480 def: GenericDefId,
481 },
482 MethodCallIllegalSizedBound {
483 #[type_visitable(ignore)]
484 call_expr: ExprId,
485 },
486 MethodCallIncorrectGenericsOrder {
487 #[type_visitable(ignore)]
488 expr: ExprId,
489 #[type_visitable(ignore)]
490 param_id: GenericParamId,
491 #[type_visitable(ignore)]
492 arg_idx: u32,
493 #[type_visitable(ignore)]
495 has_self_arg: bool,
496 },
497 InvalidLhsOfAssignment {
498 #[type_visitable(ignore)]
499 lhs: ExprId,
500 },
501 TypeMustBeKnown {
502 #[type_visitable(ignore)]
503 at_point: Span,
504 top_term: Option<StoredGenericArg>,
505 },
506 UnionExprMustHaveExactlyOneField {
507 #[type_visitable(ignore)]
508 expr: ExprId,
509 },
510 TypeMismatch {
511 #[type_visitable(ignore)]
512 node: ExprOrPatIdPacked,
513 expected: StoredTy,
514 found: StoredTy,
515 },
516 SolverDiagnostic(SolverDiagnostic),
517 ExplicitDropMethodUse {
518 #[type_visitable(ignore)]
519 kind: ExplicitDropMethodUseKind,
520 },
521 MutableRefBinding {
522 #[type_visitable(ignore)]
523 pat: PatId,
524 },
525 YieldOutsideCoroutine {
526 #[type_visitable(ignore)]
527 expr: ExprId,
528 },
529 ReturnOutsideFunction {
530 #[type_visitable(ignore)]
531 expr: ExprId,
532 #[type_visitable(ignore)]
533 kind: ReturnKind,
534 },
535 RecordMissingFields {
536 #[type_visitable(ignore)]
537 record: ExprOrPatId,
538 #[type_visitable(ignore)]
539 variant: VariantId,
540 #[type_visitable(ignore)]
541 missed_fields: Vec<LocalFieldId>,
542 },
543 InvalidPatPathRes {
544 #[type_visitable(ignore)]
545 pat: PatId,
546 #[type_visitable(ignore)]
547 res: ValueNs,
548 },
549 MatchInheritedImmRefWithMutRefPat {
550 #[type_visitable(ignore)]
551 pat: PatId,
552 },
553}
554
555#[derive(Debug, PartialEq, Eq, Clone, Copy)]
556pub enum ReturnKind {
557 ReturnExpr,
558 BecomeExpr,
559}
560
561#[derive(Debug, PartialEq, Eq, Clone)]
562pub enum ExplicitDropMethodUseKind {
563 MethodCall(ExprId),
564 Path(ExprOrPatIdPacked),
565}
566
567#[derive(Clone, Debug, PartialEq, Eq, Hash)]
608pub struct Adjustment {
609 pub kind: Adjust,
610 pub target: StoredTy,
611}
612
613impl Adjustment {
614 pub fn borrow<'db>(
615 interner: DbInterner<'db>,
616 m: Mutability,
617 ty: Ty<'db>,
618 lt: Region<'db>,
619 ) -> Self {
620 let ty = Ty::new_ref(interner, lt, ty, m);
621 Adjustment {
622 kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),
623 target: ty.store(),
624 }
625 }
626}
627
628#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
642pub enum AllowTwoPhase {
643 Yes,
645 No,
646}
647
648#[derive(Clone, Debug, PartialEq, Eq, Hash)]
649pub enum Adjust {
650 NeverToAny,
652 Deref(Option<OverloadedDeref>),
654 Borrow(AutoBorrow),
656 Pointer(PointerCast),
657}
658
659#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
664pub struct OverloadedDeref(pub Mutability);
665
666#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
667pub enum AutoBorrowMutability {
668 Mut { allow_two_phase_borrow: AllowTwoPhase },
669 Not,
670}
671
672impl AutoBorrowMutability {
673 pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {
677 match mutbl {
678 Mutability::Not => Self::Not,
679 Mutability::Mut => Self::Mut { allow_two_phase_borrow },
680 }
681 }
682}
683
684impl From<AutoBorrowMutability> for Mutability {
685 fn from(m: AutoBorrowMutability) -> Self {
686 match m {
687 AutoBorrowMutability::Mut { .. } => Mutability::Mut,
688 AutoBorrowMutability::Not => Mutability::Not,
689 }
690 }
691}
692
693#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
694pub enum AutoBorrow {
695 Ref(AutoBorrowMutability),
697 RawPtr(Mutability),
699}
700
701#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
702pub enum PointerCast {
703 ReifyFnPointer,
705
706 UnsafeFnPointer,
708
709 ClosureFnPointer(Safety),
712
713 MutToConstPointer,
715
716 #[allow(dead_code)]
717 ArrayToPointer,
719
720 Unsize,
731}
732
733#[derive(Debug, Clone, PartialEq, Eq)]
736pub struct PatAdjustment {
737 pub kind: PatAdjust,
738 pub source: StoredTy,
741}
742
743#[derive(Clone, Copy, PartialEq, Eq, Debug)]
745pub enum PatAdjust {
746 BuiltinDeref,
749 OverloadedDeref,
752}
753
754#[derive(Clone, PartialEq, Eq, Debug, SalsaValue)]
760pub struct InferenceResult<'db> {
761 method_resolutions: ThinFxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,
763 field_resolutions: ThinFxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
765 variant_resolutions: ThinFxHashMap<ExprOrPatIdPacked, VariantId>,
767 assoc_resolutions: ThinFxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>,
769 tuple_field_access_types: ThinVec<StoredTys>,
773
774 pub type_of_expr: ArenaMap<ExprId, StoredTy>,
775 pub type_of_pat: ArenaMap<PatId, StoredTy>,
780 pub type_of_binding: ArenaMap<BindingId, StoredTy>,
781 pub type_of_type_placeholder: ThinFxHashMap<TypeRefId, StoredTy>,
782 pub type_of_opaque: ThinFxHashMap<InternedOpaqueTyId<'db>, StoredTy>,
783
784 pub has_errors: bool,
789 diagnostics: ThinVec<InferenceDiagnostic>,
791 nodes_with_type_mismatches: ThinFxHashSet<ExprOrPatIdPacked>,
793
794 pub expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
795 pub pat_adjustments: ThinFxHashMap<PatId, Vec<PatAdjustment>>,
797 pub binding_modes: ArenaMap<PatId, BindingMode>,
811
812 skipped_ref_pats: ThinFxHashSet<PatId>,
815
816 pub coercion_casts: ThinFxHashSet<ExprId>,
817
818 pub closures_data: ThinFxHashMap<ExprId, ClosureData>,
819
820 defined_anon_consts: ThinVec<AnonConstId<'db>>,
821}
822
823#[derive(Clone, PartialEq, Eq, Debug)]
824pub struct ClosureData {
825 pub min_captures: RootVariableMinCaptureList,
828
829 pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,
852
853 pub liberated_sig: StoredFnSig,
888}
889
890pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;
897
898pub(crate) type MinCaptureList = Vec<CapturedPlace>;
900
901#[derive(Eq, PartialEq, Clone, Debug, Hash)]
903pub struct CapturedPlace {
904 pub place: Place,
906
907 pub info: CaptureInfo,
909
910 pub mutability: Mutability,
912}
913
914impl CapturedPlace {
915 pub fn is_by_ref(&self) -> bool {
916 match self.info.capture_kind {
917 UpvarCapture::ByValue | UpvarCapture::ByUse => false,
918 UpvarCapture::ByRef(..) => true,
919 }
920 }
921
922 pub fn captured_local(&self) -> BindingId {
923 match self.place.base {
924 PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,
925 PlaceBase::Rvalue | PlaceBase::StaticItem => {
926 unreachable!("only locals can be captured")
927 }
928 }
929 }
930
931 pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
934 let place_ty = self.place.ty();
935 let make_ref = |mutbl| {
936 let interner = DbInterner::new_no_crate(db);
937 let region = Region::new_erased(interner);
938 Ty::new_ref(interner, region, place_ty, mutbl)
939 };
940 match self.info.capture_kind {
941 UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,
942 UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),
943 }
944 }
945}
946
947#[derive(Clone)]
948pub struct CaptureSourceStack(CaptureSourceStackRepr);
949
950#[derive(Clone)]
951enum CaptureSourceStackRepr {
952 One(ExprOrPatIdPacked),
953 Two([ExprOrPatIdPacked; 2]),
954 Many(ThinVec<ExprOrPatIdPacked>),
955}
956
957impl PartialEq for CaptureSourceStack {
958 fn eq(&self, other: &Self) -> bool {
959 **self == **other
960 }
961}
962
963impl Eq for CaptureSourceStack {}
964
965impl std::hash::Hash for CaptureSourceStack {
966 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
967 (**self).hash(state);
968 }
969}
970
971#[cfg(target_pointer_width = "64")]
972const _: () = assert!(size_of::<CaptureSourceStack>() == 16);
973
974impl Deref for CaptureSourceStack {
975 type Target = [ExprOrPatIdPacked];
976
977 #[inline]
978 fn deref(&self) -> &Self::Target {
979 match &self.0 {
980 CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),
981 CaptureSourceStackRepr::Two(it) => it,
982 CaptureSourceStackRepr::Many(it) => it,
983 }
984 }
985}
986
987impl fmt::Debug for CaptureSourceStack {
988 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989 f.debug_tuple("CaptureSourceStack").field(&&**self).finish()
990 }
991}
992
993impl CaptureSourceStack {
994 #[inline]
995 pub fn len(&self) -> usize {
996 match &self.0 {
997 CaptureSourceStackRepr::One(_) => 1,
998 CaptureSourceStackRepr::Two(_) => 2,
999 CaptureSourceStackRepr::Many(it) => it.len(),
1000 }
1001 }
1002
1003 #[inline]
1004 pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self {
1005 Self(CaptureSourceStackRepr::One(id))
1006 }
1007
1008 #[inline]
1009 pub fn final_source(&self) -> ExprOrPatIdPacked {
1010 *self.last().expect("should always have a final source")
1011 }
1012
1013 pub fn push(&mut self, new_id: ExprOrPatIdPacked) {
1014 match &mut self.0 {
1015 CaptureSourceStackRepr::One(old_id) => {
1016 self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])
1017 }
1018 CaptureSourceStackRepr::Two([old_id1, old_id2]) => {
1019 self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));
1020 }
1021 CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),
1022 }
1023 }
1024
1025 pub fn truncate(&mut self, new_len: usize) {
1026 debug_assert!(new_len > 0);
1027 match &mut self.0 {
1028 CaptureSourceStackRepr::One(_) => {}
1029 CaptureSourceStackRepr::Two([first, _]) => {
1030 if new_len == 1 {
1031 self.0 = CaptureSourceStackRepr::One(*first)
1032 }
1033 }
1034 CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),
1035 }
1036 }
1037
1038 pub fn shrink_to_fit(&mut self) {
1039 match &mut self.0 {
1040 CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}
1041 CaptureSourceStackRepr::Many(ids) => match **ids {
1042 [one] => self.0 = CaptureSourceStackRepr::One(one),
1043 [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),
1044 _ => ids.shrink_to_fit(),
1045 },
1046 }
1047 }
1048}
1049
1050#[derive(Eq, PartialEq, Clone, Debug, Hash)]
1054pub struct CaptureInfo {
1055 pub sources: SmallVec<[CaptureSourceStack; 2]>,
1056
1057 pub capture_kind: UpvarCapture,
1059}
1060
1061#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]
1064pub enum UpvarCapture {
1065 ByRef(BorrowKind),
1067
1068 ByUse,
1070
1071 ByValue,
1075}
1076
1077impl PartialOrd for UpvarCapture {
1079 #[inline]
1080 fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
1081 match (self, other) {
1082 (Self::ByValue, Self::ByValue) | (Self::ByUse, Self::ByUse) => {
1083 Some(cmp::Ordering::Equal)
1084 }
1085 (Self::ByValue | Self::ByUse, Self::ByRef(_)) => Some(cmp::Ordering::Greater),
1086 (Self::ByRef(_), Self::ByValue | Self::ByUse) => Some(cmp::Ordering::Less),
1087 (Self::ByRef(left), Self::ByRef(right)) => Some(left.cmp(right)),
1088 (Self::ByUse, Self::ByValue) | (Self::ByValue, Self::ByUse) => None,
1089 }
1090 }
1091}
1092
1093#[salsa::tracked]
1094impl<'db> InferenceResult<'db> {
1095 #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
1096 fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {
1097 infer_query(db, def)
1098 }
1099
1100 #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]
1106 fn for_anon_const(db: &'db dyn HirDatabase, def: AnonConstId<'db>) -> InferenceResult<'db> {
1107 infer_anon_const_query(db, def)
1108 }
1109}
1110
1111impl<'db> InferenceResult<'db> {
1112 #[inline]
1113 pub fn of(
1114 db: &'db dyn HirDatabase,
1115 def: impl Into<InferBodyId<'db>>,
1116 ) -> &'db InferenceResult<'db> {
1117 match def.into() {
1118 InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),
1119 InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),
1120 }
1121 }
1122}
1123
1124impl<'db> InferenceResult<'db> {
1125 fn new() -> Self {
1126 Self {
1127 method_resolutions: Default::default(),
1128 field_resolutions: Default::default(),
1129 variant_resolutions: Default::default(),
1130 assoc_resolutions: Default::default(),
1131 tuple_field_access_types: Default::default(),
1132 diagnostics: Default::default(),
1133 nodes_with_type_mismatches: Default::default(),
1134 type_of_expr: Default::default(),
1135 type_of_pat: Default::default(),
1136 type_of_binding: Default::default(),
1137 type_of_type_placeholder: Default::default(),
1138 type_of_opaque: Default::default(),
1139 skipped_ref_pats: Default::default(),
1140 has_errors: Default::default(),
1141 pat_adjustments: Default::default(),
1142 binding_modes: Default::default(),
1143 expr_adjustments: Default::default(),
1144 coercion_casts: Default::default(),
1145 closures_data: Default::default(),
1146 defined_anon_consts: Default::default(),
1147 }
1148 }
1149
1150 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {
1151 self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))
1152 }
1153 pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
1154 self.field_resolutions.get(&expr).copied()
1155 }
1156 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
1157 self.variant_resolutions.get(&id.into()).copied()
1158 }
1159 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
1160 self.variant_resolutions.get(&id.into()).copied()
1161 }
1162 pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
1163 match id {
1164 ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
1165 ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
1166 }
1167 }
1168 pub fn assoc_resolutions_for_expr<'a>(
1169 &self,
1170 id: ExprId,
1171 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1172 self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1173 }
1174 pub fn assoc_resolutions_for_pat<'a>(
1175 &self,
1176 id: PatId,
1177 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1178 self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1179 }
1180 pub fn assoc_resolutions_for_expr_or_pat<'a>(
1181 &self,
1182 id: ExprOrPatId,
1183 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1184 match id {
1185 ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
1186 ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
1187 }
1188 }
1189 pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool {
1190 self.nodes_with_type_mismatches.contains(&node)
1191 }
1192 pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {
1193 self.expr_or_pat_has_type_mismatch(expr.into())
1194 }
1195 pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {
1196 self.expr_or_pat_has_type_mismatch(pat.into())
1197 }
1198 pub fn exprs_have_type_mismatches(&self) -> bool {
1199 self.nodes_with_type_mismatches.iter().any(|node| node.is_expr())
1200 }
1201 pub fn has_type_mismatches(&self) -> bool {
1202 !self.nodes_with_type_mismatches.is_empty()
1203 }
1204 pub fn placeholder_types<'a>(&self) -> impl Iterator<Item = (TypeRefId, Ty<'a>)> {
1205 self.type_of_type_placeholder.iter().map(|(&type_ref, ty)| (type_ref, ty.as_ref()))
1206 }
1207 pub fn type_of_type_placeholder<'a>(&self, type_ref: TypeRefId) -> Option<Ty<'a>> {
1208 self.type_of_type_placeholder.get(&type_ref).map(|ty| ty.as_ref())
1209 }
1210 pub fn type_of_expr_or_pat<'a>(&self, id: ExprOrPatId) -> Option<Ty<'a>> {
1211 match id {
1212 ExprOrPatId::ExprId(id) => self.type_of_expr.get(id).map(|it| it.as_ref()),
1213 ExprOrPatId::PatId(id) => self.type_of_pat.get(id).map(|it| it.as_ref()),
1214 }
1215 }
1216 pub fn type_of_expr_with_adjust<'a>(&self, id: ExprId) -> Option<Ty<'a>> {
1217 match self.expr_adjustments.get(&id).and_then(|adjustments| {
1218 adjustments.iter().rfind(|adj| {
1219 !matches!(
1221 adj,
1222 Adjustment {
1223 kind: Adjust::NeverToAny,
1224 target,
1225 } if target.as_ref().is_never()
1226 )
1227 })
1228 }) {
1229 Some(adjustment) => Some(adjustment.target.as_ref()),
1230 None => self.type_of_expr.get(id).map(|it| it.as_ref()),
1231 }
1232 }
1233 pub fn type_of_pat_with_adjust<'a>(&self, id: PatId) -> Ty<'a> {
1234 match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
1235 Some(adjusted) => adjusted.source.as_ref(),
1236 None => self.pat_ty(id),
1237 }
1238 }
1239 pub fn is_erroneous(&self) -> bool {
1240 self.has_errors && self.type_of_expr.iter().count() == 0
1241 }
1242
1243 pub fn diagnostics(&self) -> &[InferenceDiagnostic] {
1244 &self.diagnostics
1245 }
1246
1247 pub fn tuple_field_access_type<'a>(&self, id: TupleId) -> Tys<'a> {
1248 self.tuple_field_access_types[id.0 as usize].as_ref()
1249 }
1250
1251 pub fn pat_adjustment(&self, id: PatId) -> Option<&[PatAdjustment]> {
1252 self.pat_adjustments.get(&id).map(|it| &**it)
1253 }
1254
1255 pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {
1256 self.expr_adjustments.get(&id).map(|it| &**it)
1257 }
1258
1259 pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {
1260 self.binding_modes.get(id).copied()
1261 }
1262
1263 pub fn expression_types<'a>(&self) -> impl Iterator<Item = (ExprId, Ty<'a>)> {
1265 self.type_of_expr.iter().map(|(k, v)| (k, v.as_ref()))
1266 }
1267
1268 pub fn pattern_types<'a>(&self) -> impl Iterator<Item = (PatId, Ty<'a>)> {
1270 self.type_of_pat.iter().map(|(k, v)| (k, v.as_ref()))
1271 }
1272
1273 pub fn binding_types<'a>(&self) -> impl Iterator<Item = (BindingId, Ty<'a>)> {
1275 self.type_of_binding.iter().map(|(k, v)| (k, v.as_ref()))
1276 }
1277
1278 pub fn return_position_impl_trait_types<'a>(
1280 &'a self,
1281 db: &'a dyn HirDatabase,
1282 ) -> impl Iterator<Item = (ImplTraitIdx, Ty<'a>)> {
1283 self.type_of_opaque.iter().filter_map(move |(&id, ty)| {
1284 let ImplTraitId::ReturnTypeImplTrait(_, rpit_idx) = id.loc(db) else {
1285 return None;
1286 };
1287 Some((rpit_idx, ty.as_ref()))
1288 })
1289 }
1290
1291 pub fn expr_ty<'a>(&self, id: ExprId) -> Ty<'a> {
1292 self.type_of_expr.get(id).map_or(default_types().types.error, |it| it.as_ref())
1293 }
1294
1295 pub fn pat_ty<'a>(&self, id: PatId) -> Ty<'a> {
1296 self.type_of_pat.get(id).map_or(default_types().types.error, |it| it.as_ref())
1297 }
1298
1299 pub fn expr_or_pat_ty<'a>(&self, id: ExprOrPatId) -> Ty<'a> {
1300 self.type_of_expr_or_pat(id).unwrap_or(default_types().types.error)
1301 }
1302
1303 pub fn binding_ty<'a>(&self, id: BindingId) -> Ty<'a> {
1304 self.type_of_binding.get(id).map_or(default_types().types.error, |it| it.as_ref())
1305 }
1306
1307 pub fn closure_captures_tys<'a>(&self, closure: ExprId) -> impl Iterator<Item = Ty<'a>> {
1309 self.closures_data[&closure]
1310 .min_captures
1311 .values()
1312 .flat_map(|captures| captures.iter().map(|capture| capture.place.ty()))
1313 }
1314
1315 pub fn closure_captures_captured_tys<'a>(
1317 &self,
1318 db: &'a dyn HirDatabase,
1319 closure: ExprId,
1320 ) -> impl Iterator<Item = Ty<'a>> {
1321 self.closures_data[&closure]
1322 .min_captures
1323 .values()
1324 .flat_map(|captures| captures.iter().map(|capture| capture.captured_ty(db)))
1325 }
1326
1327 pub fn is_skipped_ref_pat(&self, pat: PatId) -> bool {
1328 self.skipped_ref_pats.contains(&pat)
1329 }
1330}
1331
1332#[derive(Debug, Clone, Copy)]
1333enum DerefPatBorrowMode {
1334 Borrow(Mutability),
1335 Box,
1336}
1337
1338#[derive(Debug)]
1340pub(crate) struct InferenceContext<'db> {
1341 pub(crate) db: &'db dyn HirDatabase,
1342 pub(crate) owner: InferBodyId<'db>,
1343 pub(crate) store_owner: ExpressionStoreOwnerId,
1344 pub(crate) generic_def: GenericDefId,
1345 pub(crate) store: &'db ExpressionStore,
1346 pub(crate) lowering_mode: LoweringMode,
1347 pub(crate) resolver: Resolver<'db>,
1350 target_features: OnceCell<(TargetFeatures<'db>, TargetFeatureIsSafeInTarget)>,
1351 data_layout: OnceCell<&'db TargetDataLayout>,
1352 pub(crate) edition: Edition,
1353 allow_using_generic_params: bool,
1354 generics: OnceCell<Generics<'db>>,
1355 identity_args: OnceCell<GenericArgs<'db>>,
1356 pub(crate) table: unify::InferenceTable<'db>,
1357 pub(crate) lang_items: &'db LangItems,
1358 pub(crate) features: &'db UnstableFeatures,
1359 traits_in_scope: FxHashSet<TraitId>,
1361 pub(crate) result: InferenceResult<'db>,
1362 tuple_field_accesses_rev:
1363 IndexSet<Tys<'db>, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
1364 return_ty: Ty<'db>,
1370 return_coercion: Option<DynamicCoerceMany<'db>>,
1374 resume_yield_tys: Option<(Ty<'db>, Ty<'db>)>,
1376 diverges: Diverges,
1377 breakables: Vec<BreakableContext<'db>>,
1378 types: &'db crate::next_solver::DefaultAny<'db>,
1379
1380 deferred_cast_checks: Vec<CastCheck<'db>>,
1381
1382 deferred_call_resolutions: FxHashMap<ExprId, Vec<DeferredCallResolution<'db>>>,
1384
1385 diagnostics: Diagnostics,
1386 vars_emitted_type_must_be_known_for: FxHashSet<Term<'db>>,
1387
1388 defined_anon_consts: RefCell<ThinVec<AnonConstId<'db>>>,
1389}
1390
1391#[derive(Clone, Debug)]
1392struct BreakableContext<'db> {
1393 may_break: bool,
1395 coerce: Option<DynamicCoerceMany<'db>>,
1397 label: Option<LabelId>,
1399 kind: BreakableKind,
1400}
1401
1402#[derive(Clone, Debug)]
1403enum BreakableKind {
1404 Block,
1405 Loop,
1406 Border,
1409}
1410
1411fn find_breakable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {
1412 let mut ctxs = ctxs
1413 .iter()
1414 .enumerate()
1415 .rev()
1416 .take_while(|(_, it)| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
1417 let result = match label {
1418 Some(_) => ctxs.find(|(_, ctx)| ctx.label == label),
1419 None => ctxs.find(|(_, ctx)| matches!(ctx.kind, BreakableKind::Loop)),
1420 };
1421 result.map(|(idx, _)| idx)
1422}
1423
1424fn find_continuable(ctxs: &[BreakableContext<'_>], label: Option<LabelId>) -> Option<usize> {
1425 find_breakable(ctxs, label)
1426 .filter(|&idx| label.is_none() || matches!(ctxs[idx].kind, BreakableKind::Loop))
1427}
1428
1429impl<'db> InferenceContext<'db> {
1430 fn new(
1431 db: &'db dyn HirDatabase,
1432 owner: InferBodyId<'db>,
1433 store_owner: ExpressionStoreOwnerId,
1434 generic_def: GenericDefId,
1435 store: &'db ExpressionStore,
1436 resolver: Resolver<'db>,
1437 allow_using_generic_params: bool,
1438 lowering_mode: LoweringMode,
1439 ) -> Self {
1440 let trait_env = db.trait_environment(generic_def);
1441 let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), owner);
1442 let types = crate::next_solver::default_types();
1443 InferenceContext {
1444 result: InferenceResult::new(),
1445 return_ty: types.types.error, types,
1447 target_features: OnceCell::new(),
1448 data_layout: OnceCell::new(),
1449 lang_items: table.interner().lang_items(),
1450 features: resolver.top_level_def_map().features(),
1451 edition: resolver.krate().data(db).edition,
1452 table,
1453 tuple_field_accesses_rev: Default::default(),
1454 resume_yield_tys: None,
1455 return_coercion: None,
1456 db,
1457 owner,
1458 store_owner,
1459 generic_def,
1460 allow_using_generic_params,
1461 generics: OnceCell::new(),
1462 identity_args: OnceCell::new(),
1463 store,
1464 traits_in_scope: resolver.traits_in_scope(db),
1465 resolver,
1466 diverges: Diverges::Maybe,
1467 breakables: Vec::new(),
1468 deferred_cast_checks: Vec::new(),
1469 diagnostics: Diagnostics::default(),
1470 vars_emitted_type_must_be_known_for: FxHashSet::default(),
1471 deferred_call_resolutions: FxHashMap::default(),
1472 defined_anon_consts: RefCell::new(ThinVec::new()),
1473 lowering_mode,
1474 }
1475 }
1476
1477 fn merge(&mut self, other: &InferenceResult<'db>) {
1478 let InferenceResult {
1479 method_resolutions,
1480 field_resolutions,
1481 variant_resolutions,
1482 assoc_resolutions,
1483 tuple_field_access_types: _,
1484 type_of_expr,
1485 type_of_pat,
1486 type_of_binding,
1487 type_of_type_placeholder,
1488 type_of_opaque,
1489 has_errors: _,
1490 diagnostics: _,
1491 expr_adjustments,
1492 pat_adjustments,
1493 binding_modes,
1494 skipped_ref_pats,
1495 coercion_casts,
1496 closures_data,
1497 nodes_with_type_mismatches,
1498 defined_anon_consts: _,
1499 } = &mut self.result;
1500 merge_thin_hash_maps(method_resolutions, &other.method_resolutions);
1501 merge_thin_hash_maps(variant_resolutions, &other.variant_resolutions);
1502 merge_thin_hash_maps(assoc_resolutions, &other.assoc_resolutions);
1503 field_resolutions.extend(other.field_resolutions.iter().map(
1504 |(&field_expr, &field_resolution)| {
1505 let mut field_resolution = field_resolution;
1506 if let Either::Right(tuple_field) = &mut field_resolution {
1507 let tys = other.tuple_field_access_type(tuple_field.tuple);
1508 tuple_field.tuple =
1509 TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);
1510 };
1511 (field_expr, field_resolution)
1512 },
1513 ));
1514 merge_arena_maps(type_of_expr, &other.type_of_expr);
1515 merge_arena_maps(type_of_pat, &other.type_of_pat);
1516 merge_arena_maps(type_of_binding, &other.type_of_binding);
1517 merge_thin_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);
1518 merge_thin_hash_maps(type_of_opaque, &other.type_of_opaque);
1519 merge_hash_maps(expr_adjustments, &other.expr_adjustments);
1520 merge_thin_hash_maps(pat_adjustments, &other.pat_adjustments);
1521 merge_arena_maps(binding_modes, &other.binding_modes);
1522 merge_thin_hash_set(skipped_ref_pats, &other.skipped_ref_pats);
1523 merge_thin_hash_set(coercion_casts, &other.coercion_casts);
1524 merge_thin_hash_maps(closures_data, &other.closures_data);
1525 merge_thin_hash_set(nodes_with_type_mismatches, &other.nodes_with_type_mismatches);
1526 self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());
1527 self.diagnostics.extend(&other.diagnostics);
1528
1529 fn merge_thin_hash_set<T: Hash + Eq + Clone>(
1530 dest: &mut ThinFxHashSet<T>,
1531 source: &ThinFxHashSet<T>,
1532 ) {
1533 dest.extend(source.iter().cloned());
1534 }
1535
1536 #[cfg_attr(debug_assertions, track_caller)]
1537 fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(
1538 dest: &mut FxHashMap<K, V>,
1539 source: &FxHashMap<K, V>,
1540 ) {
1541 if cfg!(debug_assertions) {
1542 for (key, src) in source {
1543 assert!(dest.get(key).is_none_or(|dst| dst == src));
1544 }
1545 }
1546
1547 dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));
1548 }
1549
1550 #[cfg_attr(debug_assertions, track_caller)]
1551 fn merge_thin_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(
1552 dest: &mut ThinFxHashMap<K, V>,
1553 source: &ThinFxHashMap<K, V>,
1554 ) {
1555 if cfg!(debug_assertions) {
1556 for (key, src) in source {
1557 assert!(dest.get(key).is_none_or(|dst| dst == src));
1558 }
1559 }
1560
1561 dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));
1562 }
1563
1564 #[cfg_attr(debug_assertions, track_caller)]
1565 fn merge_arena_maps<K, V: Clone + PartialEq>(
1566 dest: &mut ArenaMap<la_arena::Idx<K>, V>,
1567 source: &ArenaMap<la_arena::Idx<K>, V>,
1568 ) {
1569 if cfg!(debug_assertions) {
1570 for (key, src) in source.iter() {
1571 assert!(dest.get(key).is_none_or(|dst| dst == src));
1572 }
1573 }
1574
1575 dest.extend(source.iter().map(|(k, v)| (k, v.clone())));
1576 }
1577 }
1578
1579 #[inline]
1580 fn krate(&self) -> Crate {
1581 self.resolver.krate()
1582 }
1583
1584 fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {
1585 let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {
1586 let target_features = match self.store_owner {
1587 ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {
1588 TargetFeatures::from_fn(self.db, id)
1589 }
1590 _ => TargetFeatures::default(),
1591 };
1592 let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {
1593 Ok(target) => crate::utils::target_feature_is_safe_in_target(target),
1594 Err(_) => TargetFeatureIsSafeInTarget::No,
1595 };
1596 (target_features, target_feature_is_safe)
1597 });
1598 (target_features, *target_feature_is_safe)
1599 }
1600
1601 fn data_layout(&self) -> &'db TargetDataLayout {
1602 self.data_layout.get_or_init(|| self.db.target_data_layout_or_default(self.krate()))
1603 }
1604
1605 fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {
1612 if pointer_ty.is_box() {
1613 DerefPatBorrowMode::Box
1614 } else {
1615 let mutability =
1616 if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
1617 DerefPatBorrowMode::Borrow(mutability)
1618 }
1619 }
1620
1621 #[inline]
1622 fn set_tainted_by_errors(&mut self) {
1623 self.result.has_errors = true;
1624 }
1625
1626 fn merge_anon_consts(&mut self) {
1629 let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());
1630 defined_anon_consts.retain(|&konst| {
1631 if konst.loc(self.db).owner != self.store_owner {
1632 return false;
1634 }
1635
1636 let const_infer = InferenceResult::of(self.db, konst);
1637 self.merge(const_infer);
1638 true
1639 });
1640 self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);
1642 }
1643
1644 fn resolve_all(self) -> InferenceResult<'db> {
1645 let InferenceContext {
1646 table,
1647 mut result,
1648 tuple_field_accesses_rev,
1649 diagnostics,
1650 types,
1651 vars_emitted_type_must_be_known_for,
1652 ..
1653 } = self;
1654 let diagnostics = diagnostics.finish();
1655 let InferenceResult {
1658 method_resolutions,
1659 field_resolutions: _,
1660 variant_resolutions: _,
1661 assoc_resolutions,
1662 type_of_expr,
1663 type_of_pat,
1664 type_of_binding,
1665 type_of_type_placeholder,
1666 type_of_opaque,
1667 skipped_ref_pats,
1668 closures_data,
1669 has_errors,
1670 pat_adjustments,
1671 binding_modes: _,
1672 expr_adjustments,
1673 tuple_field_access_types,
1674 coercion_casts: _,
1675 diagnostics: result_diagnostics,
1676 nodes_with_type_mismatches,
1677 defined_anon_consts: result_defined_anon_consts,
1678 } = &mut result;
1679
1680 *result_defined_anon_consts = self.defined_anon_consts.into_inner();
1681 result_defined_anon_consts.shrink_to_fit();
1682
1683 let mut resolver =
1684 WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);
1685
1686 skipped_ref_pats.shrink_to_fit();
1687 for ty in type_of_expr.values_mut() {
1688 resolver.resolve_completely(ty);
1689 }
1690 type_of_expr.shrink_to_fit();
1691 for ty in type_of_pat.values_mut() {
1692 resolver.resolve_completely(ty);
1693 }
1694 type_of_pat.shrink_to_fit();
1695 for ty in type_of_binding.values_mut() {
1696 resolver.resolve_completely(ty);
1697 }
1698 type_of_binding.shrink_to_fit();
1699 for ty in type_of_type_placeholder.values_mut() {
1700 resolver.resolve_completely(ty);
1701 }
1702 type_of_type_placeholder.shrink_to_fit();
1703 type_of_opaque.shrink_to_fit();
1704
1705 if !nodes_with_type_mismatches.is_empty() {
1706 *has_errors = true;
1707 }
1708 nodes_with_type_mismatches.shrink_to_fit();
1709 for (_, subst) in method_resolutions.values_mut() {
1710 resolver.resolve_completely(subst);
1711 }
1712 method_resolutions.shrink_to_fit();
1713 for (_, subst) in assoc_resolutions.values_mut() {
1714 resolver.resolve_completely(subst);
1715 }
1716 assoc_resolutions.shrink_to_fit();
1717 for adjustment in expr_adjustments.values_mut().flatten() {
1718 resolver.resolve_completely(&mut adjustment.target);
1719 }
1720 expr_adjustments.shrink_to_fit();
1721 for adjustments in pat_adjustments.values_mut() {
1722 for adjustment in &mut *adjustments {
1723 resolver.resolve_completely(&mut adjustment.source);
1724 }
1725 adjustments.shrink_to_fit();
1726 }
1727 pat_adjustments.shrink_to_fit();
1728 for closure_data in closures_data.values_mut() {
1729 let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data;
1730 let dummy_place = || Place {
1731 base_ty: types.types.error.store(),
1732 base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,
1733 projections: Vec::new(),
1734 };
1735
1736 for (place, _, sources) in fake_reads {
1737 resolver.resolve_completely_with_default(place, dummy_place());
1738 place.projections.shrink_to_fit();
1739 for source in &mut *sources {
1740 source.shrink_to_fit();
1741 }
1742 sources.shrink_to_fit();
1743 }
1744
1745 for min_capture in min_captures.values_mut() {
1746 for captured in &mut *min_capture {
1747 let CapturedPlace { place, info, mutability: _ } = captured;
1748 resolver.resolve_completely_with_default(place, dummy_place());
1749 let CaptureInfo { sources, capture_kind: _ } = info;
1750 for source in &mut *sources {
1751 source.shrink_to_fit();
1752 }
1753 sources.shrink_to_fit();
1754 }
1755 min_capture.shrink_to_fit();
1756 }
1757 min_captures.shrink_to_fit();
1758
1759 resolver.resolve_completely(liberated_sig);
1760 }
1761 closures_data.shrink_to_fit();
1762 *tuple_field_access_types = tuple_field_accesses_rev
1763 .into_iter()
1764 .map(|mut subst| {
1765 resolver.resolve_completely(&mut subst);
1766 subst.store()
1767 })
1768 .collect();
1769 tuple_field_access_types.shrink_to_fit();
1770
1771 let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();
1772 *result_diagnostics = diagnostics;
1773 *has_errors |= resolver_has_errors;
1774
1775 result
1776 }
1777
1778 fn collect_const_or_static(&mut self, id: ValueTyDefId) {
1779 let return_ty = self.db.value_ty(id).unwrap().instantiate_identity().skip_norm_wip();
1780 self.return_ty = self.process_remote_user_written_ty(return_ty);
1781 }
1782
1783 fn collect_fn(
1784 &mut self,
1785 func: FunctionId,
1786 self_param: Option<BindingId>,
1787 params: &[Param<PatId>],
1788 ) {
1789 let sig = self.interner().liberate_late_bound_regions(
1790 func.into(),
1791 self.db.callable_item_signature(func.into()).instantiate_identity().skip_norm_wip(),
1792 );
1793
1794 let maybe_va_list =
1797 if sig.fn_sig_kind.c_variadic() { self.resolve_va_list() } else { None };
1798 let maybe_va_list = maybe_va_list.map(|va_list| {
1799 let region = self.table.next_region_var(
1800 params.last().expect("variadic function must have parameters").user_written.into(),
1801 );
1802 Ty::new_adt(self.interner(), va_list, GenericArgs::new_from_slice(&[region.into()]))
1803 });
1804
1805 let mut param_tys = sig.inputs().iter().copied();
1806
1807 if let Some(self_param) = self_param
1808 && let Some(ty) = param_tys.next()
1809 {
1810 let ty = self.process_remote_user_written_ty(ty);
1811 self.write_binding_ty(self_param, ty);
1812 }
1813
1814 let mut param_tys = param_tys.chain(maybe_va_list);
1815 for pat in params {
1816 let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));
1817 let ty = self.process_remote_user_written_ty(ty);
1818
1819 self.infer_top_pat(pat.formal, ty, PatOrigin::Param);
1820 }
1821
1822 self.return_ty = self.process_remote_user_written_ty(sig.output());
1823 self.return_coercion = Some(CoerceMany::new(self.return_ty));
1824 }
1825
1826 #[inline]
1827 pub(crate) fn interner(&self) -> DbInterner<'db> {
1828 self.table.interner()
1829 }
1830
1831 #[inline]
1832 pub(crate) fn infcx(&self) -> &InferCtxt<'db> {
1833 &self.table.infer_ctxt
1834 }
1835
1836 fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
1851 if ty.is_ty_error() {
1852 let var = self.table.next_ty_var(Span::Dummy);
1853
1854 self.vars_emitted_type_must_be_known_for.insert(var.into());
1856
1857 var
1858 } else {
1859 ty
1860 }
1861 }
1862
1863 fn infer_body(&mut self, body_expr: ExprId) {
1864 match self.return_coercion {
1865 Some(_) => self.infer_return(body_expr),
1866 None => {
1867 _ = self.infer_expr_coerce(
1868 body_expr,
1869 &Expectation::has_type(self.return_ty),
1870 ExprIsRead::Yes,
1871 )
1872 }
1873 }
1874 }
1875
1876 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {
1877 self.result.type_of_expr.insert(expr, ty.store());
1878 }
1879
1880 pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1881 if adjustments.is_empty() {
1882 return;
1883 }
1884 match self.result.expr_adjustments.entry(expr) {
1885 std::collections::hash_map::Entry::Occupied(mut entry) => {
1886 match (&mut entry.get_mut()[..], &adjustments[..]) {
1887 (
1888 [Adjustment { kind: Adjust::NeverToAny, target }],
1889 [.., Adjustment { target: new_target, .. }],
1890 ) => {
1891 *target = new_target.clone();
1894 }
1895 _ => {
1896 *entry.get_mut() = adjustments;
1897 }
1898 }
1899 }
1900 std::collections::hash_map::Entry::Vacant(entry) => {
1901 entry.insert(adjustments);
1902 }
1903 }
1904 }
1905
1906 pub(crate) fn write_method_resolution(
1907 &mut self,
1908 expr: ExprId,
1909 func: FunctionId,
1910 subst: GenericArgs<'db>,
1911 ) {
1912 self.result.method_resolutions.insert(expr, (func, subst.store()));
1913 }
1914
1915 fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) {
1916 self.result.variant_resolutions.insert(id, variant);
1917 }
1918
1919 fn write_assoc_resolution(
1920 &mut self,
1921 id: ExprOrPatIdPacked,
1922 item: CandidateId,
1923 subs: GenericArgs<'db>,
1924 ) {
1925 self.result.assoc_resolutions.insert(id, (item, subs.store()));
1926 }
1927
1928 fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {
1929 self.result.type_of_pat.insert(pat, ty.store());
1930 }
1931
1932 fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {
1933 self.result.type_of_binding.insert(id, ty.store());
1934 }
1935
1936 pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1937 self.diagnostics.push(diagnostic);
1938 }
1939
1940 fn record_deferred_call_resolution(
1941 &mut self,
1942 closure_def_id: ExprId,
1943 r: DeferredCallResolution<'db>,
1944 ) {
1945 self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
1946 }
1947
1948 fn remove_deferred_call_resolutions(
1949 &mut self,
1950 closure_def_id: ExprId,
1951 ) -> Vec<DeferredCallResolution<'db>> {
1952 self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
1953 }
1954
1955 fn with_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R) -> R {
1956 let mut infer_vars = InferenceTyLoweringVarsCtx {
1957 table: &mut self.table,
1958 type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
1959 };
1960 let mut ctx = TyLoweringContext::new(
1961 self.db,
1962 &self.resolver,
1963 self.store,
1964 &self.diagnostics,
1965 self.store_owner,
1966 self.generic_def,
1967 &self.generics,
1968 LifetimeElisionKind::Infer,
1969 self.allow_using_generic_params,
1970 &mut infer_vars,
1971 &self.defined_anon_consts,
1972 LifetimeLoweringMode::LateParam,
1973 );
1974 f(&mut ctx)
1975 }
1976
1977 pub(crate) fn make_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
1978 let ty = self.with_ty_lowering(|ctx| ctx.lower_ty(type_ref));
1979 self.process_user_written_ty(ty)
1980 }
1981
1982 fn generics(&self) -> &Generics<'db> {
1983 self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
1984 }
1985
1986 fn identity_args(&self) -> GenericArgs<'db> {
1987 *self.identity_args.get_or_init(|| {
1988 GenericArgs::identity_for_item(self.interner(), self.generic_def.into())
1989 })
1990 }
1991
1992 pub(crate) fn create_anon_const(&mut self, expr: ExprId, expected_ty: Ty<'db>) -> Const<'db> {
1993 never!(expected_ty.has_infer(), "cannot have infer vars in an anon const's ty");
1994 let konst = create_anon_const(
1995 self.interner(),
1996 self.store_owner,
1997 self.store,
1998 expr,
1999 &self.resolver,
2000 expected_ty,
2001 &|| self.generics(),
2002 Some(&mut |span| self.table.next_const_var(span)),
2003 self.lowering_mode,
2004 (!self.allow_using_generic_params).then_some(0),
2005 false,
2009 );
2010
2011 if let Ok(konst) = konst
2012 && let ConstKind::Unevaluated(konst) = konst.kind()
2013 && let GeneralConstId::AnonConstId(konst) = konst.def.0
2014 {
2015 self.defined_anon_consts.borrow_mut().push(konst);
2016 } else {
2017 self.write_expr_ty(expr, expected_ty);
2018 }
2019
2020 konst.unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2022 }
2023
2024 pub(crate) fn make_path_as_const(&mut self, path: &Path) -> Const<'db> {
2025 let forbid_params_after = if self.allow_using_generic_params { None } else { Some(0) };
2026 path_to_const(self.db, &self.resolver, &|| self.generics(), forbid_params_after, path)
2028 .unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2029 }
2030
2031 fn err_ty(&self) -> Ty<'db> {
2032 self.types.types.error
2033 }
2034
2035 pub(crate) fn make_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
2036 let lt = self.with_ty_lowering(|ctx| ctx.lower_lifetime(lifetime_ref));
2037 self.insert_type_vars(lt)
2038 }
2039
2040 fn insert_type_vars<T>(&mut self, ty: T) -> T
2041 where
2042 T: TypeFoldable<DbInterner<'db>>,
2043 {
2044 self.table.insert_type_vars(ty)
2045 }
2046
2047 fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db> {
2051 self.struct_tail_with_normalize(ty, identity)
2052 }
2053
2054 fn struct_tail_with_normalize(
2062 &mut self,
2063 mut ty: Ty<'db>,
2064 mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
2065 ) -> Ty<'db> {
2066 let recursion_limit = 10;
2068 for iteration in 0.. {
2069 if iteration > recursion_limit {
2070 return self.err_ty();
2071 }
2072 match ty.kind() {
2073 TyKind::Adt(adt_def, substs) => match adt_def.def_id() {
2074 AdtId::StructId(struct_id) => {
2075 match self
2076 .db
2077 .field_types(struct_id.into())
2078 .values()
2079 .next_back()
2080 .map(|it| it.ty())
2081 {
2082 Some(field) => {
2083 ty = field.instantiate(self.interner(), substs).skip_norm_wip();
2084 }
2085 None => break,
2086 }
2087 }
2088 _ => break,
2089 },
2090 TyKind::Tuple(substs) => match substs.as_slice().split_last() {
2091 Some((last_ty, _)) => ty = *last_ty,
2092 None => break,
2093 },
2094 TyKind::Alias(..) => {
2095 let normalized = normalize(ty);
2096 if ty == normalized {
2097 return ty;
2098 } else {
2099 ty = normalized;
2100 }
2101 }
2102 _ => break,
2103 }
2104 }
2105 ty
2106 }
2107
2108 fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2110 self.table.process_user_written_ty(ty)
2111 }
2112
2113 fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2116 self.table.process_remote_user_written_ty(ty)
2117 }
2118
2119 fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
2120 self.table.shallow_resolve(ty)
2121 }
2122
2123 pub(crate) fn resolve_vars_if_possible<T: TypeFoldable<DbInterner<'db>>>(&self, t: T) -> T {
2124 self.table.resolve_vars_if_possible(t)
2125 }
2126
2127 pub(crate) fn structurally_resolve_type(
2128 &mut self,
2129 node: ExprOrPatIdPacked,
2130 ty: Ty<'db>,
2131 ) -> Ty<'db> {
2132 let result = self.table.try_structurally_resolve_type(node.into(), ty);
2133 if result.is_ty_var() { self.type_must_be_known_at_this_point(node, ty) } else { result }
2134 }
2135
2136 pub(crate) fn innermost_tail_expr(&self, mut expr: ExprId) -> ExprId {
2137 while let Expr::Block { tail: Some(tail), label: None, .. } = self.store[expr] {
2138 expr = tail;
2139 }
2140 expr
2141 }
2142
2143 pub(crate) fn emit_type_mismatch(
2144 &mut self,
2145 node: ExprOrPatIdPacked,
2146 expected: Ty<'db>,
2147 found: Ty<'db>,
2148 ) {
2149 if self.result.nodes_with_type_mismatches.insert(node) {
2150 self.diagnostics.push(InferenceDiagnostic::TypeMismatch {
2151 node,
2152 expected: expected.store(),
2153 found: found.store(),
2154 });
2155 }
2156 }
2157
2158 fn demand_eqtype(
2159 &mut self,
2160 id: ExprOrPatIdPacked,
2161 expected: Ty<'db>,
2162 actual: Ty<'db>,
2163 ) -> Result<(), ()> {
2164 let result = self
2165 .table
2166 .at(&ObligationCause::new(id))
2167 .eq(expected, actual)
2168 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2169 if result.is_err() {
2170 self.emit_type_mismatch(id, expected, actual);
2171 }
2172 result.map_err(drop)
2173 }
2174
2175 fn demand_eqtype_fixme_no_diag(
2176 &mut self,
2177 expected: Ty<'db>,
2178 actual: Ty<'db>,
2179 ) -> Result<(), ()> {
2180 let result = self
2181 .table
2182 .at(&ObligationCause::dummy())
2183 .eq(expected, actual)
2184 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2185 result.map_err(drop)
2186 }
2187
2188 fn demand_suptype(
2189 &mut self,
2190 id: ExprOrPatIdPacked,
2191 expected: Ty<'db>,
2192 actual: Ty<'db>,
2193 ) -> Result<(), ()> {
2194 let result = self
2195 .table
2196 .at(&ObligationCause::new(id))
2197 .sup(expected, actual)
2198 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2199 if result.is_err() {
2200 self.emit_type_mismatch(id, expected, actual);
2201 }
2202 result.map_err(drop)
2203 }
2204
2205 fn demand_coerce(
2206 &mut self,
2207 expr: ExprId,
2208 checked_ty: Ty<'db>,
2209 expected: Ty<'db>,
2210 allow_two_phase: AllowTwoPhase,
2211 expr_is_read: ExprIsRead,
2212 ) -> Ty<'db> {
2213 let result = self.coerce(expr, checked_ty, expected, allow_two_phase, expr_is_read);
2214 if let Err(_err) = result {
2215 }
2217 result.unwrap_or(self.types.types.error)
2218 }
2219
2220 pub(crate) fn type_must_be_known_at_this_point(
2221 &mut self,
2222 node: ExprOrPatIdPacked,
2223 ty: Ty<'db>,
2224 ) -> Ty<'db> {
2225 if self.vars_emitted_type_must_be_known_for.insert(ty.into()) {
2226 self.push_diagnostic(InferenceDiagnostic::TypeMustBeKnown {
2227 at_point: node.into(),
2228 top_term: None,
2229 });
2230 }
2231 self.types.types.error
2232 }
2233
2234 pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>, span: Span) {
2235 if !ty.references_non_lt_error()
2236 && let Some(sized_trait) = self.lang_items.Sized
2237 {
2238 self.table.register_bound(ty, sized_trait, ObligationCause::new(span));
2239 }
2240 }
2241
2242 fn expr_ty(&self, expr: ExprId) -> Ty<'db> {
2243 self.result.expr_ty(expr)
2244 }
2245
2246 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
2247 let mut ty = None;
2248 if let Some(it) = self.result.expr_adjustments.get(&e)
2249 && let Some(it) = it.last()
2250 {
2251 ty = Some(it.target.as_ref());
2252 }
2253 ty.unwrap_or_else(|| self.expr_ty(e))
2254 }
2255
2256 fn resolve_variant(
2257 &mut self,
2258 node: ExprOrPatIdPacked,
2259 path: &Path,
2260 value_ns: bool,
2261 ) -> (Ty<'db>, Option<VariantId>) {
2262 let interner = self.interner();
2263 let mut vars_ctx = InferenceTyLoweringVarsCtx {
2264 table: &mut self.table,
2265 type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
2266 };
2267 let mut ctx = TyLoweringContext::new(
2268 self.db,
2269 &self.resolver,
2270 self.store,
2271 &self.diagnostics,
2272 self.store_owner,
2273 self.generic_def,
2274 &self.generics,
2275 LifetimeElisionKind::Infer,
2276 self.allow_using_generic_params,
2277 &mut vars_ctx,
2278 &self.defined_anon_consts,
2279 LifetimeLoweringMode::LateParam,
2280 );
2281
2282 if let Some(type_anchor) = path.type_anchor() {
2283 let mut segments = path.segments();
2284 if segments.is_empty() {
2285 return (self.types.types.error, None);
2286 }
2287 let (mut ty, type_ns) = ctx.lower_ty_ext(type_anchor);
2288 ty = ctx.expect_table().process_user_written_ty(ty);
2289
2290 if let Some(TypeNs::SelfType(impl_)) = type_ns
2291 && let Some(trait_ref) = self.db.impl_trait(impl_)
2292 && let trait_ref = trait_ref.instantiate_identity().skip_norm_wip()
2293 && let Some(assoc_type) = trait_ref
2294 .def_id
2295 .0
2296 .trait_items(self.db)
2297 .associated_type_by_name(segments.first().unwrap().name)
2298 {
2299 let args = ctx.expect_table().infer_ctxt.fill_rest_fresh_args(
2301 node.into(),
2302 assoc_type.into(),
2303 trait_ref.args,
2304 );
2305 let alias = Ty::new_alias(
2306 interner,
2307 AliasTy::new_from_args(
2308 interner,
2309 AliasTyKind::Projection { def_id: assoc_type.into() },
2310 args,
2311 ),
2312 );
2313 ty = ctx.expect_table().try_structurally_resolve_type(node.into(), alias);
2314 segments = segments.skip(1);
2315 }
2316
2317 let variant = match ty.as_adt() {
2318 Some((AdtId::StructId(id), _)) => id.into(),
2319 Some((AdtId::UnionId(id), _)) => id.into(),
2320 Some((AdtId::EnumId(id), _)) => {
2321 if let Some(segment) = segments.first()
2322 && let enum_data = id.enum_variants(self.db)
2323 && let Some(variant) = enum_data.variant(segment.name)
2324 {
2325 segments = segments.skip(1);
2327 variant.into()
2328 } else {
2329 return (self.types.types.error, None);
2330 }
2331 }
2332 None => return (self.types.types.error, None),
2333 };
2334
2335 if !segments.is_empty() {
2336 return (self.types.types.error, None);
2338 } else {
2339 return (ty, Some(variant));
2340 }
2341 }
2342
2343 let mut path_ctx = ctx.at_path(path, node);
2344 let interner = DbInterner::conjure();
2345 let (resolution, unresolved) = if value_ns {
2346 let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
2347 return (self.types.types.error, None);
2348 };
2349 match res {
2350 ResolveValueResult::ValueNs(value) => match value {
2351 ValueNs::EnumVariantId(var) => {
2352 let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2353 drop(ctx);
2354 let ty = self
2355 .db
2356 .ty(var.lookup(self.db).parent.into())
2357 .instantiate(interner, args)
2358 .skip_norm_wip();
2359 let ty = self.insert_type_vars(ty);
2360 return (ty, Some(var.into()));
2361 }
2362 ValueNs::StructId(strukt) => {
2363 let args =
2364 path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2365 drop(ctx);
2366 let ty =
2367 self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2368 let ty = self.insert_type_vars(ty);
2369 return (ty, Some(strukt.into()));
2370 }
2371 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
2372 _ => {
2373 drop(ctx);
2374 return (self.types.types.error, None);
2375 }
2376 },
2377 ResolveValueResult::Partial(typens, unresolved) => (typens, Some(unresolved)),
2378 }
2379 } else {
2380 match path_ctx.resolve_path_in_type_ns() {
2381 Some((it, idx)) => (it, idx),
2382 None => return (self.types.types.error, None),
2383 }
2384 };
2385 return match resolution {
2386 TypeNs::AdtId(AdtId::StructId(strukt)) => {
2387 let args = path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2388 drop(ctx);
2389 let ty = self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2390 let ty = self.insert_type_vars(ty);
2391 forbid_unresolved_segments(self, (ty, Some(strukt.into())), unresolved)
2392 }
2393 TypeNs::AdtId(AdtId::UnionId(u)) => {
2394 let args = path_ctx.substs_from_path(u.into(), true, false, node.into());
2395 drop(ctx);
2396 let ty = self.db.ty(u.into()).instantiate(interner, args).skip_norm_wip();
2397 let ty = self.insert_type_vars(ty);
2398 forbid_unresolved_segments(self, (ty, Some(u.into())), unresolved)
2399 }
2400 TypeNs::EnumVariantId(var) => {
2401 let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2402 drop(ctx);
2403 let ty = self
2404 .db
2405 .ty(var.lookup(self.db).parent.into())
2406 .instantiate(interner, args)
2407 .skip_norm_wip();
2408 let ty = self.insert_type_vars(ty);
2409 forbid_unresolved_segments(self, (ty, Some(var.into())), unresolved)
2410 }
2411 TypeNs::SelfType(impl_id) => {
2412 let mut ty = self.db.impl_self_ty(impl_id).instantiate_identity().skip_norm_wip();
2413
2414 let Some(remaining_idx) = unresolved else {
2415 drop(ctx);
2416 let Some(mod_path) = path.mod_path() else {
2417 never!("resolver should always resolve lang item paths");
2418 return (self.types.types.error, None);
2419 };
2420 return self.resolve_variant_on_alias(node, ty, None, mod_path);
2421 };
2422
2423 let mut remaining_segments = path.segments().skip(remaining_idx);
2424
2425 if remaining_segments.len() >= 2 {
2426 path_ctx.ignore_last_segment();
2427 }
2428
2429 let mut tried_resolving_once = false;
2432 while let Some(current_segment) = remaining_segments.first() {
2433 if let TyKind::Adt(adt_def, _) = ty.kind()
2436 && let AdtId::EnumId(id) = adt_def.def_id()
2437 {
2438 let enum_data = id.enum_variants(self.db);
2439 if let Some(variant) = enum_data.variant(current_segment.name) {
2440 return if remaining_segments.len() == 1 {
2441 (ty, Some(variant.into()))
2442 } else {
2443 (self.types.types.error, None)
2447 };
2448 }
2449 }
2450
2451 if tried_resolving_once {
2452 break;
2455 }
2456
2457 (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2461 tried_resolving_once = true;
2462
2463 ty = path_ctx.expect_table().process_user_written_ty(ty);
2464 if ty.is_ty_error() {
2465 return (self.types.types.error, None);
2466 }
2467
2468 remaining_segments = remaining_segments.skip(1);
2469 }
2470 drop(ctx);
2471
2472 let variant = ty.as_adt().and_then(|(id, _)| match id {
2473 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2474 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2475 AdtId::EnumId(_) => {
2476 None
2478 }
2479 });
2480 (ty, variant)
2481 }
2482 TypeNs::TraitId(_) => {
2483 let Some(remaining_idx) = unresolved else {
2484 return (self.types.types.error, None);
2485 };
2486
2487 let remaining_segments = path.segments().skip(remaining_idx);
2488
2489 if remaining_segments.len() >= 2 {
2490 path_ctx.ignore_last_segment();
2491 }
2492
2493 let (mut ty, _) =
2494 path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2495 ty = ctx.expect_table().process_user_written_ty(ty);
2496
2497 if let Some(segment) = remaining_segments.get(1)
2498 && let Some((AdtId::EnumId(id), _)) = ty.as_adt()
2499 {
2500 let enum_data = id.enum_variants(self.db);
2501 if let Some(variant) = enum_data.variant(segment.name) {
2502 return if remaining_segments.len() == 2 {
2503 (ty, Some(variant.into()))
2504 } else {
2505 (self.types.types.error, None)
2509 };
2510 }
2511 }
2512
2513 let variant = ty.as_adt().and_then(|(id, _)| match id {
2514 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2515 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2516 AdtId::EnumId(_) => {
2517 None
2519 }
2520 });
2521 (ty, variant)
2522 }
2523 TypeNs::TypeAliasId(it) => {
2524 let Some(mod_path) = path.mod_path() else {
2525 never!("resolver should always resolve lang item paths");
2526 return (self.types.types.error, None);
2527 };
2528 let args =
2529 path_ctx.substs_from_path_segment(it.into(), true, None, false, node.into());
2530 let interner = path_ctx.interner();
2531 drop(ctx);
2532 let ty = self.db.ty(it.into()).instantiate(interner, args).skip_norm_wip();
2533 let ty = self.insert_type_vars(ty);
2534
2535 self.resolve_variant_on_alias(node, ty, unresolved, mod_path)
2536 }
2537 TypeNs::AdtSelfType(_) => {
2538 (self.types.types.error, None)
2540 }
2541 TypeNs::GenericParam(_) => {
2542 (self.types.types.error, None)
2544 }
2545 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::ModuleId(_) => {
2546 (self.types.types.error, None)
2548 }
2549 };
2550
2551 fn forbid_unresolved_segments<'db>(
2552 ctx: &InferenceContext<'db>,
2553 result: (Ty<'db>, Option<VariantId>),
2554 unresolved: Option<usize>,
2555 ) -> (Ty<'db>, Option<VariantId>) {
2556 if unresolved.is_none() {
2557 result
2558 } else {
2559 (ctx.types.types.error, None)
2561 }
2562 }
2563 }
2564
2565 fn resolve_variant_on_alias(
2566 &mut self,
2567 node: ExprOrPatIdPacked,
2568 ty: Ty<'db>,
2569 unresolved: Option<usize>,
2570 path: &ModPath,
2571 ) -> (Ty<'db>, Option<VariantId>) {
2572 let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
2573 let ty = self.table.try_structurally_resolve_type(node.into(), ty);
2574 match remaining {
2575 None => {
2576 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
2577 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2578 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2579 AdtId::EnumId(_) => {
2580 None
2582 }
2583 });
2584 (ty, variant)
2585 }
2586 Some(1) => {
2587 let segment = path.segments().last().unwrap();
2588 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
2590 let enum_data = enum_id.enum_variants(self.db);
2591 if let Some(variant) = enum_data.variant(segment) {
2592 return (ty, Some(variant.into()));
2593 }
2594 }
2595 (self.err_ty(), None)
2597 }
2598 Some(_) => {
2599 (self.err_ty(), None)
2601 }
2602 }
2603 }
2604
2605 fn resolve_va_list(&self) -> Option<AdtId> {
2606 let struct_ = self.lang_items.VaList?;
2607 Some(struct_.into())
2608 }
2609
2610 pub(crate) fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
2611 let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
2612 if b_traits.peek().is_some() {
2613 Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
2614 } else {
2615 Either::Right(&self.traits_in_scope)
2616 }
2617 }
2618
2619 fn has_applicable_non_exhaustive(&self, def: AttrDefId) -> bool {
2620 AttrFlags::query(self.db, def).contains(AttrFlags::NON_EXHAUSTIVE)
2621 && def.krate(self.db) != self.krate()
2622 }
2623}
2624
2625#[derive(Clone, PartialEq, Eq, Debug)]
2628pub(crate) enum Expectation<'db> {
2629 None,
2630 HasType(Ty<'db>),
2631 Castable(Ty<'db>),
2632 RValueLikeUnsized(Ty<'db>),
2633}
2634
2635impl<'db> Expectation<'db> {
2636 fn has_type(ty: Ty<'db>) -> Self {
2639 if ty.is_ty_error() {
2640 Expectation::None
2642 } else {
2643 Expectation::HasType(ty)
2644 }
2645 }
2646
2647 fn rvalue_hint(ctx: &mut InferenceContext<'db>, ty: Ty<'db>) -> Self {
2668 match ctx.struct_tail_without_normalization(ty).kind() {
2669 TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(..) => {
2670 Expectation::RValueLikeUnsized(ty)
2671 }
2672 _ => Expectation::has_type(ty),
2673 }
2674 }
2675
2676 fn none() -> Self {
2678 Expectation::None
2679 }
2680
2681 fn resolve(&self, table: &unify::InferenceTable<'db>) -> Expectation<'db> {
2682 match self {
2683 Expectation::None => Expectation::None,
2684 Expectation::HasType(t) => Expectation::HasType(table.shallow_resolve(*t)),
2685 Expectation::Castable(t) => Expectation::Castable(table.shallow_resolve(*t)),
2686 Expectation::RValueLikeUnsized(t) => {
2687 Expectation::RValueLikeUnsized(table.shallow_resolve(*t))
2688 }
2689 }
2690 }
2691
2692 fn to_option(&self, table: &unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2693 match self.resolve(table) {
2694 Expectation::None => None,
2695 Expectation::HasType(t)
2696 | Expectation::Castable(t)
2697 | Expectation::RValueLikeUnsized(t) => Some(t),
2698 }
2699 }
2700
2701 fn only_has_type(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2702 match self {
2703 Expectation::HasType(t) => Some(table.resolve_vars_if_possible(*t)),
2704 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2705 None
2706 }
2707 }
2708 }
2709
2710 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'db>, span: Span) -> Ty<'db> {
2711 self.only_has_type(table).unwrap_or_else(|| table.next_ty_var(span))
2712 }
2713
2714 fn adjust_for_branches(
2732 &self,
2733 table: &mut unify::InferenceTable<'db>,
2734 span: Span,
2735 ) -> Expectation<'db> {
2736 match *self {
2737 Expectation::HasType(ety) => {
2738 let ety = table.try_structurally_resolve_type(span, ety);
2739 if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2740 }
2741 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),
2742 _ => Expectation::None,
2743 }
2744 }
2745}
2746
2747#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2748enum Diverges {
2749 Maybe,
2750 Always,
2751}
2752
2753impl Diverges {
2754 fn is_always(self) -> bool {
2755 self == Diverges::Always
2756 }
2757}
2758
2759impl std::ops::BitAnd for Diverges {
2760 type Output = Self;
2761 fn bitand(self, other: Self) -> Self {
2762 std::cmp::min(self, other)
2763 }
2764}
2765
2766impl std::ops::BitOr for Diverges {
2767 type Output = Self;
2768 fn bitor(self, other: Self) -> Self {
2769 std::cmp::max(self, other)
2770 }
2771}
2772
2773impl std::ops::BitAndAssign for Diverges {
2774 fn bitand_assign(&mut self, other: Self) {
2775 *self = *self & other;
2776 }
2777}
2778
2779impl std::ops::BitOrAssign for Diverges {
2780 fn bitor_assign(&mut self, other: Self) {
2781 *self = *self | other;
2782 }
2783}