1 //! Type inference, i.e. the process of walking through the code and determining
2 //! the type of each expression and pattern.
3 //!
4 //! For type inference, compare the implementations in rustc (the various
5 //! check_* methods in rustc_hir_analysis/check/mod.rs are a good entry point) and
6 //! IntelliJ-Rust (org.rust.lang.core.types.infer). Our entry point for
7 //! inference here is the `infer` function, which infers the types of all
8 //! expressions in a given function.
9 //!
10 //! During inference, types (i.e. the `Ty` struct) can contain type 'variables'
11 //! which represent currently unknown types; as we walk through the expressions,
12 //! we might determine that certain variables need to be equal to each other, or
13 //! to certain types. To record this, we use the union-find implementation from
14 //! the `ena` crate, which is extracted from rustc.
15
16 use std::{convert::identity, ops::Index};
17
18 use chalk_ir::{
19 cast::Cast, fold::TypeFoldable, interner::HasInterner, DebruijnIndex, Mutability, Safety,
20 Scalar, TyKind, TypeFlags,
21 };
22 use either::Either;
23 use hir_def::{
24 body::Body,
25 builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
26 data::{ConstData, StaticData},
27 hir::LabelId,
28 hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, PatId},
29 lang_item::{LangItem, LangItemTarget},
30 layout::Integer,
31 path::{ModPath, Path},
32 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
33 type_ref::TypeRef,
34 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, ItemContainerId, Lookup,
35 TraitId, TypeAliasId, VariantId,
36 };
37 use hir_expand::name::{name, Name};
38 use la_arena::{ArenaMap, Entry};
39 use rustc_hash::{FxHashMap, FxHashSet};
40 use stdx::{always, never};
41 use triomphe::Arc;
42
43 use crate::{
44 db::HirDatabase,
45 fold_tys,
46 infer::coerce::CoerceMany,
47 lower::ImplTraitLoweringMode,
48 static_lifetime, to_assoc_type_id,
49 traits::FnTrait,
50 utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
51 AliasEq, AliasTy, ClosureId, DomainGoal, GenericArg, Goal, ImplTraitId, InEnvironment,
52 Interner, ProjectionTy, RpitId, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
53 };
54
55 // This lint has a false positive here. See the link below for details.
56 //
57 // https://github.com/rust-lang/rust/issues/57411
58 #[allow(unreachable_pub)]
59 pub use coerce::could_coerce;
60 #[allow(unreachable_pub)]
61 pub use unify::could_unify;
62
63 pub(crate) use self::closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
64
65 pub(crate) mod unify;
66 mod path;
67 mod expr;
68 mod pat;
69 mod coerce;
70 pub(crate) mod closure;
71 mod mutability;
72
73 /// The entry point of type inference.
infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult>74 pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
75 let _p = profile::span("infer_query");
76 let resolver = def.resolver(db.upcast());
77 let body = db.body(def);
78 let mut ctx = InferenceContext::new(db, def, &body, resolver);
79
80 match def {
81 DefWithBodyId::FunctionId(f) => {
82 ctx.collect_fn(f);
83 }
84 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
85 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
86 DefWithBodyId::VariantId(v) => {
87 ctx.return_ty = TyBuilder::builtin(match db.enum_data(v.parent).variant_body_type() {
88 hir_def::layout::IntegerType::Pointer(signed) => match signed {
89 true => BuiltinType::Int(BuiltinInt::Isize),
90 false => BuiltinType::Uint(BuiltinUint::Usize),
91 },
92 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
93 true => BuiltinType::Int(match size {
94 Integer::I8 => BuiltinInt::I8,
95 Integer::I16 => BuiltinInt::I16,
96 Integer::I32 => BuiltinInt::I32,
97 Integer::I64 => BuiltinInt::I64,
98 Integer::I128 => BuiltinInt::I128,
99 }),
100 false => BuiltinType::Uint(match size {
101 Integer::I8 => BuiltinUint::U8,
102 Integer::I16 => BuiltinUint::U16,
103 Integer::I32 => BuiltinUint::U32,
104 Integer::I64 => BuiltinUint::U64,
105 Integer::I128 => BuiltinUint::U128,
106 }),
107 },
108 });
109 }
110 DefWithBodyId::InTypeConstId(c) => {
111 // FIXME(const-generic-body): We should not get the return type in this way.
112 ctx.return_ty = c
113 .lookup(db.upcast())
114 .thing
115 .box_any()
116 .downcast::<InTypeConstIdMetadata>()
117 .unwrap()
118 .0;
119 }
120 }
121
122 ctx.infer_body();
123
124 ctx.infer_mut_body();
125
126 ctx.infer_closures();
127
128 Arc::new(ctx.resolve_all())
129 }
130
131 /// Fully normalize all the types found within `ty` in context of `owner` body definition.
132 ///
133 /// This is appropriate to use only after type-check: it assumes
134 /// that normalization will succeed, for example.
normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment>, ty: Ty) -> Ty135 pub(crate) fn normalize(db: &dyn HirDatabase, trait_env: Arc<TraitEnvironment>, ty: Ty) -> Ty {
136 // FIXME: TypeFlags::HAS_CT_PROJECTION is not implemented in chalk, so TypeFlags::HAS_PROJECTION only
137 // works for the type case, so we check array unconditionally. Remove the array part
138 // when the bug in chalk becomes fixed.
139 if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION)
140 && !matches!(ty.kind(Interner), TyKind::Array(..))
141 {
142 return ty;
143 }
144 let mut table = unify::InferenceTable::new(db, trait_env);
145
146 let ty_with_vars = table.normalize_associated_types_in(ty);
147 table.resolve_obligations_as_possible();
148 table.propagate_diverging_flag();
149 table.resolve_completely(ty_with_vars)
150 }
151
152 /// Binding modes inferred for patterns.
153 /// <https://doc.rust-lang.org/reference/patterns.html#binding-modes>
154 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
155 pub enum BindingMode {
156 Move,
157 Ref(Mutability),
158 }
159
160 impl BindingMode {
convert(annotation: BindingAnnotation) -> BindingMode161 fn convert(annotation: BindingAnnotation) -> BindingMode {
162 match annotation {
163 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
164 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
165 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
166 }
167 }
168 }
169
170 impl Default for BindingMode {
default() -> Self171 fn default() -> Self {
172 BindingMode::Move
173 }
174 }
175
176 #[derive(Debug)]
177 pub(crate) struct InferOk<T> {
178 value: T,
179 goals: Vec<InEnvironment<Goal>>,
180 }
181
182 impl<T> InferOk<T> {
map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U>183 fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
184 InferOk { value: f(self.value), goals: self.goals }
185 }
186 }
187
188 #[derive(Debug)]
189 pub(crate) struct TypeError;
190 pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
191
192 #[derive(Debug, PartialEq, Eq, Clone)]
193 pub enum InferenceDiagnostic {
194 NoSuchField {
195 expr: ExprId,
196 },
197 PrivateField {
198 expr: ExprId,
199 field: FieldId,
200 },
201 PrivateAssocItem {
202 id: ExprOrPatId,
203 item: AssocItemId,
204 },
205 UnresolvedField {
206 expr: ExprId,
207 receiver: Ty,
208 name: Name,
209 method_with_same_name_exists: bool,
210 },
211 UnresolvedMethodCall {
212 expr: ExprId,
213 receiver: Ty,
214 name: Name,
215 /// Contains the type the field resolves to
216 field_with_same_name: Option<Ty>,
217 },
218 // FIXME: This should be emitted in body lowering
219 BreakOutsideOfLoop {
220 expr: ExprId,
221 is_break: bool,
222 bad_value_break: bool,
223 },
224 MismatchedArgCount {
225 call_expr: ExprId,
226 expected: usize,
227 found: usize,
228 },
229 ExpectedFunction {
230 call_expr: ExprId,
231 found: Ty,
232 },
233 TypedHole {
234 expr: ExprId,
235 expected: Ty,
236 },
237 }
238
239 /// A mismatch between an expected and an inferred type.
240 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
241 pub struct TypeMismatch {
242 pub expected: Ty,
243 pub actual: Ty,
244 }
245
246 #[derive(Clone, PartialEq, Eq, Debug)]
247 struct InternedStandardTypes {
248 unknown: Ty,
249 bool_: Ty,
250 unit: Ty,
251 never: Ty,
252 }
253
254 impl Default for InternedStandardTypes {
default() -> Self255 fn default() -> Self {
256 InternedStandardTypes {
257 unknown: TyKind::Error.intern(Interner),
258 bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
259 unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
260 never: TyKind::Never.intern(Interner),
261 }
262 }
263 }
264 /// Represents coercing a value to a different type of value.
265 ///
266 /// We transform values by following a number of `Adjust` steps in order.
267 /// See the documentation on variants of `Adjust` for more details.
268 ///
269 /// Here are some common scenarios:
270 ///
271 /// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
272 /// Here the pointer will be dereferenced N times (where a dereference can
273 /// happen to raw or borrowed pointers or any smart pointer which implements
274 /// Deref, including Box<_>). The types of dereferences is given by
275 /// `autoderefs`. It can then be auto-referenced zero or one times, indicated
276 /// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
277 /// `false`.
278 ///
279 /// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
280 /// with a thin pointer, deref a number of times, unsize the underlying data,
281 /// then autoref. The 'unsize' phase may change a fixed length array to a
282 /// dynamically sized one, a concrete object to a trait object, or statically
283 /// sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
284 /// represented by:
285 ///
286 /// ```
287 /// Deref(None) -> [i32; 4],
288 /// Borrow(AutoBorrow::Ref) -> &[i32; 4],
289 /// Unsize -> &[i32],
290 /// ```
291 ///
292 /// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
293 /// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
294 /// The autoderef and -ref are the same as in the above example, but the type
295 /// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
296 /// the underlying conversions from `[i32; 4]` to `[i32]`.
297 ///
298 /// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
299 /// that case, we have the pointer we need coming in, so there are no
300 /// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
301 /// At some point, of course, `Box` should move out of the compiler, in which
302 /// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
303 /// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
304 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
305 pub struct Adjustment {
306 pub kind: Adjust,
307 pub target: Ty,
308 }
309
310 impl Adjustment {
borrow(m: Mutability, ty: Ty) -> Self311 pub fn borrow(m: Mutability, ty: Ty) -> Self {
312 let ty = TyKind::Ref(m, static_lifetime(), ty).intern(Interner);
313 Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(m)), target: ty }
314 }
315 }
316
317 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
318 pub enum Adjust {
319 /// Go from ! to any type.
320 NeverToAny,
321 /// Dereference once, producing a place.
322 Deref(Option<OverloadedDeref>),
323 /// Take the address and produce either a `&` or `*` pointer.
324 Borrow(AutoBorrow),
325 Pointer(PointerCast),
326 }
327
328 /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
329 /// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
330 /// The target type is `U` in both cases, with the region and mutability
331 /// being those shared by both the receiver and the returned reference.
332 ///
333 /// Mutability is `None` when we are not sure.
334 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
335 pub struct OverloadedDeref(pub Option<Mutability>);
336
337 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
338 pub enum AutoBorrow {
339 /// Converts from T to &T.
340 Ref(Mutability),
341 /// Converts from T to *T.
342 RawPtr(Mutability),
343 }
344
345 impl AutoBorrow {
mutability(self) -> Mutability346 fn mutability(self) -> Mutability {
347 let (AutoBorrow::Ref(m) | AutoBorrow::RawPtr(m)) = self;
348 m
349 }
350 }
351
352 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
353 pub enum PointerCast {
354 /// Go from a fn-item type to a fn-pointer type.
355 ReifyFnPointer,
356
357 /// Go from a safe fn pointer to an unsafe fn pointer.
358 UnsafeFnPointer,
359
360 /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
361 /// It cannot convert a closure that requires unsafe.
362 ClosureFnPointer(Safety),
363
364 /// Go from a mut raw pointer to a const raw pointer.
365 MutToConstPointer,
366
367 #[allow(dead_code)]
368 /// Go from `*const [T; N]` to `*const T`
369 ArrayToPointer,
370
371 /// Unsize a pointer/reference value, e.g., `&[T; n]` to
372 /// `&[T]`. Note that the source could be a thin or fat pointer.
373 /// This will do things like convert thin pointers to fat
374 /// pointers, or convert structs containing thin pointers to
375 /// structs containing fat pointers, or convert between fat
376 /// pointers. We don't store the details of how the transform is
377 /// done (in fact, we don't know that, because it might depend on
378 /// the precise type parameters). We just store the target
379 /// type. Codegen backends and miri figure out what has to be done
380 /// based on the precise source/target type at hand.
381 Unsize,
382 }
383
384 /// The result of type inference: A mapping from expressions and patterns to types.
385 ///
386 /// When you add a field that stores types (including `Substitution` and the like), don't forget
387 /// `resolve_completely()`'ing them in `InferenceContext::resolve_all()`. Inference variables must
388 /// not appear in the final inference result.
389 #[derive(Clone, PartialEq, Eq, Debug, Default)]
390 pub struct InferenceResult {
391 /// For each method call expr, records the function it resolves to.
392 method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
393 /// For each field access expr, records the field it resolves to.
394 field_resolutions: FxHashMap<ExprId, FieldId>,
395 /// For each struct literal or pattern, records the variant it resolves to.
396 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
397 /// For each associated item record what it resolves to
398 assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
399 pub diagnostics: Vec<InferenceDiagnostic>,
400 pub type_of_expr: ArenaMap<ExprId, Ty>,
401 /// For each pattern record the type it resolves to.
402 ///
403 /// **Note**: When a pattern type is resolved it may still contain
404 /// unresolved or missing subpatterns or subpatterns of mismatched types.
405 pub type_of_pat: ArenaMap<PatId, Ty>,
406 pub type_of_binding: ArenaMap<BindingId, Ty>,
407 pub type_of_rpit: ArenaMap<RpitId, Ty>,
408 /// Type of the result of `.into_iter()` on the for. `ExprId` is the one of the whole for loop.
409 pub type_of_for_iterator: FxHashMap<ExprId, Ty>,
410 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
411 /// Interned common types to return references to.
412 standard_types: InternedStandardTypes,
413 /// Stores the types which were implicitly dereferenced in pattern binding modes.
414 pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
415 pub binding_modes: ArenaMap<BindingId, BindingMode>,
416 pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>,
417 pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
418 // FIXME: remove this field
419 pub mutated_bindings_in_closure: FxHashSet<BindingId>,
420 }
421
422 impl InferenceResult {
method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)>423 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
424 self.method_resolutions.get(&expr).cloned()
425 }
field_resolution(&self, expr: ExprId) -> Option<FieldId>426 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
427 self.field_resolutions.get(&expr).copied()
428 }
variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId>429 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
430 self.variant_resolutions.get(&id.into()).copied()
431 }
variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId>432 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
433 self.variant_resolutions.get(&id.into()).copied()
434 }
assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)>435 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
436 self.assoc_resolutions.get(&id.into()).cloned()
437 }
assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)>438 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
439 self.assoc_resolutions.get(&id.into()).cloned()
440 }
type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch>441 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
442 self.type_mismatches.get(&expr.into())
443 }
type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch>444 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
445 self.type_mismatches.get(&pat.into())
446 }
type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch)>447 pub fn type_mismatches(&self) -> impl Iterator<Item = (ExprOrPatId, &TypeMismatch)> {
448 self.type_mismatches.iter().map(|(expr_or_pat, mismatch)| (*expr_or_pat, mismatch))
449 }
expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)>450 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
451 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
452 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
453 _ => None,
454 })
455 }
closure_info(&self, closure: &ClosureId) -> &(Vec<CapturedItem>, FnTrait)456 pub fn closure_info(&self, closure: &ClosureId) -> &(Vec<CapturedItem>, FnTrait) {
457 self.closure_info.get(closure).unwrap()
458 }
459 }
460
461 impl Index<ExprId> for InferenceResult {
462 type Output = Ty;
463
index(&self, expr: ExprId) -> &Ty464 fn index(&self, expr: ExprId) -> &Ty {
465 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
466 }
467 }
468
469 impl Index<PatId> for InferenceResult {
470 type Output = Ty;
471
index(&self, pat: PatId) -> &Ty472 fn index(&self, pat: PatId) -> &Ty {
473 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
474 }
475 }
476
477 impl Index<BindingId> for InferenceResult {
478 type Output = Ty;
479
index(&self, b: BindingId) -> &Ty480 fn index(&self, b: BindingId) -> &Ty {
481 self.type_of_binding.get(b).unwrap_or(&self.standard_types.unknown)
482 }
483 }
484
485 /// The inference context contains all information needed during type inference.
486 #[derive(Clone, Debug)]
487 pub(crate) struct InferenceContext<'a> {
488 pub(crate) db: &'a dyn HirDatabase,
489 pub(crate) owner: DefWithBodyId,
490 pub(crate) body: &'a Body,
491 pub(crate) resolver: Resolver,
492 table: unify::InferenceTable<'a>,
493 /// The traits in scope, disregarding block modules. This is used for caching purposes.
494 traits_in_scope: FxHashSet<TraitId>,
495 pub(crate) result: InferenceResult,
496 /// The return type of the function being inferred, the closure or async block if we're
497 /// currently within one.
498 ///
499 /// We might consider using a nested inference context for checking
500 /// closures so we can swap all shared things out at once.
501 return_ty: Ty,
502 /// If `Some`, this stores coercion information for returned
503 /// expressions. If `None`, this is in a context where return is
504 /// inappropriate, such as a const expression.
505 return_coercion: Option<CoerceMany>,
506 /// The resume type and the yield type, respectively, of the generator being inferred.
507 resume_yield_tys: Option<(Ty, Ty)>,
508 diverges: Diverges,
509 breakables: Vec<BreakableContext>,
510
511 // fields related to closure capture
512 current_captures: Vec<CapturedItemWithoutTy>,
513 current_closure: Option<ClosureId>,
514 /// Stores the list of closure ids that need to be analyzed before this closure. See the
515 /// comment on `InferenceContext::sort_closures`
516 closure_dependencies: FxHashMap<ClosureId, Vec<ClosureId>>,
517 deferred_closures: FxHashMap<ClosureId, Vec<(Ty, Ty, Vec<Ty>, ExprId)>>,
518 }
519
520 #[derive(Clone, Debug)]
521 struct BreakableContext {
522 /// Whether this context contains at least one break expression.
523 may_break: bool,
524 /// The coercion target of the context.
525 coerce: Option<CoerceMany>,
526 /// The optional label of the context.
527 label: Option<LabelId>,
528 kind: BreakableKind,
529 }
530
531 #[derive(Clone, Debug)]
532 enum BreakableKind {
533 Block,
534 Loop,
535 /// A border is something like an async block, closure etc. Anything that prevents
536 /// breaking/continuing through
537 Border,
538 }
539
find_breakable<'c>( ctxs: &'c mut [BreakableContext], label: Option<LabelId>, ) -> Option<&'c mut BreakableContext>540 fn find_breakable<'c>(
541 ctxs: &'c mut [BreakableContext],
542 label: Option<LabelId>,
543 ) -> Option<&'c mut BreakableContext> {
544 let mut ctxs = ctxs
545 .iter_mut()
546 .rev()
547 .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
548 match label {
549 Some(_) => ctxs.find(|ctx| ctx.label == label),
550 None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
551 }
552 }
553
find_continuable<'c>( ctxs: &'c mut [BreakableContext], label: Option<LabelId>, ) -> Option<&'c mut BreakableContext>554 fn find_continuable<'c>(
555 ctxs: &'c mut [BreakableContext],
556 label: Option<LabelId>,
557 ) -> Option<&'c mut BreakableContext> {
558 match label {
559 Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
560 None => find_breakable(ctxs, label),
561 }
562 }
563
564 impl<'a> InferenceContext<'a> {
new( db: &'a dyn HirDatabase, owner: DefWithBodyId, body: &'a Body, resolver: Resolver, ) -> Self565 fn new(
566 db: &'a dyn HirDatabase,
567 owner: DefWithBodyId,
568 body: &'a Body,
569 resolver: Resolver,
570 ) -> Self {
571 let trait_env = db.trait_environment_for_body(owner);
572 InferenceContext {
573 result: InferenceResult::default(),
574 table: unify::InferenceTable::new(db, trait_env),
575 return_ty: TyKind::Error.intern(Interner), // set in collect_* calls
576 resume_yield_tys: None,
577 return_coercion: None,
578 db,
579 owner,
580 body,
581 traits_in_scope: resolver.traits_in_scope(db.upcast()),
582 resolver,
583 diverges: Diverges::Maybe,
584 breakables: Vec::new(),
585 current_captures: vec![],
586 current_closure: None,
587 deferred_closures: FxHashMap::default(),
588 closure_dependencies: FxHashMap::default(),
589 }
590 }
591
592 // FIXME: This function should be private in module. It is currently only used in the consteval, since we need
593 // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you
594 // used this function for another workaround, mention it here. If you really need this function and believe that
595 // there is no problem in it being `pub(crate)`, remove this comment.
resolve_all(self) -> InferenceResult596 pub(crate) fn resolve_all(self) -> InferenceResult {
597 let InferenceContext { mut table, mut result, .. } = self;
598 // Destructure every single field so whenever new fields are added to `InferenceResult` we
599 // don't forget to handle them here.
600 let InferenceResult {
601 method_resolutions,
602 field_resolutions: _,
603 variant_resolutions: _,
604 assoc_resolutions,
605 diagnostics,
606 type_of_expr,
607 type_of_pat,
608 type_of_binding,
609 type_of_rpit,
610 type_of_for_iterator,
611 type_mismatches,
612 standard_types: _,
613 pat_adjustments,
614 binding_modes: _,
615 expr_adjustments,
616 // Types in `closure_info` have already been `resolve_completely()`'d during
617 // `InferenceContext::infer_closures()` (in `HirPlace::ty()` specifically), so no need
618 // to resolve them here.
619 closure_info: _,
620 mutated_bindings_in_closure: _,
621 } = &mut result;
622
623 table.fallback_if_possible();
624
625 // FIXME resolve obligations as well (use Guidance if necessary)
626 table.resolve_obligations_as_possible();
627
628 // make sure diverging type variables are marked as such
629 table.propagate_diverging_flag();
630 for ty in type_of_expr.values_mut() {
631 *ty = table.resolve_completely(ty.clone());
632 }
633 for ty in type_of_pat.values_mut() {
634 *ty = table.resolve_completely(ty.clone());
635 }
636 for ty in type_of_binding.values_mut() {
637 *ty = table.resolve_completely(ty.clone());
638 }
639 for ty in type_of_rpit.values_mut() {
640 *ty = table.resolve_completely(ty.clone());
641 }
642 for ty in type_of_for_iterator.values_mut() {
643 *ty = table.resolve_completely(ty.clone());
644 }
645 for mismatch in type_mismatches.values_mut() {
646 mismatch.expected = table.resolve_completely(mismatch.expected.clone());
647 mismatch.actual = table.resolve_completely(mismatch.actual.clone());
648 }
649 diagnostics.retain_mut(|diagnostic| {
650 use InferenceDiagnostic::*;
651 match diagnostic {
652 ExpectedFunction { found: ty, .. }
653 | UnresolvedField { receiver: ty, .. }
654 | UnresolvedMethodCall { receiver: ty, .. } => {
655 *ty = table.resolve_completely(ty.clone());
656 // FIXME: Remove this when we are on par with rustc in terms of inference
657 if ty.contains_unknown() {
658 return false;
659 }
660
661 if let UnresolvedMethodCall { field_with_same_name, .. } = diagnostic {
662 if let Some(ty) = field_with_same_name {
663 *ty = table.resolve_completely(ty.clone());
664 if ty.contains_unknown() {
665 *field_with_same_name = None;
666 }
667 }
668 }
669 }
670 TypedHole { expected: ty, .. } => {
671 *ty = table.resolve_completely(ty.clone());
672 }
673 _ => (),
674 }
675 true
676 });
677 for (_, subst) in method_resolutions.values_mut() {
678 *subst = table.resolve_completely(subst.clone());
679 }
680 for (_, subst) in assoc_resolutions.values_mut() {
681 *subst = table.resolve_completely(subst.clone());
682 }
683 for adjustment in expr_adjustments.values_mut().flatten() {
684 adjustment.target = table.resolve_completely(adjustment.target.clone());
685 }
686 for adjustment in pat_adjustments.values_mut().flatten() {
687 *adjustment = table.resolve_completely(adjustment.clone());
688 }
689 result
690 }
691
collect_const(&mut self, data: &ConstData)692 fn collect_const(&mut self, data: &ConstData) {
693 self.return_ty = self.make_ty(&data.type_ref);
694 }
695
collect_static(&mut self, data: &StaticData)696 fn collect_static(&mut self, data: &StaticData) {
697 self.return_ty = self.make_ty(&data.type_ref);
698 }
699
collect_fn(&mut self, func: FunctionId)700 fn collect_fn(&mut self, func: FunctionId) {
701 let data = self.db.function_data(func);
702 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, func.into())
703 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
704 let mut param_tys =
705 data.params.iter().map(|type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
706 // Check if function contains a va_list, if it does then we append it to the parameter types
707 // that are collected from the function data
708 if data.is_varargs() {
709 let va_list_ty = match self.resolve_va_list() {
710 Some(va_list) => TyBuilder::adt(self.db, va_list)
711 .fill_with_defaults(self.db, || self.table.new_type_var())
712 .build(),
713 None => self.err_ty(),
714 };
715
716 param_tys.push(va_list_ty)
717 }
718 for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
719 let ty = self.insert_type_vars(ty);
720 let ty = self.normalize_associated_types_in(ty);
721
722 self.infer_top_pat(*pat, &ty);
723 }
724 let return_ty = &*data.ret_type;
725
726 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into())
727 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
728 let return_ty = ctx.lower_ty(return_ty);
729 let return_ty = self.insert_type_vars(return_ty);
730
731 let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) {
732 // RPIT opaque types use substitution of their parent function.
733 let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
734 let result =
735 self.insert_inference_vars_for_rpit(return_ty, rpits.clone(), fn_placeholders);
736 let rpits = rpits.skip_binders();
737 for (id, _) in rpits.impl_traits.iter() {
738 if let Entry::Vacant(e) = self.result.type_of_rpit.entry(id) {
739 never!("Missed RPIT in `insert_inference_vars_for_rpit`");
740 e.insert(TyKind::Error.intern(Interner));
741 }
742 }
743 result
744 } else {
745 return_ty
746 };
747
748 self.return_ty = self.normalize_associated_types_in(return_ty);
749 self.return_coercion = Some(CoerceMany::new(self.return_ty.clone()));
750 }
751
insert_inference_vars_for_rpit<T>( &mut self, t: T, rpits: Arc<chalk_ir::Binders<crate::ReturnTypeImplTraits>>, fn_placeholders: Substitution, ) -> T where T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,752 fn insert_inference_vars_for_rpit<T>(
753 &mut self,
754 t: T,
755 rpits: Arc<chalk_ir::Binders<crate::ReturnTypeImplTraits>>,
756 fn_placeholders: Substitution,
757 ) -> T
758 where
759 T: crate::HasInterner<Interner = Interner> + crate::TypeFoldable<Interner>,
760 {
761 fold_tys(
762 t,
763 |ty, _| {
764 let opaque_ty_id = match ty.kind(Interner) {
765 TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
766 _ => return ty,
767 };
768 let idx = match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
769 ImplTraitId::ReturnTypeImplTrait(_, idx) => idx,
770 _ => unreachable!(),
771 };
772 let bounds = (*rpits)
773 .map_ref(|rpits| rpits.impl_traits[idx].bounds.map_ref(|it| it.into_iter()));
774 let var = self.table.new_type_var();
775 let var_subst = Substitution::from1(Interner, var.clone());
776 for bound in bounds {
777 let predicate =
778 bound.map(|it| it.cloned()).substitute(Interner, &fn_placeholders);
779 let (var_predicate, binders) =
780 predicate.substitute(Interner, &var_subst).into_value_and_skipped_binders();
781 always!(binders.is_empty(Interner)); // quantified where clauses not yet handled
782 let var_predicate = self.insert_inference_vars_for_rpit(
783 var_predicate,
784 rpits.clone(),
785 fn_placeholders.clone(),
786 );
787 self.push_obligation(var_predicate.cast(Interner));
788 }
789 self.result.type_of_rpit.insert(idx, var.clone());
790 var
791 },
792 DebruijnIndex::INNERMOST,
793 )
794 }
795
infer_body(&mut self)796 fn infer_body(&mut self) {
797 match self.return_coercion {
798 Some(_) => self.infer_return(self.body.body_expr),
799 None => {
800 _ = self.infer_expr_coerce(
801 self.body.body_expr,
802 &Expectation::has_type(self.return_ty.clone()),
803 )
804 }
805 }
806 }
807
write_expr_ty(&mut self, expr: ExprId, ty: Ty)808 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
809 self.result.type_of_expr.insert(expr, ty);
810 }
811
write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>)812 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>) {
813 self.result.expr_adjustments.insert(expr, adjustments);
814 }
815
write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution)816 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
817 self.result.method_resolutions.insert(expr, (func, subst));
818 }
819
write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId)820 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
821 self.result.variant_resolutions.insert(id, variant);
822 }
823
write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution)824 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
825 self.result.assoc_resolutions.insert(id, (item, subs));
826 }
827
write_pat_ty(&mut self, pat: PatId, ty: Ty)828 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
829 self.result.type_of_pat.insert(pat, ty);
830 }
831
write_binding_ty(&mut self, id: BindingId, ty: Ty)832 fn write_binding_ty(&mut self, id: BindingId, ty: Ty) {
833 self.result.type_of_binding.insert(id, ty);
834 }
835
push_diagnostic(&mut self, diagnostic: InferenceDiagnostic)836 fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) {
837 self.result.diagnostics.push(diagnostic);
838 }
839
make_ty(&mut self, type_ref: &TypeRef) -> Ty840 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
841 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
842 let ty = ctx.lower_ty(type_ref);
843 let ty = self.insert_type_vars(ty);
844 self.normalize_associated_types_in(ty)
845 }
846
err_ty(&self) -> Ty847 fn err_ty(&self) -> Ty {
848 self.result.standard_types.unknown.clone()
849 }
850
851 /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
insert_type_vars_shallow(&mut self, ty: Ty) -> Ty852 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
853 self.table.insert_type_vars_shallow(ty)
854 }
855
insert_type_vars<T>(&mut self, ty: T) -> T where T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,856 fn insert_type_vars<T>(&mut self, ty: T) -> T
857 where
858 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
859 {
860 self.table.insert_type_vars(ty)
861 }
862
push_obligation(&mut self, o: DomainGoal)863 fn push_obligation(&mut self, o: DomainGoal) {
864 self.table.register_obligation(o.cast(Interner));
865 }
866
unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool867 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
868 let ty1 = ty1
869 .clone()
870 .try_fold_with(
871 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
872 DebruijnIndex::INNERMOST,
873 )
874 .unwrap();
875 let ty2 = ty2
876 .clone()
877 .try_fold_with(
878 &mut UnevaluatedConstEvaluatorFolder { db: self.db },
879 DebruijnIndex::INNERMOST,
880 )
881 .unwrap();
882 self.table.unify(&ty1, &ty2)
883 }
884
885 /// Attempts to returns the deeply last field of nested structures, but
886 /// does not apply any normalization in its search. Returns the same type
887 /// if input `ty` is not a structure at all.
struct_tail_without_normalization(&mut self, ty: Ty) -> Ty888 fn struct_tail_without_normalization(&mut self, ty: Ty) -> Ty {
889 self.struct_tail_with_normalize(ty, identity)
890 }
891
892 /// Returns the deeply last field of nested structures, or the same type if
893 /// not a structure at all. Corresponds to the only possible unsized field,
894 /// and its type can be used to determine unsizing strategy.
895 ///
896 /// This is parameterized over the normalization strategy (i.e. how to
897 /// handle `<T as Trait>::Assoc` and `impl Trait`); pass the identity
898 /// function to indicate no normalization should take place.
struct_tail_with_normalize( &mut self, mut ty: Ty, mut normalize: impl FnMut(Ty) -> Ty, ) -> Ty899 fn struct_tail_with_normalize(
900 &mut self,
901 mut ty: Ty,
902 mut normalize: impl FnMut(Ty) -> Ty,
903 ) -> Ty {
904 // FIXME: fetch the limit properly
905 let recursion_limit = 10;
906 for iteration in 0.. {
907 if iteration > recursion_limit {
908 return self.err_ty();
909 }
910 match ty.kind(Interner) {
911 TyKind::Adt(chalk_ir::AdtId(hir_def::AdtId::StructId(struct_id)), substs) => {
912 match self.db.field_types((*struct_id).into()).values().next_back().cloned() {
913 Some(field) => {
914 ty = field.substitute(Interner, substs);
915 }
916 None => break,
917 }
918 }
919 TyKind::Adt(..) => break,
920 TyKind::Tuple(_, substs) => {
921 match substs
922 .as_slice(Interner)
923 .split_last()
924 .and_then(|(last_ty, _)| last_ty.ty(Interner))
925 {
926 Some(last_ty) => ty = last_ty.clone(),
927 None => break,
928 }
929 }
930 TyKind::Alias(..) => {
931 let normalized = normalize(ty.clone());
932 if ty == normalized {
933 return ty;
934 } else {
935 ty = normalized;
936 }
937 }
938 _ => break,
939 }
940 }
941 ty
942 }
943
944 /// Recurses through the given type, normalizing associated types mentioned
945 /// in it by replacing them by type variables and registering obligations to
946 /// resolve later. This should be done once for every type we get from some
947 /// type annotation (e.g. from a let type annotation, field type or function
948 /// call). `make_ty` handles this already, but e.g. for field types we need
949 /// to do it as well.
normalize_associated_types_in<T>(&mut self, ty: T) -> T where T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,950 fn normalize_associated_types_in<T>(&mut self, ty: T) -> T
951 where
952 T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
953 {
954 self.table.normalize_associated_types_in(ty)
955 }
956
resolve_ty_shallow(&mut self, ty: &Ty) -> Ty957 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
958 self.table.resolve_ty_shallow(ty)
959 }
960
resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty961 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
962 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
963 }
964
resolve_associated_type_with_params( &mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>, params: &[GenericArg], ) -> Ty965 fn resolve_associated_type_with_params(
966 &mut self,
967 inner_ty: Ty,
968 assoc_ty: Option<TypeAliasId>,
969 // FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
970 // handled when we support them.
971 params: &[GenericArg],
972 ) -> Ty {
973 match assoc_ty {
974 Some(res_assoc_ty) => {
975 let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container {
976 hir_def::ItemContainerId::TraitId(trait_) => trait_,
977 _ => panic!("resolve_associated_type called with non-associated type"),
978 };
979 let ty = self.table.new_type_var();
980 let mut param_iter = params.iter().cloned();
981 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
982 .push(inner_ty)
983 .fill(|_| param_iter.next().unwrap())
984 .build();
985 let alias_eq = AliasEq {
986 alias: AliasTy::Projection(ProjectionTy {
987 associated_ty_id: to_assoc_type_id(res_assoc_ty),
988 substitution: trait_ref.substitution.clone(),
989 }),
990 ty: ty.clone(),
991 };
992 self.push_obligation(trait_ref.cast(Interner));
993 self.push_obligation(alias_eq.cast(Interner));
994 ty
995 }
996 None => self.err_ty(),
997 }
998 }
999
resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>)1000 fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>) {
1001 let path = match path {
1002 Some(path) => path,
1003 None => return (self.err_ty(), None),
1004 };
1005 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
1006 let (resolution, unresolved) = if value_ns {
1007 match self.resolver.resolve_path_in_value_ns(self.db.upcast(), path) {
1008 Some(ResolveValueResult::ValueNs(value)) => match value {
1009 ValueNs::EnumVariantId(var) => {
1010 let substs = ctx.substs_from_path(path, var.into(), true);
1011 let ty = self.db.ty(var.parent.into());
1012 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1013 return (ty, Some(var.into()));
1014 }
1015 ValueNs::StructId(strukt) => {
1016 let substs = ctx.substs_from_path(path, strukt.into(), true);
1017 let ty = self.db.ty(strukt.into());
1018 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1019 return (ty, Some(strukt.into()));
1020 }
1021 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
1022 _ => return (self.err_ty(), None),
1023 },
1024 Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
1025 None => return (self.err_ty(), None),
1026 }
1027 } else {
1028 match self.resolver.resolve_path_in_type_ns(self.db.upcast(), path) {
1029 Some(it) => it,
1030 None => return (self.err_ty(), None),
1031 }
1032 };
1033 let Some(mod_path) = path.mod_path() else {
1034 never!("resolver should always resolve lang item paths");
1035 return (self.err_ty(), None);
1036 };
1037 return match resolution {
1038 TypeNs::AdtId(AdtId::StructId(strukt)) => {
1039 let substs = ctx.substs_from_path(path, strukt.into(), true);
1040 let ty = self.db.ty(strukt.into());
1041 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1042 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
1043 }
1044 TypeNs::AdtId(AdtId::UnionId(u)) => {
1045 let substs = ctx.substs_from_path(path, u.into(), true);
1046 let ty = self.db.ty(u.into());
1047 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1048 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
1049 }
1050 TypeNs::EnumVariantId(var) => {
1051 let substs = ctx.substs_from_path(path, var.into(), true);
1052 let ty = self.db.ty(var.parent.into());
1053 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
1054 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
1055 }
1056 TypeNs::SelfType(impl_id) => {
1057 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
1058 let substs = generics.placeholder_subst(self.db);
1059 let mut ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
1060
1061 let Some(mut remaining_idx) = unresolved else {
1062 return self.resolve_variant_on_alias(ty, None, mod_path);
1063 };
1064
1065 let mut remaining_segments = path.segments().skip(remaining_idx);
1066
1067 // We need to try resolving unresolved segments one by one because each may resolve
1068 // to a projection, which `TyLoweringContext` cannot handle on its own.
1069 while !remaining_segments.is_empty() {
1070 let resolved_segment = path.segments().get(remaining_idx - 1).unwrap();
1071 let current_segment = remaining_segments.take(1);
1072
1073 // If we can resolve to an enum variant, it takes priority over associated type
1074 // of the same name.
1075 if let Some((AdtId::EnumId(id), _)) = ty.as_adt() {
1076 let enum_data = self.db.enum_data(id);
1077 let name = current_segment.first().unwrap().name;
1078 if let Some(local_id) = enum_data.variant(name) {
1079 let variant = EnumVariantId { parent: id, local_id };
1080 return if remaining_segments.len() == 1 {
1081 (ty, Some(variant.into()))
1082 } else {
1083 // We still have unresolved paths, but enum variants never have
1084 // associated types!
1085 (self.err_ty(), None)
1086 };
1087 }
1088 }
1089
1090 // `lower_partly_resolved_path()` returns `None` as type namespace unless
1091 // `remaining_segments` is empty, which is never the case here. We don't know
1092 // which namespace the new `ty` is in until normalized anyway.
1093 (ty, _) = ctx.lower_partly_resolved_path(
1094 resolution,
1095 resolved_segment,
1096 current_segment,
1097 false,
1098 );
1099
1100 ty = self.table.insert_type_vars(ty);
1101 ty = self.table.normalize_associated_types_in(ty);
1102 ty = self.table.resolve_ty_shallow(&ty);
1103 if ty.is_unknown() {
1104 return (self.err_ty(), None);
1105 }
1106
1107 // FIXME(inherent_associated_types): update `resolution` based on `ty` here.
1108 remaining_idx += 1;
1109 remaining_segments = remaining_segments.skip(1);
1110 }
1111
1112 let variant = ty.as_adt().and_then(|(id, _)| match id {
1113 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1114 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1115 AdtId::EnumId(_) => {
1116 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1117 None
1118 }
1119 });
1120 (ty, variant)
1121 }
1122 TypeNs::TypeAliasId(it) => {
1123 let container = it.lookup(self.db.upcast()).container;
1124 let parent_subst = match container {
1125 ItemContainerId::TraitId(id) => {
1126 let subst = TyBuilder::subst_for_def(self.db, id, None)
1127 .fill_with_inference_vars(&mut self.table)
1128 .build();
1129 Some(subst)
1130 }
1131 // Type aliases do not exist in impls.
1132 _ => None,
1133 };
1134 let ty = TyBuilder::def_ty(self.db, it.into(), parent_subst)
1135 .fill_with_inference_vars(&mut self.table)
1136 .build();
1137 self.resolve_variant_on_alias(ty, unresolved, mod_path)
1138 }
1139 TypeNs::AdtSelfType(_) => {
1140 // FIXME this could happen in array size expressions, once we're checking them
1141 (self.err_ty(), None)
1142 }
1143 TypeNs::GenericParam(_) => {
1144 // FIXME potentially resolve assoc type
1145 (self.err_ty(), None)
1146 }
1147 TypeNs::AdtId(AdtId::EnumId(_))
1148 | TypeNs::BuiltinType(_)
1149 | TypeNs::TraitId(_)
1150 | TypeNs::TraitAliasId(_) => {
1151 // FIXME diagnostic
1152 (self.err_ty(), None)
1153 }
1154 };
1155
1156 fn forbid_unresolved_segments(
1157 result: (Ty, Option<VariantId>),
1158 unresolved: Option<usize>,
1159 ) -> (Ty, Option<VariantId>) {
1160 if unresolved.is_none() {
1161 result
1162 } else {
1163 // FIXME diagnostic
1164 (TyKind::Error.intern(Interner), None)
1165 }
1166 }
1167 }
1168
resolve_variant_on_alias( &mut self, ty: Ty, unresolved: Option<usize>, path: &ModPath, ) -> (Ty, Option<VariantId>)1169 fn resolve_variant_on_alias(
1170 &mut self,
1171 ty: Ty,
1172 unresolved: Option<usize>,
1173 path: &ModPath,
1174 ) -> (Ty, Option<VariantId>) {
1175 let remaining = unresolved.map(|x| path.segments()[x..].len()).filter(|x| x > &0);
1176 match remaining {
1177 None => {
1178 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
1179 AdtId::StructId(s) => Some(VariantId::StructId(s)),
1180 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
1181 AdtId::EnumId(_) => {
1182 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
1183 None
1184 }
1185 });
1186 (ty, variant)
1187 }
1188 Some(1) => {
1189 let segment = path.segments().last().unwrap();
1190 // this could be an enum variant or associated type
1191 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
1192 let enum_data = self.db.enum_data(enum_id);
1193 if let Some(local_id) = enum_data.variant(segment) {
1194 let variant = EnumVariantId { parent: enum_id, local_id };
1195 return (ty, Some(variant.into()));
1196 }
1197 }
1198 // FIXME potentially resolve assoc type
1199 (self.err_ty(), None)
1200 }
1201 Some(_) => {
1202 // FIXME diagnostic
1203 (self.err_ty(), None)
1204 }
1205 }
1206 }
1207
resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget>1208 fn resolve_lang_item(&self, item: LangItem) -> Option<LangItemTarget> {
1209 let krate = self.resolver.krate();
1210 self.db.lang_item(krate, item)
1211 }
1212
resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId>1213 fn resolve_output_on(&self, trait_: TraitId) -> Option<TypeAliasId> {
1214 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
1215 }
1216
resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId>1217 fn resolve_lang_trait(&self, lang: LangItem) -> Option<TraitId> {
1218 self.resolve_lang_item(lang)?.as_trait()
1219 }
1220
resolve_ops_neg_output(&self) -> Option<TypeAliasId>1221 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
1222 self.resolve_output_on(self.resolve_lang_trait(LangItem::Neg)?)
1223 }
1224
resolve_ops_not_output(&self) -> Option<TypeAliasId>1225 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
1226 self.resolve_output_on(self.resolve_lang_trait(LangItem::Not)?)
1227 }
1228
resolve_future_future_output(&self) -> Option<TypeAliasId>1229 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
1230 let ItemContainerId::TraitId(trait_) = self
1231 .resolve_lang_item(LangItem::IntoFutureIntoFuture)?
1232 .as_function()?
1233 .lookup(self.db.upcast())
1234 .container
1235 else { return None };
1236 self.resolve_output_on(trait_)
1237 }
1238
resolve_boxed_box(&self) -> Option<AdtId>1239 fn resolve_boxed_box(&self) -> Option<AdtId> {
1240 let struct_ = self.resolve_lang_item(LangItem::OwnedBox)?.as_struct()?;
1241 Some(struct_.into())
1242 }
1243
resolve_range_full(&self) -> Option<AdtId>1244 fn resolve_range_full(&self) -> Option<AdtId> {
1245 let struct_ = self.resolve_lang_item(LangItem::RangeFull)?.as_struct()?;
1246 Some(struct_.into())
1247 }
1248
resolve_range(&self) -> Option<AdtId>1249 fn resolve_range(&self) -> Option<AdtId> {
1250 let struct_ = self.resolve_lang_item(LangItem::Range)?.as_struct()?;
1251 Some(struct_.into())
1252 }
1253
resolve_range_inclusive(&self) -> Option<AdtId>1254 fn resolve_range_inclusive(&self) -> Option<AdtId> {
1255 let struct_ = self.resolve_lang_item(LangItem::RangeInclusiveStruct)?.as_struct()?;
1256 Some(struct_.into())
1257 }
1258
resolve_range_from(&self) -> Option<AdtId>1259 fn resolve_range_from(&self) -> Option<AdtId> {
1260 let struct_ = self.resolve_lang_item(LangItem::RangeFrom)?.as_struct()?;
1261 Some(struct_.into())
1262 }
1263
resolve_range_to(&self) -> Option<AdtId>1264 fn resolve_range_to(&self) -> Option<AdtId> {
1265 let struct_ = self.resolve_lang_item(LangItem::RangeTo)?.as_struct()?;
1266 Some(struct_.into())
1267 }
1268
resolve_range_to_inclusive(&self) -> Option<AdtId>1269 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
1270 let struct_ = self.resolve_lang_item(LangItem::RangeToInclusive)?.as_struct()?;
1271 Some(struct_.into())
1272 }
1273
resolve_ops_index_output(&self) -> Option<TypeAliasId>1274 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
1275 self.resolve_output_on(self.resolve_lang_trait(LangItem::Index)?)
1276 }
1277
resolve_va_list(&self) -> Option<AdtId>1278 fn resolve_va_list(&self) -> Option<AdtId> {
1279 let struct_ = self.resolve_lang_item(LangItem::VaList)?.as_struct()?;
1280 Some(struct_.into())
1281 }
1282
get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>>1283 fn get_traits_in_scope(&self) -> Either<FxHashSet<TraitId>, &FxHashSet<TraitId>> {
1284 let mut b_traits = self.resolver.traits_in_scope_from_block_scopes().peekable();
1285 if b_traits.peek().is_some() {
1286 Either::Left(self.traits_in_scope.iter().copied().chain(b_traits).collect())
1287 } else {
1288 Either::Right(&self.traits_in_scope)
1289 }
1290 }
1291 }
1292
1293 /// When inferring an expression, we propagate downward whatever type hint we
1294 /// are able in the form of an `Expectation`.
1295 #[derive(Clone, PartialEq, Eq, Debug)]
1296 pub(crate) enum Expectation {
1297 None,
1298 HasType(Ty),
1299 #[allow(dead_code)]
1300 Castable(Ty),
1301 RValueLikeUnsized(Ty),
1302 }
1303
1304 impl Expectation {
1305 /// The expectation that the type of the expression needs to equal the given
1306 /// type.
has_type(ty: Ty) -> Self1307 fn has_type(ty: Ty) -> Self {
1308 if ty.is_unknown() {
1309 // FIXME: get rid of this?
1310 Expectation::None
1311 } else {
1312 Expectation::HasType(ty)
1313 }
1314 }
1315
1316 /// The following explanation is copied straight from rustc:
1317 /// Provides an expectation for an rvalue expression given an *optional*
1318 /// hint, which is not required for type safety (the resulting type might
1319 /// be checked higher up, as is the case with `&expr` and `box expr`), but
1320 /// is useful in determining the concrete type.
1321 ///
1322 /// The primary use case is where the expected type is a fat pointer,
1323 /// like `&[isize]`. For example, consider the following statement:
1324 ///
1325 /// let x: &[isize] = &[1, 2, 3];
1326 ///
1327 /// In this case, the expected type for the `&[1, 2, 3]` expression is
1328 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
1329 /// expectation `ExpectHasType([isize])`, that would be too strong --
1330 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
1331 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
1332 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
1333 /// which still is useful, because it informs integer literals and the like.
1334 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
1335 /// for examples of where this comes up,.
rvalue_hint(ctx: &mut InferenceContext<'_>, ty: Ty) -> Self1336 fn rvalue_hint(ctx: &mut InferenceContext<'_>, ty: Ty) -> Self {
1337 match ctx.struct_tail_without_normalization(ty.clone()).kind(Interner) {
1338 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
1339 _ => Expectation::has_type(ty),
1340 }
1341 }
1342
1343 /// This expresses no expectation on the type.
none() -> Self1344 fn none() -> Self {
1345 Expectation::None
1346 }
1347
resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation1348 fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1349 match self {
1350 Expectation::None => Expectation::None,
1351 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
1352 Expectation::Castable(t) => Expectation::Castable(table.resolve_ty_shallow(t)),
1353 Expectation::RValueLikeUnsized(t) => {
1354 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
1355 }
1356 }
1357 }
1358
to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty>1359 fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1360 match self.resolve(table) {
1361 Expectation::None => None,
1362 Expectation::HasType(t)
1363 | Expectation::Castable(t)
1364 | Expectation::RValueLikeUnsized(t) => Some(t),
1365 }
1366 }
1367
only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty>1368 fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1369 match self {
1370 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
1371 Expectation::Castable(_) | Expectation::RValueLikeUnsized(_) | Expectation::None => {
1372 None
1373 }
1374 }
1375 }
1376
coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty1377 fn coercion_target_type(&self, table: &mut unify::InferenceTable<'_>) -> Ty {
1378 self.only_has_type(table).unwrap_or_else(|| table.new_type_var())
1379 }
1380
1381 /// Comment copied from rustc:
1382 /// Disregard "castable to" expectations because they
1383 /// can lead us astray. Consider for example `if cond
1384 /// {22} else {c} as u8` -- if we propagate the
1385 /// "castable to u8" constraint to 22, it will pick the
1386 /// type 22u8, which is overly constrained (c might not
1387 /// be a u8). In effect, the problem is that the
1388 /// "castable to" expectation is not the tightest thing
1389 /// we can say, so we want to drop it in this case.
1390 /// The tightest thing we can say is "must unify with
1391 /// else branch". Note that in the case of a "has type"
1392 /// constraint, this limitation does not hold.
1393 ///
1394 /// If the expected type is just a type variable, then don't use
1395 /// an expected type. Otherwise, we might write parts of the type
1396 /// when checking the 'then' block which are incompatible with the
1397 /// 'else' branch.
adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation1398 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1399 match self {
1400 Expectation::HasType(ety) => {
1401 let ety = table.resolve_ty_shallow(ety);
1402 if !ety.is_ty_var() {
1403 Expectation::HasType(ety)
1404 } else {
1405 Expectation::None
1406 }
1407 }
1408 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
1409 _ => Expectation::None,
1410 }
1411 }
1412 }
1413
1414 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
1415 enum Diverges {
1416 Maybe,
1417 Always,
1418 }
1419
1420 impl Diverges {
is_always(self) -> bool1421 fn is_always(self) -> bool {
1422 self == Diverges::Always
1423 }
1424 }
1425
1426 impl std::ops::BitAnd for Diverges {
1427 type Output = Self;
bitand(self, other: Self) -> Self1428 fn bitand(self, other: Self) -> Self {
1429 std::cmp::min(self, other)
1430 }
1431 }
1432
1433 impl std::ops::BitOr for Diverges {
1434 type Output = Self;
bitor(self, other: Self) -> Self1435 fn bitor(self, other: Self) -> Self {
1436 std::cmp::max(self, other)
1437 }
1438 }
1439
1440 impl std::ops::BitAndAssign for Diverges {
bitand_assign(&mut self, other: Self)1441 fn bitand_assign(&mut self, other: Self) {
1442 *self = *self & other;
1443 }
1444 }
1445
1446 impl std::ops::BitOrAssign for Diverges {
bitor_assign(&mut self, other: Self)1447 fn bitor_assign(&mut self, other: Self) {
1448 *self = *self | other;
1449 }
1450 }
1451