1pub(crate) mod cast;
17pub(crate) mod closure;
18mod coerce;
19pub(crate) mod diagnostics;
20mod expr;
21mod mutability;
22mod pat;
23mod path;
24pub(crate) mod unify;
25
26use std::{cell::OnceCell, convert::identity, iter, ops::Index};
27
28use chalk_ir::{
29 DebruijnIndex, Mutability, Safety, Scalar, TyKind, TypeFlags, Variance,
30 cast::Cast,
31 fold::TypeFoldable,
32 interner::HasInterner,
33 visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
34};
35use either::Either;
36use hir_def::{
37 AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
38 ImplId, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId,
39 VariantId,
40 builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
41 expr_store::{Body, ExpressionStore, HygieneId, path::Path},
42 hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
43 lang_item::{LangItem, LangItemTarget, lang_item},
44 layout::Integer,
45 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
46 signatures::{ConstSignature, StaticSignature},
47 type_ref::{ConstRef, LifetimeRefId, TypeRefId},
48};
49use hir_expand::{mod_path::ModPath, name::Name};
50use indexmap::IndexSet;
51use intern::sym;
52use la_arena::{ArenaMap, Entry};
53use rustc_hash::{FxHashMap, FxHashSet};
54use stdx::{always, never};
55use triomphe::Arc;
56
57use crate::{
58 AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
59 ImplTraitIdx, InEnvironment, IncorrectGenericsLenKind, Interner, Lifetime, OpaqueTyId,
60 ParamLoweringMode, PathLoweringDiagnostic, ProjectionTy, Substitution, TraitEnvironment, Ty,
61 TyBuilder, TyExt,
62 db::HirDatabase,
63 fold_tys,
64 generics::Generics,
65 infer::{
66 coerce::CoerceMany,
67 diagnostics::{Diagnostics, InferenceTyLoweringContext as TyLoweringContext},
68 expr::ExprIsRead,
69 unify::InferenceTable,
70 },
71 lower::{ImplTraitLoweringMode, LifetimeElisionKind, diagnostics::TyLoweringDiagnostic},
72 mir::MirSpan,
73 static_lifetime, to_assoc_type_id,
74 traits::FnTrait,
75 utils::UnevaluatedConstEvaluatorFolder,
76};
77
78#[allow(unreachable_pub)]
82pub use coerce::could_coerce;
83#[allow(unreachable_pub)]
84pub use unify::{could_unify, could_unify_deeply};
85
86use cast::{CastCheck, CastError};
87pub(crate) use closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
88
89pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
91 let _p = tracing::info_span!("infer_query").entered();
92 let resolver = def.resolver(db);
93 let body = db.body(def);
94 let mut ctx = InferenceContext::new(db, def, &body, resolver);
95
96 match def {
97 DefWithBodyId::FunctionId(f) => {
98 ctx.collect_fn(f);
99 }
100 DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
101 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
102 DefWithBodyId::VariantId(v) => {
103 ctx.return_ty = TyBuilder::builtin(
104 match db.enum_signature(v.lookup(db).parent).variant_body_type() {
105 hir_def::layout::IntegerType::Pointer(signed) => match signed {
106 true => BuiltinType::Int(BuiltinInt::Isize),
107 false => BuiltinType::Uint(BuiltinUint::Usize),
108 },
109 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
110 true => BuiltinType::Int(match size {
111 Integer::I8 => BuiltinInt::I8,
112 Integer::I16 => BuiltinInt::I16,
113 Integer::I32 => BuiltinInt::I32,
114 Integer::I64 => BuiltinInt::I64,
115 Integer::I128 => BuiltinInt::I128,
116 }),
117 false => BuiltinType::Uint(match size {
118 Integer::I8 => BuiltinUint::U8,
119 Integer::I16 => BuiltinUint::U16,
120 Integer::I32 => BuiltinUint::U32,
121 Integer::I64 => BuiltinUint::U64,
122 Integer::I128 => BuiltinUint::U128,
123 }),
124 },
125 },
126 );
127 }
128 }
129
130 ctx.infer_body();
131
132 ctx.infer_mut_body();
133
134 ctx.infer_closures();
135
136 Arc::new(ctx.resolve_all())
137}
138
139pub(crate) fn infer_cycle_result(_: &dyn HirDatabase, _: DefWithBodyId) -> Arc<InferenceResult> {
140 Arc::new(InferenceResult { has_errors: true, ..Default::default() })
141}
142
143#[tracing::instrument(level = "debug", skip(db))]
148pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment>, ty: Ty) -> Ty {
149 if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION)
153 && !matches!(ty.kind(Interner), TyKind::Array(..))
154 {
155 return ty;
156 }
157 let mut table = unify::InferenceTable::new(db, trait_env);
158
159 let ty_with_vars = table.normalize_associated_types_in(ty);
160 table.resolve_obligations_as_possible();
161 table.propagate_diverging_flag();
162 table.resolve_completely(ty_with_vars)
163}
164
165#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
168pub enum BindingMode {
169 #[default]
170 Move,
171 Ref(Mutability),
172}
173
174impl BindingMode {
175 fn convert(annotation: BindingAnnotation) -> BindingMode {
176 match annotation {
177 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
178 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
179 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
180 }
181 }
182}
183
184#[derive(Debug)]
185pub(crate) struct InferOk<T> {
186 value: T,
187 goals: Vec<InEnvironment<Goal>>,
188}
189
190impl<T> InferOk<T> {
191 fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
192 InferOk { value: f(self.value), goals: self.goals }
193 }
194}
195
196#[derive(Debug, PartialEq, Eq, Clone, Copy)]
197pub enum InferenceTyDiagnosticSource {
198 Body,
200 Signature,
202}
203
204#[derive(Debug)]
205pub(crate) struct TypeError;
206pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
207
208#[derive(Debug, PartialEq, Eq, Clone)]
209pub enum InferenceDiagnostic {
210 NoSuchField {
211 field: ExprOrPatId,
212 private: Option<LocalFieldId>,
213 variant: VariantId,
214 },
215 PrivateField {
216 expr: ExprId,
217 field: FieldId,
218 },
219 PrivateAssocItem {
220 id: ExprOrPatId,
221 item: AssocItemId,
222 },
223 UnresolvedField {
224 expr: ExprId,
225 receiver: Ty,
226 name: Name,
227 method_with_same_name_exists: bool,
228 },
229 UnresolvedMethodCall {
230 expr: ExprId,
231 receiver: Ty,
232 name: Name,
233 field_with_same_name: Option<Ty>,
235 assoc_func_with_same_name: Option<FunctionId>,
236 },
237 UnresolvedAssocItem {
238 id: ExprOrPatId,
239 },
240 UnresolvedIdent {
241 id: ExprOrPatId,
242 },
243 BreakOutsideOfLoop {
245 expr: ExprId,
246 is_break: bool,
247 bad_value_break: bool,
248 },
249 MismatchedArgCount {
250 call_expr: ExprId,
251 expected: usize,
252 found: usize,
253 },
254 MismatchedTupleStructPatArgCount {
255 pat: ExprOrPatId,
256 expected: usize,
257 found: usize,
258 },
259 ExpectedFunction {
260 call_expr: ExprId,
261 found: Ty,
262 },
263 TypedHole {
264 expr: ExprId,
265 expected: Ty,
266 },
267 CastToUnsized {
268 expr: ExprId,
269 cast_ty: Ty,
270 },
271 InvalidCast {
272 expr: ExprId,
273 error: CastError,
274 expr_ty: Ty,
275 cast_ty: Ty,
276 },
277 TyDiagnostic {
278 source: InferenceTyDiagnosticSource,
279 diag: TyLoweringDiagnostic,
280 },
281 PathDiagnostic {
282 node: ExprOrPatId,
283 diag: PathLoweringDiagnostic,
284 },
285 MethodCallIncorrectGenericsLen {
286 expr: ExprId,
287 provided_count: u32,
288 expected_count: u32,
289 kind: IncorrectGenericsLenKind,
290 def: GenericDefId,
291 },
292 MethodCallIncorrectGenericsOrder {
293 expr: ExprId,
294 param_id: GenericParamId,
295 arg_idx: u32,
296 has_self_arg: bool,
298 },
299}
300
301#[derive(Clone, PartialEq, Eq, Debug, Hash)]
303pub struct TypeMismatch {
304 pub expected: Ty,
305 pub actual: Ty,
306}
307
308#[derive(Clone, PartialEq, Eq, Debug)]
309struct InternedStandardTypes {
310 unknown: Ty,
311 bool_: Ty,
312 unit: Ty,
313 never: Ty,
314}
315
316impl Default for InternedStandardTypes {
317 fn default() -> Self {
318 InternedStandardTypes {
319 unknown: TyKind::Error.intern(Interner),
320 bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
321 unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
322 never: TyKind::Never.intern(Interner),
323 }
324 }
325}
326#[derive(Clone, Debug, PartialEq, Eq, Hash)]
367pub struct Adjustment {
368 pub kind: Adjust,
369 pub target: Ty,
370}
371
372impl Adjustment {
373 pub fn borrow(m: Mutability, ty: Ty, lt: Lifetime) -> Self {
374 let ty = TyKind::Ref(m, lt.clone(), ty).intern(Interner);
375 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(lt, m)), target: ty }
376 }
377}
378
379#[derive(Clone, Debug, PartialEq, Eq, Hash)]
380pub enum Adjust {
381 NeverToAny,
383 Deref(Option<OverloadedDeref>),
385 Borrow(AutoBorrow),
387 Pointer(PointerCast),
388}
389
390#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
397pub struct OverloadedDeref(pub Option<Mutability>);
398
399#[derive(Clone, Debug, PartialEq, Eq, Hash)]
400pub enum AutoBorrow {
401 Ref(Lifetime, Mutability),
403 RawPtr(Mutability),
405}
406
407impl AutoBorrow {
408 fn mutability(&self) -> Mutability {
409 let (AutoBorrow::Ref(_, m) | AutoBorrow::RawPtr(m)) = self;
410 *m
411 }
412}
413
414#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
415pub enum PointerCast {
416 ReifyFnPointer,
418
419 UnsafeFnPointer,
421
422 ClosureFnPointer(Safety),
425
426 MutToConstPointer,
428
429 #[allow(dead_code)]
430 ArrayToPointer,
432
433 Unsize,
444}
445
446#[derive(Clone, PartialEq, Eq, Debug, Default)]
452pub struct InferenceResult {
453 method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
455 field_resolutions: FxHashMap<ExprId, Either<FieldId, TupleFieldId>>,
457 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
459 assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
461 tuple_field_access_types: FxHashMap<TupleId, Substitution>,
465 diagnostics: Vec<InferenceDiagnostic>,
467 pub(crate) type_of_expr: ArenaMap<ExprId, Ty>,
468 pub(crate) type_of_pat: ArenaMap<PatId, Ty>,
473 pub(crate) type_of_binding: ArenaMap<BindingId, Ty>,
474 pub(crate) type_of_rpit: ArenaMap<ImplTraitIdx, Ty>,
475 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
476 pub(crate) has_errors: bool,
481 standard_types: InternedStandardTypes,
484 pub(crate) pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
486 pub(crate) binding_modes: ArenaMap<PatId, BindingMode>,
500 pub(crate) expr_adjustments: FxHashMap<ExprId, Box<[Adjustment]>>,
501 pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
502 pub mutated_bindings_in_closure: FxHashSet<BindingId>,
504 pub(crate) coercion_casts: FxHashSet<ExprId>,
505}
506
507impl InferenceResult {
508 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
509 self.method_resolutions.get(&expr).cloned()
510 }
511 pub fn field_resolution(&self, expr: ExprId) -> Option<Either<FieldId, TupleFieldId>> {
512 self.field_resolutions.get(&expr).copied()
513 }
514 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
515 self.variant_resolutions.get(&id.into()).copied()
516 }
517 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
518 self.variant_resolutions.get(&id.into()).copied()
519 }
520 pub fn variant_resolution_for_expr_or_pat(&self, id: ExprOrPatId) -> Option<VariantId> {
521 match id {
522 ExprOrPatId::ExprId(id) => self.variant_resolution_for_expr(id),
523 ExprOrPatId::PatId(id) => self.variant_resolution_for_pat(id),
524 }
525 }
526 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
527 self.assoc_resolutions.get(&id.into()).cloned()
528 }
529 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
530 self.assoc_resolutions.get(&id.into()).cloned()
531 }
532 pub fn assoc_resolutions_for_expr_or_pat(
533 &self,
534 id: ExprOrPatId,
535 ) -> Option<(AssocItemId, Substitution)> {
536 match id {
537 ExprOrPatId::ExprId(id) => self.assoc_resolutions_for_expr(id),
538 ExprOrPatId::PatId(id) => self.assoc_resolutions_for_pat(id),
539 }
540 }
541 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
542 self.type_mismatches.get(&expr.into())
543 }
544 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
545 self.type_mismatches.get(&pat.into())
546 }
547 pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch)> {
548 self.type_mismatches.iter().map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch))
549 }
550 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
551 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
552 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
553 _ => None,
554 })
555 }
556 pub fn closure_info(&self, closure: &ClosureId) -> &(Vec<CapturedItem>, FnTrait) {
557 self.closure_info.get(closure).unwrap()
558 }
559 pub fn type_of_expr_or_pat(&self, id: ExprOrPatId) -> Option<&Ty> {
560 match id {
561 ExprOrPatId::ExprId(id) => self.type_of_expr.get(id),
562 ExprOrPatId::PatId(id) => self.type_of_pat.get(id),
563 }
564 }
565 pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<&Ty> {
566 match self.expr_adjustments.get(&id).and_then(|adjustments| {
567 adjustments
568 .iter()
569 .filter(|adj| {
570 !matches!(
572 adj,
573 Adjustment {
574 kind: Adjust::NeverToAny,
575 target,
576 } if target.is_never()
577 )
578 })
579 .next_back()
580 }) {
581 Some(adjustment) => Some(&adjustment.target),
582 None => self.type_of_expr.get(id),
583 }
584 }
585 pub fn type_of_pat_with_adjust(&self, id: PatId) -> Option<&Ty> {
586 match self.pat_adjustments.get(&id).and_then(|adjustments| adjustments.last()) {
587 adjusted @ Some(_) => adjusted,
588 None => self.type_of_pat.get(id),
589 }
590 }
591 pub fn is_erroneous(&self) -> bool {
592 self.has_errors && self.type_of_expr.iter().count() == 0
593 }
594
595 pub fn diagnostics(&self) -> &[InferenceDiagnostic] {
596 &self.diagnostics
597 }
598
599 pub fn tuple_field_access_type(&self, id: TupleId) -> &Substitution {
600 &self.tuple_field_access_types[&id]
601 }
602
603 pub fn pat_adjustment(&self, id: PatId) -> Option<&[Ty]> {
604 self.pat_adjustments.get(&id).map(|it| &**it)
605 }
606
607 pub fn expr_adjustment(&self, id: ExprId) -> Option<&[Adjustment]> {
608 self.expr_adjustments.get(&id).map(|it| &**it)
609 }
610
611 pub fn binding_mode(&self, id: PatId) -> Option<BindingMode> {
612 self.binding_modes.get(id).copied()
613 }
614}
615
616impl Index<ExprId> for InferenceResult {
617 type Output = Ty;
618
619 fn index(&self, expr: ExprId) -> &Ty {
620 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
621 }
622}
623
624impl Index<PatId> for InferenceResult {
625 type Output = Ty;
626
627 fn index(&self, pat: PatId) -> &Ty {
628 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
629 }
630}
631
632impl Index<ExprOrPatId> for InferenceResult {
633 type Output = Ty;
634
635 fn index(&self, id: ExprOrPatId) -> &Ty {
636 self.type_of_expr_or_pat(id).unwrap_or(&self.standard_types.unknown)
637 }
638}
639
640impl Index<BindingId> for InferenceResult {
641 type Output = Ty;
642
643 fn index(&self, b: BindingId) -> &Ty {
644 self.type_of_binding.get(b).unwrap_or(&self.standard_types.unknown)
645 }
646}
647
648#[derive(Clone, Debug)]
650pub(crate) struct InferenceContext<'db> {
651 pub(crate) db: &'db dyn HirDatabase,
652 pub(crate) owner: DefWithBodyId,
653 pub(crate) body: &'db Body,
654 pub(crate) resolver: Resolver<'db>,
657 generic_def: GenericDefId,
658 generics: OnceCell<Generics>,
659 table: unify::InferenceTable<'db>,
660 traits_in_scope: FxHashSet<TraitId>,
662 pub(crate) result: InferenceResult,
663 tuple_field_accesses_rev:
664 IndexSet<Substitution, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>,
665 return_ty: Ty,
671 return_coercion: Option<CoerceMany>,
675 resume_yield_tys: Option<(Ty, Ty)>,
677 diverges: Diverges,
678 breakables: Vec<BreakableContext>,
679
680 inside_assignment: bool,
682
683 deferred_cast_checks: Vec<CastCheck>,
684
685 current_captures: Vec<CapturedItemWithoutTy>,
687 current_capture_span_stack: Vec<MirSpan>,
693 current_closure: Option<ClosureId>,
694 closure_dependencies: FxHashMap<ClosureId, Vec<ClosureId>>,
697 deferred_closures: FxHashMap<ClosureId, Vec<(Ty, Ty, Vec<Ty>, ExprId)>>,
698
699 diagnostics: Diagnostics,
700}
701
702#[derive(Clone, Debug)]
703struct BreakableContext {
704 may_break: bool,
706 coerce: Option<CoerceMany>,
708 label: Option<LabelId>,
710 kind: BreakableKind,
711}
712
713#[derive(Clone, Debug)]
714enum BreakableKind {
715 Block,
716 Loop,
717 Border,
720}
721
722fn find_breakable(
723 ctxs: &mut [BreakableContext],
724 label: Option<LabelId>,
725) -> Option<&mut BreakableContext> {
726 let mut ctxs = ctxs
727 .iter_mut()
728 .rev()
729 .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
730 match label {
731 Some(_) => ctxs.find(|ctx| ctx.label == label),
732 None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
733 }
734}
735
736fn find_continuable(
737 ctxs: &mut [BreakableContext],
738 label: Option<LabelId>,
739) -> Option<&mut BreakableContext> {
740 match label {
741 Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
742 None => find_breakable(ctxs, label),
743 }
744}
745
746enum ImplTraitReplacingMode {
747 ReturnPosition(FxHashSet<Ty>),
748 TypeAlias,
749}
750
751impl<'db> InferenceContext<'db> {
752 fn new(
753 db: &'db dyn HirDatabase,
754 owner: DefWithBodyId,
755 body: &'db Body,
756 resolver: Resolver<'db>,
757 ) -> Self {
758 let trait_env = db.trait_environment_for_body(owner);
759 InferenceContext {
760 generics: OnceCell::new(),
761 result: InferenceResult::default(),
762 table: unify::InferenceTable::new(db, trait_env),
763 tuple_field_accesses_rev: Default::default(),
764 return_ty: TyKind::Error.intern(Interner), resume_yield_tys: None,
766 return_coercion: None,
767 db,
768 owner,
769 generic_def: match owner {
770 DefWithBodyId::FunctionId(it) => it.into(),
771 DefWithBodyId::StaticId(it) => it.into(),
772 DefWithBodyId::ConstId(it) => it.into(),
773 DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
774 },
775 body,
776 traits_in_scope: resolver.traits_in_scope(db),
777 resolver,
778 diverges: Diverges::Maybe,
779 breakables: Vec::new(),
780 deferred_cast_checks: Vec::new(),
781 current_captures: Vec::new(),
782 current_capture_span_stack: Vec::new(),
783 current_closure: None,
784 deferred_closures: FxHashMap::default(),
785 closure_dependencies: FxHashMap::default(),
786 inside_assignment: false,
787 diagnostics: Diagnostics::default(),
788 }
789 }
790
791 pub(crate) fn generics(&self) -> &Generics {
792 self.generics.get_or_init(|| crate::generics::generics(self.db, self.generic_def))
793 }
794
795 pub(crate) fn resolve_all(self) -> InferenceResult {
800 let InferenceContext {
801 mut table,
802 mut result,
803 mut deferred_cast_checks,
804 tuple_field_accesses_rev,
805 diagnostics,
806 ..
807 } = self;
808 let mut diagnostics = diagnostics.finish();
809 let InferenceResult {
812 method_resolutions,
813 field_resolutions: _,
814 variant_resolutions: _,
815 assoc_resolutions,
816 type_of_expr,
817 type_of_pat,
818 type_of_binding,
819 type_of_rpit,
820 type_mismatches,
821 has_errors,
822 standard_types: _,
823 pat_adjustments,
824 binding_modes: _,
825 expr_adjustments,
826 closure_info: _,
830 mutated_bindings_in_closure: _,
831 tuple_field_access_types: _,
832 coercion_casts,
833 diagnostics: _,
834 } = &mut result;
835 table.fallback_if_possible();
836
837 let mut apply_adjustments = |expr, adj: Vec<_>| {
841 expr_adjustments.insert(expr, adj.into_boxed_slice());
842 };
843 let mut set_coercion_cast = |expr| {
844 coercion_casts.insert(expr);
845 };
846 for cast in deferred_cast_checks.iter_mut() {
847 if let Err(diag) =
848 cast.check(&mut table, &mut apply_adjustments, &mut set_coercion_cast)
849 {
850 diagnostics.push(diag);
851 }
852 }
853
854 table.resolve_obligations_as_possible();
856
857 table.propagate_diverging_flag();
859 for ty in type_of_expr.values_mut() {
860 *ty = table.resolve_completely(ty.clone());
861 *has_errors = *has_errors || ty.contains_unknown();
862 }
863 type_of_expr.shrink_to_fit();
864 for ty in type_of_pat.values_mut() {
865 *ty = table.resolve_completely(ty.clone());
866 *has_errors = *has_errors || ty.contains_unknown();
867 }
868 type_of_pat.shrink_to_fit();
869 for ty in type_of_binding.values_mut() {
870 *ty = table.resolve_completely(ty.clone());
871 *has_errors = *has_errors || ty.contains_unknown();
872 }
873 type_of_binding.shrink_to_fit();
874 for ty in type_of_rpit.values_mut() {
875 *ty = table.resolve_completely(ty.clone());
876 *has_errors = *has_errors || ty.contains_unknown();
877 }
878 type_of_rpit.shrink_to_fit();
879
880 *has_errors |= !type_mismatches.is_empty();
881
882 type_mismatches.retain(|_, mismatch| {
883 mismatch.expected = table.resolve_completely(mismatch.expected.clone());
884 mismatch.actual = table.resolve_completely(mismatch.actual.clone());
885 chalk_ir::zip::Zip::zip_with(
886 &mut UnknownMismatch(self.db),
887 Variance::Invariant,
888 &mismatch.expected,
889 &mismatch.actual,
890 )
891 .is_ok()
892 });
893 type_mismatches.shrink_to_fit();
894 diagnostics.retain_mut(|diagnostic| {
895 use InferenceDiagnostic::*;
896 match diagnostic {
897 ExpectedFunction { found: ty, .. }
898 | UnresolvedField { receiver: ty, .. }
899 | UnresolvedMethodCall { receiver: ty, .. } => {
900 *ty = table.resolve_completely(ty.clone());
901 if ty.contains_unknown() {
903 return false;
904 }
905
906 if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic
907 && let Some(ty) = field_with_same_name
908 {
909 *ty = table.resolve_completely(ty.clone());
910 if ty.contains_unknown() {
911 *field_with_same_name = None;
912 }
913 }
914 }
915 TypedHole { expected: ty, .. } => {
916 *ty = table.resolve_completely(ty.clone());
917 }
918 _ => (),
919 }
920 true
921 });
922 diagnostics.shrink_to_fit();
923 for (_, subst) in method_resolutions.values_mut() {
924 *subst = table.resolve_completely(subst.clone());
925 *has_errors =
926 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
927 }
928 method_resolutions.shrink_to_fit();
929 for (_, subst) in assoc_resolutions.values_mut() {
930 *subst = table.resolve_completely(subst.clone());
931 *has_errors =
932 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
933 }
934 assoc_resolutions.shrink_to_fit();
935 for adjustment in expr_adjustments.values_mut().flatten() {
936 adjustment.target = table.resolve_completely(adjustment.target.clone());
937 *has_errors = *has_errors || adjustment.target.contains_unknown();
938 }
939 expr_adjustments.shrink_to_fit();
940 for adjustment in pat_adjustments.values_mut().flatten() {
941 *adjustment = table.resolve_completely(adjustment.clone());
942 *has_errors = *has_errors || adjustment.contains_unknown();
943 }
944 pat_adjustments.shrink_to_fit();
945 result.tuple_field_access_types = tuple_field_accesses_rev
946 .into_iter()
947 .enumerate()
948 .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
949 .inspect(|(_, subst)| {
950 *has_errors =
951 *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
952 })
953 .collect();
954 result.tuple_field_access_types.shrink_to_fit();
955
956 result.diagnostics = diagnostics;
957
958 result
959 }
960
961 fn collect_const(&mut self, id: ConstId, data: &ConstSignature) {
962 let return_ty = self.make_ty(
963 data.type_ref,
964 &data.store,
965 InferenceTyDiagnosticSource::Signature,
966 LifetimeElisionKind::for_const(id.loc(self.db).container),
967 );
968
969 self.make_tait_coercion_table(iter::once(&return_ty));
971
972 self.return_ty = return_ty;
973 }
974
975 fn collect_static(&mut self, data: &StaticSignature) {
976 let return_ty = self.make_ty(
977 data.type_ref,
978 &data.store,
979 InferenceTyDiagnosticSource::Signature,
980 LifetimeElisionKind::Elided(static_lifetime()),
981 );
982
983 self.make_tait_coercion_table(iter::once(&return_ty));
985
986 self.return_ty = return_ty;
987 }
988
989 fn collect_fn(&mut self, func: FunctionId) {
990 let data = self.db.function_signature(func);
991 let mut param_tys = self.with_ty_lowering(
992 &data.store,
993 InferenceTyDiagnosticSource::Signature,
994 LifetimeElisionKind::for_fn_params(&data),
995 |ctx| {
996 ctx.type_param_mode(ParamLoweringMode::Placeholder);
997 data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>()
998 },
999 );
1000
1001 if data.is_varargs() {
1004 let va_list_ty = match self.resolve_va_list() {
1005 Some(va_list) => TyBuilder::adt(self.db, va_list)
1006 .fill_with_defaults(self.db, || self.table.new_type_var())
1007 .build(),
1008 None => self.err_ty(),
1009 };
1010
1011 param_tys.push(va_list_ty);
1012 }
1013 let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.new_type_var()));
1014 if let Some(self_param) = self.body.self_param
1015 && let Some(ty) = param_tys.next()
1016 {
1017 let ty = self.insert_type_vars(ty);
1018 let ty = self.normalize_associated_types_in(ty);
1019 self.write_binding_ty(self_param, ty);
1020 }
1021 let mut tait_candidates = FxHashSet::default();
1022 for (ty, pat) in param_tys.zip(&*self.body.params) {
1023 let ty = self.insert_type_vars(ty);
1024 let ty = self.normalize_associated_types_in(ty);
1025
1026 self.infer_top_pat(*pat, &ty, None);
1027 if ty
1028 .data(Interner)
1029 .flags
1030 .intersects(TypeFlags::HAS_TY_OPAQUE.union(TypeFlags::HAS_TY_INFER))
1031 {
1032 tait_candidates.insert(ty);
1033 }
1034 }
1035 let return_ty = match data.ret_type {
1036 Some(return_ty) => {
1037 let return_ty = self.with_ty_lowering(
1038 &data.store,
1039 InferenceTyDiagnosticSource::Signature,
1040 LifetimeElisionKind::for_fn_ret(),
1041 |ctx| {
1042 ctx.type_param_mode(ParamLoweringMode::Placeholder)
1043 .impl_trait_mode(ImplTraitLoweringMode::Opaque);
1044 ctx.lower_ty(return_ty)
1045 },
1046 );
1047 let return_ty = self.insert_type_vars(return_ty);
1048 if let Some(rpits) = self.db.return_type_impl_traits(func) {
1049 let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
1051 let mut mode = ImplTraitReplacingMode::ReturnPosition(FxHashSet::default());
1052 let result = self.insert_inference_vars_for_impl_trait(
1053 return_ty,
1054 fn_placeholders,
1055 &mut mode,
1056 );
1057 if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1058 tait_candidates.extend(taits);
1059 }
1060 let rpits = rpits.skip_binders();
1061 for (id, _) in rpits.impl_traits.iter() {
1062 if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
1063 never!("Missed RPIT in `insert_inference_vars_for_rpit`");
1064 e.insert(TyKind::Error.intern(Interner));
1065 }
1066 }
1067 result
1068 } else {
1069 return_ty
1070 }
1071 }
1072 None => self.result.standard_types.unit.clone(),
1073 };
1074
1075 self.return_ty = self.normalize_associated_types_in(return_ty);
1076 self.return_coercion = Some(CoerceMany::new(self.return_ty.clone()));
1077
1078 fold_tys(
1082 self.return_ty.clone(),
1083 |ty, _| {
1084 match ty.kind(Interner) {
1085 TyKind::OpaqueType(..)
1086 | TyKind::Alias(AliasTy::Opaque(..))
1087 | TyKind::InferenceVar(..) => {
1088 tait_candidates.insert(self.return_ty.clone());
1089 }
1090 _ => {}
1091 }
1092 ty
1093 },
1094 DebruijnIndex::INNERMOST,
1095 );
1096
1097 self.make_tait_coercion_table(tait_candidates.iter());
1098 }
1099
1100 fn insert_inference_vars_for_impl_trait<T>(
1101 &mut self,
1102 t: T,
1103 placeholders: Substitution,
1104 mode: &mut ImplTraitReplacingMode,
1105 ) -> T
1106 where
1107 T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,
1108 {
1109 fold_tys(
1110 t,
1111 |ty, _| {
1112 let opaque_ty_id = match ty.kind(Interner) {
1113 TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
1114 _ => return ty,
1115 };
1116 let (impl_traits, idx) =
1117 match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
1118 ImplTraitId::ReturnTypeImplTrait(def, idx) => {
1126 if matches!(mode, ImplTraitReplacingMode::TypeAlias) {
1127 if let Some(ty) = self.result.type_of_rpit.get(idx) {
1130 return ty.clone();
1131 }
1132 return ty;
1133 }
1134 (self.db.return_type_impl_traits(def), idx)
1135 }
1136 ImplTraitId::TypeAliasImplTrait(def, idx) => {
1137 if let ImplTraitReplacingMode::ReturnPosition(taits) = mode {
1138 taits.insert(ty.clone());
1141 return ty;
1142 }
1143 (self.db.type_alias_impl_traits(def), idx)
1144 }
1145 _ => unreachable!(),
1146 };
1147 let Some(impl_traits) = impl_traits else {
1148 return ty;
1149 };
1150 let bounds = (*impl_traits)
1151 .map_ref(|its| its.impl_traits[idx].bounds.map_ref(|it| it.iter()));
1152 let var = self.table.new_type_var();
1153 let var_subst = Substitution::from1(Interner, var.clone());
1154 for bound in bounds {
1155 let predicate = bound.map(|it| it.cloned());
1156 let predicate = predicate.substitute(Interner, &placeholders);
1157 let (var_predicate, binders) =
1158 predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders();
1159 always!(binders.is_empty(Interner)); let var_predicate = self.insert_inference_vars_for_impl_trait(
1161 var_predicate,
1162 placeholders.clone(),
1163 mode,
1164 );
1165 self.push_obligation(var_predicate.cast(Interner));
1166 }
1167 self.result.type_of_rpit.insert(idx, var.clone());
1168 var
1169 },
1170 DebruijnIndex::INNERMOST,
1171 )
1172 }
1173
1174 fn make_tait_coercion_table<'b>(&mut self, tait_candidates: impl Iterator<Item = &'b Ty>) {
1186 struct TypeAliasImplTraitCollector<'a, 'b> {
1187 db: &'b dyn HirDatabase,
1188 table: &'b mut InferenceTable<'a>,
1189 assocs: FxHashMap<OpaqueTyId, (ImplId, Ty)>,
1190 non_assocs: FxHashMap<OpaqueTyId, Ty>,
1191 }
1192
1193 impl TypeVisitor<Interner> for TypeAliasImplTraitCollector<'_, '_> {
1194 type BreakTy = ();
1195
1196 fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
1197 self
1198 }
1199
1200 fn interner(&self) -> Interner {
1201 Interner
1202 }
1203
1204 fn visit_ty(
1205 &mut self,
1206 ty: &chalk_ir::Ty<Interner>,
1207 outer_binder: DebruijnIndex,
1208 ) -> std::ops::ControlFlow<Self::BreakTy> {
1209 let ty = self.table.resolve_ty_shallow(ty);
1210
1211 if let TyKind::OpaqueType(id, _) = ty.kind(Interner)
1212 && let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1213 self.db.lookup_intern_impl_trait_id((*id).into())
1214 {
1215 let loc = self.db.lookup_intern_type_alias(alias_id);
1216 match loc.container {
1217 ItemContainerId::ImplId(impl_id) => {
1218 self.assocs.insert(*id, (impl_id, ty.clone()));
1219 }
1220 ItemContainerId::ModuleId(..) | ItemContainerId::ExternBlockId(..) => {
1221 self.non_assocs.insert(*id, ty.clone());
1222 }
1223 _ => {}
1224 }
1225 }
1226
1227 ty.super_visit_with(self, outer_binder)
1228 }
1229 }
1230
1231 let mut collector = TypeAliasImplTraitCollector {
1232 db: self.db,
1233 table: &mut self.table,
1234 assocs: FxHashMap::default(),
1235 non_assocs: FxHashMap::default(),
1236 };
1237 for ty in tait_candidates {
1238 _ = ty.visit_with(collector.as_dyn(), DebruijnIndex::INNERMOST);
1239 }
1240
1241 let mut taits = collector.non_assocs;
1244
1245 let impl_id = match self.owner {
1264 DefWithBodyId::FunctionId(it) => {
1265 let loc = self.db.lookup_intern_function(it);
1266 if let ItemContainerId::ImplId(impl_id) = loc.container {
1267 Some(impl_id)
1268 } else {
1269 None
1270 }
1271 }
1272 DefWithBodyId::ConstId(it) => {
1273 let loc = self.db.lookup_intern_const(it);
1274 if let ItemContainerId::ImplId(impl_id) = loc.container {
1275 Some(impl_id)
1276 } else {
1277 None
1278 }
1279 }
1280 _ => None,
1281 };
1282
1283 if let Some(impl_id) = impl_id {
1284 taits.extend(collector.assocs.into_iter().filter_map(|(id, (impl_, ty))| {
1285 if impl_ == impl_id { Some((id, ty)) } else { None }
1286 }));
1287 }
1288
1289 let tait_coercion_table: FxHashMap<_, _> = taits
1290 .into_iter()
1291 .filter_map(|(id, ty)| {
1292 if let ImplTraitId::TypeAliasImplTrait(alias_id, _) =
1293 self.db.lookup_intern_impl_trait_id(id.into())
1294 {
1295 let subst = TyBuilder::placeholder_subst(self.db, alias_id);
1296 let ty = self.insert_inference_vars_for_impl_trait(
1297 ty,
1298 subst,
1299 &mut ImplTraitReplacingMode::TypeAlias,
1300 );
1301 Some((id, ty))
1302 } else {
1303 None
1304 }
1305 })
1306 .collect();
1307
1308 if !tait_coercion_table.is_empty() {
1309 self.table.tait_coercion_table = Some(tait_coercion_table);
1310 }
1311 }
1312
1313 fn infer_body(&mut self) {
1314 match self.return_coercion {
1315 Some(_) => self.infer_return(self.body.body_expr),
1316 None => {
1317 _ = self.infer_expr_coerce(
1318 self.body.body_expr,
1319 &Expectation::has_type(self.return_ty.clone()),
1320 ExprIsRead::Yes,
1321 )
1322 }
1323 }
1324 }
1325
1326 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
1327 self.result.type_of_expr.insert(expr, ty);
1328 }
1329
1330 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Box<[Adjustment]>) {
1331 if adjustments.is_empty() {
1332 return;
1333 }
1334 match self.result.expr_adjustments.entry(expr) {
1335 std::collections::hash_map::Entry::Occupied(mut entry) => {
1336 match (&mut entry.get_mut()[..], &adjustments[..]) {
1337 (
1338 [Adjustment { kind: Adjust::NeverToAny, target }],
1339 [.., Adjustment { target: new_target, .. }],
1340 ) => {
1341 *target = new_target.clone();
1344 }
1345 _ => {
1346 *entry.get_mut() = adjustments;
1347 }
1348 }
1349 }
1350 std::collections::hash_map::Entry::Vacant(entry) => {
1351 entry.insert(adjustments);
1352 }
1353 }
1354 }
1355
1356 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
1357 self.result.method_resolutions.insert(expr, (func, subst));
1358 }
1359
1360 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
1361 self.result.variant_resolutions.insert(id, variant);
1362 }
1363
1364 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
1365 self.result.assoc_resolutions.insert(id, (item, subs));
1366 }
1367
1368 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
1369 self.result.type_of_pat.insert(pat, ty);
1370 }
1371
1372 fn write_binding_ty(&mut self, id: BindingId, ty: Ty) {
1373 self.result.type_of_binding.insert(id, ty);
1374 }
1375
1376 fn push_diagnostic(&self, diagnostic: InferenceDiagnostic) {
1377 self.diagnostics.push(diagnostic);
1378 }
1379
1380 fn with_ty_lowering<R>(
1381 &mut self,
1382 store: &ExpressionStore,
1383 types_source: InferenceTyDiagnosticSource,
1384 lifetime_elision: LifetimeElisionKind,
1385 f: impl FnOnce(&mut TyLoweringContext<'_>) -> R,
1386 ) -> R {
1387 let mut ctx = TyLoweringContext::new(
1388 self.db,
1389 &self.resolver,
1390 store,
1391 &self.diagnostics,
1392 types_source,
1393 self.generic_def,
1394 lifetime_elision,
1395 );
1396 f(&mut ctx)
1397 }
1398
1399 fn with_body_ty_lowering<R>(&mut self, f: impl FnOnce(&mut TyLoweringContext<'_>) -> R) -> R {
1400 self.with_ty_lowering(
1401 self.body,
1402 InferenceTyDiagnosticSource::Body,
1403 LifetimeElisionKind::Infer,
1404 f,
1405 )
1406 }
1407
1408 fn make_ty(
1409 &mut self,
1410 type_ref: TypeRefId,
1411 store: &ExpressionStore,
1412 type_source: InferenceTyDiagnosticSource,
1413 lifetime_elision: LifetimeElisionKind,
1414 ) -> Ty {
1415 let ty = self
1416 .with_ty_lowering(store, type_source, lifetime_elision, |ctx| ctx.lower_ty(type_ref));
1417 let ty = self.insert_type_vars(ty);
1418 self.normalize_associated_types_in(ty)
1419 }
1420
1421 fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty {
1422 self.make_ty(
1423 type_ref,
1424 self.body,
1425 InferenceTyDiagnosticSource::Body,
1426 LifetimeElisionKind::Infer,
1427 )
1428 }
1429
1430 fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty) -> Const {
1431 let const_ = self.with_ty_lowering(
1432 self.body,
1433 InferenceTyDiagnosticSource::Body,
1434 LifetimeElisionKind::Infer,
1435 |ctx| {
1436 ctx.type_param_mode = ParamLoweringMode::Placeholder;
1437 ctx.lower_const(&const_ref, ty)
1438 },
1439 );
1440 self.insert_type_vars(const_)
1441 }
1442
1443 fn make_path_as_body_const(&mut self, path: &Path, ty: Ty) -> Const {
1444 let const_ = self.with_ty_lowering(
1445 self.body,
1446 InferenceTyDiagnosticSource::Body,
1447 LifetimeElisionKind::Infer,
1448 |ctx| {
1449 ctx.type_param_mode = ParamLoweringMode::Placeholder;
1450 ctx.lower_path_as_const(path, ty)
1451 },
1452 );
1453 self.insert_type_vars(const_)
1454 }
1455
1456 fn err_ty(&self) -> Ty {
1457 self.result.standard_types.unknown.clone()
1458 }
1459
1460 fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Lifetime {
1461 let lt = self.with_ty_lowering(
1462 self.body,
1463 InferenceTyDiagnosticSource::Body,
1464 LifetimeElisionKind::Infer,
1465 |ctx| ctx.lower_lifetime(lifetime_ref),
1466 );
1467 self.insert_type_vars(lt)
1468 }
1469
1470 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
1472 self.table.insert_type_vars_shallow(ty)
1473 }
1474
1475 fn insert_type_vars<T>(&mut self, ty: T) -> T
1476 where
1477 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1478 {
1479 self.table.insert_type_vars(ty)
1480 }
1481
1482 fn push_obligation(&mut self, o: DomainGoal) {
1483 self.table.register_obligation(o.cast(Interner));
1484 }
1485
1486 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
1487 let ty1 = ty1
1488 .clone()
1489 .try_fold_with(
1490 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1491 DebruijnIndex::INNERMOST,
1492 )
1493 .unwrap();
1494 let ty2 = ty2
1495 .clone()
1496 .try_fold_with(
1497 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
1498 DebruijnIndex::INNERMOST,
1499 )
1500 .unwrap();
1501 self.table.unify(&ty1, &ty2)
1502 }
1503
1504 fn struct_tail_without_normalization(&mut self, ty: Ty) -> Ty {
1508 self.struct_tail_with_normalize(ty, identity)
1509 }
1510
1511 fn struct_tail_with_normalize(
1519 &mut self,
1520 mut ty: Ty,
1521 mut normalize: impl FnMut(Ty) -> Ty,
1522 ) -> Ty {
1523 let recursion_limit = 10;
1525 for iteration in 0.. {
1526 if iteration > recursion_limit {
1527 return self.err_ty();
1528 }
1529 match ty.kind(Interner) {
1530 TyKind::Adt(chalk_ir::AdtId(hir_def::AdtId::StructId(struct_id)), substs) => {
1531 match self.db.field_types((*struct_id).into()).values().next_back().cloned() {
1532 Some(field) => {
1533 ty = field.substitute(Interner, substs);
1534 }
1535 None => break,
1536 }
1537 }
1538 TyKind::Adt(..) => break,
1539 TyKind::Tuple(_, substs) => {
1540 match substs
1541 .as_slice(Interner)
1542 .split_last()
1543 .and_then(|(last_ty, _)| last_ty.ty(Interner))
1544 {
1545 Some(last_ty) => ty = last_ty.clone(),
1546 None => break,
1547 }
1548 }
1549 TyKind::Alias(..) => {
1550 let normalized = normalize(ty.clone());
1551 if ty == normalized {
1552 return ty;
1553 } else {
1554 ty = normalized;
1555 }
1556 }
1557 _ => break,
1558 }
1559 }
1560 ty
1561 }
1562
1563 fn normalize_associated_types_in<T>(&mut self, ty: T) -> T
1570 where
1571 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
1572 {
1573 self.table.normalize_associated_types_in(ty)
1574 }
1575
1576 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
1577 self.table.resolve_ty_shallow(ty)
1578 }
1579
1580 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
1581 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
1582 }
1583
1584 fn resolve_associated_type_with_params(
1585 &mut self,
1586 inner_ty: Ty,
1587 assoc_ty: Option<TypeAliasId>,
1588 params: &[GenericArg],
1591 ) -> Ty {
1592 match assoc_ty {
1593 Some(res_assoc_ty) => {
1594 let trait_ = match res_assoc_ty.lookup(self.db).container {
1595 hir_def::ItemContainerId::TraitId(trait_) => trait_,
1596 _ => panic!("resolve_associated_type called with non-associated type"),
1597 };
1598 let ty = self.table.new_type_var();
1599 let mut param_iter = params.iter().cloned();
1600 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
1601 .push(inner_ty)
1602 .fill(|_| param_iter.next().unwrap())
1603 .build();
1604 let alias_eq = AliasEq {
1605 alias: AliasTy::Projection(ProjectionTy {
1606 associated_ty_id: to_assoc_type_id(res_assoc_ty),
1607 substitution: trait_ref.substitution.clone(),
1608 }),
1609 ty: ty.clone(),
1610 };
1611 self.push_obligation(trait_ref.cast(Interner));
1612 self.push_obligation(alias_eq.cast(Interner));
1613 ty
1614 }
1615 None => self.err_ty(),
1616 }
1617 }
1618
1619 fn resolve_variant(
1620 &mut self,
1621 node: ExprOrPatId,
1622 path: Option<&Path>,
1623 value_ns: bool,
1624 ) -> (Ty, Option<VariantId>) {
1625 let path = match path {
1626 Some(path) => path,
1627 None => return (self.err_ty(), None),
1628 };
1629 let mut ctx = TyLoweringContext::new(
1630 self.db,
1631 &self.resolver,
1632 &self.body.store,
1633 &self.diagnostics,
1634 InferenceTyDiagnosticSource::Body,
1635 self.generic_def,
1636 LifetimeElisionKind::Infer,
1637 );
1638 let mut path_ctx = ctx.at_path(path, node);
1639 let (resolution, unresolved) = if value_ns {
1640 let Some(res) = path_ctx.resolve_path_in_value_ns(HygieneId::ROOT) else {
1641 return (self.err_ty(), None);
1642 };
1643 match res {
1644 ResolveValueResult::ValueNs(value, _) => match value {
1645 ValueNs::EnumVariantId(var) => {
1646 let substs = path_ctx.substs_from_path(var.into(), true, false);
1647 drop(ctx);
1648 let ty = self.db.ty(var.lookup(self.db).parent.into());
1649 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1650 return (ty, Some(var.into()));
1651 }
1652 ValueNs::StructId(strukt) => {
1653 let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1654 drop(ctx);
1655 let ty = self.db.ty(strukt.into());
1656 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1657 return (ty, Some(strukt.into()));
1658 }
1659 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
1660 _ => {
1661 drop(ctx);
1662 return (self.err_ty(), None);
1663 }
1664 },
1665 ResolveValueResult::Partial(typens, unresolved, _) => (typens, Some(unresolved)),
1666 }
1667 } else {
1668 match path_ctx.resolve_path_in_type_ns() {
1669 Some((it, idx)) => (it, idx),
1670 None => return (self.err_ty(), None),
1671 }
1672 };
1673 return match resolution {
1674 TypeNs::AdtId(AdtId::StructId(strukt)) => {
1675 let substs = path_ctx.substs_from_path(strukt.into(), true, false);
1676 drop(ctx);
1677 let ty = self.db.ty(strukt.into());
1678 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1679 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
1680 }
1681 TypeNs::AdtId(AdtId::UnionId(u)) => {
1682 let substs = path_ctx.substs_from_path(u.into(), true, false);
1683 drop(ctx);
1684 let ty = self.db.ty(u.into());
1685 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1686 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
1687 }
1688 TypeNs::EnumVariantId(var) => {
1689 let substs = path_ctx.substs_from_path(var.into(), true, false);
1690 drop(ctx);
1691 let ty = self.db.ty(var.lookup(self.db).parent.into());
1692 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1693 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
1694 }
1695 TypeNs::SelfType(impl_id) => {
1696 let generics = crate::generics::generics(self.db, impl_id.into());
1697 let substs = generics.placeholder_subst(self.db);
1698 let mut ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
1699
1700 let Some(remaining_idx) = unresolved else {
1701 drop(ctx);
1702 let Some(mod_path) = path.mod_path() else {
1703 never!("resolver should always resolve lang item paths");
1704 return (self.err_ty(), None);
1705 };
1706 return self.resolve_variant_on_alias(ty, None, mod_path);
1707 };
1708
1709 let mut remaining_segments = path.segments().skip(remaining_idx);
1710
1711 if remaining_segments.len() >= 2 {
1712 path_ctx.ignore_last_segment();
1713 }
1714
1715 let mut tried_resolving_once = false;
1718 while let Some(current_segment) = remaining_segments.first() {
1719 if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1722 let enum_data = id.enum_variants(self.db);
1723 if let Some(variant) = enum_data.variant(current_segment.name) {
1724 return if remaining_segments.len() == 1 {
1725 (ty, Some(variant.into()))
1726 } else {
1727 (self.err_ty(), None)
1731 };
1732 }
1733 }
1734
1735 if tried_resolving_once {
1736 break;
1739 }
1740
1741 (ty, _) = path_ctx.lower_partly_resolved_path(resolution, true);
1745 tried_resolving_once = true;
1746
1747 ty = self.table.insert_type_vars(ty);
1748 ty = self.table.normalize_associated_types_in(ty);
1749 ty = self.table.resolve_ty_shallow(&ty);
1750 if ty.is_unknown() {
1751 return (self.err_ty(), None);
1752 }
1753
1754 remaining_segments = remaining_segments.skip(1);
1755 }
1756 drop(ctx);
1757
1758 let variant = ty.as_adt().and_then(|(id, _)| match id {
1759 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1760 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1761 AdtId::EnumId(_) => {
1762 None
1764 }
1765 });
1766 (ty, variant)
1767 }
1768 TypeNs::TypeAliasId(it) => {
1769 let Some(mod_path) = path.mod_path() else {
1770 never!("resolver should always resolve lang item paths");
1771 return (self.err_ty(), None);
1772 };
1773 let substs = path_ctx.substs_from_path_segment(it.into(), true, None, false);
1774 drop(ctx);
1775 let ty = self.db.ty(it.into());
1776 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1777
1778 self.resolve_variant_on_alias(ty, unresolved, mod_path)
1779 }
1780 TypeNs::AdtSelfType(_) => {
1781 (self.err_ty(), None)
1783 }
1784 TypeNs::GenericParam(_) => {
1785 (self.err_ty(), None)
1787 }
1788 TypeNs::AdtId(AdtId::EnumId(_))
1789 | TypeNs::BuiltinType(_)
1790 | TypeNs::TraitId(_)
1791 | TypeNs::ModuleId(_) => {
1792 (self.err_ty(), None)
1794 }
1795 };
1796
1797 fn forbid_unresolved_segments(
1798 result: (Ty, Option<VariantId>),
1799 unresolved: Option<usize>,
1800 ) -> (Ty, Option<VariantId>) {
1801 if unresolved.is_none() {
1802 result
1803 } else {
1804 (TyKind::Error.intern(Interner), None)
1806 }
1807 }
1808 }
1809
1810 fn resolve_variant_on_alias(
1811 &mut self,
1812 ty: Ty,
1813 unresolved: Option<usize>,
1814 path: &ModPath,
1815 ) -> (Ty, Option<VariantId>) {
1816 let remaining = unresolved.map(|it| path.segments()[it..].len()).filter(|it| it > &0);
1817 let ty = match ty.kind(Interner) {
1818 TyKind::Alias(AliasTy::Projection(proj_ty)) => {
1819 let ty = self.table.normalize_projection_ty(proj_ty.clone());
1820 self.table.resolve_ty_shallow(&ty)
1821 }
1822 _ => ty,
1823 };
1824 match remaining {
1825 None => {
1826 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
1827 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1828 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1829 AdtId::EnumId(_) => {
1830 None
1832 }
1833 });
1834 (ty, variant)
1835 }
1836 Some(1) => {
1837 let segment = path.segments().last().unwrap();
1838 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1840 let enum_data = enum_id.enum_variants(self.db);
1841 if let Some(variant) = enum_data.variant(segment) {
1842 return (ty, Some(variant.into()));
1843 }
1844 }
1845 (self.err_ty(), None)
1847 }
1848 Some(_) => {
1849 (self.err_ty(), None)
1851 }
1852 }
1853 }
1854
1855 fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
1856 let krate = self.resolver.krate();
1857 lang_item(self.db, krate, item)
1858 }
1859
1860 fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
1861 trait_.trait_items(self.db).associated_type_by_name(&Name::new_symbol_root(sym::Output))
1862 }
1863
1864 fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {
1865 self.resolve_lang_item(lang)?.as_trait()
1866 }
1867
1868 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
1869 self.resolve_output_on(self.resolve_lang_trait(LangItem::Neg)?)
1870 }
1871
1872 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
1873 self.resolve_output_on(self.resolve_lang_trait(LangItem::Not)?)
1874 }
1875
1876 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
1877 let ItemContainerId::TraitId(trait_) = self
1878 .resolve_lang_item(LangItem::IntoFutureIntoFuture)?
1879 .as_function()?
1880 .lookup(self.db)
1881 .container
1882 else {
1883 return None;
1884 };
1885 self.resolve_output_on(trait_)
1886 }
1887
1888 fn resolve_boxed_box(&self) -> Option<AdtId> {
1889 let struct_ = self.resolve_lang_item(LangItem::OwnedBox)?.as_struct()?;
1890 Some(struct_.into())
1891 }
1892
1893 fn resolve_range_full(&self) -> Option<AdtId> {
1894 let struct_ = self.resolve_lang_item(LangItem::RangeFull)?.as_struct()?;
1895 Some(struct_.into())
1896 }
1897
1898 fn resolve_range(&self) -> Option<AdtId> {
1899 let struct_ = self.resolve_lang_item(LangItem::Range)?.as_struct()?;
1900 Some(struct_.into())
1901 }
1902
1903 fn resolve_range_inclusive(&self) -> Option<AdtId> {
1904 let struct_ = self.resolve_lang_item(LangItem::RangeInclusiveStruct)?.as_struct()?;
1905 Some(struct_.into())
1906 }
1907
1908 fn resolve_range_from(&self) -> Option<AdtId> {
1909 let struct_ = self.resolve_lang_item(LangItem::RangeFrom)?.as_struct()?;
1910 Some(struct_.into())
1911 }
1912
1913 fn resolve_range_to(&self) -> Option<AdtId> {
1914 let struct_ = self.resolve_lang_item(LangItem::RangeTo)?.as_struct()?;
1915 Some(struct_.into())
1916 }
1917
1918 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
1919 let struct_ = self.resolve_lang_item(LangItem::RangeToInclusive)?.as_struct()?;
1920 Some(struct_.into())
1921 }
1922
1923 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
1924 self.resolve_output_on(self.resolve_lang_trait(LangItem::Index)?)
1925 }
1926
1927 fn resolve_va_list(&self) -> Option<AdtId> {
1928 let struct_ = self.resolve_lang_item(LangItem::VaList)?.as_struct()?;
1929 Some(struct_.into())
1930 }
1931
1932 fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
1933 let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
1934 if b_traits.peek().is_some() {
1935 Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
1936 } else {
1937 Either::Right(&self.traits_in_scope)
1938 }
1939 }
1940}
1941
1942#[derive(Clone, PartialEq, Eq, Debug)]
1945pub(crate) enum Expectation {
1946 None,
1947 HasType(Ty),
1948 #[allow(dead_code)]
1949 Castable(Ty),
1950 RValueLikeUnsized(Ty),
1951}
1952
1953impl Expectation {
1954 fn has_type(ty: Ty) -> Self {
1957 if ty.is_unknown() {
1958 Expectation::None
1960 } else {
1961 Expectation::HasType(ty)
1962 }
1963 }
1964
1965 fn rvalue_hint(ctx: &mut InferenceContext<'_>, ty: Ty) -> Self {
1986 match ctx.struct_tail_without_normalization(ty.clone()).kind(Interner) {
1987 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
1988 _ => Expectation::has_type(ty),
1989 }
1990 }
1991
1992 fn none() -> Self {
1994 Expectation::None
1995 }
1996
1997 fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1998 match self {
1999 Expectation::None => Expectation::None,
2000 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
2001 Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
2002 Expectation::RValueLikeUnsized(t) => {
2003 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
2004 }
2005 }
2006 }
2007
2008 fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2009 match self.resolve(table) {
2010 Expectation::None => None,
2011 Expectation::HasType(t)
2012 | Expectation::Castable(t)
2013 | Expectation::RValueLikeUnsized(t) => Some(t),
2014 }
2015 }
2016
2017 fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
2018 match self {
2019 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
2020 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
2021 None
2022 }
2023 }
2024 }
2025
2026 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
2027 self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
2028 }
2029
2030 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
2048 match self {
2049 Expectation::HasType(ety) => {
2050 let ety = table.resolve_ty_shallow(ety);
2051 if ety.is_ty_var() { Expectation::None } else { Expectation::HasType(ety) }
2052 }
2053 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
2054 _ => Expectation::None,
2055 }
2056 }
2057}
2058
2059#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
2060enum Diverges {
2061 Maybe,
2062 Always,
2063}
2064
2065impl Diverges {
2066 fn is_always(self) -> bool {
2067 self == Diverges::Always
2068 }
2069}
2070
2071impl std::ops::BitAnd for Diverges {
2072 type Output = Self;
2073 fn bitand(self, other: Self) -> Self {
2074 std::cmp::min(self, other)
2075 }
2076}
2077
2078impl std::ops::BitOr for Diverges {
2079 type Output = Self;
2080 fn bitor(self, other: Self) -> Self {
2081 std::cmp::max(self, other)
2082 }
2083}
2084
2085impl std::ops::BitAndAssign for Diverges {
2086 fn bitand_assign(&mut self, other: Self) {
2087 *self = *self & other;
2088 }
2089}
2090
2091impl std::ops::BitOrAssign for Diverges {
2092 fn bitor_assign(&mut self, other: Self) {
2093 *self = *self | other;
2094 }
2095}
2096
2097struct UnknownMismatch<'db>(&'db dyn HirDatabase);
2102impl chalk_ir::zip::Zipper<Interner> for UnknownMismatch<'_> {
2103 fn zip_tys(&mut self, variance: Variance, a: &Ty, b: &Ty) -> chalk_ir::Fallible<()> {
2104 let zip_substs = |this: &mut Self,
2105 variances,
2106 sub_a: &Substitution,
2107 sub_b: &Substitution| {
2108 this.zip_substs(variance, variances, sub_a.as_slice(Interner), sub_b.as_slice(Interner))
2109 };
2110 match (a.kind(Interner), b.kind(Interner)) {
2111 (TyKind::Adt(id_a, sub_a), TyKind::Adt(id_b, sub_b)) if id_a == id_b => zip_substs(
2112 self,
2113 Some(self.unification_database().adt_variance(*id_a)),
2114 sub_a,
2115 sub_b,
2116 )?,
2117 (
2118 TyKind::AssociatedType(assoc_ty_a, sub_a),
2119 TyKind::AssociatedType(assoc_ty_b, sub_b),
2120 ) if assoc_ty_a == assoc_ty_b => zip_substs(self, None, sub_a, sub_b)?,
2121 (TyKind::Tuple(arity_a, sub_a), TyKind::Tuple(arity_b, sub_b))
2122 if arity_a == arity_b =>
2123 {
2124 zip_substs(self, None, sub_a, sub_b)?
2125 }
2126 (TyKind::OpaqueType(opaque_ty_a, sub_a), TyKind::OpaqueType(opaque_ty_b, sub_b))
2127 if opaque_ty_a == opaque_ty_b =>
2128 {
2129 zip_substs(self, None, sub_a, sub_b)?
2130 }
2131 (TyKind::Slice(ty_a), TyKind::Slice(ty_b)) => self.zip_tys(variance, ty_a, ty_b)?,
2132 (TyKind::FnDef(fn_def_a, sub_a), TyKind::FnDef(fn_def_b, sub_b))
2133 if fn_def_a == fn_def_b =>
2134 {
2135 zip_substs(
2136 self,
2137 Some(self.unification_database().fn_def_variance(*fn_def_a)),
2138 sub_a,
2139 sub_b,
2140 )?
2141 }
2142 (TyKind::Ref(mutability_a, _, ty_a), TyKind::Ref(mutability_b, _, ty_b))
2143 if mutability_a == mutability_b =>
2144 {
2145 self.zip_tys(variance, ty_a, ty_b)?
2146 }
2147 (TyKind::Raw(mutability_a, ty_a), TyKind::Raw(mutability_b, ty_b))
2148 if mutability_a == mutability_b =>
2149 {
2150 self.zip_tys(variance, ty_a, ty_b)?
2151 }
2152 (TyKind::Array(ty_a, const_a), TyKind::Array(ty_b, const_b)) if const_a == const_b => {
2153 self.zip_tys(variance, ty_a, ty_b)?
2154 }
2155 (TyKind::Closure(id_a, sub_a), TyKind::Closure(id_b, sub_b)) if id_a == id_b => {
2156 zip_substs(self, None, sub_a, sub_b)?
2157 }
2158 (TyKind::Coroutine(coroutine_a, sub_a), TyKind::Coroutine(coroutine_b, sub_b))
2159 if coroutine_a == coroutine_b =>
2160 {
2161 zip_substs(self, None, sub_a, sub_b)?
2162 }
2163 (
2164 TyKind::CoroutineWitness(coroutine_a, sub_a),
2165 TyKind::CoroutineWitness(coroutine_b, sub_b),
2166 ) if coroutine_a == coroutine_b => zip_substs(self, None, sub_a, sub_b)?,
2167 (TyKind::Function(fn_ptr_a), TyKind::Function(fn_ptr_b))
2168 if fn_ptr_a.sig == fn_ptr_b.sig && fn_ptr_a.num_binders == fn_ptr_b.num_binders =>
2169 {
2170 zip_substs(self, None, &fn_ptr_a.substitution.0, &fn_ptr_b.substitution.0)?
2171 }
2172 (TyKind::Error, TyKind::Error) => (),
2173 (TyKind::Error, _)
2174 | (_, TyKind::Error)
2175 | (TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _), _)
2176 | (_, TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(_, _)) => {
2177 return Err(chalk_ir::NoSolution);
2178 }
2179 _ => (),
2180 }
2181
2182 Ok(())
2183 }
2184
2185 fn zip_lifetimes(&mut self, _: Variance, _: &Lifetime, _: &Lifetime) -> chalk_ir::Fallible<()> {
2186 Ok(())
2187 }
2188
2189 fn zip_consts(&mut self, _: Variance, _: &Const, _: &Const) -> chalk_ir::Fallible<()> {
2190 Ok(())
2191 }
2192
2193 fn zip_binders<T>(
2194 &mut self,
2195 variance: Variance,
2196 a: &Binders<T>,
2197 b: &Binders<T>,
2198 ) -> chalk_ir::Fallible<()>
2199 where
2200 T: Clone
2201 + HasInterner<Interner = Interner>
2202 + chalk_ir::zip::Zip<Interner>
2203 + TypeFoldable<Interner>,
2204 {
2205 chalk_ir::zip::Zip::zip_with(self, variance, a.skip_binders(), b.skip_binders())
2206 }
2207
2208 fn interner(&self) -> Interner {
2209 Interner
2210 }
2211
2212 fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> {
2213 &self.0
2214 }
2215}