]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/borrow_check/nll/region_infer/error_reporting/var_name.rs
New upstream version 1.29.0+dfsg1
[rustc.git] / src / librustc_mir / borrow_check / nll / region_infer / error_reporting / var_name.rs
CommitLineData
8faf50e0
XL
1// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use borrow_check::nll::region_infer::RegionInferenceContext;
12use borrow_check::nll::ToRegionVid;
13use rustc::mir::{Local, Mir};
14use rustc::ty::{RegionVid, TyCtxt};
15use rustc_data_structures::indexed_vec::Idx;
16use syntax::codemap::Span;
17use syntax_pos::symbol::Symbol;
18
19impl<'tcx> RegionInferenceContext<'tcx> {
20 crate fn get_var_name_and_span_for_region(
21 &self,
22 tcx: TyCtxt<'_, '_, 'tcx>,
23 mir: &Mir<'tcx>,
24 fr: RegionVid,
25 ) -> Option<(Option<Symbol>, Span)> {
26 debug!("get_var_name_and_span_for_region(fr={:?})", fr);
27 assert!(self.universal_regions.is_universal_region(fr));
28
29 debug!("get_var_name_and_span_for_region: attempting upvar");
30 self.get_upvar_index_for_region(tcx, fr)
31 .map(|index| {
32 let (name, span) = self.get_upvar_name_and_span_for_region(tcx, mir, index);
33 (Some(name), span)
34 })
35 .or_else(|| {
36 debug!("get_var_name_and_span_for_region: attempting argument");
37 self.get_argument_index_for_region(tcx, fr)
38 .map(|index| self.get_argument_name_and_span_for_region(mir, index))
39 })
40 }
41
42 /// Search the upvars (if any) to find one that references fr. Return its index.
43 crate fn get_upvar_index_for_region(
44 &self,
45 tcx: TyCtxt<'_, '_, 'tcx>,
46 fr: RegionVid,
47 ) -> Option<usize> {
48 let upvar_index = self
49 .universal_regions
50 .defining_ty
51 .upvar_tys(tcx)
52 .position(|upvar_ty| {
53 debug!(
54 "get_upvar_index_for_region: upvar_ty = {:?}",
55 upvar_ty,
56 );
57 tcx.any_free_region_meets(&upvar_ty, |r| r.to_region_vid() == fr)
58 })?;
59
60 let upvar_ty = self
61 .universal_regions
62 .defining_ty
63 .upvar_tys(tcx)
64 .nth(upvar_index);
65
66 debug!(
67 "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}",
68 fr, upvar_index, upvar_ty,
69 );
70
71 Some(upvar_index)
72 }
73
74 /// Given the index of an upvar, finds its name and the span from where it was
75 /// declared.
76 crate fn get_upvar_name_and_span_for_region(
77 &self,
78 tcx: TyCtxt<'_, '_, 'tcx>,
79 mir: &Mir<'tcx>,
80 upvar_index: usize,
81 ) -> (Symbol, Span) {
82 let upvar_hir_id = mir.upvar_decls[upvar_index].var_hir_id.assert_crate_local();
83 let upvar_node_id = tcx.hir.hir_to_node_id(upvar_hir_id);
84 debug!("get_upvar_name_and_span_for_region: upvar_node_id={:?}", upvar_node_id);
85
86 let upvar_name = tcx.hir.name(upvar_node_id);
87 let upvar_span = tcx.hir.span(upvar_node_id);
88 debug!("get_upvar_name_and_span_for_region: upvar_name={:?} upvar_span={:?}",
89 upvar_name, upvar_span);
90
91 (upvar_name, upvar_span)
92 }
93
94 /// Search the argument types for one that references fr (which should be a free region).
95 /// Returns Some(_) with the index of the input if one is found.
96 ///
97 /// NB: In the case of a closure, the index is indexing into the signature as seen by the
98 /// user - in particular, index 0 is not the implicit self parameter.
99 crate fn get_argument_index_for_region(
100 &self,
101 tcx: TyCtxt<'_, '_, 'tcx>,
102 fr: RegionVid,
103 ) -> Option<usize> {
104 let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
105 let argument_index = self
106 .universal_regions
107 .unnormalized_input_tys
108 .iter()
109 .skip(implicit_inputs)
110 .position(|arg_ty| {
111 debug!(
112 "get_argument_index_for_region: arg_ty = {:?}",
113 arg_ty
114 );
115 tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr)
116 })?;
117
118 debug!(
119 "get_argument_index_for_region: found {:?} in argument {} which has type {:?}",
120 fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index],
121 );
122
123 Some(argument_index)
124 }
125
126 /// Given the index of an argument, finds its name (if any) and the span from where it was
127 /// declared.
128 crate fn get_argument_name_and_span_for_region(
129 &self,
130 mir: &Mir<'tcx>,
131 argument_index: usize,
132 ) -> (Option<Symbol>, Span) {
133 let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
134 let argument_local = Local::new(implicit_inputs + argument_index + 1);
135 debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local);
136
137 let argument_name = mir.local_decls[argument_local].name;
138 let argument_span = mir.local_decls[argument_local].source_info.span;
139 debug!("get_argument_name_and_span_for_region: argument_name={:?} argument_span={:?}",
140 argument_name, argument_span);
141
142 (argument_name, argument_span)
143 }
144
145}