]> git.proxmox.com Git - rustc.git/blame - src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / src / tools / rust-analyzer / crates / hir-ty / src / infer.rs
CommitLineData
064997fb
FG
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
2b03887a 5//! check_* methods in rustc_hir_analysis/check/mod.rs are a good entry point) and
064997fb
FG
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
16use std::ops::Index;
17use std::sync::Arc;
18
19use chalk_ir::{cast::Cast, ConstValue, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
20use hir_def::{
21 body::Body,
f25598a0 22 builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
064997fb 23 data::{ConstData, StaticData},
f25598a0 24 expr::{BindingAnnotation, ExprId, ExprOrPatId, PatId},
064997fb 25 lang_item::LangItemTarget,
f25598a0 26 layout::Integer,
064997fb
FG
27 path::{path, Path},
28 resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
29 type_ref::TypeRef,
2b03887a
FG
30 AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, FunctionId, HasModule,
31 ItemContainerId, Lookup, TraitId, TypeAliasId, VariantId,
064997fb
FG
32};
33use hir_expand::name::{name, Name};
34use itertools::Either;
35use la_arena::ArenaMap;
36use rustc_hash::FxHashMap;
f25598a0 37use stdx::always;
064997fb
FG
38
39use crate::{
40 db::HirDatabase, fold_tys, fold_tys_and_consts, infer::coerce::CoerceMany,
41 lower::ImplTraitLoweringMode, to_assoc_type_id, AliasEq, AliasTy, Const, DomainGoal,
42 GenericArg, Goal, ImplTraitId, InEnvironment, Interner, ProjectionTy, Substitution,
43 TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind,
44};
45
46// This lint has a false positive here. See the link below for details.
47//
48// https://github.com/rust-lang/rust/issues/57411
49#[allow(unreachable_pub)]
50pub use coerce::could_coerce;
51#[allow(unreachable_pub)]
52pub use unify::could_unify;
53
54pub(crate) mod unify;
55mod path;
56mod expr;
57mod pat;
58mod coerce;
59mod closure;
60
61/// The entry point of type inference.
62pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
63 let _p = profile::span("infer_query");
64 let resolver = def.resolver(db.upcast());
65 let body = db.body(def);
66 let mut ctx = InferenceContext::new(db, def, &body, resolver);
67
68 match def {
69 DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
70 DefWithBodyId::FunctionId(f) => ctx.collect_fn(f),
71 DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
2b03887a
FG
72 DefWithBodyId::VariantId(v) => {
73 ctx.return_ty = TyBuilder::builtin(match db.enum_data(v.parent).variant_body_type() {
f25598a0
FG
74 hir_def::layout::IntegerType::Pointer(signed) => match signed {
75 true => BuiltinType::Int(BuiltinInt::Isize),
76 false => BuiltinType::Uint(BuiltinUint::Usize),
77 },
78 hir_def::layout::IntegerType::Fixed(size, signed) => match signed {
79 true => BuiltinType::Int(match size {
80 Integer::I8 => BuiltinInt::I8,
81 Integer::I16 => BuiltinInt::I16,
82 Integer::I32 => BuiltinInt::I32,
83 Integer::I64 => BuiltinInt::I64,
84 Integer::I128 => BuiltinInt::I128,
85 }),
86 false => BuiltinType::Uint(match size {
87 Integer::I8 => BuiltinUint::U8,
88 Integer::I16 => BuiltinUint::U16,
89 Integer::I32 => BuiltinUint::U32,
90 Integer::I64 => BuiltinUint::U64,
91 Integer::I128 => BuiltinUint::U128,
92 }),
93 },
2b03887a
FG
94 });
95 }
064997fb
FG
96 }
97
98 ctx.infer_body();
99
100 Arc::new(ctx.resolve_all())
101}
102
103/// Fully normalize all the types found within `ty` in context of `owner` body definition.
104///
105/// This is appropriate to use only after type-check: it assumes
106/// that normalization will succeed, for example.
107pub(crate) fn normalize(db: &dyn HirDatabase, owner: DefWithBodyId, ty: Ty) -> Ty {
108 if !ty.data(Interner).flags.intersects(TypeFlags::HAS_PROJECTION) {
109 return ty;
110 }
111 let krate = owner.module(db.upcast()).krate();
112 let trait_env = owner
113 .as_generic_def_id()
114 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
115 let mut table = unify::InferenceTable::new(db, trait_env);
116
117 let ty_with_vars = table.normalize_associated_types_in(ty);
118 table.resolve_obligations_as_possible();
119 table.propagate_diverging_flag();
120 table.resolve_completely(ty_with_vars)
121}
122
064997fb
FG
123/// Binding modes inferred for patterns.
124/// <https://doc.rust-lang.org/reference/patterns.html#binding-modes>
125#[derive(Copy, Clone, Debug, Eq, PartialEq)]
126pub enum BindingMode {
127 Move,
128 Ref(Mutability),
129}
130
131impl BindingMode {
132 fn convert(annotation: BindingAnnotation) -> BindingMode {
133 match annotation {
134 BindingAnnotation::Unannotated | BindingAnnotation::Mutable => BindingMode::Move,
135 BindingAnnotation::Ref => BindingMode::Ref(Mutability::Not),
136 BindingAnnotation::RefMut => BindingMode::Ref(Mutability::Mut),
137 }
138 }
139}
140
141impl Default for BindingMode {
142 fn default() -> Self {
143 BindingMode::Move
144 }
145}
146
147/// Used to generalize patterns and assignee expressions.
148trait PatLike: Into<ExprOrPatId> + Copy {
149 type BindingMode: Copy;
150
151 fn infer(
152 this: &mut InferenceContext<'_>,
153 id: Self,
154 expected_ty: &Ty,
155 default_bm: Self::BindingMode,
156 ) -> Ty;
157}
158
159impl PatLike for ExprId {
160 type BindingMode = ();
161
162 fn infer(
163 this: &mut InferenceContext<'_>,
164 id: Self,
165 expected_ty: &Ty,
166 _: Self::BindingMode,
167 ) -> Ty {
168 this.infer_assignee_expr(id, expected_ty)
169 }
170}
171
172impl PatLike for PatId {
173 type BindingMode = BindingMode;
174
175 fn infer(
176 this: &mut InferenceContext<'_>,
177 id: Self,
178 expected_ty: &Ty,
179 default_bm: Self::BindingMode,
180 ) -> Ty {
181 this.infer_pat(id, expected_ty, default_bm)
182 }
183}
184
185#[derive(Debug)]
186pub(crate) struct InferOk<T> {
187 value: T,
188 goals: Vec<InEnvironment<Goal>>,
189}
190
191impl<T> InferOk<T> {
192 fn map<U>(self, f: impl FnOnce(T) -> U) -> InferOk<U> {
193 InferOk { value: f(self.value), goals: self.goals }
194 }
195}
196
197#[derive(Debug)]
198pub(crate) struct TypeError;
199pub(crate) type InferResult<T> = Result<InferOk<T>, TypeError>;
200
201#[derive(Debug, PartialEq, Eq, Clone)]
202pub enum InferenceDiagnostic {
203 NoSuchField { expr: ExprId },
f25598a0
FG
204 PrivateField { expr: ExprId, field: FieldId },
205 PrivateAssocItem { id: ExprOrPatId, item: AssocItemId },
f2b60f7d 206 BreakOutsideOfLoop { expr: ExprId, is_break: bool },
064997fb
FG
207 MismatchedArgCount { call_expr: ExprId, expected: usize, found: usize },
208}
209
210/// A mismatch between an expected and an inferred type.
211#[derive(Clone, PartialEq, Eq, Debug, Hash)]
212pub struct TypeMismatch {
213 pub expected: Ty,
214 pub actual: Ty,
215}
216
217#[derive(Clone, PartialEq, Eq, Debug)]
218struct InternedStandardTypes {
219 unknown: Ty,
220 bool_: Ty,
221 unit: Ty,
222}
223
224impl Default for InternedStandardTypes {
225 fn default() -> Self {
226 InternedStandardTypes {
227 unknown: TyKind::Error.intern(Interner),
228 bool_: TyKind::Scalar(Scalar::Bool).intern(Interner),
229 unit: TyKind::Tuple(0, Substitution::empty(Interner)).intern(Interner),
230 }
231 }
232}
233/// Represents coercing a value to a different type of value.
234///
235/// We transform values by following a number of `Adjust` steps in order.
236/// See the documentation on variants of `Adjust` for more details.
237///
238/// Here are some common scenarios:
239///
240/// 1. The simplest cases are where a pointer is not adjusted fat vs thin.
241/// Here the pointer will be dereferenced N times (where a dereference can
242/// happen to raw or borrowed pointers or any smart pointer which implements
243/// Deref, including Box<_>). The types of dereferences is given by
244/// `autoderefs`. It can then be auto-referenced zero or one times, indicated
245/// by `autoref`, to either a raw or borrowed pointer. In these cases unsize is
246/// `false`.
247///
248/// 2. A thin-to-fat coercion involves unsizing the underlying data. We start
249/// with a thin pointer, deref a number of times, unsize the underlying data,
250/// then autoref. The 'unsize' phase may change a fixed length array to a
251/// dynamically sized one, a concrete object to a trait object, or statically
252/// sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
253/// represented by:
254///
255/// ```
256/// Deref(None) -> [i32; 4],
257/// Borrow(AutoBorrow::Ref) -> &[i32; 4],
258/// Unsize -> &[i32],
259/// ```
260///
261/// Note that for a struct, the 'deep' unsizing of the struct is not recorded.
262/// E.g., `struct Foo<T> { x: T }` we can coerce &Foo<[i32; 4]> to &Foo<[i32]>
263/// The autoderef and -ref are the same as in the above example, but the type
264/// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
265/// the underlying conversions from `[i32; 4]` to `[i32]`.
266///
267/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
268/// that case, we have the pointer we need coming in, so there are no
269/// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
270/// At some point, of course, `Box` should move out of the compiler, in which
271/// case this is analogous to transforming a struct. E.g., Box<[i32; 4]> ->
272/// Box<[i32]> is an `Adjust::Unsize` with the target `Box<[i32]>`.
273#[derive(Clone, Debug, PartialEq, Eq, Hash)]
274pub struct Adjustment {
275 pub kind: Adjust,
276 pub target: Ty,
277}
278
279#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
280pub enum Adjust {
281 /// Go from ! to any type.
282 NeverToAny,
283 /// Dereference once, producing a place.
284 Deref(Option<OverloadedDeref>),
285 /// Take the address and produce either a `&` or `*` pointer.
286 Borrow(AutoBorrow),
287 Pointer(PointerCast),
288}
289
290/// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
291/// call, with the signature `&'a T -> &'a U` or `&'a mut T -> &'a mut U`.
292/// The target type is `U` in both cases, with the region and mutability
293/// being those shared by both the receiver and the returned reference.
294#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
295pub struct OverloadedDeref(pub Mutability);
296
297#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
298pub enum AutoBorrow {
299 /// Converts from T to &T.
300 Ref(Mutability),
301 /// Converts from T to *T.
302 RawPtr(Mutability),
303}
304
305#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
306pub enum PointerCast {
307 /// Go from a fn-item type to a fn-pointer type.
308 ReifyFnPointer,
309
310 /// Go from a safe fn pointer to an unsafe fn pointer.
311 UnsafeFnPointer,
312
313 /// Go from a non-capturing closure to an fn pointer or an unsafe fn pointer.
314 /// It cannot convert a closure that requires unsafe.
315 ClosureFnPointer(Safety),
316
317 /// Go from a mut raw pointer to a const raw pointer.
318 MutToConstPointer,
319
320 #[allow(dead_code)]
321 /// Go from `*const [T; N]` to `*const T`
322 ArrayToPointer,
323
324 /// Unsize a pointer/reference value, e.g., `&[T; n]` to
325 /// `&[T]`. Note that the source could be a thin or fat pointer.
326 /// This will do things like convert thin pointers to fat
327 /// pointers, or convert structs containing thin pointers to
328 /// structs containing fat pointers, or convert between fat
329 /// pointers. We don't store the details of how the transform is
330 /// done (in fact, we don't know that, because it might depend on
331 /// the precise type parameters). We just store the target
332 /// type. Codegen backends and miri figure out what has to be done
333 /// based on the precise source/target type at hand.
334 Unsize,
335}
336
337/// The result of type inference: A mapping from expressions and patterns to types.
338#[derive(Clone, PartialEq, Eq, Debug, Default)]
339pub struct InferenceResult {
340 /// For each method call expr, records the function it resolves to.
341 method_resolutions: FxHashMap<ExprId, (FunctionId, Substitution)>,
342 /// For each field access expr, records the field it resolves to.
343 field_resolutions: FxHashMap<ExprId, FieldId>,
344 /// For each struct literal or pattern, records the variant it resolves to.
345 variant_resolutions: FxHashMap<ExprOrPatId, VariantId>,
346 /// For each associated item record what it resolves to
f25598a0 347 assoc_resolutions: FxHashMap<ExprOrPatId, (AssocItemId, Substitution)>,
064997fb
FG
348 pub diagnostics: Vec<InferenceDiagnostic>,
349 pub type_of_expr: ArenaMap<ExprId, Ty>,
350 /// For each pattern record the type it resolves to.
351 ///
352 /// **Note**: When a pattern type is resolved it may still contain
353 /// unresolved or missing subpatterns or subpatterns of mismatched types.
354 pub type_of_pat: ArenaMap<PatId, Ty>,
355 type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
2b03887a 356 /// Interned common types to return references to.
064997fb
FG
357 standard_types: InternedStandardTypes,
358 /// Stores the types which were implicitly dereferenced in pattern binding modes.
359 pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
360 pub pat_binding_modes: FxHashMap<PatId, BindingMode>,
361 pub expr_adjustments: FxHashMap<ExprId, Vec<Adjustment>>,
362}
363
364impl InferenceResult {
365 pub fn method_resolution(&self, expr: ExprId) -> Option<(FunctionId, Substitution)> {
366 self.method_resolutions.get(&expr).cloned()
367 }
368 pub fn field_resolution(&self, expr: ExprId) -> Option<FieldId> {
369 self.field_resolutions.get(&expr).copied()
370 }
371 pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> {
372 self.variant_resolutions.get(&id.into()).copied()
373 }
374 pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantId> {
375 self.variant_resolutions.get(&id.into()).copied()
376 }
f25598a0
FG
377 pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<(AssocItemId, Substitution)> {
378 self.assoc_resolutions.get(&id.into()).cloned()
064997fb 379 }
f25598a0
FG
380 pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<(AssocItemId, Substitution)> {
381 self.assoc_resolutions.get(&id.into()).cloned()
064997fb
FG
382 }
383 pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> {
384 self.type_mismatches.get(&expr.into())
385 }
386 pub fn type_mismatch_for_pat(&self, pat: PatId) -> Option<&TypeMismatch> {
387 self.type_mismatches.get(&pat.into())
388 }
389 pub fn expr_type_mismatches(&self) -> impl Iterator<Item = (ExprId, &TypeMismatch)> {
390 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
391 ExprOrPatId::ExprId(expr) => Some((expr, mismatch)),
392 _ => None,
393 })
394 }
395 pub fn pat_type_mismatches(&self) -> impl Iterator<Item = (PatId, &TypeMismatch)> {
396 self.type_mismatches.iter().filter_map(|(expr_or_pat, mismatch)| match *expr_or_pat {
397 ExprOrPatId::PatId(pat) => Some((pat, mismatch)),
398 _ => None,
399 })
400 }
401}
402
403impl Index<ExprId> for InferenceResult {
404 type Output = Ty;
405
406 fn index(&self, expr: ExprId) -> &Ty {
407 self.type_of_expr.get(expr).unwrap_or(&self.standard_types.unknown)
408 }
409}
410
411impl Index<PatId> for InferenceResult {
412 type Output = Ty;
413
414 fn index(&self, pat: PatId) -> &Ty {
415 self.type_of_pat.get(pat).unwrap_or(&self.standard_types.unknown)
416 }
417}
418
419/// The inference context contains all information needed during type inference.
420#[derive(Clone, Debug)]
421pub(crate) struct InferenceContext<'a> {
422 pub(crate) db: &'a dyn HirDatabase,
423 pub(crate) owner: DefWithBodyId,
424 pub(crate) body: &'a Body,
425 pub(crate) resolver: Resolver,
426 table: unify::InferenceTable<'a>,
427 trait_env: Arc<TraitEnvironment>,
428 pub(crate) result: InferenceResult,
429 /// The return type of the function being inferred, the closure or async block if we're
430 /// currently within one.
431 ///
432 /// We might consider using a nested inference context for checking
433 /// closures, but currently this is the only field that will change there,
434 /// so it doesn't make sense.
435 return_ty: Ty,
2b03887a
FG
436 /// The resume type and the yield type, respectively, of the generator being inferred.
437 resume_yield_tys: Option<(Ty, Ty)>,
064997fb
FG
438 diverges: Diverges,
439 breakables: Vec<BreakableContext>,
440}
441
442#[derive(Clone, Debug)]
443struct BreakableContext {
f2b60f7d 444 /// Whether this context contains at least one break expression.
064997fb 445 may_break: bool,
f2b60f7d 446 /// The coercion target of the context.
064997fb 447 coerce: CoerceMany,
f2b60f7d 448 /// The optional label of the context.
064997fb 449 label: Option<name::Name>,
f2b60f7d
FG
450 kind: BreakableKind,
451}
452
453#[derive(Clone, Debug)]
454enum BreakableKind {
455 Block,
456 Loop,
457 /// A border is something like an async block, closure etc. Anything that prevents
458 /// breaking/continuing through
459 Border,
064997fb
FG
460}
461
462fn find_breakable<'c>(
463 ctxs: &'c mut [BreakableContext],
464 label: Option<&name::Name>,
f2b60f7d
FG
465) -> Option<&'c mut BreakableContext> {
466 let mut ctxs = ctxs
467 .iter_mut()
468 .rev()
469 .take_while(|it| matches!(it.kind, BreakableKind::Block | BreakableKind::Loop));
470 match label {
471 Some(_) => ctxs.find(|ctx| ctx.label.as_ref() == label),
472 None => ctxs.find(|ctx| matches!(ctx.kind, BreakableKind::Loop)),
473 }
474}
475
476fn find_continuable<'c>(
477 ctxs: &'c mut [BreakableContext],
478 label: Option<&name::Name>,
064997fb
FG
479) -> Option<&'c mut BreakableContext> {
480 match label {
f2b60f7d
FG
481 Some(_) => find_breakable(ctxs, label).filter(|it| matches!(it.kind, BreakableKind::Loop)),
482 None => find_breakable(ctxs, label),
064997fb
FG
483 }
484}
485
486impl<'a> InferenceContext<'a> {
487 fn new(
488 db: &'a dyn HirDatabase,
489 owner: DefWithBodyId,
490 body: &'a Body,
491 resolver: Resolver,
492 ) -> Self {
493 let krate = owner.module(db.upcast()).krate();
494 let trait_env = owner
495 .as_generic_def_id()
496 .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
497 InferenceContext {
498 result: InferenceResult::default(),
499 table: unify::InferenceTable::new(db, trait_env.clone()),
500 trait_env,
f25598a0 501 return_ty: TyKind::Error.intern(Interner), // set in collect_* calls
2b03887a 502 resume_yield_tys: None,
064997fb
FG
503 db,
504 owner,
505 body,
506 resolver,
507 diverges: Diverges::Maybe,
508 breakables: Vec::new(),
509 }
510 }
511
512 fn resolve_all(self) -> InferenceResult {
513 let InferenceContext { mut table, mut result, .. } = self;
514
f25598a0
FG
515 table.fallback_if_possible();
516
064997fb
FG
517 // FIXME resolve obligations as well (use Guidance if necessary)
518 table.resolve_obligations_as_possible();
519
520 // make sure diverging type variables are marked as such
521 table.propagate_diverging_flag();
522 for ty in result.type_of_expr.values_mut() {
523 *ty = table.resolve_completely(ty.clone());
524 }
525 for ty in result.type_of_pat.values_mut() {
526 *ty = table.resolve_completely(ty.clone());
527 }
528 for mismatch in result.type_mismatches.values_mut() {
529 mismatch.expected = table.resolve_completely(mismatch.expected.clone());
530 mismatch.actual = table.resolve_completely(mismatch.actual.clone());
531 }
532 for (_, subst) in result.method_resolutions.values_mut() {
533 *subst = table.resolve_completely(subst.clone());
534 }
f25598a0
FG
535 for (_, subst) in result.assoc_resolutions.values_mut() {
536 *subst = table.resolve_completely(subst.clone());
537 }
064997fb
FG
538 for adjustment in result.expr_adjustments.values_mut().flatten() {
539 adjustment.target = table.resolve_completely(adjustment.target.clone());
540 }
541 for adjustment in result.pat_adjustments.values_mut().flatten() {
542 *adjustment = table.resolve_completely(adjustment.clone());
543 }
544 result
545 }
546
547 fn collect_const(&mut self, data: &ConstData) {
548 self.return_ty = self.make_ty(&data.type_ref);
549 }
550
551 fn collect_static(&mut self, data: &StaticData) {
552 self.return_ty = self.make_ty(&data.type_ref);
553 }
554
555 fn collect_fn(&mut self, func: FunctionId) {
556 let data = self.db.function_data(func);
557 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
558 .with_impl_trait_mode(ImplTraitLoweringMode::Param);
f25598a0 559 let mut param_tys =
064997fb 560 data.params.iter().map(|(_, type_ref)| ctx.lower_ty(type_ref)).collect::<Vec<_>>();
f25598a0
FG
561 // Check if function contains a va_list, if it does then we append it to the parameter types
562 // that are collected from the function data
563 if data.is_varargs() {
564 let va_list_ty = match self.resolve_va_list() {
565 Some(va_list) => TyBuilder::adt(self.db, va_list)
566 .fill_with_defaults(self.db, || self.table.new_type_var())
567 .build(),
568 None => self.err_ty(),
569 };
570
571 param_tys.push(va_list_ty)
572 }
064997fb
FG
573 for (ty, pat) in param_tys.into_iter().zip(self.body.params.iter()) {
574 let ty = self.insert_type_vars(ty);
575 let ty = self.normalize_associated_types_in(ty);
576
577 self.infer_pat(*pat, &ty, BindingMode::default());
578 }
579 let error_ty = &TypeRef::Error;
580 let return_ty = if data.has_async_kw() {
581 data.async_ret_type.as_deref().unwrap_or(error_ty)
582 } else {
583 &*data.ret_type
584 };
064997fb 585
f25598a0
FG
586 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver)
587 .with_impl_trait_mode(ImplTraitLoweringMode::Opaque);
588 let return_ty = ctx.lower_ty(return_ty);
589 let return_ty = self.insert_type_vars(return_ty);
590
591 let return_ty = if let Some(rpits) = self.db.return_type_impl_traits(func) {
064997fb
FG
592 // RPIT opaque types use substitution of their parent function.
593 let fn_placeholders = TyBuilder::placeholder_subst(self.db, func);
f25598a0
FG
594 fold_tys(
595 return_ty,
064997fb
FG
596 |ty, _| {
597 let opaque_ty_id = match ty.kind(Interner) {
598 TyKind::OpaqueType(opaque_ty_id, _) => *opaque_ty_id,
599 _ => return ty,
600 };
601 let idx = match self.db.lookup_intern_impl_trait_id(opaque_ty_id.into()) {
602 ImplTraitId::ReturnTypeImplTrait(_, idx) => idx,
603 _ => unreachable!(),
604 };
605 let bounds = (*rpits).map_ref(|rpits| {
606 rpits.impl_traits[idx as usize].bounds.map_ref(|it| it.into_iter())
607 });
608 let var = self.table.new_type_var();
609 let var_subst = Substitution::from1(Interner, var.clone());
610 for bound in bounds {
611 let predicate =
612 bound.map(|it| it.cloned()).substitute(Interner, &fn_placeholders);
613 let (var_predicate, binders) = predicate
614 .substitute(Interner, &var_subst)
615 .into_value_and_skipped_binders();
f25598a0 616 always!(binders.is_empty(Interner)); // quantified where clauses not yet handled
064997fb
FG
617 self.push_obligation(var_predicate.cast(Interner));
618 }
619 var
620 },
621 DebruijnIndex::INNERMOST,
f25598a0
FG
622 )
623 } else {
624 return_ty
625 };
626
627 self.return_ty = self.normalize_associated_types_in(return_ty);
064997fb
FG
628 }
629
630 fn infer_body(&mut self) {
631 self.infer_expr_coerce(self.body.body_expr, &Expectation::has_type(self.return_ty.clone()));
632 }
633
634 fn write_expr_ty(&mut self, expr: ExprId, ty: Ty) {
635 self.result.type_of_expr.insert(expr, ty);
636 }
637
638 fn write_expr_adj(&mut self, expr: ExprId, adjustments: Vec<Adjustment>) {
639 self.result.expr_adjustments.insert(expr, adjustments);
640 }
641
642 fn write_method_resolution(&mut self, expr: ExprId, func: FunctionId, subst: Substitution) {
643 self.result.method_resolutions.insert(expr, (func, subst));
644 }
645
646 fn write_variant_resolution(&mut self, id: ExprOrPatId, variant: VariantId) {
647 self.result.variant_resolutions.insert(id, variant);
648 }
649
f25598a0
FG
650 fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItemId, subs: Substitution) {
651 self.result.assoc_resolutions.insert(id, (item, subs));
064997fb
FG
652 }
653
654 fn write_pat_ty(&mut self, pat: PatId, ty: Ty) {
655 self.result.type_of_pat.insert(pat, ty);
656 }
657
658 fn push_diagnostic(&mut self, diagnostic: InferenceDiagnostic) {
659 self.result.diagnostics.push(diagnostic);
660 }
661
f25598a0 662 fn make_ty(&mut self, type_ref: &TypeRef) -> Ty {
064997fb 663 // FIXME use right resolver for block
f25598a0 664 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
064997fb
FG
665 let ty = ctx.lower_ty(type_ref);
666 let ty = self.insert_type_vars(ty);
667 self.normalize_associated_types_in(ty)
668 }
669
064997fb
FG
670 fn err_ty(&self) -> Ty {
671 self.result.standard_types.unknown.clone()
672 }
673
674 /// Replaces ConstScalar::Unknown by a new type var, so we can maybe still infer it.
675 fn insert_const_vars_shallow(&mut self, c: Const) -> Const {
676 let data = c.data(Interner);
677 match data.value {
678 ConstValue::Concrete(cc) => match cc.interned {
679 hir_def::type_ref::ConstScalar::Unknown => {
680 self.table.new_const_var(data.ty.clone())
681 }
682 _ => c,
683 },
684 _ => c,
685 }
686 }
687
f25598a0 688 /// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
064997fb
FG
689 fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
690 match ty.kind(Interner) {
691 TyKind::Error => self.table.new_type_var(),
692 TyKind::InferenceVar(..) => {
693 let ty_resolved = self.resolve_ty_shallow(&ty);
694 if ty_resolved.is_unknown() {
695 self.table.new_type_var()
696 } else {
697 ty
698 }
699 }
700 _ => ty,
701 }
702 }
703
704 fn insert_type_vars(&mut self, ty: Ty) -> Ty {
705 fold_tys_and_consts(
706 ty,
707 |x, _| match x {
708 Either::Left(ty) => Either::Left(self.insert_type_vars_shallow(ty)),
709 Either::Right(c) => Either::Right(self.insert_const_vars_shallow(c)),
710 },
711 DebruijnIndex::INNERMOST,
712 )
713 }
714
064997fb
FG
715 fn push_obligation(&mut self, o: DomainGoal) {
716 self.table.register_obligation(o.cast(Interner));
717 }
718
719 fn unify(&mut self, ty1: &Ty, ty2: &Ty) -> bool {
720 self.table.unify(ty1, ty2)
721 }
722
723 /// Recurses through the given type, normalizing associated types mentioned
724 /// in it by replacing them by type variables and registering obligations to
725 /// resolve later. This should be done once for every type we get from some
726 /// type annotation (e.g. from a let type annotation, field type or function
727 /// call). `make_ty` handles this already, but e.g. for field types we need
728 /// to do it as well.
729 fn normalize_associated_types_in(&mut self, ty: Ty) -> Ty {
730 self.table.normalize_associated_types_in(ty)
731 }
732
733 fn resolve_ty_shallow(&mut self, ty: &Ty) -> Ty {
064997fb
FG
734 self.table.resolve_ty_shallow(ty)
735 }
736
737 fn resolve_associated_type(&mut self, inner_ty: Ty, assoc_ty: Option<TypeAliasId>) -> Ty {
738 self.resolve_associated_type_with_params(inner_ty, assoc_ty, &[])
739 }
740
741 fn resolve_associated_type_with_params(
742 &mut self,
743 inner_ty: Ty,
744 assoc_ty: Option<TypeAliasId>,
2b03887a
FG
745 // FIXME(GATs): these are args for the trait ref, args for assoc type itself should be
746 // handled when we support them.
064997fb
FG
747 params: &[GenericArg],
748 ) -> Ty {
749 match assoc_ty {
750 Some(res_assoc_ty) => {
751 let trait_ = match res_assoc_ty.lookup(self.db.upcast()).container {
752 hir_def::ItemContainerId::TraitId(trait_) => trait_,
753 _ => panic!("resolve_associated_type called with non-associated type"),
754 };
755 let ty = self.table.new_type_var();
756 let mut param_iter = params.iter().cloned();
757 let trait_ref = TyBuilder::trait_ref(self.db, trait_)
758 .push(inner_ty)
759 .fill(|_| param_iter.next().unwrap())
760 .build();
761 let alias_eq = AliasEq {
762 alias: AliasTy::Projection(ProjectionTy {
763 associated_ty_id: to_assoc_type_id(res_assoc_ty),
764 substitution: trait_ref.substitution.clone(),
765 }),
766 ty: ty.clone(),
767 };
768 self.push_obligation(trait_ref.cast(Interner));
769 self.push_obligation(alias_eq.cast(Interner));
770 ty
771 }
772 None => self.err_ty(),
773 }
774 }
775
776 fn resolve_variant(&mut self, path: Option<&Path>, value_ns: bool) -> (Ty, Option<VariantId>) {
777 let path = match path {
778 Some(path) => path,
779 None => return (self.err_ty(), None),
780 };
781 let resolver = &self.resolver;
782 let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver);
783 // FIXME: this should resolve assoc items as well, see this example:
784 // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521
785 let (resolution, unresolved) = if value_ns {
786 match resolver.resolve_path_in_value_ns(self.db.upcast(), path.mod_path()) {
787 Some(ResolveValueResult::ValueNs(value)) => match value {
788 ValueNs::EnumVariantId(var) => {
789 let substs = ctx.substs_from_path(path, var.into(), true);
790 let ty = self.db.ty(var.parent.into());
791 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
792 return (ty, Some(var.into()));
793 }
794 ValueNs::StructId(strukt) => {
795 let substs = ctx.substs_from_path(path, strukt.into(), true);
796 let ty = self.db.ty(strukt.into());
797 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
798 return (ty, Some(strukt.into()));
799 }
f2b60f7d 800 ValueNs::ImplSelf(impl_id) => (TypeNs::SelfType(impl_id), None),
064997fb
FG
801 _ => return (self.err_ty(), None),
802 },
803 Some(ResolveValueResult::Partial(typens, unresolved)) => (typens, Some(unresolved)),
804 None => return (self.err_ty(), None),
805 }
806 } else {
807 match resolver.resolve_path_in_type_ns(self.db.upcast(), path.mod_path()) {
808 Some(it) => it,
809 None => return (self.err_ty(), None),
810 }
811 };
812 return match resolution {
813 TypeNs::AdtId(AdtId::StructId(strukt)) => {
814 let substs = ctx.substs_from_path(path, strukt.into(), true);
815 let ty = self.db.ty(strukt.into());
816 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
817 forbid_unresolved_segments((ty, Some(strukt.into())), unresolved)
818 }
819 TypeNs::AdtId(AdtId::UnionId(u)) => {
820 let substs = ctx.substs_from_path(path, u.into(), true);
821 let ty = self.db.ty(u.into());
822 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
823 forbid_unresolved_segments((ty, Some(u.into())), unresolved)
824 }
825 TypeNs::EnumVariantId(var) => {
826 let substs = ctx.substs_from_path(path, var.into(), true);
827 let ty = self.db.ty(var.parent.into());
828 let ty = self.insert_type_vars(ty.substitute(Interner, &substs));
829 forbid_unresolved_segments((ty, Some(var.into())), unresolved)
830 }
831 TypeNs::SelfType(impl_id) => {
832 let generics = crate::utils::generics(self.db.upcast(), impl_id.into());
833 let substs = generics.placeholder_subst(self.db);
834 let ty = self.db.impl_self_ty(impl_id).substitute(Interner, &substs);
835 self.resolve_variant_on_alias(ty, unresolved, path)
836 }
837 TypeNs::TypeAliasId(it) => {
2b03887a
FG
838 let container = it.lookup(self.db.upcast()).container;
839 let parent_subst = match container {
840 ItemContainerId::TraitId(id) => {
841 let subst = TyBuilder::subst_for_def(self.db, id, None)
842 .fill_with_inference_vars(&mut self.table)
843 .build();
844 Some(subst)
845 }
846 // Type aliases do not exist in impls.
847 _ => None,
848 };
849 let ty = TyBuilder::def_ty(self.db, it.into(), parent_subst)
064997fb
FG
850 .fill_with_inference_vars(&mut self.table)
851 .build();
852 self.resolve_variant_on_alias(ty, unresolved, path)
853 }
854 TypeNs::AdtSelfType(_) => {
855 // FIXME this could happen in array size expressions, once we're checking them
856 (self.err_ty(), None)
857 }
858 TypeNs::GenericParam(_) => {
859 // FIXME potentially resolve assoc type
860 (self.err_ty(), None)
861 }
862 TypeNs::AdtId(AdtId::EnumId(_)) | TypeNs::BuiltinType(_) | TypeNs::TraitId(_) => {
863 // FIXME diagnostic
864 (self.err_ty(), None)
865 }
866 };
867
868 fn forbid_unresolved_segments(
869 result: (Ty, Option<VariantId>),
870 unresolved: Option<usize>,
871 ) -> (Ty, Option<VariantId>) {
872 if unresolved.is_none() {
873 result
874 } else {
875 // FIXME diagnostic
876 (TyKind::Error.intern(Interner), None)
877 }
878 }
879 }
880
881 fn resolve_variant_on_alias(
882 &mut self,
883 ty: Ty,
884 unresolved: Option<usize>,
885 path: &Path,
886 ) -> (Ty, Option<VariantId>) {
887 let remaining = unresolved.map(|x| path.segments().skip(x).len()).filter(|x| x > &0);
888 match remaining {
889 None => {
890 let variant = ty.as_adt().and_then(|(adt_id, _)| match adt_id {
891 AdtId::StructId(s) => Some(VariantId::StructId(s)),
892 AdtId::UnionId(u) => Some(VariantId::UnionId(u)),
893 AdtId::EnumId(_) => {
894 // FIXME Error E0071, expected struct, variant or union type, found enum `Foo`
895 None
896 }
897 });
898 (ty, variant)
899 }
900 Some(1) => {
901 let segment = path.mod_path().segments().last().unwrap();
902 // this could be an enum variant or associated type
903 if let Some((AdtId::EnumId(enum_id), _)) = ty.as_adt() {
904 let enum_data = self.db.enum_data(enum_id);
905 if let Some(local_id) = enum_data.variant(segment) {
906 let variant = EnumVariantId { parent: enum_id, local_id };
907 return (ty, Some(variant.into()));
908 }
909 }
910 // FIXME potentially resolve assoc type
911 (self.err_ty(), None)
912 }
913 Some(_) => {
914 // FIXME diagnostic
915 (self.err_ty(), None)
916 }
917 }
918 }
919
920 fn resolve_lang_item(&self, name: Name) -> Option<LangItemTarget> {
921 let krate = self.resolver.krate();
922 self.db.lang_item(krate, name.to_smol_str())
923 }
924
925 fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
926 let path = path![core::iter::IntoIterator];
927 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
2b03887a
FG
928 self.db.trait_data(trait_).associated_type_by_name(&name![IntoIter])
929 }
930
931 fn resolve_iterator_item(&self) -> Option<TypeAliasId> {
932 let path = path![core::iter::Iterator];
933 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
064997fb
FG
934 self.db.trait_data(trait_).associated_type_by_name(&name![Item])
935 }
936
937 fn resolve_ops_try_ok(&self) -> Option<TypeAliasId> {
938 // FIXME resolve via lang_item once try v2 is stable
939 let path = path![core::ops::Try];
940 let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
941 let trait_data = self.db.trait_data(trait_);
942 trait_data
943 // FIXME remove once try v2 is stable
944 .associated_type_by_name(&name![Ok])
945 .or_else(|| trait_data.associated_type_by_name(&name![Output]))
946 }
947
948 fn resolve_ops_neg_output(&self) -> Option<TypeAliasId> {
949 let trait_ = self.resolve_lang_item(name![neg])?.as_trait()?;
950 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
951 }
952
953 fn resolve_ops_not_output(&self) -> Option<TypeAliasId> {
954 let trait_ = self.resolve_lang_item(name![not])?.as_trait()?;
955 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
956 }
957
958 fn resolve_future_future_output(&self) -> Option<TypeAliasId> {
f2b60f7d
FG
959 let trait_ = self
960 .resolver
961 .resolve_known_trait(self.db.upcast(), &path![core::future::IntoFuture])
962 .or_else(|| self.resolve_lang_item(name![future_trait])?.as_trait())?;
064997fb
FG
963 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
964 }
965
966 fn resolve_boxed_box(&self) -> Option<AdtId> {
967 let struct_ = self.resolve_lang_item(name![owned_box])?.as_struct()?;
968 Some(struct_.into())
969 }
970
971 fn resolve_range_full(&self) -> Option<AdtId> {
972 let path = path![core::ops::RangeFull];
973 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
974 Some(struct_.into())
975 }
976
977 fn resolve_range(&self) -> Option<AdtId> {
978 let path = path![core::ops::Range];
979 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
980 Some(struct_.into())
981 }
982
983 fn resolve_range_inclusive(&self) -> Option<AdtId> {
984 let path = path![core::ops::RangeInclusive];
985 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
986 Some(struct_.into())
987 }
988
989 fn resolve_range_from(&self) -> Option<AdtId> {
990 let path = path![core::ops::RangeFrom];
991 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
992 Some(struct_.into())
993 }
994
995 fn resolve_range_to(&self) -> Option<AdtId> {
996 let path = path![core::ops::RangeTo];
997 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
998 Some(struct_.into())
999 }
1000
1001 fn resolve_range_to_inclusive(&self) -> Option<AdtId> {
1002 let path = path![core::ops::RangeToInclusive];
1003 let struct_ = self.resolver.resolve_known_struct(self.db.upcast(), &path)?;
1004 Some(struct_.into())
1005 }
1006
1007 fn resolve_ops_index(&self) -> Option<TraitId> {
1008 self.resolve_lang_item(name![index])?.as_trait()
1009 }
1010
1011 fn resolve_ops_index_output(&self) -> Option<TypeAliasId> {
1012 let trait_ = self.resolve_ops_index()?;
1013 self.db.trait_data(trait_).associated_type_by_name(&name![Output])
1014 }
f25598a0
FG
1015
1016 fn resolve_va_list(&self) -> Option<AdtId> {
1017 let struct_ = self.resolve_lang_item(name![va_list])?.as_struct()?;
1018 Some(struct_.into())
1019 }
064997fb
FG
1020}
1021
1022/// When inferring an expression, we propagate downward whatever type hint we
1023/// are able in the form of an `Expectation`.
1024#[derive(Clone, PartialEq, Eq, Debug)]
1025pub(crate) enum Expectation {
1026 None,
1027 HasType(Ty),
1028 // Castable(Ty), // rustc has this, we currently just don't propagate an expectation for casts
1029 RValueLikeUnsized(Ty),
1030}
1031
1032impl Expectation {
1033 /// The expectation that the type of the expression needs to equal the given
1034 /// type.
1035 fn has_type(ty: Ty) -> Self {
1036 if ty.is_unknown() {
1037 // FIXME: get rid of this?
1038 Expectation::None
1039 } else {
1040 Expectation::HasType(ty)
1041 }
1042 }
1043
1044 fn from_option(ty: Option<Ty>) -> Self {
1045 ty.map_or(Expectation::None, Expectation::HasType)
1046 }
1047
1048 /// The following explanation is copied straight from rustc:
1049 /// Provides an expectation for an rvalue expression given an *optional*
1050 /// hint, which is not required for type safety (the resulting type might
1051 /// be checked higher up, as is the case with `&expr` and `box expr`), but
1052 /// is useful in determining the concrete type.
1053 ///
1054 /// The primary use case is where the expected type is a fat pointer,
1055 /// like `&[isize]`. For example, consider the following statement:
1056 ///
487cf647 1057 /// let x: &[isize] = &[1, 2, 3];
064997fb
FG
1058 ///
1059 /// In this case, the expected type for the `&[1, 2, 3]` expression is
1060 /// `&[isize]`. If however we were to say that `[1, 2, 3]` has the
1061 /// expectation `ExpectHasType([isize])`, that would be too strong --
1062 /// `[1, 2, 3]` does not have the type `[isize]` but rather `[isize; 3]`.
1063 /// It is only the `&[1, 2, 3]` expression as a whole that can be coerced
1064 /// to the type `&[isize]`. Therefore, we propagate this more limited hint,
1065 /// which still is useful, because it informs integer literals and the like.
1066 /// See the test case `test/ui/coerce-expect-unsized.rs` and #20169
1067 /// for examples of where this comes up,.
1068 fn rvalue_hint(table: &mut unify::InferenceTable<'_>, ty: Ty) -> Self {
1069 // FIXME: do struct_tail_without_normalization
1070 match table.resolve_ty_shallow(&ty).kind(Interner) {
1071 TyKind::Slice(_) | TyKind::Str | TyKind::Dyn(_) => Expectation::RValueLikeUnsized(ty),
1072 _ => Expectation::has_type(ty),
1073 }
1074 }
1075
1076 /// This expresses no expectation on the type.
1077 fn none() -> Self {
1078 Expectation::None
1079 }
1080
1081 fn resolve(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1082 match self {
1083 Expectation::None => Expectation::None,
1084 Expectation::HasType(t) => Expectation::HasType(table.resolve_ty_shallow(t)),
1085 Expectation::RValueLikeUnsized(t) => {
1086 Expectation::RValueLikeUnsized(table.resolve_ty_shallow(t))
1087 }
1088 }
1089 }
1090
1091 fn to_option(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1092 match self.resolve(table) {
1093 Expectation::None => None,
1094 Expectation::HasType(t) |
1095 // Expectation::Castable(t) |
1096 Expectation::RValueLikeUnsized(t) => Some(t),
1097 }
1098 }
1099
1100 fn only_has_type(&self, table: &mut unify::InferenceTable<'_>) -> Option<Ty> {
1101 match self {
1102 Expectation::HasType(t) => Some(table.resolve_ty_shallow(t)),
1103 // Expectation::Castable(_) |
1104 Expectation::RValueLikeUnsized(_) | Expectation::None => None,
1105 }
1106 }
1107
1108 /// Comment copied from rustc:
1109 /// Disregard "castable to" expectations because they
1110 /// can lead us astray. Consider for example `if cond
1111 /// {22} else {c} as u8` -- if we propagate the
1112 /// "castable to u8" constraint to 22, it will pick the
1113 /// type 22u8, which is overly constrained (c might not
1114 /// be a u8). In effect, the problem is that the
1115 /// "castable to" expectation is not the tightest thing
1116 /// we can say, so we want to drop it in this case.
1117 /// The tightest thing we can say is "must unify with
1118 /// else branch". Note that in the case of a "has type"
1119 /// constraint, this limitation does not hold.
1120 ///
1121 /// If the expected type is just a type variable, then don't use
1122 /// an expected type. Otherwise, we might write parts of the type
1123 /// when checking the 'then' block which are incompatible with the
1124 /// 'else' branch.
1125 fn adjust_for_branches(&self, table: &mut unify::InferenceTable<'_>) -> Expectation {
1126 match self {
1127 Expectation::HasType(ety) => {
1128 let ety = table.resolve_ty_shallow(ety);
1129 if !ety.is_ty_var() {
1130 Expectation::HasType(ety)
1131 } else {
1132 Expectation::None
1133 }
1134 }
1135 Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
1136 _ => Expectation::None,
1137 }
1138 }
1139}
1140
1141#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
1142enum Diverges {
1143 Maybe,
1144 Always,
1145}
1146
1147impl Diverges {
1148 fn is_always(self) -> bool {
1149 self == Diverges::Always
1150 }
1151}
1152
1153impl std::ops::BitAnd for Diverges {
1154 type Output = Self;
1155 fn bitand(self, other: Self) -> Self {
1156 std::cmp::min(self, other)
1157 }
1158}
1159
1160impl std::ops::BitOr for Diverges {
1161 type Output = Self;
1162 fn bitor(self, other: Self) -> Self {
1163 std::cmp::max(self, other)
1164 }
1165}
1166
1167impl std::ops::BitAndAssign for Diverges {
1168 fn bitand_assign(&mut self, other: Self) {
1169 *self = *self & other;
1170 }
1171}
1172
1173impl std::ops::BitOrAssign for Diverges {
1174 fn bitor_assign(&mut self, other: Self) {
1175 *self = *self | other;
1176 }
1177}