diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 79fe50ecd14..709d1537d41 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -203,6 +203,7 @@ fn Parser(sess: parse_sess, cfg: ast::crate_cfg, strict_keywords: token::strict_keyword_table(), reserved_keywords: token::reserved_keyword_table(), obsolete_set: std::map::HashMap(), + mod_path_stack: ~[], } } @@ -226,6 +227,8 @@ struct Parser { /// The set of seen errors about obsolete syntax. Used to suppress /// extra detail when the same error is seen twice obsolete_set: HashMap, + /// Used to determine the path to externally loaded source files + mut mod_path_stack: ~[~str], drop {} /* do not copy the parser; its state is tied to outside state */ } @@ -3041,10 +3044,12 @@ impl Parser { let (m, attrs) = self.eval_src_mod(id, outer_attrs, id_span); (id, m, Some(move attrs)) } else { + self.push_mod_path(id, outer_attrs); self.expect(token::LBRACE); let inner_attrs = self.parse_inner_attrs_and_next(); let m = self.parse_mod_items(token::RBRACE, inner_attrs.next); self.expect(token::RBRACE); + self.pop_mod_path(); (id, item_mod(m), Some(inner_attrs.inner)) }; @@ -3081,20 +3086,40 @@ impl Parser { } } + fn push_mod_path(id: ident, attrs: ~[ast::attribute]) { + let default_path = self.sess.interner.get(id); + let file_path = match ::attr::first_attr_value_str_by_name( + attrs, ~"path2") { + + Some(ref d) => (*d), + None => copy *default_path + }; + self.mod_path_stack.push(file_path) + } + + fn pop_mod_path() { + self.mod_path_stack.pop(); + } + fn eval_src_mod(id: ast::ident, outer_attrs: ~[ast::attribute], id_sp: span) -> (ast::item_, ~[ast::attribute]) { + let prefix = Path(self.sess.cm.span_to_filename(copy self.span)); let prefix = prefix.dir_path(); + let mod_path = Path(".").push_many(self.mod_path_stack); let default_path = self.sess.interner.get(id) + ~".rs"; let file_path = match ::attr::first_attr_value_str_by_name( - outer_attrs, ~"path") { + outer_attrs, ~"path2") { - Some(ref d) => (*d), - None => default_path + Some(ref d) => mod_path.push(*d), + None => match ::attr::first_attr_value_str_by_name( + outer_attrs, ~"path") { + Some(ref d) => Path(*d), + None => mod_path.push(default_path) + } }; - let file_path = Path(file_path); self.eval_src_mod_from_path(prefix, file_path, outer_attrs, id_sp) } diff --git a/src/test/run-pass/mod_dir_path.rs b/src/test/run-pass/mod_dir_path.rs new file mode 100644 index 00000000000..14ad18cd091 --- /dev/null +++ b/src/test/run-pass/mod_dir_path.rs @@ -0,0 +1,21 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +mod mod_dir_simple { + #[path2 = "test.rs"] + pub mod syrup; +} + +fn main() { + assert mod_dir_simple::syrup::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_path2.rs b/src/test/run-pass/mod_dir_path2.rs new file mode 100644 index 00000000000..98ed84ec707 --- /dev/null +++ b/src/test/run-pass/mod_dir_path2.rs @@ -0,0 +1,22 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +#[path2 = "mod_dir_simple"] +mod pancakes { + #[path2 = "test.rs"] + pub mod syrup; +} + +fn main() { + assert pancakes::syrup::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_path3.rs b/src/test/run-pass/mod_dir_path3.rs new file mode 100644 index 00000000000..cc11dbe1fbd --- /dev/null +++ b/src/test/run-pass/mod_dir_path3.rs @@ -0,0 +1,21 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +#[path2 = "mod_dir_simple"] +mod pancakes { + pub mod test; +} + +fn main() { + assert pancakes::test::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_path_multi.rs b/src/test/run-pass/mod_dir_path_multi.rs new file mode 100644 index 00000000000..ef6b3be6e45 --- /dev/null +++ b/src/test/run-pass/mod_dir_path_multi.rs @@ -0,0 +1,27 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +#[path2 = "mod_dir_simple"] +mod biscuits { + pub mod test; +} + +#[path2 = "mod_dir_simple"] +mod gravy { + pub mod test; +} + +fn main() { + assert biscuits::test::foo() == 10; + assert gravy::test::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_recursive.rs b/src/test/run-pass/mod_dir_recursive.rs new file mode 100644 index 00000000000..b95852f3a31 --- /dev/null +++ b/src/test/run-pass/mod_dir_recursive.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +// Testing that the parser for each file tracks its modules +// and paths independently. The load_another_mod module should +// not try to reuse the 'mod_dir_simple' path. + +mod mod_dir_simple { + pub mod load_another_mod; +} + +fn main() { + assert mod_dir_simple::load_another_mod::test::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_simple.rs b/src/test/run-pass/mod_dir_simple.rs new file mode 100644 index 00000000000..7f07982a65b --- /dev/null +++ b/src/test/run-pass/mod_dir_simple.rs @@ -0,0 +1,20 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// xfail-pretty +// xfail-fast + +mod mod_dir_simple { + pub mod test; +} + +fn main() { + assert mod_dir_simple::test::foo() == 10; +} diff --git a/src/test/run-pass/mod_dir_simple/load_another_mod.rs b/src/test/run-pass/mod_dir_simple/load_another_mod.rs new file mode 100644 index 00000000000..335da61cd4e --- /dev/null +++ b/src/test/run-pass/mod_dir_simple/load_another_mod.rs @@ -0,0 +1,11 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod test; diff --git a/src/test/run-pass/mod_dir_simple/test.rs b/src/test/run-pass/mod_dir_simple/test.rs new file mode 100644 index 00000000000..a3c1628725a --- /dev/null +++ b/src/test/run-pass/mod_dir_simple/test.rs @@ -0,0 +1,11 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub fn foo() -> int { 10 }