Skip to content

Commit b36cbcb

Browse files
committed
add a comment about Locations::All
1 parent 9788479 commit b36cbcb

File tree

1 file changed

+36
-0
lines changed
  • src/librustc_mir/borrow_check/nll/type_check

1 file changed

+36
-0
lines changed

src/librustc_mir/borrow_check/nll/type_check/mod.rs

+36
Original file line numberDiff line numberDiff line change
@@ -618,9 +618,45 @@ pub struct OutlivesSet<'tcx> {
618618
pub data: RegionConstraintData<'tcx>,
619619
}
620620

621+
/// The `Locations` type summarizes *where* region constraints are
622+
/// required to hold. Normally, this is at a particular point which
623+
/// created the obligation, but for constraints that the user gave, we
624+
/// want the constraint to hold at all points.
621625
#[derive(Copy, Clone, Debug)]
622626
pub enum Locations {
627+
/// Indicates that a type constraint should always be true. This
628+
/// is particularly important in the new borrowck analysis for
629+
/// things like the type of the return slot. Consider this
630+
/// example:
631+
///
632+
/// ```
633+
/// fn foo<'a>(x: &'a u32) -> &'a u32 {
634+
/// let y = 22;
635+
/// return &y; // error
636+
/// }
637+
/// ```
638+
///
639+
/// Here, we wind up with the signature from the return type being
640+
/// something like `&'1 u32` where `'1` is a universal region. But
641+
/// the type of the return slot `_0` is something like `&'2 u32`
642+
/// where `'2` is an existential region variable. The type checker
643+
/// requires that `&'2 u32 = &'1 u32` -- but at what point? In the
644+
/// older NLL analysis, we required this only at the entry point
645+
/// to the function. By the nature of the constraints, this wound
646+
/// up propagating to all points reachable from start (because
647+
/// `'1` -- as a universal region -- is live everywhere). In the
648+
/// newer analysis, though, this doesn't work: `_0` is considered
649+
/// dead at the start (it has no usable value) and hence this type
650+
/// equality is basically a no-op. Then, later on, when we do `_0
651+
/// = &'3 y`, that region `'3` never winds up related to the
652+
/// universal region `'1` and hence no error occurs. Therefore, we
653+
/// use Locations::All instead, which ensures that the `'1` and
654+
/// `'2` are equal everything. We also use this for other
655+
/// user-given type annotations; e.g., if the user wrote `let mut
656+
/// x: &'static u32 = ...`, we would ensure that all values
657+
/// assigned to `x` are of `'static` lifetime.
623658
All,
659+
624660
Pair {
625661
/// The location in the MIR that generated these constraints.
626662
/// This is intended for error reporting and diagnosis; the

0 commit comments

Comments
 (0)