]> git.lizzy.rs Git - rust.git/blob - src/librustc_typeck/check/regionck.rs
Rollup merge of #62557 - taiki-e:typo, r=Centril
[rust.git] / src / librustc_typeck / check / regionck.rs
1 //! The region check is a final pass that runs over the AST after we have
2 //! inferred the type constraints but before we have actually finalized
3 //! the types. Its purpose is to embed a variety of region constraints.
4 //! Inserting these constraints as a separate pass is good because (1) it
5 //! localizes the code that has to do with region inference and (2) often
6 //! we cannot know what constraints are needed until the basic types have
7 //! been inferred.
8 //!
9 //! ### Interaction with the borrow checker
10 //!
11 //! In general, the job of the borrowck module (which runs later) is to
12 //! check that all soundness criteria are met, given a particular set of
13 //! regions. The job of *this* module is to anticipate the needs of the
14 //! borrow checker and infer regions that will satisfy its requirements.
15 //! It is generally true that the inference doesn't need to be sound,
16 //! meaning that if there is a bug and we inferred bad regions, the borrow
17 //! checker should catch it. This is not entirely true though; for
18 //! example, the borrow checker doesn't check subtyping, and it doesn't
19 //! check that region pointers are always live when they are used. It
20 //! might be worthwhile to fix this so that borrowck serves as a kind of
21 //! verification step -- that would add confidence in the overall
22 //! correctness of the compiler, at the cost of duplicating some type
23 //! checks and effort.
24 //!
25 //! ### Inferring the duration of borrows, automatic and otherwise
26 //!
27 //! Whenever we introduce a borrowed pointer, for example as the result of
28 //! a borrow expression `let x = &data`, the lifetime of the pointer `x`
29 //! is always specified as a region inference variable. `regionck` has the
30 //! job of adding constraints such that this inference variable is as
31 //! narrow as possible while still accommodating all uses (that is, every
32 //! dereference of the resulting pointer must be within the lifetime).
33 //!
34 //! #### Reborrows
35 //!
36 //! Generally speaking, `regionck` does NOT try to ensure that the data
37 //! `data` will outlive the pointer `x`. That is the job of borrowck. The
38 //! one exception is when "re-borrowing" the contents of another borrowed
39 //! pointer. For example, imagine you have a borrowed pointer `b` with
40 //! lifetime `L1` and you have an expression `&*b`. The result of this
41 //! expression will be another borrowed pointer with lifetime `L2` (which is
42 //! an inference variable). The borrow checker is going to enforce the
43 //! constraint that `L2 < L1`, because otherwise you are re-borrowing data
44 //! for a lifetime larger than the original loan. However, without the
45 //! routines in this module, the region inferencer would not know of this
46 //! dependency and thus it might infer the lifetime of `L2` to be greater
47 //! than `L1` (issue #3148).
48 //!
49 //! There are a number of troublesome scenarios in the tests
50 //! `region-dependent-*.rs`, but here is one example:
51 //!
52 //!     struct Foo { i: i32 }
53 //!     struct Bar { foo: Foo  }
54 //!     fn get_i<'a>(x: &'a Bar) -> &'a i32 {
55 //!        let foo = &x.foo; // Lifetime L1
56 //!        &foo.i            // Lifetime L2
57 //!     }
58 //!
59 //! Note that this comes up either with `&` expressions, `ref`
60 //! bindings, and `autorefs`, which are the three ways to introduce
61 //! a borrow.
62 //!
63 //! The key point here is that when you are borrowing a value that
64 //! is "guaranteed" by a borrowed pointer, you must link the
65 //! lifetime of that borrowed pointer (`L1`, here) to the lifetime of
66 //! the borrow itself (`L2`). What do I mean by "guaranteed" by a
67 //! borrowed pointer? I mean any data that is reached by first
68 //! dereferencing a borrowed pointer and then either traversing
69 //! interior offsets or boxes. We say that the guarantor
70 //! of such data is the region of the borrowed pointer that was
71 //! traversed. This is essentially the same as the ownership
72 //! relation, except that a borrowed pointer never owns its
73 //! contents.
74
75 use crate::check::dropck;
76 use crate::check::FnCtxt;
77 use crate::middle::mem_categorization as mc;
78 use crate::middle::mem_categorization::Categorization;
79 use crate::middle::region;
80 use rustc::hir::def_id::DefId;
81 use rustc::infer::outlives::env::OutlivesEnvironment;
82 use rustc::infer::{self, RegionObligation, SuppressRegionErrors};
83 use rustc::ty::adjustment;
84 use rustc::ty::subst::{SubstsRef, UnpackedKind};
85 use rustc::ty::{self, Ty};
86
87 use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
88 use rustc::hir::{self, PatKind};
89 use std::mem;
90 use std::ops::Deref;
91 use std::rc::Rc;
92 use syntax_pos::Span;
93
94 // a variation on try that just returns unit
95 macro_rules! ignore_err {
96     ($e:expr) => {
97         match $e {
98             Ok(e) => e,
99             Err(_) => {
100                 debug!("ignoring mem-categorization error!");
101                 return ();
102             }
103         }
104     };
105 }
106
107 ///////////////////////////////////////////////////////////////////////////
108 // PUBLIC ENTRY POINTS
109
110 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111     pub fn regionck_expr(&self, body: &'tcx hir::Body) {
112         let subject = self.tcx.hir().body_owner_def_id(body.id());
113         let id = body.value.hir_id;
114         let mut rcx = RegionCtxt::new(
115             self,
116             RepeatingScope(id),
117             id,
118             Subject(subject),
119             self.param_env,
120         );
121
122         // There are no add'l implied bounds when checking a
123         // standalone expr (e.g., the `E` in a type like `[u32; E]`).
124         rcx.outlives_environment.save_implied_bounds(id);
125
126         if !self.errors_reported_since_creation() {
127             // regionck assumes typeck succeeded
128             rcx.visit_body(body);
129             rcx.visit_region_obligations(id);
130         }
131         rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
132
133         assert!(self.tables.borrow().free_region_map.is_empty());
134         self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
135     }
136
137     /// Region checking during the WF phase for items. `wf_tys` are the
138     /// types from which we should derive implied bounds, if any.
139     pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: &[Ty<'tcx>]) {
140         debug!("regionck_item(item.id={:?}, wf_tys={:?})", item_id, wf_tys);
141         let subject = self.tcx.hir().local_def_id(item_id);
142         let mut rcx = RegionCtxt::new(
143             self,
144             RepeatingScope(item_id),
145             item_id,
146             Subject(subject),
147             self.param_env,
148         );
149         rcx.outlives_environment
150             .add_implied_bounds(self, wf_tys, item_id, span);
151         rcx.outlives_environment.save_implied_bounds(item_id);
152         rcx.visit_region_obligations(item_id);
153         rcx.resolve_regions_and_report_errors(SuppressRegionErrors::default());
154     }
155
156     /// Region check a function body. Not invoked on closures, but
157     /// only on the "root" fn item (in which closures may be
158     /// embedded). Walks the function body and adds various add'l
159     /// constraints that are needed for region inference. This is
160     /// separated both to isolate "pure" region constraints from the
161     /// rest of type check and because sometimes we need type
162     /// inference to have completed before we can determine which
163     /// constraints to add.
164     pub fn regionck_fn(&self, fn_id: hir::HirId, body: &'tcx hir::Body) {
165         debug!("regionck_fn(id={})", fn_id);
166         let subject = self.tcx.hir().body_owner_def_id(body.id());
167         let hir_id = body.value.hir_id;
168         let mut rcx = RegionCtxt::new(
169             self,
170             RepeatingScope(hir_id),
171             hir_id,
172             Subject(subject),
173             self.param_env,
174         );
175
176         if !self.errors_reported_since_creation() {
177             // regionck assumes typeck succeeded
178             rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
179         }
180
181         rcx.resolve_regions_and_report_errors(SuppressRegionErrors::when_nll_is_enabled(self.tcx));
182
183         // In this mode, we also copy the free-region-map into the
184         // tables of the enclosing fcx. In the other regionck modes
185         // (e.g., `regionck_item`), we don't have an enclosing tables.
186         assert!(self.tables.borrow().free_region_map.is_empty());
187         self.tables.borrow_mut().free_region_map = rcx.outlives_environment.into_free_region_map();
188     }
189 }
190
191 ///////////////////////////////////////////////////////////////////////////
192 // INTERNALS
193
194 pub struct RegionCtxt<'a, 'tcx> {
195     pub fcx: &'a FnCtxt<'a, 'tcx>,
196
197     pub region_scope_tree: &'tcx region::ScopeTree,
198
199     outlives_environment: OutlivesEnvironment<'tcx>,
200
201     // id of innermost fn body id
202     body_id: hir::HirId,
203     body_owner: DefId,
204
205     // call_site scope of innermost fn
206     call_site_scope: Option<region::Scope>,
207
208     // id of innermost fn or loop
209     repeating_scope: hir::HirId,
210
211     // id of AST node being analyzed (the subject of the analysis).
212     subject_def_id: DefId,
213 }
214
215 impl<'a, 'tcx> Deref for RegionCtxt<'a, 'tcx> {
216     type Target = FnCtxt<'a, 'tcx>;
217     fn deref(&self) -> &Self::Target {
218         &self.fcx
219     }
220 }
221
222 pub struct RepeatingScope(hir::HirId);
223 pub struct Subject(DefId);
224
225 impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
226     pub fn new(
227         fcx: &'a FnCtxt<'a, 'tcx>,
228         RepeatingScope(initial_repeating_scope): RepeatingScope,
229         initial_body_id: hir::HirId,
230         Subject(subject): Subject,
231         param_env: ty::ParamEnv<'tcx>,
232     ) -> RegionCtxt<'a, 'tcx> {
233         let region_scope_tree = fcx.tcx.region_scope_tree(subject);
234         let outlives_environment = OutlivesEnvironment::new(param_env);
235         RegionCtxt {
236             fcx,
237             region_scope_tree,
238             repeating_scope: initial_repeating_scope,
239             body_id: initial_body_id,
240             body_owner: subject,
241             call_site_scope: None,
242             subject_def_id: subject,
243             outlives_environment,
244         }
245     }
246
247     fn set_repeating_scope(&mut self, scope: hir::HirId) -> hir::HirId {
248         mem::replace(&mut self.repeating_scope, scope)
249     }
250
251     /// Try to resolve the type for the given node, returning `t_err` if an error results. Note that
252     /// we never care about the details of the error, the same error will be detected and reported
253     /// in the writeback phase.
254     ///
255     /// Note one important point: we do not attempt to resolve *region variables* here. This is
256     /// because regionck is essentially adding constraints to those region variables and so may yet
257     /// influence how they are resolved.
258     ///
259     /// Consider this silly example:
260     ///
261     /// ```
262     /// fn borrow(x: &i32) -> &i32 {x}
263     /// fn foo(x: @i32) -> i32 {  // block: B
264     ///     let b = borrow(x);    // region: <R0>
265     ///     *b
266     /// }
267     /// ```
268     ///
269     /// Here, the region of `b` will be `<R0>`. `<R0>` is constrained to be some subregion of the
270     /// block B and some superregion of the call. If we forced it now, we'd choose the smaller
271     /// region (the call). But that would make the *b illegal. Since we don't resolve, the type
272     /// of b will be `&<R0>.i32` and then `*b` will require that `<R0>` be bigger than the let and
273     /// the `*b` expression, so we will effectively resolve `<R0>` to be the block B.
274     pub fn resolve_type(&self, unresolved_ty: Ty<'tcx>) -> Ty<'tcx> {
275         self.resolve_vars_if_possible(&unresolved_ty)
276     }
277
278     /// Try to resolve the type for the given node.
279     fn resolve_node_type(&self, id: hir::HirId) -> Ty<'tcx> {
280         let t = self.node_ty(id);
281         self.resolve_type(t)
282     }
283
284     /// Try to resolve the type for the given node.
285     pub fn resolve_expr_type_adjusted(&mut self, expr: &hir::Expr) -> Ty<'tcx> {
286         let ty = self.tables.borrow().expr_ty_adjusted(expr);
287         self.resolve_type(ty)
288     }
289
290     /// This is the "main" function when region-checking a function item or a closure
291     /// within a function item. It begins by updating various fields (e.g., `call_site_scope`
292     /// and `outlives_environment`) to be appropriate to the function and then adds constraints
293     /// derived from the function body.
294     ///
295     /// Note that it does **not** restore the state of the fields that
296     /// it updates! This is intentional, since -- for the main
297     /// function -- we wish to be able to read the final
298     /// `outlives_environment` and other fields from the caller. For
299     /// closures, however, we save and restore any "scoped state"
300     /// before we invoke this function. (See `visit_fn` in the
301     /// `intravisit::Visitor` impl below.)
302     fn visit_fn_body(
303         &mut self,
304         id: hir::HirId, // the id of the fn itself
305         body: &'tcx hir::Body,
306         span: Span,
307     ) {
308         // When we enter a function, we can derive
309         debug!("visit_fn_body(id={:?})", id);
310
311         let body_id = body.id();
312         self.body_id = body_id.hir_id;
313         self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
314
315         let call_site = region::Scope {
316             id: body.value.hir_id.local_id,
317             data: region::ScopeData::CallSite,
318         };
319         self.call_site_scope = Some(call_site);
320
321         let fn_sig = {
322             match self.tables.borrow().liberated_fn_sigs().get(id) {
323                 Some(f) => f.clone(),
324                 None => {
325                     bug!("No fn-sig entry for id={:?}", id);
326                 }
327             }
328         };
329
330         // Collect the types from which we create inferred bounds.
331         // For the return type, if diverging, substitute `bool` just
332         // because it will have no effect.
333         //
334         // FIXME(#27579) return types should not be implied bounds
335         let fn_sig_tys: Vec<_> = fn_sig
336             .inputs()
337             .iter()
338             .cloned()
339             .chain(Some(fn_sig.output()))
340             .collect();
341
342         self.outlives_environment.add_implied_bounds(
343             self.fcx,
344             &fn_sig_tys[..],
345             body_id.hir_id,
346             span,
347         );
348         self.outlives_environment
349             .save_implied_bounds(body_id.hir_id);
350         self.link_fn_args(
351             region::Scope {
352                 id: body.value.hir_id.local_id,
353                 data: region::ScopeData::Node,
354             },
355             &body.arguments,
356         );
357         self.visit_body(body);
358         self.visit_region_obligations(body_id.hir_id);
359
360         let call_site_scope = self.call_site_scope.unwrap();
361         debug!(
362             "visit_fn_body body.id {:?} call_site_scope: {:?}",
363             body.id(),
364             call_site_scope
365         );
366         let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope));
367
368         self.type_of_node_must_outlive(infer::CallReturn(span), body_id.hir_id, call_site_region);
369
370         self.constrain_opaque_types(
371             &self.fcx.opaque_types.borrow(),
372             self.outlives_environment.free_region_map(),
373         );
374     }
375
376     fn visit_region_obligations(&mut self, hir_id: hir::HirId) {
377         debug!("visit_region_obligations: hir_id={:?}", hir_id);
378
379         // region checking can introduce new pending obligations
380         // which, when processed, might generate new region
381         // obligations. So make sure we process those.
382         self.select_all_obligations_or_error();
383     }
384
385     fn resolve_regions_and_report_errors(&self, suppress: SuppressRegionErrors) {
386         self.infcx.process_registered_region_obligations(
387             self.outlives_environment.region_bound_pairs_map(),
388             self.implicit_region_bound,
389             self.param_env,
390         );
391
392         self.fcx.resolve_regions_and_report_errors(
393             self.subject_def_id,
394             &self.region_scope_tree,
395             &self.outlives_environment,
396             suppress,
397         );
398     }
399
400     fn constrain_bindings_in_pat(&mut self, pat: &hir::Pat) {
401         debug!("regionck::visit_pat(pat={:?})", pat);
402         pat.each_binding(|_, hir_id, span, _| {
403             // If we have a variable that contains region'd data, that
404             // data will be accessible from anywhere that the variable is
405             // accessed. We must be wary of loops like this:
406             //
407             //     // from src/test/compile-fail/borrowck-lend-flow.rs
408             //     let mut v = box 3, w = box 4;
409             //     let mut x = &mut w;
410             //     loop {
411             //         **x += 1;   // (2)
412             //         borrow(v);  //~ ERROR cannot borrow
413             //         x = &mut v; // (1)
414             //     }
415             //
416             // Typically, we try to determine the region of a borrow from
417             // those points where it is dereferenced. In this case, one
418             // might imagine that the lifetime of `x` need only be the
419             // body of the loop. But of course this is incorrect because
420             // the pointer that is created at point (1) is consumed at
421             // point (2), meaning that it must be live across the loop
422             // iteration. The easiest way to guarantee this is to require
423             // that the lifetime of any regions that appear in a
424             // variable's type enclose at least the variable's scope.
425             let var_scope = self.region_scope_tree.var_scope(hir_id.local_id);
426             let var_region = self.tcx.mk_region(ty::ReScope(var_scope));
427
428             let origin = infer::BindingTypeIsNotValidAtDecl(span);
429             self.type_of_node_must_outlive(origin, hir_id, var_region);
430
431             let typ = self.resolve_node_type(hir_id);
432             let body_id = self.body_id;
433             let _ = dropck::check_safety_of_destructor_if_necessary(
434                 self, typ, span, body_id, var_scope,
435             );
436         })
437     }
438 }
439
440 impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
441     // (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
442     // However, right now we run into an issue whereby some free
443     // regions are not properly related if they appear within the
444     // types of arguments that must be inferred. This could be
445     // addressed by deferring the construction of the region
446     // hierarchy, and in particular the relationships between free
447     // regions, until regionck, as described in #3238.
448
449     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
450         NestedVisitorMap::None
451     }
452
453     fn visit_fn(
454         &mut self,
455         fk: intravisit::FnKind<'tcx>,
456         _: &'tcx hir::FnDecl,
457         body_id: hir::BodyId,
458         span: Span,
459         hir_id: hir::HirId,
460     ) {
461         assert!(
462             match fk {
463                 intravisit::FnKind::Closure(..) => true,
464                 _ => false,
465             },
466             "visit_fn invoked for something other than a closure"
467         );
468
469         // Save state of current function before invoking
470         // `visit_fn_body`.  We will restore afterwards.
471         let old_body_id = self.body_id;
472         let old_body_owner = self.body_owner;
473         let old_call_site_scope = self.call_site_scope;
474         let env_snapshot = self.outlives_environment.push_snapshot_pre_closure();
475
476         let body = self.tcx.hir().body(body_id);
477         self.visit_fn_body(hir_id, body, span);
478
479         // Restore state from previous function.
480         self.outlives_environment
481             .pop_snapshot_post_closure(env_snapshot);
482         self.call_site_scope = old_call_site_scope;
483         self.body_id = old_body_id;
484         self.body_owner = old_body_owner;
485     }
486
487     //visit_pat: visit_pat, // (..) see above
488
489     fn visit_arm(&mut self, arm: &'tcx hir::Arm) {
490         // see above
491         for p in &arm.pats {
492             self.constrain_bindings_in_pat(p);
493         }
494         intravisit::walk_arm(self, arm);
495     }
496
497     fn visit_local(&mut self, l: &'tcx hir::Local) {
498         // see above
499         self.constrain_bindings_in_pat(&l.pat);
500         self.link_local(l);
501         intravisit::walk_local(self, l);
502     }
503
504     fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
505         debug!(
506             "regionck::visit_expr(e={:?}, repeating_scope={:?})",
507             expr, self.repeating_scope
508         );
509
510         // No matter what, the type of each expression must outlive the
511         // scope of that expression. This also guarantees basic WF.
512         let expr_ty = self.resolve_node_type(expr.hir_id);
513         // the region corresponding to this expression
514         let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope {
515             id: expr.hir_id.local_id,
516             data: region::ScopeData::Node,
517         }));
518         self.type_must_outlive(
519             infer::ExprTypeIsNotInScope(expr_ty, expr.span),
520             expr_ty,
521             expr_region,
522         );
523
524         let is_method_call = self.tables.borrow().is_method_call(expr);
525
526         // If we are calling a method (either explicitly or via an
527         // overloaded operator), check that all of the types provided as
528         // arguments for its type parameters are well-formed, and all the regions
529         // provided as arguments outlive the call.
530         if is_method_call {
531             let origin = match expr.node {
532                 hir::ExprKind::MethodCall(..) => infer::ParameterOrigin::MethodCall,
533                 hir::ExprKind::Unary(op, _) if op == hir::UnDeref => {
534                     infer::ParameterOrigin::OverloadedDeref
535                 }
536                 _ => infer::ParameterOrigin::OverloadedOperator,
537             };
538
539             let substs = self.tables.borrow().node_substs(expr.hir_id);
540             self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
541             // Arguments (sub-expressions) are checked via `constrain_call`, below.
542         }
543
544         // Check any autoderefs or autorefs that appear.
545         let cmt_result = self.constrain_adjustments(expr);
546
547         // If necessary, constrain destructors in this expression. This will be
548         // the adjusted form if there is an adjustment.
549         match cmt_result {
550             Ok(head_cmt) => {
551                 self.check_safety_of_rvalue_destructor_if_necessary(&head_cmt, expr.span);
552             }
553             Err(..) => {
554                 self.tcx.sess.delay_span_bug(expr.span, "cat_expr Errd");
555             }
556         }
557
558         debug!(
559             "regionck::visit_expr(e={:?}, repeating_scope={:?}) - visiting subexprs",
560             expr, self.repeating_scope
561         );
562         match expr.node {
563             hir::ExprKind::Path(_) => {
564                 let substs = self.tables.borrow().node_substs(expr.hir_id);
565                 let origin = infer::ParameterOrigin::Path;
566                 self.substs_wf_in_scope(origin, substs, expr.span, expr_region);
567             }
568
569             hir::ExprKind::Call(ref callee, ref args) => {
570                 if is_method_call {
571                     self.constrain_call(expr, Some(&callee), args.iter().map(|e| &*e));
572                 } else {
573                     self.constrain_callee(&callee);
574                     self.constrain_call(expr, None, args.iter().map(|e| &*e));
575                 }
576
577                 intravisit::walk_expr(self, expr);
578             }
579
580             hir::ExprKind::MethodCall(.., ref args) => {
581                 self.constrain_call(expr, Some(&args[0]), args[1..].iter().map(|e| &*e));
582
583                 intravisit::walk_expr(self, expr);
584             }
585
586             hir::ExprKind::AssignOp(_, ref lhs, ref rhs) => {
587                 if is_method_call {
588                     self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
589                 }
590
591                 intravisit::walk_expr(self, expr);
592             }
593
594             hir::ExprKind::Index(ref lhs, ref rhs) if is_method_call => {
595                 self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
596
597                 intravisit::walk_expr(self, expr);
598             }
599
600             hir::ExprKind::Binary(_, ref lhs, ref rhs) if is_method_call => {
601                 // As `ExprKind::MethodCall`, but the call is via an overloaded op.
602                 self.constrain_call(expr, Some(&lhs), Some(&**rhs).into_iter());
603
604                 intravisit::walk_expr(self, expr);
605             }
606
607             hir::ExprKind::Binary(_, ref lhs, ref rhs) => {
608                 // If you do `x OP y`, then the types of `x` and `y` must
609                 // outlive the operation you are performing.
610                 let lhs_ty = self.resolve_expr_type_adjusted(&lhs);
611                 let rhs_ty = self.resolve_expr_type_adjusted(&rhs);
612                 for &ty in &[lhs_ty, rhs_ty] {
613                     self.type_must_outlive(infer::Operand(expr.span), ty, expr_region);
614                 }
615                 intravisit::walk_expr(self, expr);
616             }
617
618             hir::ExprKind::Unary(hir::UnDeref, ref base) => {
619                 // For *a, the lifetime of a must enclose the deref
620                 if is_method_call {
621                     self.constrain_call(expr, Some(base), None::<hir::Expr>.iter());
622                 }
623                 // For overloaded derefs, base_ty is the input to `Deref::deref`,
624                 // but it's a reference type uing the same region as the output.
625                 let base_ty = self.resolve_expr_type_adjusted(base);
626                 if let ty::Ref(r_ptr, _, _) = base_ty.sty {
627                     self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
628                 }
629
630                 intravisit::walk_expr(self, expr);
631             }
632
633             hir::ExprKind::Unary(_, ref lhs) if is_method_call => {
634                 // As above.
635                 self.constrain_call(expr, Some(&lhs), None::<hir::Expr>.iter());
636
637                 intravisit::walk_expr(self, expr);
638             }
639
640             hir::ExprKind::Index(ref vec_expr, _) => {
641                 // For a[b], the lifetime of a must enclose the deref
642                 let vec_type = self.resolve_expr_type_adjusted(&vec_expr);
643                 self.constrain_index(expr, vec_type);
644
645                 intravisit::walk_expr(self, expr);
646             }
647
648             hir::ExprKind::Cast(ref source, _) => {
649                 // Determine if we are casting `source` to a trait
650                 // instance.  If so, we have to be sure that the type of
651                 // the source obeys the trait's region bound.
652                 self.constrain_cast(expr, &source);
653                 intravisit::walk_expr(self, expr);
654             }
655
656             hir::ExprKind::AddrOf(m, ref base) => {
657                 self.link_addr_of(expr, m, &base);
658
659                 // Require that when you write a `&expr` expression, the
660                 // resulting pointer has a lifetime that encompasses the
661                 // `&expr` expression itself. Note that we constraining
662                 // the type of the node expr.id here *before applying
663                 // adjustments*.
664                 //
665                 // FIXME(https://github.com/rust-lang/rfcs/issues/811)
666                 // nested method calls requires that this rule change
667                 let ty0 = self.resolve_node_type(expr.hir_id);
668                 self.type_must_outlive(infer::AddrOf(expr.span), ty0, expr_region);
669                 intravisit::walk_expr(self, expr);
670             }
671
672             hir::ExprKind::Match(ref discr, ref arms, _) => {
673                 self.link_match(&discr, &arms[..]);
674
675                 intravisit::walk_expr(self, expr);
676             }
677
678             hir::ExprKind::Closure(.., body_id, _, _) => {
679                 self.check_expr_fn_block(expr, body_id);
680             }
681
682             hir::ExprKind::Loop(ref body, _, _) => {
683                 let repeating_scope = self.set_repeating_scope(body.hir_id);
684                 intravisit::walk_expr(self, expr);
685                 self.set_repeating_scope(repeating_scope);
686             }
687
688             hir::ExprKind::Ret(Some(ref ret_expr)) => {
689                 let call_site_scope = self.call_site_scope;
690                 debug!(
691                     "visit_expr ExprKind::Ret ret_expr.hir_id {} call_site_scope: {:?}",
692                     ret_expr.hir_id, call_site_scope
693                 );
694                 let call_site_region = self.tcx.mk_region(ty::ReScope(call_site_scope.unwrap()));
695                 self.type_of_node_must_outlive(
696                     infer::CallReturn(ret_expr.span),
697                     ret_expr.hir_id,
698                     call_site_region,
699                 );
700                 intravisit::walk_expr(self, expr);
701             }
702
703             _ => {
704                 intravisit::walk_expr(self, expr);
705             }
706         }
707     }
708 }
709
710 impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
711     fn constrain_cast(&mut self, cast_expr: &hir::Expr, source_expr: &hir::Expr) {
712         debug!(
713             "constrain_cast(cast_expr={:?}, source_expr={:?})",
714             cast_expr, source_expr
715         );
716
717         let source_ty = self.resolve_node_type(source_expr.hir_id);
718         let target_ty = self.resolve_node_type(cast_expr.hir_id);
719
720         self.walk_cast(cast_expr, source_ty, target_ty);
721     }
722
723     fn walk_cast(&mut self, cast_expr: &hir::Expr, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) {
724         debug!("walk_cast(from_ty={:?}, to_ty={:?})", from_ty, to_ty);
725         match (&from_ty.sty, &to_ty.sty) {
726             /*From:*/
727             (&ty::Ref(from_r, from_ty, _), /*To:  */ &ty::Ref(to_r, to_ty, _)) => {
728                 // Target cannot outlive source, naturally.
729                 self.sub_regions(infer::Reborrow(cast_expr.span), to_r, from_r);
730                 self.walk_cast(cast_expr, from_ty, to_ty);
731             }
732
733             /*From:*/
734             (_, /*To:  */ &ty::Dynamic(.., r)) => {
735                 // When T is existentially quantified as a trait
736                 // `Foo+'to`, it must outlive the region bound `'to`.
737                 self.type_must_outlive(infer::RelateObjectBound(cast_expr.span), from_ty, r);
738             }
739
740             /*From:*/
741             (&ty::Adt(from_def, _), /*To:  */ &ty::Adt(to_def, _))
742                 if from_def.is_box() && to_def.is_box() =>
743             {
744                 self.walk_cast(cast_expr, from_ty.boxed_ty(), to_ty.boxed_ty());
745             }
746
747             _ => {}
748         }
749     }
750
751     fn check_expr_fn_block(&mut self, expr: &'tcx hir::Expr, body_id: hir::BodyId) {
752         let repeating_scope = self.set_repeating_scope(body_id.hir_id);
753         intravisit::walk_expr(self, expr);
754         self.set_repeating_scope(repeating_scope);
755     }
756
757     fn constrain_callee(&mut self, callee_expr: &hir::Expr) {
758         let callee_ty = self.resolve_node_type(callee_expr.hir_id);
759         match callee_ty.sty {
760             ty::FnDef(..) | ty::FnPtr(_) => {}
761             _ => {
762                 // this should not happen, but it does if the program is
763                 // erroneous
764                 //
765                 // bug!(
766                 //     callee_expr.span,
767                 //     "Calling non-function: {}",
768                 //     callee_ty);
769             }
770         }
771     }
772
773     fn constrain_call<'b, I: Iterator<Item = &'b hir::Expr>>(
774         &mut self,
775         call_expr: &hir::Expr,
776         receiver: Option<&hir::Expr>,
777         arg_exprs: I,
778     ) {
779         //! Invoked on every call site (i.e., normal calls, method calls,
780         //! and overloaded operators). Constrains the regions which appear
781         //! in the type of the function. Also constrains the regions that
782         //! appear in the arguments appropriately.
783
784         debug!(
785             "constrain_call(call_expr={:?}, receiver={:?})",
786             call_expr, receiver
787         );
788
789         // `callee_region` is the scope representing the time in which the
790         // call occurs.
791         //
792         // FIXME(#6268) to support nested method calls, should be callee_id
793         let callee_scope = region::Scope {
794             id: call_expr.hir_id.local_id,
795             data: region::ScopeData::Node,
796         };
797         let callee_region = self.tcx.mk_region(ty::ReScope(callee_scope));
798
799         debug!("callee_region={:?}", callee_region);
800
801         for arg_expr in arg_exprs {
802             debug!("argument: {:?}", arg_expr);
803
804             // ensure that any regions appearing in the argument type are
805             // valid for at least the lifetime of the function:
806             self.type_of_node_must_outlive(
807                 infer::CallArg(arg_expr.span),
808                 arg_expr.hir_id,
809                 callee_region,
810             );
811         }
812
813         // as loop above, but for receiver
814         if let Some(r) = receiver {
815             debug!("receiver: {:?}", r);
816             self.type_of_node_must_outlive(infer::CallRcvr(r.span), r.hir_id, callee_region);
817         }
818     }
819
820     /// Creates a temporary `MemCategorizationContext` and pass it to the closure.
821     fn with_mc<F, R>(&self, f: F) -> R
822     where
823         F: for<'b> FnOnce(mc::MemCategorizationContext<'b, 'tcx>) -> R,
824     {
825         f(mc::MemCategorizationContext::with_infer(
826             &self.infcx,
827             self.body_owner,
828             &self.region_scope_tree,
829             &self.tables.borrow(),
830         ))
831     }
832
833     /// Invoked on any adjustments that occur. Checks that if this is a region pointer being
834     /// dereferenced, the lifetime of the pointer includes the deref expr.
835     fn constrain_adjustments(&mut self, expr: &hir::Expr) -> mc::McResult<mc::cmt_<'tcx>> {
836         debug!("constrain_adjustments(expr={:?})", expr);
837
838         let mut cmt = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
839
840         let tables = self.tables.borrow();
841         let adjustments = tables.expr_adjustments(&expr);
842         if adjustments.is_empty() {
843             return Ok(cmt);
844         }
845
846         debug!("constrain_adjustments: adjustments={:?}", adjustments);
847
848         // If necessary, constrain destructors in the unadjusted form of this
849         // expression.
850         self.check_safety_of_rvalue_destructor_if_necessary(&cmt, expr.span);
851
852         let expr_region = self.tcx.mk_region(ty::ReScope(region::Scope {
853             id: expr.hir_id.local_id,
854             data: region::ScopeData::Node,
855         }));
856         for adjustment in adjustments {
857             debug!(
858                 "constrain_adjustments: adjustment={:?}, cmt={:?}",
859                 adjustment, cmt
860             );
861
862             if let adjustment::Adjust::Deref(Some(deref)) = adjustment.kind {
863                 debug!("constrain_adjustments: overloaded deref: {:?}", deref);
864
865                 // Treat overloaded autoderefs as if an AutoBorrow adjustment
866                 // was applied on the base type, as that is always the case.
867                 let input = self.tcx.mk_ref(
868                     deref.region,
869                     ty::TypeAndMut {
870                         ty: cmt.ty,
871                         mutbl: deref.mutbl,
872                     },
873                 );
874                 let output = self.tcx.mk_ref(
875                     deref.region,
876                     ty::TypeAndMut {
877                         ty: adjustment.target,
878                         mutbl: deref.mutbl,
879                     },
880                 );
881
882                 self.link_region(
883                     expr.span,
884                     deref.region,
885                     ty::BorrowKind::from_mutbl(deref.mutbl),
886                     &cmt,
887                 );
888
889                 // Specialized version of constrain_call.
890                 self.type_must_outlive(infer::CallRcvr(expr.span), input, expr_region);
891                 self.type_must_outlive(infer::CallReturn(expr.span), output, expr_region);
892             }
893
894             if let adjustment::Adjust::Borrow(ref autoref) = adjustment.kind {
895                 self.link_autoref(expr, &cmt, autoref);
896
897                 // Require that the resulting region encompasses
898                 // the current node.
899                 //
900                 // FIXME(#6268) remove to support nested method calls
901                 self.type_of_node_must_outlive(
902                     infer::AutoBorrow(expr.span),
903                     expr.hir_id,
904                     expr_region,
905                 );
906             }
907
908             cmt = self.with_mc(|mc| mc.cat_expr_adjusted(expr, cmt, &adjustment))?;
909
910             if let Categorization::Deref(_, mc::BorrowedPtr(_, r_ptr)) = cmt.cat {
911                 self.mk_subregion_due_to_dereference(expr.span, expr_region, r_ptr);
912             }
913         }
914
915         Ok(cmt)
916     }
917
918     pub fn mk_subregion_due_to_dereference(
919         &mut self,
920         deref_span: Span,
921         minimum_lifetime: ty::Region<'tcx>,
922         maximum_lifetime: ty::Region<'tcx>,
923     ) {
924         self.sub_regions(
925             infer::DerefPointer(deref_span),
926             minimum_lifetime,
927             maximum_lifetime,
928         )
929     }
930
931     fn check_safety_of_rvalue_destructor_if_necessary(&mut self, cmt: &mc::cmt_<'tcx>, span: Span) {
932         if let Categorization::Rvalue(region) = cmt.cat {
933             match *region {
934                 ty::ReScope(rvalue_scope) => {
935                     let typ = self.resolve_type(cmt.ty);
936                     let body_id = self.body_id;
937                     let _ = dropck::check_safety_of_destructor_if_necessary(
938                         self,
939                         typ,
940                         span,
941                         body_id,
942                         rvalue_scope,
943                     );
944                 }
945                 ty::ReStatic => {}
946                 _ => {
947                     span_bug!(
948                         span,
949                         "unexpected rvalue region in rvalue \
950                          destructor safety checking: `{:?}`",
951                         region
952                     );
953                 }
954             }
955         }
956     }
957
958     /// Invoked on any index expression that occurs. Checks that if this is a slice
959     /// being indexed, the lifetime of the pointer includes the deref expr.
960     fn constrain_index(&mut self, index_expr: &hir::Expr, indexed_ty: Ty<'tcx>) {
961         debug!(
962             "constrain_index(index_expr=?, indexed_ty={}",
963             self.ty_to_string(indexed_ty)
964         );
965
966         let r_index_expr = ty::ReScope(region::Scope {
967             id: index_expr.hir_id.local_id,
968             data: region::ScopeData::Node,
969         });
970         if let ty::Ref(r_ptr, r_ty, _) = indexed_ty.sty {
971             match r_ty.sty {
972                 ty::Slice(_) | ty::Str => {
973                     self.sub_regions(
974                         infer::IndexSlice(index_expr.span),
975                         self.tcx.mk_region(r_index_expr),
976                         r_ptr,
977                     );
978                 }
979                 _ => {}
980             }
981         }
982     }
983
984     /// Guarantees that any lifetimes that appear in the type of the node `id` (after applying
985     /// adjustments) are valid for at least `minimum_lifetime`.
986     fn type_of_node_must_outlive(
987         &mut self,
988         origin: infer::SubregionOrigin<'tcx>,
989         hir_id: hir::HirId,
990         minimum_lifetime: ty::Region<'tcx>,
991     ) {
992         // Try to resolve the type.  If we encounter an error, then typeck
993         // is going to fail anyway, so just stop here and let typeck
994         // report errors later on in the writeback phase.
995         let ty0 = self.resolve_node_type(hir_id);
996
997         let ty = self.tables
998             .borrow()
999             .adjustments()
1000             .get(hir_id)
1001             .and_then(|adj| adj.last())
1002             .map_or(ty0, |adj| adj.target);
1003         let ty = self.resolve_type(ty);
1004         debug!(
1005             "constrain_regions_in_type_of_node(\
1006              ty={}, ty0={}, id={:?}, minimum_lifetime={:?})",
1007             ty, ty0, hir_id, minimum_lifetime
1008         );
1009         self.type_must_outlive(origin, ty, minimum_lifetime);
1010     }
1011
1012     /// Adds constraints to inference such that `T: 'a` holds (or
1013     /// reports an error if it cannot).
1014     ///
1015     /// # Parameters
1016     ///
1017     /// - `origin`, the reason we need this constraint
1018     /// - `ty`, the type `T`
1019     /// - `region`, the region `'a`
1020     pub fn type_must_outlive(
1021         &self,
1022         origin: infer::SubregionOrigin<'tcx>,
1023         ty: Ty<'tcx>,
1024         region: ty::Region<'tcx>,
1025     ) {
1026         self.infcx.register_region_obligation(
1027             self.body_id,
1028             RegionObligation {
1029                 sub_region: region,
1030                 sup_type: ty,
1031                 origin,
1032             },
1033         );
1034     }
1035
1036     /// Computes the guarantor for an expression `&base` and then ensures that the lifetime of the
1037     /// resulting pointer is linked to the lifetime of its guarantor (if any).
1038     fn link_addr_of(&mut self, expr: &hir::Expr, mutability: hir::Mutability, base: &hir::Expr) {
1039         debug!("link_addr_of(expr={:?}, base={:?})", expr, base);
1040
1041         let cmt = ignore_err!(self.with_mc(|mc| mc.cat_expr(base)));
1042
1043         debug!("link_addr_of: cmt={:?}", cmt);
1044
1045         self.link_region_from_node_type(expr.span, expr.hir_id, mutability, &cmt);
1046     }
1047
1048     /// Computes the guarantors for any ref bindings in a `let` and
1049     /// then ensures that the lifetime of the resulting pointer is
1050     /// linked to the lifetime of the initialization expression.
1051     fn link_local(&self, local: &hir::Local) {
1052         debug!("regionck::for_local()");
1053         let init_expr = match local.init {
1054             None => {
1055                 return;
1056             }
1057             Some(ref expr) => &**expr,
1058         };
1059         let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(init_expr))));
1060         self.link_pattern(discr_cmt, &local.pat);
1061     }
1062
1063     /// Computes the guarantors for any ref bindings in a match and
1064     /// then ensures that the lifetime of the resulting pointer is
1065     /// linked to the lifetime of its guarantor (if any).
1066     fn link_match(&self, discr: &hir::Expr, arms: &[hir::Arm]) {
1067         debug!("regionck::for_match()");
1068         let discr_cmt = Rc::new(ignore_err!(self.with_mc(|mc| mc.cat_expr(discr))));
1069         debug!("discr_cmt={:?}", discr_cmt);
1070         for arm in arms {
1071             for root_pat in &arm.pats {
1072                 self.link_pattern(discr_cmt.clone(), &root_pat);
1073             }
1074         }
1075     }
1076
1077     /// Computes the guarantors for any ref bindings in a match and
1078     /// then ensures that the lifetime of the resulting pointer is
1079     /// linked to the lifetime of its guarantor (if any).
1080     fn link_fn_args(&self, body_scope: region::Scope, args: &[hir::Arg]) {
1081         debug!("regionck::link_fn_args(body_scope={:?})", body_scope);
1082         for arg in args {
1083             let arg_ty = self.node_ty(arg.hir_id);
1084             let re_scope = self.tcx.mk_region(ty::ReScope(body_scope));
1085             let arg_cmt = self.with_mc(|mc| {
1086                 Rc::new(mc.cat_rvalue(arg.hir_id, arg.pat.span, re_scope, arg_ty))
1087             });
1088             debug!("arg_ty={:?} arg_cmt={:?} arg={:?}", arg_ty, arg_cmt, arg);
1089             self.link_pattern(arg_cmt, &arg.pat);
1090         }
1091     }
1092
1093     /// Link lifetimes of any ref bindings in `root_pat` to the pointers found
1094     /// in the discriminant, if needed.
1095     fn link_pattern(&self, discr_cmt: mc::cmt<'tcx>, root_pat: &hir::Pat) {
1096         debug!(
1097             "link_pattern(discr_cmt={:?}, root_pat={:?})",
1098             discr_cmt, root_pat
1099         );
1100         ignore_err!(self.with_mc(|mc| {
1101             mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, sub_pat| {
1102                 // `ref x` pattern
1103                 if let PatKind::Binding(..) = sub_pat.node {
1104                     if let Some(&bm) = mc.tables.pat_binding_modes().get(sub_pat.hir_id) {
1105                         if let ty::BindByReference(mutbl) = bm {
1106                             self.link_region_from_node_type(
1107                                 sub_pat.span,
1108                                 sub_pat.hir_id,
1109                                 mutbl,
1110                                 &sub_cmt,
1111                             );
1112                         }
1113                     } else {
1114                         self.tcx
1115                             .sess
1116                             .delay_span_bug(sub_pat.span, "missing binding mode");
1117                     }
1118                 }
1119             })
1120         }));
1121     }
1122
1123     /// Link lifetime of borrowed pointer resulting from autoref to lifetimes in the value being
1124     /// autoref'd.
1125     fn link_autoref(
1126         &self,
1127         expr: &hir::Expr,
1128         expr_cmt: &mc::cmt_<'tcx>,
1129         autoref: &adjustment::AutoBorrow<'tcx>,
1130     ) {
1131         debug!(
1132             "link_autoref(autoref={:?}, expr_cmt={:?})",
1133             autoref, expr_cmt
1134         );
1135
1136         match *autoref {
1137             adjustment::AutoBorrow::Ref(r, m) => {
1138                 self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m.into()), expr_cmt);
1139             }
1140
1141             adjustment::AutoBorrow::RawPtr(m) => {
1142                 let r = self.tcx.mk_region(ty::ReScope(region::Scope {
1143                     id: expr.hir_id.local_id,
1144                     data: region::ScopeData::Node,
1145                 }));
1146                 self.link_region(expr.span, r, ty::BorrowKind::from_mutbl(m), expr_cmt);
1147             }
1148         }
1149     }
1150
1151     /// Like `link_region()`, except that the region is extracted from the type of `id`,
1152     /// which must be some reference (`&T`, `&str`, etc).
1153     fn link_region_from_node_type(
1154         &self,
1155         span: Span,
1156         id: hir::HirId,
1157         mutbl: hir::Mutability,
1158         cmt_borrowed: &mc::cmt_<'tcx>,
1159     ) {
1160         debug!(
1161             "link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})",
1162             id, mutbl, cmt_borrowed
1163         );
1164
1165         let rptr_ty = self.resolve_node_type(id);
1166         if let ty::Ref(r, _, _) = rptr_ty.sty {
1167             debug!("rptr_ty={}", rptr_ty);
1168             self.link_region(span, r, ty::BorrowKind::from_mutbl(mutbl), cmt_borrowed);
1169         }
1170     }
1171
1172     /// Informs the inference engine that `borrow_cmt` is being borrowed with
1173     /// kind `borrow_kind` and lifetime `borrow_region`.
1174     /// In order to ensure borrowck is satisfied, this may create constraints
1175     /// between regions, as explained in `link_reborrowed_region()`.
1176     fn link_region(
1177         &self,
1178         span: Span,
1179         borrow_region: ty::Region<'tcx>,
1180         borrow_kind: ty::BorrowKind,
1181         borrow_cmt: &mc::cmt_<'tcx>,
1182     ) {
1183         let origin = infer::DataBorrowed(borrow_cmt.ty, span);
1184         self.type_must_outlive(origin, borrow_cmt.ty, borrow_region);
1185
1186         let mut borrow_kind = borrow_kind;
1187         let mut borrow_cmt_cat = borrow_cmt.cat.clone();
1188
1189         loop {
1190             debug!(
1191                 "link_region(borrow_region={:?}, borrow_kind={:?}, borrow_cmt={:?})",
1192                 borrow_region, borrow_kind, borrow_cmt
1193             );
1194             match borrow_cmt_cat {
1195                 Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => {
1196                     match self.link_reborrowed_region(
1197                         span,
1198                         borrow_region,
1199                         borrow_kind,
1200                         ref_cmt,
1201                         ref_region,
1202                         ref_kind,
1203                         borrow_cmt.note,
1204                     ) {
1205                         Some((c, k)) => {
1206                             borrow_cmt_cat = c.cat.clone();
1207                             borrow_kind = k;
1208                         }
1209                         None => {
1210                             return;
1211                         }
1212                     }
1213                 }
1214
1215                 Categorization::Downcast(cmt_base, _)
1216                 | Categorization::Deref(cmt_base, mc::Unique)
1217                 | Categorization::Interior(cmt_base, _) => {
1218                     // Borrowing interior or owned data requires the base
1219                     // to be valid and borrowable in the same fashion.
1220                     borrow_cmt_cat = cmt_base.cat.clone();
1221                     borrow_kind = borrow_kind;
1222                 }
1223
1224                 Categorization::Deref(_, mc::UnsafePtr(..))
1225                 | Categorization::StaticItem
1226                 | Categorization::Upvar(..)
1227                 | Categorization::Local(..)
1228                 | Categorization::ThreadLocal(..)
1229                 | Categorization::Rvalue(..) => {
1230                     // These are all "base cases" with independent lifetimes
1231                     // that are not subject to inference
1232                     return;
1233                 }
1234             }
1235         }
1236     }
1237
1238     /// This is the most complicated case: the path being borrowed is
1239     /// itself the referent of a borrowed pointer. Let me give an
1240     /// example fragment of code to make clear(er) the situation:
1241     ///
1242     ///    let r: &'a mut T = ...;  // the original reference "r" has lifetime 'a
1243     ///    ...
1244     ///    &'z *r                   // the reborrow has lifetime 'z
1245     ///
1246     /// Now, in this case, our primary job is to add the inference
1247     /// constraint that `'z <= 'a`. Given this setup, let's clarify the
1248     /// parameters in (roughly) terms of the example:
1249     ///
1250     /// ```plain,ignore (pseudo-Rust)
1251     ///     A borrow of: `& 'z bk * r` where `r` has type `& 'a bk T`
1252     ///     borrow_region   ^~                 ref_region    ^~
1253     ///     borrow_kind        ^~               ref_kind        ^~
1254     ///     ref_cmt                 ^
1255     /// ```
1256     ///
1257     /// Here `bk` stands for some borrow-kind (e.g., `mut`, `uniq`, etc).
1258     ///
1259     /// Unfortunately, there are some complications beyond the simple
1260     /// scenario I just painted:
1261     ///
1262     /// 1. The reference `r` might in fact be a "by-ref" upvar. In that
1263     ///    case, we have two jobs. First, we are inferring whether this reference
1264     ///    should be an `&T`, `&mut T`, or `&uniq T` reference, and we must
1265     ///    adjust that based on this borrow (e.g., if this is an `&mut` borrow,
1266     ///    then `r` must be an `&mut` reference). Second, whenever we link
1267     ///    two regions (here, `'z <= 'a`), we supply a *cause*, and in this
1268     ///    case we adjust the cause to indicate that the reference being
1269     ///    "reborrowed" is itself an upvar. This provides a nicer error message
1270     ///    should something go wrong.
1271     ///
1272     /// 2. There may in fact be more levels of reborrowing. In the
1273     ///    example, I said the borrow was like `&'z *r`, but it might
1274     ///    in fact be a borrow like `&'z **q` where `q` has type `&'a
1275     ///    &'b mut T`. In that case, we want to ensure that `'z <= 'a`
1276     ///    and `'z <= 'b`. This is explained more below.
1277     ///
1278     /// The return value of this function indicates whether we need to
1279     /// recurse and process `ref_cmt` (see case 2 above).
1280     fn link_reborrowed_region(
1281         &self,
1282         span: Span,
1283         borrow_region: ty::Region<'tcx>,
1284         borrow_kind: ty::BorrowKind,
1285         ref_cmt: mc::cmt<'tcx>,
1286         ref_region: ty::Region<'tcx>,
1287         mut ref_kind: ty::BorrowKind,
1288         note: mc::Note,
1289     ) -> Option<(mc::cmt<'tcx>, ty::BorrowKind)> {
1290         // Possible upvar ID we may need later to create an entry in the
1291         // maybe link map.
1292
1293         // Detect by-ref upvar `x`:
1294         let cause = match note {
1295             mc::NoteUpvarRef(ref upvar_id) => {
1296                 match self.tables.borrow().upvar_capture_map.get(upvar_id) {
1297                     Some(&ty::UpvarCapture::ByRef(ref upvar_borrow)) => {
1298                         // The mutability of the upvar may have been modified
1299                         // by the above adjustment, so update our local variable.
1300                         ref_kind = upvar_borrow.kind;
1301
1302                         infer::ReborrowUpvar(span, *upvar_id)
1303                     }
1304                     _ => {
1305                         span_bug!(span, "Illegal upvar id: {:?}", upvar_id);
1306                     }
1307                 }
1308             }
1309             mc::NoteClosureEnv(ref upvar_id) => {
1310                 // We don't have any mutability changes to propagate, but
1311                 // we do want to note that an upvar reborrow caused this
1312                 // link
1313                 infer::ReborrowUpvar(span, *upvar_id)
1314             }
1315             _ => infer::Reborrow(span),
1316         };
1317
1318         debug!(
1319             "link_reborrowed_region: {:?} <= {:?}",
1320             borrow_region, ref_region
1321         );
1322         self.sub_regions(cause, borrow_region, ref_region);
1323
1324         // If we end up needing to recurse and establish a region link
1325         // with `ref_cmt`, calculate what borrow kind we will end up
1326         // needing. This will be used below.
1327         //
1328         // One interesting twist is that we can weaken the borrow kind
1329         // when we recurse: to reborrow an `&mut` referent as mutable,
1330         // borrowck requires a unique path to the `&mut` reference but not
1331         // necessarily a *mutable* path.
1332         let new_borrow_kind = match borrow_kind {
1333             ty::ImmBorrow => ty::ImmBorrow,
1334             ty::MutBorrow | ty::UniqueImmBorrow => ty::UniqueImmBorrow,
1335         };
1336
1337         // Decide whether we need to recurse and link any regions within
1338         // the `ref_cmt`. This is concerned for the case where the value
1339         // being reborrowed is in fact a borrowed pointer found within
1340         // another borrowed pointer. For example:
1341         //
1342         //    let p: &'b &'a mut T = ...;
1343         //    ...
1344         //    &'z **p
1345         //
1346         // What makes this case particularly tricky is that, if the data
1347         // being borrowed is a `&mut` or `&uniq` borrow, borrowck requires
1348         // not only that `'z <= 'a`, (as before) but also `'z <= 'b`
1349         // (otherwise the user might mutate through the `&mut T` reference
1350         // after `'b` expires and invalidate the borrow we are looking at
1351         // now).
1352         //
1353         // So let's re-examine our parameters in light of this more
1354         // complicated (possible) scenario:
1355         //
1356         //     A borrow of: `& 'z bk * * p` where `p` has type `&'b bk & 'a bk T`
1357         //     borrow_region   ^~                 ref_region             ^~
1358         //     borrow_kind        ^~               ref_kind                 ^~
1359         //     ref_cmt                 ^~~
1360         //
1361         // (Note that since we have not examined `ref_cmt.cat`, we don't
1362         // know whether this scenario has occurred; but I wanted to show
1363         // how all the types get adjusted.)
1364         match ref_kind {
1365             ty::ImmBorrow => {
1366                 // The reference being reborrowed is a shareable ref of
1367                 // type `&'a T`. In this case, it doesn't matter where we
1368                 // *found* the `&T` pointer, the memory it references will
1369                 // be valid and immutable for `'a`. So we can stop here.
1370                 //
1371                 // (Note that the `borrow_kind` must also be ImmBorrow or
1372                 // else the user is borrowed imm memory as mut memory,
1373                 // which means they'll get an error downstream in borrowck
1374                 // anyhow.)
1375                 return None;
1376             }
1377
1378             ty::MutBorrow | ty::UniqueImmBorrow => {
1379                 // The reference being reborrowed is either an `&mut T` or
1380                 // `&uniq T`. This is the case where recursion is needed.
1381                 return Some((ref_cmt, new_borrow_kind));
1382             }
1383         }
1384     }
1385
1386     /// Checks that the values provided for type/region arguments in a given
1387     /// expression are well-formed and in-scope.
1388     fn substs_wf_in_scope(
1389         &mut self,
1390         origin: infer::ParameterOrigin,
1391         substs: SubstsRef<'tcx>,
1392         expr_span: Span,
1393         expr_region: ty::Region<'tcx>,
1394     ) {
1395         debug!(
1396             "substs_wf_in_scope(substs={:?}, \
1397              expr_region={:?}, \
1398              origin={:?}, \
1399              expr_span={:?})",
1400             substs, expr_region, origin, expr_span
1401         );
1402
1403         let origin = infer::ParameterInScope(origin, expr_span);
1404
1405         for kind in substs {
1406             match kind.unpack() {
1407                 UnpackedKind::Lifetime(lt) => {
1408                     self.sub_regions(origin.clone(), expr_region, lt);
1409                 }
1410                 UnpackedKind::Type(ty) => {
1411                     let ty = self.resolve_type(ty);
1412                     self.type_must_outlive(origin.clone(), ty, expr_region);
1413                 }
1414                 UnpackedKind::Const(_) => {
1415                     // Const parameters don't impose constraints.
1416                 }
1417             }
1418         }
1419     }
1420 }