Skip to content

Commit 58e2624

Browse files
committed
syntax: Add a hack to support the int-template pattern
1 parent de0268b commit 58e2624

File tree

5 files changed

+74
-9
lines changed

5 files changed

+74
-9
lines changed

src/libsyntax/parse/eval.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use codemap::span;
55

66
export eval_crate_directives_to_mod;
77
export eval_src_mod;
8+
export eval_src_mod_from_path;
89

910
type ctx =
1011
@{sess: parse::parse_sess,
@@ -84,15 +85,23 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
8485
}
8586
}
8687

87-
fn eval_src_mod(cx: ctx, prefix: &Path, id: ast::ident,
88+
fn eval_src_mod(cx: ctx, prefix: &Path,
8889
outer_attrs: ~[ast::attribute],
89-
sp: span) -> (ast::item_, ~[ast::attribute]) {
90+
id: ast::ident, sp: span
91+
) -> (ast::item_, ~[ast::attribute]) {
9092
let file_path = Path(cdir_path_opt(
9193
cx.sess.interner.get(id) + ~".rs", outer_attrs));
92-
let full_path = if file_path.is_absolute {
93-
copy file_path
94+
eval_src_mod_from_path(cx, prefix, &file_path, outer_attrs, sp)
95+
}
96+
97+
fn eval_src_mod_from_path(cx: ctx, prefix: &Path, path: &Path,
98+
outer_attrs: ~[ast::attribute],
99+
sp: span
100+
) -> (ast::item_, ~[ast::attribute]) {
101+
let full_path = if path.is_absolute {
102+
copy *path
94103
} else {
95-
prefix.push_many(file_path.components)
104+
prefix.push_many(path.components)
96105
};
97106
let p0 =
98107
new_sub_parser_from_file(cx.sess, cx.cfg,
@@ -121,7 +130,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
121130
items: &mut ~[@ast::item]) {
122131
match cdir.node {
123132
ast::cdir_src_mod(vis, id, attrs) => {
124-
let (m, mod_attrs) = eval_src_mod(cx, prefix, id, attrs, cdir.span);
133+
let (m, mod_attrs) = eval_src_mod(cx, prefix, attrs, id, cdir.span);
125134
let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
126135
/* FIXME (#2543) */ copy id,
127136
m, vis, mod_attrs);

src/libsyntax/parse/parser.rs

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2963,7 +2963,7 @@ impl Parser {
29632963
fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info {
29642964
let id_span = self.span;
29652965
let id = self.parse_ident();
2966-
if self.token == token::SEMI {
2966+
let info_ = if self.token == token::SEMI {
29672967
self.bump();
29682968
// This mod is in an external file. Let's go get it!
29692969
let eval_ctx = @{
@@ -2972,15 +2972,50 @@ impl Parser {
29722972
};
29732973
let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
29742974
let prefix = prefix.dir_path();
2975-
let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix, id,
2976-
outer_attrs, id_span);
2975+
let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix,
2976+
outer_attrs,
2977+
id, id_span);
29772978
(id, m, Some(move attrs))
29782979
} else {
29792980
self.expect(token::LBRACE);
29802981
let inner_attrs = self.parse_inner_attrs_and_next();
29812982
let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
29822983
self.expect(token::RBRACE);
29832984
(id, item_mod(m), Some(inner_attrs.inner))
2985+
};
2986+
2987+
// XXX: Transitionary hack to do the template work inside core
2988+
// (int-template, iter-trait). If there's a 'merge' attribute
2989+
// on the mod, then we'll go and suck in another file and merge
2990+
// its contents
2991+
match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") {
2992+
Some(path) => {
2993+
let eval_ctx = @{
2994+
sess: self.sess,
2995+
cfg: self.cfg
2996+
};
2997+
let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
2998+
let prefix = prefix.dir_path();
2999+
let path = Path(path);
3000+
let (new_mod_item, new_attrs) = eval::eval_src_mod_from_path(
3001+
eval_ctx, &prefix, &path, ~[], id_span);
3002+
3003+
let (main_id, main_mod_item, main_attrs) = info_;
3004+
let main_attrs = main_attrs.get();
3005+
3006+
let (main_mod, new_mod) = match (main_mod_item, new_mod_item) {
3007+
(item_mod(m), item_mod(n)) => (m, n),
3008+
_ => self.bug(~"parsed mod item should be mod")
3009+
};
3010+
let merged_mod = {
3011+
view_items: main_mod.view_items + new_mod.view_items,
3012+
items: main_mod.items + new_mod.items
3013+
};
3014+
3015+
let merged_attrs = main_attrs + new_attrs;
3016+
(main_id, item_mod(merged_mod), Some(merged_attrs))
3017+
}
3018+
None => info_
29843019
}
29853020
}
29863021
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// xfail-test not a test. used by mod-merge-hack.rs
2+
3+
mod inst {
4+
pub type T = i32;
5+
pub const bits: uint = 32;
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// xfail-test not a test. used by mod-merge-hack.rs
2+
3+
use T = inst::T;
4+
5+
pub const bits: uint = inst::bits;
6+
pub pure fn min(x: T, y: T) -> T { if x < y { x } else { y } }

src/test/run-pass/mod-merge-hack.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// xfail-pretty
2+
#[path = "mod-merge-hack-template.rs"]
3+
#[merge = "mod-merge-hack-inst.rs"]
4+
mod myint32;
5+
6+
fn main() {
7+
assert myint32::bits == 32;
8+
assert myint32::min(10, 20) == 10;
9+
}

0 commit comments

Comments
 (0)