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