]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/borrow_check/nll/region_infer/mod.rs
Auto merge of #67004 - estebank:issue-66958, r=eddyb
[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::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     ) -> Option<ClosureRegionRequirements<'tcx>> {
488         self.propagate_constraints(body);
489
490         // If this is a closure, we can propagate unsatisfied
491         // `outlives_requirements` to our creator, so create a vector
492         // to store those. Otherwise, we'll pass in `None` to the
493         // functions below, which will trigger them to report errors
494         // eagerly.
495         let mut outlives_requirements =
496             infcx.tcx.is_closure(mir_def_id).then(|| vec![]);
497
498         self.check_type_tests(
499             infcx,
500             body,
501             mir_def_id,
502             outlives_requirements.as_mut(),
503             errors_buffer,
504         );
505
506         // If we produce any errors, we keep track of the names of all regions, so that we can use
507         // the same error names in any suggestions we produce. Note that we need names to be unique
508         // across different errors for the same MIR def so that we can make suggestions that fix
509         // multiple problems.
510         let mut region_naming = RegionErrorNamingCtx::new();
511
512         self.check_universal_regions(
513             infcx,
514             body,
515             local_names,
516             upvars,
517             mir_def_id,
518             outlives_requirements.as_mut(),
519             errors_buffer,
520             &mut region_naming,
521         );
522
523         self.check_member_constraints(infcx, mir_def_id, errors_buffer);
524
525         let outlives_requirements = outlives_requirements.unwrap_or(vec![]);
526
527         if outlives_requirements.is_empty() {
528             None
529         } else {
530             let num_external_vids = self.universal_regions.num_global_and_external_regions();
531             Some(ClosureRegionRequirements { num_external_vids, outlives_requirements })
532         }
533     }
534
535     /// Propagate the region constraints: this will grow the values
536     /// for each region variable until all the constraints are
537     /// satisfied. Note that some values may grow **too** large to be
538     /// feasible, but we check this later.
539     fn propagate_constraints(&mut self, _body: &Body<'tcx>) {
540         debug!("propagate_constraints()");
541
542         debug!("propagate_constraints: constraints={:#?}", {
543             let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
544             constraints.sort();
545             constraints
546                 .into_iter()
547                 .map(|c| (c, self.constraint_sccs.scc(c.sup), self.constraint_sccs.scc(c.sub)))
548                 .collect::<Vec<_>>()
549         });
550
551         // To propagate constraints, we walk the DAG induced by the
552         // SCC. For each SCC, we visit its successors and compute
553         // their values, then we union all those values to get our
554         // own.
555         let visited = &mut BitSet::new_empty(self.constraint_sccs.num_sccs());
556         for scc_index in self.constraint_sccs.all_sccs() {
557             self.propagate_constraint_sccs_if_new(scc_index, visited);
558         }
559
560         // Sort the applied member constraints so we can binary search
561         // through them later.
562         self.member_constraints_applied.sort_by_key(|applied| applied.member_region_scc);
563     }
564
565     /// Computes the value of the SCC `scc_a` if it has not already
566     /// been computed. The `visited` parameter is a bitset
567     #[inline]
568     fn propagate_constraint_sccs_if_new(
569         &mut self,
570         scc_a: ConstraintSccIndex,
571         visited: &mut BitSet<ConstraintSccIndex>,
572     ) {
573         if visited.insert(scc_a) {
574             self.propagate_constraint_sccs_new(scc_a, visited);
575         }
576     }
577
578     /// Computes the value of the SCC `scc_a`, which has not yet been
579     /// computed. This works by first computing all successors of the
580     /// SCC (if they haven't been computed already) and then unioning
581     /// together their elements.
582     fn propagate_constraint_sccs_new(
583         &mut self,
584         scc_a: ConstraintSccIndex,
585         visited: &mut BitSet<ConstraintSccIndex>,
586     ) {
587         let constraint_sccs = self.constraint_sccs.clone();
588
589         // Walk each SCC `B` such that `A: B`...
590         for &scc_b in constraint_sccs.successors(scc_a) {
591             debug!("propagate_constraint_sccs: scc_a = {:?} scc_b = {:?}", scc_a, scc_b);
592
593             // ...compute the value of `B`...
594             self.propagate_constraint_sccs_if_new(scc_b, visited);
595
596             // ...and add elements from `B` into `A`. One complication
597             // arises because of universes: If `B` contains something
598             // that `A` cannot name, then `A` can only contain `B` if
599             // it outlives static.
600             if self.universe_compatible(scc_b, scc_a) {
601                 // `A` can name everything that is in `B`, so just
602                 // merge the bits.
603                 self.scc_values.add_region(scc_a, scc_b);
604             } else {
605                 self.add_incompatible_universe(scc_a);
606             }
607         }
608
609         // Now take member constraints into account.
610         let member_constraints = self.member_constraints.clone();
611         for m_c_i in member_constraints.indices(scc_a) {
612             self.apply_member_constraint(
613                 scc_a,
614                 m_c_i,
615                 member_constraints.choice_regions(m_c_i),
616             );
617         }
618
619         debug!(
620             "propagate_constraint_sccs: scc_a = {:?} has value {:?}",
621             scc_a,
622             self.scc_values.region_value_str(scc_a),
623         );
624     }
625
626     /// Invoked for each `R0 member of [R1..Rn]` constraint.
627     ///
628     /// `scc` is the SCC containing R0, and `choice_regions` are the
629     /// `R1..Rn` regions -- they are always known to be universal
630     /// regions (and if that's not true, we just don't attempt to
631     /// enforce the constraint).
632     ///
633     /// The current value of `scc` at the time the method is invoked
634     /// is considered a *lower bound*.  If possible, we will modify
635     /// the constraint to set it equal to one of the option regions.
636     /// If we make any changes, returns true, else false.
637     fn apply_member_constraint(
638         &mut self,
639         scc: ConstraintSccIndex,
640         member_constraint_index: NllMemberConstraintIndex,
641         choice_regions: &[ty::RegionVid],
642     ) -> bool {
643         debug!("apply_member_constraint(scc={:?}, choice_regions={:#?})", scc, choice_regions,);
644
645         if let Some(uh_oh) =
646             choice_regions.iter().find(|&&r| !self.universal_regions.is_universal_region(r))
647         {
648             // FIXME(#61773): This case can only occur with
649             // `impl_trait_in_bindings`, I believe, and we are just
650             // opting not to handle it for now. See #61773 for
651             // details.
652             bug!(
653                 "member constraint for `{:?}` has an option region `{:?}` \
654                  that is not a universal region",
655                 self.member_constraints[member_constraint_index].opaque_type_def_id,
656                 uh_oh,
657             );
658         }
659
660         // Create a mutable vector of the options. We'll try to winnow
661         // them down.
662         let mut choice_regions: Vec<ty::RegionVid> = choice_regions.to_vec();
663
664         // The 'member region' in a member constraint is part of the
665         // hidden type, which must be in the root universe. Therefore,
666         // it cannot have any placeholders in its value.
667         assert!(self.scc_universes[scc] == ty::UniverseIndex::ROOT);
668         debug_assert!(
669             self.scc_values.placeholders_contained_in(scc).next().is_none(),
670             "scc {:?} in a member constraint has placeholder value: {:?}",
671             scc,
672             self.scc_values.region_value_str(scc),
673         );
674
675         // The existing value for `scc` is a lower-bound. This will
676         // consist of some set `{P} + {LB}` of points `{P}` and
677         // lower-bound free regions `{LB}`. As each choice region `O`
678         // is a free region, it will outlive the points. But we can
679         // only consider the option `O` if `O: LB`.
680         choice_regions.retain(|&o_r| {
681             self.scc_values
682                 .universal_regions_outlived_by(scc)
683                 .all(|lb| self.universal_region_relations.outlives(o_r, lb))
684         });
685         debug!("apply_member_constraint: after lb, choice_regions={:?}", choice_regions);
686
687         // Now find all the *upper bounds* -- that is, each UB is a
688         // free region that must outlive the member region `R0` (`UB:
689         // R0`). Therefore, we need only keep an option `O` if `UB: O`
690         // for all UB.
691         if choice_regions.len() > 1 {
692             let universal_region_relations = self.universal_region_relations.clone();
693             let rev_constraint_graph = self.rev_constraint_graph();
694             for ub in self.upper_bounds(scc, &rev_constraint_graph) {
695                 debug!("apply_member_constraint: ub={:?}", ub);
696                 choice_regions.retain(|&o_r| universal_region_relations.outlives(ub, o_r));
697             }
698             debug!("apply_member_constraint: after ub, choice_regions={:?}", choice_regions);
699         }
700
701         // If we ruled everything out, we're done.
702         if choice_regions.is_empty() {
703             return false;
704         }
705
706         // Otherwise, we need to find the minimum remaining choice, if
707         // any, and take that.
708         debug!("apply_member_constraint: choice_regions remaining are {:#?}", choice_regions);
709         let min = |r1: ty::RegionVid, r2: ty::RegionVid| -> Option<ty::RegionVid> {
710             let r1_outlives_r2 = self.universal_region_relations.outlives(r1, r2);
711             let r2_outlives_r1 = self.universal_region_relations.outlives(r2, r1);
712             match (r1_outlives_r2, r2_outlives_r1) {
713                 (true, true) => Some(r1.min(r2)),
714                 (true, false) => Some(r2),
715                 (false, true) => Some(r1),
716                 (false, false) => None,
717             }
718         };
719         let mut min_choice = choice_regions[0];
720         for &other_option in &choice_regions[1..] {
721             debug!(
722                 "apply_member_constraint: min_choice={:?} other_option={:?}",
723                 min_choice, other_option,
724             );
725             match min(min_choice, other_option) {
726                 Some(m) => min_choice = m,
727                 None => {
728                     debug!(
729                         "apply_member_constraint: {:?} and {:?} are incomparable; no min choice",
730                         min_choice, other_option,
731                     );
732                     return false;
733                 }
734             }
735         }
736
737         let min_choice_scc = self.constraint_sccs.scc(min_choice);
738         debug!(
739             "apply_member_constraint: min_choice={:?} best_choice_scc={:?}",
740             min_choice,
741             min_choice_scc,
742         );
743         if self.scc_values.add_region(scc, min_choice_scc) {
744             self.member_constraints_applied.push(AppliedMemberConstraint {
745                 member_region_scc: scc,
746                 min_choice,
747                 member_constraint_index,
748             });
749
750             true
751         } else {
752             false
753         }
754     }
755
756     /// Compute and return the reverse SCC-based constraint graph (lazilly).
757     fn upper_bounds(
758         &'a mut self,
759         scc0: ConstraintSccIndex,
760         rev_constraint_graph: &'a VecGraph<ConstraintSccIndex>,
761     ) -> impl Iterator<Item = RegionVid> + 'a {
762         let scc_values = &self.scc_values;
763         let mut duplicates = FxHashSet::default();
764         rev_constraint_graph
765             .depth_first_search(scc0)
766             .skip(1)
767             .flat_map(move |scc1| scc_values.universal_regions_outlived_by(scc1))
768             .filter(move |&r| duplicates.insert(r))
769     }
770
771     /// Compute and return the reverse SCC-based constraint graph (lazilly).
772     fn rev_constraint_graph(
773         &mut self,
774     ) -> Rc<VecGraph<ConstraintSccIndex>> {
775         if let Some(g) = &self.rev_constraint_graph {
776             return g.clone();
777         }
778
779         let rev_graph = Rc::new(self.constraint_sccs.reverse());
780         self.rev_constraint_graph = Some(rev_graph.clone());
781         rev_graph
782     }
783
784     /// Returns `true` if all the elements in the value of `scc_b` are nameable
785     /// in `scc_a`. Used during constraint propagation, and only once
786     /// the value of `scc_b` has been computed.
787     fn universe_compatible(&self, scc_b: ConstraintSccIndex, scc_a: ConstraintSccIndex) -> bool {
788         let universe_a = self.scc_universes[scc_a];
789
790         // Quick check: if scc_b's declared universe is a subset of
791         // scc_a's declared univese (typically, both are ROOT), then
792         // it cannot contain any problematic universe elements.
793         if universe_a.can_name(self.scc_universes[scc_b]) {
794             return true;
795         }
796
797         // Otherwise, we have to iterate over the universe elements in
798         // B's value, and check whether all of them are nameable
799         // from universe_a
800         self.scc_values.placeholders_contained_in(scc_b).all(|p| universe_a.can_name(p.universe))
801     }
802
803     /// Extend `scc` so that it can outlive some placeholder region
804     /// from a universe it can't name; at present, the only way for
805     /// this to be true is if `scc` outlives `'static`. This is
806     /// actually stricter than necessary: ideally, we'd support bounds
807     /// like `for<'a: 'b`>` that might then allow us to approximate
808     /// `'a` with `'b` and not `'static`. But it will have to do for
809     /// now.
810     fn add_incompatible_universe(&mut self, scc: ConstraintSccIndex) {
811         debug!("add_incompatible_universe(scc={:?})", scc);
812
813         let fr_static = self.universal_regions.fr_static;
814         self.scc_values.add_all_points(scc);
815         self.scc_values.add_element(scc, fr_static);
816     }
817
818     /// Once regions have been propagated, this method is used to see
819     /// whether the "type tests" produced by typeck were satisfied;
820     /// type tests encode type-outlives relationships like `T:
821     /// 'a`. See `TypeTest` for more details.
822     fn check_type_tests(
823         &self,
824         infcx: &InferCtxt<'_, 'tcx>,
825         body: &Body<'tcx>,
826         mir_def_id: DefId,
827         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
828         errors_buffer: &mut Vec<Diagnostic>,
829     ) {
830         let tcx = infcx.tcx;
831
832         // Sometimes we register equivalent type-tests that would
833         // result in basically the exact same error being reported to
834         // the user. Avoid that.
835         let mut deduplicate_errors = FxHashSet::default();
836
837         for type_test in &self.type_tests {
838             debug!("check_type_test: {:?}", type_test);
839
840             let generic_ty = type_test.generic_kind.to_ty(tcx);
841             if self.eval_verify_bound(
842                 tcx,
843                 body,
844                 generic_ty,
845                 type_test.lower_bound,
846                 &type_test.verify_bound,
847             ) {
848                 continue;
849             }
850
851             if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
852                 if self.try_promote_type_test(
853                     infcx,
854                     body,
855                     type_test,
856                     propagated_outlives_requirements,
857                 ) {
858                     continue;
859                 }
860             }
861
862             // Type-test failed. Report the error.
863
864             // Try to convert the lower-bound region into something named we can print for the user.
865             let lower_bound_region = self.to_error_region(type_test.lower_bound);
866
867             // Skip duplicate-ish errors.
868             let type_test_span = type_test.locations.span(body);
869             let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind);
870             if !deduplicate_errors.insert((
871                 erased_generic_kind,
872                 lower_bound_region,
873                 type_test.locations,
874             )) {
875                 continue;
876             } else {
877                 debug!(
878                     "check_type_test: reporting error for erased_generic_kind={:?}, \
879                      lower_bound_region={:?}, \
880                      type_test.locations={:?}",
881                     erased_generic_kind, lower_bound_region, type_test.locations,
882                 );
883             }
884
885             if let Some(lower_bound_region) = lower_bound_region {
886                 let region_scope_tree = &tcx.region_scope_tree(mir_def_id);
887                 infcx
888                     .construct_generic_bound_failure(
889                         region_scope_tree,
890                         type_test_span,
891                         None,
892                         type_test.generic_kind,
893                         lower_bound_region,
894                     )
895                     .buffer(errors_buffer);
896             } else {
897                 // FIXME. We should handle this case better. It
898                 // indicates that we have e.g., some region variable
899                 // whose value is like `'a+'b` where `'a` and `'b` are
900                 // distinct unrelated univesal regions that are not
901                 // known to outlive one another. It'd be nice to have
902                 // some examples where this arises to decide how best
903                 // to report it; we could probably handle it by
904                 // iterating over the universal regions and reporting
905                 // an error that multiple bounds are required.
906                 tcx.sess
907                     .struct_span_err(
908                         type_test_span,
909                         &format!("`{}` does not live long enough", type_test.generic_kind,),
910                     )
911                     .buffer(errors_buffer);
912             }
913         }
914     }
915
916     /// Converts a region inference variable into a `ty::Region` that
917     /// we can use for error reporting. If `r` is universally bound,
918     /// then we use the name that we have on record for it. If `r` is
919     /// existentially bound, then we check its inferred value and try
920     /// to find a good name from that. Returns `None` if we can't find
921     /// one (e.g., this is just some random part of the CFG).
922     pub fn to_error_region(&self, r: RegionVid) -> Option<ty::Region<'tcx>> {
923         self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name)
924     }
925
926     /// Returns the [RegionVid] corresponding to the region returned by
927     /// `to_error_region`.
928     pub fn to_error_region_vid(&self, r: RegionVid) -> Option<RegionVid> {
929         if self.universal_regions.is_universal_region(r) {
930             Some(r)
931         } else {
932             let r_scc = self.constraint_sccs.scc(r);
933             let upper_bound = self.universal_upper_bound(r);
934             if self.scc_values.contains(r_scc, upper_bound) {
935                 self.to_error_region_vid(upper_bound)
936             } else {
937                 None
938             }
939         }
940     }
941
942     /// Invoked when we have some type-test (e.g., `T: 'X`) that we cannot
943     /// prove to be satisfied. If this is a closure, we will attempt to
944     /// "promote" this type-test into our `ClosureRegionRequirements` and
945     /// hence pass it up the creator. To do this, we have to phrase the
946     /// type-test in terms of external free regions, as local free
947     /// regions are not nameable by the closure's creator.
948     ///
949     /// Promotion works as follows: we first check that the type `T`
950     /// contains only regions that the creator knows about. If this is
951     /// true, then -- as a consequence -- we know that all regions in
952     /// the type `T` are free regions that outlive the closure body. If
953     /// false, then promotion fails.
954     ///
955     /// Once we've promoted T, we have to "promote" `'X` to some region
956     /// that is "external" to the closure. Generally speaking, a region
957     /// may be the union of some points in the closure body as well as
958     /// various free lifetimes. We can ignore the points in the closure
959     /// body: if the type T can be expressed in terms of external regions,
960     /// we know it outlives the points in the closure body. That
961     /// just leaves the free regions.
962     ///
963     /// The idea then is to lower the `T: 'X` constraint into multiple
964     /// bounds -- e.g., if `'X` is the union of two free lifetimes,
965     /// `'1` and `'2`, then we would create `T: '1` and `T: '2`.
966     fn try_promote_type_test(
967         &self,
968         infcx: &InferCtxt<'_, 'tcx>,
969         body: &Body<'tcx>,
970         type_test: &TypeTest<'tcx>,
971         propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
972     ) -> bool {
973         let tcx = infcx.tcx;
974
975         let TypeTest { generic_kind, lower_bound, locations, verify_bound: _ } = type_test;
976
977         let generic_ty = generic_kind.to_ty(tcx);
978         let subject = match self.try_promote_type_test_subject(infcx, generic_ty) {
979             Some(s) => s,
980             None => return false,
981         };
982
983         // For each region outlived by lower_bound find a non-local,
984         // universal region (it may be the same region) and add it to
985         // `ClosureOutlivesRequirement`.
986         let r_scc = self.constraint_sccs.scc(*lower_bound);
987         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
988             // Check whether we can already prove that the "subject" outlives `ur`.
989             // If so, we don't have to propagate this requirement to our caller.
990             //
991             // To continue the example from the function, if we are trying to promote
992             // a requirement that `T: 'X`, and we know that `'X = '1 + '2` (i.e., the union
993             // `'1` and `'2`), then in this loop `ur` will be `'1` (and `'2`). So here
994             // we check whether `T: '1` is something we *can* prove. If so, no need
995             // to propagate that requirement.
996             //
997             // This is needed because -- particularly in the case
998             // where `ur` is a local bound -- we are sometimes in a
999             // position to prove things that our caller cannot.  See
1000             // #53570 for an example.
1001             if self.eval_verify_bound(tcx, body, generic_ty, ur, &type_test.verify_bound) {
1002                 continue;
1003             }
1004
1005             debug!("try_promote_type_test: ur={:?}", ur);
1006
1007             let non_local_ub = self.universal_region_relations.non_local_upper_bounds(&ur);
1008             debug!("try_promote_type_test: non_local_ub={:?}", non_local_ub);
1009
1010             // This is slightly too conservative. To show T: '1, given `'2: '1`
1011             // and `'3: '1` we only need to prove that T: '2 *or* T: '3, but to
1012             // avoid potential non-determinism we approximate this by requiring
1013             // T: '1 and T: '2.
1014             for &upper_bound in non_local_ub {
1015                 debug_assert!(self.universal_regions.is_universal_region(upper_bound));
1016                 debug_assert!(!self.universal_regions.is_local_free_region(upper_bound));
1017
1018                 let requirement = ClosureOutlivesRequirement {
1019                     subject,
1020                     outlived_free_region: upper_bound,
1021                     blame_span: locations.span(body),
1022                     category: ConstraintCategory::Boring,
1023                 };
1024                 debug!("try_promote_type_test: pushing {:#?}", requirement);
1025                 propagated_outlives_requirements.push(requirement);
1026             }
1027         }
1028         true
1029     }
1030
1031     /// When we promote a type test `T: 'r`, we have to convert the
1032     /// type `T` into something we can store in a query result (so
1033     /// something allocated for `'tcx`). This is problematic if `ty`
1034     /// contains regions. During the course of NLL region checking, we
1035     /// will have replaced all of those regions with fresh inference
1036     /// variables. To create a test subject, we want to replace those
1037     /// inference variables with some region from the closure
1038     /// signature -- this is not always possible, so this is a
1039     /// fallible process. Presuming we do find a suitable region, we
1040     /// will represent it with a `ReClosureBound`, which is a
1041     /// `RegionKind` variant that can be allocated in the gcx.
1042     fn try_promote_type_test_subject(
1043         &self,
1044         infcx: &InferCtxt<'_, 'tcx>,
1045         ty: Ty<'tcx>,
1046     ) -> Option<ClosureOutlivesSubject<'tcx>> {
1047         let tcx = infcx.tcx;
1048
1049         debug!("try_promote_type_test_subject(ty = {:?})", ty);
1050
1051         let ty = tcx.fold_regions(&ty, &mut false, |r, _depth| {
1052             let region_vid = self.to_region_vid(r);
1053
1054             // The challenge if this. We have some region variable `r`
1055             // whose value is a set of CFG points and universal
1056             // regions. We want to find if that set is *equivalent* to
1057             // any of the named regions found in the closure.
1058             //
1059             // To do so, we compute the
1060             // `non_local_universal_upper_bound`. This will be a
1061             // non-local, universal region that is greater than `r`.
1062             // However, it might not be *contained* within `r`, so
1063             // then we further check whether this bound is contained
1064             // in `r`. If so, we can say that `r` is equivalent to the
1065             // bound.
1066             //
1067             // Let's work through a few examples. For these, imagine
1068             // that we have 3 non-local regions (I'll denote them as
1069             // `'static`, `'a`, and `'b`, though of course in the code
1070             // they would be represented with indices) where:
1071             //
1072             // - `'static: 'a`
1073             // - `'static: 'b`
1074             //
1075             // First, let's assume that `r` is some existential
1076             // variable with an inferred value `{'a, 'static}` (plus
1077             // some CFG nodes). In this case, the non-local upper
1078             // bound is `'static`, since that outlives `'a`. `'static`
1079             // is also a member of `r` and hence we consider `r`
1080             // equivalent to `'static` (and replace it with
1081             // `'static`).
1082             //
1083             // Now let's consider the inferred value `{'a, 'b}`. This
1084             // means `r` is effectively `'a | 'b`. I'm not sure if
1085             // this can come about, actually, but assuming it did, we
1086             // would get a non-local upper bound of `'static`. Since
1087             // `'static` is not contained in `r`, we would fail to
1088             // find an equivalent.
1089             let upper_bound = self.non_local_universal_upper_bound(region_vid);
1090             if self.region_contains(region_vid, upper_bound) {
1091                 tcx.mk_region(ty::ReClosureBound(upper_bound))
1092             } else {
1093                 // In the case of a failure, use a `ReVar`
1094                 // result. This will cause the `lift` later on to
1095                 // fail.
1096                 r
1097             }
1098         });
1099         debug!("try_promote_type_test_subject: folded ty = {:?}", ty);
1100
1101         // `has_local_value` will only be true if we failed to promote some region.
1102         if ty.has_local_value() {
1103             return None;
1104         }
1105
1106         Some(ClosureOutlivesSubject::Ty(ty))
1107     }
1108
1109     /// Given some universal or existential region `r`, finds a
1110     /// non-local, universal region `r+` that outlives `r` at entry to (and
1111     /// exit from) the closure. In the worst case, this will be
1112     /// `'static`.
1113     ///
1114     /// This is used for two purposes. First, if we are propagated
1115     /// some requirement `T: r`, we can use this method to enlarge `r`
1116     /// to something we can encode for our creator (which only knows
1117     /// about non-local, universal regions). It is also used when
1118     /// encoding `T` as part of `try_promote_type_test_subject` (see
1119     /// that fn for details).
1120     ///
1121     /// This is based on the result `'y` of `universal_upper_bound`,
1122     /// except that it converts further takes the non-local upper
1123     /// bound of `'y`, so that the final result is non-local.
1124     fn non_local_universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1125         debug!("non_local_universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
1126
1127         let lub = self.universal_upper_bound(r);
1128
1129         // Grow further to get smallest universal region known to
1130         // creator.
1131         let non_local_lub = self.universal_region_relations.non_local_upper_bound(lub);
1132
1133         debug!("non_local_universal_upper_bound: non_local_lub={:?}", non_local_lub);
1134
1135         non_local_lub
1136     }
1137
1138     /// Returns a universally quantified region that outlives the
1139     /// value of `r` (`r` may be existentially or universally
1140     /// quantified).
1141     ///
1142     /// Since `r` is (potentially) an existential region, it has some
1143     /// value which may include (a) any number of points in the CFG
1144     /// and (b) any number of `end('x)` elements of universally
1145     /// quantified regions. To convert this into a single universal
1146     /// region we do as follows:
1147     ///
1148     /// - Ignore the CFG points in `'r`. All universally quantified regions
1149     ///   include the CFG anyhow.
1150     /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
1151     ///   a result `'y`.
1152     fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
1153         debug!("universal_upper_bound(r={:?}={})", r, self.region_value_str(r));
1154
1155         // Find the smallest universal region that contains all other
1156         // universal regions within `region`.
1157         let mut lub = self.universal_regions.fr_fn_body;
1158         let r_scc = self.constraint_sccs.scc(r);
1159         for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
1160             lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
1161         }
1162
1163         debug!("universal_upper_bound: r={:?} lub={:?}", r, lub);
1164
1165         lub
1166     }
1167
1168     /// Tests if `test` is true when applied to `lower_bound` at
1169     /// `point`.
1170     fn eval_verify_bound(
1171         &self,
1172         tcx: TyCtxt<'tcx>,
1173         body: &Body<'tcx>,
1174         generic_ty: Ty<'tcx>,
1175         lower_bound: RegionVid,
1176         verify_bound: &VerifyBound<'tcx>,
1177     ) -> bool {
1178         debug!("eval_verify_bound(lower_bound={:?}, verify_bound={:?})", lower_bound, verify_bound);
1179
1180         match verify_bound {
1181             VerifyBound::IfEq(test_ty, verify_bound1) => {
1182                 self.eval_if_eq(tcx, body, generic_ty, lower_bound, test_ty, verify_bound1)
1183             }
1184
1185             VerifyBound::OutlivedBy(r) => {
1186                 let r_vid = self.to_region_vid(r);
1187                 self.eval_outlives(r_vid, lower_bound)
1188             }
1189
1190             VerifyBound::AnyBound(verify_bounds) => verify_bounds.iter().any(|verify_bound| {
1191                 self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1192             }),
1193
1194             VerifyBound::AllBounds(verify_bounds) => verify_bounds.iter().all(|verify_bound| {
1195                 self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1196             }),
1197         }
1198     }
1199
1200     fn eval_if_eq(
1201         &self,
1202         tcx: TyCtxt<'tcx>,
1203         body: &Body<'tcx>,
1204         generic_ty: Ty<'tcx>,
1205         lower_bound: RegionVid,
1206         test_ty: Ty<'tcx>,
1207         verify_bound: &VerifyBound<'tcx>,
1208     ) -> bool {
1209         let generic_ty_normalized = self.normalize_to_scc_representatives(tcx, generic_ty);
1210         let test_ty_normalized = self.normalize_to_scc_representatives(tcx, test_ty);
1211         if generic_ty_normalized == test_ty_normalized {
1212             self.eval_verify_bound(tcx, body, generic_ty, lower_bound, verify_bound)
1213         } else {
1214             false
1215         }
1216     }
1217
1218     /// This is a conservative normalization procedure. It takes every
1219     /// free region in `value` and replaces it with the
1220     /// "representative" of its SCC (see `scc_representatives` field).
1221     /// We are guaranteed that if two values normalize to the same
1222     /// thing, then they are equal; this is a conservative check in
1223     /// that they could still be equal even if they normalize to
1224     /// different results. (For example, there might be two regions
1225     /// with the same value that are not in the same SCC).
1226     ///
1227     /// N.B., this is not an ideal approach and I would like to revisit
1228     /// it. However, it works pretty well in practice. In particular,
1229     /// this is needed to deal with projection outlives bounds like
1230     ///
1231     ///     <T as Foo<'0>>::Item: '1
1232     ///
1233     /// In particular, this routine winds up being important when
1234     /// there are bounds like `where <T as Foo<'a>>::Item: 'b` in the
1235     /// environment. In this case, if we can show that `'0 == 'a`,
1236     /// and that `'b: '1`, then we know that the clause is
1237     /// satisfied. In such cases, particularly due to limitations of
1238     /// the trait solver =), we usually wind up with a where-clause like
1239     /// `T: Foo<'a>` in scope, which thus forces `'0 == 'a` to be added as
1240     /// a constraint, and thus ensures that they are in the same SCC.
1241     ///
1242     /// So why can't we do a more correct routine? Well, we could
1243     /// *almost* use the `relate_tys` code, but the way it is
1244     /// currently setup it creates inference variables to deal with
1245     /// higher-ranked things and so forth, and right now the inference
1246     /// context is not permitted to make more inference variables. So
1247     /// we use this kind of hacky solution.
1248     fn normalize_to_scc_representatives<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
1249     where
1250         T: TypeFoldable<'tcx>,
1251     {
1252         tcx.fold_regions(&value, &mut false, |r, _db| {
1253             let vid = self.to_region_vid(r);
1254             let scc = self.constraint_sccs.scc(vid);
1255             let repr = self.scc_representatives[scc];
1256             tcx.mk_region(ty::ReVar(repr))
1257         })
1258     }
1259
1260     // Evaluate whether `sup_region == sub_region`.
1261     fn eval_equal(&self, r1: RegionVid, r2: RegionVid) -> bool {
1262         self.eval_outlives(r1, r2) && self.eval_outlives(r2, r1)
1263     }
1264
1265     // Evaluate whether `sup_region: sub_region`.
1266     fn eval_outlives(&self, sup_region: RegionVid, sub_region: RegionVid) -> bool {
1267         debug!("eval_outlives({:?}: {:?})", sup_region, sub_region);
1268
1269         debug!(
1270             "eval_outlives: sup_region's value = {:?} universal={:?}",
1271             self.region_value_str(sup_region),
1272             self.universal_regions.is_universal_region(sup_region),
1273         );
1274         debug!(
1275             "eval_outlives: sub_region's value = {:?} universal={:?}",
1276             self.region_value_str(sub_region),
1277             self.universal_regions.is_universal_region(sub_region),
1278         );
1279
1280         let sub_region_scc = self.constraint_sccs.scc(sub_region);
1281         let sup_region_scc = self.constraint_sccs.scc(sup_region);
1282
1283         // Both the `sub_region` and `sup_region` consist of the union
1284         // of some number of universal regions (along with the union
1285         // of various points in the CFG; ignore those points for
1286         // now). Therefore, the sup-region outlives the sub-region if,
1287         // for each universal region R1 in the sub-region, there
1288         // exists some region R2 in the sup-region that outlives R1.
1289         let universal_outlives =
1290             self.scc_values.universal_regions_outlived_by(sub_region_scc).all(|r1| {
1291                 self.scc_values
1292                     .universal_regions_outlived_by(sup_region_scc)
1293                     .any(|r2| self.universal_region_relations.outlives(r2, r1))
1294             });
1295
1296         if !universal_outlives {
1297             return false;
1298         }
1299
1300         // Now we have to compare all the points in the sub region and make
1301         // sure they exist in the sup region.
1302
1303         if self.universal_regions.is_universal_region(sup_region) {
1304             // Micro-opt: universal regions contain all points.
1305             return true;
1306         }
1307
1308         self.scc_values.contains_points(sup_region_scc, sub_region_scc)
1309     }
1310
1311     /// Once regions have been propagated, this method is used to see
1312     /// whether any of the constraints were too strong. In particular,
1313     /// we want to check for a case where a universally quantified
1314     /// region exceeded its bounds. Consider:
1315     ///
1316     ///     fn foo<'a, 'b>(x: &'a u32) -> &'b u32 { x }
1317     ///
1318     /// In this case, returning `x` requires `&'a u32 <: &'b u32`
1319     /// and hence we establish (transitively) a constraint that
1320     /// `'a: 'b`. The `propagate_constraints` code above will
1321     /// therefore add `end('a)` into the region for `'b` -- but we
1322     /// have no evidence that `'b` outlives `'a`, so we want to report
1323     /// an error.
1324     ///
1325     /// If `propagated_outlives_requirements` is `Some`, then we will
1326     /// push unsatisfied obligations into there. Otherwise, we'll
1327     /// report them as errors.
1328     fn check_universal_regions(
1329         &self,
1330         infcx: &InferCtxt<'_, 'tcx>,
1331         body: &Body<'tcx>,
1332         local_names: &IndexVec<Local, Option<Symbol>>,
1333         upvars: &[Upvar],
1334         mir_def_id: DefId,
1335         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1336         errors_buffer: &mut Vec<Diagnostic>,
1337         region_naming: &mut RegionErrorNamingCtx,
1338     ) {
1339         let mut outlives_suggestion = OutlivesSuggestionBuilder::new(mir_def_id, local_names);
1340
1341         for (fr, fr_definition) in self.definitions.iter_enumerated() {
1342             match fr_definition.origin {
1343                 NLLRegionVariableOrigin::FreeRegion => {
1344                     // Go through each of the universal regions `fr` and check that
1345                     // they did not grow too large, accumulating any requirements
1346                     // for our caller into the `outlives_requirements` vector.
1347                     self.check_universal_region(
1348                         infcx,
1349                         body,
1350                         local_names,
1351                         upvars,
1352                         mir_def_id,
1353                         fr,
1354                         &mut propagated_outlives_requirements,
1355                         &mut outlives_suggestion,
1356                         errors_buffer,
1357                         region_naming,
1358                     );
1359                 }
1360
1361                 NLLRegionVariableOrigin::Placeholder(placeholder) => {
1362                     self.check_bound_universal_region(infcx, body, mir_def_id, fr, placeholder);
1363                 }
1364
1365                 NLLRegionVariableOrigin::Existential { .. } => {
1366                     // nothing to check here
1367                 }
1368             }
1369         }
1370
1371         // Emit outlives suggestions
1372         outlives_suggestion.add_suggestion(body, self, infcx, errors_buffer, region_naming);
1373     }
1374
1375     /// Checks the final value for the free region `fr` to see if it
1376     /// grew too large. In particular, examine what `end(X)` points
1377     /// wound up in `fr`'s final value; for each `end(X)` where `X !=
1378     /// fr`, we want to check that `fr: X`. If not, that's either an
1379     /// error, or something we have to propagate to our creator.
1380     ///
1381     /// Things that are to be propagated are accumulated into the
1382     /// `outlives_requirements` vector.
1383     fn check_universal_region(
1384         &self,
1385         infcx: &InferCtxt<'_, 'tcx>,
1386         body: &Body<'tcx>,
1387         local_names: &IndexVec<Local, Option<Symbol>>,
1388         upvars: &[Upvar],
1389         mir_def_id: DefId,
1390         longer_fr: RegionVid,
1391         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1392         outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1393         errors_buffer: &mut Vec<Diagnostic>,
1394         region_naming: &mut RegionErrorNamingCtx,
1395     ) {
1396         debug!("check_universal_region(fr={:?})", longer_fr);
1397
1398         let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
1399
1400         // Because this free region must be in the ROOT universe, we
1401         // know it cannot contain any bound universes.
1402         assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT);
1403         debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
1404
1405         // Only check all of the relations for the main representative of each
1406         // SCC, otherwise just check that we outlive said representative. This
1407         // reduces the number of redundant relations propagated out of
1408         // closures.
1409         // Note that the representative will be a universal region if there is
1410         // one in this SCC, so we will always check the representative here.
1411         let representative = self.scc_representatives[longer_fr_scc];
1412         if representative != longer_fr {
1413             self.check_universal_region_relation(
1414                 longer_fr,
1415                 representative,
1416                 infcx,
1417                 body,
1418                 local_names,
1419                 upvars,
1420                 mir_def_id,
1421                 propagated_outlives_requirements,
1422                 outlives_suggestion,
1423                 errors_buffer,
1424                 region_naming,
1425             );
1426             return;
1427         }
1428
1429         // Find every region `o` such that `fr: o`
1430         // (because `fr` includes `end(o)`).
1431         for shorter_fr in self.scc_values.universal_regions_outlived_by(longer_fr_scc) {
1432             if let Some(ErrorReported) = self.check_universal_region_relation(
1433                 longer_fr,
1434                 shorter_fr,
1435                 infcx,
1436                 body,
1437                 local_names,
1438                 upvars,
1439                 mir_def_id,
1440                 propagated_outlives_requirements,
1441                 outlives_suggestion,
1442                 errors_buffer,
1443                 region_naming,
1444             ) {
1445                 // continuing to iterate just reports more errors than necessary
1446                 //
1447                 // FIXME It would also allow us to report more Outlives Suggestions, though, so
1448                 // it's not clear that that's a bad thing. Somebody should try commenting out this
1449                 // line and see it is actually a regression.
1450                 return;
1451             }
1452         }
1453     }
1454
1455     fn check_universal_region_relation(
1456         &self,
1457         longer_fr: RegionVid,
1458         shorter_fr: RegionVid,
1459         infcx: &InferCtxt<'_, 'tcx>,
1460         body: &Body<'tcx>,
1461         local_names: &IndexVec<Local, Option<Symbol>>,
1462         upvars: &[Upvar],
1463         mir_def_id: DefId,
1464         propagated_outlives_requirements: &mut Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
1465         outlives_suggestion: &mut OutlivesSuggestionBuilder<'_>,
1466         errors_buffer: &mut Vec<Diagnostic>,
1467         region_naming: &mut RegionErrorNamingCtx,
1468     ) -> Option<ErrorReported> {
1469         // If it is known that `fr: o`, carry on.
1470         if self.universal_region_relations.outlives(longer_fr, shorter_fr) {
1471             return None;
1472         }
1473
1474         debug!(
1475             "check_universal_region_relation: fr={:?} does not outlive shorter_fr={:?}",
1476             longer_fr, shorter_fr,
1477         );
1478
1479         if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
1480             // Shrink `longer_fr` until we find a non-local region (if we do).
1481             // We'll call it `fr-` -- it's ever so slightly smaller than
1482             // `longer_fr`.
1483
1484             if let Some(fr_minus) = self.universal_region_relations.non_local_lower_bound(longer_fr)
1485             {
1486                 debug!("check_universal_region: fr_minus={:?}", fr_minus);
1487
1488                 let blame_span_category =
1489                     self.find_outlives_blame_span(body, longer_fr,
1490                                                   NLLRegionVariableOrigin::FreeRegion,shorter_fr);
1491
1492                 // Grow `shorter_fr` until we find some non-local regions. (We
1493                 // always will.)  We'll call them `shorter_fr+` -- they're ever
1494                 // so slightly larger than `shorter_fr`.
1495                 let shorter_fr_plus =
1496                     self.universal_region_relations.non_local_upper_bounds(&shorter_fr);
1497                 debug!("check_universal_region: shorter_fr_plus={:?}", shorter_fr_plus);
1498                 for &&fr in &shorter_fr_plus {
1499                     // Push the constraint `fr-: shorter_fr+`
1500                     propagated_outlives_requirements.push(ClosureOutlivesRequirement {
1501                         subject: ClosureOutlivesSubject::Region(fr_minus),
1502                         outlived_free_region: fr,
1503                         blame_span: blame_span_category.1,
1504                         category: blame_span_category.0,
1505                     });
1506                 }
1507                 return None;
1508             }
1509         }
1510
1511         // If we are not in a context where we can't propagate errors, or we
1512         // could not shrink `fr` to something smaller, then just report an
1513         // error.
1514         //
1515         // Note: in this case, we use the unapproximated regions to report the
1516         // error. This gives better error messages in some cases.
1517         let db = self.report_error(
1518             body,
1519             local_names,
1520             upvars,
1521             infcx,
1522             mir_def_id,
1523             longer_fr,
1524             NLLRegionVariableOrigin::FreeRegion,
1525             shorter_fr,
1526             outlives_suggestion,
1527             region_naming,
1528         );
1529
1530         db.buffer(errors_buffer);
1531
1532         Some(ErrorReported)
1533     }
1534
1535     fn check_bound_universal_region(
1536         &self,
1537         infcx: &InferCtxt<'_, 'tcx>,
1538         body: &Body<'tcx>,
1539         _mir_def_id: DefId,
1540         longer_fr: RegionVid,
1541         placeholder: ty::PlaceholderRegion,
1542     ) {
1543         debug!("check_bound_universal_region(fr={:?}, placeholder={:?})", longer_fr, placeholder,);
1544
1545         let longer_fr_scc = self.constraint_sccs.scc(longer_fr);
1546         debug!("check_bound_universal_region: longer_fr_scc={:?}", longer_fr_scc,);
1547
1548         // If we have some bound universal region `'a`, then the only
1549         // elements it can contain is itself -- we don't know anything
1550         // else about it!
1551         let error_element = match {
1552             self.scc_values.elements_contained_in(longer_fr_scc).find(|element| match element {
1553                 RegionElement::Location(_) => true,
1554                 RegionElement::RootUniversalRegion(_) => true,
1555                 RegionElement::PlaceholderRegion(placeholder1) => placeholder != *placeholder1,
1556             })
1557         } {
1558             Some(v) => v,
1559             None => return,
1560         };
1561         debug!("check_bound_universal_region: error_element = {:?}", error_element);
1562
1563         // Find the region that introduced this `error_element`.
1564         let error_region = match error_element {
1565             RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
1566             RegionElement::RootUniversalRegion(r) => r,
1567             RegionElement::PlaceholderRegion(error_placeholder) => self
1568                 .definitions
1569                 .iter_enumerated()
1570                 .filter_map(|(r, definition)| match definition.origin {
1571                     NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
1572                     _ => None,
1573                 })
1574                 .next()
1575                 .unwrap(),
1576         };
1577
1578         // Find the code to blame for the fact that `longer_fr` outlives `error_fr`.
1579         let (_, span) = self.find_outlives_blame_span(
1580             body, longer_fr, NLLRegionVariableOrigin::Placeholder(placeholder), error_region
1581         );
1582
1583         // Obviously, this error message is far from satisfactory.
1584         // At present, though, it only appears in unit tests --
1585         // the AST-based checker uses a more conservative check,
1586         // so to even see this error, one must pass in a special
1587         // flag.
1588         let mut diag = infcx.tcx.sess.struct_span_err(span, "higher-ranked subtype error");
1589         diag.emit();
1590     }
1591
1592     fn check_member_constraints(
1593         &self,
1594         infcx: &InferCtxt<'_, 'tcx>,
1595         mir_def_id: DefId,
1596         errors_buffer: &mut Vec<Diagnostic>,
1597     ) {
1598         let member_constraints = self.member_constraints.clone();
1599         for m_c_i in member_constraints.all_indices() {
1600             debug!("check_member_constraint(m_c_i={:?})", m_c_i);
1601             let m_c = &member_constraints[m_c_i];
1602             let member_region_vid = m_c.member_region_vid;
1603             debug!(
1604                 "check_member_constraint: member_region_vid={:?} with value {}",
1605                 member_region_vid,
1606                 self.region_value_str(member_region_vid),
1607             );
1608             let choice_regions = member_constraints.choice_regions(m_c_i);
1609             debug!("check_member_constraint: choice_regions={:?}", choice_regions);
1610
1611             // Did the member region wind up equal to any of the option regions?
1612             if let Some(o) = choice_regions.iter().find(|&&o_r| {
1613                 self.eval_equal(o_r, m_c.member_region_vid)
1614             }) {
1615                 debug!("check_member_constraint: evaluated as equal to {:?}", o);
1616                 continue;
1617             }
1618
1619             // If not, report an error.
1620             let region_scope_tree = &infcx.tcx.region_scope_tree(mir_def_id);
1621             let member_region = infcx.tcx.mk_region(ty::ReVar(member_region_vid));
1622             opaque_types::unexpected_hidden_region_diagnostic(
1623                 infcx.tcx,
1624                 Some(region_scope_tree),
1625                 m_c.opaque_type_def_id,
1626                 m_c.hidden_ty,
1627                 member_region,
1628             )
1629             .buffer(errors_buffer);
1630         }
1631     }
1632 }
1633
1634 impl<'tcx> RegionDefinition<'tcx> {
1635     fn new(universe: ty::UniverseIndex, rv_origin: RegionVariableOrigin) -> Self {
1636         // Create a new region definition. Note that, for free
1637         // regions, the `external_name` field gets updated later in
1638         // `init_universal_regions`.
1639
1640         let origin = match rv_origin {
1641             RegionVariableOrigin::NLL(origin) => origin,
1642             _ => NLLRegionVariableOrigin::Existential { from_forall: false },
1643         };
1644
1645         Self { origin, universe, external_name: None }
1646     }
1647 }
1648
1649 pub trait ClosureRegionRequirementsExt<'tcx> {
1650     fn apply_requirements(
1651         &self,
1652         tcx: TyCtxt<'tcx>,
1653         closure_def_id: DefId,
1654         closure_substs: SubstsRef<'tcx>,
1655     ) -> Vec<QueryOutlivesConstraint<'tcx>>;
1656
1657     fn subst_closure_mapping<T>(
1658         &self,
1659         tcx: TyCtxt<'tcx>,
1660         closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
1661         value: &T,
1662     ) -> T
1663     where
1664         T: TypeFoldable<'tcx>;
1665 }
1666
1667 impl<'tcx> ClosureRegionRequirementsExt<'tcx> for ClosureRegionRequirements<'tcx> {
1668     /// Given an instance T of the closure type, this method
1669     /// instantiates the "extra" requirements that we computed for the
1670     /// closure into the inference context. This has the effect of
1671     /// adding new outlives obligations to existing variables.
1672     ///
1673     /// As described on `ClosureRegionRequirements`, the extra
1674     /// requirements are expressed in terms of regionvids that index
1675     /// into the free regions that appear on the closure type. So, to
1676     /// do this, we first copy those regions out from the type T into
1677     /// a vector. Then we can just index into that vector to extract
1678     /// out the corresponding region from T and apply the
1679     /// requirements.
1680     fn apply_requirements(
1681         &self,
1682         tcx: TyCtxt<'tcx>,
1683         closure_def_id: DefId,
1684         closure_substs: SubstsRef<'tcx>,
1685     ) -> Vec<QueryOutlivesConstraint<'tcx>> {
1686         debug!(
1687             "apply_requirements(closure_def_id={:?}, closure_substs={:?})",
1688             closure_def_id, closure_substs
1689         );
1690
1691         // Extract the values of the free regions in `closure_substs`
1692         // into a vector.  These are the regions that we will be
1693         // relating to one another.
1694         let closure_mapping = &UniversalRegions::closure_mapping(
1695             tcx,
1696             closure_substs,
1697             self.num_external_vids,
1698             tcx.closure_base_def_id(closure_def_id),
1699         );
1700         debug!("apply_requirements: closure_mapping={:?}", closure_mapping);
1701
1702         // Create the predicates.
1703         self.outlives_requirements
1704             .iter()
1705             .map(|outlives_requirement| {
1706                 let outlived_region = closure_mapping[outlives_requirement.outlived_free_region];
1707
1708                 match outlives_requirement.subject {
1709                     ClosureOutlivesSubject::Region(region) => {
1710                         let region = closure_mapping[region];
1711                         debug!(
1712                             "apply_requirements: region={:?} \
1713                              outlived_region={:?} \
1714                              outlives_requirement={:?}",
1715                             region, outlived_region, outlives_requirement,
1716                         );
1717                         ty::Binder::dummy(ty::OutlivesPredicate(region.into(), outlived_region))
1718                     }
1719
1720                     ClosureOutlivesSubject::Ty(ty) => {
1721                         let ty = self.subst_closure_mapping(tcx, closure_mapping, &ty);
1722                         debug!(
1723                             "apply_requirements: ty={:?} \
1724                              outlived_region={:?} \
1725                              outlives_requirement={:?}",
1726                             ty, outlived_region, outlives_requirement,
1727                         );
1728                         ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), outlived_region))
1729                     }
1730                 }
1731             })
1732             .collect()
1733     }
1734
1735     fn subst_closure_mapping<T>(
1736         &self,
1737         tcx: TyCtxt<'tcx>,
1738         closure_mapping: &IndexVec<RegionVid, ty::Region<'tcx>>,
1739         value: &T,
1740     ) -> T
1741     where
1742         T: TypeFoldable<'tcx>,
1743     {
1744         tcx.fold_regions(value, &mut false, |r, _depth| {
1745             if let ty::ReClosureBound(vid) = r {
1746                 closure_mapping[*vid]
1747             } else {
1748                 bug!("subst_closure_mapping: encountered non-closure bound free region {:?}", r)
1749             }
1750         })
1751     }
1752 }