@@ -1760,12 +1760,11 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
1760
1760
self . borrow ( assignee_place, diag_expr_id, ty:: BorrowKind :: MutBorrow ) ;
1761
1761
}
1762
1762
}
1763
-
1764
- /// Truncate projections so that following rules are obeyed by the captured `place`:
1763
+ /// Truncate `place` so that an `unsafe` block isn't required to capture it.
1765
1764
/// - No projections are applied to raw pointers, since these require unsafe blocks. We capture
1766
1765
/// them completely.
1767
- /// - No Index projections are captured , since arrays are captured completely .
1768
- fn restrict_capture_precision < ' tcx > ( mut place : Place < ' tcx > ) -> Place < ' tcx > {
1766
+ /// - No projections are applied on top of Union ADTs , since these require unsafe blocks .
1767
+ fn restrict_precision_for_unsafe ( mut place : Place < ' tcx > ) -> Place < ' tcx > {
1769
1768
if place. projections . is_empty ( ) {
1770
1769
// Nothing to do here
1771
1770
return place;
@@ -1776,18 +1775,45 @@ fn restrict_capture_precision<'tcx>(mut place: Place<'tcx>) -> Place<'tcx> {
1776
1775
return place;
1777
1776
}
1778
1777
1779
- let mut truncated_length = usize:: MAX ;
1778
+ if place. base_ty . is_union ( ) {
1779
+ place. projections . truncate ( 0 ) ;
1780
+ return place;
1781
+ }
1780
1782
1781
1783
for ( i, proj) in place. projections . iter ( ) . enumerate ( ) {
1782
1784
if proj. ty . is_unsafe_ptr ( ) {
1783
- // Don't apply any projections on top of an unsafe ptr
1784
- truncated_length = truncated_length . min ( i + 1 ) ;
1785
+ // Don't apply any projections on top of an unsafe ptr.
1786
+ place . projections . truncate ( i + 1 ) ;
1785
1787
break ;
1786
1788
}
1789
+
1790
+ if proj. ty . is_union ( ) {
1791
+ // Don't capture preicse fields of a union.
1792
+ place. projections . truncate ( i + 1 ) ;
1793
+ break ;
1794
+ }
1795
+ }
1796
+
1797
+ place
1798
+ }
1799
+
1800
+ /// Truncate projections so that following rules are obeyed by the captured `place`:
1801
+ /// - No Index projections are captured, since arrays are captured completely.
1802
+ /// - No unsafe block is required to capture `place`
1803
+ /// Truncate projections so that following rules are obeyed by the captured `place`:
1804
+ fn restrict_capture_precision < ' tcx > ( mut place : Place < ' tcx > ) -> Place < ' tcx > {
1805
+ place = restrict_precision_for_unsafe ( place) ;
1806
+
1807
+ if place. projections . is_empty ( ) {
1808
+ // Nothing to do here
1809
+ return place;
1810
+ }
1811
+
1812
+ for ( i, proj) in place. projections . iter ( ) . enumerate ( ) {
1787
1813
match proj. kind {
1788
1814
ProjectionKind :: Index => {
1789
1815
// Arrays are completely captured, so we drop Index projections
1790
- truncated_length = truncated_length . min ( i) ;
1816
+ place . projections . truncate ( i) ;
1791
1817
break ;
1792
1818
}
1793
1819
ProjectionKind :: Deref => { }
@@ -1796,10 +1822,6 @@ fn restrict_capture_precision<'tcx>(mut place: Place<'tcx>) -> Place<'tcx> {
1796
1822
}
1797
1823
}
1798
1824
1799
- let length = place. projections . len ( ) . min ( truncated_length) ;
1800
-
1801
- place. projections . truncate ( length) ;
1802
-
1803
1825
place
1804
1826
}
1805
1827
0 commit comments