Skip to content

Commit 2c02fd9

Browse files
committed
fix exponential time blowup on compile-fail/huge-struct.rs by keeping
the breadcrumbs until end of traversal.
1 parent a322029 commit 2c02fd9

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/librustc/middle/typeck/check/dropck.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ pub fn check_safety_of_destructor_if_necessary<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>
1919
span,
2020
scope,
2121
false,
22-
0)
22+
0);
23+
rcx.reset_traversal();
2324
}
2425

2526
fn constrain_region_for_destructor_safety(rcx: &mut Rcx,

src/librustc/middle/typeck/check/regionck.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
278278
maybe_links: RefCell::new(FnvHashMap::new()) }
279279
}
280280

281+
pub fn reset_traversal(&mut self) {
282+
self.breadcrumbs.clear();
283+
self.breadcrumbs.shrink_to_fit();
284+
}
285+
281286
pub fn traverse_type_if_unseen(&mut self,
282287
typ: ty::Ty<'tcx>,
283288
keep_going: |&mut Rcx<'a, 'tcx>| -> bool) -> bool {
@@ -287,8 +292,18 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
287292
if !rcx.breadcrumbs.contains(&typ) {
288293
rcx.breadcrumbs.push(typ);
289294
let keep_going = keep_going(rcx);
290-
let top_t = rcx.breadcrumbs.pop();
291-
assert_eq!(top_t, Some(typ));
295+
296+
// FIXME: popping the breadcrumbs here is a reasonable
297+
// idea, but then you fall victim to exponential time on
298+
// examples like src/tests/compile-fail/huge-struct.rs.
299+
// So pnkfelix is trying to experimentally not remove
300+
// anything from the vector during any particular
301+
// traversal, and instead clear it after the whole
302+
// traversal is done.
303+
//
304+
// let top_t = rcx.breadcrumbs.pop();
305+
// assert_eq!(top_t, Some(typ));
306+
292307
keep_going
293308
} else {
294309
false

0 commit comments

Comments
 (0)