1 use crate::borrow_check
::location
::{LocationIndex, LocationTable}
;
2 use crate::dataflow
::indexes
::{BorrowIndex, MovePathIndex}
;
3 use polonius_engine
::AllFacts
as PoloniusAllFacts
;
4 use polonius_engine
::Atom
;
6 use rustc
::ty
::{RegionVid, TyCtxt}
;
7 use rustc_data_structures
::indexed_vec
::Idx
;
10 use std
::fs
::{self, File}
;
14 crate type AllFacts
= PoloniusAllFacts
<RegionVid
, BorrowIndex
, LocationIndex
, Local
, MovePathIndex
>;
16 crate trait AllFactsExt
{
17 /// Returns `true` if there is a need to gather `AllFacts` given the
18 /// current `-Z` flags.
19 fn enabled(tcx
: TyCtxt
<'_
>) -> bool
;
23 dir
: impl AsRef
<Path
>,
24 location_table
: &LocationTable
,
25 ) -> Result
<(), Box
<dyn Error
>>;
28 impl AllFactsExt
for AllFacts
{
30 fn enabled(tcx
: TyCtxt
<'_
>) -> bool
{
31 tcx
.sess
.opts
.debugging_opts
.nll_facts
|| tcx
.sess
.opts
.debugging_opts
.polonius
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
. [
47 $wr
.write_facts_to_path(
49 &format
!("{}.facts", stringify
!($field
))
54 write_facts_to_path
! {
55 wr
.write_facts_to_path(self.[
78 impl Atom
for BorrowIndex
{
79 fn index(self) -> usize {
84 impl Atom
for LocationIndex
{
85 fn index(self) -> usize {
90 impl Atom
for MovePathIndex
{
91 fn index(self) -> usize {
96 struct FactWriter
<'w
> {
97 location_table
: &'w LocationTable
,
101 impl<'w
> FactWriter
<'w
> {
102 fn write_facts_to_path
<T
>(&self, rows
: &[T
], file_name
: &str) -> Result
<(), Box
<dyn Error
>>
106 let file
= &self.dir
.join(file_name
);
107 let mut file
= File
::create(file
)?
;
109 row
.write(&mut file
, self.location_table
)?
;
116 fn write(&self, out
: &mut File
, location_table
: &LocationTable
) -> Result
<(), Box
<dyn Error
>>;
119 impl FactRow
for RegionVid
{
120 fn write(&self, out
: &mut File
, location_table
: &LocationTable
) -> Result
<(), Box
<dyn Error
>> {
121 write_row(out
, location_table
, &[self])
125 impl<A
, B
> FactRow
for (A
, B
)
130 fn write(&self, out
: &mut File
, location_table
: &LocationTable
) -> Result
<(), Box
<dyn Error
>> {
131 write_row(out
, location_table
, &[&self.0, &self.1])
135 impl<A
, B
, C
> FactRow
for (A
, B
, C
)
141 fn write(&self, out
: &mut File
, location_table
: &LocationTable
) -> Result
<(), Box
<dyn Error
>> {
142 write_row(out
, location_table
, &[&self.0, &self.1, &self.2])
146 impl<A
, B
, C
, D
> FactRow
for (A
, B
, C
, D
)
153 fn write(&self, out
: &mut File
, location_table
: &LocationTable
) -> Result
<(), Box
<dyn Error
>> {
154 write_row(out
, location_table
, &[&self.0, &self.1, &self.2, &self.3])
160 location_table
: &LocationTable
,
161 columns
: &[&dyn FactCell
],
162 ) -> Result
<(), Box
<dyn Error
>> {
163 for (index
, c
) in columns
.iter().enumerate() {
164 let tail
= if index
== columns
.len() - 1 { "\n" }
else { "\t" }
;
165 write
!(out
, "{:?}{}", c
.to_string(location_table
), tail
)?
;
171 fn to_string(&self, location_table
: &LocationTable
) -> String
;
174 impl<A
: Debug
> FactCell
for A
{
175 default fn to_string(&self, _location_table
: &LocationTable
) -> String
{
176 format
!("{:?}", self)
180 impl FactCell
for LocationIndex
{
181 fn to_string(&self, location_table
: &LocationTable
) -> String
{
182 format
!("{:?}", location_table
.to_location(*self))