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