]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/region_infer/mod.rs
appease the vociferous tidy
[rust.git] / src / librustc_mir / borrow_check / nll / region_infer / mod.rs
1 use std::rc::Rc;
2
3 use rustc::hir::def_id::DefId;
4 use rustc::infer::canonical::QueryOutlivesConstraint;
5 use rustc::infer::opaque_types;
6 use rustc::infer::region_constraints::{GenericKind, VarInfos, VerifyBound};
7 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin, RegionVariableOrigin};
8 use rustc::mir::{
9     Body, ClosureOutlivesRequirement, ClosureOutlivesSubject, ClosureRegionRequirements,
10     ConstraintCategory, Local, Location,
11 };
12 use rustc::ty::{self, subst::SubstsRef, RegionVid, Ty, TyCtxt, TypeFoldable};
13 use rustc::util::common::ErrorReported;
14 use rustc_data_structures::binary_search_util;
15 use rustc_index::bit_set::BitSet;
16 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
17 use rustc_data_structures::graph::WithSuccessors;
18 use rustc_data_structures::graph::scc::Sccs;
19 use rustc_data_structures::graph::vec_graph::VecGraph;
20 use rustc_index::vec::IndexVec;
21 use rustc_errors::{Diagnostic, DiagnosticBuilder};
22 use syntax_pos::Span;
23 use syntax_pos::symbol::Symbol;
24
25 use crate::borrow_check::{
26     nll::{
27         constraints::{
28             graph::NormalConstraintGraph,
29             ConstraintSccIndex,
30             OutlivesConstraint,
31             OutlivesConstraintSet,
32         },
33         member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
34         region_infer::values::{
35             PlaceholderIndices, RegionElement, ToElementIndex
36         },
37         type_check::{free_region_relations::UniversalRegionRelations, Locations},
38     },
39     diagnostics::{
40         OutlivesSuggestionBuilder, RegionErrorNamingCtx,
41     },
42     Upvar,
43 };
44
45 use self::values::{LivenessValues, RegionValueElements, RegionValues};
46 use super::universal_regions::UniversalRegions;
47 use super::{PoloniusOutput, ToRegionVid};
48
49 mod dump_mir;
50 mod graphviz;
51
52 pub mod values;
53
54 pub struct RegionInferenceContext<'tcx> {
55     /// Contains the definition for every region variable. Region
56     /// variables are identified by their index (`RegionVid`). The
57     /// definition contains information about where the region came
58     /// from as well as its final inferred value.
59     pub(in crate::borrow_check) definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
60
61     /// The liveness constraints added to each region. For most
62     /// regions, these start out empty and steadily grow, though for
63     /// each universally quantified region R they start out containing
64     /// the entire CFG and `end(R)`.
65     pub(in crate::borrow_check) liveness_constraints: LivenessValues<RegionVid>,
66
67     /// The outlives constraints computed by the type-check.
68     pub(in crate::borrow_check) constraints: Rc<OutlivesConstraintSet>,
69
70     /// The constraint-set, but in graph form, making it easy to traverse
71     /// the constraints adjacent to a particular region. Used to construct
72     /// the SCC (see `constraint_sccs`) and for error reporting.
73     pub(in crate::borrow_check) constraint_graph: Rc<NormalConstraintGraph>,
74
75     /// The SCC computed from `constraints` and the constraint
76     /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to
77     /// compute the values of each region.
78     pub(in crate::borrow_check) constraint_sccs: Rc<Sccs<RegionVid, ConstraintSccIndex>>,
79
80     /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B`
81     /// exists if `B: A`. Computed lazilly.
82     pub(in crate::borrow_check) rev_constraint_graph:
83         Option<Rc<VecGraph<ConstraintSccIndex>>>,
84
85     /// The "R0 member of [R1..Rn]" constraints, indexed by SCC.
86     pub(in crate::borrow_check) member_constraints:
87         Rc<MemberConstraintSet<'tcx, ConstraintSccIndex>>,
88
89     /// Records the member constraints that we applied to each scc.
90     /// This is useful for error reporting. Once constraint
91     /// propagation is done, this vector is sorted according to
92     /// `member_region_scc`.
93     pub(in crate::borrow_check) member_constraints_applied: Vec<AppliedMemberConstraint>,
94
95     /// Map closure bounds to a `Span` that should be used for error reporting.
96     pub(in crate::borrow_check) closure_bounds_mapping:
97         FxHashMap<Location, FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>>,
98
99     /// Contains the minimum universe of any variable within the same
100     /// SCC. We will ensure that no SCC contains values that are not
101     /// visible from this index.
102     pub(in crate::borrow_check) scc_universes:
103         IndexVec<ConstraintSccIndex, ty::UniverseIndex>,
104
105     /// Contains a "representative" from each SCC. This will be the
106     /// minimal RegionVid belonging to that universe. It is used as a
107     /// kind of hacky way to manage checking outlives relationships,
108     /// since we can 'canonicalize' each region to the representative
109     /// of its SCC and be sure that -- if they have the same repr --
110     /// they *must* be equal (though not having the same repr does not
111     /// mean they are unequal).
112     pub(in crate::borrow_check) scc_representatives:
113         IndexVec<ConstraintSccIndex, ty::RegionVid>,
114
115     /// The final inferred values of the region variables; we compute
116     /// one value per SCC. To get the value for any given *region*,
117     /// you first find which scc it is a part of.
118     pub(in crate::borrow_check) scc_values: RegionValues<ConstraintSccIndex>,
119
120     /// Type constraints that we check after solving.
121     pub(in crate::borrow_check) type_tests: Vec<TypeTest<'tcx>>,
122
123     /// Information about the universally quantified regions in scope
124     /// on this function.
125     pub (in crate::borrow_check) universal_regions: Rc<UniversalRegions<'tcx>>,
126
127     /// Information about how the universally quantified regions in
128     /// scope on this function relate to one another.
129     pub(in crate::borrow_check) universal_region_relations:
130         Rc<UniversalRegionRelations<'tcx>>,
131 }
132
133 /// Each time that `apply_member_constraint` is successful, it appends
134 /// one of these structs to the `member_constraints_applied` field.
135 /// This is used in error reporting to trace out what happened.
136 ///
137 /// The way that `apply_member_constraint` works is that it effectively
138 /// adds a new lower bound to the SCC it is analyzing: so you wind up
139 /// with `'R: 'O` where `'R` is the pick-region and `'O` is the
140 /// minimal viable option.
141 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
142 pub(crate) struct AppliedMemberConstraint {
143     /// The SCC that was affected. (The "member region".)
144     ///
145     /// The vector if `AppliedMemberConstraint` elements is kept sorted
146     /// by this field.
147     pub(in crate::borrow_check) member_region_scc: ConstraintSccIndex,
148
149     /// The "best option" that `apply_member_constraint` found -- this was
150     /// added as an "ad-hoc" lower-bound to `member_region_scc`.
151     pub(in crate::borrow_check) min_choice: ty::RegionVid,
152
153     /// The "member constraint index" -- we can find out details about
154     /// the constraint from
155     /// `set.member_constraints[member_constraint_index]`.
156     pub(in crate::borrow_check) member_constraint_index: NllMemberConstraintIndex,
157 }
158
159 pub(crate) struct RegionDefinition<'tcx> {
160     /// What kind of variable is this -- a free region? existential
161     /// variable? etc. (See the `NLLRegionVariableOrigin` for more
162     /// info.)
163     pub(in crate::borrow_check) origin: NLLRegionVariableOrigin,
164
165     /// Which universe is this region variable defined in? This is
166     /// most often `ty::UniverseIndex::ROOT`, but when we encounter
167     /// forall-quantifiers like `for<'a> { 'a = 'b }`, we would create
168     /// the variable for `'a` in a fresh universe that extends ROOT.
169     pub(in crate::borrow_check) universe: ty::UniverseIndex,
170
171     /// If this is 'static or an early-bound region, then this is
172     /// `Some(X)` where `X` is the name of the region.
173     pub(in crate::borrow_check) external_name: Option<ty::Region<'tcx>>,
174 }
175
176 /// N.B., the variants in `Cause` are intentionally ordered. Lower
177 /// values are preferred when it comes to error messages. Do not
178 /// reorder willy nilly.
179 #[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
180 pub(crate) enum Cause {
181     /// point inserted because Local was live at the given Location
182     LiveVar(Local, Location),
183
184     /// point inserted because Local was dropped at the given Location
185     DropVar(Local, Location),
186 }
187
188 /// A "type test" corresponds to an outlives constraint between a type
189 /// and a lifetime, like `T: 'x` or `<T as Foo>::Bar: 'x`. They are
190 /// translated from the `Verify` region constraints in the ordinary
191 /// inference context.
192 ///
193 /// These sorts of constraints are handled differently than ordinary
194 /// constraints, at least at present. During type checking, the
195 /// `InferCtxt::process_registered_region_obligations` method will
196 /// attempt to convert a type test like `T: 'x` into an ordinary
197 /// outlives constraint when possible (for example, `&'a T: 'b` will
198 /// be converted into `'a: 'b` and registered as a `Constraint`).
199 ///
200 /// In some cases, however, there are outlives relationships that are
201 /// not converted into a region constraint, but rather into one of
202 /// these "type tests". The distinction is that a type test does not
203 /// influence the inference result, but instead just examines the
204 /// values that we ultimately inferred for each region variable and
205 /// checks that they meet certain extra criteria. If not, an error
206 /// can be issued.
207 ///
208 /// One reason for this is that these type tests typically boil down
209 /// to a check like `'a: 'x` where `'a` is a universally quantified
210 /// region -- and therefore not one whose value is really meant to be
211 /// *inferred*, precisely (this is not always the case: one can have a
212 /// type test like `<Foo as Trait<'?0>>::Bar: 'x`, where `'?0` is an
213 /// inference variable). Another reason is that these type tests can
214 /// involve *disjunction* -- that is, they can be satisfied in more
215 /// than one way.
216 ///
217 /// For more information about this translation, see
218 /// `InferCtxt::process_registered_region_obligations` and
219 /// `InferCtxt::type_must_outlive` in `rustc::infer::outlives`.
220 #[derive(Clone, Debug)]
221 pub struct TypeTest<'tcx> {
222     /// The type `T` that must outlive the region.
223     pub generic_kind: GenericKind<'tcx>,
224
225     /// The region `'x` that the type must outlive.
226     pub lower_bound: RegionVid,
227
228     /// Where did this constraint arise and why?
229     pub locations: Locations,
230
231     /// A test which, if met by the region `'x`, proves that this type
232     /// constraint is satisfied.
233     pub verify_bound: VerifyBound<'tcx>,
234 }
235
236 impl<'tcx> RegionInferenceContext<'tcx> {
237     /// Creates a new region inference context with a total of
238     /// `num_region_variables` valid inference variables; the first N
239     /// of those will be constant regions representing the free
240     /// regions defined in `universal_regions`.
241     ///
242     /// The `outlives_constraints` and `type_tests` are an initial set
243     /// of constraints produced by the MIR type check.
244     pub(crate) fn new(
245         var_infos: VarInfos,
246         universal_regions: Rc<UniversalRegions<'tcx>>,
247         placeholder_indices: Rc<PlaceholderIndices>,
248         universal_region_relations: Rc<UniversalRegionRelations<'tcx>>,
249         outlives_constraints: OutlivesConstraintSet,
250         member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
251         closure_bounds_mapping: FxHashMap<
252             Location,
253             FxHashMap<(RegionVid, RegionVid), (ConstraintCategory, Span)>,
254         >,
255         type_tests: Vec<TypeTest<'tcx>>,
256         liveness_constraints: LivenessValues<RegionVid>,
257         elements: &Rc<RegionValueElements>,
258     ) -> Self {
259         // Create a RegionDefinition for each inference variable.
260         let definitions: IndexVec<_, _> = var_infos
261             .into_iter()
262             .map(|info| RegionDefinition::new(info.universe, info.origin))
263             .collect();
264
265         let constraints = Rc::new(outlives_constraints); // freeze constraints
266         let constraint_graph = Rc::new(constraints.graph(definitions.len()));
267         let fr_static = universal_regions.fr_static;
268         let constraint_sccs = Rc::new(constraints.compute_sccs(&constraint_graph, fr_static));
269
270         let mut scc_values =
271             RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
272
273         for region in liveness_constraints.rows() {
274             let scc = constraint_sccs.scc(region);
275             scc_values.merge_liveness(scc, region, &liveness_constraints);
276         }
277
278         let scc_universes = Self::compute_scc_universes(&constraint_sccs, &definitions);
279
280         let scc_representatives = Self::compute_scc_representatives(&constraint_sccs, &definitions);
281
282         let member_constraints =
283             Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r)));
284
285         let mut result = Self {
286             definitions,
287             liveness_constraints,
288             constraints,
289             constraint_graph,
290             constraint_sccs,
291             rev_constraint_graph: None,
292             member_constraints,
293             member_constraints_applied: Vec::new(),
294             closure_bounds_mapping,
295             scc_universes,
296             scc_representatives,
297             scc_values,
298             type_tests,
299             universal_regions,
300             universal_region_relations,
301         };
302
303         result.init_free_and_bound_regions();
304
305         result
306     }
307
308     /// Each SCC is the combination of many region variables which
309     /// have been equated. Therefore, we can associate a universe with
310     /// each SCC which is minimum of all the universes of its
311     /// constituent regions -- this is because whatever value the SCC
312     /// takes on must be a value that each of the regions within the
313     /// SCC could have as well. This implies that the SCC must have
314     /// the minimum, or narrowest, universe.
315     fn compute_scc_universes(
316         constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
317         definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
318     ) -> IndexVec<ConstraintSccIndex, ty::UniverseIndex> {
319         let num_sccs = constraints_scc.num_sccs();
320         let mut scc_universes = IndexVec::from_elem_n(ty::UniverseIndex::MAX, num_sccs);
321
322         for (region_vid, region_definition) in definitions.iter_enumerated() {
323             let scc = constraints_scc.scc(region_vid);
324             let scc_universe = &mut scc_universes[scc];
325             *scc_universe = ::std::cmp::min(*scc_universe, region_definition.universe);
326         }
327
328         debug!("compute_scc_universes: scc_universe = {:#?}", scc_universes);
329
330         scc_universes
331     }
332
333     /// For each SCC, we compute a unique `RegionVid` (in fact, the
334     /// minimal one that belongs to the SCC). See
335     /// `scc_representatives` field of `RegionInferenceContext` for
336     /// more details.
337     fn compute_scc_representatives(
338         constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>,
339         definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
340     ) -> IndexVec<ConstraintSccIndex, ty::RegionVid> {
341         let num_sccs = constraints_scc.num_sccs();
342         let next_region_vid = definitions.next_index();
343         let mut scc_representatives = IndexVec::from_elem_n(next_region_vid, num_sccs);
344
345         for region_vid in definitions.indices() {
346             let scc = constraints_scc.scc(region_vid);
347             let prev_min = scc_representatives[scc];
348             scc_representatives[scc] = region_vid.min(prev_min);
349         }
350
351         scc_representatives
352     }
353
354     /// Initializes the region variables for each universally
355     /// quantified region (lifetime parameter). The first N variables
356     /// always correspond to the regions appearing in the function
357     /// signature (both named and anonymous) and where-clauses. This
358     /// function iterates over those regions and initializes them with
359     /// minimum values.
360     ///
361     /// For example:
362     ///
363     ///     fn foo<'a, 'b>(..) where 'a: 'b
364     ///
365     /// would initialize two variables like so:
366     ///
367     ///     R0 = { CFG, R0 } // 'a
368     ///     R1 = { CFG, R0, R1 } // 'b
369     ///
370     /// Here, R0 represents `'a`, and it contains (a) the entire CFG
371     /// and (b) any universally quantified regions that it outlives,
372     /// which in this case is just itself. R1 (`'b`) in contrast also
373     /// outlives `'a` and hence contains R0 and R1.
374     fn init_free_and_bound_regions(&mut self) {
375         // Update the names (if any)
376         for (external_name, variable) in self.universal_regions.named_universal_regions() {
377             debug!(
378                 "init_universal_regions: region {:?} has external name {:?}",
379                 variable, external_name
380             );
381             self.definitions[variable].external_name = Some(external_name);
382         }
383
384         for variable in self.definitions.indices() {
385             let scc = self.constraint_sccs.scc(variable);
386
387             match self.definitions[variable].origin {
388                 NLLRegionVariableOrigin::FreeRegion => {
389                     // For each free, universally quantified region X:
390
391                     // Add all nodes in the CFG to liveness constraints
392                     self.liveness_constraints.add_all_points(variable);
393                     self.scc_values.add_all_points(scc);
394
395                     // Add `end(X)` into the set for X.
396                     self.scc_values.add_element(scc, variable);
397                 }
398
399                 NLLRegionVariableOrigin::Placeholder(placeholder) => {
400                     // Each placeholder region is only visible from
401                     // its universe `ui` and its extensions. So we
402                     // can't just add it into `scc` unless the
403                     // universe of the scc can name this region.
404                     let scc_universe = self.scc_universes[scc];
405                     if scc_universe.can_name(placeholder.universe) {
406                         self.scc_values.add_element(scc, placeholder);
407                     } else {
408                         debug!(
409                             "init_free_and_bound_regions: placeholder {:?} is \
410                              not compatible with universe {:?} of its SCC {:?}",
411                             placeholder, scc_universe, scc,
412                         );
413                         self.add_incompatible_universe(scc);
414                     }
415                 }
416
417                 NLLRegionVariableOrigin::Existential { .. } => {
418                     // For existential, regions, nothing to do.
419                 }
420             }
421         }
422     }
423
424     /// Returns an iterator over all the region indices.
425     pub fn regions(&self) -> impl Iterator<Item = RegionVid> {
426         self.definitions.indices()
427     }
428
429     /// Given a universal region in scope on the MIR, returns the
430     /// corresponding index.
431     ///
432     /// (Panics if `r` is not a registered universal region.)
433     pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
434         self.universal_regions.to_region_vid(r)
435     }
436
437     /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
438     crate fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut DiagnosticBuilder<'_>) {
439         self.universal_regions.annotate(tcx, err)
440     }
441
442     /// Returns `true` if the region `r` contains the point `p`.
443     ///
444     /// Panics if called before `solve()` executes,
445     crate fn region_contains(&self, r: impl ToRegionVid, p: impl ToElementIndex) -> bool {
446         let scc = self.constraint_sccs.scc(r.to_region_vid());
447         self.scc_values.contains(scc, p)
448     }
449
450     /// Returns access to the value of `r` for debugging purposes.
451     crate fn region_value_str(&self, r: RegionVid) -> String {
452         let scc = self.constraint_sccs.scc(r.to_region_vid());
453         self.scc_values.region_value_str(scc)
454     }
455
456     /// Returns access to the value of `r` for debugging purposes.
457     crate fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
458         let scc = self.constraint_sccs.scc(r.to_region_vid());
459         self.scc_universes[scc]
460     }
461
462     /// Once region solving has completed, this function will return
463     /// the member constraints that were applied to the value of a given
464     /// region `r`. See `AppliedMemberConstraint`.
465     pub(in crate::borrow_check) fn applied_member_constraints(
466         &self, r: impl ToRegionVid
467     ) -> &[AppliedMemberConstraint] {
468         let scc = self.constraint_sccs.scc(r.to_region_vid());
469         binary_search_util::binary_search_slice(
470             &self.member_constraints_applied,
471             |applied| applied.member_region_scc,
472             &scc,
473         )
474     }
475
476     /// Performs region inference and report errors if we see any
477     /// unsatisfiable constraints. If this is a closure, returns the
478     /// region requirements to propagate to our creator, if any.
479     pub(super) fn solve(
480         &mut self,
481         infcx: &InferCtxt<'_, 'tcx>,
482         body: &Body<'tcx>,
483         local_names: &IndexVec<Local, Option<Symbol>>,
484         upvars: &[Upvar],
485         mir_def_id: DefId,
486         errors_buffer: &mut Vec<Diagnostic>,
487         polonius_output: Option<Rc<PoloniusOutput>>,
488     ) -> Option<ClosureRegionRequirements<'tcx>> {
489         self.propagate_constraints(body);
490
491         // If this is a closure, we can propagate unsatisfied
492         // `outlives_requirements` to our creator, so create a vector
493         // to store those. Otherwise, we'll pass in `None` to the
494         // functions below, which will trigger them to report errors
495         // eagerly.
496         let mut outlives_requirements =
497             if infcx.tcx.is_closure(mir_def_id) { Some(vec![]) } else { None };
498
499         self.check_type_tests(
500             infcx,
501             body,
502             mir_def_id,
503             outlives_requirements.as_mut(),
504             errors_buffer,
505         );
506
507         // If we produce any errors, we keep track of the names of all regions, so that we can use
508         // the same error names in any suggestions we produce. Note that we need names to be unique
509         // across different errors for the same MIR def so that we can make suggestions that fix
510         // multiple problems.
511         let mut region_naming = RegionErrorNamingCtx::new();
512
513         // In Polonius mode, the errors about missing universal region relations are in the output
514         // and need to be emitted or propagated. Otherwise, we need to check whether the
515         // constraints were too strong, and if so, emit or propagate those errors.
516         if infcx.tcx.sess.opts.debugging_opts.polonius {
517             self.check_polonius_subset_errors(
518                 infcx,
519                 body,
520                 local_names,
521                 upvars,
522                 mir_def_id,
523                 outlives_requirements.as_mut(),
524                 errors_buffer,
525                 &mut region_naming,
526                 polonius_output.expect("Polonius output is unavailable despite `-Z polonius`"),
527             );
528         } else {
529             self.check_universal_regions(
530                 infcx,
531                 body,
532                 local_names,
533                 upvars,
534                 mir_def_id,
535                 outlives_requirements.as_mut(),
536                 errors_buffer,
537                 &mut region_naming,
538             );
539         }
540
541         self.check_member_constraints(infcx, mir_def_id, errors_buffer);
542
543         let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
544
545         if outlives_requirements.is_empty() {
546             None
547         } else {
548             let num_external_vids = self.universal_regions.num_global_and_external_regions();
549             Some(ClosureRegionRequirements { num_external_vids, outlives_requirements })
550         }
551     }
552
553     /// Propagate the region constraints: this will grow the values
554     /// for each region variable until all the constraints are
555     /// satisfied. Note that some values may grow **too** large to be
556     /// feasible, but we check this later.
557     fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
558         debug!("propagate_constraints()");
559
560         debug!("propagate_constraints: constraints={:#?}", {
561             let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
562             constraints.sort();
563             constraints
564                 .into_iter()
565                 .map(|c| (c, self.constraint_sccs.scc(c.sup), self.constraint_sccs.scc(c.sub)))
566                 .collect::<Vec<_>>()
567         });
568
569         // To propagate constraints, we walk the DAG induced by the
570         // SCC. For each SCC, we visit its successors and compute
571         // their values, then we union all those values to get our
572         // own.
573         let visited = &mut BitSet::new_empty(self.constraint_sccs.num_sccs());
574         for scc_index in self.constraint_sccs.all_sccs() {
575             self.propagate_constraint_sccs_if_new(scc_index, visited);
576         }
577
578         // Sort the applied member constraints so we can binary search
579         // through them later.
580         self.member_constraints_applied.sort_by_key(|applied| applied.member_region_scc);
581     }
582
583     /// Computes the value of the SCC `scc_a` if it has not already
584     /// been computed. The `visited` parameter is a bitset
585     #[inline]
586     fn propagate_constraint_sccs_if_new(
587         &mut self,
588         scc_a: ConstraintSccIndex,
589         visited: &mut BitSet<ConstraintSccIndex>,
590     ) {
591         if visited.insert(scc_a) {
592             self.propagate_constraint_sccs_new(scc_a, visited);
593         }
594     }
595
596     /// Computes the value of the SCC `scc_a`, which has not yet been
597     /// computed. This works by first computing all successors of the
598     /// SCC (if they haven't been computed already) and then unioning
599     /// together their elements.
600     fn propagate_constraint_sccs_new(
601         &mut self,
602         scc_a: ConstraintSccIndex,
603         visited: &mut BitSet<ConstraintSccIndex>,
604     ) {
605         let constraint_sccs = self.constraint_sccs.clone();
606
607         // Walk each SCC `B` such that `A: B`...
608         for &scc_b in constraint_sccs.successors(scc_a) {
609             debug!("propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", scc_a, scc_b);
610
611             // ...compute the value of `B`...
612             self.propagate_constraint_sccs_if_new(scc_b, visited);
613
614             // ...and add elements from `B` into `A`. One complication
615             // arises because of universes: If `B` contains something
616             // that `A` cannot name, then `A` can only contain `B` if
617             // it outlives static.
618             if self.universe_compatible(scc_b, scc_a) {
619                 // `A` can name everything that is in `B`, so just
620                 // merge the bits.
621                 self.scc_values.add_region(scc_a, scc_b);
622             } else {
623                 self.add_incompatible_universe(scc_a);
624             }
625         }
626
627         // Now take member constraints into account.
628         let member_constraints = self.member_constraints.clone();
629         for m_c_i in member_constraints.indices(scc_a) {
630             self.apply_member_constraint(
631                 scc_a,
632                 m_c_i,
633                 member_constraints.choice_regions(m_c_i),
634             );
635         }
636
637         debug!(
638             "propagate_constraint_sccs: scc_a = {:?} has value {:?}",
639             scc_a,
640             self.scc_values.region_value_str(scc_a),
641         );
642     }
643
644     /// Invoked for each `R0 member of [R1..Rn]` constraint.
645     ///
646     /// `scc` is the SCC containing R0, and `choice_regions` are the
647     /// `R1..Rn` regions -- they are always known to be universal
648     /// regions (and if that's not true, we just don't attempt to
649     /// enforce the constraint).
650     ///
651     /// The current value of `scc` at the time the method is invoked
652     /// is considered a *lower bound*.  If possible, we will modify
653     /// the constraint to set it equal to one of the option regions.
654     /// If we make any changes, returns true, else false.
655     fn apply_member_constraint(
656         &mut self,
657         scc: ConstraintSccIndex,
658         member_constraint_index: NllMemberConstraintIndex,
659         choice_regions: &[ty::RegionVid],
660     ) -> bool {
661         debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,);
662
663         if let Some(uh_oh) =
664             choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r))
665         {
666             // FIXME(#61773): This case can only occur with
667             // `impl_trait_in_bindings`, I believe, and we are just
668             // opting not to handle it for now. See #61773 for
669             // details.
670             bug!(
671                 "member constraint for `{:?}` has an option region `{:?}` \
672                  that is not a universal region",
673                 self.member_constraints[member_constraint_index].opaque_type_def_id,
674                 uh_oh,
675             );
676         }
677
678         // Create a mutable vector of the options. We'll try to winnow
679         // them down.
680         let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
681
682         // The 'member region' in a member constraint is part of the
683         // hidden type, which must be in the root universe. Therefore,
684         // it cannot have any placeholders in its value.
685         assert!(self.scc_universes[scc] == ty::UniverseIndex::ROOT);
686         debug_assert!(
687             self.scc_values.placeholders_contained_in(scc).next().is_none(),
688             "scc {:?} in a member constraint has placeholder value: {:?}",
689             scc,
690             self.scc_values.region_value_str(scc),
691         );
692
693         // The existing value for `scc` is a lower-bound. This will
694         // consist of some set `{P} + {LB}` of points `{P}` and
695         // lower-bound free regions `{LB}`. As each choice region `O`
696         // is a free region, it will outlive the points. But we can
697         // only consider the option `O` if `O: LB`.
698         choice_regions.retain(|&o_r| {
699             self.scc_values
700                 .universal_regions_outlived_by(scc)
701                 .all(|lb| self.universal_region_relations.outlives(o_r, lb))
702         });
703         debug!("apply_member_constraint: after lb, choice_regions={:?}", choice_regions);
704
705         // Now find all the *upper bounds* -- that is, each UB is a
706         // free region that must outlive the member region `R0` (`UB:
707         // R0`). Therefore, we need only keep an option `O` if `UB: O`
708         // for all UB.
709         if choice_regions.len() > 1 {
710             let universal_region_relations = self.universal_region_relations.clone();
711             let rev_constraint_graph = self.rev_constraint_graph();
712             for ub in self.upper_bounds(scc, &rev_constraint_graph) {
713                 debug!("apply_member_constraint: ub={:?}", ub);
714                 choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r));
715             }
716             debug!("apply_member_constraint: after ub, choice_regions={:?}", choice_regions);
717         }
718
719         // If we ruled everything out, we're done.
720         if choice_regions.is_empty() {
721             return false;
722         }
723
724         // Otherwise, we need to find the minimum remaining choice, if
725         // any, and take that.
726         debug!("apply_member_constraint: choice_regions remaining are {:#?}", choice_regions);
727         let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option<ty::RegionVid> {
728             let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2);
729             let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1);
730             if r1_outlives_r2 && r2_outlives_r1 {
731                 Some(r1.min(r2))
732             } else if r1_outlives_r2 {
733                 Some(r2)
734             } else if r2_outlives_r1 {
735                 Some(r1)
736             } else {
737                 None
738             }
739         };
740         let mut min_choice = choice_regions[0];
741         for &other_option in &choice_regions[1..] {
742             debug!(
743                 "apply_member_constraint: min_choice={:?} other_option={:?}",
744                 min_choice, other_option,
745             );
746             match min(min_choice, other_option) {
747                 Some(m) => min_choice = m,
748                 None => {
749                     debug!(
750                         "apply_member_constraint: {:?} and {:?} are incomparable; no min choice",
751                         min_choice, other_option,
752                     );
753                     return false;
754                 }
755             }
756         }
757
758         let min_choice_scc = self.constraint_sccs.scc(min_choice);
759         debug!(
760             "apply_member_constraint: min_choice={:?} best_choice_scc={:?}",
761             min_choice,
762             min_choice_scc,
763         );
764         if self.scc_values.add_region(scc, min_choice_scc) {
765             self.member_constraints_applied.push(AppliedMemberConstraint {
766                 member_region_scc: scc,
767                 min_choice,
768                 member_constraint_index,
769             });
770
771             true
772         } else {
773             false
774         }
775     }
776
777     /// Compute and return the reverse SCC-based constraint graph (lazilly).
778     fn upper_bounds(
779         &'a mut self,
780         scc0: ConstraintSccIndex,
781         rev_constraint_graph: &'a VecGraph<ConstraintSccIndex>,
782     ) -> impl Iterator<Item = RegionVid> + 'a {
783         let scc_values = &self.scc_values;
784         let mut duplicates = FxHashSet::default();
785         rev_constraint_graph
786             .depth_first_search(scc0)
787             .skip(1)
788             .flat_map(move |scc1| scc_values.universal_regions_outlived_by(scc1))
789             .filter(move |&r| duplicates.insert(r))
790     }
791
792     /// Compute and return the reverse SCC-based constraint graph (lazilly).
793     fn rev_constraint_graph(
794         &mut self,
795     ) -> Rc<VecGraph<ConstraintSccIndex>> {
796         if let Some(g) = &self.rev_constraint_graph {
797             return g.clone();
798         }
799
800         let rev_graph = Rc::new(self.constraint_sccs.reverse());
801         self.rev_constraint_graph = Some(rev_graph.clone());
802         rev_graph
803     }
804
805     /// Returns `true` if all the elements in the value of `scc_b` are nameable
806     /// in `scc_a`. Used during constraint propagation, and only once
807     /// the value of `scc_b` has been computed.
808     fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool {
809         let universe_a = self.scc_universes[scc_a];
810
811         // Quick check: if scc_b's declared universe is a subset of
812         // scc_a's declared univese (typically, both are ROOT), then
813         // it cannot contain any problematic universe elements.
814         if universe_a.can_name(self.scc_universes[scc_b]) {
815             return true;
816         }
817
818         // Otherwise, we have to iterate over the universe elements in
819         // B's value, and check whether all of them are nameable
820         // from universe_a
821         self.scc_values.placeholders_contained_in(scc_b).all(|p| universe_a.can_name(p.universe))
822     }
823
824     /// Extend `scc` so that it can outlive some placeholder region
825     /// from a universe it can't name; at present, the only way for
826     /// this to be true is if `scc` outlives `'static`. This is
827     /// actually stricter than necessary: ideally, we'd support bounds
828     /// like `for<'a: 'b`>` that might then allow us to approximate
829     /// `'a` with `'b` and not `'static`. But it will have to do for
830     /// now.
831     fn add_incompatible_universe(&mut self, scc: ConstraintSccIndex) {
832         debug!("add_incompatible_universe(scc={:?})", scc);
833
834         let fr_static = self.universal_regions.fr_static;
835         self.scc_values.add_all_points(scc);
836         self.scc_values.add_element(scc, fr_static);
837     }
838
839     /// Once regions have been propagated, this method is used to see
840     /// whether the "type tests" produced by typeck were satisfied;
841     /// type tests encode type-outlives relationships like `T:
842     /// 'a`. See `TypeTest` for more details.
843     fn check_type_tests(
844         &self,
845         infcx: &InferCtxt<'_, 'tcx>,
846         body: &Body<'tcx>,
847         mir_def_id: DefId,
848         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
849         errors_buffer: &mut Vec<Diagnostic>,
850     ) {
851         let tcx = infcx.tcx;
852
853         // Sometimes we register equivalent type-tests that would
854         // result in basically the exact same error being reported to
855         // the user. Avoid that.
856         let mut deduplicate_errors = FxHashSet::default();
857
858         for type_test in &self.type_tests {
859             debug!("check_type_test: {:?}", type_test);
860
861             let generic_ty = type_test.generic_kind.to_ty(tcx);
862             if self.eval_verify_bound(
863                 tcx,
864                 body,
865                 generic_ty,
866                 type_test.lower_bound,
867                 &type_test.verify_bound,
868             ) {
869                 continue;
870             }
871
872             if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
873                 if self.try_promote_type_test(
874                     infcx,
875                     body,
876                     type_test,
877                     propagated_outlives_requirements,
878                 ) {
879                     continue;
880                 }
881             }
882
883             // Type-test failed. Report the error.
884
885             // Try to convert the lower-bound region into something named we can print for the user.
886             let lower_bound_region = self.to_error_region(type_test.lower_bound);
887
888             // Skip duplicate-ish errors.
889             let type_test_span = type_test.locations.span(body);
890             let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
891             if !deduplicate_errors.insert((
892                 erased_generic_kind,
893                 lower_bound_region,
894                 type_test.locations,
895             )) {
896                 continue;
897             } else {
898                 debug!(
899                     "check_type_test: reporting error for erased_generic_kind={:?}, \
900                      lower_bound_region={:?}, \
901                      type_test.locations={:?}",
902                     erased_generic_kind, lower_bound_region, type_test.locations,
903                 );
904             }
905
906             if let Some(lower_bound_region) = lower_bound_region {
907                 let region_scope_tree = &tcx.region_scope_tree(mir_def_id);
908                 infcx
909                     .construct_generic_bound_failure(
910                         region_scope_tree,
911                         type_test_span,
912                         None,
913                         type_test.generic_kind,
914                         lower_bound_region,
915                     )
916                     .buffer(errors_buffer);
917             } else {
918                 // FIXME. We should handle this case better. It
919                 // indicates that we have e.g., some region variable
920                 // whose value is like `'a+'b` where `'a` and `'b` are
921                 // distinct unrelated univesal regions that are not
922                 // known to outlive one another. It'd be nice to have
923                 // some examples where this arises to decide how best
924                 // to report it; we could probably handle it by
925                 // iterating over the universal regions and reporting
926                 // an error that multiple bounds are required.
927                 tcx.sess
928                     .struct_span_err(
929                         type_test_span,
930                         &format!("`{}` does not live long enough", type_test.generic_kind,),
931                     )
932                     .buffer(errors_buffer);
933             }
934         }
935     }
936
937     /// Converts a region inference variable into a `ty::Region` that
938     /// we can use for error reporting. If `r` is universally bound,
939     /// then we use the name that we have on record for it. If `r` is
940     /// existentially bound, then we check its inferred value and try
941     /// to find a good name from that. Returns `None` if we can't find
942     /// one (e.g., this is just some random part of the CFG).
943     pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
944         self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
945     }
946
947     /// Returns the [RegionVid] corresponding to the region returned by
948     /// `to_error_region`.
949     pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
950         if self.universal_regions.is_universal_region(r) {
951             Some(r)
952         } else {
953             let r_scc = self.constraint_sccs.scc(r);
954             let upper_bound = self.universal_upper_bound(r);
955             if self.scc_values.contains(r_scc, upper_bound) {
956                 self.to_error_region_vid(upper_bound)
957             } else {
958                 None
959             }
960         }
961     }
962
963     /// Invoked when we have some type-test (e.g., `T: 'X`) that we cannot
964     /// prove to be satisfied. If this is a closure, we will attempt to
965     /// "promote" this type-test into our `ClosureRegionRequirements` and
966     /// hence pass it up the creator. To do this, we have to phrase the
967     /// type-test in terms of external free regions, as local free
968     /// regions are not nameable by the closure's creator.
969     ///
970     /// Promotion works as follows: we first check that the type `T`
971     /// contains only regions that the creator knows about. If this is
972     /// true, then -- as a consequence -- we know that all regions in
973     /// the type `T` are free regions that outlive the closure body. If
974     /// false, then promotion fails.
975     ///
976     /// Once we've promoted T, we have to "promote" `'X` to some region
977     /// that is "external" to the closure. Generally speaking, a region
978     /// may be the union of some points in the closure body as well as
979     /// various free lifetimes. We can ignore the points in the closure
980     /// body: if the type T can be expressed in terms of external regions,
981     /// we know it outlives the points in the closure body. That
982     /// just leaves the free regions.
983     ///
984     /// The idea then is to lower the `T: 'X` constraint into multiple
985     /// bounds -- e.g., if `'X` is the union of two free lifetimes,
986     /// `'1` and `'2`, then we would create `T: '1` and `T: '2`.
987     fn try_promote_type_test(
988         &self,
989         infcx: &InferCtxt<'_, 'tcx>,
990         body: &Body<'tcx>,
991         type_test: &TypeTest<'tcx>,
992         propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
993     ) -> bool {
994         let tcx = infcx.tcx;
995
996         let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
997
998         let generic_ty = generic_kind.to_ty(tcx);
999         let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
1000             Some(s) => s,
1001             None => return false,
1002         };
1003
1004         // For each region outlived by lower_bound find a non-local,
1005         // universal region (it may be the same region) and add it to
1006         // `ClosureOutlivesRequirement`.
1007         let r_scc = self.constraint_sccs.scc(*lower_bound);
1008         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
1009             // Check whether we can already prove that the "subject" outlives `ur`.
1010             // If so, we don't have to propagate this requirement to our caller.
1011             //
1012             // To continue the example from the function, if we are trying to promote
1013             // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
1014             // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
1015             // we check whether `T: '1` is something we *can* prove. If so, no need
1016             // to propagate that requirement.
1017             //
1018             // This is needed because -- particularly in the case
1019             // where `ur` is a local bound -- we are sometimes in a
1020             // position to prove things that our caller cannot.  See
1021             // #53570 for an example.
1022             if self.eval_verify_bound(tcx, body, generic_ty, ur, &type_test.verify_bound) {
1023                 continue;
1024             }
1025
1026             debug!("try_promote_type_test: ur={:?}", ur);
1027
1028             let non_local_ub = self.universal_region_relations.non_local_upper_bounds(&ur);
1029             debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
1030
1031             // This is slightly too conservative. To show T: '1, given `'2: '1`
1032             // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
1033             // avoid potential non-determinism we approximate this by requiring
1034             // T: '1 and T: '2.
1035             for &upper_bound in non_local_ub {
1036                 debug_assert!(self.universal_regions.is_universal_region(upper_bound));
1037                 debug_assert!(!self.universal_regions.is_local_free_region(upper_bound));
1038
1039                 let requirement = ClosureOutlivesRequirement {
1040                     subject,
1041                     outlived_free_region: upper_bound,
1042                     blame_span: locations.span(body),
1043                     category: ConstraintCategory::Boring,
1044                 };
1045                 debug!("try_promote_type_test: pushing {:#?}", requirement);
1046                 propagated_outlives_requirements.push(requirement);
1047             }
1048         }
1049         true
1050     }
1051
1052     /// When we promote a type test `T: 'r`, we have to convert the
1053     /// type `T` into something we can store in a query result (so
1054     /// something allocated for `'tcx`). This is problematic if `ty`
1055     /// contains regions. During the course of NLL region checking, we
1056     /// will have replaced all of those regions with fresh inference
1057     /// variables. To create a test subject, we want to replace those
1058     /// inference variables with some region from the closure
1059     /// signature -- this is not always possible, so this is a
1060     /// fallible process. Presuming we do find a suitable region, we
1061     /// will represent it with a `ReClosureBound`, which is a
1062     /// `RegionKind` variant that can be allocated in the gcx.
1063     fn try_promote_type_test_subject(
1064         &self,
1065         infcx: &InferCtxt<'_, 'tcx>,
1066         ty: Ty<'tcx>,
1067     ) -> Option<ClosureOutlivesSubject<'tcx>> {
1068         let tcx = infcx.tcx;
1069
1070         debug!("try_promote_type_test_subject(ty = {:?})", ty);
1071
1072         let ty = tcx.fold_regions(&ty, &mut false, |r, _depth| {
1073             let region_vid = self.to_region_vid(r);
1074
1075             // The challenge if this. We have some region variable `r`
1076             // whose value is a set of CFG points and universal
1077             // regions. We want to find if that set is *equivalent* to
1078             // any of the named regions found in the closure.
1079             //
1080             // To do so, we compute the
1081             // `non_local_universal_upper_bound`. This will be a
1082             // non-local, universal region that is greater than `r`.
1083             // However, it might not be *contained* within `r`, so
1084             // then we further check whether this bound is contained
1085             // in `r`. If so, we can say that `r` is equivalent to the
1086             // bound.
1087             //
1088             // Let's work through a few examples. For these, imagine
1089             // that we have 3 non-local regions (I'll denote them as
1090             // `'static`, `'a`, and `'b`, though of course in the code
1091             // they would be represented with indices) where:
1092             //
1093             // - `'static: 'a`
1094             // - `'static: 'b`
1095             //
1096             // First, let's assume that `r` is some existential
1097             // variable with an inferred value `{'a, 'static}` (plus
1098             // some CFG nodes). In this case, the non-local upper
1099             // bound is `'static`, since that outlives `'a`. `'static`
1100             // is also a member of `r` and hence we consider `r`
1101             // equivalent to `'static` (and replace it with
1102             // `'static`).
1103             //
1104             // Now let's consider the inferred value `{'a, 'b}`. This
1105             // means `r` is effectively `'a | 'b`. I'm not sure if
1106             // this can come about, actually, but assuming it did, we
1107             // would get a non-local upper bound of `'static`. Since
1108             // `'static` is not contained in `r`, we would fail to
1109             // find an equivalent.
1110             let upper_bound = self.non_local_universal_upper_bound(region_vid);
1111             if self.region_contains(region_vid, upper_bound) {
1112                 tcx.mk_region(ty::ReClosureBound(upper_bound))
1113             } else {
1114                 // In the case of a failure, use a `ReVar`
1115                 // result. This will cause the `lift` later on to
1116                 // fail.
1117                 r
1118             }
1119         });
1120         debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
1121
1122         // `has_local_value` will only be true if we failed to promote some region.
1123         if ty.has_local_value() {
1124             return None;
1125         }
1126
1127         Some(ClosureOutlivesSubject::Ty(ty))
1128     }
1129
1130     /// Given some universal or existential region `r`, finds a
1131     /// non-local, universal region `r+` that outlives `r` at entry to (and
1132     /// exit from) the closure. In the worst case, this will be
1133     /// `'static`.
1134     ///
1135     /// This is used for two purposes. First, if we are propagated
1136     /// some requirement `T: r`, we can use this method to enlarge `r`
1137     /// to something we can encode for our creator (which only knows
1138     /// about non-local, universal regions). It is also used when
1139     /// encoding `T` as part of `try_promote_type_test_subject` (see
1140     /// that fn for details).
1141     ///
1142     /// This is based on the result `'y` of `universal_upper_bound`,
1143     /// except that it converts further takes the non-local upper
1144     /// bound of `'y`, so that the final result is non-local.
1145     fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1146         debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
1147
1148         let lub = self.universal_upper_bound(r);
1149
1150         // Grow further to get smallest universal region known to
1151         // creator.
1152         let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub);
1153
1154         debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub);
1155
1156         non_local_lub
1157     }
1158
1159     /// Returns a universally quantified region that outlives the
1160     /// value of `r` (`r` may be existentially or universally
1161     /// quantified).
1162     ///
1163     /// Since `r` is (potentially) an existential region, it has some
1164     /// value which may include (a) any number of points in the CFG
1165     /// and (b) any number of `end('x)` elements of universally
1166     /// quantified regions. To convert this into a single universal
1167     /// region we do as follows:
1168     ///
1169     /// - Ignore the CFG points in `'r`. All universally quantified regions
1170     ///   include the CFG anyhow.
1171     /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
1172     ///   a result `'y`.
1173     fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1174         debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
1175
1176         // Find the smallest universal region that contains all other
1177         // universal regions within `region`.
1178         let mut lub = self.universal_regions.fr_fn_body;
1179         let r_scc = self.constraint_sccs.scc(r);
1180         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
1181             lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
1182         }
1183
1184         debug!("universal_upper_bound: r={:?} lub={:?}", r, lub);
1185
1186         lub
1187     }
1188
1189     /// Tests if `test` is true when applied to `lower_bound` at
1190     /// `point`.
1191     fn eval_verify_bound(
1192         &self,
1193         tcx: TyCtxt<'tcx>,
1194         body: &Body<'tcx>,
1195         generic_ty: Ty<'tcx>,
1196         lower_bound: RegionVid,
1197         verify_bound: &VerifyBound<'tcx>,
1198     ) -> bool {
1199         debug!("eval_verify_bound(lower_bound={:?}, verify_bound={:?})", lower_bound, verify_bound);
1200
1201         match verify_bound {
1202             VerifyBound::IfEq(test_ty, verify_bound1) => {
1203                 self.eval_if_eq(tcx, body, generic_ty, lower_bound, test_ty, verify_bound1)
1204             }
1205
1206             VerifyBound::OutlivedBy(r) => {
1207                 let r_vid = self.to_region_vid(r);
1208                 self.eval_outlives(r_vid, lower_bound)
1209             }
1210
1211             VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| {
1212                 self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1213             }),
1214
1215             VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| {
1216                 self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1217             }),
1218         }
1219     }
1220
1221     fn eval_if_eq(
1222         &self,
1223         tcx: TyCtxt<'tcx>,
1224         body: &Body<'tcx>,
1225         generic_ty: Ty<'tcx>,
1226         lower_bound: RegionVid,
1227         test_ty: Ty<'tcx>,
1228         verify_bound: &VerifyBound<'tcx>,
1229     ) -> bool {
1230         let generic_ty_normalized = self.normalize_to_scc_representatives(tcx, generic_ty);
1231         let test_ty_normalized = self.normalize_to_scc_representatives(tcx, test_ty);
1232         if generic_ty_normalized == test_ty_normalized {
1233             self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1234         } else {
1235             false
1236         }
1237     }
1238
1239     /// This is a conservative normalization procedure. It takes every
1240     /// free region in `value` and replaces it with the
1241     /// "representative" of its SCC (see `scc_representatives` field).
1242     /// We are guaranteed that if two values normalize to the same
1243     /// thing, then they are equal; this is a conservative check in
1244     /// that they could still be equal even if they normalize to
1245     /// different results. (For example, there might be two regions
1246     /// with the same value that are not in the same SCC).
1247     ///
1248     /// N.B., this is not an ideal approach and I would like to revisit
1249     /// it. However, it works pretty well in practice. In particular,
1250     /// this is needed to deal with projection outlives bounds like
1251     ///
1252     ///     <T as Foo<'0>>::Item: '1
1253     ///
1254     /// In particular, this routine winds up being important when
1255     /// there are bounds like `where <T as Foo<'a>>::Item: 'b` in the
1256     /// environment. In this case, if we can show that `'0 == 'a`,
1257     /// and that `'b: '1`, then we know that the clause is
1258     /// satisfied. In such cases, particularly due to limitations of
1259     /// the trait solver =), we usually wind up with a where-clause like
1260     /// `T: Foo<'a>` in scope, which thus forces `'0 == 'a` to be added as
1261     /// a constraint, and thus ensures that they are in the same SCC.
1262     ///
1263     /// So why can't we do a more correct routine? Well, we could
1264     /// *almost* use the `relate_tys` code, but the way it is
1265     /// currently setup it creates inference variables to deal with
1266     /// higher-ranked things and so forth, and right now the inference
1267     /// context is not permitted to make more inference variables. So
1268     /// we use this kind of hacky solution.
1269     fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
1270     where
1271         T: TypeFoldable<'tcx>,
1272     {
1273         tcx.fold_regions(&value, &mut false, |r, _db| {
1274             let vid = self.to_region_vid(r);
1275             let scc = self.constraint_sccs.scc(vid);
1276             let repr = self.scc_representatives[scc];
1277             tcx.mk_region(ty::ReVar(repr))
1278         })
1279     }
1280
1281     // Evaluate whether `sup_region == sub_region`.
1282     fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
1283         self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1)
1284     }
1285
1286     // Evaluate whether `sup_region: sub_region`.
1287     fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
1288         debug!("eval_outlives({:?}: {:?})", sup_region, sub_region);
1289
1290         debug!(
1291             "eval_outlives: sup_region's value = {:?} universal={:?}",
1292             self.region_value_str(sup_region),
1293             self.universal_regions.is_universal_region(sup_region),
1294         );
1295         debug!(
1296             "eval_outlives: sub_region's value = {:?} universal={:?}",
1297             self.region_value_str(sub_region),
1298             self.universal_regions.is_universal_region(sub_region),
1299         );
1300
1301         let sub_region_scc = self.constraint_sccs.scc(sub_region);
1302         let sup_region_scc = self.constraint_sccs.scc(sup_region);
1303
1304         // Both the `sub_region` and `sup_region` consist of the union
1305         // of some number of universal regions (along with the union
1306         // of various points in the CFG; ignore those points for
1307         // now). Therefore, the sup-region outlives the sub-region if,
1308         // for each universal region R1 in the sub-region, there
1309         // exists some region R2 in the sup-region that outlives R1.
1310         let universal_outlives =
1311             self.scc_values.universal_regions_outlived_by(sub_region_scc).all(|r1| {
1312                 self.scc_values
1313                     .universal_regions_outlived_by(sup_region_scc)
1314                     .any(|r2| self.universal_region_relations.outlives(r2, r1))
1315             });
1316
1317         if !universal_outlives {
1318             return false;
1319         }
1320
1321         // Now we have to compare all the points in the sub region and make
1322         // sure they exist in the sup region.
1323
1324         if self.universal_regions.is_universal_region(sup_region) {
1325             // Micro-opt: universal regions contain all points.
1326             return true;
1327         }
1328
1329         self.scc_values.contains_points(sup_region_scc, sub_region_scc)
1330     }
1331
1332     /// Once regions have been propagated, this method is used to see
1333     /// whether any of the constraints were too strong. In particular,
1334     /// we want to check for a case where a universally quantified
1335     /// region exceeded its bounds. Consider:
1336     ///
1337     ///     fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
1338     ///
1339     /// In this case, returning `x` requires `&'a u32 <: &'b u32`
1340     /// and hence we establish (transitively) a constraint that
1341     /// `'a: 'b`. The `propagate_constraints` code above will
1342     /// therefore add `end('a)` into the region for `'b` -- but we
1343     /// have no evidence that `'b` outlives `'a`, so we want to report
1344     /// an error.
1345     ///
1346     /// If `propagated_outlives_requirements` is `Some`, then we will
1347     /// push unsatisfied obligations into there. Otherwise, we'll
1348     /// report them as errors.
1349     fn check_universal_regions(
1350         &self,
1351         infcx: &InferCtxt<'_, 'tcx>,
1352         body: &Body<'tcx>,
1353         local_names: &IndexVec<Local, Option<Symbol>>,
1354         upvars: &[Upvar],
1355         mir_def_id: DefId,
1356         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1357         errors_buffer: &mut Vec<Diagnostic>,
1358         region_naming: &mut RegionErrorNamingCtx,
1359     ) {
1360         let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id, local_names);
1361
1362         for (fr, fr_definition) in self.definitions.iter_enumerated() {
1363             match fr_definition.origin {
1364                 NLLRegionVariableOrigin::FreeRegion => {
1365                     // Go through each of the universal regions `fr` and check that
1366                     // they did not grow too large, accumulating any requirements
1367                     // for our caller into the `outlives_requirements` vector.
1368                     self.check_universal_region(
1369                         infcx,
1370                         body,
1371                         local_names,
1372                         upvars,
1373                         mir_def_id,
1374                         fr,
1375                         &mut propagated_outlives_requirements,
1376                         &mut outlives_suggestion,
1377                         errors_buffer,
1378                         region_naming,
1379                     );
1380                 }
1381
1382                 NLLRegionVariableOrigin::Placeholder(placeholder) => {
1383                     self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
1384                 }
1385
1386                 NLLRegionVariableOrigin::Existential { .. } => {
1387                     // nothing to check here
1388                 }
1389             }
1390         }
1391
1392         // Emit outlives suggestions
1393         outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
1394     }
1395
1396     /// Checks if Polonius has found any unexpected free region relations.
1397     ///
1398     /// In Polonius terms, a "subset error" (or "illegal subset relation error") is the equivalent
1399     /// of NLL's "checking if any region constraints were too strong": a placeholder origin `'a`
1400     /// was unexpectedly found to be a subset of another placeholder origin `'b`, and means in NLL
1401     /// terms that the "longer free region" `'a` outlived the "shorter free region" `'b`.
1402     ///
1403     /// More details can be found in this blog post by Niko:
1404     /// http://smallcultfollowing.com/babysteps/blog/2019/01/17/polonius-and-region-errors/
1405     ///
1406     /// In the canonical example
1407     ///
1408     ///     fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
1409     ///
1410     /// returning `x` requires `&'a u32 <: &'b u32` and hence we establish (transitively) a
1411     /// constraint that `'a: 'b`. It is an error that we have no evidence that this
1412     /// constraint holds.
1413     ///
1414     /// If `propagated_outlives_requirements` is `Some`, then we will
1415     /// push unsatisfied obligations into there. Otherwise, we'll
1416     /// report them as errors.
1417     fn check_polonius_subset_errors(
1418         &self,
1419         infcx: &InferCtxt<'_, 'tcx>,
1420         body: &Body<'tcx>,
1421         local_names: &IndexVec<Local, Option<Symbol>>,
1422         upvars: &[Upvar],
1423         mir_def_id: DefId,
1424         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1425         errors_buffer: &mut Vec<Diagnostic>,
1426         region_naming: &mut RegionErrorNamingCtx,
1427         polonius_output: Rc<PoloniusOutput>,
1428     ) {
1429         debug!(
1430             "check_polonius_subset_errors: {} subset_errors",
1431             polonius_output.subset_errors.len()
1432         );
1433
1434         let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id, local_names);
1435
1436         // Similarly to `check_universal_regions`: a free region relation, which was not explicitly
1437         // declared ("known") was found by Polonius, so emit an error, or propagate the
1438         // requirements for our caller into the `propagated_outlives_requirements` vector.
1439         //
1440         // Polonius doesn't model regions ("origins") as CFG-subsets or durations, but the
1441         // `longer_fr` and `shorter_fr` terminology will still be used here, for consistency with
1442         // the rest of the NLL infrastructure. The "subset origin" is the "longer free region",
1443         // and the "superset origin" is the outlived "shorter free region".
1444         //
1445         // Note: Polonius will produce a subset error at every point where the unexpected
1446         // `longer_fr`'s "placeholder loan" is contained in the `shorter_fr`. This can be helpful
1447         // for diagnostics in the future, e.g. to point more precisely at the key locations
1448         // requiring this constraint to hold. However, the error and diagnostics code downstream
1449         // expects that these errors are not duplicated (and that they are in a certain order).
1450         // Otherwise, diagnostics messages such as the ones giving names like `'1` to elided or
1451         // anonymous lifetimes for example, could give these names differently, while others like
1452         // the outlives suggestions or the debug output from `#[rustc_regions]` would be
1453         // duplicated. The polonius subset errors are deduplicated here, while keeping the
1454         // CFG-location ordering.
1455         let mut subset_errors: Vec<_> = polonius_output
1456             .subset_errors
1457             .iter()
1458             .flat_map(|(_location, subset_errors)| subset_errors.iter())
1459             .collect();
1460         subset_errors.sort();
1461         subset_errors.dedup();
1462
1463         for (longer_fr, shorter_fr) in subset_errors.into_iter() {
1464             debug!("check_polonius_subset_errors: subset_error longer_fr={:?},\
1465                 shorter_fr={:?}", longer_fr, shorter_fr);
1466
1467             self.report_or_propagate_universal_region_error(
1468                 *longer_fr,
1469                 *shorter_fr,
1470                 infcx,
1471                 body,
1472                 local_names,
1473                 upvars,
1474                 mir_def_id,
1475                 &mut propagated_outlives_requirements,
1476                 &mut outlives_suggestion,
1477                 errors_buffer,
1478                 region_naming,
1479             );
1480         }
1481
1482         // Handle the placeholder errors as usual, until the chalk-rustc-polonius triumvirate has
1483         // a more complete picture on how to separate this responsibility.
1484         for (fr, fr_definition) in self.definitions.iter_enumerated() {
1485             match fr_definition.origin {
1486                 NLLRegionVariableOrigin::FreeRegion => {
1487                     // handled by polonius above
1488                 }
1489
1490                 NLLRegionVariableOrigin::Placeholder(placeholder) => {
1491                     self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
1492                 }
1493
1494                 NLLRegionVariableOrigin::Existential { .. } => {
1495                     // nothing to check here
1496                 }
1497             }
1498         }
1499
1500         // Emit outlives suggestions
1501         outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
1502     }
1503
1504     /// Checks the final value for the free region `fr` to see if it
1505     /// grew too large. In particular, examine what `end(X)` points
1506     /// wound up in `fr`'s final value; for each `end(X)` where `X !=
1507     /// fr`, we want to check that `fr: X`. If not, that's either an
1508     /// error, or something we have to propagate to our creator.
1509     ///
1510     /// Things that are to be propagated are accumulated into the
1511     /// `outlives_requirements` vector.
1512     fn check_universal_region(
1513         &self,
1514         infcx: &InferCtxt<'_, 'tcx>,
1515         body: &Body<'tcx>,
1516         local_names: &IndexVec<Local, Option<Symbol>>,
1517         upvars: &[Upvar],
1518         mir_def_id: DefId,
1519         longer_fr: RegionVid,
1520         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1521         outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1522         errors_buffer: &mut Vec<Diagnostic>,
1523         region_naming: &mut RegionErrorNamingCtx,
1524     ) {
1525         debug!("check_universal_region(fr={:?})", longer_fr);
1526
1527         let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
1528
1529         // Because this free region must be in the ROOT universe, we
1530         // know it cannot contain any bound universes.
1531         assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT);
1532         debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
1533
1534         // Only check all of the relations for the main representative of each
1535         // SCC, otherwise just check that we outlive said representative. This
1536         // reduces the number of redundant relations propagated out of
1537         // closures.
1538         // Note that the representative will be a universal region if there is
1539         // one in this SCC, so we will always check the representative here.
1540         let representative = self.scc_representatives[longer_fr_scc];
1541         if representative != longer_fr {
1542             self.check_universal_region_relation(
1543                 longer_fr,
1544                 representative,
1545                 infcx,
1546                 body,
1547                 local_names,
1548                 upvars,
1549                 mir_def_id,
1550                 propagated_outlives_requirements,
1551                 outlives_suggestion,
1552                 errors_buffer,
1553                 region_naming,
1554             );
1555             return;
1556         }
1557
1558         // Find every region `o` such that `fr: o`
1559         // (because `fr` includes `end(o)`).
1560         for shorter_fr in self.scc_values.universal_regions_outlived_by(longer_fr_scc) {
1561             if let Some(ErrorReported) = self.check_universal_region_relation(
1562                 longer_fr,
1563                 shorter_fr,
1564                 infcx,
1565                 body,
1566                 local_names,
1567                 upvars,
1568                 mir_def_id,
1569                 propagated_outlives_requirements,
1570                 outlives_suggestion,
1571                 errors_buffer,
1572                 region_naming,
1573             ) {
1574                 // continuing to iterate just reports more errors than necessary
1575                 //
1576                 // FIXME It would also allow us to report more Outlives Suggestions, though, so
1577                 // it's not clear that that's a bad thing. Somebody should try commenting out this
1578                 // line and see it is actually a regression.
1579                 return;
1580             }
1581         }
1582     }
1583
1584     fn check_universal_region_relation(
1585         &self,
1586         longer_fr: RegionVid,
1587         shorter_fr: RegionVid,
1588         infcx: &InferCtxt<'_, 'tcx>,
1589         body: &Body<'tcx>,
1590         local_names: &IndexVec<Local, Option<Symbol>>,
1591         upvars: &[Upvar],
1592         mir_def_id: DefId,
1593         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1594         outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1595         errors_buffer: &mut Vec<Diagnostic>,
1596         region_naming: &mut RegionErrorNamingCtx,
1597     ) -> Option<ErrorReported> {
1598         // If it is known that `fr: o`, carry on.
1599         if self.universal_region_relations.outlives(longer_fr, shorter_fr) {
1600             return None;
1601         }
1602
1603         self.report_or_propagate_universal_region_error(
1604             longer_fr,
1605             shorter_fr,
1606             infcx,
1607             body,
1608             local_names,
1609             upvars,
1610             mir_def_id,
1611             propagated_outlives_requirements,
1612             outlives_suggestion,
1613             errors_buffer,
1614             region_naming,
1615         )
1616     }
1617
1618     fn report_or_propagate_universal_region_error(
1619         &self,
1620         longer_fr: RegionVid,
1621         shorter_fr: RegionVid,
1622         infcx: &InferCtxt<'_, 'tcx>,
1623         body: &Body<'tcx>,
1624         local_names: &IndexVec<Local, Option<Symbol>>,
1625         upvars: &[Upvar],
1626         mir_def_id: DefId,
1627         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1628         outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1629         errors_buffer: &mut Vec<Diagnostic>,
1630         region_naming: &mut RegionErrorNamingCtx,
1631     ) -> Option<ErrorReported> {
1632         debug!(
1633             "report_or_propagate_universal_region_error: fr={:?} does not outlive shorter_fr={:?}",
1634             longer_fr, shorter_fr,
1635         );
1636
1637         if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
1638             // Shrink `longer_fr` until we find a non-local region (if we do).
1639             // We'll call it `fr-` -- it's ever so slightly smaller than
1640             // `longer_fr`.
1641
1642             if let Some(fr_minus) =
1643                 self.universal_region_relations.non_local_lower_bound(longer_fr) {
1644                 debug!("report_or_propagate_universal_region_error: fr_minus={:?}", fr_minus);
1645
1646                 let blame_span_category =
1647                     self.find_outlives_blame_span(body, longer_fr,
1648                                                   NLLRegionVariableOrigin::FreeRegion,shorter_fr);
1649
1650                 // Grow `shorter_fr` until we find some non-local regions. (We
1651                 // always will.)  We'll call them `shorter_fr+` -- they're ever
1652                 // so slightly larger than `shorter_fr`.
1653                 let shorter_fr_plus = self
1654                     .universal_region_relations
1655                     .non_local_upper_bounds(&shorter_fr);
1656                 debug!(
1657                     "report_or_propagate_universal_region_error: shorter_fr_plus={:?}",
1658                     shorter_fr_plus
1659                 );
1660                 for &&fr in &shorter_fr_plus {
1661                     // Push the constraint `fr-: shorter_fr+`
1662                     propagated_outlives_requirements.push(ClosureOutlivesRequirement {
1663                         subject: ClosureOutlivesSubject::Region(fr_minus),
1664                         outlived_free_region: fr,
1665                         blame_span: blame_span_category.1,
1666                         category: blame_span_category.0,
1667                     });
1668                 }
1669                 return None;
1670             }
1671         }
1672
1673         // If we are not in a context where we can't propagate errors, or we
1674         // could not shrink `fr` to something smaller, then just report an
1675         // error.
1676         //
1677         // Note: in this case, we use the unapproximated regions to report the
1678         // error. This gives better error messages in some cases.
1679         let db = self.report_error(
1680             body,
1681             local_names,
1682             upvars,
1683             infcx,
1684             mir_def_id,
1685             longer_fr,
1686             NLLRegionVariableOrigin::FreeRegion,
1687             shorter_fr,
1688             outlives_suggestion,
1689             region_naming,
1690         );
1691
1692         db.buffer(errors_buffer);
1693
1694         Some(ErrorReported)
1695     }
1696
1697     fn check_bound_universal_region(
1698         &self,
1699         infcx: &InferCtxt<'_, 'tcx>,
1700         body: &Body<'tcx>,
1701         _mir_def_id: DefId,
1702         longer_fr: RegionVid,
1703         placeholder: ty::PlaceholderRegion,
1704     ) {
1705         debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,);
1706
1707         let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
1708         debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,);
1709
1710         // If we have some bound universal region `'a`, then the only
1711         // elements it can contain is itself -- we don't know anything
1712         // else about it!
1713         let error_element = match {
1714             self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element {
1715                 RegionElement::Location(_) => true,
1716                 RegionElement::RootUniversalRegion(_) => true,
1717                 RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1,
1718             })
1719         } {
1720             Some(v) => v,
1721             None => return,
1722         };
1723         debug!("check_bound_universal_region: error_element = {:?}", error_element);
1724
1725         // Find the region that introduced this `error_element`.
1726         let error_region = match error_element {
1727             RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
1728             RegionElement::RootUniversalRegion(r) => r,
1729             RegionElement::PlaceholderRegion(error_placeholder) => self
1730                 .definitions
1731                 .iter_enumerated()
1732                 .filter_map(|(r, definition)| match definition.origin {
1733                     NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
1734                     _ => None,
1735                 })
1736                 .next()
1737                 .unwrap(),
1738         };
1739
1740         // Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
1741         let (_, span) = self.find_outlives_blame_span(
1742             body, longer_fr, NLLRegionVariableOrigin::Placeholder(placeholder), error_region
1743         );
1744
1745         // Obviously, this error message is far from satisfactory.
1746         // At present, though, it only appears in unit tests --
1747         // the AST-based checker uses a more conservative check,
1748         // so to even see this error, one must pass in a special
1749         // flag.
1750         let mut diag = infcx.tcx.sess.struct_span_err(span, "higher-ranked subtype error");
1751         diag.emit();
1752     }
1753
1754     fn check_member_constraints(
1755         &self,
1756         infcx: &InferCtxt<'_, 'tcx>,
1757         mir_def_id: DefId,
1758         errors_buffer: &mut Vec<Diagnostic>,
1759     ) {
1760         let member_constraints = self.member_constraints.clone();
1761         for m_c_i in member_constraints.all_indices() {
1762             debug!("check_member_constraint(m_c_i={:?})", m_c_i);
1763             let m_c = &member_constraints[m_c_i];
1764             let member_region_vid = m_c.member_region_vid;
1765             debug!(
1766                 "check_member_constraint: member_region_vid={:?} with value {}",
1767                 member_region_vid,
1768                 self.region_value_str(member_region_vid),
1769             );
1770             let choice_regions = member_constraints.choice_regions(m_c_i);
1771             debug!("check_member_constraint: choice_regions={:?}", choice_regions);
1772
1773             // Did the member region wind up equal to any of the option regions?
1774             if let Some(o) = choice_regions.iter().find(|&&o_r| {
1775                 self.eval_equal(o_r, m_c.member_region_vid)
1776             }) {
1777                 debug!("check_member_constraint: evaluated as equal to {:?}", o);
1778                 continue;
1779             }
1780
1781             // If not, report an error.
1782             let region_scope_tree = &infcx.tcx.region_scope_tree(mir_def_id);
1783             let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
1784             opaque_types::unexpected_hidden_region_diagnostic(
1785                 infcx.tcx,
1786                 Some(region_scope_tree),
1787                 m_c.opaque_type_def_id,
1788                 m_c.hidden_ty,
1789                 member_region,
1790             )
1791             .buffer(errors_buffer);
1792         }
1793     }
1794 }
1795
1796 impl<'tcx> RegionDefinition<'tcx> {
1797     fn new(universe: ty::UniverseIndex, rv_origin: RegionVariableOrigin) -> Self {
1798         // Create a new region definition. Note that, for free
1799         // regions, the `external_name` field gets updated later in
1800         // `init_universal_regions`.
1801
1802         let origin = match rv_origin {
1803             RegionVariableOrigin::NLL(origin) => origin,
1804             _ => NLLRegionVariableOrigin::Existential { from_forall: false },
1805         };
1806
1807         Self { origin, universe, external_name: None }
1808     }
1809 }
1810
1811 pub trait ClosureRegionRequirementsExt<'tcx> {
1812     fn apply_requirements(
1813         &self,
1814         tcx: TyCtxt<'tcx>,
1815         closure_def_id: DefId,
1816         closure_substs: SubstsRef<'tcx>,
1817     ) -> Vec<QueryOutlivesConstraint<'tcx>>;
1818
1819     fn subst_closure_mapping<T>(
1820         &self,
1821         tcx: TyCtxt<'tcx>,
1822         closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
1823         value: &T,
1824     ) -> T
1825     where
1826         T: TypeFoldable<'tcx>;
1827 }
1828
1829 impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> {
1830     /// Given an instance T of the closure type, this method
1831     /// instantiates the "extra" requirements that we computed for the
1832     /// closure into the inference context. This has the effect of
1833     /// adding new outlives obligations to existing variables.
1834     ///
1835     /// As described on `ClosureRegionRequirements`, the extra
1836     /// requirements are expressed in terms of regionvids that index
1837     /// into the free regions that appear on the closure type. So, to
1838     /// do this, we first copy those regions out from the type T into
1839     /// a vector. Then we can just index into that vector to extract
1840     /// out the corresponding region from T and apply the
1841     /// requirements.
1842     fn apply_requirements(
1843         &self,
1844         tcx: TyCtxt<'tcx>,
1845         closure_def_id: DefId,
1846         closure_substs: SubstsRef<'tcx>,
1847     ) -> Vec<QueryOutlivesConstraint<'tcx>> {
1848         debug!(
1849             "apply_requirements(closure_def_id={:?}, closure_substs={:?})",
1850             closure_def_id, closure_substs
1851         );
1852
1853         // Extract the values of the free regions in `closure_substs`
1854         // into a vector.  These are the regions that we will be
1855         // relating to one another.
1856         let closure_mapping = &UniversalRegions::closure_mapping(
1857             tcx,
1858             closure_substs,
1859             self.num_external_vids,
1860             tcx.closure_base_def_id(closure_def_id),
1861         );
1862         debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
1863
1864         // Create the predicates.
1865         self.outlives_requirements
1866             .iter()
1867             .map(|outlives_requirement| {
1868                 let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
1869
1870                 match outlives_requirement.subject {
1871                     ClosureOutlivesSubject::Region(region) => {
1872                         let region = closure_mapping[region];
1873                         debug!(
1874                             "apply_requirements: region={:?} \
1875                              outlived_region={:?} \
1876                              outlives_requirement={:?}",
1877                             region, outlived_region, outlives_requirement,
1878                         );
1879                         ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region))
1880                     }
1881
1882                     ClosureOutlivesSubject::Ty(ty) => {
1883                         let ty = self.subst_closure_mapping(tcx, closure_mapping, &ty);
1884                         debug!(
1885                             "apply_requirements: ty={:?} \
1886                              outlived_region={:?} \
1887                              outlives_requirement={:?}",
1888                             ty, outlived_region, outlives_requirement,
1889                         );
1890                         ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region))
1891                     }
1892                 }
1893             })
1894             .collect()
1895     }
1896
1897     fn subst_closure_mapping<T>(
1898         &self,
1899         tcx: TyCtxt<'tcx>,
1900         closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
1901         value: &T,
1902     ) -> T
1903     where
1904         T: TypeFoldable<'tcx>,
1905     {
1906         tcx.fold_regions(value, &mut false, |r, _depth| {
1907             if let ty::ReClosureBound(vid) = r {
1908                 closure_mapping[*vid]
1909             } else {
1910                 bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r)
1911             }
1912         })
1913     }
1914 }