11//! This file provides API for compiler consumers. 
22
3+ use  rustc_data_structures:: fx:: FxHashMap ; 
34use  rustc_hir:: def_id:: LocalDefId ; 
45use  rustc_index:: IndexVec ; 
6+ use  rustc_middle:: bug; 
57use  rustc_middle:: mir:: { Body ,  Promoted } ; 
68use  rustc_middle:: ty:: TyCtxt ; 
79
@@ -17,7 +19,39 @@ pub use super::polonius::legacy::{
1719pub  use  super :: region_infer:: RegionInferenceContext ; 
1820use  crate :: { BorrowCheckRootCtxt ,  do_mir_borrowck} ; 
1921
20- /// Options determining the output behavior of [`get_body_with_borrowck_facts`]. 
22+ /// Struct used during mir borrowck to collect bodies with facts for a typeck root and all 
23+ /// its nested bodies. 
24+ pub ( crate )  struct  BorrowckConsumer < ' tcx >  { 
25+     options :  ConsumerOptions , 
26+     bodies :  FxHashMap < LocalDefId ,  BodyWithBorrowckFacts < ' tcx > > , 
27+ } 
28+ 
29+ impl < ' tcx >  BorrowckConsumer < ' tcx >  { 
30+     pub ( crate )  fn  new ( options :  ConsumerOptions )  -> Self  { 
31+         Self  {  options,  bodies :  Default :: default ( )  } 
32+     } 
33+ 
34+     pub ( crate )  fn  insert_body ( & mut  self ,  def_id :  LocalDefId ,  body :  BodyWithBorrowckFacts < ' tcx > )  { 
35+         if  self . bodies . insert ( def_id,  body) . is_some ( )  { 
36+             bug ! ( "unexpected previous body for {def_id:?}" ) ; 
37+         } 
38+     } 
39+ 
40+     /// Should the Polonius input facts be computed? 
41+ pub ( crate )  fn  polonius_input ( & self )  -> bool  { 
42+         matches ! ( 
43+             self . options, 
44+             ConsumerOptions :: PoloniusInputFacts  | ConsumerOptions :: PoloniusOutputFacts 
45+         ) 
46+     } 
47+ 
48+     /// Should we run Polonius and collect the output facts? 
49+ pub ( crate )  fn  polonius_output ( & self )  -> bool  { 
50+         matches ! ( self . options,  ConsumerOptions :: PoloniusOutputFacts ) 
51+     } 
52+ } 
53+ 
54+ /// Options determining the output behavior of [`get_bodies_with_borrowck_facts`]. 
2155/// 
2256/// If executing under `-Z polonius` the choice here has no effect, and everything as if 
2357/// [`PoloniusOutputFacts`](ConsumerOptions::PoloniusOutputFacts) had been selected 
@@ -43,17 +77,6 @@ pub enum ConsumerOptions {
4377PoloniusOutputFacts , 
4478} 
4579
46- impl  ConsumerOptions  { 
47-     /// Should the Polonius input facts be computed? 
48- pub ( crate )  fn  polonius_input ( & self )  -> bool  { 
49-         matches ! ( self ,  Self :: PoloniusInputFacts  | Self :: PoloniusOutputFacts ) 
50-     } 
51-     /// Should we run Polonius and collect the output facts? 
52- pub ( crate )  fn  polonius_output ( & self )  -> bool  { 
53-         matches ! ( self ,  Self :: PoloniusOutputFacts ) 
54-     } 
55- } 
56- 
5780/// A `Body` with information computed by the borrow checker. This struct is 
5881/// intended to be consumed by compiler consumers. 
5982/// 
@@ -82,25 +105,35 @@ pub struct BodyWithBorrowckFacts<'tcx> {
82105pub  output_facts :  Option < Box < PoloniusOutput > > , 
83106} 
84107
85- /// This function computes borrowck facts for the given body. The [`ConsumerOptions`] 
86- /// determine which facts are returned. This function makes a copy of the body because 
87- /// it needs to regenerate the region identifiers. It should never be invoked during a 
88- /// typical compilation session due to the unnecessary overhead of returning 
89- /// [`BodyWithBorrowckFacts`]. 
108+ /// This function computes borrowck facts for the given def id and all its nested bodies. 
109+ /// It must be called with a typeck root which will then borrowck all nested bodies as well. 
110+ /// The [`ConsumerOptions`] determine which facts are returned. This function makes a copy 
111+ /// of the bodies because it needs to regenerate the region identifiers. It should never be 
112+ /// invoked during a typical compilation session due to the unnecessary overhead of 
113+ /// returning [`BodyWithBorrowckFacts`]. 
90114/// 
91115/// Note: 
92- /// *   This function will panic if the required body was  already stolen. This 
116+ /// *   This function will panic if the required bodies were  already stolen. This 
93117///     can, for example, happen when requesting a body of a `const` function 
94118///     because they are evaluated during typechecking. The panic can be avoided 
95119///     by overriding the `mir_borrowck` query. You can find a complete example 
96- ///     that shows how to do this at `tests/run-make /obtain-borrowck/ `. 
120+ ///     that shows how to do this at `tests/ui-fulldeps /obtain-borrowck.rs `. 
97121/// 
98122/// *   Polonius is highly unstable, so expect regular changes in its signature or other details. 
99- pub  fn  get_body_with_borrowck_facts ( 
123+ pub  fn  get_bodies_with_borrowck_facts ( 
100124    tcx :  TyCtxt < ' _ > , 
101-     def_id :  LocalDefId , 
125+     root_def_id :  LocalDefId , 
102126    options :  ConsumerOptions , 
103- )  -> BodyWithBorrowckFacts < ' _ >  { 
104-     let  mut  root_cx = BorrowCheckRootCtxt :: new ( tcx,  def_id) ; 
105-     * do_mir_borrowck ( & mut  root_cx,  def_id,  Some ( options) ) . 1 . unwrap ( ) 
127+ )  -> FxHashMap < LocalDefId ,  BodyWithBorrowckFacts < ' _ > >  { 
128+     let  mut  root_cx =
129+         BorrowCheckRootCtxt :: new ( tcx,  root_def_id,  Some ( BorrowckConsumer :: new ( options) ) ) ; 
130+ 
131+     // See comment in `rustc_borrowck::mir_borrowck` 
132+     let  nested_bodies = tcx. nested_bodies_within ( root_def_id) ; 
133+     for  def_id in  nested_bodies { 
134+         root_cx. get_or_insert_nested ( def_id) ; 
135+     } 
136+ 
137+     do_mir_borrowck ( & mut  root_cx,  root_def_id) ; 
138+     root_cx. consumer . unwrap ( ) . bodies 
106139} 
0 commit comments