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, UnaryOp},
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_abi::TargetDataLayout;
63use rustc_ast_ir::Mutability;
64use rustc_hash::{FxHashMap, FxHashSet};
65use rustc_type_ir::{
66 AliasTyKind, TypeFoldable, TypeVisitableExt,
67 inherent::{GenericArgs as _, IntoKind, Ty as _},
68};
69use salsa::SalsaValue;
70use smallvec::SmallVec;
71use span::Edition;
72use stdx::never;
73use thin_vec::ThinVec;
74
75use crate::{
76 ImplTraitId, IncorrectGenericsLenKind, InferBodyId, PathLoweringDiagnostic, Span,
77 TargetFeatures,
78 closure_analysis::PlaceBase,
79 consteval::{create_anon_const, path_to_const},
80 db::{AnonConstId, GeneralConstId, HirDatabase, InternedOpaqueTyId},
81 generics::Generics,
82 infer::{
83 callee::DeferredCallResolution,
84 closure::analysis::{
85 BorrowKind,
86 expr_use_visitor::{FakeReadCause, Place},
87 },
88 coerce::{CoerceMany, DynamicCoerceMany},
89 diagnostics::{
90 Diagnostics, InferenceTyLoweringContext as TyLoweringContext,
91 InferenceTyLoweringVarsCtx,
92 },
93 expr::ExprIsRead,
94 pat::PatOrigin,
95 unify::resolve_completely::WriteBackCtxt,
96 },
97 lower::{
98 ImplTraitIdx, ImplTraitLoweringMode, LifetimeElisionKind, LifetimeLoweringMode,
99 LoweringMode, diagnostics::TyLoweringDiagnostic,
100 },
101 method_resolution::CandidateId,
102 next_solver::{
103 AliasTy, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, Region, StoredFnSig,
104 StoredGenericArg, StoredGenericArgs, StoredTy, StoredTys, Term, Ty, TyKind, Tys,
105 abi::Safety,
106 infer::{InferCtxt, ObligationInspector, traits::ObligationCause},
107 },
108 solver_errors::SolverDiagnostic,
109 utils::TargetFeatureIsSafeInTarget,
110};
111
112#[allow(unreachable_pub)]
116pub use coerce::could_coerce;
117#[allow(unreachable_pub)]
118pub use unify::{could_unify, could_unify_deeply};
119
120use cast::{CastCheck, CastError};
121
122fn infer_query<'db>(db: &'db dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'db> {
124 infer_query_with_inspect(db, def, None, LoweringMode::Analysis)
125}
126
127pub fn infer_query_with_inspect<'db>(
128 db: &'db dyn HirDatabase,
129 def: DefWithBodyId,
130 inspect: Option<ObligationInspector<'db>>,
131 lowering_mode: LoweringMode,
132) -> InferenceResult<'db> {
133 let _p = tracing::info_span!("infer_query").entered();
134 let resolver = def.resolver(db);
135 let body = Body::of(db, def);
136 let mut ctx = InferenceContext::new(
137 db,
138 InferBodyId::DefWithBodyId(def),
139 ExpressionStoreOwnerId::Body(def),
140 def.generic_def(db),
141 &body.store,
142 resolver,
143 true,
144 lowering_mode,
145 );
146
147 if let Some(inspect) = inspect {
148 ctx.table.infer_ctxt.attach_obligation_inspector(inspect);
149 }
150
151 match def {
152 DefWithBodyId::FunctionId(f) => {
153 ctx.collect_fn(f, body.self_param.map(|param| param.formal), &body.params)
154 }
155 DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)),
156 DefWithBodyId::StaticId(s) => ctx.collect_static(s, StaticSignature::of(db, s)),
157 DefWithBodyId::VariantId(v) => {
158 ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {
159 hir_def::layout::IntegerType::Pointer(signed) => match signed {
160 true => ctx.types.types.isize,
161 false => ctx.types.types.usize,
162 },
163 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
164 true => match size {
165 Integer::I8 => ctx.types.types.i8,
166 Integer::I16 => ctx.types.types.i16,
167 Integer::I32 => ctx.types.types.i32,
168 Integer::I64 => ctx.types.types.i64,
169 Integer::I128 => ctx.types.types.i128,
170 },
171 false => match size {
172 Integer::I8 => ctx.types.types.u8,
173 Integer::I16 => ctx.types.types.u16,
174 Integer::I32 => ctx.types.types.u32,
175 Integer::I64 => ctx.types.types.u64,
176 Integer::I128 => ctx.types.types.u128,
177 },
178 },
179 };
180 }
181 }
182
183 ctx.infer_body(body.root_expr());
184
185 ctx.infer_mut_body(body.root_expr());
186
187 infer_finalize(ctx)
188}
189
190fn infer_cycle_result<'db>(
191 db: &'db dyn HirDatabase,
192 _: salsa::Id,
193 _: DefWithBodyId,
194) -> InferenceResult<'db> {
195 InferenceResult {
196 has_errors: true,
197 ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
198 }
199}
200
201fn infer_anon_const_query<'db>(
203 db: &'db dyn HirDatabase,
204 def: AnonConstId<'db>,
205) -> InferenceResult<'db> {
206 let _p = tracing::info_span!("infer_anon_const_query").entered();
207 let loc = def.loc(db);
208 let store_owner = loc.owner;
209 let store = ExpressionStore::of(db, store_owner);
210
211 let resolver = store_owner.resolver(db);
212
213 let mut ctx = InferenceContext::new(
214 db,
215 InferBodyId::AnonConstId(def),
216 store_owner,
217 loc.owner.generic_def(db),
218 store,
219 resolver,
220 loc.allow_using_generic_params,
221 LoweringMode::Analysis,
222 );
223
224 ctx.infer_expr(
225 loc.expr,
226 &Expectation::has_type(loc.ty.get().instantiate_identity().skip_norm_wip()),
227 ExprIsRead::Yes,
228 );
229
230 infer_finalize(ctx)
231}
232
233fn infer_anon_const_cycle_result<'db>(
234 db: &'db dyn HirDatabase,
235 _: salsa::Id,
236 _: AnonConstId<'db>,
237) -> InferenceResult<'db> {
238 InferenceResult {
239 has_errors: true,
240 ..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
241 }
242}
243
244fn infer_finalize<'db>(mut ctx: InferenceContext<'db>) -> InferenceResult<'db> {
245 ctx.handle_opaque_type_uses();
246
247 ctx.type_inference_fallback();
248
249 let cast_checks = std::mem::take(&mut ctx.deferred_cast_checks);
253 for mut cast in cast_checks.into_iter() {
254 if let Err(diag) = cast.check(&mut ctx) {
255 ctx.diagnostics.push(diag);
256 }
257 }
258
259 ctx.table.select_obligations_where_possible();
260
261 ctx.closure_analyze();
264 assert!(ctx.deferred_call_resolutions.is_empty());
265
266 ctx.table.select_obligations_where_possible();
267
268 ctx.handle_opaque_type_uses();
269
270 ctx.merge_anon_consts();
271
272 ctx.resolve_all()
273}
274
275#[derive(Clone, Copy, Debug, Eq, PartialEq)]
276pub enum ByRef {
277 Yes(Mutability),
278 No,
279}
280
281#[derive(Copy, Clone, Debug, Eq, PartialEq)]
287pub struct BindingMode(pub ByRef, pub Mutability);
288
289#[derive(Debug, PartialEq, Eq, Clone, Copy)]
290pub enum InferenceTyDiagnosticSource {
291 Body,
293 Signature,
295}
296
297#[derive(Debug, PartialEq, Eq, Clone, TypeVisitable, TypeFoldable)]
298pub enum InferenceDiagnostic {
299 NoSuchField {
300 #[type_visitable(ignore)]
301 field: ExprOrPatIdPacked,
302 #[type_visitable(ignore)]
303 private: Option<LocalFieldId>,
304 #[type_visitable(ignore)]
305 variant: VariantId,
306 },
307 MismatchedArrayPatLen {
308 #[type_visitable(ignore)]
309 pat: PatId,
310 #[type_visitable(ignore)]
311 expected: u64,
312 #[type_visitable(ignore)]
313 found: u64,
314 #[type_visitable(ignore)]
315 has_rest: bool,
316 },
317 ArrayPatternWithoutFixedLength {
318 #[type_visitable(ignore)]
319 pat: PatId,
320 },
321 ExpectedArrayOrSlicePat {
322 #[type_visitable(ignore)]
323 pat: PatId,
324 found: StoredTy,
325 },
326 InvalidRangePatType {
327 #[type_visitable(ignore)]
328 pat: PatId,
329 },
330 DuplicateField {
331 #[type_visitable(ignore)]
332 field: ExprOrPatIdPacked,
333 #[type_visitable(ignore)]
334 variant: VariantId,
335 },
336 PrivateField {
337 #[type_visitable(ignore)]
338 expr: ExprId,
339 #[type_visitable(ignore)]
340 field: FieldId,
341 },
342 PrivateAssocItem {
343 #[type_visitable(ignore)]
344 id: ExprOrPatIdPacked,
345 #[type_visitable(ignore)]
346 item: AssocItemId,
347 },
348 UnresolvedField {
349 #[type_visitable(ignore)]
350 expr: ExprId,
351 receiver: StoredTy,
352 #[type_visitable(ignore)]
353 name: Name,
354 #[type_visitable(ignore)]
355 method_with_same_name_exists: bool,
356 },
357 UnresolvedMethodCall {
358 #[type_visitable(ignore)]
359 expr: ExprId,
360 receiver: StoredTy,
361 #[type_visitable(ignore)]
362 name: Name,
363 field_with_same_name: Option<StoredTy>,
365 #[type_visitable(ignore)]
366 assoc_func_with_same_name: Option<FunctionId>,
367 },
368 UnresolvedAssocItem {
369 #[type_visitable(ignore)]
370 id: ExprOrPatIdPacked,
371 },
372 UnresolvedIdent {
373 #[type_visitable(ignore)]
374 id: ExprOrPatIdPacked,
375 },
376 BreakOutsideOfLoop {
378 #[type_visitable(ignore)]
379 expr: ExprId,
380 #[type_visitable(ignore)]
381 is_break: bool,
382 #[type_visitable(ignore)]
383 bad_value_break: bool,
384 },
385 NonExhaustiveRecordExpr {
386 #[type_visitable(ignore)]
387 expr: ExprId,
388 },
389 NonExhaustiveRecordPat {
390 #[type_visitable(ignore)]
391 pat: PatId,
392 #[type_visitable(ignore)]
393 variant: VariantId,
394 },
395 UnionPatMustHaveExactlyOneField {
396 #[type_visitable(ignore)]
397 pat: PatId,
398 },
399 UnionPatHasRest {
400 #[type_visitable(ignore)]
401 pat: PatId,
402 },
403 FunctionalRecordUpdateOnNonStruct {
404 #[type_visitable(ignore)]
405 base_expr: ExprId,
406 },
407 MismatchedArgCount {
408 #[type_visitable(ignore)]
409 call_expr: ExprId,
410 #[type_visitable(ignore)]
411 expected: usize,
412 #[type_visitable(ignore)]
413 found: usize,
414 #[type_visitable(ignore)]
418 is_fn_trait_call: bool,
419 },
420 MismatchedTupleStructPatArgCount {
421 #[type_visitable(ignore)]
422 pat: PatId,
423 #[type_visitable(ignore)]
424 expected: usize,
425 #[type_visitable(ignore)]
426 found: usize,
427 },
428 ExpectedFunction {
429 #[type_visitable(ignore)]
430 call_expr: ExprId,
431 found: StoredTy,
432 },
433 CannotBeDereferenced {
434 #[type_visitable(ignore)]
435 expr: ExprId,
436 found: StoredTy,
437 },
438 UnaryOperatorCannotBeApplied {
439 #[type_visitable(ignore)]
440 expr: ExprId,
441 #[type_visitable(ignore)]
442 op: UnaryOp,
443 found: StoredTy,
444 },
445 MutRefInImmRefPat {
446 #[type_visitable(ignore)]
447 pat: PatId,
448 },
449 CannotImplicitlyDerefTraitObject {
450 #[type_visitable(ignore)]
451 pat: PatId,
452 found: StoredTy,
453 },
454 CannotIndexInto {
455 #[type_visitable(ignore)]
456 expr: ExprId,
457 found: StoredTy,
458 },
459 TypedHole {
460 #[type_visitable(ignore)]
461 expr: ExprId,
462 expected: StoredTy,
463 },
464 CastToUnsized {
465 #[type_visitable(ignore)]
466 expr: ExprId,
467 cast_ty: StoredTy,
468 },
469 InvalidCast {
470 #[type_visitable(ignore)]
471 expr: ExprId,
472 #[type_visitable(ignore)]
473 error: CastError,
474 expr_ty: StoredTy,
475 cast_ty: StoredTy,
476 },
477 TyDiagnostic {
478 #[type_visitable(ignore)]
479 source: InferenceTyDiagnosticSource,
480 #[type_visitable(ignore)]
481 diag: TyLoweringDiagnostic,
482 },
483 PathDiagnostic {
484 #[type_visitable(ignore)]
485 node: ExprOrPatIdPacked,
486 #[type_visitable(ignore)]
487 diag: PathLoweringDiagnostic,
488 },
489 MethodCallIncorrectGenericsLen {
490 #[type_visitable(ignore)]
491 expr: ExprId,
492 #[type_visitable(ignore)]
493 provided_count: u32,
494 #[type_visitable(ignore)]
495 expected_count: u32,
496 #[type_visitable(ignore)]
497 kind: IncorrectGenericsLenKind,
498 #[type_visitable(ignore)]
499 def: GenericDefId,
500 },
501 MethodCallIllegalSizedBound {
502 #[type_visitable(ignore)]
503 call_expr: ExprId,
504 },
505 MethodCallIncorrectGenericsOrder {
506 #[type_visitable(ignore)]
507 expr: ExprId,
508 #[type_visitable(ignore)]
509 param_id: GenericParamId,
510 #[type_visitable(ignore)]
511 arg_idx: u32,
512 #[type_visitable(ignore)]
514 has_self_arg: bool,
515 },
516 InvalidLhsOfAssignment {
517 #[type_visitable(ignore)]
518 lhs: ExprId,
519 },
520 TypeMustBeKnown {
521 #[type_visitable(ignore)]
522 at_point: Span,
523 top_term: Option<StoredGenericArg>,
524 },
525 UnionExprMustHaveExactlyOneField {
526 #[type_visitable(ignore)]
527 expr: ExprId,
528 },
529 TypeMismatch {
530 #[type_visitable(ignore)]
531 node: ExprOrPatIdPacked,
532 expected: StoredTy,
533 found: StoredTy,
534 },
535 SolverDiagnostic(SolverDiagnostic),
536 ExplicitDropMethodUse {
537 #[type_visitable(ignore)]
538 kind: ExplicitDropMethodUseKind,
539 },
540 MutableRefBinding {
541 #[type_visitable(ignore)]
542 pat: PatId,
543 },
544 YieldOutsideCoroutine {
545 #[type_visitable(ignore)]
546 expr: ExprId,
547 },
548 ReturnOutsideFunction {
549 #[type_visitable(ignore)]
550 expr: ExprId,
551 #[type_visitable(ignore)]
552 kind: ReturnKind,
553 },
554 RecordMissingFields {
555 #[type_visitable(ignore)]
556 record: ExprOrPatId,
557 #[type_visitable(ignore)]
558 variant: VariantId,
559 #[type_visitable(ignore)]
560 missed_fields: Vec<LocalFieldId>,
561 },
562}
563
564#[derive(Debug, PartialEq, Eq, Clone, Copy)]
565pub enum ReturnKind {
566 ReturnExpr,
567 BecomeExpr,
568}
569
570#[derive(Debug, PartialEq, Eq, Clone)]
571pub enum ExplicitDropMethodUseKind {
572 MethodCall(ExprId),
573 Path(ExprOrPatIdPacked),
574}
575
576#[derive(Clone, Debug, PartialEq, Eq, Hash)]
617pub struct Adjustment {
618 pub kind: Adjust,
619 pub target: StoredTy,
620}
621
622impl Adjustment {
623 pub fn borrow<'db>(
624 interner: DbInterner<'db>,
625 m: Mutability,
626 ty: Ty<'db>,
627 lt: Region<'db>,
628 ) -> Self {
629 let ty = Ty::new_ref(interner, lt, ty, m);
630 Adjustment {
631 kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::new(m, AllowTwoPhase::No))),
632 target: ty.store(),
633 }
634 }
635}
636
637#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
651pub enum AllowTwoPhase {
652 Yes,
654 No,
655}
656
657#[derive(Clone, Debug, PartialEq, Eq, Hash)]
658pub enum Adjust {
659 NeverToAny,
661 Deref(Option<OverloadedDeref>),
663 Borrow(AutoBorrow),
665 Pointer(PointerCast),
666}
667
668#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
673pub struct OverloadedDeref(pub Mutability);
674
675#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
676pub enum AutoBorrowMutability {
677 Mut { allow_two_phase_borrow: AllowTwoPhase },
678 Not,
679}
680
681impl AutoBorrowMutability {
682 pub fn new(mutbl: Mutability, allow_two_phase_borrow: AllowTwoPhase) -> Self {
686 match mutbl {
687 Mutability::Not => Self::Not,
688 Mutability::Mut => Self::Mut { allow_two_phase_borrow },
689 }
690 }
691}
692
693impl From<AutoBorrowMutability> for Mutability {
694 fn from(m: AutoBorrowMutability) -> Self {
695 match m {
696 AutoBorrowMutability::Mut { .. } => Mutability::Mut,
697 AutoBorrowMutability::Not => Mutability::Not,
698 }
699 }
700}
701
702#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
703pub enum AutoBorrow {
704 Ref(AutoBorrowMutability),
706 RawPtr(Mutability),
708}
709
710#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
711pub enum PointerCast {
712 ReifyFnPointer,
714
715 UnsafeFnPointer,
717
718 ClosureFnPointer(Safety),
721
722 MutToConstPointer,
724
725 #[allow(dead_code)]
726 ArrayToPointer,
728
729 Unsize,
740}
741
742#[derive(Debug, Clone, PartialEq, Eq)]
745pub struct PatAdjustment {
746 pub kind: PatAdjust,
747 pub source: StoredTy,
750}
751
752#[derive(Clone, Copy, PartialEq, Eq, Debug)]
754pub enum PatAdjust {
755 BuiltinDeref,
758 OverloadedDeref,
761}
762
763#[derive(Clone, PartialEq, Eq, Debug, SalsaValue)]
769pub struct InferenceResult<'db> {
770 method_resolutions: FxHashMap<ExprId, (FunctionId, StoredGenericArgs)>,
772 field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
774 variant_resolutions: FxHashMap<ExprOrPatIdPacked, VariantId>,
776 assoc_resolutions: FxHashMap<ExprOrPatIdPacked, (CandidateId, StoredGenericArgs)>,
778 tuple_field_access_types: ThinVec<StoredTys>,
782
783 pub(crate) type_of_expr: ArenaMap<ExprId, StoredTy>,
784 pub(crate) type_of_pat: ArenaMap<PatId, StoredTy>,
789 pub(crate) type_of_binding: ArenaMap<BindingId, StoredTy>,
790 pub(crate) type_of_type_placeholder: FxHashMap<TypeRefId, StoredTy>,
791 pub(crate) type_of_opaque: FxHashMap<InternedOpaqueTyId<'db>, StoredTy>,
792
793 pub(crate) has_errors: bool,
798 diagnostics: ThinVec<InferenceDiagnostic>,
800 nodes_with_type_mismatches: Option<Box<FxHashSet<ExprOrPatIdPacked>>>,
802
803 error_ty: StoredTy,
806
807 pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
808 pub(crate) pat_adjustments: FxHashMap<PatId, Vec<PatAdjustment>>,
810 pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,
824
825 skipped_ref_pats: FxHashSet<PatId>,
828
829 pub(crate) coercion_casts: FxHashSet<ExprId>,
830
831 pub closures_data: FxHashMap<ExprId, ClosureData>,
832
833 defined_anon_consts: ThinVec<AnonConstId<'db>>,
834}
835
836#[derive(Clone, PartialEq, Eq, Debug)]
837pub struct ClosureData {
838 pub min_captures: RootVariableMinCaptureList,
841
842 pub fake_reads: Box<[(Place, FakeReadCause, SmallVec<[CaptureSourceStack; 2]>)]>,
865
866 pub liberated_sig: StoredFnSig,
901}
902
903pub(crate) type RootVariableMinCaptureList = FxIndexMap<BindingId, MinCaptureList>;
910
911pub(crate) type MinCaptureList = Vec<CapturedPlace>;
913
914#[derive(Eq, PartialEq, Clone, Debug, Hash)]
916pub struct CapturedPlace {
917 pub place: Place,
919
920 pub info: CaptureInfo,
922
923 pub mutability: Mutability,
925}
926
927impl CapturedPlace {
928 pub fn is_by_ref(&self) -> bool {
929 match self.info.capture_kind {
930 UpvarCapture::ByValue | UpvarCapture::ByUse => false,
931 UpvarCapture::ByRef(..) => true,
932 }
933 }
934
935 pub fn captured_local(&self) -> BindingId {
936 match self.place.base {
937 PlaceBase::Upvar { var_id: local, .. } | PlaceBase::Local(local) => local,
938 PlaceBase::Rvalue | PlaceBase::StaticItem => {
939 unreachable!("only locals can be captured")
940 }
941 }
942 }
943
944 pub fn captured_ty<'db>(&self, db: &'db dyn HirDatabase) -> Ty<'db> {
947 let place_ty = self.place.ty();
948 let make_ref = |mutbl| {
949 let interner = DbInterner::new_no_crate(db);
950 let region = Region::new_erased(interner);
951 Ty::new_ref(interner, region, place_ty, mutbl)
952 };
953 match self.info.capture_kind {
954 UpvarCapture::ByUse | UpvarCapture::ByValue => place_ty,
955 UpvarCapture::ByRef(kind) => make_ref(kind.to_mutbl_lossy()),
956 }
957 }
958}
959
960#[derive(Clone)]
961pub struct CaptureSourceStack(CaptureSourceStackRepr);
962
963#[derive(Clone)]
964enum CaptureSourceStackRepr {
965 One(ExprOrPatIdPacked),
966 Two([ExprOrPatIdPacked; 2]),
967 Many(ThinVec<ExprOrPatIdPacked>),
968}
969
970impl PartialEq for CaptureSourceStack {
971 fn eq(&self, other: &Self) -> bool {
972 **self == **other
973 }
974}
975
976impl Eq for CaptureSourceStack {}
977
978impl std::hash::Hash for CaptureSourceStack {
979 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
980 (**self).hash(state);
981 }
982}
983
984#[cfg(target_pointer_width = "64")]
985const _: () = assert!(size_of::<CaptureSourceStack>() == 16);
986
987impl Deref for CaptureSourceStack {
988 type Target = [ExprOrPatIdPacked];
989
990 #[inline]
991 fn deref(&self) -> &Self::Target {
992 match &self.0 {
993 CaptureSourceStackRepr::One(it) => std::slice::from_ref(it),
994 CaptureSourceStackRepr::Two(it) => it,
995 CaptureSourceStackRepr::Many(it) => it,
996 }
997 }
998}
999
1000impl fmt::Debug for CaptureSourceStack {
1001 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1002 f.debug_tuple("CaptureSourceStack").field(&&**self).finish()
1003 }
1004}
1005
1006impl CaptureSourceStack {
1007 #[inline]
1008 pub fn len(&self) -> usize {
1009 match &self.0 {
1010 CaptureSourceStackRepr::One(_) => 1,
1011 CaptureSourceStackRepr::Two(_) => 2,
1012 CaptureSourceStackRepr::Many(it) => it.len(),
1013 }
1014 }
1015
1016 #[inline]
1017 pub(crate) fn from_single(id: ExprOrPatIdPacked) -> Self {
1018 Self(CaptureSourceStackRepr::One(id))
1019 }
1020
1021 #[inline]
1022 pub fn final_source(&self) -> ExprOrPatIdPacked {
1023 *self.last().expect("should always have a final source")
1024 }
1025
1026 pub fn push(&mut self, new_id: ExprOrPatIdPacked) {
1027 match &mut self.0 {
1028 CaptureSourceStackRepr::One(old_id) => {
1029 self.0 = CaptureSourceStackRepr::Two([*old_id, new_id])
1030 }
1031 CaptureSourceStackRepr::Two([old_id1, old_id2]) => {
1032 self.0 = CaptureSourceStackRepr::Many(ThinVec::from([*old_id1, *old_id2, new_id]));
1033 }
1034 CaptureSourceStackRepr::Many(old_ids) => old_ids.push(new_id),
1035 }
1036 }
1037
1038 pub fn truncate(&mut self, new_len: usize) {
1039 debug_assert!(new_len > 0);
1040 match &mut self.0 {
1041 CaptureSourceStackRepr::One(_) => {}
1042 CaptureSourceStackRepr::Two([first, _]) => {
1043 if new_len == 1 {
1044 self.0 = CaptureSourceStackRepr::One(*first)
1045 }
1046 }
1047 CaptureSourceStackRepr::Many(ids) => ids.truncate(new_len),
1048 }
1049 }
1050
1051 pub fn shrink_to_fit(&mut self) {
1052 match &mut self.0 {
1053 CaptureSourceStackRepr::One(_) | CaptureSourceStackRepr::Two(_) => {}
1054 CaptureSourceStackRepr::Many(ids) => match **ids {
1055 [one] => self.0 = CaptureSourceStackRepr::One(one),
1056 [first, second] => self.0 = CaptureSourceStackRepr::Two([first, second]),
1057 _ => ids.shrink_to_fit(),
1058 },
1059 }
1060 }
1061}
1062
1063#[derive(Eq, PartialEq, Clone, Debug, Hash)]
1067pub struct CaptureInfo {
1068 pub sources: SmallVec<[CaptureSourceStack; 2]>,
1069
1070 pub capture_kind: UpvarCapture,
1072}
1073
1074#[derive(Eq, PartialEq, Clone, Debug, Copy, Hash)]
1077pub enum UpvarCapture {
1078 ByValue,
1082
1083 ByUse,
1085
1086 ByRef(BorrowKind),
1088}
1089
1090#[salsa::tracked]
1091impl<'db> InferenceResult<'db> {
1092 #[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
1093 fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult<'_> {
1094 infer_query(db, def)
1095 }
1096
1097 #[salsa::tracked(returns(ref), cycle_result = infer_anon_const_cycle_result)]
1103 fn for_anon_const(db: &'db dyn HirDatabase, def: AnonConstId<'db>) -> InferenceResult<'db> {
1104 infer_anon_const_query(db, def)
1105 }
1106}
1107
1108impl<'db> InferenceResult<'db> {
1109 #[inline]
1110 pub fn of(
1111 db: &'db dyn HirDatabase,
1112 def: impl Into<InferBodyId<'db>>,
1113 ) -> &'db InferenceResult<'db> {
1114 match def.into() {
1115 InferBodyId::DefWithBodyId(it) => InferenceResult::for_body(db, it),
1116 InferBodyId::AnonConstId(it) => InferenceResult::for_anon_const(db, it),
1117 }
1118 }
1119}
1120
1121impl<'db> InferenceResult<'db> {
1122 fn new(error_ty: Ty<'_>) -> Self {
1123 Self {
1124 method_resolutions: Default::default(),
1125 field_resolutions: Default::default(),
1126 variant_resolutions: Default::default(),
1127 assoc_resolutions: Default::default(),
1128 tuple_field_access_types: Default::default(),
1129 diagnostics: Default::default(),
1130 nodes_with_type_mismatches: Default::default(),
1131 type_of_expr: Default::default(),
1132 type_of_pat: Default::default(),
1133 type_of_binding: Default::default(),
1134 type_of_type_placeholder: Default::default(),
1135 type_of_opaque: Default::default(),
1136 skipped_ref_pats: Default::default(),
1137 has_errors: Default::default(),
1138 error_ty: error_ty.store(),
1139 pat_adjustments: Default::default(),
1140 binding_modes: Default::default(),
1141 expr_adjustments: Default::default(),
1142 coercion_casts: Default::default(),
1143 closures_data: Default::default(),
1144 defined_anon_consts: Default::default(),
1145 }
1146 }
1147
1148 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, GenericArgs<'db>)> {
1149 self.method_resolutions.get(&expr).map(|(func, args)| (*func, args.as_ref()))
1150 }
1151 pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
1152 self.field_resolutions.get(&expr).copied()
1153 }
1154 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
1155 self.variant_resolutions.get(&id.into()).copied()
1156 }
1157 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
1158 self.variant_resolutions.get(&id.into()).copied()
1159 }
1160 pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
1161 match id {
1162 ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
1163 ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
1164 }
1165 }
1166 pub fn assoc_resolutions_for_expr<'a>(
1167 &self,
1168 id: ExprId,
1169 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1170 self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1171 }
1172 pub fn assoc_resolutions_for_pat<'a>(
1173 &self,
1174 id: PatId,
1175 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1176 self.assoc_resolutions.get(&id.into()).map(|(assoc, args)| (*assoc, args.as_ref()))
1177 }
1178 pub fn assoc_resolutions_for_expr_or_pat<'a>(
1179 &self,
1180 id: ExprOrPatId,
1181 ) -> Option<(CandidateId, GenericArgs<'a>)> {
1182 match id {
1183 ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
1184 ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
1185 }
1186 }
1187 pub fn expr_or_pat_has_type_mismatch(&self, node: ExprOrPatIdPacked) -> bool {
1188 self.nodes_with_type_mismatches.as_ref().is_some_and(|it| it.contains(&node))
1189 }
1190 pub fn expr_has_type_mismatch(&self, expr: ExprId) -> bool {
1191 self.expr_or_pat_has_type_mismatch(expr.into())
1192 }
1193 pub fn pat_has_type_mismatch(&self, pat: PatId) -> bool {
1194 self.expr_or_pat_has_type_mismatch(pat.into())
1195 }
1196 pub fn exprs_have_type_mismatches(&self) -> bool {
1197 self.nodes_with_type_mismatches
1198 .as_ref()
1199 .is_some_and(|it| it.iter().any(|node| node.is_expr()))
1200 }
1201 pub fn has_type_mismatches(&self) -> bool {
1202 self.nodes_with_type_mismatches.is_some()
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(self.error_ty.as_ref(), |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(self.error_ty.as_ref(), |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(self.error_ty.as_ref())
1301 }
1302
1303 pub fn binding_ty<'a>(&self, id: BindingId) -> Ty<'a> {
1304 self.type_of_binding.get(id).map_or(self.error_ty.as_ref(), |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(db);
1443 InferenceContext {
1444 result: InferenceResult::new(types.types.error),
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 error_ty: _,
1492 expr_adjustments,
1493 pat_adjustments,
1494 binding_modes,
1495 skipped_ref_pats,
1496 coercion_casts,
1497 closures_data,
1498 nodes_with_type_mismatches,
1499 defined_anon_consts: _,
1500 } = &mut self.result;
1501 merge_hash_maps(method_resolutions, &other.method_resolutions);
1502 merge_hash_maps(variant_resolutions, &other.variant_resolutions);
1503 merge_hash_maps(assoc_resolutions, &other.assoc_resolutions);
1504 field_resolutions.extend(other.field_resolutions.iter().map(
1505 |(&field_expr, &field_resolution)| {
1506 let mut field_resolution = field_resolution;
1507 if let Either::Right(tuple_field) = &mut field_resolution {
1508 let tys = other.tuple_field_access_type(tuple_field.tuple);
1509 tuple_field.tuple =
1510 TupleId(self.tuple_field_accesses_rev.insert_full(tys).0 as u32);
1511 };
1512 (field_expr, field_resolution)
1513 },
1514 ));
1515 merge_arena_maps(type_of_expr, &other.type_of_expr);
1516 merge_arena_maps(type_of_pat, &other.type_of_pat);
1517 merge_arena_maps(type_of_binding, &other.type_of_binding);
1518 merge_hash_maps(type_of_type_placeholder, &other.type_of_type_placeholder);
1519 merge_hash_maps(type_of_opaque, &other.type_of_opaque);
1520 merge_hash_maps(expr_adjustments, &other.expr_adjustments);
1521 merge_hash_maps(pat_adjustments, &other.pat_adjustments);
1522 merge_arena_maps(binding_modes, &other.binding_modes);
1523 merge_hash_set(skipped_ref_pats, &other.skipped_ref_pats);
1524 merge_hash_set(coercion_casts, &other.coercion_casts);
1525 merge_hash_maps(closures_data, &other.closures_data);
1526 if let Some(other_nodes_with_type_mismatches) = &other.nodes_with_type_mismatches {
1527 merge_hash_set(
1528 nodes_with_type_mismatches.get_or_insert_default(),
1529 other_nodes_with_type_mismatches,
1530 );
1531 }
1532 self.defined_anon_consts.borrow_mut().extend(other.defined_anon_consts.iter().copied());
1533
1534 fn merge_hash_set<T: Hash + Eq + Clone>(dest: &mut FxHashSet<T>, source: &FxHashSet<T>) {
1535 dest.extend(source.iter().cloned());
1536 }
1537
1538 #[cfg_attr(debug_assertions, track_caller)]
1539 fn merge_hash_maps<K: Hash + Eq + Clone, V: Clone + PartialEq>(
1540 dest: &mut FxHashMap<K, V>,
1541 source: &FxHashMap<K, V>,
1542 ) {
1543 if cfg!(debug_assertions) {
1544 for (key, src) in source {
1545 assert!(dest.get(key).is_none_or(|dst| dst == src));
1546 }
1547 }
1548
1549 dest.extend(source.iter().map(|(k, v)| (k.clone(), v.clone())));
1550 }
1551
1552 #[cfg_attr(debug_assertions, track_caller)]
1553 fn merge_arena_maps<K, V: Clone + PartialEq>(
1554 dest: &mut ArenaMap<la_arena::Idx<K>, V>,
1555 source: &ArenaMap<la_arena::Idx<K>, V>,
1556 ) {
1557 if cfg!(debug_assertions) {
1558 for (key, src) in source.iter() {
1559 assert!(dest.get(key).is_none_or(|dst| dst == src));
1560 }
1561 }
1562
1563 dest.extend(source.iter().map(|(k, v)| (k, v.clone())));
1564 }
1565 }
1566
1567 #[inline]
1568 fn krate(&self) -> Crate {
1569 self.resolver.krate()
1570 }
1571
1572 fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {
1573 let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {
1574 let target_features = match self.store_owner {
1575 ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {
1576 TargetFeatures::from_fn(self.db, id)
1577 }
1578 _ => TargetFeatures::default(),
1579 };
1580 let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {
1581 Ok(target) => crate::utils::target_feature_is_safe_in_target(target),
1582 Err(_) => TargetFeatureIsSafeInTarget::No,
1583 };
1584 (target_features, target_feature_is_safe)
1585 });
1586 (target_features, *target_feature_is_safe)
1587 }
1588
1589 fn data_layout(&self) -> &'db TargetDataLayout {
1590 self.data_layout.get_or_init(|| self.db.target_data_layout_or_default(self.krate()))
1591 }
1592
1593 fn deref_pat_borrow_mode(&self, pointer_ty: Ty<'_>, inner: PatId) -> DerefPatBorrowMode {
1600 if pointer_ty.is_box() {
1601 DerefPatBorrowMode::Box
1602 } else {
1603 let mutability =
1604 if self.pat_has_ref_mut_binding(inner) { Mutability::Mut } else { Mutability::Not };
1605 DerefPatBorrowMode::Borrow(mutability)
1606 }
1607 }
1608
1609 #[inline]
1610 fn set_tainted_by_errors(&mut self) {
1611 self.result.has_errors = true;
1612 }
1613
1614 fn merge_anon_consts(&mut self) {
1617 let mut defined_anon_consts = std::mem::take(&mut *self.defined_anon_consts.borrow_mut());
1618 defined_anon_consts.retain(|&konst| {
1619 if konst.loc(self.db).owner != self.store_owner {
1620 return false;
1622 }
1623
1624 let const_infer = InferenceResult::of(self.db, konst);
1625 self.merge(const_infer);
1626 true
1627 });
1628 self.defined_anon_consts.borrow_mut().append(&mut defined_anon_consts);
1630 }
1631
1632 fn resolve_all(self) -> InferenceResult<'db> {
1637 let InferenceContext {
1638 table,
1639 mut result,
1640 tuple_field_accesses_rev,
1641 diagnostics,
1642 types,
1643 vars_emitted_type_must_be_known_for,
1644 ..
1645 } = self;
1646 let diagnostics = diagnostics.finish();
1647 let InferenceResult {
1650 method_resolutions,
1651 field_resolutions: _,
1652 variant_resolutions: _,
1653 assoc_resolutions,
1654 type_of_expr,
1655 type_of_pat,
1656 type_of_binding,
1657 type_of_type_placeholder,
1658 type_of_opaque,
1659 skipped_ref_pats,
1660 closures_data,
1661 has_errors,
1662 error_ty: _,
1663 pat_adjustments,
1664 binding_modes: _,
1665 expr_adjustments,
1666 tuple_field_access_types,
1667 coercion_casts: _,
1668 diagnostics: result_diagnostics,
1669 nodes_with_type_mismatches,
1670 defined_anon_consts: result_defined_anon_consts,
1671 } = &mut result;
1672
1673 *result_defined_anon_consts = self.defined_anon_consts.into_inner();
1674 result_defined_anon_consts.shrink_to_fit();
1675
1676 let mut resolver =
1677 WriteBackCtxt::new(table, diagnostics, vars_emitted_type_must_be_known_for);
1678
1679 skipped_ref_pats.shrink_to_fit();
1680 for ty in type_of_expr.values_mut() {
1681 resolver.resolve_completely(ty);
1682 }
1683 type_of_expr.shrink_to_fit();
1684 for ty in type_of_pat.values_mut() {
1685 resolver.resolve_completely(ty);
1686 }
1687 type_of_pat.shrink_to_fit();
1688 for ty in type_of_binding.values_mut() {
1689 resolver.resolve_completely(ty);
1690 }
1691 type_of_binding.shrink_to_fit();
1692 for ty in type_of_type_placeholder.values_mut() {
1693 resolver.resolve_completely(ty);
1694 }
1695 type_of_type_placeholder.shrink_to_fit();
1696 type_of_opaque.shrink_to_fit();
1697
1698 if let Some(nodes_with_type_mismatches) = nodes_with_type_mismatches {
1699 *has_errors = true;
1700 nodes_with_type_mismatches.shrink_to_fit();
1701 }
1702 for (_, subst) in method_resolutions.values_mut() {
1703 resolver.resolve_completely(subst);
1704 }
1705 method_resolutions.shrink_to_fit();
1706 for (_, subst) in assoc_resolutions.values_mut() {
1707 resolver.resolve_completely(subst);
1708 }
1709 assoc_resolutions.shrink_to_fit();
1710 for adjustment in expr_adjustments.values_mut().flatten() {
1711 resolver.resolve_completely(&mut adjustment.target);
1712 }
1713 expr_adjustments.shrink_to_fit();
1714 for adjustments in pat_adjustments.values_mut() {
1715 for adjustment in &mut *adjustments {
1716 resolver.resolve_completely(&mut adjustment.source);
1717 }
1718 adjustments.shrink_to_fit();
1719 }
1720 pat_adjustments.shrink_to_fit();
1721 for closure_data in closures_data.values_mut() {
1722 let ClosureData { min_captures, fake_reads, liberated_sig } = closure_data;
1723 let dummy_place = || Place {
1724 base_ty: types.types.error.store(),
1725 base: closure::analysis::expr_use_visitor::PlaceBase::Rvalue,
1726 projections: Vec::new(),
1727 };
1728
1729 for (place, _, sources) in fake_reads {
1730 resolver.resolve_completely_with_default(place, dummy_place());
1731 place.projections.shrink_to_fit();
1732 for source in &mut *sources {
1733 source.shrink_to_fit();
1734 }
1735 sources.shrink_to_fit();
1736 }
1737
1738 for min_capture in min_captures.values_mut() {
1739 for captured in &mut *min_capture {
1740 let CapturedPlace { place, info, mutability: _ } = captured;
1741 resolver.resolve_completely_with_default(place, dummy_place());
1742 let CaptureInfo { sources, capture_kind: _ } = info;
1743 for source in &mut *sources {
1744 source.shrink_to_fit();
1745 }
1746 sources.shrink_to_fit();
1747 }
1748 min_capture.shrink_to_fit();
1749 }
1750 min_captures.shrink_to_fit();
1751
1752 resolver.resolve_completely(liberated_sig);
1753 }
1754 closures_data.shrink_to_fit();
1755 *tuple_field_access_types = tuple_field_accesses_rev
1756 .into_iter()
1757 .map(|mut subst| {
1758 resolver.resolve_completely(&mut subst);
1759 subst.store()
1760 })
1761 .collect();
1762 tuple_field_access_types.shrink_to_fit();
1763
1764 let (diagnostics, resolver_has_errors) = resolver.resolve_diagnostics();
1765 *result_diagnostics = diagnostics;
1766 *has_errors |= resolver_has_errors;
1767
1768 result
1769 }
1770
1771 fn collect_const(&mut self, id: ConstId, data: &'db ConstSignature) {
1772 let return_ty = self.make_ty(
1773 data.type_ref,
1774 &data.store,
1775 InferenceTyDiagnosticSource::Signature,
1776 ExpressionStoreOwnerId::Signature(id.into()),
1777 LifetimeElisionKind::for_const(self.interner(), id.loc(self.db).container),
1778 );
1779
1780 self.return_ty = return_ty;
1781 }
1782
1783 fn collect_static(&mut self, id: StaticId, data: &'db StaticSignature) {
1784 let return_ty = self.make_ty(
1785 data.type_ref,
1786 &data.store,
1787 InferenceTyDiagnosticSource::Signature,
1788 ExpressionStoreOwnerId::Signature(id.into()),
1789 LifetimeElisionKind::Elided(self.types.regions.statik),
1790 );
1791
1792 self.return_ty = return_ty;
1793 }
1794
1795 fn collect_fn(
1796 &mut self,
1797 func: FunctionId,
1798 self_param: Option<BindingId>,
1799 params: &[Param<PatId>],
1800 ) {
1801 let data = FunctionSignature::of(self.db, func);
1802 let mut param_tys = self.with_ty_lowering(
1803 &data.store,
1804 InferenceTyDiagnosticSource::Signature,
1805 ExpressionStoreOwnerId::Signature(func.into()),
1806 LifetimeElisionKind::for_fn_params(data),
1807 |ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),
1808 );
1809
1810 if data.is_varargs() {
1813 let va_list_ty = match self.resolve_va_list() {
1814 Some(va_list) => Ty::new_adt(
1815 self.interner(),
1816 va_list,
1817 GenericArgs::for_item_with_defaults(
1818 self.interner(),
1819 va_list.into(),
1820 |_, id, _| self.table.var_for_def(id, Span::Dummy),
1821 ),
1822 ),
1823 None => self.err_ty(),
1824 };
1825
1826 param_tys.push(va_list_ty);
1827 }
1828 let mut param_tys = param_tys.into_iter();
1829 if let Some(self_param) = self_param
1830 && let Some(ty) = param_tys.next()
1831 {
1832 let ty = self.process_user_written_ty(ty);
1833 self.write_binding_ty(self_param, ty);
1834 }
1835 for pat in params {
1836 let ty = param_tys.next().unwrap_or_else(|| self.table.next_ty_var(Span::Dummy));
1837 let ty = self.process_user_written_ty(ty);
1838
1839 self.infer_top_pat(pat.formal, ty, PatOrigin::Param);
1840 }
1841 self.return_ty = match data.ret_type {
1842 Some(return_ty) => {
1843 let return_ty = self.with_ty_lowering(
1844 &data.store,
1845 InferenceTyDiagnosticSource::Signature,
1846 ExpressionStoreOwnerId::Signature(func.into()),
1847 LifetimeElisionKind::for_fn_ret(self.interner()),
1848 |ctx| {
1849 ctx.impl_trait_mode(ImplTraitLoweringMode::Opaque);
1850 ctx.lower_ty(return_ty)
1851 },
1852 );
1853 self.process_user_written_ty(return_ty)
1854 }
1855 None => self.types.types.unit,
1856 };
1857
1858 self.return_coercion = Some(CoerceMany::new(self.return_ty));
1859 }
1860
1861 #[inline]
1862 pub(crate) fn interner(&self) -> DbInterner<'db> {
1863 self.table.interner()
1864 }
1865
1866 #[inline]
1867 pub(crate) fn infcx(&self) -> &InferCtxt<'db> {
1868 &self.table.infer_ctxt
1869 }
1870
1871 fn insert_type_vars_shallow(&mut self, ty: Ty<'db>) -> Ty<'db> {
1886 if ty.is_ty_error() {
1887 let var = self.table.next_ty_var(Span::Dummy);
1888
1889 self.vars_emitted_type_must_be_known_for.insert(var.into());
1891
1892 var
1893 } else {
1894 ty
1895 }
1896 }
1897
1898 fn infer_body(&mut self, body_expr: ExprId) {
1899 match self.return_coercion {
1900 Some(_) => self.infer_return(body_expr),
1901 None => {
1902 _ = self.infer_expr_coerce(
1903 body_expr,
1904 &Expectation::has_type(self.return_ty),
1905 ExprIsRead::Yes,
1906 )
1907 }
1908 }
1909 }
1910
1911 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty<'db>) {
1912 self.result.type_of_expr.insert(expr, ty.store());
1913 }
1914
1915 pub(crate) fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1916 if adjustments.is_empty() {
1917 return;
1918 }
1919 match self.result.expr_adjustments.entry(expr) {
1920 std::collections::hash_map::Entry::Occupied(mut entry) => {
1921 match (&mut entry.get_mut()[..], &adjustments[..]) {
1922 (
1923 [Adjustment { kind: Adjust::NeverToAny, target }],
1924 [.., Adjustment { target: new_target, .. }],
1925 ) => {
1926 *target = new_target.clone();
1929 }
1930 _ => {
1931 *entry.get_mut() = adjustments;
1932 }
1933 }
1934 }
1935 std::collections::hash_map::Entry::Vacant(entry) => {
1936 entry.insert(adjustments);
1937 }
1938 }
1939 }
1940
1941 pub(crate) fn write_method_resolution(
1942 &mut self,
1943 expr: ExprId,
1944 func: FunctionId,
1945 subst: GenericArgs<'db>,
1946 ) {
1947 self.result.method_resolutions.insert(expr, (func, subst.store()));
1948 }
1949
1950 fn write_variant_resolution(&mut self, id: ExprOrPatIdPacked, variant: VariantId) {
1951 self.result.variant_resolutions.insert(id, variant);
1952 }
1953
1954 fn write_assoc_resolution(
1955 &mut self,
1956 id: ExprOrPatIdPacked,
1957 item: CandidateId,
1958 subs: GenericArgs<'db>,
1959 ) {
1960 self.result.assoc_resolutions.insert(id, (item, subs.store()));
1961 }
1962
1963 fn write_pat_ty(&mut self, pat: PatId, ty: Ty<'db>) {
1964 self.result.type_of_pat.insert(pat, ty.store());
1965 }
1966
1967 fn write_binding_ty(&mut self, id: BindingId, ty: Ty<'db>) {
1968 self.result.type_of_binding.insert(id, ty.store());
1969 }
1970
1971 pub(crate) fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1972 self.diagnostics.push(diagnostic);
1973 }
1974
1975 fn record_deferred_call_resolution(
1976 &mut self,
1977 closure_def_id: ExprId,
1978 r: DeferredCallResolution<'db>,
1979 ) {
1980 self.deferred_call_resolutions.entry(closure_def_id).or_default().push(r);
1981 }
1982
1983 fn remove_deferred_call_resolutions(
1984 &mut self,
1985 closure_def_id: ExprId,
1986 ) -> Vec<DeferredCallResolution<'db>> {
1987 self.deferred_call_resolutions.remove(&closure_def_id).unwrap_or_default()
1988 }
1989
1990 fn with_ty_lowering<R>(
1991 &mut self,
1992 store: &'db ExpressionStore,
1993 types_source: InferenceTyDiagnosticSource,
1994 store_owner: ExpressionStoreOwnerId,
1995 lifetime_elision: LifetimeElisionKind<'db>,
1996 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
1997 ) -> R {
1998 let infer_vars = match types_source {
1999 InferenceTyDiagnosticSource::Body => Some(&mut InferenceTyLoweringVarsCtx {
2000 table: &mut self.table,
2001 type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
2002 } as _),
2003 InferenceTyDiagnosticSource::Signature => None,
2004 };
2005 let mut ctx = TyLoweringContext::new(
2006 self.db,
2007 &self.resolver,
2008 store,
2009 &self.diagnostics,
2010 types_source,
2011 store_owner,
2012 self.generic_def,
2013 &self.generics,
2014 lifetime_elision,
2015 self.allow_using_generic_params,
2016 infer_vars,
2017 &self.defined_anon_consts,
2018 LifetimeLoweringMode::LateParam,
2019 );
2020 f(&mut ctx)
2021 }
2022
2023 fn with_body_ty_lowering<R>(
2024 &mut self,
2025 f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
2026 ) -> R {
2027 self.with_ty_lowering(
2028 self.store,
2029 InferenceTyDiagnosticSource::Body,
2030 self.store_owner,
2031 LifetimeElisionKind::Infer,
2032 f,
2033 )
2034 }
2035
2036 fn make_ty(
2037 &mut self,
2038 type_ref: TypeRefId,
2039 store: &'db ExpressionStore,
2040 type_source: InferenceTyDiagnosticSource,
2041 store_owner: ExpressionStoreOwnerId,
2042 lifetime_elision: LifetimeElisionKind<'db>,
2043 ) -> Ty<'db> {
2044 let ty = self.with_ty_lowering(store, type_source, store_owner, lifetime_elision, |ctx| {
2045 ctx.lower_ty(type_ref)
2046 });
2047 self.process_user_written_ty(ty)
2048 }
2049
2050 pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
2051 self.make_ty(
2052 type_ref,
2053 self.store,
2054 InferenceTyDiagnosticSource::Body,
2055 self.store_owner,
2056 LifetimeElisionKind::Infer,
2057 )
2058 }
2059
2060 fn generics(&self) -> &Generics<'db> {
2061 self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
2062 }
2063
2064 fn identity_args(&self) -> GenericArgs<'db> {
2065 *self.identity_args.get_or_init(|| {
2066 GenericArgs::identity_for_item(self.interner(), self.generic_def.into())
2067 })
2068 }
2069
2070 pub(crate) fn create_body_anon_const(
2071 &mut self,
2072 expr: ExprId,
2073 expected_ty: Ty<'db>,
2074 allow_using_generic_params: bool,
2075 ) -> Const<'db> {
2076 never!(expected_ty.has_infer(), "cannot have infer vars in an anon const's ty");
2077 let konst = create_anon_const(
2078 self.interner(),
2079 self.store_owner,
2080 self.store,
2081 expr,
2082 &self.resolver,
2083 expected_ty,
2084 &|| self.generics(),
2085 Some(&mut |span| self.table.next_const_var(span)),
2086 self.lowering_mode,
2087 (!(allow_using_generic_params && self.allow_using_generic_params)).then_some(0),
2088 );
2089
2090 if let Ok(konst) = konst
2091 && let ConstKind::Unevaluated(konst) = konst.kind()
2092 && let GeneralConstId::AnonConstId(konst) = konst.def.0
2093 {
2094 self.defined_anon_consts.borrow_mut().push(konst);
2095 } else {
2096 self.write_expr_ty(expr, expected_ty);
2097 }
2098
2099 konst.unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2101 }
2102
2103 pub(crate) fn make_path_as_body_const(&mut self, path: &Path) -> Const<'db> {
2104 let forbid_params_after = if self.allow_using_generic_params { None } else { Some(0) };
2105 path_to_const(self.db, &self.resolver, &|| self.generics(), forbid_params_after, path)
2107 .unwrap_or_else(|_| self.table.next_const_var(Span::Dummy))
2108 }
2109
2110 fn err_ty(&self) -> Ty<'db> {
2111 self.types.types.error
2112 }
2113
2114 pub(crate) fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
2115 let lt = self.with_ty_lowering(
2116 self.store,
2117 InferenceTyDiagnosticSource::Body,
2118 self.store_owner,
2119 LifetimeElisionKind::Infer,
2120 |ctx| ctx.lower_lifetime(lifetime_ref),
2121 );
2122 self.insert_type_vars(lt)
2123 }
2124
2125 fn insert_type_vars<T>(&mut self, ty: T) -> T
2126 where
2127 T: TypeFoldable<DbInterner<'db>>,
2128 {
2129 self.table.insert_type_vars(ty)
2130 }
2131
2132 fn struct_tail_without_normalization(&mut self, ty: Ty<'db>) -> Ty<'db> {
2136 self.struct_tail_with_normalize(ty, identity)
2137 }
2138
2139 fn struct_tail_with_normalize(
2147 &mut self,
2148 mut ty: Ty<'db>,
2149 mut normalize: impl FnMut(Ty<'db>) -> Ty<'db>,
2150 ) -> Ty<'db> {
2151 let recursion_limit = 10;
2153 for iteration in 0.. {
2154 if iteration > recursion_limit {
2155 return self.err_ty();
2156 }
2157 match ty.kind() {
2158 TyKind::Adt(adt_def, substs) => match adt_def.def_id() {
2159 AdtId::StructId(struct_id) => {
2160 match self
2161 .db
2162 .field_types(struct_id.into())
2163 .values()
2164 .next_back()
2165 .map(|it| it.ty())
2166 {
2167 Some(field) => {
2168 ty = field.instantiate(self.interner(), substs).skip_norm_wip();
2169 }
2170 None => break,
2171 }
2172 }
2173 _ => break,
2174 },
2175 TyKind::Tuple(substs) => match substs.as_slice().split_last() {
2176 Some((last_ty, _)) => ty = *last_ty,
2177 None => break,
2178 },
2179 TyKind::Alias(..) => {
2180 let normalized = normalize(ty);
2181 if ty == normalized {
2182 return ty;
2183 } else {
2184 ty = normalized;
2185 }
2186 }
2187 _ => break,
2188 }
2189 }
2190 ty
2191 }
2192
2193 fn process_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2195 self.table.process_user_written_ty(ty)
2196 }
2197
2198 fn process_remote_user_written_ty(&mut self, ty: Ty<'db>) -> Ty<'db> {
2201 self.table.process_remote_user_written_ty(ty)
2202 }
2203
2204 fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
2205 self.table.shallow_resolve(ty)
2206 }
2207
2208 pub(crate) fn resolve_vars_if_possible<T: TypeFoldable<DbInterner<'db>>>(&self, t: T) -> T {
2209 self.table.resolve_vars_if_possible(t)
2210 }
2211
2212 pub(crate) fn structurally_resolve_type(
2213 &mut self,
2214 node: ExprOrPatIdPacked,
2215 ty: Ty<'db>,
2216 ) -> Ty<'db> {
2217 let result = self.table.try_structurally_resolve_type(node.into(), ty);
2218 if result.is_ty_var() { self.type_must_be_known_at_this_point(node, ty) } else { result }
2219 }
2220
2221 pub(crate) fn emit_type_mismatch(
2222 &mut self,
2223 node: ExprOrPatIdPacked,
2224 expected: Ty<'db>,
2225 found: Ty<'db>,
2226 ) {
2227 if self.result.nodes_with_type_mismatches.get_or_insert_default().insert(node) {
2228 self.diagnostics.push(InferenceDiagnostic::TypeMismatch {
2229 node,
2230 expected: expected.store(),
2231 found: found.store(),
2232 });
2233 }
2234 }
2235
2236 fn demand_eqtype(
2237 &mut self,
2238 id: ExprOrPatIdPacked,
2239 expected: Ty<'db>,
2240 actual: Ty<'db>,
2241 ) -> Result<(), ()> {
2242 let result = self
2243 .table
2244 .at(&ObligationCause::new(id))
2245 .eq(expected, actual)
2246 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2247 if result.is_err() {
2248 self.emit_type_mismatch(id, expected, actual);
2249 }
2250 result.map_err(drop)
2251 }
2252
2253 fn demand_eqtype_fixme_no_diag(
2254 &mut self,
2255 expected: Ty<'db>,
2256 actual: Ty<'db>,
2257 ) -> Result<(), ()> {
2258 let result = self
2259 .table
2260 .at(&ObligationCause::dummy())
2261 .eq(expected, actual)
2262 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2263 result.map_err(drop)
2264 }
2265
2266 fn demand_suptype(
2267 &mut self,
2268 id: ExprOrPatIdPacked,
2269 expected: Ty<'db>,
2270 actual: Ty<'db>,
2271 ) -> Result<(), ()> {
2272 let result = self
2273 .table
2274 .at(&ObligationCause::new(id))
2275 .sup(expected, actual)
2276 .map(|infer_ok| self.table.register_infer_ok(infer_ok));
2277 if result.is_err() {
2278 self.emit_type_mismatch(id, expected, actual);
2279 }
2280 result.map_err(drop)
2281 }
2282
2283 fn demand_coerce(
2284 &mut self,
2285 expr: ExprId,
2286 checked_ty: Ty<'db>,
2287 expected: Ty<'db>,
2288 allow_two_phase: AllowTwoPhase,
2289 expr_is_read: ExprIsRead,
2290 ) -> Ty<'db> {
2291 let result = self.coerce(expr, checked_ty, expected, allow_two_phase, expr_is_read);
2292 if let Err(_err) = result {
2293 }
2295 result.unwrap_or(self.types.types.error)
2296 }
2297
2298 pub(crate) fn type_must_be_known_at_this_point(
2299 &mut self,
2300 node: ExprOrPatIdPacked,
2301 ty: Ty<'db>,
2302 ) -> Ty<'db> {
2303 if self.vars_emitted_type_must_be_known_for.insert(ty.into()) {
2304 self.push_diagnostic(InferenceDiagnostic::TypeMustBeKnown {
2305 at_point: node.into(),
2306 top_term: None,
2307 });
2308 }
2309 self.types.types.error
2310 }
2311
2312 pub(crate) fn require_type_is_sized(&mut self, ty: Ty<'db>, span: Span) {
2313 if !ty.references_non_lt_error()
2314 && let Some(sized_trait) = self.lang_items.Sized
2315 {
2316 self.table.register_bound(ty, sized_trait, ObligationCause::new(span));
2317 }
2318 }
2319
2320 fn expr_ty(&self, expr: ExprId) -> Ty<'db> {
2321 self.result.expr_ty(expr)
2322 }
2323
2324 fn expr_ty_after_adjustments(&self, e: ExprId) -> Ty<'db> {
2325 let mut ty = None;
2326 if let Some(it) = self.result.expr_adjustments.get(&e)
2327 && let Some(it) = it.last()
2328 {
2329 ty = Some(it.target.as_ref());
2330 }
2331 ty.unwrap_or_else(|| self.expr_ty(e))
2332 }
2333
2334 fn resolve_variant(
2335 &mut self,
2336 node: ExprOrPatIdPacked,
2337 path: &Path,
2338 value_ns: bool,
2339 ) -> (Ty<'db>, Option<VariantId>) {
2340 let interner = self.interner();
2341 let mut vars_ctx = InferenceTyLoweringVarsCtx {
2342 table: &mut self.table,
2343 type_of_type_placeholder: &mut self.result.type_of_type_placeholder,
2344 };
2345 let mut ctx = TyLoweringContext::new(
2346 self.db,
2347 &self.resolver,
2348 self.store,
2349 &self.diagnostics,
2350 InferenceTyDiagnosticSource::Body,
2351 self.store_owner,
2352 self.generic_def,
2353 &self.generics,
2354 LifetimeElisionKind::Infer,
2355 self.allow_using_generic_params,
2356 Some(&mut vars_ctx),
2357 &self.defined_anon_consts,
2358 LifetimeLoweringMode::LateParam,
2359 );
2360
2361 if let Some(type_anchor) = path.type_anchor() {
2362 let mut segments = path.segments();
2363 if segments.is_empty() {
2364 return (self.types.types.error, None);
2365 }
2366 let (mut ty, type_ns) = ctx.lower_ty_ext(type_anchor);
2367 ty = ctx.expect_table().process_user_written_ty(ty);
2368
2369 if let Some(TypeNs::SelfType(impl_)) = type_ns
2370 && let Some(trait_ref) = self.db.impl_trait(impl_)
2371 && let trait_ref = trait_ref.instantiate_identity().skip_norm_wip()
2372 && let Some(assoc_type) = trait_ref
2373 .def_id
2374 .0
2375 .trait_items(self.db)
2376 .associated_type_by_name(segments.first().unwrap().name)
2377 {
2378 let args = ctx.expect_table().infer_ctxt.fill_rest_fresh_args(
2380 node.into(),
2381 assoc_type.into(),
2382 trait_ref.args,
2383 );
2384 let alias = Ty::new_alias(
2385 interner,
2386 AliasTy::new_from_args(
2387 interner,
2388 AliasTyKind::Projection { def_id: assoc_type.into() },
2389 args,
2390 ),
2391 );
2392 ty = ctx.expect_table().try_structurally_resolve_type(node.into(), alias);
2393 segments = segments.skip(1);
2394 }
2395
2396 let variant = match ty.as_adt() {
2397 Some((AdtId::StructId(id), _)) => id.into(),
2398 Some((AdtId::UnionId(id), _)) => id.into(),
2399 Some((AdtId::EnumId(id), _)) => {
2400 if let Some(segment) = segments.first()
2401 && let enum_data = id.enum_variants(self.db)
2402 && let Some(variant) = enum_data.variant(segment.name)
2403 {
2404 segments = segments.skip(1);
2406 variant.into()
2407 } else {
2408 return (self.types.types.error, None);
2409 }
2410 }
2411 None => return (self.types.types.error, None),
2412 };
2413
2414 if !segments.is_empty() {
2415 return (self.types.types.error, None);
2417 } else {
2418 return (ty, Some(variant));
2419 }
2420 }
2421
2422 let mut path_ctx = ctx.at_path(path, node);
2423 let interner = DbInterner::conjure();
2424 let (resolution, unresolved) = if value_ns {
2425 let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
2426 return (self.types.types.error, None);
2427 };
2428 match res {
2429 ResolveValueResult::ValueNs(value) => match value {
2430 ValueNs::EnumVariantId(var) => {
2431 let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2432 drop(ctx);
2433 let ty = self
2434 .db
2435 .ty(var.lookup(self.db).parent.into())
2436 .instantiate(interner, args)
2437 .skip_norm_wip();
2438 let ty = self.insert_type_vars(ty);
2439 return (ty, Some(var.into()));
2440 }
2441 ValueNs::StructId(strukt) => {
2442 let args =
2443 path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2444 drop(ctx);
2445 let ty =
2446 self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2447 let ty = self.insert_type_vars(ty);
2448 return (ty, Some(strukt.into()));
2449 }
2450 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
2451 _ => {
2452 drop(ctx);
2453 return (self.types.types.error, None);
2454 }
2455 },
2456 ResolveValueResult::Partial(typens, unresolved) => (typens, Some(unresolved)),
2457 }
2458 } else {
2459 match path_ctx.resolve_path_in_type_ns() {
2460 Some((it, idx)) => (it, idx),
2461 None => return (self.types.types.error, None),
2462 }
2463 };
2464 return match resolution {
2465 TypeNs::AdtId(AdtId::StructId(strukt)) => {
2466 let args = path_ctx.substs_from_path(strukt.into(), true, false, node.into());
2467 drop(ctx);
2468 let ty = self.db.ty(strukt.into()).instantiate(interner, args).skip_norm_wip();
2469 let ty = self.insert_type_vars(ty);
2470 forbid_unresolved_segments(self, (ty, Some(strukt.into())), unresolved)
2471 }
2472 TypeNs::AdtId(AdtId::UnionId(u)) => {
2473 let args = path_ctx.substs_from_path(u.into(), true, false, node.into());
2474 drop(ctx);
2475 let ty = self.db.ty(u.into()).instantiate(interner, args).skip_norm_wip();
2476 let ty = self.insert_type_vars(ty);
2477 forbid_unresolved_segments(self, (ty, Some(u.into())), unresolved)
2478 }
2479 TypeNs::EnumVariantId(var) => {
2480 let args = path_ctx.substs_from_path(var.into(), true, false, node.into());
2481 drop(ctx);
2482 let ty = self
2483 .db
2484 .ty(var.lookup(self.db).parent.into())
2485 .instantiate(interner, args)
2486 .skip_norm_wip();
2487 let ty = self.insert_type_vars(ty);
2488 forbid_unresolved_segments(self, (ty, Some(var.into())), unresolved)
2489 }
2490 TypeNs::SelfType(impl_id) => {
2491 let mut ty = self.db.impl_self_ty(impl_id).instantiate_identity().skip_norm_wip();
2492
2493 let Some(remaining_idx) = unresolved else {
2494 drop(ctx);
2495 let Some(mod_path) = path.mod_path() else {
2496 never!("resolver should always resolve lang item paths");
2497 return (self.types.types.error, None);
2498 };
2499 return self.resolve_variant_on_alias(node, ty, None, mod_path);
2500 };
2501
2502 let mut remaining_segments = path.segments().skip(remaining_idx);
2503
2504 if remaining_segments.len() >= 2 {
2505 path_ctx.ignore_last_segment();
2506 }
2507
2508 let mut tried_resolving_once = false;
2511 while let Some(current_segment) = remaining_segments.first() {
2512 if let TyKind::Adt(adt_def, _) = ty.kind()
2515 && let AdtId::EnumId(id) = adt_def.def_id()
2516 {
2517 let enum_data = id.enum_variants(self.db);
2518 if let Some(variant) = enum_data.variant(current_segment.name) {
2519 return if remaining_segments.len() == 1 {
2520 (ty, Some(variant.into()))
2521 } else {
2522 (self.types.types.error, None)
2526 };
2527 }
2528 }
2529
2530 if tried_resolving_once {
2531 break;
2534 }
2535
2536 (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2540 tried_resolving_once = true;
2541
2542 ty = path_ctx.expect_table().process_user_written_ty(ty);
2543 if ty.is_ty_error() {
2544 return (self.types.types.error, None);
2545 }
2546
2547 remaining_segments = remaining_segments.skip(1);
2548 }
2549 drop(ctx);
2550
2551 let variant = ty.as_adt().and_then(|(id, _)| match id {
2552 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2553 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2554 AdtId::EnumId(_) => {
2555 None
2557 }
2558 });
2559 (ty, variant)
2560 }
2561 TypeNs::TraitId(_) => {
2562 let Some(remaining_idx) = unresolved else {
2563 return (self.types.types.error, None);
2564 };
2565
2566 let remaining_segments = path.segments().skip(remaining_idx);
2567
2568 if remaining_segments.len() >= 2 {
2569 path_ctx.ignore_last_segment();
2570 }
2571
2572 let (mut ty, _) =
2573 path_ctx.lower_partly_resolved_path(resolution, true, node.into());
2574 ty = ctx.expect_table().process_user_written_ty(ty);
2575
2576 if let Some(segment) = remaining_segments.get(1)
2577 && let Some((AdtId::EnumId(id), _)) = ty.as_adt()
2578 {
2579 let enum_data = id.enum_variants(self.db);
2580 if let Some(variant) = enum_data.variant(segment.name) {
2581 return if remaining_segments.len() == 2 {
2582 (ty, Some(variant.into()))
2583 } else {
2584 (self.types.types.error, None)
2588 };
2589 }
2590 }
2591
2592 let variant = ty.as_adt().and_then(|(id, _)| match id {
2593 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2594 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2595 AdtId::EnumId(_) => {
2596 None
2598 }
2599 });
2600 (ty, variant)
2601 }
2602 TypeNs::TypeAliasId(it) => {
2603 let Some(mod_path) = path.mod_path() else {
2604 never!("resolver should always resolve lang item paths");
2605 return (self.types.types.error, None);
2606 };
2607 let args =
2608 path_ctx.substs_from_path_segment(it.into(), true, None, false, node.into());
2609 let interner = path_ctx.interner();
2610 drop(ctx);
2611 let ty = self.db.ty(it.into()).instantiate(interner, args).skip_norm_wip();
2612 let ty = self.insert_type_vars(ty);
2613
2614 self.resolve_variant_on_alias(node, ty, unresolved, mod_path)
2615 }
2616 TypeNs::AdtSelfType(_) => {
2617 (self.types.types.error, None)
2619 }
2620 TypeNs::GenericParam(_) => {
2621 (self.types.types.error, None)
2623 }
2624 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::ModuleId(_) => {
2625 (self.types.types.error, None)
2627 }
2628 };
2629
2630 fn forbid_unresolved_segments<'db>(
2631 ctx: &InferenceContext<'db>,
2632 result: (Ty<'db>, Option<VariantId>),
2633 unresolved: Option<usize>,
2634 ) -> (Ty<'db>, Option<VariantId>) {
2635 if unresolved.is_none() {
2636 result
2637 } else {
2638 (ctx.types.types.error, None)
2640 }
2641 }
2642 }
2643
2644 fn resolve_variant_on_alias(
2645 &mut self,
2646 node: ExprOrPatIdPacked,
2647 ty: Ty<'db>,
2648 unresolved: Option<usize>,
2649 path: &ModPath,
2650 ) -> (Ty<'db>, Option<VariantId>) {
2651 let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
2652 let ty = self.table.try_structurally_resolve_type(node.into(), ty);
2653 match remaining {
2654 None => {
2655 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
2656 AdtId::StructId(s) => Some(VariantId::StructId(s)),
2657 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
2658 AdtId::EnumId(_) => {
2659 None
2661 }
2662 });
2663 (ty, variant)
2664 }
2665 Some(1) => {
2666 let segment = path.segments().last().unwrap();
2667 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
2669 let enum_data = enum_id.enum_variants(self.db);
2670 if let Some(variant) = enum_data.variant(segment) {
2671 return (ty, Some(variant.into()));
2672 }
2673 }
2674 (self.err_ty(), None)
2676 }
2677 Some(_) => {
2678 (self.err_ty(), None)
2680 }
2681 }
2682 }
2683
2684 fn resolve_va_list(&self) -> Option<AdtId> {
2685 let struct_ = self.lang_items.VaList?;
2686 Some(struct_.into())
2687 }
2688
2689 pub(crate) fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
2690 let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
2691 if b_traits.peek().is_some() {
2692 Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
2693 } else {
2694 Either::Right(&self.traits_in_scope)
2695 }
2696 }
2697
2698 fn has_applicable_non_exhaustive(&self, def: AttrDefId) -> bool {
2699 AttrFlags::query(self.db, def).contains(AttrFlags::NON_EXHAUSTIVE)
2700 && def.krate(self.db) != self.krate()
2701 }
2702}
2703
2704#[derive(Clone, PartialEq, Eq, Debug)]
2707pub(crate) enum Expectation<'db> {
2708 None,
2709 HasType(Ty<'db>),
2710 Castable(Ty<'db>),
2711 RValueLikeUnsized(Ty<'db>),
2712}
2713
2714impl<'db> Expectation<'db> {
2715 fn has_type(ty: Ty<'db>) -> Self {
2718 if ty.is_ty_error() {
2719 Expectation::None
2721 } else {
2722 Expectation::HasType(ty)
2723 }
2724 }
2725
2726 fn rvalue_hint(ctx: &mut InferenceContext<'db>, ty: Ty<'db>) -> Self {
2747 match ctx.struct_tail_without_normalization(ty).kind() {
2748 TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(..) => {
2749 Expectation::RValueLikeUnsized(ty)
2750 }
2751 _ => Expectation::has_type(ty),
2752 }
2753 }
2754
2755 fn none() -> Self {
2757 Expectation::None
2758 }
2759
2760 fn resolve(&self, table: &unify::InferenceTable<'db>) -> Expectation<'db> {
2761 match self {
2762 Expectation::None => Expectation::None,
2763 Expectation::HasType(t) => Expectation::HasType(table.shallow_resolve(*t)),
2764 Expectation::Castable(t) => Expectation::Castable(table.shallow_resolve(*t)),
2765 Expectation::RValueLikeUnsized(t) => {
2766 Expectation::RValueLikeUnsized(table.shallow_resolve(*t))
2767 }
2768 }
2769 }
2770
2771 fn to_option(&self, table: &unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2772 match self.resolve(table) {
2773 Expectation::None => None,
2774 Expectation::HasType(t)
2775 | Expectation::Castable(t)
2776 | Expectation::RValueLikeUnsized(t) => Some(t),
2777 }
2778 }
2779
2780 fn only_has_type(&self, table: &mut unify::InferenceTable<'db>) -> Option<Ty<'db>> {
2781 match self {
2782 Expectation::HasType(t) => Some(table.resolve_vars_if_possible(*t)),
2783 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2784 None
2785 }
2786 }
2787 }
2788
2789 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'db>, span: Span) -> Ty<'db> {
2790 self.only_has_type(table).unwrap_or_else(|| table.next_ty_var(span))
2791 }
2792
2793 fn adjust_for_branches(
2811 &self,
2812 table: &mut unify::InferenceTable<'db>,
2813 span: Span,
2814 ) -> Expectation<'db> {
2815 match *self {
2816 Expectation::HasType(ety) => {
2817 let ety = table.try_structurally_resolve_type(span, ety);
2818 if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2819 }
2820 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety),
2821 _ => Expectation::None,
2822 }
2823 }
2824}
2825
2826#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2827enum Diverges {
2828 Maybe,
2829 Always,
2830}
2831
2832impl Diverges {
2833 fn is_always(self) -> bool {
2834 self == Diverges::Always
2835 }
2836}
2837
2838impl std::ops::BitAnd for Diverges {
2839 type Output = Self;
2840 fn bitand(self, other: Self) -> Self {
2841 std::cmp::min(self, other)
2842 }
2843}
2844
2845impl std::ops::BitOr for Diverges {
2846 type Output = Self;
2847 fn bitor(self, other: Self) -> Self {
2848 std::cmp::max(self, other)
2849 }
2850}
2851
2852impl std::ops::BitAndAssign for Diverges {
2853 fn bitand_assign(&mut self, other: Self) {
2854 *self = *self & other;
2855 }
2856}
2857
2858impl std::ops::BitOrAssign for Diverges {
2859 fn bitor_assign(&mut self, other: Self) {
2860 *self = *self | other;
2861 }
2862}