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