@@ -207,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
207
207
assert_eq ! ( body_owner_def_id. to_def_id( ) , closure_def_id) ;
208
208
let mut delegate = InferBorrowKind {
209
209
fcx : self ,
210
- closure_def_id,
210
+ closure_def_id : local_def_id ,
211
211
capture_information : Default :: default ( ) ,
212
212
fake_reads : Default :: default ( ) ,
213
213
} ;
@@ -1648,7 +1648,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1648
1648
fn restrict_repr_packed_field_ref_capture < ' tcx > (
1649
1649
tcx : TyCtxt < ' tcx > ,
1650
1650
param_env : ty:: ParamEnv < ' tcx > ,
1651
- place : & Place < ' tcx > ,
1651
+ mut place : Place < ' tcx > ,
1652
1652
mut curr_borrow_kind : ty:: UpvarCapture ,
1653
1653
) -> ( Place < ' tcx > , ty:: UpvarCapture ) {
1654
1654
let pos = place. projections . iter ( ) . enumerate ( ) . position ( |( i, p) | {
@@ -1681,8 +1681,6 @@ fn restrict_repr_packed_field_ref_capture<'tcx>(
1681
1681
}
1682
1682
} ) ;
1683
1683
1684
- let mut place = place. clone ( ) ;
1685
-
1686
1684
if let Some ( pos) = pos {
1687
1685
truncate_place_to_len_and_update_capture_kind ( & mut place, & mut curr_borrow_kind, pos) ;
1688
1686
}
@@ -1729,7 +1727,7 @@ struct InferBorrowKind<'a, 'tcx> {
1729
1727
fcx : & ' a FnCtxt < ' a , ' tcx > ,
1730
1728
1731
1729
// The def-id of the closure whose kind and upvar accesses are being inferred.
1732
- closure_def_id : DefId ,
1730
+ closure_def_id : LocalDefId ,
1733
1731
1734
1732
/// For each Place that is captured by the closure, we track the minimal kind of
1735
1733
/// access we need (ref, ref mut, move, etc) and the expression that resulted in such access.
@@ -1762,170 +1760,51 @@ struct InferBorrowKind<'a, 'tcx> {
1762
1760
}
1763
1761
1764
1762
impl < ' 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) ;
1802
1767
}
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) ;
1817
1771
}
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" ) ;
1899
1772
}
1900
1773
}
1901
1774
}
1902
1775
1903
1776
impl < ' a , ' tcx > euv:: Delegate < ' tcx > for InferBorrowKind < ' a , ' tcx > {
1904
1777
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 ) ) ;
1920
1793
}
1921
1794
1922
1795
#[ instrument( skip( self ) , level = "debug" ) ]
1923
1796
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) ;
1927
1799
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
+ ) ;
1929
1808
}
1930
1809
1931
1810
#[ instrument( skip( self ) , level = "debug" ) ]
@@ -1935,39 +1814,35 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
1935
1814
diag_expr_id : hir:: HirId ,
1936
1815
bk : ty:: BorrowKind ,
1937
1816
) {
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
+
1938
1820
// The region here will get discarded/ignored
1939
- let dummy_capture_kind = ty:: UpvarCapture :: ByRef ( bk) ;
1821
+ let capture_kind = ty:: UpvarCapture :: ByRef ( bk) ;
1940
1822
1941
1823
// We only want repr packed restriction to be applied to reading references into a packed
1942
1824
// struct, and not when the data is being moved. Therefore we call this method here instead
1943
1825
// 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 (
1945
1827
self . fcx . tcx ,
1946
1828
self . fcx . param_env ,
1947
- & place_with_id. place ,
1948
- dummy_capture_kind ,
1829
+ place_with_id. place . clone ( ) ,
1830
+ capture_kind ,
1949
1831
) ;
1950
1832
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 ) ;
1955
1836
}
1956
1837
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,
1966
1844
} ,
1967
-
1968
- // Just truncating the place will never cause capture kind to be updated to ByValue
1969
- ty:: UpvarCapture :: ByValue => unreachable ! ( ) ,
1970
- }
1845
+ ) ;
1971
1846
}
1972
1847
1973
1848
#[ instrument( skip( self ) , level = "debug" ) ]
0 commit comments