]> git.proxmox.com Git - rustc.git/blame - src/librustc_mir/borrow_check/nll/facts.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / librustc_mir / borrow_check / nll / facts.rs
CommitLineData
9fa01778
XL
1use crate::borrow_check::location::{LocationIndex, LocationTable};
2use crate::dataflow::indexes::BorrowIndex;
94b46f34
XL
3use polonius_engine::AllFacts as PoloniusAllFacts;
4use polonius_engine::Atom;
8faf50e0 5use rustc::ty::{RegionVid, TyCtxt};
94b46f34 6use rustc_data_structures::indexed_vec::Idx;
83c7162d
XL
7use std::error::Error;
8use std::fmt::Debug;
9use std::fs::{self, File};
10use std::io::Write;
11use std::path::Path;
12
94b46f34 13crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex>;
83c7162d 14
94b46f34 15crate trait AllFactsExt {
9fa01778 16 /// Returns `true` if there is a need to gather `AllFacts` given the
8faf50e0
XL
17 /// current `-Z` flags.
18 fn enabled(tcx: TyCtxt<'_, '_, '_>) -> bool;
19
94b46f34
XL
20 fn write_to_dir(
21 &self,
22 dir: impl AsRef<Path>,
23 location_table: &LocationTable,
24 ) -> Result<(), Box<dyn Error>>;
83c7162d
XL
25}
26
94b46f34 27impl AllFactsExt for AllFacts {
8faf50e0
XL
28 /// Return
29 fn enabled(tcx: TyCtxt<'_, '_, '_>) -> bool {
30 tcx.sess.opts.debugging_opts.nll_facts
31 || tcx.sess.opts.debugging_opts.polonius
32 }
33
94b46f34 34 fn write_to_dir(
83c7162d
XL
35 &self,
36 dir: impl AsRef<Path>,
37 location_table: &LocationTable,
38 ) -> Result<(), Box<dyn Error>> {
39 let dir: &Path = dir.as_ref();
40 fs::create_dir_all(dir)?;
41 let wr = FactWriter { location_table, dir };
42 macro_rules! write_facts_to_path {
43 ($wr:ident . write_facts_to_path($this:ident . [
44 $($field:ident,)*
45 ])) => {
46 $(
47 $wr.write_facts_to_path(
48 &$this.$field,
49 &format!("{}.facts", stringify!($field))
50 )?;
51 )*
52 }
53 }
54 write_facts_to_path! {
55 wr.write_facts_to_path(self.[
56 borrow_region,
57 universal_region,
58 cfg_edge,
59 killed,
60 outlives,
61 region_live_at,
94b46f34 62 invalidates,
83c7162d
XL
63 ])
64 }
65 Ok(())
66 }
67}
68
94b46f34
XL
69impl Atom for BorrowIndex {
70 fn index(self) -> usize {
71 Idx::index(self)
72 }
73}
74
75impl From<usize> for BorrowIndex {
76 fn from(i: usize) -> BorrowIndex {
77 BorrowIndex::new(i)
78 }
79}
80
81impl From<BorrowIndex> for usize {
82 fn from(vid: BorrowIndex) -> usize {
83 Idx::index(vid)
84 }
85}
86
87impl Atom for LocationIndex {
88 fn index(self) -> usize {
89 Idx::index(self)
90 }
91}
92
83c7162d
XL
93struct FactWriter<'w> {
94 location_table: &'w LocationTable,
95 dir: &'w Path,
96}
97
98impl<'w> FactWriter<'w> {
99 fn write_facts_to_path<T>(
100 &self,
8faf50e0 101 rows: &[T],
83c7162d
XL
102 file_name: &str,
103 ) -> Result<(), Box<dyn Error>>
104 where
105 T: FactRow,
106 {
107 let file = &self.dir.join(file_name);
108 let mut file = File::create(file)?;
109 for row in rows {
110 row.write(&mut file, self.location_table)?;
111 }
112 Ok(())
113 }
114}
115
116trait FactRow {
117 fn write(
118 &self,
119 out: &mut File,
120 location_table: &LocationTable,
121 ) -> Result<(), Box<dyn Error>>;
122}
123
124impl FactRow for RegionVid {
125 fn write(
126 &self,
127 out: &mut File,
128 location_table: &LocationTable,
129 ) -> Result<(), Box<dyn Error>> {
130 write_row(out, location_table, &[self])
131 }
132}
133
134impl<A, B> FactRow for (A, B)
135where
136 A: FactCell,
137 B: FactCell,
138{
139 fn write(
140 &self,
141 out: &mut File,
142 location_table: &LocationTable,
143 ) -> Result<(), Box<dyn Error>> {
144 write_row(out, location_table, &[&self.0, &self.1])
145 }
146}
147
148impl<A, B, C> FactRow for (A, B, C)
149where
150 A: FactCell,
151 B: FactCell,
152 C: FactCell,
153{
154 fn write(
155 &self,
156 out: &mut File,
157 location_table: &LocationTable,
158 ) -> Result<(), Box<dyn Error>> {
159 write_row(out, location_table, &[&self.0, &self.1, &self.2])
160 }
161}
162
163impl<A, B, C, D> FactRow for (A, B, C, D)
164where
165 A: FactCell,
166 B: FactCell,
167 C: FactCell,
168 D: FactCell,
169{
170 fn write(
171 &self,
172 out: &mut File,
173 location_table: &LocationTable,
174 ) -> Result<(), Box<dyn Error>> {
175 write_row(out, location_table, &[&self.0, &self.1, &self.2, &self.3])
176 }
177}
178
179fn write_row(
180 out: &mut dyn Write,
181 location_table: &LocationTable,
182 columns: &[&dyn FactCell],
183) -> Result<(), Box<dyn Error>> {
184 for (index, c) in columns.iter().enumerate() {
185 let tail = if index == columns.len() - 1 {
186 "\n"
187 } else {
188 "\t"
189 };
190 write!(out, "{:?}{}", c.to_string(location_table), tail)?;
191 }
192 Ok(())
193}
194
195trait FactCell {
196 fn to_string(&self, location_table: &LocationTable) -> String;
197}
198
199impl<A: Debug> FactCell for A {
200 default fn to_string(&self, _location_table: &LocationTable) -> String {
201 format!("{:?}", self)
202 }
203}
204
205impl FactCell for LocationIndex {
206 fn to_string(&self, location_table: &LocationTable) -> String {
207 format!("{:?}", location_table.to_location(*self))
208 }
209}