Refactor view_path to parse (but not yet process) export globs, unify code paths.
This commit is contained in:
parent
6f70896854
commit
ef6f628589
11 changed files with 431 additions and 409 deletions
|
@ -31,7 +31,8 @@ fn inject_libcore_ref(sess: session,
|
||||||
let n2 = sess.next_node_id();
|
let n2 = sess.next_node_id();
|
||||||
|
|
||||||
let vi1 = spanned(ast::view_item_use("core", [], n1));
|
let vi1 = spanned(ast::view_item_use("core", [], n1));
|
||||||
let vi2 = spanned(ast::view_item_import_glob(@["core"], n2));
|
let vp = spanned(ast::view_path_glob(@["core"], n2));
|
||||||
|
let vi2 = spanned(ast::view_item_import([vp]));
|
||||||
|
|
||||||
let vis = [vi1, vi2] + crate.node.module.view_items;
|
let vis = [vi1, vi2] + crate.node.module.view_items;
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ enum mod_index_entry {
|
||||||
|
|
||||||
type mod_index = hashmap<ident, list<mod_index_entry>>;
|
type mod_index = hashmap<ident, list<mod_index_entry>>;
|
||||||
|
|
||||||
// A tuple of an imported def and the import stmt that brung it
|
// A tuple of an imported def and the view_path from its originating import
|
||||||
type glob_imp_def = {def: def, item: @ast::view_item};
|
type glob_imp_def = {def: def, path: @ast::view_path};
|
||||||
|
|
||||||
type indexed_mod = {
|
type indexed_mod = {
|
||||||
m: option<ast::_mod>,
|
m: option<ast::_mod>,
|
||||||
|
@ -200,43 +200,53 @@ fn create_env(sess: session, amap: ast_map::map) -> @env {
|
||||||
sess: sess}
|
sess: sess}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locate all modules and imports and index them, so that the next passes can
|
fn iter_import_paths(vi: ast::view_item, f: fn(vp: @ast::view_path)) {
|
||||||
// resolve through them.
|
alt vi.node {
|
||||||
fn map_crate(e: @env, c: @ast::crate) {
|
ast::view_item_import(vps) {
|
||||||
// First, find all the modules, and index the names that they contain
|
for vp in vps {
|
||||||
let v_map_mod =
|
f(vp);
|
||||||
@{visit_view_item: bind index_vi(e, _, _, _),
|
|
||||||
visit_item: bind index_i(e, _, _, _),
|
|
||||||
visit_block: visit_block_with_scope
|
|
||||||
with *visit::default_visitor::<scopes>()};
|
|
||||||
visit::visit_crate(*c, top_scope(), visit::mk_vt(v_map_mod));
|
|
||||||
|
|
||||||
// Register the top-level mod
|
|
||||||
e.mod_map.insert(ast::crate_node_id,
|
|
||||||
@{m: some(c.node.module),
|
|
||||||
index: index_mod(c.node.module),
|
|
||||||
mutable glob_imports: [],
|
|
||||||
glob_imported_names: new_str_hash(),
|
|
||||||
path: ""});
|
|
||||||
fn index_vi(e: @env, i: @ast::view_item, sc: scopes, _v: vt<scopes>) {
|
|
||||||
alt i.node {
|
|
||||||
ast::view_item_import(name, ids, id) {
|
|
||||||
e.imports.insert(id, todo(id, name, ids, i.span, sc));
|
|
||||||
}
|
}
|
||||||
ast::view_item_import_from(mod_path, idents, id) {
|
|
||||||
for ident in idents {
|
|
||||||
e.imports.insert(ident.node.id,
|
|
||||||
todo(ident.node.id, ident.node.name,
|
|
||||||
@(*mod_path + [ident.node.name]),
|
|
||||||
ident.span, sc));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::view_item_import_glob(pth, id) {
|
|
||||||
e.imports.insert(id, is_glob(pth, sc, i.span));
|
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn iter_export_paths(vi: ast::view_item, f: fn(vp: @ast::view_path)) {
|
||||||
|
alt vi.node {
|
||||||
|
ast::view_item_export(vps) {
|
||||||
|
for vp in vps {
|
||||||
|
f(vp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate all modules and imports and index them, so that the next passes can
|
||||||
|
// resolve through them.
|
||||||
|
fn map_crate(e: @env, c: @ast::crate) {
|
||||||
|
|
||||||
|
fn index_vi(e: @env, i: @ast::view_item, sc: scopes, _v: vt<scopes>) {
|
||||||
|
iter_import_paths(*i) { |vp|
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(name, path, id) {
|
||||||
|
e.imports.insert(id, todo(id, name, path, vp.span, sc));
|
||||||
|
}
|
||||||
|
ast::view_path_glob(path, id) {
|
||||||
|
e.imports.insert(id, is_glob(path, sc, vp.span));
|
||||||
|
}
|
||||||
|
ast::view_path_list(mod_path, idents, _) {
|
||||||
|
for ident in idents {
|
||||||
|
let t = todo(ident.node.id, ident.node.name,
|
||||||
|
@(*mod_path + [ident.node.name]),
|
||||||
|
ident.span, sc);
|
||||||
|
e.imports.insert(ident.node.id, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn path_from_scope(sc: scopes, n: str) -> str {
|
fn path_from_scope(sc: scopes, n: str) -> str {
|
||||||
let path = n + "::";
|
let path = n + "::";
|
||||||
list::iter(sc) {|s|
|
list::iter(sc) {|s|
|
||||||
|
@ -247,6 +257,7 @@ fn map_crate(e: @env, c: @ast::crate) {
|
||||||
}
|
}
|
||||||
path
|
path
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index_i(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
|
fn index_i(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
|
||||||
visit_item_with_scope(e, i, sc, v);
|
visit_item_with_scope(e, i, sc, v);
|
||||||
alt i.node {
|
alt i.node {
|
||||||
|
@ -270,20 +281,14 @@ fn map_crate(e: @env, c: @ast::crate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next, assemble the links for globbed imports.
|
|
||||||
let v_link_glob =
|
|
||||||
@{visit_view_item: bind link_glob(e, _, _, _),
|
|
||||||
visit_block: visit_block_with_scope,
|
|
||||||
visit_item: bind visit_item_with_scope(e, _, _, _)
|
|
||||||
with *visit::default_visitor::<scopes>()};
|
|
||||||
visit::visit_crate(*c, top_scope(), visit::mk_vt(v_link_glob));
|
|
||||||
fn link_glob(e: @env, vi: @ast::view_item, sc: scopes, _v: vt<scopes>) {
|
fn link_glob(e: @env, vi: @ast::view_item, sc: scopes, _v: vt<scopes>) {
|
||||||
alt vi.node {
|
iter_import_paths(*vi) { |vp|
|
||||||
//if it really is a glob import, that is
|
//if it really is a glob import, that is
|
||||||
ast::view_item_import_glob(path, _) {
|
alt vp.node {
|
||||||
alt follow_import(*e, sc, *path, vi.span) {
|
ast::view_path_glob(path, _) {
|
||||||
|
alt follow_import(*e, sc, *path, vp.span) {
|
||||||
some(imp) {
|
some(imp) {
|
||||||
let glob = {def: imp, item: vi};
|
let glob = {def: imp, path: vp};
|
||||||
check list::is_not_empty(sc);
|
check list::is_not_empty(sc);
|
||||||
alt list::head(sc) {
|
alt list::head(sc) {
|
||||||
scope_item(i) {
|
scope_item(i) {
|
||||||
|
@ -291,7 +296,8 @@ fn map_crate(e: @env, c: @ast::crate) {
|
||||||
}
|
}
|
||||||
scope_block(b, _, _) {
|
scope_block(b, _, _) {
|
||||||
let globs = alt e.block_map.find(b.node.id) {
|
let globs = alt e.block_map.find(b.node.id) {
|
||||||
some(globs) { globs + [glob] } none { [glob] }
|
some(globs) { globs + [glob] }
|
||||||
|
none { [glob] }
|
||||||
};
|
};
|
||||||
e.block_map.insert(b.node.id, globs);
|
e.block_map.insert(b.node.id, globs);
|
||||||
}
|
}
|
||||||
|
@ -311,6 +317,32 @@ fn map_crate(e: @env, c: @ast::crate) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// First, find all the modules, and index the names that they contain
|
||||||
|
let v_map_mod =
|
||||||
|
@{visit_view_item: bind index_vi(e, _, _, _),
|
||||||
|
visit_item: bind index_i(e, _, _, _),
|
||||||
|
visit_block: visit_block_with_scope
|
||||||
|
with *visit::default_visitor::<scopes>()};
|
||||||
|
visit::visit_crate(*c, top_scope(), visit::mk_vt(v_map_mod));
|
||||||
|
|
||||||
|
// Register the top-level mod
|
||||||
|
e.mod_map.insert(ast::crate_node_id,
|
||||||
|
@{m: some(c.node.module),
|
||||||
|
index: index_mod(c.node.module),
|
||||||
|
mutable glob_imports: [],
|
||||||
|
glob_imported_names: new_str_hash(),
|
||||||
|
path: ""});
|
||||||
|
|
||||||
|
// Next, assemble the links for globbed imports.
|
||||||
|
let v_link_glob =
|
||||||
|
@{visit_view_item: bind link_glob(e, _, _, _),
|
||||||
|
visit_block: visit_block_with_scope,
|
||||||
|
visit_item: bind visit_item_with_scope(e, _, _, _)
|
||||||
|
with *visit::default_visitor::<scopes>()};
|
||||||
|
visit::visit_crate(*c, top_scope(), visit::mk_vt(v_link_glob));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_imports(e: env) {
|
fn resolve_imports(e: env) {
|
||||||
e.used_imports.track = true;
|
e.used_imports.track = true;
|
||||||
e.imports.values {|v|
|
e.imports.values {|v|
|
||||||
|
@ -674,18 +706,20 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
|
||||||
fn lst(my_id: node_id, vis: [@view_item]) -> [node_id] {
|
fn lst(my_id: node_id, vis: [@view_item]) -> [node_id] {
|
||||||
let imports = [], found = false;
|
let imports = [], found = false;
|
||||||
for vi in vis {
|
for vi in vis {
|
||||||
alt vi.node {
|
iter_import_paths(*vi) {|vp|
|
||||||
view_item_import(_, _, id) | view_item_import_glob(_, id) {
|
alt vp.node {
|
||||||
|
view_path_simple(_, _, id)
|
||||||
|
| view_path_glob(_, id) {
|
||||||
if id == my_id { found = true; }
|
if id == my_id { found = true; }
|
||||||
if found { imports += [id]; }
|
if found { imports += [id]; }
|
||||||
}
|
}
|
||||||
view_item_import_from(_, ids, _) {
|
view_path_list(_, ids, _) {
|
||||||
for id in ids {
|
for id in ids {
|
||||||
if id.node.id == my_id { found = true; }
|
if id.node.id == my_id { found = true; }
|
||||||
if found { imports += [id.node.id]; }
|
if found { imports += [id.node.id]; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
imports
|
imports
|
||||||
|
@ -1177,25 +1211,38 @@ fn lookup_in_block(e: env, name: ident, sp: span, b: ast::blk_, pos: uint,
|
||||||
}
|
}
|
||||||
for vi in b.view_items {
|
for vi in b.view_items {
|
||||||
alt vi.node {
|
alt vi.node {
|
||||||
ast::view_item_import(ident, _, id) {
|
|
||||||
if name == ident { ret lookup_import(e, local_def(id), ns); }
|
ast::view_item_import(vps) {
|
||||||
|
for vp in vps {
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(ident, _, id) {
|
||||||
|
if name == ident {
|
||||||
|
ret lookup_import(e, local_def(id), ns);
|
||||||
}
|
}
|
||||||
ast::view_item_import_from(mod_path, idents, id) {
|
}
|
||||||
|
|
||||||
|
ast::view_path_list(path, idents, _) {
|
||||||
for ident in idents {
|
for ident in idents {
|
||||||
if name == ident.node.name {
|
if name == ident.node.name {
|
||||||
ret lookup_import(e, local_def(ident.node.id), ns);
|
let def = local_def(ident.node.id);
|
||||||
|
ret lookup_import(e, def, ns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::view_item_import_glob(_, _) {
|
|
||||||
|
ast::view_path_glob(_, _) {
|
||||||
alt e.block_map.find(b.id) {
|
alt e.block_map.find(b.id) {
|
||||||
some(globs) {
|
some(globs) {
|
||||||
let found = lookup_in_globs(e, globs, sp, name, ns, inside);
|
let found = lookup_in_globs(e, globs, sp, name,
|
||||||
|
ns, inside);
|
||||||
if found != none { ret found; }
|
if found != none { ret found; }
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
_ { e.sess.span_bug(vi.span, "Unexpected view_item in block"); }
|
_ { e.sess.span_bug(vi.span, "Unexpected view_item in block"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1363,16 +1410,18 @@ fn lookup_in_globs(e: env, globs: [glob_imp_def], sp: span, id: ident,
|
||||||
ns: namespace, dr: dir) -> option<def> {
|
ns: namespace, dr: dir) -> option<def> {
|
||||||
fn lookup_in_mod_(e: env, def: glob_imp_def, sp: span, name: ident,
|
fn lookup_in_mod_(e: env, def: glob_imp_def, sp: span, name: ident,
|
||||||
ns: namespace, dr: dir) -> option<glob_imp_def> {
|
ns: namespace, dr: dir) -> option<glob_imp_def> {
|
||||||
alt def.item.node {
|
alt def.path.node {
|
||||||
ast::view_item_import_glob(_, id) {
|
|
||||||
|
ast::view_path_glob(_, id) {
|
||||||
if vec::contains(e.ignored_imports, id) { ret none; }
|
if vec::contains(e.ignored_imports, id) { ret none; }
|
||||||
}
|
}
|
||||||
|
|
||||||
_ {
|
_ {
|
||||||
e.sess.span_bug(sp, "lookup_in_globs: not a glob");
|
e.sess.span_bug(sp, "lookup_in_globs: not a glob");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alt lookup_in_mod(e, def.def, sp, name, ns, dr) {
|
alt lookup_in_mod(e, def.def, sp, name, ns, dr) {
|
||||||
some(d) { option::some({def: d, item: def.item}) }
|
some(d) { option::some({def: d, path: def.path}) }
|
||||||
none { none }
|
none { none }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1385,7 +1434,7 @@ fn lookup_in_globs(e: env, globs: [glob_imp_def], sp: span, id: ident,
|
||||||
ret some(matches[0].def);
|
ret some(matches[0].def);
|
||||||
} else {
|
} else {
|
||||||
for match: glob_imp_def in matches {
|
for match: glob_imp_def in matches {
|
||||||
let sp = match.item.span;
|
let sp = match.path.span;
|
||||||
e.sess.span_note(sp, #fmt["'%s' is imported here", id]);
|
e.sess.span_note(sp, #fmt["'%s' is imported here", id]);
|
||||||
}
|
}
|
||||||
e.sess.span_fatal(sp, "'" + id + "' is glob-imported from" +
|
e.sess.span_fatal(sp, "'" + id + "' is glob-imported from" +
|
||||||
|
@ -1476,28 +1525,41 @@ fn add_to_index(index: hashmap<ident, list<mod_index_entry>>, id: ident,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn index_mod(md: ast::_mod) -> mod_index {
|
fn index_view_items(view_items: [@ast::view_item],
|
||||||
let index = new_str_hash::<list<mod_index_entry>>();
|
index: hashmap<ident, list<mod_index_entry>>) {
|
||||||
for it: @ast::view_item in md.view_items {
|
for vi in view_items {
|
||||||
alt it.node {
|
alt vi.node {
|
||||||
ast::view_item_use(ident, _, id) {
|
ast::view_item_use(ident, _, id) {
|
||||||
add_to_index(index, ident, mie_view_item(ident, id, it.span));
|
add_to_index(index, ident, mie_view_item(ident, id, vi.span));
|
||||||
}
|
}
|
||||||
ast::view_item_import(ident, _, id) {
|
|
||||||
add_to_index(index, ident, mie_import_ident(id, it.span));
|
|
||||||
}
|
|
||||||
ast::view_item_import_from(_, idents, _) {
|
|
||||||
for ident in idents {
|
|
||||||
add_to_index(index, ident.node.name,
|
|
||||||
mie_import_ident(ident.node.id, ident.span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//globbed imports have to be resolved lazily.
|
|
||||||
ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) {}
|
|
||||||
// exports: ignore
|
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iter_import_paths(*vi) {|vp|
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(ident, _, id) {
|
||||||
|
add_to_index(index, ident, mie_import_ident(id, vp.span));
|
||||||
}
|
}
|
||||||
|
ast::view_path_list(_, idents, _) {
|
||||||
|
for ident in idents {
|
||||||
|
add_to_index(index, ident.node.name,
|
||||||
|
mie_import_ident(ident.node.id,
|
||||||
|
ident.span));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// globbed imports have to be resolved lazily.
|
||||||
|
ast::view_path_glob(_, _) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn index_mod(md: ast::_mod) -> mod_index {
|
||||||
|
let index = new_str_hash::<list<mod_index_entry>>();
|
||||||
|
|
||||||
|
index_view_items(md.view_items, index);
|
||||||
|
|
||||||
for it: @ast::item in md.items {
|
for it: @ast::item in md.items {
|
||||||
alt it.node {
|
alt it.node {
|
||||||
ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
|
ast::item_const(_, _) | ast::item_fn(_, _, _) | ast::item_mod(_) |
|
||||||
|
@ -1537,27 +1599,12 @@ fn index_mod(md: ast::_mod) -> mod_index {
|
||||||
ret index;
|
ret index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn index_nmod(md: ast::native_mod) -> mod_index {
|
fn index_nmod(md: ast::native_mod) -> mod_index {
|
||||||
let index = new_str_hash::<list<mod_index_entry>>();
|
let index = new_str_hash::<list<mod_index_entry>>();
|
||||||
for it: @ast::view_item in md.view_items {
|
|
||||||
alt it.node {
|
index_view_items(md.view_items, index);
|
||||||
ast::view_item_use(ident, _, id) {
|
|
||||||
add_to_index(index, ident, mie_view_item(ident, id,
|
|
||||||
it.span));
|
|
||||||
}
|
|
||||||
ast::view_item_import(ident, _, id) {
|
|
||||||
add_to_index(index, ident, mie_import_ident(id, it.span));
|
|
||||||
}
|
|
||||||
ast::view_item_import_from(_, idents, _) {
|
|
||||||
for ident in idents {
|
|
||||||
add_to_index(index, ident.node.name,
|
|
||||||
mie_import_ident(ident.node.id, ident.span));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::view_item_import_glob(_, _) | ast::view_item_export(_, _) { }
|
|
||||||
_ { /* tag exports */ }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for it: @ast::native_item in md.items {
|
for it: @ast::native_item in md.items {
|
||||||
add_to_index(index, it.ident, mie_native_item(it));
|
add_to_index(index, it.ident, mie_native_item(it));
|
||||||
}
|
}
|
||||||
|
@ -1912,55 +1959,72 @@ fn check_exports(e: @env) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.mod_map.values {|val|
|
fn check_export_enum_list(e: @env, val: @indexed_mod,
|
||||||
alt val.m {
|
span: codemap::span, id: ast::ident,
|
||||||
some(m) {
|
ids: [ast::path_list_ident]) {
|
||||||
for vi in m.view_items {
|
if vec::len(ids) == 0u {
|
||||||
alt vi.node {
|
let _ = check_enum_ok(e, span, id, val);
|
||||||
ast::view_item_export(idents, _) {
|
} else {
|
||||||
for ident in idents {
|
let parent_id = check_enum_ok(e, span, id, val);
|
||||||
check_export(e, ident, val, vi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::view_item_export_enum_none(id, _) {
|
|
||||||
let _ = check_enum_ok(e, vi.span, id, val);
|
|
||||||
}
|
|
||||||
ast::view_item_export_enum_some(id, ids, _) {
|
|
||||||
// Check that it's an enum and all the given variants
|
|
||||||
// belong to it
|
|
||||||
let parent_id = check_enum_ok(e, vi.span, id, val);
|
|
||||||
for variant_id in ids {
|
for variant_id in ids {
|
||||||
alt val.index.find(variant_id.node.name) {
|
alt val.index.find(variant_id.node.name) {
|
||||||
some(ms) {
|
some(ms) {
|
||||||
list::iter(ms) {|m|
|
list::iter(ms) {|m|
|
||||||
alt m {
|
alt m {
|
||||||
mie_enum_variant(_, _, actual_parent_id,
|
mie_enum_variant(_, _, actual_parent_id, _) {
|
||||||
_) {
|
|
||||||
if actual_parent_id != parent_id {
|
if actual_parent_id != parent_id {
|
||||||
e.sess.span_err(vi.span,
|
let msg = #fmt("variant %s \
|
||||||
#fmt("variant %s \
|
|
||||||
doesn't belong to enum %s",
|
doesn't belong to enum %s",
|
||||||
variant_id.node.name,
|
variant_id.node.name,
|
||||||
id));
|
id);
|
||||||
|
e.sess.span_err(span, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ { e.sess.span_err(vi.span,
|
_ {
|
||||||
#fmt("%s is not a \
|
e.sess.span_err(span,
|
||||||
variant", variant_id.node.name)); }
|
#fmt("%s is not a variant",
|
||||||
}}
|
variant_id.node.name));
|
||||||
}
|
|
||||||
_ { e.sess.span_err(vi.span, #fmt("%s is not a\
|
|
||||||
variant", variant_id.node.name)); }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_ {
|
||||||
|
e.sess.span_err(span,
|
||||||
|
#fmt("%s is not a variant",
|
||||||
|
variant_id.node.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.mod_map.values {|val|
|
||||||
|
alt val.m {
|
||||||
|
some(m) {
|
||||||
|
for vi in m.view_items {
|
||||||
|
iter_export_paths(*vi) { |vp|
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(ident, _, _) {
|
||||||
|
check_export(e, ident, val, vi);
|
||||||
|
}
|
||||||
|
ast::view_path_list(path, ids, _) {
|
||||||
|
let id = if vec::len(*path) == 1u {
|
||||||
|
path[0]
|
||||||
|
} else {
|
||||||
|
e.sess.span_fatal(vp.span,
|
||||||
|
#fmt("bad export name-list"))
|
||||||
|
};
|
||||||
|
check_export_enum_list(e, val, vp.span, id, ids);
|
||||||
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
none { }
|
none { }
|
||||||
}
|
}
|
||||||
}}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Impl resolution
|
// Impl resolution
|
||||||
|
|
||||||
|
@ -1993,8 +2057,10 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alt vi.node {
|
|
||||||
ast::view_item_import(name, pt, id) {
|
iter_import_paths(*vi) { |vp|
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(name, pt, id) {
|
||||||
let found = [];
|
let found = [];
|
||||||
if vec::len(*pt) == 1u {
|
if vec::len(*pt) == 1u {
|
||||||
option::may(sc) {|sc|
|
option::may(sc) {|sc|
|
||||||
|
@ -2014,12 +2080,14 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::view_item_import_from(base, names, _) {
|
|
||||||
|
ast::view_path_list(base, names, _) {
|
||||||
for nm in names {
|
for nm in names {
|
||||||
lookup_imported_impls(e, nm.node.id) {|is| impls += *is; }
|
lookup_imported_impls(e, nm.node.id) {|is| impls += *is; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::view_item_import_glob(ids, id) {
|
|
||||||
|
ast::view_path_glob(ids, id) {
|
||||||
alt check e.imports.get(id) {
|
alt check e.imports.get(id) {
|
||||||
is_glob(path, sc, sp) {
|
is_glob(path, sc, sp) {
|
||||||
alt follow_import(e, sc, *path, sp) {
|
alt follow_import(e, sc, *path, sp) {
|
||||||
|
@ -2029,7 +2097,7 @@ fn find_impls_in_view_item(e: env, vi: @ast::view_item,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ {}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -441,26 +441,36 @@ type variant_ = {name: ident, attrs: [attribute], args: [variant_arg],
|
||||||
|
|
||||||
type variant = spanned<variant_>;
|
type variant = spanned<variant_>;
|
||||||
|
|
||||||
type view_item = spanned<view_item_>;
|
|
||||||
|
|
||||||
// FIXME: May want to just use path here, which would allow things like
|
// FIXME: May want to just use path here, which would allow things like
|
||||||
// 'import ::foo'
|
// 'import ::foo'
|
||||||
type simple_path = [ident];
|
type simple_path = [ident];
|
||||||
|
|
||||||
type import_ident_ = {name: ident, id: node_id};
|
type path_list_ident_ = {name: ident, id: node_id};
|
||||||
|
type path_list_ident = spanned<path_list_ident_>;
|
||||||
|
|
||||||
type import_ident = spanned<import_ident_>;
|
type view_path = spanned<view_path_>;
|
||||||
|
enum view_path_ {
|
||||||
|
|
||||||
|
// quux = foo::bar::baz
|
||||||
|
//
|
||||||
|
// or just
|
||||||
|
//
|
||||||
|
// foo::bar::baz (with 'baz =' implicitly on the left)
|
||||||
|
view_path_simple(ident, @simple_path, node_id),
|
||||||
|
|
||||||
|
// foo::bar::*
|
||||||
|
view_path_glob(@simple_path, node_id),
|
||||||
|
|
||||||
|
// foo::bar::{a,b,c}
|
||||||
|
view_path_list(@simple_path, [path_list_ident], node_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
type view_item = spanned<view_item_>;
|
||||||
enum view_item_ {
|
enum view_item_ {
|
||||||
view_item_use(ident, [@meta_item], node_id),
|
view_item_use(ident, [@meta_item], node_id),
|
||||||
view_item_import(ident, @simple_path, node_id),
|
view_item_import([@view_path]),
|
||||||
view_item_import_glob(@simple_path, node_id),
|
view_item_export([@view_path])
|
||||||
view_item_import_from(@simple_path, [import_ident], node_id),
|
|
||||||
view_item_export([ident], node_id),
|
|
||||||
// export foo::{}
|
|
||||||
view_item_export_enum_none(ident, node_id),
|
|
||||||
// export foo::{bar, baz, blat}
|
|
||||||
view_item_export_enum_some(ident, [import_ident], node_id)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Meta-data associated with an item
|
// Meta-data associated with an item
|
||||||
|
|
|
@ -116,56 +116,63 @@ fn float_ty_to_str(t: float_ty) -> str {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_exported(i: ident, m: _mod) -> bool {
|
fn is_exported(i: ident, m: _mod) -> bool {
|
||||||
let nonlocal = true;
|
let local = false;
|
||||||
let parent_enum : option<ident> = none;
|
let parent_enum : option<ident> = none;
|
||||||
for it: @item in m.items {
|
for it: @item in m.items {
|
||||||
if it.ident == i { nonlocal = false; }
|
if it.ident == i { local = true; }
|
||||||
alt it.node {
|
alt it.node {
|
||||||
item_enum(variants, _) {
|
item_enum(variants, _) {
|
||||||
for v: variant in variants {
|
for v: variant in variants {
|
||||||
if v.node.name == i {
|
if v.node.name == i {
|
||||||
nonlocal = false;
|
local = true;
|
||||||
parent_enum = some(it.ident);
|
parent_enum = some(it.ident);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ { }
|
_ { }
|
||||||
}
|
}
|
||||||
if !nonlocal { break; }
|
if local { break; }
|
||||||
}
|
}
|
||||||
let count = 0u;
|
let has_explicit_exports = false;
|
||||||
for vi: @view_item in m.view_items {
|
for vi: @view_item in m.view_items {
|
||||||
alt vi.node {
|
alt vi.node {
|
||||||
view_item_export(ids, _) {
|
view_item_export(vps) {
|
||||||
// If any of ids is a enum, we want to consider
|
has_explicit_exports = true;
|
||||||
// all the variants to be exported
|
for vp in vps {
|
||||||
for id in ids {
|
alt vp.node {
|
||||||
if str::eq(i, id) { ret true; }
|
ast::view_path_simple(id, _, _) {
|
||||||
|
if id == i { ret true; }
|
||||||
alt parent_enum {
|
alt parent_enum {
|
||||||
some(parent_enum_id) {
|
some(parent_enum_id) {
|
||||||
if str::eq(id, parent_enum_id) { ret true; }
|
if id == parent_enum_id { ret true; }
|
||||||
}
|
}
|
||||||
_ {}
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
count += 1u;
|
|
||||||
|
ast::view_path_list(path, ids, _) {
|
||||||
|
if vec::len(*path) == 1u {
|
||||||
|
if i == path[0] { ret true; }
|
||||||
|
for id in ids {
|
||||||
|
if id.node.name == i { ret true; }
|
||||||
}
|
}
|
||||||
view_item_export_enum_none(id, _) {
|
} else {
|
||||||
if str::eq(i, id) { ret true; }
|
fail "export of path-qualified list";
|
||||||
count += 1u;
|
|
||||||
}
|
}
|
||||||
view_item_export_enum_some(id, ids, _) {
|
|
||||||
if str::eq(i, id) { ret true; }
|
|
||||||
for id in ids { if str::eq(i, id.node.name) { ret true; } }
|
|
||||||
count += 1u;
|
|
||||||
}
|
}
|
||||||
_ {/* fall through */ }
|
|
||||||
|
// FIXME: glob-exports aren't supported yet.
|
||||||
|
_ {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there are no declared exports then
|
// If there are no declared exports then
|
||||||
// everything not imported is exported
|
// everything not imported is exported
|
||||||
// even if it's nonlocal (since it's explicit)
|
// even if it's local (since it's explicit)
|
||||||
ret count == 0u && !nonlocal;
|
ret !has_explicit_exports && local;
|
||||||
}
|
}
|
||||||
|
|
||||||
pure fn is_call_expr(e: @expr) -> bool {
|
pure fn is_call_expr(e: @expr) -> bool {
|
||||||
|
|
|
@ -202,7 +202,7 @@ fn parse_ident(p: parser) -> ast::ident {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_import_ident(p: parser) -> ast::import_ident {
|
fn parse_path_list_ident(p: parser) -> ast::path_list_ident {
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
let ident = parse_ident(p);
|
let ident = parse_ident(p);
|
||||||
let hi = p.span.hi;
|
let hi = p.span.hi;
|
||||||
|
@ -2421,140 +2421,81 @@ fn parse_use(p: parser) -> ast::view_item_ {
|
||||||
ret ast::view_item_use(ident, metadata, p.get_id());
|
ret ast::view_item_use(ident, metadata, p.get_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_rest_import_name(p: parser, first: ast::ident,
|
fn parse_view_path(p: parser) -> @ast::view_path {
|
||||||
def_ident: option<ast::ident>) ->
|
let lo = p.span.lo;
|
||||||
ast::view_item_ {
|
let first_ident = parse_ident(p);
|
||||||
let identifiers: [ast::ident] = [first];
|
let path = [first_ident];
|
||||||
let glob: bool = false;
|
#debug("parsed view_path: %s", first_ident);
|
||||||
let from_idents = option::none::<[ast::import_ident]>;
|
|
||||||
while true {
|
|
||||||
alt p.token {
|
|
||||||
token::SEMI { break; }
|
|
||||||
token::MOD_SEP {
|
|
||||||
if glob { p.fatal("cannot path into a glob"); }
|
|
||||||
if option::is_some(from_idents) {
|
|
||||||
p.fatal("cannot path into import list");
|
|
||||||
}
|
|
||||||
p.bump();
|
|
||||||
}
|
|
||||||
_ { p.fatal("expecting '::' or ';'"); }
|
|
||||||
}
|
|
||||||
alt p.token {
|
|
||||||
token::IDENT(_, _) { identifiers += [parse_ident(p)]; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//the lexer can't tell the different kinds of stars apart ) :
|
|
||||||
token::BINOP(token::STAR) {
|
|
||||||
glob = true;
|
|
||||||
p.bump();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
token::LBRACE {
|
|
||||||
let from_idents_ =
|
|
||||||
parse_seq(token::LBRACE, token::RBRACE, seq_sep(token::COMMA),
|
|
||||||
parse_import_ident, p).node;
|
|
||||||
if vec::is_empty(from_idents_) {
|
|
||||||
p.fatal("at least one import is required");
|
|
||||||
}
|
|
||||||
from_idents = some(from_idents_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_ {
|
|
||||||
p.fatal("expecting an identifier, or '*'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alt def_ident {
|
|
||||||
some(i) {
|
|
||||||
if glob { p.fatal("globbed imports can't be renamed"); }
|
|
||||||
if option::is_some(from_idents) {
|
|
||||||
p.fatal("can't rename import list");
|
|
||||||
}
|
|
||||||
ret ast::view_item_import(i, @identifiers, p.get_id());
|
|
||||||
}
|
|
||||||
_ {
|
|
||||||
if glob {
|
|
||||||
ret ast::view_item_import_glob(@identifiers, p.get_id());
|
|
||||||
} else if option::is_some(from_idents) {
|
|
||||||
ret ast::view_item_import_from(@identifiers,
|
|
||||||
option::get(from_idents),
|
|
||||||
p.get_id());
|
|
||||||
} else {
|
|
||||||
let len = vec::len(identifiers);
|
|
||||||
ret ast::view_item_import(identifiers[len - 1u], @identifiers,
|
|
||||||
p.get_id());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_full_import_name(p: parser, def_ident: ast::ident) ->
|
|
||||||
ast::view_item_ {
|
|
||||||
alt p.token {
|
|
||||||
token::IDENT(i, _) {
|
|
||||||
p.bump();
|
|
||||||
ret parse_rest_import_name(p, p.get_str(i), some(def_ident));
|
|
||||||
}
|
|
||||||
_ { p.fatal("expecting an identifier"); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_import(p: parser) -> ast::view_item_ {
|
|
||||||
alt p.token {
|
|
||||||
token::IDENT(i, _) {
|
|
||||||
p.bump();
|
|
||||||
alt p.token {
|
alt p.token {
|
||||||
token::EQ {
|
token::EQ {
|
||||||
|
// x = foo::bar
|
||||||
p.bump();
|
p.bump();
|
||||||
ret parse_full_import_name(p, p.get_str(i));
|
path = [parse_ident(p)];
|
||||||
}
|
while p.token == token::MOD_SEP {
|
||||||
_ { ret parse_rest_import_name(p, p.get_str(i), none); }
|
p.bump();
|
||||||
}
|
let id = parse_ident(p);
|
||||||
}
|
path += [id];
|
||||||
_ { p.fatal("expecting an identifier"); }
|
|
||||||
}
|
}
|
||||||
|
let hi = p.span.hi;
|
||||||
|
ret @spanned(lo, hi,
|
||||||
|
ast::view_path_simple(first_ident,
|
||||||
|
@path, p.get_id()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_enum_export(p:parser, tyname:ast::ident) -> ast::view_item_ {
|
|
||||||
let enumnames:[ast::import_ident] =
|
|
||||||
parse_seq(token::LBRACE, token::RBRACE,
|
|
||||||
seq_sep(token::COMMA), {|p| parse_import_ident(p) }, p).node;
|
|
||||||
let id = p.get_id();
|
|
||||||
if vec::is_empty(enumnames) {
|
|
||||||
ret ast::view_item_export_enum_none(tyname, id);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ret ast::view_item_export_enum_some(tyname, enumnames, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_export(p: parser) -> ast::view_item_ {
|
|
||||||
let first = parse_ident(p);
|
|
||||||
alt p.token {
|
|
||||||
token::MOD_SEP {
|
token::MOD_SEP {
|
||||||
|
// foo::bar or foo::{a,b,c} or foo::*
|
||||||
|
while p.token == token::MOD_SEP {
|
||||||
p.bump();
|
p.bump();
|
||||||
ret parse_enum_export(p, first);
|
|
||||||
|
alt p.token {
|
||||||
|
|
||||||
|
token::IDENT(i, _) {
|
||||||
|
p.bump();
|
||||||
|
path += [p.get_str(i)];
|
||||||
}
|
}
|
||||||
t {
|
|
||||||
if t == token::COMMA { p.bump(); }
|
// foo::bar::{a,b,c}
|
||||||
let ids =
|
token::LBRACE {
|
||||||
parse_seq_to_before_end(token::SEMI, seq_sep(token::COMMA),
|
let idents =
|
||||||
parse_ident, p);
|
parse_seq(token::LBRACE, token::RBRACE,
|
||||||
ret ast::view_item_export(vec::concat([[first], ids]), p.get_id());
|
seq_sep(token::COMMA),
|
||||||
|
parse_path_list_ident, p).node;
|
||||||
|
let hi = p.span.hi;
|
||||||
|
ret @spanned(lo, hi,
|
||||||
|
ast::view_path_list(@path, idents,
|
||||||
|
p.get_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// foo::bar::*
|
||||||
|
token::BINOP(token::STAR) {
|
||||||
|
p.bump();
|
||||||
|
let hi = p.span.hi;
|
||||||
|
ret @spanned(lo, hi,
|
||||||
|
ast::view_path_glob(@path,
|
||||||
|
p.get_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
_ { break; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ { }
|
||||||
|
}
|
||||||
|
let hi = p.span.hi;
|
||||||
|
let last = path[vec::len(path) - 1u];
|
||||||
|
ret @spanned(lo, hi,
|
||||||
|
ast::view_path_simple(last, @path,
|
||||||
|
p.get_id()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_view_paths(p: parser) -> [@ast::view_path] {
|
||||||
|
let vp = [parse_view_path(p)];
|
||||||
|
while p.token == token::COMMA {
|
||||||
|
p.bump();
|
||||||
|
vp += [parse_view_path(p)];
|
||||||
|
}
|
||||||
|
ret vp;
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_view_item(p: parser) -> @ast::view_item {
|
fn parse_view_item(p: parser) -> @ast::view_item {
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
|
@ -2562,8 +2503,12 @@ fn parse_view_item(p: parser) -> @ast::view_item {
|
||||||
if eat_word(p, "use") {
|
if eat_word(p, "use") {
|
||||||
parse_use(p)
|
parse_use(p)
|
||||||
} else if eat_word(p, "import") {
|
} else if eat_word(p, "import") {
|
||||||
parse_import(p)
|
ast::view_item_import(parse_view_paths(p))
|
||||||
} else if eat_word(p, "export") { parse_export(p) } else { fail };
|
} else if eat_word(p, "export") {
|
||||||
|
ast::view_item_export(parse_view_paths(p))
|
||||||
|
} else {
|
||||||
|
fail
|
||||||
|
};
|
||||||
let hi = p.span.lo;
|
let hi = p.span.lo;
|
||||||
expect(p, token::SEMI);
|
expect(p, token::SEMI);
|
||||||
ret @spanned(lo, hi, the_item);
|
ret @spanned(lo, hi, the_item);
|
||||||
|
|
|
@ -1333,6 +1333,44 @@ fn print_meta_item(s: ps, &&item: @ast::meta_item) {
|
||||||
end(s);
|
end(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_simple_path(s: ps, path: ast::simple_path) {
|
||||||
|
let first = true;
|
||||||
|
for id in path {
|
||||||
|
if first { first = false; } else { word(s.s, "::"); }
|
||||||
|
word(s.s, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_view_path(s: ps, &&vp: @ast::view_path) {
|
||||||
|
alt vp.node {
|
||||||
|
ast::view_path_simple(ident, path, _) {
|
||||||
|
if path[vec::len(*path)-1u] != ident {
|
||||||
|
word_space(s, ident);
|
||||||
|
word_space(s, "=");
|
||||||
|
}
|
||||||
|
print_simple_path(s, *path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast::view_path_glob(path, _) {
|
||||||
|
print_simple_path(s, *path);
|
||||||
|
word(s.s, "::*");
|
||||||
|
}
|
||||||
|
|
||||||
|
ast::view_path_list(path, idents, _) {
|
||||||
|
print_simple_path(s, *path);
|
||||||
|
word(s.s, "::{");
|
||||||
|
commasep(s, inconsistent, idents) {|s, w|
|
||||||
|
word(s.s, w.node.name)
|
||||||
|
}
|
||||||
|
word(s.s, "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_view_paths(s: ps, vps: [@ast::view_path]) {
|
||||||
|
commasep(s, inconsistent, vps, print_view_path);
|
||||||
|
}
|
||||||
|
|
||||||
fn print_view_item(s: ps, item: @ast::view_item) {
|
fn print_view_item(s: ps, item: @ast::view_item) {
|
||||||
hardbreak_if_not_bol(s);
|
hardbreak_if_not_bol(s);
|
||||||
maybe_print_comment(s, item.span.lo);
|
maybe_print_comment(s, item.span.lo);
|
||||||
|
@ -1346,59 +1384,20 @@ fn print_view_item(s: ps, item: @ast::view_item) {
|
||||||
pclose(s);
|
pclose(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::view_item_import(id, ids, _) {
|
|
||||||
|
ast::view_item_import(vps) {
|
||||||
head(s, "import");
|
head(s, "import");
|
||||||
if !str::eq(id, ids[vec::len(*ids) - 1u]) {
|
print_view_paths(s, vps);
|
||||||
word_space(s, id);
|
|
||||||
word_space(s, "=");
|
|
||||||
}
|
}
|
||||||
let first = true;
|
|
||||||
for elt: ast::ident in *ids {
|
ast::view_item_export(vps) {
|
||||||
if first { first = false; } else { word(s.s, "::"); }
|
|
||||||
word(s.s, elt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ast::view_item_import_from(mod_path, idents, _) {
|
|
||||||
head(s, "import");
|
|
||||||
for elt: ast::ident in *mod_path { word(s.s, elt); word(s.s, "::"); }
|
|
||||||
word(s.s, "{");
|
|
||||||
commasep(s, inconsistent, idents,
|
|
||||||
fn@(s: ps, w: ast::import_ident) { word(s.s, w.node.name) });
|
|
||||||
word(s.s, "}");
|
|
||||||
}
|
|
||||||
ast::view_item_import_glob(ids, _) {
|
|
||||||
head(s, "import");
|
|
||||||
let first = true;
|
|
||||||
for elt: ast::ident in *ids {
|
|
||||||
if first { first = false; } else { word(s.s, "::"); }
|
|
||||||
word(s.s, elt);
|
|
||||||
}
|
|
||||||
word(s.s, "::*");
|
|
||||||
}
|
|
||||||
ast::view_item_export(ids, _) {
|
|
||||||
head(s, "export");
|
head(s, "export");
|
||||||
commasep(s, inconsistent, ids,
|
print_view_paths(s, vps);
|
||||||
fn@(s: ps, &&w: ast::ident) { word(s.s, w) });
|
|
||||||
}
|
|
||||||
ast::view_item_export_enum_none(id, _) {
|
|
||||||
head(s, "export");
|
|
||||||
word(s.s, id);
|
|
||||||
word(s.s, "::{}");
|
|
||||||
}
|
|
||||||
ast::view_item_export_enum_some(id, ids, _) {
|
|
||||||
head(s, "export");
|
|
||||||
word(s.s, id);
|
|
||||||
word(s.s, "::{");
|
|
||||||
commasep(s, inconsistent, ids, fn@(s:ps, &&w: ast::import_ident) {
|
|
||||||
word(s.s, w.node.name) });
|
|
||||||
word(s.s, "}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
word(s.s, ";");
|
word(s.s, ";");
|
||||||
end(s); // end inner head-block
|
end(s); // end inner head-block
|
||||||
|
|
||||||
end(s); // end outer head-block
|
end(s); // end outer head-block
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
// error-pattern:at least one import is required
|
|
||||||
import spam::{};
|
|
||||||
|
|
||||||
mod spam {
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,2 +1,2 @@
|
||||||
// error-pattern:cannot path into import list
|
// error-pattern:expecting
|
||||||
import foo::{bar}::baz
|
import foo::{bar}::baz
|
|
@ -1,4 +1,4 @@
|
||||||
// error-pattern:can't rename import list
|
// error-pattern:expecting
|
||||||
|
|
||||||
import baz = foo::{bar};
|
import baz = foo::{bar};
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
// error-pattern:cannot path into a glob
|
// error-pattern:expecting
|
||||||
import foo::*::bar
|
import foo::*::bar
|
|
@ -1,4 +1,4 @@
|
||||||
// error-pattern:globbed imports can't be renamed
|
// error-pattern:expecting
|
||||||
|
|
||||||
import baz = foo::*;
|
import baz = foo::*;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue