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