From b1bf9ef5aef81eec4a1b0e00fc179e7a0e1766b6 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 19 Sep 2011 15:30:58 -0700 Subject: [PATCH] Break fold's circular reference during unwinding This converts the AST fold into a resource that breaks it's own circular reference (just a temporary workaround until GC), so that failure during fold will unwind correctly. Issue #936 --- src/comp/front/config.rs | 2 -- src/comp/front/test.rs | 2 -- src/comp/syntax/ext/expand.rs | 1 - src/comp/syntax/ext/simplext.rs | 2 -- src/comp/syntax/fold.rs | 9 +++++++-- src/fuzzer/fuzzer.rs | 2 -- 6 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/comp/front/config.rs b/src/comp/front/config.rs index a00a71ddedb3..cdd95bd6313a 100644 --- a/src/comp/front/config.rs +++ b/src/comp/front/config.rs @@ -17,8 +17,6 @@ fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate { let fold = fold::make_fold(precursor); let res = @fold.fold_crate(*crate); - // FIXME: This is necessary to break a circular reference - fold::dummy_out(fold); ret res; } diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs index 44ae6838a81b..9aed642a2d5d 100644 --- a/src/comp/front/test.rs +++ b/src/comp/front/test.rs @@ -47,8 +47,6 @@ fn modify_for_testing(crate: @ast::crate) -> @ast::crate { let fold = fold::make_fold(precursor); let res = @fold.fold_crate(*crate); - // FIXME: This is necessary to break a circular reference - fold::dummy_out(fold); ret res; } diff --git a/src/comp/syntax/ext/expand.rs b/src/comp/syntax/ext/expand.rs index 5fd2b1692dae..53b068243206 100644 --- a/src/comp/syntax/ext/expand.rs +++ b/src/comp/syntax/ext/expand.rs @@ -56,7 +56,6 @@ fn expand_crate(sess: session::session, c: @crate) -> @crate { with *afp}; let f = make_fold(f_pre); let res = @f.fold_crate(*c); - dummy_out(f); //temporary: kill circular reference ret res; } diff --git a/src/comp/syntax/ext/simplext.rs b/src/comp/syntax/ext/simplext.rs index f81e101c17b6..c6b6056bbc46 100644 --- a/src/comp/syntax/ext/simplext.rs +++ b/src/comp/syntax/ext/simplext.rs @@ -206,7 +206,6 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr { new_span: bind new_span(cx, _) with *afp}; let f = make_fold(f_pre); let result = f.fold_expr(body); - dummy_out(f); //temporary: kill circular reference ret result; } @@ -258,7 +257,6 @@ iter free_vars(b: bindings, e: @expr) -> ident { with *default_ast_fold()}; let f = make_fold(f_pre); f.fold_expr(e); // ignore result - dummy_out(f); for each id: ident in idents.keys() { put id; } } diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs index d3702dacfc65..23293adbd80d 100644 --- a/src/comp/syntax/fold.rs +++ b/src/comp/syntax/fold.rs @@ -563,8 +563,13 @@ fn dummy_out(a: ast_fold) { new_span: noop_span}; } +// FIXME: Fold has a circular reference that has to be broken. With GC this +// can go away +resource foldres(f: ast_fold) { + dummy_out(f); +} -fn make_fold(afp: ast_fold_precursor) -> ast_fold { +fn make_fold(afp: ast_fold_precursor) -> @foldres { let result: ast_fold = @mutable {fold_crate: nf_crate_dummy, fold_crate_directive: nf_crate_directive_dummy, @@ -699,7 +704,7 @@ fn make_fold(afp: ast_fold_precursor) -> ast_fold { map_exprs: afp.map_exprs, new_id: afp.new_id, new_span: afp.new_span}; - ret result; + ret @foldres(result); } diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 679072abd92d..95a78125aba0 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -149,7 +149,6 @@ fn replace_expr_in_crate(crate: ast::crate, i: uint, newexpr: ast::expr) -> with *fold::default_ast_fold()}; let af = fold::make_fold(afp); let crate2: @ast::crate = @af.fold_crate(crate); - fold::dummy_out(af); // work around a leak (https://github.com/graydon/rust/issues/651) *crate2 } @@ -170,7 +169,6 @@ fn replace_ty_in_crate(crate: ast::crate, i: uint, newty: ast::ty) -> with *fold::default_ast_fold()}; let af = fold::make_fold(afp); let crate2: @ast::crate = @af.fold_crate(crate); - fold::dummy_out(af); // work around a leak (https://github.com/graydon/rust/issues/651) *crate2 }