Skip to content

Commit a246930

Browse files
committed
---
yaml --- r: 11694 b: refs/heads/master c: 2bfed90 h: refs/heads/master v: v3
1 parent c95b4e2 commit a246930

File tree

6 files changed

+133
-6
lines changed

6 files changed

+133
-6
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: c9375fed8d55197a528edb3c3182aaf3b71abe76
2+
refs/heads/master: 2bfed908e39f162532be56d9680295bb383ddcf2
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
55
refs/heads/try: 2898dcc5d97da9427ac367542382b6239d9c0bbf

trunk/src/rustc/metadata/astencode.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ fn encode_inlined_item(ecx: @e::encode_ctxt,
6363
let id_range = compute_id_range(ii);
6464
ebml_w.wr_tag(c::tag_ast as uint) {||
6565
encode_id_range(ebml_w, id_range);
66-
encode_ast(ebml_w, ii);
66+
encode_ast(ebml_w, simplify_ast(ii));
6767
encode_side_tables_for_ii(ecx, ebml_w, ii);
6868
}
6969

@@ -326,6 +326,44 @@ fn encode_ast(ebml_w: ebml::writer, item: ast::inlined_item) {
326326
}
327327
}
328328

329+
// Produces a simplified copy of the AST which does not include things
330+
// that we do not need to or do not want to export. For example, we
331+
// do not include any nested items: if these nested items are to be
332+
// inlined, their AST will be exported separately (this only makes
333+
// sense because, in Rust, nested items are independent except for
334+
// their visibility).
335+
//
336+
// As it happens, trans relies on the fact that we do not export
337+
// nested items, as otherwise it would get confused when translating
338+
// inlined items.
339+
fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
340+
fn drop_nested_items(blk: ast::blk_, fld: fold::ast_fold) -> ast::blk_ {
341+
let stmts_sans_items = vec::filter(blk.stmts) {|stmt|
342+
alt stmt.node {
343+
ast::stmt_expr(_, _) | ast::stmt_semi(_, _) |
344+
ast::stmt_decl(@{node: ast::decl_local(_), span: _}, _) { true }
345+
ast::stmt_decl(@{node: ast::decl_item(_), span: _}, _) { false }
346+
}
347+
};
348+
let blk_sans_items = { stmts: stmts_sans_items with blk };
349+
fold::noop_fold_block(blk_sans_items, fld)
350+
}
351+
352+
let fld = fold::make_fold({
353+
fold_block: fold::wrap(drop_nested_items)
354+
with *fold::default_ast_fold()
355+
});
356+
357+
alt ii {
358+
ast::ii_item(i) {
359+
ast::ii_item(fld.fold_item(i))
360+
}
361+
ast::ii_method(d, m) {
362+
ast::ii_method(d, fld.fold_method(m))
363+
}
364+
}
365+
}
366+
329367
fn decode_ast(par_doc: ebml::doc) -> ast::inlined_item {
330368
let chi_doc = par_doc[c::tag_tree];
331369
let d = serialization::mk_ebml_deserializer(chi_doc);
@@ -923,3 +961,26 @@ fn test_more() {
923961
}
924962
});
925963
}
964+
965+
#[test]
966+
fn test_simplification() {
967+
let ext_cx = mk_ctxt();
968+
let item_in = ast::ii_item(#ast(item) {
969+
fn new_int_alist<B: copy>() -> alist<int, B> {
970+
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
971+
ret {eq_fn: eq_int, mut data: []};
972+
}
973+
});
974+
let item_out = simplify_ast(item_in);
975+
let item_exp = ast::ii_item(#ast(item) {
976+
fn new_int_alist<B: copy>() -> alist<int, B> {
977+
ret {eq_fn: eq_int, mut data: []};
978+
}
979+
});
980+
alt (item_out, item_exp) {
981+
(ast::ii_item(item_out), ast::ii_item(item_exp)) {
982+
assert pprust::item_to_str(item_out) == pprust::item_to_str(item_exp);
983+
}
984+
_ { fail; }
985+
}
986+
}

trunk/src/rustc/middle/trans/base.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,18 +2146,31 @@ fn monomorphic_fn(ccx: crate_ctxt, fn_id: ast::def_id, substs: [ty::t],
21462146
fn maybe_instantiate_inline(ccx: crate_ctxt, fn_id: ast::def_id)
21472147
-> ast::def_id {
21482148
alt ccx.external.find(fn_id) {
2149-
some(some(node_id)) { local_def(node_id) } // Already inline
2149+
some(some(node_id)) {
2150+
// Already inline
2151+
#debug["maybe_instantiate_inline(%s): already inline as node id %d",
2152+
ty::item_path_str(ccx.tcx, fn_id), node_id];
2153+
local_def(node_id)
2154+
}
21502155
some(none) { fn_id } // Not inlinable
21512156
none { // Not seen yet
21522157
alt csearch::maybe_get_item_ast(ccx.tcx, ccx.maps, fn_id) {
21532158
none { ccx.external.insert(fn_id, none); fn_id }
21542159
some(ast::ii_item(item)) {
2160+
#debug["maybe_instantiate_inline(%s): inlining to local id %d",
2161+
ty::item_path_str(ccx.tcx, fn_id),
2162+
item.id];
21552163
ccx.external.insert(fn_id, some(item.id));
21562164
collect_item(ccx, @mutable none, item);
21572165
trans_item(ccx, *item);
21582166
local_def(item.id)
21592167
}
21602168
some(ast::ii_method(impl_did, mth)) {
2169+
#debug["maybe_instantiate_inline(%s): \
2170+
inlining method of %s to %d",
2171+
ty::item_path_str(ccx.tcx, fn_id),
2172+
ty::item_path_str(ccx.tcx, impl_did),
2173+
mth.id];
21612174
ccx.external.insert(fn_id, some(mth.id));
21622175
compute_ii_method_info(ccx, impl_did, mth) {|ty, bounds, path|
21632176
let mth_ty = ty::node_id_to_type(ccx.tcx, mth.id);
@@ -3586,7 +3599,7 @@ fn zero_alloca(cx: block, llptr: ValueRef, t: ty::t)
35863599
}
35873600

35883601
fn trans_stmt(cx: block, s: ast::stmt) -> block {
3589-
#debug["trans_expr(%s)", stmt_to_str(s)];
3602+
#debug["trans_stmt(%s)", stmt_to_str(s)];
35903603

35913604
if (!cx.sess().opts.no_asm_comments) {
35923605
add_span_comment(cx, s.span, stmt_to_str(s));
@@ -4330,8 +4343,10 @@ fn trans_item(ccx: crate_ctxt, item: ast::item) {
43304343
let llfndecl = alt ccx.item_ids.find(item.id) {
43314344
some(llfndecl) { llfndecl }
43324345
_ {
4333-
ccx.sess.span_bug(item.span,
4334-
"unbound function item in trans_item");
4346+
ccx.sess.span_bug(
4347+
item.span,
4348+
#fmt["unbound function item %s in trans_item",
4349+
ast_map::path_to_str(*path)]);
43354350
}
43364351
};
43374352
if decl.purity != ast::crust_fn {

trunk/src/rustc/syntax/fold.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export noop_fold_expr;
1111
export noop_fold_pat;
1212
export noop_fold_mod;
1313
export noop_fold_ty;
14+
export noop_fold_block;
1415
export wrap;
1516

1617
type ast_fold = @mutable a_f;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
type alist<A,B> = { eq_fn: fn@(A,A) -> bool, mut data: [(A,B)] };
2+
3+
fn alist_add<A: copy, B: copy>(lst: alist<A,B>, k: A, v: B) {
4+
lst.data += [(k, v)];
5+
}
6+
7+
fn alist_get<A: copy, B: copy>(lst: alist<A,B>, k: A) -> B {
8+
let eq_fn = lst.eq_fn;
9+
for pair in lst.data {
10+
let (ki, vi) = pair; // copy req'd for alias analysis
11+
if eq_fn(k, ki) { ret vi; }
12+
}
13+
fail;
14+
}
15+
16+
#[inline]
17+
fn new_int_alist<B: copy>() -> alist<int, B> {
18+
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
19+
ret {eq_fn: eq_int,
20+
mut data: []};
21+
}
22+
23+
#[inline]
24+
fn new_int_alist_2<B: copy>() -> alist<int, B> {
25+
#[inline]
26+
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
27+
ret {eq_fn: eq_int,
28+
mut data: []};
29+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// xfail-fast - check-fast doesn't understand aux-build
2+
// aux-build:cci_nested_lib.rs
3+
4+
use std;
5+
use cci_nested_lib;
6+
import std::io;
7+
import cci_nested_lib::*;
8+
9+
fn main() {
10+
let lst = new_int_alist();
11+
alist_add(lst, 22, "hi");
12+
alist_add(lst, 44, "ho");
13+
assert alist_get(lst, 22) == "hi";
14+
assert alist_get(lst, 44) == "ho";
15+
16+
let lst = new_int_alist_2();
17+
alist_add(lst, 22, "hi");
18+
alist_add(lst, 44, "ho");
19+
assert alist_get(lst, 22) == "hi";
20+
assert alist_get(lst, 44) == "ho";
21+
}

0 commit comments

Comments
 (0)