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