@@ -207,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
207207 assert_eq ! ( body_owner_def_id. to_def_id( ) , closure_def_id) ;
208208 let mut delegate = InferBorrowKind {
209209 fcx : self ,
210- closure_def_id,
210+ closure_def_id : local_def_id ,
211211 capture_information : Default :: default ( ) ,
212212 fake_reads : Default :: default ( ) ,
213213 } ;
@@ -1648,7 +1648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16481648fn restrict_repr_packed_field_ref_capture < ' tcx > (
16491649 tcx : TyCtxt < ' tcx > ,
16501650 param_env : ty:: ParamEnv < ' tcx > ,
1651- place : & Place < ' tcx > ,
1651+ mut place : Place < ' tcx > ,
16521652 mut curr_borrow_kind : ty:: UpvarCapture ,
16531653) -> ( Place < ' tcx > , ty:: UpvarCapture ) {
16541654 let pos = place. projections . iter ( ) . enumerate ( ) . position ( |( i, p) | {
@@ -1681,8 +1681,6 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
16811681 }
16821682 } ) ;
16831683
1684- let mut place = place. clone ( ) ;
1685-
16861684 if let Some ( pos) = pos {
16871685 truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_borrow_kind, pos) ;
16881686 }
@@ -1729,7 +1727,7 @@ struct InferBorrowKind<'a, 'tcx> {
17291727 fcx : & ' a FnCtxt < ' a , ' tcx > ,
17301728
17311729 // The def-id of the closure whose kind and upvar accesses are being inferred.
1732- closure_def_id : DefId ,
1730+ closure_def_id : LocalDefId ,
17331731
17341732 /// For each Place that is captured by the closure, we track the minimal kind of
17351733 /// access we need (ref, ref mut, move, etc) and the expression that resulted in such access.
@@ -1762,170 +1760,51 @@ struct InferBorrowKind<'a, 'tcx> {
17621760}
17631761
17641762impl < ' a , ' tcx > InferBorrowKind < ' a , ' tcx > {
1765- #[ instrument( skip( self ) , level = "debug" ) ]
1766- fn adjust_upvar_borrow_kind_for_consume (
1767- & mut self ,
1768- place_with_id : & PlaceWithHirId < ' tcx > ,
1769- diag_expr_id : hir:: HirId ,
1770- ) {
1771- let PlaceBase :: Upvar ( upvar_id) = place_with_id. place . base else {
1772- return ;
1773- } ;
1774-
1775- debug ! ( ?upvar_id) ;
1776-
1777- let capture_info = ty:: CaptureInfo {
1778- capture_kind_expr_id : Some ( diag_expr_id) ,
1779- path_expr_id : Some ( diag_expr_id) ,
1780- capture_kind : ty:: UpvarCapture :: ByValue ,
1781- } ;
1782-
1783- let curr_info = self . capture_information [ & place_with_id. place ] ;
1784- let updated_info = determine_capture_info ( curr_info, capture_info) ;
1785-
1786- self . capture_information [ & place_with_id. place ] = updated_info;
1787- }
1788-
1789- /// Indicates that `place_with_id` is being directly mutated (e.g., assigned
1790- /// to). If the place is based on a by-ref upvar, this implies that
1791- /// the upvar must be borrowed using an `&mut` borrow.
1792- #[ instrument( skip( self ) , level = "debug" ) ]
1793- fn adjust_upvar_borrow_kind_for_mut (
1794- & mut self ,
1795- place_with_id : & PlaceWithHirId < ' tcx > ,
1796- diag_expr_id : hir:: HirId ,
1797- ) {
1798- if let PlaceBase :: Upvar ( _) = place_with_id. place . base {
1799- // Raw pointers don't inherit mutability
1800- if place_with_id. place . deref_tys ( ) . any ( ty:: TyS :: is_unsafe_ptr) {
1801- return ;
1763+ fn adjust_capture_info ( & mut self , place : Place < ' tcx > , capture_info : ty:: CaptureInfo ) {
1764+ match self . capture_information . get_mut ( & place) {
1765+ Some ( curr_info) => {
1766+ * curr_info = determine_capture_info ( * curr_info, capture_info) ;
18021767 }
1803- self . adjust_upvar_deref ( place_with_id, diag_expr_id, ty:: MutBorrow ) ;
1804- }
1805- }
1806-
1807- #[ instrument( skip( self ) , level = "debug" ) ]
1808- fn adjust_upvar_borrow_kind_for_unique (
1809- & mut self ,
1810- place_with_id : & PlaceWithHirId < ' tcx > ,
1811- diag_expr_id : hir:: HirId ,
1812- ) {
1813- if let PlaceBase :: Upvar ( _) = place_with_id. place . base {
1814- if place_with_id. place . deref_tys ( ) . any ( ty:: TyS :: is_unsafe_ptr) {
1815- // Raw pointers don't inherit mutability.
1816- return ;
1768+ None => {
1769+ debug ! ( "Capturing new place {:?}, capture_info={:?}" , place, capture_info) ;
1770+ self . capture_information . insert ( place, capture_info) ;
18171771 }
1818- // for a borrowed pointer to be unique, its base must be unique
1819- self . adjust_upvar_deref ( place_with_id, diag_expr_id, ty:: UniqueImmBorrow ) ;
1820- }
1821- }
1822-
1823- fn adjust_upvar_deref (
1824- & mut self ,
1825- place_with_id : & PlaceWithHirId < ' tcx > ,
1826- diag_expr_id : hir:: HirId ,
1827- borrow_kind : ty:: BorrowKind ,
1828- ) {
1829- assert ! ( match borrow_kind {
1830- ty:: MutBorrow => true ,
1831- ty:: UniqueImmBorrow => true ,
1832-
1833- // imm borrows never require adjusting any kinds, so we don't wind up here
1834- ty:: ImmBorrow => false ,
1835- } ) ;
1836-
1837- // if this is an implicit deref of an
1838- // upvar, then we need to modify the
1839- // borrow_kind of the upvar to make sure it
1840- // is inferred to mutable if necessary
1841- self . adjust_upvar_borrow_kind ( place_with_id, diag_expr_id, borrow_kind) ;
1842- }
1843-
1844- /// We infer the borrow_kind with which to borrow upvars in a stack closure.
1845- /// The borrow_kind basically follows a lattice of `imm < unique-imm < mut`,
1846- /// moving from left to right as needed (but never right to left).
1847- /// Here the argument `mutbl` is the borrow_kind that is required by
1848- /// some particular use.
1849- #[ instrument( skip( self ) , level = "debug" ) ]
1850- fn adjust_upvar_borrow_kind (
1851- & mut self ,
1852- place_with_id : & PlaceWithHirId < ' tcx > ,
1853- diag_expr_id : hir:: HirId ,
1854- kind : ty:: BorrowKind ,
1855- ) {
1856- let curr_capture_info = self . capture_information [ & place_with_id. place ] ;
1857-
1858- debug ! ( ?curr_capture_info) ;
1859-
1860- if let ty:: UpvarCapture :: ByValue = curr_capture_info. capture_kind {
1861- // It's already captured by value, we don't need to do anything here
1862- return ;
1863- } else if let ty:: UpvarCapture :: ByRef ( _) = curr_capture_info. capture_kind {
1864- let capture_info = ty:: CaptureInfo {
1865- capture_kind_expr_id : Some ( diag_expr_id) ,
1866- path_expr_id : Some ( diag_expr_id) ,
1867- capture_kind : ty:: UpvarCapture :: ByRef ( kind) ,
1868- } ;
1869- let updated_info = determine_capture_info ( curr_capture_info, capture_info) ;
1870- self . capture_information [ & place_with_id. place ] = updated_info;
1871- } ;
1872- }
1873-
1874- #[ instrument( skip( self , diag_expr_id) , level = "debug" ) ]
1875- fn init_capture_info_for_place (
1876- & mut self ,
1877- place_with_id : & PlaceWithHirId < ' tcx > ,
1878- diag_expr_id : hir:: HirId ,
1879- ) {
1880- if let PlaceBase :: Upvar ( upvar_id) = place_with_id. place . base {
1881- assert_eq ! ( self . closure_def_id. expect_local( ) , upvar_id. closure_expr_id) ;
1882-
1883- // Initialize to ImmBorrow
1884- // We will escalate the CaptureKind based on any uses we see or in `process_collected_capture_information`.
1885- let capture_kind = ty:: UpvarCapture :: ByRef ( ty:: ImmBorrow ) ;
1886-
1887- let expr_id = Some ( diag_expr_id) ;
1888- let capture_info = ty:: CaptureInfo {
1889- capture_kind_expr_id : expr_id,
1890- path_expr_id : expr_id,
1891- capture_kind,
1892- } ;
1893-
1894- debug ! ( "Capturing new place {:?}, capture_info={:?}" , place_with_id, capture_info) ;
1895-
1896- self . capture_information . insert ( place_with_id. place . clone ( ) , capture_info) ;
1897- } else {
1898- debug ! ( "Not upvar" ) ;
18991772 }
19001773 }
19011774}
19021775
19031776impl < ' a , ' tcx > euv:: Delegate < ' tcx > for InferBorrowKind < ' a , ' tcx > {
19041777 fn fake_read ( & mut self , place : Place < ' tcx > , cause : FakeReadCause , diag_expr_id : hir:: HirId ) {
1905- if let PlaceBase :: Upvar ( _) = place. base {
1906- // We need to restrict Fake Read precision to avoid fake reading unsafe code,
1907- // such as deref of a raw pointer.
1908- let dummy_capture_kind = ty :: UpvarCapture :: ByRef ( ty :: BorrowKind :: ImmBorrow ) ;
1909-
1910- let ( place , _ ) = restrict_capture_precision ( place , dummy_capture_kind ) ;
1911-
1912- let ( place , _ ) = restrict_repr_packed_field_ref_capture (
1913- self . fcx . tcx ,
1914- self . fcx . param_env ,
1915- & place ,
1916- dummy_capture_kind ,
1917- ) ;
1918- self . fake_reads . push ( ( place , cause , diag_expr_id ) ) ;
1919- }
1778+ let PlaceBase :: Upvar ( _) = place. base else { return } ;
1779+
1780+ // We need to restrict Fake Read precision to avoid fake reading unsafe code,
1781+ // such as deref of a raw pointer.
1782+ let dummy_capture_kind = ty :: UpvarCapture :: ByRef ( ty :: BorrowKind :: ImmBorrow ) ;
1783+
1784+ let ( place , _ ) = restrict_capture_precision ( place , dummy_capture_kind ) ;
1785+
1786+ let ( place , _ ) = restrict_repr_packed_field_ref_capture (
1787+ self . fcx . tcx ,
1788+ self . fcx . param_env ,
1789+ place ,
1790+ dummy_capture_kind ,
1791+ ) ;
1792+ self . fake_reads . push ( ( place , cause , diag_expr_id ) ) ;
19201793 }
19211794
19221795 #[ instrument( skip( self ) , level = "debug" ) ]
19231796 fn consume ( & mut self , place_with_id : & PlaceWithHirId < ' tcx > , diag_expr_id : hir:: HirId ) {
1924- if !self . capture_information . contains_key ( & place_with_id. place ) {
1925- self . init_capture_info_for_place ( place_with_id, diag_expr_id) ;
1926- }
1797+ let PlaceBase :: Upvar ( upvar_id) = place_with_id. place . base else { return } ;
1798+ assert_eq ! ( self . closure_def_id, upvar_id. closure_expr_id) ;
19271799
1928- self . adjust_upvar_borrow_kind_for_consume ( place_with_id, diag_expr_id) ;
1800+ self . adjust_capture_info (
1801+ place_with_id. place . clone ( ) ,
1802+ ty:: CaptureInfo {
1803+ capture_kind_expr_id : Some ( diag_expr_id) ,
1804+ path_expr_id : Some ( diag_expr_id) ,
1805+ capture_kind : ty:: UpvarCapture :: ByValue ,
1806+ } ,
1807+ ) ;
19291808 }
19301809
19311810 #[ instrument( skip( self ) , level = "debug" ) ]
@@ -1935,39 +1814,35 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
19351814 diag_expr_id : hir:: HirId ,
19361815 bk : ty:: BorrowKind ,
19371816 ) {
1817+ let PlaceBase :: Upvar ( upvar_id) = place_with_id. place . base else { return } ;
1818+ assert_eq ! ( self . closure_def_id, upvar_id. closure_expr_id) ;
1819+
19381820 // The region here will get discarded/ignored
1939- let dummy_capture_kind = ty:: UpvarCapture :: ByRef ( bk) ;
1821+ let capture_kind = ty:: UpvarCapture :: ByRef ( bk) ;
19401822
19411823 // We only want repr packed restriction to be applied to reading references into a packed
19421824 // struct, and not when the data is being moved. Therefore we call this method here instead
19431825 // of in `restrict_capture_precision`.
1944- let ( place, updated_kind ) = restrict_repr_packed_field_ref_capture (
1826+ let ( place, mut capture_kind ) = restrict_repr_packed_field_ref_capture (
19451827 self . fcx . tcx ,
19461828 self . fcx . param_env ,
1947- & place_with_id. place ,
1948- dummy_capture_kind ,
1829+ place_with_id. place . clone ( ) ,
1830+ capture_kind ,
19491831 ) ;
19501832
1951- let place_with_id = PlaceWithHirId { place, ..* place_with_id } ;
1952-
1953- if !self . capture_information . contains_key ( & place_with_id. place ) {
1954- self . init_capture_info_for_place ( & place_with_id, diag_expr_id) ;
1833+ // Raw pointers don't inherit mutability
1834+ if place_with_id. place . deref_tys ( ) . any ( ty:: TyS :: is_unsafe_ptr) {
1835+ capture_kind = ty:: UpvarCapture :: ByRef ( ty:: BorrowKind :: ImmBorrow ) ;
19551836 }
19561837
1957- match updated_kind {
1958- ty:: UpvarCapture :: ByRef ( kind) => match kind {
1959- ty:: ImmBorrow => { }
1960- ty:: UniqueImmBorrow => {
1961- self . adjust_upvar_borrow_kind_for_unique ( & place_with_id, diag_expr_id) ;
1962- }
1963- ty:: MutBorrow => {
1964- self . adjust_upvar_borrow_kind_for_mut ( & place_with_id, diag_expr_id) ;
1965- }
1838+ self . adjust_capture_info (
1839+ place,
1840+ ty:: CaptureInfo {
1841+ capture_kind_expr_id : Some ( diag_expr_id) ,
1842+ path_expr_id : Some ( diag_expr_id) ,
1843+ capture_kind,
19661844 } ,
1967-
1968- // Just truncating the place will never cause capture kind to be updated to ByValue
1969- ty:: UpvarCapture :: ByValue => unreachable ! ( ) ,
1970- }
1845+ ) ;
19711846 }
19721847
19731848 #[ instrument( skip( self ) , level = "debug" ) ]
0 commit comments