summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Wood <david@davidtw.co>2018-05-27 22:26:10 +0100
committerDavid Wood <david@davidtw.co>2018-05-27 22:26:10 +0100
commit24ee5069134e6ee6b88487f229cd05e383e1a314 (patch)
tree289b01451df629f03354896eb01ecc3ca444f1c9
parentEnsure that we don't skip the last statement. (diff)
downloadgrust-24ee5069134e6ee6b88487f229cd05e383e1a314.tar.gz
grust-24ee5069134e6ee6b88487f229cd05e383e1a314.tar.bz2
grust-24ee5069134e6ee6b88487f229cd05e383e1a314.tar.xz
Ensure that depth first search does not get stuck in cycles.
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs40
1 files changed, 28 insertions, 12 deletions
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index ed111c994f..317b62b22d 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -59,9 +59,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
59 borrows_out_of_scope_at_location: &mut FxHashMap<Location, Vec<BorrowIndex>>, 59 borrows_out_of_scope_at_location: &mut FxHashMap<Location, Vec<BorrowIndex>>,
60 borrow_index: BorrowIndex, 60 borrow_index: BorrowIndex,
61 borrow_region: RegionVid, 61 borrow_region: RegionVid,
62 location: Location 62 location: Location,
63 visited_locations: &mut Vec<Location>
63) { 64) {
64 // Start by dealing with the current location. 65 // Check if we have already visited this location and skip
66 // it if we have - avoids infinite loops.
67 if visited_locations.contains(&location) { return; }
68 visited_locations.push(location.clone());
69
70 // Next, add the borrow index to the current location's vector if the region does
71 // not contain the point at that location (or create a new vector if required).
65 if !regioncx.region_contains_point(borrow_region, location) { 72 if !regioncx.region_contains_point(borrow_region, location) {
66 borrows_out_of_scope_at_location 73 borrows_out_of_scope_at_location
67 .entry(location.clone()) 74 .entry(location.clone())
@@ -80,14 +87,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
80 TerminatorKind::FalseUnwind { real_target: target, .. } => { 87 TerminatorKind::FalseUnwind { real_target: target, .. } => {
81 precompute_borrows_out_of_scope( 88 precompute_borrows_out_of_scope(
82 mir, regioncx, borrows_out_of_scope_at_location, 89 mir, regioncx, borrows_out_of_scope_at_location,
83 borrow_index, borrow_region, target.start_location() 90 borrow_index, borrow_region, target.start_location(),
91 visited_locations
84 ); 92 );
85 }, 93 },
86 TerminatorKind::SwitchInt { ref targets, .. } => { 94 TerminatorKind::SwitchInt { ref targets, .. } => {
87 for block in targets { 95 for block in targets {
88 precompute_borrows_out_of_scope( 96 precompute_borrows_out_of_scope(
89 mir, regioncx, borrows_out_of_scope_at_location, 97 mir, regioncx, borrows_out_of_scope_at_location,
90 borrow_index, borrow_region, block.start_location() 98 borrow_index, borrow_region, block.start_location(),
99 visited_locations
91 ); 100 );
92 } 101 }
93 }, 102 },
@@ -95,13 +104,15 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
95 TerminatorKind::DropAndReplace { target, unwind, .. } => { 104 TerminatorKind::DropAndReplace { target, unwind, .. } => {
96 precompute_borrows_out_of_scope( 105 precompute_borrows_out_of_scope(
97 mir, regioncx, borrows_out_of_scope_at_location, 106 mir, regioncx, borrows_out_of_scope_at_location,
98 borrow_index, borrow_region, target.start_location() 107 borrow_index, borrow_region, target.start_location(),
108 visited_locations
99 ); 109 );
100 110
101 if let Some(unwind_block) = unwind { 111 if let Some(unwind_block) = unwind {
102 precompute_borrows_out_of_scope( 112 precompute_borrows_out_of_scope(
103 mir, regioncx, borrows_out_of_scope_at_location, 113 mir, regioncx, borrows_out_of_scope_at_location,
104 borrow_index, borrow_region, unwind_block.start_location() 114 borrow_index, borrow_region, unwind_block.start_location(),
115 visited_locations
105 ); 116 );
106 } 117 }
107 }, 118 },
@@ -109,14 +120,16 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
109 if let Some((_, block)) = destination { 120 if let Some((_, block)) = destination {
110 precompute_borrows_out_of_scope( 121 precompute_borrows_out_of_scope(
111 mir, regioncx, borrows_out_of_scope_at_location, 122 mir, regioncx, borrows_out_of_scope_at_location,
112 borrow_index, borrow_region, block.start_location() 123 borrow_index, borrow_region, block.start_location(),
124 visited_locations
113 ); 125 );
114 } 126 }
115 127
116 if let Some(block) = cleanup { 128 if let Some(block) = cleanup {
117 precompute_borrows_out_of_scope( 129 precompute_borrows_out_of_scope(
118 mir, regioncx, borrows_out_of_scope_at_location, 130 mir, regioncx, borrows_out_of_scope_at_location,
119 borrow_index, borrow_region, block.start_location() 131 borrow_index, borrow_region, block.start_location(),
132 visited_locations
120 ); 133 );
121 } 134 }
122 }, 135 },
@@ -124,13 +137,15 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
124 TerminatorKind::Yield { resume: target, drop: cleanup, .. } => { 137 TerminatorKind::Yield { resume: target, drop: cleanup, .. } => {
125 precompute_borrows_out_of_scope( 138 precompute_borrows_out_of_scope(
126 mir, regioncx, borrows_out_of_scope_at_location, 139 mir, regioncx, borrows_out_of_scope_at_location,
127 borrow_index, borrow_region, target.start_location() 140 borrow_index, borrow_region, target.start_location(),
141 visited_locations
128 ); 142 );
129 143
130 if let Some(block) = cleanup { 144 if let Some(block) = cleanup {
131 precompute_borrows_out_of_scope( 145 precompute_borrows_out_of_scope(
132 mir, regioncx, borrows_out_of_scope_at_location, 146 mir, regioncx, borrows_out_of_scope_at_location,
133 borrow_index, borrow_region, block.start_location() 147 borrow_index, borrow_region, block.start_location(),
148 visited_locations
134 ); 149 );
135 } 150 }
136 }, 151 },
@@ -142,7 +157,7 @@ fn precompute_borrows_out_of_scope<'a, 'tcx>(
142 } else { 157 } else {
143 precompute_borrows_out_of_scope(mir, regioncx, borrows_out_of_scope_at_location, 158 precompute_borrows_out_of_scope(mir, regioncx, borrows_out_of_scope_at_location,
144 borrow_index, borrow_region, 159 borrow_index, borrow_region,
145 location.successor_within_block()); 160 location.successor_within_block(), visited_locations);
146 } 161 }
147} 162}
148 163
@@ -167,7 +182,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
167 182
168 precompute_borrows_out_of_scope(mir, &nonlexical_regioncx, 183 precompute_borrows_out_of_scope(mir, &nonlexical_regioncx,
169 &mut borrows_out_of_scope_at_location, 184 &mut borrows_out_of_scope_at_location,
170 borrow_index, borrow_region, location); 185 borrow_index, borrow_region, location,
186 &mut Vec::new());
171 } 187 }
172 188
173 Borrows { 189 Borrows {