rollup merge of #20179: eddyb/blind-items
Conflicts: src/librustc/diagnostics.rs src/librustdoc/clean/mod.rs src/librustdoc/html/format.rs src/libsyntax/parse/parser.rs
This commit is contained in:
commit
df1cddf20a
60 changed files with 1098 additions and 1520 deletions
|
@ -803,8 +803,9 @@ Crates contain [items](#items), each of which may have some number of
|
|||
## Items
|
||||
|
||||
```{.ebnf .gram}
|
||||
item : mod_item | fn_item | type_item | struct_item | enum_item
|
||||
| static_item | trait_item | impl_item | extern_block ;
|
||||
item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
|
||||
| struct_item | enum_item | static_item | trait_item | impl_item
|
||||
| extern_block ;
|
||||
```
|
||||
|
||||
An _item_ is a component of a crate; some module items can be defined in crate
|
||||
|
@ -818,6 +819,8 @@ execution, and may reside in read-only memory.
|
|||
|
||||
There are several kinds of item:
|
||||
|
||||
* [`extern crate` declarations](#extern-crate-declarations)
|
||||
* [`use` declarations](#use-declarations)
|
||||
* [modules](#modules)
|
||||
* [functions](#functions)
|
||||
* [type definitions](#type-definitions)
|
||||
|
@ -854,13 +857,10 @@ no notion of type abstraction: there are no first-class "forall" types.
|
|||
|
||||
```{.ebnf .gram}
|
||||
mod_item : "mod" ident ( ';' | '{' mod '}' );
|
||||
mod : [ view_item | item ] * ;
|
||||
mod : item * ;
|
||||
```
|
||||
|
||||
A module is a container for zero or more [view items](#view-items) and zero or
|
||||
more [items](#items). The view items manage the visibility of the items defined
|
||||
within the module, as well as the visibility of names from outside the module
|
||||
when referenced from inside the module.
|
||||
A module is a container for zero or more [items](#items).
|
||||
|
||||
A _module item_ is a module, surrounded in braces, named, and prefixed with the
|
||||
keyword `mod`. A module item introduces a new, named module into the tree of
|
||||
|
@ -918,19 +918,6 @@ mod thread {
|
|||
}
|
||||
```
|
||||
|
||||
#### View items
|
||||
|
||||
```{.ebnf .gram}
|
||||
view_item : extern_crate_decl | use_decl ;
|
||||
```
|
||||
|
||||
A view item manages the namespace of a module. View items do not define new
|
||||
items, but rather, simply change other items' visibility. There are two
|
||||
kinds of view items:
|
||||
|
||||
* [`extern crate` declarations](#extern-crate-declarations)
|
||||
* [`use` declarations](#use-declarations)
|
||||
|
||||
##### Extern crate declarations
|
||||
|
||||
```{.ebnf .gram}
|
||||
|
@ -2887,13 +2874,12 @@ Point3d {y: 0, z: 10, .. base};
|
|||
### Block expressions
|
||||
|
||||
```{.ebnf .gram}
|
||||
block_expr : '{' [ view_item ] *
|
||||
[ stmt ';' | item ] *
|
||||
block_expr : '{' [ stmt ';' | item ] *
|
||||
[ expr ] '}' ;
|
||||
```
|
||||
|
||||
A _block expression_ is similar to a module in terms of the declarations that
|
||||
are possible. Each block conceptually introduces a new namespace scope. View
|
||||
are possible. Each block conceptually introduces a new namespace scope. Use
|
||||
items can bring new names into scopes and declared items are in scope for only
|
||||
the block itself.
|
||||
|
||||
|
|
|
@ -77,6 +77,9 @@ register_diagnostics! {
|
|||
E0138,
|
||||
E0139,
|
||||
E0152,
|
||||
E0153,
|
||||
E0154,
|
||||
E0157,
|
||||
E0158,
|
||||
E0161,
|
||||
E0162,
|
||||
|
|
|
@ -1202,17 +1202,17 @@ impl LintPass for UnusedImportBraces {
|
|||
lint_array!(UNUSED_IMPORT_BRACES)
|
||||
}
|
||||
|
||||
fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
|
||||
match view_item.node {
|
||||
ast::ViewItemUse(ref view_path) => {
|
||||
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
|
||||
match item.node {
|
||||
ast::ItemUse(ref view_path) => {
|
||||
match view_path.node {
|
||||
ast::ViewPathList(_, ref items, _) => {
|
||||
ast::ViewPathList(_, ref items) => {
|
||||
if items.len() == 1 {
|
||||
match items[0].node {
|
||||
ast::PathListIdent {ref name, ..} => {
|
||||
let m = format!("braces around {} is unnecessary",
|
||||
token::get_ident(*name).get());
|
||||
cx.span_lint(UNUSED_IMPORT_BRACES, view_item.span,
|
||||
cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
|
||||
&m[]);
|
||||
},
|
||||
_ => ()
|
||||
|
@ -1709,22 +1709,6 @@ impl LintPass for Stability {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_view_item(&mut self, cx: &Context, item: &ast::ViewItem) {
|
||||
// compiler-generated `extern crate` statements have a dummy span.
|
||||
if item.span == DUMMY_SP { return }
|
||||
|
||||
let id = match item.node {
|
||||
ast::ViewItemExternCrate(_, _, id) => id,
|
||||
ast::ViewItemUse(..) => return,
|
||||
};
|
||||
let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(id) {
|
||||
Some(cnum) => cnum,
|
||||
None => return,
|
||||
};
|
||||
let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
|
||||
self.lint(cx, id, item.span);
|
||||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||
if self.is_internal(cx, e.span) { return; }
|
||||
|
||||
|
@ -1776,6 +1760,17 @@ impl LintPass for Stability {
|
|||
if self.is_internal(cx, item.span) { return }
|
||||
|
||||
match item.node {
|
||||
ast::ItemExternCrate(_) => {
|
||||
// compiler-generated `extern crate` items have a dummy span.
|
||||
if item.span == DUMMY_SP { return }
|
||||
|
||||
let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
|
||||
Some(cnum) => cnum,
|
||||
None => return,
|
||||
};
|
||||
let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
|
||||
self.lint(cx, id, item.span);
|
||||
}
|
||||
ast::ItemTrait(_, _, ref supertraits, _) => {
|
||||
for t in supertraits.iter() {
|
||||
if let ast::TraitTyParamBound(ref t, _) = *t {
|
||||
|
|
|
@ -580,14 +580,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, i: &ast::ViewItem) {
|
||||
self.with_lint_attrs(&i.attrs[], |cx| {
|
||||
run_lints!(cx, check_view_item, i);
|
||||
cx.visit_ids(|v| v.visit_view_item(i));
|
||||
visit::walk_view_item(cx, i);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, p: &ast::Pat) {
|
||||
run_lints!(self, check_pat, p);
|
||||
visit::walk_pat(self, p);
|
||||
|
|
|
@ -128,7 +128,6 @@ pub trait LintPass {
|
|||
fn check_crate(&mut self, _: &Context, _: &ast::Crate) { }
|
||||
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
|
||||
fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span, _: ast::NodeId) { }
|
||||
fn check_view_item(&mut self, _: &Context, _: &ast::ViewItem) { }
|
||||
fn check_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) { }
|
||||
fn check_item(&mut self, _: &Context, _: &ast::Item) { }
|
||||
fn check_local(&mut self, _: &Context, _: &ast::Local) { }
|
||||
|
|
|
@ -40,10 +40,6 @@ pub struct CrateReader<'a> {
|
|||
}
|
||||
|
||||
impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> {
|
||||
fn visit_view_item(&mut self, a: &ast::ViewItem) {
|
||||
self.process_view_item(a);
|
||||
visit::walk_view_item(self, a);
|
||||
}
|
||||
fn visit_item(&mut self, a: &ast::Item) {
|
||||
self.process_item(a);
|
||||
visit::walk_item(self, a);
|
||||
|
@ -64,9 +60,8 @@ fn dump_crates(cstore: &CStore) {
|
|||
})
|
||||
}
|
||||
|
||||
fn should_link(i: &ast::ViewItem) -> bool {
|
||||
fn should_link(i: &ast::Item) -> bool {
|
||||
!attr::contains_name(&i.attrs[], "no_link")
|
||||
|
||||
}
|
||||
|
||||
struct CrateInfo {
|
||||
|
@ -181,7 +176,35 @@ impl<'a> CrateReader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_view_item(&mut self, i: &ast::ViewItem) {
|
||||
fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
|
||||
match i.node {
|
||||
ast::ItemExternCrate(ref path_opt) => {
|
||||
let ident = token::get_ident(i.ident);
|
||||
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
|
||||
ident, path_opt);
|
||||
let name = match *path_opt {
|
||||
Some((ref path_str, _)) => {
|
||||
let name = path_str.get().to_string();
|
||||
validate_crate_name(Some(self.sess), &name[],
|
||||
Some(i.span));
|
||||
name
|
||||
}
|
||||
None => ident.get().to_string(),
|
||||
};
|
||||
Some(CrateInfo {
|
||||
ident: ident.get().to_string(),
|
||||
name: name,
|
||||
id: i.id,
|
||||
should_link: should_link(i),
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn process_item(&mut self, i: &ast::Item) {
|
||||
match i.node {
|
||||
ast::ItemExternCrate(_) => {
|
||||
if !should_link(i) {
|
||||
return;
|
||||
}
|
||||
|
@ -199,35 +222,6 @@ impl<'a> CrateReader<'a> {
|
|||
None => ()
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_crate_info(&self, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
match i.node {
|
||||
ast::ViewItemExternCrate(ident, ref path_opt, id) => {
|
||||
let ident = token::get_ident(ident);
|
||||
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
|
||||
ident, path_opt);
|
||||
let name = match *path_opt {
|
||||
Some((ref path_str, _)) => {
|
||||
let name = path_str.get().to_string();
|
||||
validate_crate_name(Some(self.sess), &name[],
|
||||
Some(i.span));
|
||||
name
|
||||
}
|
||||
None => ident.get().to_string(),
|
||||
};
|
||||
Some(CrateInfo {
|
||||
ident: ident.get().to_string(),
|
||||
name: name,
|
||||
id: id,
|
||||
should_link: should_link(i),
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
fn process_item(&self, i: &ast::Item) {
|
||||
match i.node {
|
||||
ast::ItemForeignMod(ref fm) => {
|
||||
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
|
||||
return;
|
||||
|
@ -533,7 +527,7 @@ impl<'a> CrateReader<'a> {
|
|||
|
||||
#[derive(Copy)]
|
||||
pub enum CrateOrString<'a> {
|
||||
Krate(&'a ast::ViewItem),
|
||||
Krate(&'a ast::Item),
|
||||
Str(&'a str)
|
||||
}
|
||||
|
||||
|
|
|
@ -1456,8 +1456,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||
rbml_w.end_tag();
|
||||
}
|
||||
}
|
||||
ast::ItemMac(..) => {
|
||||
// macros are encoded separately
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
|
||||
// these are encoded separately
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,8 +332,6 @@ impl Folder for NestedItemsDropper {
|
|||
}
|
||||
}).collect();
|
||||
let blk_sans_items = P(ast::Block {
|
||||
view_items: Vec::new(), // I don't know if we need the view_items
|
||||
// here, but it doesn't break tests!
|
||||
stmts: stmts_sans_items,
|
||||
expr: expr,
|
||||
id: id,
|
||||
|
|
|
@ -297,6 +297,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
|||
// These are normal, nothing reachable about these
|
||||
// inherently and their children are already in the
|
||||
// worklist, as determined by the privacy pass
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
|
||||
ast::ItemMod(..) | ast::ItemForeignMod(..) |
|
||||
ast::ItemImpl(..) | ast::ItemTrait(..) |
|
||||
|
|
|
@ -94,6 +94,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
|||
// Fn lifetimes get added in visit_fn below:
|
||||
visit::walk_item(this, item);
|
||||
}
|
||||
ast::ItemExternCrate(_) |
|
||||
ast::ItemUse(_) |
|
||||
ast::ItemMod(..) |
|
||||
ast::ItemMac(..) |
|
||||
ast::ItemForeignMod(..) |
|
||||
|
|
|
@ -73,8 +73,10 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
|
|||
// We need to error on `#[macro_use] extern crate` when it isn't at the
|
||||
// crate root, because `$crate` won't work properly. Identify these by
|
||||
// spans, because the crate map isn't set up yet.
|
||||
for vi in krate.module.view_items.iter() {
|
||||
loader.span_whitelist.insert(vi.span);
|
||||
for item in krate.module.items.iter() {
|
||||
if let ast::ItemExternCrate(_) = item.node {
|
||||
loader.span_whitelist.insert(item.span);
|
||||
}
|
||||
}
|
||||
|
||||
visit::walk_crate(&mut loader, krate);
|
||||
|
@ -91,18 +93,21 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
|
|||
|
||||
// note that macros aren't expanded yet, and therefore macros can't add plugins.
|
||||
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
||||
fn visit_view_item(&mut self, vi: &ast::ViewItem) {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
// We're only interested in `extern crate`.
|
||||
match vi.node {
|
||||
ast::ViewItemExternCrate(..) => (),
|
||||
_ => return,
|
||||
match item.node {
|
||||
ast::ItemExternCrate(_) => {}
|
||||
_ => {
|
||||
visit::walk_item(self, item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the attributes relating to macro / plugin loading.
|
||||
let mut plugin_attr = None;
|
||||
let mut macro_selection = Some(HashSet::new()); // None => load all
|
||||
let mut reexport = HashSet::new();
|
||||
for attr in vi.attrs.iter() {
|
||||
for attr in item.attrs.iter() {
|
||||
let mut used = true;
|
||||
match attr.name().get() {
|
||||
"phase" => {
|
||||
|
@ -155,7 +160,10 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
self.load_plugin(CrateOrString::Krate(vi), plugin_attr, macro_selection, Some(reexport))
|
||||
self.load_plugin(CrateOrString::Krate(item),
|
||||
plugin_attr,
|
||||
macro_selection,
|
||||
Some(reexport))
|
||||
}
|
||||
|
||||
fn visit_mac(&mut self, _: &ast::Mac) {
|
||||
|
|
|
@ -182,7 +182,6 @@ mod svh_visitor {
|
|||
SawLifetimeDef(token::InternedString),
|
||||
|
||||
SawMod,
|
||||
SawViewItem,
|
||||
SawForeignItem,
|
||||
SawItem,
|
||||
SawDecl,
|
||||
|
@ -430,19 +429,6 @@ mod svh_visitor {
|
|||
SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, i: &ViewItem) {
|
||||
// Two kinds of view items can affect the ABI for a crate:
|
||||
// exported `pub use` view items (since that may expose
|
||||
// items that downstream crates can call), and `use
|
||||
// foo::Trait`, since changing that may affect method
|
||||
// resolution.
|
||||
//
|
||||
// The simplest approach to handling both of the above is
|
||||
// just to adopt the same simple-minded (fine-grained)
|
||||
// hash that I am deploying elsewhere here.
|
||||
SawViewItem.hash(self.st); visit::walk_view_item(self, i)
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, i: &ForeignItem) {
|
||||
// FIXME (#14132) ideally we would incorporate privacy (or
|
||||
// perhaps reachability) somewhere here, so foreign items
|
||||
|
|
|
@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
|
|||
e: Option<P<ast::Expr>>) -> P<ast::Block> {
|
||||
P(ast::Block {
|
||||
expr: e,
|
||||
view_items: vec![], stmts: vec![], rules: rules,
|
||||
stmts: vec![], rules: rules,
|
||||
id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -200,6 +200,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
|||
}
|
||||
|
||||
return match it.node {
|
||||
ast::ItemUse(..) | ast::ItemExternCrate(..) |
|
||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
|
||||
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
|
||||
None
|
||||
|
|
|
@ -830,6 +830,38 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
|
||||
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
match item.node {
|
||||
ast::ItemUse(ref vpath) => {
|
||||
match vpath.node {
|
||||
ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
|
||||
ast::ViewPathList(ref prefix, ref list) => {
|
||||
for pid in list.iter() {
|
||||
match pid.node {
|
||||
ast::PathListIdent { id, name } => {
|
||||
debug!("privacy - ident item {}", id);
|
||||
let seg = ast::PathSegment {
|
||||
identifier: name,
|
||||
parameters: ast::PathParameters::none(),
|
||||
};
|
||||
let segs = vec![seg];
|
||||
let path = ast::Path {
|
||||
global: false,
|
||||
span: pid.span,
|
||||
segments: segs,
|
||||
};
|
||||
self.check_path(pid.span, id, &path);
|
||||
}
|
||||
ast::PathListMod { id } => {
|
||||
debug!("privacy - mod item {}", id);
|
||||
self.check_path(pid.span, id, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let orig_curitem = replace(&mut self.curitem, item.id);
|
||||
visit::walk_item(self, item);
|
||||
self.curitem = orig_curitem;
|
||||
|
@ -926,42 +958,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
|||
visit::walk_expr(self, expr);
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, a: &ast::ViewItem) {
|
||||
match a.node {
|
||||
ast::ViewItemExternCrate(..) => {}
|
||||
ast::ViewItemUse(ref vpath) => {
|
||||
match vpath.node {
|
||||
ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
|
||||
ast::ViewPathList(ref prefix, ref list, _) => {
|
||||
for pid in list.iter() {
|
||||
match pid.node {
|
||||
ast::PathListIdent { id, name } => {
|
||||
debug!("privacy - ident item {}", id);
|
||||
let seg = ast::PathSegment {
|
||||
identifier: name,
|
||||
parameters: ast::PathParameters::none(),
|
||||
};
|
||||
let segs = vec![seg];
|
||||
let path = ast::Path {
|
||||
global: false,
|
||||
span: pid.span,
|
||||
segments: segs,
|
||||
};
|
||||
self.check_path(pid.span, id, &path);
|
||||
}
|
||||
ast::PathListMod { id } => {
|
||||
debug!("privacy - mod item {}", id);
|
||||
self.check_path(pid.span, id, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_view_item(self, a);
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pattern: &ast::Pat) {
|
||||
// Foreign functions do not have their patterns mapped in the def_map,
|
||||
// and there's nothing really relevant there anyway, so don't bother
|
||||
|
@ -1069,23 +1065,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
|
|||
visit::walk_fn(self, fk, fd, b, s);
|
||||
self.in_fn = orig_in_fn;
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, i: &ast::ViewItem) {
|
||||
match i.vis {
|
||||
ast::Inherited => {}
|
||||
ast::Public => {
|
||||
if self.in_fn {
|
||||
self.tcx.sess.span_err(i.span, "unnecessary `pub`, imports \
|
||||
in functions are never \
|
||||
reachable");
|
||||
} else if let ast::ViewItemExternCrate(..) = i.node {
|
||||
self.tcx.sess.span_err(i.span, "`pub` visibility \
|
||||
is not allowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_view_item(self, i);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||
|
@ -1162,7 +1141,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
|
||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemMac(..) => {}
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1219,6 +1198,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemStatic(..) | ast::ItemConst(..) |
|
||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||
ast::ItemMac(..) => {}
|
||||
|
@ -1521,11 +1501,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||
|
||||
|
||||
// we don't need to introspect into these at all: an
|
||||
// expression/block context can't possibly contain exported
|
||||
// things, and neither do view_items. (Making them no-ops stops us
|
||||
// from traversing the whole AST without having to be super
|
||||
// careful about our `walk_...` calls above.)
|
||||
fn visit_view_item(&mut self, _: &ast::ViewItem) {}
|
||||
// expression/block context can't possibly contain exported things.
|
||||
// (Making them no-ops stops us from traversing the whole AST without
|
||||
// having to be super careful about our `walk_...` calls above.)
|
||||
fn visit_block(&mut self, _: &ast::Block) {}
|
||||
fn visit_expr(&mut self, _: &ast::Expr) {}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ use rustc::middle::subst::FnSpace;
|
|||
use syntax::ast::{Block, Crate};
|
||||
use syntax::ast::{DeclItem, DefId};
|
||||
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
|
||||
use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
|
||||
use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
|
||||
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
|
||||
use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
|
||||
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
|
||||
use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
|
||||
use syntax::ast::{PathListIdent, PathListMod};
|
||||
use syntax::ast::{Public, SelfStatic};
|
||||
|
@ -50,8 +50,7 @@ use syntax::ast::StructVariantKind;
|
|||
use syntax::ast::TupleVariantKind;
|
||||
use syntax::ast::TyObjectSum;
|
||||
use syntax::ast::{TypeImplItem, UnnamedField};
|
||||
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
|
||||
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::ast::{Visibility};
|
||||
use syntax::ast::TyPath;
|
||||
use syntax::ast;
|
||||
|
@ -238,11 +237,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
|
||||
// If the block has view items, we need an anonymous module.
|
||||
if block.view_items.len() > 0 {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check each statement.
|
||||
for statement in block.stmts.iter() {
|
||||
match statement.node {
|
||||
|
@ -262,7 +256,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// If we found neither view items nor items, we don't need to create
|
||||
// If we found no items, we don't need to create
|
||||
// an anonymous module.
|
||||
|
||||
return false;
|
||||
|
@ -280,6 +274,133 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||
|
||||
match item.node {
|
||||
ItemUse(ref view_path) => {
|
||||
// Extract and intern the module part of the path. For
|
||||
// globs and lists, the path is found directly in the AST;
|
||||
// for simple paths we have to munge the path a little.
|
||||
let module_path = match view_path.node {
|
||||
ViewPathSimple(_, ref full_path) => {
|
||||
full_path.segments
|
||||
.init()
|
||||
.iter().map(|ident| ident.identifier.name)
|
||||
.collect()
|
||||
}
|
||||
|
||||
ViewPathGlob(ref module_ident_path) |
|
||||
ViewPathList(ref module_ident_path, _) => {
|
||||
module_ident_path.segments
|
||||
.iter().map(|ident| ident.identifier.name).collect()
|
||||
}
|
||||
};
|
||||
|
||||
// Build up the import directives.
|
||||
let shadowable = item.attrs.iter().any(|attr| {
|
||||
attr.name() == token::get_name(special_idents::prelude_import.name)
|
||||
});
|
||||
let shadowable = if shadowable {
|
||||
Shadowable::Always
|
||||
} else {
|
||||
Shadowable::Never
|
||||
};
|
||||
|
||||
match view_path.node {
|
||||
ViewPathSimple(binding, ref full_path) => {
|
||||
let source_name =
|
||||
full_path.segments.last().unwrap().identifier.name;
|
||||
if token::get_name(source_name).get() == "mod" ||
|
||||
token::get_name(source_name).get() == "self" {
|
||||
self.resolve_error(view_path.span,
|
||||
"`self` imports are only allowed within a { } list");
|
||||
}
|
||||
|
||||
let subclass = SingleImport(binding.name,
|
||||
source_name);
|
||||
self.build_import_directive(&**parent,
|
||||
module_path,
|
||||
subclass,
|
||||
view_path.span,
|
||||
item.id,
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
ViewPathList(_, ref source_items) => {
|
||||
// Make sure there's at most one `mod` import in the list.
|
||||
let mod_spans = source_items.iter().filter_map(|item| match item.node {
|
||||
PathListMod { .. } => Some(item.span),
|
||||
_ => None
|
||||
}).collect::<Vec<Span>>();
|
||||
if mod_spans.len() > 1 {
|
||||
self.resolve_error(mod_spans[0],
|
||||
"`self` import can only appear once in the list");
|
||||
for other_span in mod_spans.iter().skip(1) {
|
||||
self.session.span_note(*other_span,
|
||||
"another `self` import appears here");
|
||||
}
|
||||
}
|
||||
|
||||
for source_item in source_items.iter() {
|
||||
let (module_path, name) = match source_item.node {
|
||||
PathListIdent { name, .. } =>
|
||||
(module_path.clone(), name.name),
|
||||
PathListMod { .. } => {
|
||||
let name = match module_path.last() {
|
||||
Some(name) => *name,
|
||||
None => {
|
||||
self.resolve_error(source_item.span,
|
||||
"`self` import can only appear in an import list \
|
||||
with a non-empty prefix");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let module_path = module_path.init();
|
||||
(module_path.to_vec(), name)
|
||||
}
|
||||
};
|
||||
self.build_import_directive(
|
||||
&**parent,
|
||||
module_path,
|
||||
SingleImport(name, name),
|
||||
source_item.span,
|
||||
source_item.node.id(),
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
}
|
||||
ViewPathGlob(_) => {
|
||||
self.build_import_directive(&**parent,
|
||||
module_path,
|
||||
GlobImport,
|
||||
view_path.span,
|
||||
item.id,
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
}
|
||||
parent.clone()
|
||||
}
|
||||
|
||||
ItemExternCrate(_) => {
|
||||
// n.b. we don't need to look at the path option here, because cstore already did
|
||||
for &crate_id in self.session.cstore
|
||||
.find_extern_mod_stmt_cnum(item.id).iter() {
|
||||
let def_id = DefId { krate: crate_id, node: 0 };
|
||||
self.external_exports.insert(def_id);
|
||||
let parent_link = ModuleParentLink(parent.downgrade(), name);
|
||||
let external_module = Rc::new(Module::new(parent_link,
|
||||
Some(def_id),
|
||||
NormalModuleKind,
|
||||
false,
|
||||
true));
|
||||
debug!("(build reduced graph for item) found extern `{}`",
|
||||
self.module_to_string(&*external_module));
|
||||
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
|
||||
parent.external_module_children.borrow_mut()
|
||||
.insert(name, external_module.clone());
|
||||
self.build_reduced_graph_for_external_crate(&external_module);
|
||||
}
|
||||
parent.clone()
|
||||
}
|
||||
|
||||
ItemMod(..) => {
|
||||
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
|
||||
|
||||
|
@ -650,145 +771,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
|||
variant.span, PUBLIC | IMPORTABLE);
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one 'view item'. View items consist
|
||||
/// of imports and use directives.
|
||||
fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc<Module>) {
|
||||
match view_item.node {
|
||||
ViewItemUse(ref view_path) => {
|
||||
// Extract and intern the module part of the path. For
|
||||
// globs and lists, the path is found directly in the AST;
|
||||
// for simple paths we have to munge the path a little.
|
||||
let module_path = match view_path.node {
|
||||
ViewPathSimple(_, ref full_path, _) => {
|
||||
full_path.segments
|
||||
.init()
|
||||
.iter().map(|ident| ident.identifier.name)
|
||||
.collect()
|
||||
}
|
||||
|
||||
ViewPathGlob(ref module_ident_path, _) |
|
||||
ViewPathList(ref module_ident_path, _, _) => {
|
||||
module_ident_path.segments
|
||||
.iter().map(|ident| ident.identifier.name).collect()
|
||||
}
|
||||
};
|
||||
|
||||
// Build up the import directives.
|
||||
let is_public = view_item.vis == ast::Public;
|
||||
let shadowable =
|
||||
view_item.attrs
|
||||
.iter()
|
||||
.any(|attr| {
|
||||
attr.name() == token::get_name(
|
||||
special_idents::prelude_import.name)
|
||||
});
|
||||
let shadowable = if shadowable {
|
||||
Shadowable::Always
|
||||
} else {
|
||||
Shadowable::Never
|
||||
};
|
||||
|
||||
match view_path.node {
|
||||
ViewPathSimple(binding, ref full_path, id) => {
|
||||
let source_name =
|
||||
full_path.segments.last().unwrap().identifier.name;
|
||||
if token::get_name(source_name).get() == "mod" ||
|
||||
token::get_name(source_name).get() == "self" {
|
||||
self.resolve_error(view_path.span,
|
||||
"`self` imports are only allowed within a { } list");
|
||||
}
|
||||
|
||||
let subclass = SingleImport(binding.name,
|
||||
source_name);
|
||||
self.build_import_directive(&**parent,
|
||||
module_path,
|
||||
subclass,
|
||||
view_path.span,
|
||||
id,
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
ViewPathList(_, ref source_items, _) => {
|
||||
// Make sure there's at most one `mod` import in the list.
|
||||
let mod_spans = source_items.iter().filter_map(|item| match item.node {
|
||||
PathListMod { .. } => Some(item.span),
|
||||
_ => None
|
||||
}).collect::<Vec<Span>>();
|
||||
if mod_spans.len() > 1 {
|
||||
self.resolve_error(mod_spans[0],
|
||||
"`self` import can only appear once in the list");
|
||||
for other_span in mod_spans.iter().skip(1) {
|
||||
self.session.span_note(*other_span,
|
||||
"another `self` import appears here");
|
||||
}
|
||||
}
|
||||
|
||||
for source_item in source_items.iter() {
|
||||
let (module_path, name) = match source_item.node {
|
||||
PathListIdent { name, .. } =>
|
||||
(module_path.clone(), name.name),
|
||||
PathListMod { .. } => {
|
||||
let name = match module_path.last() {
|
||||
Some(name) => *name,
|
||||
None => {
|
||||
self.resolve_error(source_item.span,
|
||||
"`self` import can only appear in an import list \
|
||||
with a non-empty prefix");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let module_path = module_path.init();
|
||||
(module_path.to_vec(), name)
|
||||
}
|
||||
};
|
||||
self.build_import_directive(
|
||||
&**parent,
|
||||
module_path,
|
||||
SingleImport(name, name),
|
||||
source_item.span,
|
||||
source_item.node.id(),
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
}
|
||||
ViewPathGlob(_, id) => {
|
||||
self.build_import_directive(&**parent,
|
||||
module_path,
|
||||
GlobImport,
|
||||
view_path.span,
|
||||
id,
|
||||
is_public,
|
||||
shadowable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ViewItemExternCrate(name, _, node_id) => {
|
||||
// n.b. we don't need to look at the path option here, because cstore already did
|
||||
for &crate_id in self.session.cstore
|
||||
.find_extern_mod_stmt_cnum(node_id).iter() {
|
||||
let def_id = DefId { krate: crate_id, node: 0 };
|
||||
self.external_exports.insert(def_id);
|
||||
let parent_link = ModuleParentLink(parent.downgrade(), name.name);
|
||||
let external_module = Rc::new(Module::new(parent_link,
|
||||
Some(def_id),
|
||||
NormalModuleKind,
|
||||
false,
|
||||
true));
|
||||
debug!("(build reduced graph for item) found extern `{}`",
|
||||
self.module_to_string(&*external_module));
|
||||
self.check_for_conflicts_between_external_crates(
|
||||
&**parent,
|
||||
name.name,
|
||||
view_item.span);
|
||||
parent.external_module_children.borrow_mut()
|
||||
.insert(name.name, external_module.clone());
|
||||
self.build_reduced_graph_for_external_crate(&external_module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one foreign item.
|
||||
fn build_reduced_graph_for_foreign_item<F>(&mut self,
|
||||
foreign_item: &ForeignItem,
|
||||
|
@ -1270,10 +1252,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
|
|||
})
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, view_item: &ViewItem) {
|
||||
self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, block: &Block) {
|
||||
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
|
||||
let old_parent = replace(&mut self.parent, np);
|
||||
|
|
|
@ -25,7 +25,6 @@ use Namespace::{TypeNS, ValueNS};
|
|||
use rustc::lint;
|
||||
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
|
||||
use syntax::ast;
|
||||
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
|
||||
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::codemap::{Span, DUMMY_SP};
|
||||
use syntax::visit::{self, Visitor};
|
||||
|
@ -109,53 +108,54 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
|
||||
fn visit_view_item(&mut self, vi: &ViewItem) {
|
||||
fn visit_item(&mut self, item: &ast::Item) {
|
||||
// Ignore is_public import statements because there's no way to be sure
|
||||
// whether they're used or not. Also ignore imports with a dummy span
|
||||
// because this means that they were generated in some fashion by the
|
||||
// compiler and we don't need to consider them.
|
||||
if vi.vis == ast::Public || vi.span == DUMMY_SP {
|
||||
visit::walk_view_item(self, vi);
|
||||
if item.vis == ast::Public || item.span == DUMMY_SP {
|
||||
visit::walk_item(self, item);
|
||||
return;
|
||||
}
|
||||
|
||||
match vi.node {
|
||||
ViewItemExternCrate(_, _, id) => {
|
||||
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
|
||||
match item.node {
|
||||
ast::ItemExternCrate(_) => {
|
||||
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
|
||||
if !self.used_crates.contains(&crate_num) {
|
||||
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
|
||||
id,
|
||||
vi.span,
|
||||
item.id,
|
||||
item.span,
|
||||
"unused extern crate".to_string());
|
||||
}
|
||||
}
|
||||
},
|
||||
ViewItemUse(ref p) => {
|
||||
ast::ItemUse(ref p) => {
|
||||
match p.node {
|
||||
ViewPathSimple(_, _, id) => {
|
||||
self.finalize_import(id, p.span)
|
||||
ViewPathSimple(_, _) => {
|
||||
self.finalize_import(item.id, p.span)
|
||||
}
|
||||
|
||||
ViewPathList(_, ref list, _) => {
|
||||
ViewPathList(_, ref list) => {
|
||||
for i in list.iter() {
|
||||
self.finalize_import(i.node.id(), i.span);
|
||||
}
|
||||
}
|
||||
ViewPathGlob(_, id) => {
|
||||
if !self.used_imports.contains(&(id, TypeNS)) &&
|
||||
!self.used_imports.contains(&(id, ValueNS)) {
|
||||
ViewPathGlob(_) => {
|
||||
if !self.used_imports.contains(&(item.id, TypeNS)) &&
|
||||
!self.used_imports.contains(&(item.id, ValueNS)) {
|
||||
self.session
|
||||
.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||
id,
|
||||
item.id,
|
||||
p.span,
|
||||
"unused import".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_view_item(self, vi);
|
||||
visit::walk_item(self, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,10 +65,10 @@ use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
|||
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
|
||||
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
|
||||
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
|
||||
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
|
||||
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
|
||||
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
|
||||
use syntax::ast::{MethodImplItem, Mod, Name, NodeId};
|
||||
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
|
||||
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
|
||||
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
|
||||
use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
|
||||
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
||||
use syntax::ast::{PatRange, PatStruct, Path};
|
||||
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
|
||||
|
@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_trait_name(&self, did: DefId) -> Name {
|
||||
if did.krate == LOCAL_CRATE {
|
||||
if did.krate == ast::LOCAL_CRATE {
|
||||
self.ast_map.expect_item(did.node).ident.name
|
||||
} else {
|
||||
csearch::get_trait_name(&self.session.cstore, did)
|
||||
|
@ -1752,10 +1752,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
import_span: Span,
|
||||
name: Name,
|
||||
namespace: Namespace) {
|
||||
if self.session.features.borrow().import_shadowing {
|
||||
return
|
||||
}
|
||||
|
||||
debug!("check_for_conflicting_import: {}; target exists: {}",
|
||||
token::get_name(name).get(),
|
||||
target.is_some());
|
||||
|
@ -1795,10 +1791,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
&ImportResolution,
|
||||
import_span: Span,
|
||||
name: Name) {
|
||||
if self.session.features.borrow().import_shadowing {
|
||||
return
|
||||
}
|
||||
|
||||
// First, check for conflicts between imports and `extern crate`s.
|
||||
if module.external_module_children
|
||||
.borrow()
|
||||
|
@ -1892,10 +1884,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module: &Module,
|
||||
name: Name,
|
||||
span: Span) {
|
||||
if self.session.features.borrow().import_shadowing {
|
||||
return
|
||||
}
|
||||
|
||||
if module.external_module_children.borrow().contains_key(&name) {
|
||||
span_err!(self.session, span, E0259,
|
||||
"an external crate named `{}` has already \
|
||||
|
@ -1909,10 +1897,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
module: &Module,
|
||||
name: Name,
|
||||
span: Span) {
|
||||
if self.session.features.borrow().import_shadowing {
|
||||
return
|
||||
}
|
||||
|
||||
if module.external_module_children.borrow().contains_key(&name) {
|
||||
span_err!(self.session, span, E0260,
|
||||
"the name `{}` conflicts with an external \
|
||||
|
@ -2984,7 +2968,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
ItemMac(..) => {
|
||||
ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
|
||||
// do nothing, these are just around to be encoded
|
||||
}
|
||||
}
|
||||
|
@ -3527,6 +3511,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Check for imports appearing after non-item statements.
|
||||
let mut found_non_item = false;
|
||||
for statement in block.stmts.iter() {
|
||||
if let ast::StmtDecl(ref declaration, _) = statement.node {
|
||||
if let ast::DeclItem(ref i) = declaration.node {
|
||||
match i.node {
|
||||
ItemExternCrate(_) | ItemUse(_) if found_non_item => {
|
||||
span_err!(self.session, i.span, E0154,
|
||||
"imports are not allowed after non-item statements");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
found_non_item = true
|
||||
}
|
||||
} else {
|
||||
found_non_item = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Descend into the block.
|
||||
visit::walk_block(self, block);
|
||||
|
||||
|
|
|
@ -1037,6 +1037,110 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemUse(ref use_item) => {
|
||||
match use_item.node {
|
||||
ast::ViewPathSimple(ident, ref path) => {
|
||||
let sub_span = self.span.span_for_last_ident(path.span);
|
||||
let mod_id = match self.lookup_type_ref(item.id) {
|
||||
Some(def_id) => {
|
||||
match self.lookup_def_kind(item.id, path.span) {
|
||||
Some(kind) => self.fmt.ref_str(kind,
|
||||
path.span,
|
||||
sub_span,
|
||||
def_id,
|
||||
self.cur_scope),
|
||||
None => {},
|
||||
}
|
||||
Some(def_id)
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
// 'use' always introduces an alias, if there is not an explicit
|
||||
// one, there is an implicit one.
|
||||
let sub_span =
|
||||
match self.span.sub_span_after_keyword(use_item.span, keywords::As) {
|
||||
Some(sub_span) => Some(sub_span),
|
||||
None => sub_span,
|
||||
};
|
||||
|
||||
self.fmt.use_alias_str(path.span,
|
||||
sub_span,
|
||||
item.id,
|
||||
mod_id,
|
||||
get_ident(ident).get(),
|
||||
self.cur_scope);
|
||||
self.write_sub_paths_truncated(path);
|
||||
}
|
||||
ast::ViewPathGlob(ref path) => {
|
||||
// Make a comma-separated list of names of imported modules.
|
||||
let mut name_string = String::new();
|
||||
let glob_map = &self.analysis.glob_map;
|
||||
let glob_map = glob_map.as_ref().unwrap();
|
||||
if glob_map.contains_key(&item.id) {
|
||||
for n in glob_map[item.id].iter() {
|
||||
if name_string.len() > 0 {
|
||||
name_string.push_str(", ");
|
||||
}
|
||||
name_string.push_str(n.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
let sub_span = self.span.sub_span_of_token(path.span,
|
||||
token::BinOp(token::Star));
|
||||
self.fmt.use_glob_str(path.span,
|
||||
sub_span,
|
||||
item.id,
|
||||
name_string.as_slice(),
|
||||
self.cur_scope);
|
||||
self.write_sub_paths(path);
|
||||
}
|
||||
ast::ViewPathList(ref path, ref list) => {
|
||||
for plid in list.iter() {
|
||||
match plid.node {
|
||||
ast::PathListIdent { id, .. } => {
|
||||
match self.lookup_type_ref(id) {
|
||||
Some(def_id) =>
|
||||
match self.lookup_def_kind(id, plid.span) {
|
||||
Some(kind) => {
|
||||
self.fmt.ref_str(
|
||||
kind, plid.span,
|
||||
Some(plid.span),
|
||||
def_id, self.cur_scope);
|
||||
}
|
||||
None => ()
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
},
|
||||
ast::PathListMod { .. } => ()
|
||||
}
|
||||
}
|
||||
|
||||
self.write_sub_paths(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ItemExternCrate(ref s) => {
|
||||
let name = get_ident(item.ident);
|
||||
let name = name.get();
|
||||
let s = match *s {
|
||||
Some((ref s, _)) => s.get().to_string(),
|
||||
None => name.to_string(),
|
||||
};
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Crate);
|
||||
let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
|
||||
Some(cnum) => cnum,
|
||||
None => 0,
|
||||
};
|
||||
self.fmt.extern_crate_str(item.span,
|
||||
sub_span,
|
||||
item.id,
|
||||
cnum,
|
||||
name,
|
||||
&s[],
|
||||
self.cur_scope);
|
||||
}
|
||||
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
|
||||
self.process_fn(item, &**decl, ty_params, &**body),
|
||||
ast::ItemStatic(ref typ, mt, ref expr) =>
|
||||
|
@ -1160,119 +1264,6 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, i: &ast::ViewItem) {
|
||||
if generated_code(i.span) {
|
||||
return
|
||||
}
|
||||
|
||||
match i.node {
|
||||
ast::ViewItemUse(ref item) => {
|
||||
match item.node {
|
||||
ast::ViewPathSimple(ident, ref path, id) => {
|
||||
let sub_span = self.span.span_for_last_ident(path.span);
|
||||
let mod_id = match self.lookup_type_ref(id) {
|
||||
Some(def_id) => {
|
||||
match self.lookup_def_kind(id, path.span) {
|
||||
Some(kind) => self.fmt.ref_str(kind,
|
||||
path.span,
|
||||
sub_span,
|
||||
def_id,
|
||||
self.cur_scope),
|
||||
None => {},
|
||||
}
|
||||
Some(def_id)
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
// 'use' always introduces an alias, if there is not an explicit
|
||||
// one, there is an implicit one.
|
||||
let sub_span =
|
||||
match self.span.sub_span_after_keyword(item.span, keywords::As) {
|
||||
Some(sub_span) => Some(sub_span),
|
||||
None => sub_span,
|
||||
};
|
||||
|
||||
self.fmt.use_alias_str(path.span,
|
||||
sub_span,
|
||||
id,
|
||||
mod_id,
|
||||
get_ident(ident).get(),
|
||||
self.cur_scope);
|
||||
self.write_sub_paths_truncated(path);
|
||||
}
|
||||
ast::ViewPathGlob(ref path, id) => {
|
||||
// Make a comma-separated list of names of imported modules.
|
||||
let mut name_string = String::new();
|
||||
let glob_map = &self.analysis.glob_map;
|
||||
let glob_map = glob_map.as_ref().unwrap();
|
||||
if glob_map.contains_key(&id) {
|
||||
for n in glob_map[id].iter() {
|
||||
if name_string.len() > 0 {
|
||||
name_string.push_str(", ");
|
||||
}
|
||||
name_string.push_str(n.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
let sub_span = self.span.sub_span_of_token(path.span,
|
||||
token::BinOp(token::Star));
|
||||
self.fmt.use_glob_str(path.span,
|
||||
sub_span,
|
||||
id,
|
||||
name_string.as_slice(),
|
||||
self.cur_scope);
|
||||
self.write_sub_paths(path);
|
||||
}
|
||||
ast::ViewPathList(ref path, ref list, _) => {
|
||||
for plid in list.iter() {
|
||||
match plid.node {
|
||||
ast::PathListIdent { id, .. } => {
|
||||
match self.lookup_type_ref(id) {
|
||||
Some(def_id) =>
|
||||
match self.lookup_def_kind(id, plid.span) {
|
||||
Some(kind) => {
|
||||
self.fmt.ref_str(
|
||||
kind, plid.span,
|
||||
Some(plid.span),
|
||||
def_id, self.cur_scope);
|
||||
}
|
||||
None => ()
|
||||
},
|
||||
None => ()
|
||||
}
|
||||
},
|
||||
ast::PathListMod { .. } => ()
|
||||
}
|
||||
}
|
||||
|
||||
self.write_sub_paths(path);
|
||||
}
|
||||
}
|
||||
},
|
||||
ast::ViewItemExternCrate(ident, ref s, id) => {
|
||||
let name = get_ident(ident);
|
||||
let name = name.get();
|
||||
let s = match *s {
|
||||
Some((ref s, _)) => s.get().to_string(),
|
||||
None => name.to_string(),
|
||||
};
|
||||
let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate);
|
||||
let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) {
|
||||
Some(cnum) => cnum,
|
||||
None => 0,
|
||||
};
|
||||
self.fmt.extern_crate_str(i.span,
|
||||
sub_span,
|
||||
id,
|
||||
cnum,
|
||||
name,
|
||||
&s[],
|
||||
self.cur_scope);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_ty(&mut self, t: &ast::Ty) {
|
||||
if generated_code(t.span) {
|
||||
return
|
||||
|
|
|
@ -274,7 +274,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
ast_map::NodeArg(..) |
|
||||
ast_map::NodeBlock(..) |
|
||||
ast_map::NodePat(..) |
|
||||
ast_map::NodeViewItem(..) |
|
||||
ast_map::NodeLocal(..) => {
|
||||
ccx.sess().bug(&format!("can't monomorphize a {:?}",
|
||||
map_node)[])
|
||||
|
|
|
@ -555,6 +555,7 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) {
|
|||
debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
|
||||
match it.node {
|
||||
// These don't define types.
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
|
||||
ast::ItemEnum(ref enum_definition, ref generics) => {
|
||||
let scheme = ty_of_item(ccx, it);
|
||||
|
@ -1004,6 +1005,7 @@ fn ty_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item)
|
|||
tcx.tcache.borrow_mut().insert(local_def(it.id), scheme.clone());
|
||||
return scheme;
|
||||
}
|
||||
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||
ast::ItemImpl(..) | ast::ItemMod(_) |
|
||||
ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
|
||||
}
|
||||
|
|
|
@ -380,6 +380,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
|||
visit::walk_item(self, item);
|
||||
}
|
||||
|
||||
ast::ItemExternCrate(_) |
|
||||
ast::ItemUse(_) |
|
||||
ast::ItemImpl(..) |
|
||||
ast::ItemStatic(..) |
|
||||
ast::ItemConst(..) |
|
||||
|
@ -532,6 +534,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ast::ItemExternCrate(_) |
|
||||
ast::ItemUse(_) |
|
||||
ast::ItemStatic(..) |
|
||||
ast::ItemConst(..) |
|
||||
ast::ItemFn(..) |
|
||||
|
|
|
@ -18,8 +18,7 @@ pub use self::TypeKind::*;
|
|||
pub use self::StructField::*;
|
||||
pub use self::VariantKind::*;
|
||||
pub use self::Mutability::*;
|
||||
pub use self::ViewItemInner::*;
|
||||
pub use self::ViewPath::*;
|
||||
pub use self::Import::*;
|
||||
pub use self::ItemEnum::*;
|
||||
pub use self::Attribute::*;
|
||||
pub use self::TyParamBound::*;
|
||||
|
@ -315,6 +314,8 @@ impl Item {
|
|||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum ItemEnum {
|
||||
ExternCrateItem(String, Option<String>),
|
||||
ImportItem(Import),
|
||||
StructItem(Struct),
|
||||
EnumItem(Enum),
|
||||
FunctionItem(Function),
|
||||
|
@ -324,8 +325,6 @@ pub enum ItemEnum {
|
|||
ConstantItem(Constant),
|
||||
TraitItem(Trait),
|
||||
ImplItem(Impl),
|
||||
/// `use` and `extern crate`
|
||||
ViewItemItem(ViewItem),
|
||||
/// A method signature only. Used for required methods in traits (ie,
|
||||
/// non-default-methods).
|
||||
TyMethodItem(TyMethod),
|
||||
|
@ -355,27 +354,21 @@ impl Clean<Item> for doctree::Module {
|
|||
} else {
|
||||
"".to_string()
|
||||
};
|
||||
let mut foreigns = Vec::new();
|
||||
for subforeigns in self.foreigns.clean(cx).into_iter() {
|
||||
for foreign in subforeigns.into_iter() {
|
||||
foreigns.push(foreign)
|
||||
}
|
||||
}
|
||||
let items: Vec<Vec<Item> > = vec!(
|
||||
self.structs.clean(cx),
|
||||
self.enums.clean(cx),
|
||||
self.fns.clean(cx),
|
||||
foreigns,
|
||||
self.mods.clean(cx),
|
||||
self.typedefs.clean(cx),
|
||||
self.statics.clean(cx),
|
||||
self.constants.clean(cx),
|
||||
self.traits.clean(cx),
|
||||
self.impls.clean(cx),
|
||||
self.view_items.clean(cx).into_iter()
|
||||
.flat_map(|s| s.into_iter()).collect(),
|
||||
self.macros.clean(cx),
|
||||
);
|
||||
let items: Vec<Item> =
|
||||
self.extern_crates.iter().map(|x| x.clean(cx))
|
||||
.chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||
.chain(self.structs.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.enums.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.fns.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||
.chain(self.mods.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.typedefs.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.statics.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.constants.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.traits.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.impls.iter().map(|x| x.clean(cx)))
|
||||
.chain(self.macros.iter().map(|x| x.clean(cx)))
|
||||
.collect();
|
||||
|
||||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
|
@ -401,9 +394,7 @@ impl Clean<Item> for doctree::Module {
|
|||
def_id: ast_util::local_def(self.id),
|
||||
inner: ModuleItem(Module {
|
||||
is_crate: self.is_crate,
|
||||
items: items.iter()
|
||||
.flat_map(|x| x.iter().map(|x| (*x).clone()))
|
||||
.collect(),
|
||||
items: items
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -2143,12 +2134,21 @@ impl Clean<Item> for doctree::Impl {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct ViewItem {
|
||||
pub inner: ViewItemInner,
|
||||
impl Clean<Item> for doctree::ExternCrate {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clean<Vec<Item>> for ast::ViewItem {
|
||||
impl Clean<Vec<Item>> for doctree::Import {
|
||||
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
||||
// We consider inlining the documentation of `pub use` statements, but we
|
||||
// forcefully don't inline if this is not public or if the
|
||||
|
@ -2159,81 +2159,63 @@ impl Clean<Vec<Item>> for ast::ViewItem {
|
|||
None => false,
|
||||
}
|
||||
});
|
||||
let convert = |&: node: &ast::ViewItem_| {
|
||||
Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.span.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ViewItemItem(ViewItem { inner: node.clean(cx) }),
|
||||
let (mut ret, inner) = match self.node {
|
||||
ast::ViewPathGlob(ref p) => {
|
||||
(vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
|
||||
}
|
||||
};
|
||||
let mut ret = Vec::new();
|
||||
match self.node {
|
||||
ast::ViewItemUse(ref path) if !denied => {
|
||||
match path.node {
|
||||
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
|
||||
ast::ViewPathList(ref a, ref list, ref b) => {
|
||||
ast::ViewPathList(ref p, ref list) => {
|
||||
// Attempt to inline all reexported items, but be sure
|
||||
// to keep any non-inlineable reexports so they can be
|
||||
// listed in the documentation.
|
||||
let remaining = list.iter().filter(|path| {
|
||||
let mut ret = vec![];
|
||||
let remaining = if !denied {
|
||||
let mut remaining = vec![];
|
||||
for path in list.iter() {
|
||||
match inline::try_inline(cx, path.node.id(), None) {
|
||||
Some(items) => {
|
||||
ret.extend(items.into_iter()); false
|
||||
ret.extend(items.into_iter());
|
||||
}
|
||||
None => true,
|
||||
}
|
||||
}).map(|a| a.clone()).collect::<Vec<ast::PathListItem>>();
|
||||
if remaining.len() > 0 {
|
||||
let path = ast::ViewPathList(a.clone(),
|
||||
remaining,
|
||||
b.clone());
|
||||
let path = syntax::codemap::dummy_spanned(path);
|
||||
ret.push(convert(&ast::ViewItemUse(P(path))));
|
||||
}
|
||||
}
|
||||
ast::ViewPathSimple(ident, _, id) => {
|
||||
match inline::try_inline(cx, id, Some(ident)) {
|
||||
Some(items) => ret.extend(items.into_iter()),
|
||||
None => ret.push(convert(&self.node)),
|
||||
None => {
|
||||
remaining.push(path.clean(cx));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ref n => ret.push(convert(n)),
|
||||
}
|
||||
remaining
|
||||
} else {
|
||||
list.clean(cx)
|
||||
};
|
||||
if remaining.is_empty() {
|
||||
return ret;
|
||||
}
|
||||
(ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id),
|
||||
remaining))
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum ViewItemInner {
|
||||
ExternCrate(String, Option<String>, ast::NodeId),
|
||||
Import(ViewPath)
|
||||
ast::ViewPathSimple(i, ref p) => {
|
||||
if !denied {
|
||||
match inline::try_inline(cx, self.id, Some(i)) {
|
||||
Some(items) => return items,
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
(vec![], SimpleImport(i.clean(cx),
|
||||
resolve_use_source(cx, p.clean(cx), self.id)))
|
||||
}
|
||||
|
||||
impl Clean<ViewItemInner> for ast::ViewItem_ {
|
||||
fn clean(&self, cx: &DocContext) -> ViewItemInner {
|
||||
match self {
|
||||
&ast::ViewItemExternCrate(ref i, ref p, ref id) => {
|
||||
let string = match *p {
|
||||
None => None,
|
||||
Some((ref x, _)) => Some(x.get().to_string()),
|
||||
};
|
||||
ExternCrate(i.clean(cx), string, *id)
|
||||
}
|
||||
&ast::ViewItemUse(ref vp) => {
|
||||
Import(vp.clean(cx))
|
||||
}
|
||||
}
|
||||
ret.push(Item {
|
||||
name: None,
|
||||
attrs: self.attrs.clean(cx),
|
||||
source: self.whence.clean(cx),
|
||||
def_id: ast_util::local_def(0),
|
||||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
inner: ImportItem(inner)
|
||||
});
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub enum ViewPath {
|
||||
pub enum Import {
|
||||
// use source as str;
|
||||
SimpleImport(String, ImportSource),
|
||||
// use source::*;
|
||||
|
@ -2248,21 +2230,6 @@ pub struct ImportSource {
|
|||
pub did: Option<ast::DefId>,
|
||||
}
|
||||
|
||||
impl Clean<ViewPath> for ast::ViewPath {
|
||||
fn clean(&self, cx: &DocContext) -> ViewPath {
|
||||
match self.node {
|
||||
ast::ViewPathSimple(ref i, ref p, id) =>
|
||||
SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)),
|
||||
ast::ViewPathGlob(ref p, id) =>
|
||||
GlobImport(resolve_use_source(cx, p.clean(cx), id)),
|
||||
ast::ViewPathList(ref p, ref pl, id) => {
|
||||
ImportList(resolve_use_source(cx, p.clean(cx), id),
|
||||
pl.clean(cx))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||
pub struct ViewListIdent {
|
||||
pub name: String,
|
||||
|
|
|
@ -25,6 +25,8 @@ pub struct Module {
|
|||
pub attrs: Vec<ast::Attribute>,
|
||||
pub where_outer: Span,
|
||||
pub where_inner: Span,
|
||||
pub extern_crates: Vec<ExternCrate>,
|
||||
pub imports: Vec<Import>,
|
||||
pub structs: Vec<Struct>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub fns: Vec<Function>,
|
||||
|
@ -38,7 +40,6 @@ pub struct Module {
|
|||
pub stab: Option<attr::Stability>,
|
||||
pub impls: Vec<Impl>,
|
||||
pub foreigns: Vec<ast::ForeignMod>,
|
||||
pub view_items: Vec<ast::ViewItem>,
|
||||
pub macros: Vec<Macro>,
|
||||
pub is_crate: bool,
|
||||
}
|
||||
|
@ -53,6 +54,8 @@ impl Module {
|
|||
where_outer: syntax::codemap::DUMMY_SP,
|
||||
where_inner: syntax::codemap::DUMMY_SP,
|
||||
attrs : Vec::new(),
|
||||
extern_crates: Vec::new(),
|
||||
imports : Vec::new(),
|
||||
structs : Vec::new(),
|
||||
enums : Vec::new(),
|
||||
fns : Vec::new(),
|
||||
|
@ -62,7 +65,6 @@ impl Module {
|
|||
constants : Vec::new(),
|
||||
traits : Vec::new(),
|
||||
impls : Vec::new(),
|
||||
view_items : Vec::new(),
|
||||
foreigns : Vec::new(),
|
||||
macros : Vec::new(),
|
||||
is_crate : false,
|
||||
|
@ -202,6 +204,22 @@ pub struct Macro {
|
|||
pub stab: Option<attr::Stability>,
|
||||
}
|
||||
|
||||
pub struct ExternCrate {
|
||||
pub name: Ident,
|
||||
pub path: Option<String>,
|
||||
pub vis: ast::Visibility,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub struct Import {
|
||||
pub id: NodeId,
|
||||
pub vis: ast::Visibility,
|
||||
pub attrs: Vec<ast::Attribute>,
|
||||
pub node: ast::ViewPath_,
|
||||
pub whence: Span,
|
||||
}
|
||||
|
||||
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
|
||||
if sd.ctor_id.is_some() {
|
||||
// We are in a tuple-struct
|
||||
|
|
|
@ -617,7 +617,7 @@ impl fmt::Display for UnsafetySpace {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for clean::ViewPath {
|
||||
impl fmt::Display for clean::Import {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
clean::SimpleImport(ref name, ref src) => {
|
||||
|
|
|
@ -22,29 +22,31 @@ use clean;
|
|||
#[derive(Copy, PartialEq, Clone)]
|
||||
pub enum ItemType {
|
||||
Module = 0,
|
||||
Struct = 1,
|
||||
Enum = 2,
|
||||
Function = 3,
|
||||
Typedef = 4,
|
||||
Static = 5,
|
||||
Trait = 6,
|
||||
Impl = 7,
|
||||
ViewItem = 8,
|
||||
TyMethod = 9,
|
||||
Method = 10,
|
||||
StructField = 11,
|
||||
Variant = 12,
|
||||
// we used to have ForeignFunction and ForeignStatic. they are retired now.
|
||||
Macro = 15,
|
||||
Primitive = 16,
|
||||
AssociatedType = 17,
|
||||
Constant = 18,
|
||||
ExternCrate = 1,
|
||||
Import = 2,
|
||||
Struct = 3,
|
||||
Enum = 4,
|
||||
Function = 5,
|
||||
Typedef = 6,
|
||||
Static = 7,
|
||||
Trait = 8,
|
||||
Impl = 9,
|
||||
TyMethod = 10,
|
||||
Method = 11,
|
||||
StructField = 12,
|
||||
Variant = 13,
|
||||
Macro = 14,
|
||||
Primitive = 15,
|
||||
AssociatedType = 16,
|
||||
Constant = 17,
|
||||
}
|
||||
|
||||
impl ItemType {
|
||||
pub fn from_item(item: &clean::Item) -> ItemType {
|
||||
match item.inner {
|
||||
clean::ModuleItem(..) => ItemType::Module,
|
||||
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
||||
clean::ImportItem(..) => ItemType::Import,
|
||||
clean::StructItem(..) => ItemType::Struct,
|
||||
clean::EnumItem(..) => ItemType::Enum,
|
||||
clean::FunctionItem(..) => ItemType::Function,
|
||||
|
@ -53,7 +55,6 @@ impl ItemType {
|
|||
clean::ConstantItem(..) => ItemType::Constant,
|
||||
clean::TraitItem(..) => ItemType::Trait,
|
||||
clean::ImplItem(..) => ItemType::Impl,
|
||||
clean::ViewItemItem(..) => ItemType::ViewItem,
|
||||
clean::TyMethodItem(..) => ItemType::TyMethod,
|
||||
clean::MethodItem(..) => ItemType::Method,
|
||||
clean::StructFieldItem(..) => ItemType::StructField,
|
||||
|
@ -83,6 +84,8 @@ impl ItemType {
|
|||
pub fn to_static_str(&self) -> &'static str {
|
||||
match *self {
|
||||
ItemType::Module => "mod",
|
||||
ItemType::ExternCrate => "externcrate",
|
||||
ItemType::Import => "import",
|
||||
ItemType::Struct => "struct",
|
||||
ItemType::Enum => "enum",
|
||||
ItemType::Function => "fn",
|
||||
|
@ -90,7 +93,6 @@ impl ItemType {
|
|||
ItemType::Static => "static",
|
||||
ItemType::Trait => "trait",
|
||||
ItemType::Impl => "impl",
|
||||
ItemType::ViewItem => "viewitem",
|
||||
ItemType::TyMethod => "tymethod",
|
||||
ItemType::Method => "method",
|
||||
ItemType::StructField => "structfield",
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
pub use self::ExternalLocation::*;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cmp::Ordering::{self, Less, Greater, Equal};
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::default::Default;
|
||||
use std::fmt;
|
||||
|
@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
// the order of item types in the listing
|
||||
fn reorder(ty: ItemType) -> u8 {
|
||||
match ty {
|
||||
ItemType::ViewItem => 0,
|
||||
ItemType::Primitive => 1,
|
||||
ItemType::Module => 2,
|
||||
ItemType::Macro => 3,
|
||||
ItemType::Struct => 4,
|
||||
ItemType::Enum => 5,
|
||||
ItemType::Constant => 6,
|
||||
ItemType::Static => 7,
|
||||
ItemType::Trait => 8,
|
||||
ItemType::Function => 9,
|
||||
ItemType::Typedef => 10,
|
||||
_ => 11 + ty as u8,
|
||||
ItemType::ExternCrate => 0,
|
||||
ItemType::Import => 1,
|
||||
ItemType::Primitive => 2,
|
||||
ItemType::Module => 3,
|
||||
ItemType::Macro => 4,
|
||||
ItemType::Struct => 5,
|
||||
ItemType::Enum => 6,
|
||||
ItemType::Constant => 7,
|
||||
ItemType::Static => 8,
|
||||
ItemType::Trait => 9,
|
||||
ItemType::Function => 10,
|
||||
ItemType::Typedef => 12,
|
||||
_ => 13 + ty as u8,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1518,25 +1519,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
if ty1 == ty2 {
|
||||
return i1.name.cmp(&i2.name);
|
||||
}
|
||||
|
||||
let tycmp = reorder(ty1).cmp(&reorder(ty2));
|
||||
if let Equal = tycmp {
|
||||
// for reexports, `extern crate` takes precedence.
|
||||
match (&i1.inner, &i2.inner) {
|
||||
(&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
|
||||
match (&a.inner, &b.inner) {
|
||||
(&clean::ExternCrate(..), _) => return Less,
|
||||
(_, &clean::ExternCrate(..)) => return Greater,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
(_, _) => {}
|
||||
}
|
||||
|
||||
idx1.cmp(&idx2)
|
||||
} else {
|
||||
tycmp
|
||||
}
|
||||
(reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
|
||||
}
|
||||
|
||||
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
|
||||
|
@ -1547,12 +1530,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
let myitem = &items[idx];
|
||||
|
||||
let myty = Some(shortty(myitem));
|
||||
if myty != curty {
|
||||
if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
|
||||
// Put `extern crate` and `use` re-exports in the same section.
|
||||
curty = myty;
|
||||
} else if myty != curty {
|
||||
if curty.is_some() {
|
||||
try!(write!(w, "</table>"));
|
||||
}
|
||||
curty = myty;
|
||||
let (short, name) = match myty.unwrap() {
|
||||
ItemType::ExternCrate |
|
||||
ItemType::Import => ("reexports", "Reexports"),
|
||||
ItemType::Module => ("modules", "Modules"),
|
||||
ItemType::Struct => ("structs", "Structs"),
|
||||
ItemType::Enum => ("enums", "Enums"),
|
||||
|
@ -1562,7 +1550,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
ItemType::Constant => ("constants", "Constants"),
|
||||
ItemType::Trait => ("traits", "Traits"),
|
||||
ItemType::Impl => ("impls", "Implementations"),
|
||||
ItemType::ViewItem => ("reexports", "Reexports"),
|
||||
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
||||
ItemType::Method => ("methods", "Methods"),
|
||||
ItemType::StructField => ("fields", "Struct Fields"),
|
||||
|
@ -1578,28 +1565,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
|||
}
|
||||
|
||||
match myitem.inner {
|
||||
clean::ViewItemItem(ref item) => {
|
||||
match item.inner {
|
||||
clean::ExternCrate(ref name, ref src, _) => {
|
||||
clean::ExternCrateItem(ref name, ref src) => {
|
||||
match *src {
|
||||
Some(ref src) =>
|
||||
try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}",
|
||||
src.as_slice(),
|
||||
name.as_slice())),
|
||||
None =>
|
||||
try!(write!(w, "<tr><td><code>extern crate {}",
|
||||
name.as_slice())),
|
||||
}
|
||||
try!(write!(w, ";</code></td></tr>"));
|
||||
}
|
||||
|
||||
clean::Import(ref import) => {
|
||||
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
|
||||
Some(ref src) => {
|
||||
try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
|
||||
VisSpace(myitem.visibility),
|
||||
*import));
|
||||
src.as_slice(),
|
||||
name.as_slice()))
|
||||
}
|
||||
None => {
|
||||
try!(write!(w, "<tr><td><code>{}extern crate {};",
|
||||
VisSpace(myitem.visibility), name.as_slice()))
|
||||
}
|
||||
}
|
||||
try!(write!(w, "</code></td></tr>"));
|
||||
}
|
||||
|
||||
clean::ImportItem(ref import) => {
|
||||
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
|
||||
VisSpace(myitem.visibility), *import));
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
|
|
@ -245,7 +245,6 @@ nav.sub {
|
|||
.content .highlighted.method { background-color: #c6afb3; }
|
||||
.content .highlighted.tymethod { background-color: #c6afb3; }
|
||||
.content .highlighted.type { background-color: #c6afb3; }
|
||||
.content .highlighted.ffi { background-color: #c6afb3; }
|
||||
|
||||
.docblock.short.nowrap {
|
||||
display: block;
|
||||
|
@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; }
|
|||
.content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
|
||||
.content span.method, .content a.method, .block a.current.method { color: #8c6067; }
|
||||
.content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; }
|
||||
.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
|
||||
.content .fnname { color: #8c6067; }
|
||||
|
||||
.search-input {
|
||||
|
|
|
@ -555,6 +555,8 @@
|
|||
// This mapping table should match the discriminants of
|
||||
// `rustdoc::html::item_type::ItemType` type in Rust.
|
||||
var itemTypes = ["mod",
|
||||
"externcrate",
|
||||
"import",
|
||||
"struct",
|
||||
"enum",
|
||||
"fn",
|
||||
|
@ -562,13 +564,10 @@
|
|||
"static",
|
||||
"trait",
|
||||
"impl",
|
||||
"viewitem",
|
||||
"tymethod",
|
||||
"method",
|
||||
"structfield",
|
||||
"variant",
|
||||
"ffi", // retained for backward compatibility
|
||||
"ffs", // retained for backward compatibility
|
||||
"macro",
|
||||
"primitive",
|
||||
"associatedtype",
|
||||
|
|
|
@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
clean::ViewItemItem(..) => {
|
||||
clean::ExternCrateItem(..) | clean::ImportItem(_) => {
|
||||
if i.visibility != Some(ast::Public) {
|
||||
return None
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use syntax::ast::Public;
|
|||
|
||||
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
||||
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
|
||||
use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
|
||||
use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
|
||||
|
||||
use html::render::cache;
|
||||
|
||||
|
@ -199,7 +199,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
|||
}))
|
||||
}
|
||||
// no stability information for the following items:
|
||||
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
|
||||
ExternCrateItem(..) | ImportItem(_) |
|
||||
PrimitiveItem(_) => (Counts::zero(), None),
|
||||
_ => (item_counts, None)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ use syntax::ast_map;
|
|||
use syntax::attr;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ptr::P;
|
||||
|
||||
use rustc::middle::stability;
|
||||
|
||||
|
@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
m: &ast::Mod,
|
||||
name: Option<ast::Ident>) -> Module {
|
||||
let mut om = Module::new(name);
|
||||
for item in m.view_items.iter() {
|
||||
self.visit_view_item(item, &mut om);
|
||||
}
|
||||
om.where_outer = span;
|
||||
om.where_inner = m.inner;
|
||||
om.attrs = attrs;
|
||||
|
@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
om
|
||||
}
|
||||
|
||||
pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
|
||||
if item.vis != ast::Public {
|
||||
return om.view_items.push(item.clone());
|
||||
}
|
||||
let please_inline = item.attrs.iter().any(|item| {
|
||||
match item.meta_item_list() {
|
||||
Some(list) => {
|
||||
list.iter().any(|i| i.name().get() == "inline")
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
});
|
||||
let item = match item.node {
|
||||
ast::ViewItemUse(ref vpath) => {
|
||||
match self.visit_view_path(&**vpath, om, please_inline) {
|
||||
None => return,
|
||||
Some(path) => {
|
||||
ast::ViewItem {
|
||||
node: ast::ViewItemUse(path),
|
||||
.. item.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ViewItemExternCrate(..) => item.clone()
|
||||
};
|
||||
om.view_items.push(item);
|
||||
}
|
||||
|
||||
fn visit_view_path(&mut self, path: &ast::ViewPath,
|
||||
fn visit_view_path(&mut self, path: ast::ViewPath_,
|
||||
om: &mut Module,
|
||||
please_inline: bool) -> Option<P<ast::ViewPath>> {
|
||||
match path.node {
|
||||
ast::ViewPathSimple(dst, _, id) => {
|
||||
id: ast::NodeId,
|
||||
please_inline: bool) -> Option<ast::ViewPath_> {
|
||||
match path {
|
||||
ast::ViewPathSimple(dst, base) => {
|
||||
if self.resolve_id(id, Some(dst), false, om, please_inline) {
|
||||
return None
|
||||
}
|
||||
}
|
||||
ast::ViewPathList(ref p, ref paths, ref b) => {
|
||||
let mut mine = Vec::new();
|
||||
for path in paths.iter() {
|
||||
if !self.resolve_id(path.node.id(), None, false, om,
|
||||
please_inline) {
|
||||
mine.push(path.clone());
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathSimple(dst, base))
|
||||
}
|
||||
}
|
||||
ast::ViewPathList(p, paths) => {
|
||||
let mine = paths.into_iter().filter(|path| {
|
||||
!self.resolve_id(path.node.id(), None, false, om,
|
||||
please_inline)
|
||||
}).collect::<Vec<ast::PathListItem>>();
|
||||
|
||||
if mine.len() == 0 { return None }
|
||||
return Some(P(::syntax::codemap::Spanned {
|
||||
node: ast::ViewPathList(p.clone(), mine, b.clone()),
|
||||
span: path.span,
|
||||
}))
|
||||
if mine.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathList(p, mine))
|
||||
}
|
||||
}
|
||||
|
||||
// these are feature gated anyway
|
||||
ast::ViewPathGlob(_, id) => {
|
||||
ast::ViewPathGlob(base) => {
|
||||
if self.resolve_id(id, None, true, om, please_inline) {
|
||||
return None
|
||||
None
|
||||
} else {
|
||||
Some(ast::ViewPathGlob(base))
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(P(path.clone()))
|
||||
|
||||
}
|
||||
|
||||
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
|
||||
|
@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
if glob {
|
||||
match it.node {
|
||||
ast::ItemMod(ref m) => {
|
||||
for vi in m.view_items.iter() {
|
||||
self.visit_view_item(vi, om);
|
||||
}
|
||||
for i in m.items.iter() {
|
||||
self.visit_item(&**i, None, om);
|
||||
}
|
||||
|
@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||
debug!("Visiting item {:?}", item);
|
||||
let name = renamed.unwrap_or(item.ident);
|
||||
match item.node {
|
||||
ast::ItemExternCrate(ref p) => {
|
||||
let path = match *p {
|
||||
None => None,
|
||||
Some((ref x, _)) => Some(x.get().to_string()),
|
||||
};
|
||||
om.extern_crates.push(ExternCrate {
|
||||
name: name,
|
||||
path: path,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
whence: item.span,
|
||||
})
|
||||
}
|
||||
ast::ItemUse(ref vpath) => {
|
||||
let node = vpath.node.clone();
|
||||
let node = if item.vis == ast::Public {
|
||||
let please_inline = item.attrs.iter().any(|item| {
|
||||
match item.meta_item_list() {
|
||||
Some(list) => {
|
||||
list.iter().any(|i| i.name().get() == "inline")
|
||||
}
|
||||
None => false,
|
||||
}
|
||||
});
|
||||
match self.visit_view_path(node, om, item.id, please_inline) {
|
||||
None => return,
|
||||
Some(p) => p
|
||||
}
|
||||
} else {
|
||||
node
|
||||
};
|
||||
om.imports.push(Import {
|
||||
id: item.id,
|
||||
vis: item.vis,
|
||||
attrs: item.attrs.clone(),
|
||||
node: node,
|
||||
whence: item.span,
|
||||
});
|
||||
}
|
||||
ast::ItemMod(ref m) => {
|
||||
om.mods.push(self.visit_mod_contents(item.span,
|
||||
item.attrs.clone(),
|
||||
|
|
|
@ -53,7 +53,6 @@ pub use self::UnboxedClosureKind::*;
|
|||
pub use self::UnOp::*;
|
||||
pub use self::UnsafeSource::*;
|
||||
pub use self::VariantKind::*;
|
||||
pub use self::ViewItem_::*;
|
||||
pub use self::ViewPath_::*;
|
||||
pub use self::Visibility::*;
|
||||
pub use self::PathParameters::*;
|
||||
|
@ -511,7 +510,6 @@ impl PartialEq for MetaItem_ {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct Block {
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub stmts: Vec<P<Stmt>>,
|
||||
pub expr: Option<P<Expr>>,
|
||||
pub id: NodeId,
|
||||
|
@ -1443,14 +1441,12 @@ pub struct Mod {
|
|||
/// For `mod foo;`, the inner span ranges from the first token
|
||||
/// to the last token in the external file.
|
||||
pub inner: Span,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<P<Item>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct ForeignMod {
|
||||
pub abi: Abi,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<P<ForeignItem>>,
|
||||
}
|
||||
|
||||
|
@ -1509,44 +1505,13 @@ pub enum ViewPath_ {
|
|||
/// or just
|
||||
///
|
||||
/// `foo::bar::baz` (with `as baz` implicitly on the right)
|
||||
ViewPathSimple(Ident, Path, NodeId),
|
||||
ViewPathSimple(Ident, Path),
|
||||
|
||||
/// `foo::bar::*`
|
||||
ViewPathGlob(Path, NodeId),
|
||||
ViewPathGlob(Path),
|
||||
|
||||
/// `foo::bar::{a,b,c}`
|
||||
ViewPathList(Path, Vec<PathListItem> , NodeId)
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct ViewItem {
|
||||
pub node: ViewItem_,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub vis: Visibility,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ViewItem {
|
||||
pub fn id(&self) -> NodeId {
|
||||
match self.node {
|
||||
ViewItemExternCrate(_, _, id) => id,
|
||||
ViewItemUse(ref vp) => match vp.node {
|
||||
ViewPathSimple(_, _, id) => id,
|
||||
ViewPathGlob(_, id) => id,
|
||||
ViewPathList(_, _, id) => id,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum ViewItem_ {
|
||||
/// Ident: name used to refer to this crate in the code
|
||||
/// optional (InternedString,StrStyle): if present, this is a location
|
||||
/// (containing arbitrary characters) from which to fetch the crate sources
|
||||
/// For example, extern crate whatever = "github.com/rust-lang/rust"
|
||||
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
|
||||
ViewItemUse(P<ViewPath>),
|
||||
ViewPathList(Path, Vec<PathListItem>)
|
||||
}
|
||||
|
||||
/// Meta-data associated with an item
|
||||
|
@ -1668,6 +1633,12 @@ pub struct Item {
|
|||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum Item_ {
|
||||
// Optional location (containing arbitrary characters) from which
|
||||
// to fetch the crate sources.
|
||||
// For example, extern crate whatever = "github.com/rust-lang/rust".
|
||||
ItemExternCrate(Option<(InternedString, StrStyle)>),
|
||||
ItemUse(P<ViewPath>),
|
||||
|
||||
ItemStatic(P<Ty>, Mutability, P<Expr>),
|
||||
ItemConst(P<Ty>, P<Expr>),
|
||||
ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
|
||||
|
@ -1694,6 +1665,8 @@ pub enum Item_ {
|
|||
impl Item_ {
|
||||
pub fn descriptive_variant(&self) -> &str {
|
||||
match *self {
|
||||
ItemExternCrate(..) => "extern crate",
|
||||
ItemUse(..) => "use",
|
||||
ItemStatic(..) => "static item",
|
||||
ItemConst(..) => "constant item",
|
||||
ItemFn(..) => "function",
|
||||
|
|
|
@ -107,7 +107,6 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
|
|||
#[derive(Copy, Show)]
|
||||
pub enum Node<'ast> {
|
||||
NodeItem(&'ast Item),
|
||||
NodeViewItem(&'ast ViewItem),
|
||||
NodeForeignItem(&'ast ForeignItem),
|
||||
NodeTraitItem(&'ast TraitItem),
|
||||
NodeImplItem(&'ast ImplItem),
|
||||
|
@ -134,7 +133,6 @@ enum MapEntry<'ast> {
|
|||
|
||||
/// All the node types, with a parent ID.
|
||||
EntryItem(NodeId, &'ast Item),
|
||||
EntryViewItem(NodeId, &'ast ViewItem),
|
||||
EntryForeignItem(NodeId, &'ast ForeignItem),
|
||||
EntryTraitItem(NodeId, &'ast TraitItem),
|
||||
EntryImplItem(NodeId, &'ast ImplItem),
|
||||
|
@ -169,7 +167,6 @@ impl<'ast> MapEntry<'ast> {
|
|||
fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
|
||||
match node {
|
||||
NodeItem(n) => EntryItem(p, n),
|
||||
NodeViewItem(n) => EntryViewItem(p, n),
|
||||
NodeForeignItem(n) => EntryForeignItem(p, n),
|
||||
NodeTraitItem(n) => EntryTraitItem(p, n),
|
||||
NodeImplItem(n) => EntryImplItem(p, n),
|
||||
|
@ -188,7 +185,6 @@ impl<'ast> MapEntry<'ast> {
|
|||
fn parent(self) -> Option<NodeId> {
|
||||
Some(match self {
|
||||
EntryItem(id, _) => id,
|
||||
EntryViewItem(id, _) => id,
|
||||
EntryForeignItem(id, _) => id,
|
||||
EntryTraitItem(id, _) => id,
|
||||
EntryImplItem(id, _) => id,
|
||||
|
@ -208,7 +204,6 @@ impl<'ast> MapEntry<'ast> {
|
|||
fn to_node(self) -> Option<Node<'ast>> {
|
||||
Some(match self {
|
||||
EntryItem(_, n) => NodeItem(n),
|
||||
EntryViewItem(_, n) => NodeViewItem(n),
|
||||
EntryForeignItem(_, n) => NodeForeignItem(n),
|
||||
EntryTraitItem(_, n) => NodeTraitItem(n),
|
||||
EntryImplItem(_, n) => NodeImplItem(n),
|
||||
|
@ -341,13 +336,6 @@ impl<'ast> Map<'ast> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn expect_view_item(&self, id: NodeId) -> &'ast ViewItem {
|
||||
match self.find(id) {
|
||||
Some(NodeViewItem(view_item)) => view_item,
|
||||
_ => panic!("expected view item, found {}", self.node_to_string(id))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
|
||||
match self.find(id) {
|
||||
Some(NodeItem(i)) => {
|
||||
|
@ -533,7 +521,6 @@ impl<'ast> Map<'ast> {
|
|||
pub fn opt_span(&self, id: NodeId) -> Option<Span> {
|
||||
let sp = match self.find(id) {
|
||||
Some(NodeItem(item)) => item.span,
|
||||
Some(NodeViewItem(item)) => item.span,
|
||||
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
|
||||
Some(NodeTraitItem(trait_method)) => {
|
||||
match *trait_method {
|
||||
|
@ -826,11 +813,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
|||
self.parent = parent;
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, item: &'ast ViewItem) {
|
||||
self.insert(item.id(), NodeViewItem(item));
|
||||
visit::walk_view_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &'ast Pat) {
|
||||
self.insert(pat.id, match pat.node {
|
||||
// Note: this is at least *potentially* a pattern...
|
||||
|
@ -904,7 +886,6 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map
|
|||
let krate = mem::replace(&mut forest.krate, Crate {
|
||||
module: Mod {
|
||||
inner: DUMMY_SP,
|
||||
view_items: vec![],
|
||||
items: vec![],
|
||||
},
|
||||
attrs: vec![],
|
||||
|
@ -1036,7 +1017,6 @@ impl<'a> NodePrinter for pprust::State<'a> {
|
|||
fn print_node(&mut self, node: &Node) -> IoResult<()> {
|
||||
match *node {
|
||||
NodeItem(a) => self.print_item(&*a),
|
||||
NodeViewItem(a) => self.print_view_item(&*a),
|
||||
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
||||
NodeTraitItem(a) => self.print_trait_method(&*a),
|
||||
NodeImplItem(a) => self.print_impl_item(&*a),
|
||||
|
@ -1065,6 +1045,8 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
|||
Some(NodeItem(item)) => {
|
||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||
let item_str = match item.node {
|
||||
ItemExternCrate(..) => "extern crate",
|
||||
ItemUse(..) => "use",
|
||||
ItemStatic(..) => "static",
|
||||
ItemConst(..) => "const",
|
||||
ItemFn(..) => "fn",
|
||||
|
@ -1079,9 +1061,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
|
|||
};
|
||||
format!("{} {}{}", item_str, path_str, id_str)
|
||||
}
|
||||
Some(NodeViewItem(item)) => {
|
||||
format!("view item {}{}", pprust::view_item_to_string(&*item), id_str)
|
||||
}
|
||||
Some(NodeForeignItem(item)) => {
|
||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||
format!("foreign item {}{}", path_str, id_str)
|
||||
|
|
|
@ -410,37 +410,6 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
|||
visit::walk_mod(self, module)
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, view_item: &ViewItem) {
|
||||
if !self.pass_through_items {
|
||||
if self.visited_outermost {
|
||||
return;
|
||||
} else {
|
||||
self.visited_outermost = true;
|
||||
}
|
||||
}
|
||||
match view_item.node {
|
||||
ViewItemExternCrate(_, _, node_id) => {
|
||||
self.operation.visit_id(node_id)
|
||||
}
|
||||
ViewItemUse(ref view_path) => {
|
||||
match view_path.node {
|
||||
ViewPathSimple(_, _, node_id) |
|
||||
ViewPathGlob(_, node_id) => {
|
||||
self.operation.visit_id(node_id)
|
||||
}
|
||||
ViewPathList(_, ref paths, node_id) => {
|
||||
self.operation.visit_id(node_id);
|
||||
for path in paths.iter() {
|
||||
self.operation.visit_id(path.node.id())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_view_item(self, view_item);
|
||||
self.visited_outermost = false;
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||
self.operation.visit_id(foreign_item.id);
|
||||
visit::walk_foreign_item(self, foreign_item)
|
||||
|
@ -456,11 +425,25 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
|||
}
|
||||
|
||||
self.operation.visit_id(item.id);
|
||||
if let ItemEnum(ref enum_definition, _) = item.node {
|
||||
match item.node {
|
||||
ItemUse(ref view_path) => {
|
||||
match view_path.node {
|
||||
ViewPathSimple(_, _) |
|
||||
ViewPathGlob(_) => {}
|
||||
ViewPathList(_, ref paths) => {
|
||||
for path in paths.iter() {
|
||||
self.operation.visit_id(path.node.id())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemEnum(ref enum_definition, _) => {
|
||||
for variant in enum_definition.variants.iter() {
|
||||
self.operation.visit_id(variant.node.id)
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit::walk_item(self, item);
|
||||
|
||||
|
@ -662,37 +645,6 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
|
|||
walk_pat_(pat, &mut it)
|
||||
}
|
||||
|
||||
pub trait EachViewItem {
|
||||
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool;
|
||||
}
|
||||
|
||||
struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
|
||||
callback: F,
|
||||
}
|
||||
|
||||
impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
|
||||
fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
|
||||
let _ = (self.callback)(view_item);
|
||||
}
|
||||
}
|
||||
|
||||
impl EachViewItem for ast::Crate {
|
||||
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool {
|
||||
let mut visit = EachViewItemData {
|
||||
callback: f,
|
||||
};
|
||||
visit::walk_crate(&mut visit, self);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_path_id(p: &ViewPath) -> NodeId {
|
||||
match p.node {
|
||||
ViewPathSimple(_, _, id) | ViewPathGlob(_, id)
|
||||
| ViewPathList(_, _, id) => id
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the given struct def is tuple-like; i.e. that its fields
|
||||
/// are unnamed.
|
||||
pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
|
||||
|
|
|
@ -63,28 +63,13 @@ pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where
|
|||
ctxt.fold_crate(krate)
|
||||
}
|
||||
|
||||
fn filter_view_item<F>(cx: &mut Context<F>,
|
||||
view_item: ast::ViewItem)
|
||||
-> Option<ast::ViewItem> where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
if view_item_in_cfg(cx, &view_item) {
|
||||
Some(view_item)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_mod<F>(cx: &mut Context<F>,
|
||||
ast::Mod {inner,
|
||||
view_items, items}: ast::Mod) -> ast::Mod where
|
||||
ast::Mod {inner, items}: ast::Mod)
|
||||
-> ast::Mod where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
ast::Mod {
|
||||
inner: inner,
|
||||
view_items: view_items.into_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect(),
|
||||
items: items.into_iter().flat_map(|a| {
|
||||
cx.fold_item(a).into_iter()
|
||||
}).collect()
|
||||
|
@ -104,15 +89,12 @@ fn filter_foreign_item<F>(cx: &mut Context<F>,
|
|||
}
|
||||
|
||||
fn fold_foreign_mod<F>(cx: &mut Context<F>,
|
||||
ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
|
||||
ast::ForeignMod {abi, items}: ast::ForeignMod)
|
||||
-> ast::ForeignMod where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
ast::ForeignMod {
|
||||
abi: abi,
|
||||
view_items: view_items.into_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect(),
|
||||
items: items.into_iter()
|
||||
.filter_map(|a| filter_foreign_item(cx, a))
|
||||
.collect()
|
||||
|
@ -216,18 +198,14 @@ fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where
|
|||
fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
|
||||
b.map(|ast::Block {id, stmts, expr, rules, span}| {
|
||||
let resulting_stmts: Vec<P<ast::Stmt>> =
|
||||
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
||||
let resulting_stmts = resulting_stmts.into_iter()
|
||||
.flat_map(|stmt| cx.fold_stmt(stmt).into_iter())
|
||||
.collect();
|
||||
let filtered_view_items = view_items.into_iter().filter_map(|a| {
|
||||
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
|
||||
}).collect();
|
||||
ast::Block {
|
||||
id: id,
|
||||
view_items: filtered_view_items,
|
||||
stmts: resulting_stmts,
|
||||
expr: expr.map(|x| cx.fold_expr(x)),
|
||||
rules: rules,
|
||||
|
@ -267,12 +245,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
|
|||
return (cx.in_cfg)(item.attrs.as_slice());
|
||||
}
|
||||
|
||||
fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
return (cx.in_cfg)(item.attrs.as_slice());
|
||||
}
|
||||
|
||||
fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
|
||||
F: FnMut(&[ast::Attribute]) -> bool
|
||||
{
|
||||
|
|
|
@ -97,7 +97,6 @@ pub trait AstBuilder {
|
|||
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
||||
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
|
||||
fn block_all(&self, span: Span,
|
||||
view_items: Vec<ast::ViewItem>,
|
||||
stmts: Vec<P<ast::Stmt>>,
|
||||
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
||||
|
||||
|
@ -242,7 +241,7 @@ pub trait AstBuilder {
|
|||
|
||||
fn item_mod(&self, span: Span, inner_span: Span,
|
||||
name: Ident, attrs: Vec<ast::Attribute>,
|
||||
vi: Vec<ast::ViewItem> , items: Vec<P<ast::Item>> ) -> P<ast::Item>;
|
||||
items: Vec<P<ast::Item>>) -> P<ast::Item>;
|
||||
|
||||
fn item_static(&self,
|
||||
span: Span,
|
||||
|
@ -280,15 +279,15 @@ pub trait AstBuilder {
|
|||
value: ast::Lit_)
|
||||
-> P<ast::MetaItem>;
|
||||
|
||||
fn view_use(&self, sp: Span,
|
||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem;
|
||||
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
|
||||
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||
ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
|
||||
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem;
|
||||
fn view_use_glob(&self, sp: Span,
|
||||
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem;
|
||||
fn item_use(&self, sp: Span,
|
||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
|
||||
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
|
||||
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||
ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
|
||||
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
|
||||
fn item_use_glob(&self, sp: Span,
|
||||
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>;
|
||||
}
|
||||
|
||||
impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||
|
@ -519,7 +518,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
|
||||
fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>,
|
||||
expr: Option<P<Expr>>) -> P<ast::Block> {
|
||||
self.block_all(span, Vec::new(), stmts, expr)
|
||||
self.block_all(span, stmts, expr)
|
||||
}
|
||||
|
||||
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> P<ast::Stmt> {
|
||||
|
@ -528,15 +527,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
}
|
||||
|
||||
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
|
||||
self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
|
||||
self.block_all(expr.span, Vec::new(), Some(expr))
|
||||
}
|
||||
fn block_all(&self,
|
||||
span: Span,
|
||||
view_items: Vec<ast::ViewItem>,
|
||||
stmts: Vec<P<ast::Stmt>>,
|
||||
expr: Option<P<ast::Expr>>) -> P<ast::Block> {
|
||||
P(ast::Block {
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
expr: expr,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -1032,7 +1029,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
|
||||
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
|
||||
attrs: Vec<ast::Attribute>,
|
||||
vi: Vec<ast::ViewItem> ,
|
||||
items: Vec<P<ast::Item>>) -> P<ast::Item> {
|
||||
self.item(
|
||||
span,
|
||||
|
@ -1040,7 +1036,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
attrs,
|
||||
ast::ItemMod(ast::Mod {
|
||||
inner: inner_span,
|
||||
view_items: vi,
|
||||
items: items,
|
||||
})
|
||||
)
|
||||
|
@ -1101,47 +1096,47 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
|||
P(respan(sp, ast::MetaNameValue(name, respan(sp, value))))
|
||||
}
|
||||
|
||||
fn view_use(&self, sp: Span,
|
||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem {
|
||||
ast::ViewItem {
|
||||
node: ast::ViewItemUse(vp),
|
||||
attrs: Vec::new(),
|
||||
fn item_use(&self, sp: Span,
|
||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> {
|
||||
P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: special_idents::invalid,
|
||||
attrs: vec![],
|
||||
node: ast::ItemUse(vp),
|
||||
vis: vis,
|
||||
span: sp
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem {
|
||||
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
|
||||
let last = path.segments.last().unwrap().identifier;
|
||||
self.view_use_simple_(sp, vis, last, path)
|
||||
self.item_use_simple_(sp, vis, last, path)
|
||||
}
|
||||
|
||||
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||
ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
|
||||
self.view_use(sp, vis,
|
||||
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||
ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
|
||||
self.item_use(sp, vis,
|
||||
P(respan(sp,
|
||||
ast::ViewPathSimple(ident,
|
||||
path,
|
||||
ast::DUMMY_NODE_ID))))
|
||||
path))))
|
||||
}
|
||||
|
||||
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem {
|
||||
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
|
||||
let imports = imports.iter().map(|id| {
|
||||
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
|
||||
}).collect();
|
||||
|
||||
self.view_use(sp, vis,
|
||||
self.item_use(sp, vis,
|
||||
P(respan(sp,
|
||||
ast::ViewPathList(self.path(sp, path),
|
||||
imports,
|
||||
ast::DUMMY_NODE_ID))))
|
||||
imports))))
|
||||
}
|
||||
|
||||
fn view_use_glob(&self, sp: Span,
|
||||
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
|
||||
self.view_use(sp, vis,
|
||||
fn item_use_glob(&self, sp: Span,
|
||||
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
|
||||
self.item_use(sp, vis,
|
||||
P(respan(sp,
|
||||
ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))))
|
||||
ast::ViewPathGlob(self.path(sp, path)))))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1073,7 +1073,7 @@ impl<'a> MethodDef<'a> {
|
|||
// <delegated expression referring to __self0_vi, et al.>
|
||||
// }
|
||||
let arm_expr = cx.expr_block(
|
||||
cx.block_all(sp, Vec::new(), index_let_stmts, Some(arm_expr)));
|
||||
cx.block_all(sp, index_let_stmts, Some(arm_expr)));
|
||||
|
||||
// Builds arm:
|
||||
// _ => { let __self0_vi = ...;
|
||||
|
|
|
@ -206,7 +206,6 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
|
|||
// wrap the if-let expr in a block
|
||||
let span = els.span;
|
||||
let blk = P(ast::Block {
|
||||
view_items: vec![],
|
||||
stmts: vec![],
|
||||
expr: Some(P(els)),
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -799,8 +798,7 @@ pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
|||
|
||||
// expand the elements of a block.
|
||||
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
||||
b.map(|Block {id, view_items, stmts, expr, rules, span}| {
|
||||
let new_view_items = view_items.into_iter().map(|x| fld.fold_view_item(x)).collect();
|
||||
b.map(|Block {id, stmts, expr, rules, span}| {
|
||||
let new_stmts = stmts.into_iter().flat_map(|x| {
|
||||
// perform all pending renames
|
||||
let renamed_stmt = {
|
||||
|
@ -821,7 +819,6 @@ pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
|||
});
|
||||
Block {
|
||||
id: fld.new_id(id),
|
||||
view_items: new_view_items,
|
||||
stmts: new_stmts,
|
||||
expr: new_expr,
|
||||
rules: rules,
|
||||
|
|
|
@ -352,18 +352,11 @@ pub mod rt {
|
|||
impl<'a> ExtParseUtils for ExtCtxt<'a> {
|
||||
|
||||
fn parse_item(&self, s: String) -> P<ast::Item> {
|
||||
let res = parse::parse_item_from_source_str(
|
||||
parse::parse_item_from_source_str(
|
||||
"<quote expansion>".to_string(),
|
||||
s,
|
||||
self.cfg(),
|
||||
self.parse_sess());
|
||||
match res {
|
||||
Some(ast) => ast,
|
||||
None => {
|
||||
error!("parse error");
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
self.parse_sess()).expect("parse error")
|
||||
}
|
||||
|
||||
fn parse_stmt(&self, s: String) -> P<ast::Stmt> {
|
||||
|
@ -767,7 +760,6 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
|
|||
vector.extend(mk_tts(cx, &tts[]).into_iter());
|
||||
let block = cx.expr_block(
|
||||
cx.block_all(sp,
|
||||
Vec::new(),
|
||||
vector,
|
||||
Some(cx.expr_ident(sp, id_ext("tt")))));
|
||||
|
||||
|
@ -778,18 +770,18 @@ fn expand_wrapper(cx: &ExtCtxt,
|
|||
sp: Span,
|
||||
cx_expr: P<ast::Expr>,
|
||||
expr: P<ast::Expr>) -> P<ast::Expr> {
|
||||
let uses = [
|
||||
&["syntax", "ext", "quote", "rt"],
|
||||
].iter().map(|path| {
|
||||
let path = path.iter().map(|s| s.to_string()).collect();
|
||||
cx.view_use_glob(sp, ast::Inherited, ids_ext(path))
|
||||
}).collect();
|
||||
|
||||
// Explicitly borrow to avoid moving from the invoker (#16992)
|
||||
let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
|
||||
let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
|
||||
|
||||
cx.expr_block(cx.block_all(sp, uses, vec!(stmt_let_ext_cx), Some(expr)))
|
||||
let stmts = [
|
||||
&["syntax", "ext", "quote", "rt"],
|
||||
].iter().map(|path| {
|
||||
let path = path.iter().map(|s| s.to_string()).collect();
|
||||
cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path)))
|
||||
}).chain(Some(stmt_let_ext_cx).into_iter()).collect();
|
||||
|
||||
cx.expr_block(cx.block_all(sp, stmts, Some(expr)))
|
||||
}
|
||||
|
||||
fn expand_parse_call(cx: &ExtCtxt,
|
||||
|
|
|
@ -64,7 +64,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
|
|||
|
||||
("rustc_diagnostic_macros", Active),
|
||||
("unboxed_closures", Active),
|
||||
("import_shadowing", Active),
|
||||
("import_shadowing", Removed),
|
||||
("advanced_slice_patterns", Active),
|
||||
("tuple_indexing", Accepted),
|
||||
("associated_types", Accepted),
|
||||
|
@ -127,7 +127,6 @@ enum Status {
|
|||
pub struct Features {
|
||||
pub unboxed_closures: bool,
|
||||
pub rustc_diagnostic_macros: bool,
|
||||
pub import_shadowing: bool,
|
||||
pub visible_private_types: bool,
|
||||
pub quote: bool,
|
||||
pub old_orphan_check: bool,
|
||||
|
@ -139,7 +138,6 @@ impl Features {
|
|||
Features {
|
||||
unboxed_closures: false,
|
||||
rustc_diagnostic_macros: false,
|
||||
import_shadowing: false,
|
||||
visible_private_types: false,
|
||||
quote: false,
|
||||
old_orphan_check: false,
|
||||
|
@ -228,22 +226,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, i: &ast::ViewItem) {
|
||||
match i.node {
|
||||
ast::ViewItemUse(..) => {}
|
||||
ast::ViewItemExternCrate(..) => {
|
||||
for attr in i.attrs.iter() {
|
||||
if attr.check_name("plugin") {
|
||||
self.gate_feature("plugin", attr.span,
|
||||
"compiler plugins are experimental \
|
||||
and possibly buggy");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visit::walk_view_item(self, i)
|
||||
}
|
||||
|
||||
fn visit_item(&mut self, i: &ast::Item) {
|
||||
for attr in i.attrs.iter() {
|
||||
if attr.name() == "thread_local" {
|
||||
|
@ -262,6 +244,14 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
|
|||
}
|
||||
}
|
||||
match i.node {
|
||||
ast::ItemExternCrate(_) => {
|
||||
if attr::contains_name(&i.attrs[], "plugin") {
|
||||
self.gate_feature("plugin", i.span,
|
||||
"compiler plugins are experimental \
|
||||
and possibly buggy");
|
||||
}
|
||||
}
|
||||
|
||||
ast::ItemForeignMod(ref foreign_module) => {
|
||||
if attr::contains_name(&i.attrs[], "link_args") {
|
||||
self.gate_feature("link_args", i.span,
|
||||
|
@ -537,7 +527,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
|
|||
(Features {
|
||||
unboxed_closures: cx.has_feature("unboxed_closures"),
|
||||
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
|
||||
import_shadowing: cx.has_feature("import_shadowing"),
|
||||
visible_private_types: cx.has_feature("visible_private_types"),
|
||||
quote: cx.has_feature("quote"),
|
||||
old_orphan_check: cx.has_feature("old_orphan_check"),
|
||||
|
|
|
@ -78,10 +78,6 @@ pub trait Folder : Sized {
|
|||
noop_fold_view_path(view_path, self)
|
||||
}
|
||||
|
||||
fn fold_view_item(&mut self, vi: ViewItem) -> ViewItem {
|
||||
noop_fold_view_item(vi, self)
|
||||
}
|
||||
|
||||
fn fold_foreign_item(&mut self, ni: P<ForeignItem>) -> P<ForeignItem> {
|
||||
noop_fold_foreign_item(ni, self)
|
||||
}
|
||||
|
@ -349,16 +345,13 @@ pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T
|
|||
pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
|
||||
view_path.map(|Spanned {node, span}| Spanned {
|
||||
node: match node {
|
||||
ViewPathSimple(ident, path, node_id) => {
|
||||
let id = fld.new_id(node_id);
|
||||
ViewPathSimple(ident, fld.fold_path(path), id)
|
||||
ViewPathSimple(ident, path) => {
|
||||
ViewPathSimple(ident, fld.fold_path(path))
|
||||
}
|
||||
ViewPathGlob(path, node_id) => {
|
||||
let id = fld.new_id(node_id);
|
||||
ViewPathGlob(fld.fold_path(path), id)
|
||||
ViewPathGlob(path) => {
|
||||
ViewPathGlob(fld.fold_path(path))
|
||||
}
|
||||
ViewPathList(path, path_list_idents, node_id) => {
|
||||
let id = fld.new_id(node_id);
|
||||
ViewPathList(path, path_list_idents) => {
|
||||
ViewPathList(fld.fold_path(path),
|
||||
path_list_idents.move_map(|path_list_ident| {
|
||||
Spanned {
|
||||
|
@ -373,8 +366,7 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
|
|||
},
|
||||
span: fld.new_span(path_list_ident.span)
|
||||
}
|
||||
}),
|
||||
id)
|
||||
}))
|
||||
}
|
||||
},
|
||||
span: fld.new_span(span)
|
||||
|
@ -470,11 +462,10 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, view_items, items}: ForeignMod,
|
||||
pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
|
||||
fld: &mut T) -> ForeignMod {
|
||||
ForeignMod {
|
||||
abi: abi,
|
||||
view_items: view_items.move_map(|x| fld.fold_view_item(x)),
|
||||
items: items.move_map(|x| fld.fold_foreign_item(x)),
|
||||
}
|
||||
}
|
||||
|
@ -953,28 +944,9 @@ fn noop_fold_variant_arg<T: Folder>(VariantArg {id, ty}: VariantArg, folder: &mu
|
|||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_view_item<T: Folder>(ViewItem {node, attrs, vis, span}: ViewItem,
|
||||
folder: &mut T) -> ViewItem {
|
||||
ViewItem {
|
||||
node: match node {
|
||||
ViewItemExternCrate(ident, string, node_id) => {
|
||||
ViewItemExternCrate(ident, string,
|
||||
folder.new_id(node_id))
|
||||
}
|
||||
ViewItemUse(view_path) => {
|
||||
ViewItemUse(folder.fold_view_path(view_path))
|
||||
}
|
||||
},
|
||||
attrs: attrs.move_map(|a| folder.fold_attribute(a)),
|
||||
vis: vis,
|
||||
span: folder.new_span(span)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
|
||||
b.map(|Block {id, view_items, stmts, expr, rules, span}| Block {
|
||||
b.map(|Block {id, stmts, expr, rules, span}| Block {
|
||||
id: folder.new_id(id),
|
||||
view_items: view_items.move_map(|x| folder.fold_view_item(x)),
|
||||
stmts: stmts.into_iter().flat_map(|s| folder.fold_stmt(s).into_iter()).collect(),
|
||||
expr: expr.map(|x| folder.fold_expr(x)),
|
||||
rules: rules,
|
||||
|
@ -984,6 +956,10 @@ pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
|
|||
|
||||
pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
||||
match i {
|
||||
ItemExternCrate(string) => ItemExternCrate(string),
|
||||
ItemUse(view_path) => {
|
||||
ItemUse(folder.fold_view_path(view_path))
|
||||
}
|
||||
ItemStatic(t, m, e) => {
|
||||
ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e))
|
||||
}
|
||||
|
@ -1103,10 +1079,9 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
|
|||
}
|
||||
}
|
||||
|
||||
pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mut T) -> Mod {
|
||||
pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
|
||||
Mod {
|
||||
inner: folder.new_span(inner),
|
||||
view_items: view_items.move_map(|x| folder.fold_view_item(x)),
|
||||
items: items.into_iter().flat_map(|x| folder.fold_item(x).into_iter()).collect(),
|
||||
}
|
||||
}
|
||||
|
@ -1137,9 +1112,8 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac
|
|||
}
|
||||
None => (ast::Mod {
|
||||
inner: span,
|
||||
view_items: Vec::new(),
|
||||
items: Vec::new(),
|
||||
}, Vec::new(), span)
|
||||
items: vec![],
|
||||
}, vec![], span)
|
||||
};
|
||||
|
||||
for def in exported_macros.iter_mut() {
|
||||
|
|
|
@ -757,11 +757,10 @@ mod test {
|
|||
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
|
||||
use parse::parser::Parser;
|
||||
use parse::token::{str_to_ident};
|
||||
use print::pprust::view_item_to_string;
|
||||
use print::pprust::item_to_string;
|
||||
use ptr::P;
|
||||
use util::parser_testing::{string_to_tts, string_to_parser};
|
||||
use util::parser_testing::{string_to_expr, string_to_item};
|
||||
use util::parser_testing::{string_to_stmt, string_to_view_item};
|
||||
use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt};
|
||||
|
||||
// produce a codemap::span
|
||||
fn sp(a: u32, b: u32) -> Span {
|
||||
|
@ -1079,7 +1078,6 @@ mod test {
|
|||
}
|
||||
},
|
||||
P(ast::Block {
|
||||
view_items: Vec::new(),
|
||||
stmts: vec!(P(Spanned{
|
||||
node: ast::StmtSemi(P(ast::Expr{
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -1111,25 +1109,25 @@ mod test {
|
|||
|
||||
#[test] fn parse_use() {
|
||||
let use_s = "use foo::bar::baz;";
|
||||
let vitem = string_to_view_item(use_s.to_string());
|
||||
let vitem_s = view_item_to_string(&vitem);
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&*vitem);
|
||||
assert_eq!(&vitem_s[], use_s);
|
||||
|
||||
let use_s = "use foo::bar as baz;";
|
||||
let vitem = string_to_view_item(use_s.to_string());
|
||||
let vitem_s = view_item_to_string(&vitem);
|
||||
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&*vitem);
|
||||
assert_eq!(&vitem_s[], use_s);
|
||||
}
|
||||
|
||||
#[test] fn parse_extern_crate() {
|
||||
let ex_s = "extern crate foo;";
|
||||
let vitem = string_to_view_item(ex_s.to_string());
|
||||
let vitem_s = view_item_to_string(&vitem);
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&*vitem);
|
||||
assert_eq!(&vitem_s[], ex_s);
|
||||
|
||||
let ex_s = "extern crate \"foo\" as bar;";
|
||||
let vitem = string_to_view_item(ex_s.to_string());
|
||||
let vitem_s = view_item_to_string(&vitem);
|
||||
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||
let vitem_s = item_to_string(&*vitem);
|
||||
assert_eq!(&vitem_s[], ex_s);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
pub use self::PathParsingMode::*;
|
||||
use self::ItemOrViewItem::*;
|
||||
|
||||
use abi;
|
||||
use ast::{AssociatedType, BareFnTy};
|
||||
|
@ -35,6 +34,7 @@ use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRet
|
|||
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
||||
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
|
||||
use ast::{ItemExternCrate, ItemUse};
|
||||
use ast::{LifetimeDef, Lit, Lit_};
|
||||
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||
use ast::{LitStr, LitInt, Local, LocalLet};
|
||||
|
@ -59,7 +59,6 @@ use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath
|
|||
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
|
||||
use ast::{UnnamedField, UnsafeBlock};
|
||||
use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
|
||||
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use ast::{Visibility, WhereClause};
|
||||
use ast;
|
||||
|
@ -122,14 +121,9 @@ pub enum BoundParsingMode {
|
|||
Modified,
|
||||
}
|
||||
|
||||
enum ItemOrViewItem {
|
||||
/// Indicates a failure to parse any kind of item. The attributes are
|
||||
/// returned.
|
||||
IoviNone(Vec<Attribute>),
|
||||
IoviItem(P<Item>),
|
||||
IoviForeignItem(P<ForeignItem>),
|
||||
IoviViewItem(ViewItem)
|
||||
}
|
||||
/// The `Err` case indicates a failure to parse any kind of item.
|
||||
/// The attributes are returned.
|
||||
type MaybeItem = Result<P<Item>, Vec<Attribute>>;
|
||||
|
||||
|
||||
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
|
||||
|
@ -231,19 +225,6 @@ macro_rules! maybe_whole {
|
|||
}
|
||||
}
|
||||
);
|
||||
(iovi $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return IoviItem(x.clone());
|
||||
}
|
||||
}
|
||||
);
|
||||
(pair_empty $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
|
@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
|
|||
lhs
|
||||
}
|
||||
|
||||
|
||||
struct ParsedItemsAndViewItems {
|
||||
attrs_remaining: Vec<Attribute>,
|
||||
view_items: Vec<ViewItem>,
|
||||
items: Vec<P<Item>> ,
|
||||
foreign_items: Vec<P<ForeignItem>>
|
||||
}
|
||||
|
||||
/* ident is handled by common.rs */
|
||||
|
||||
pub struct Parser<'a> {
|
||||
|
@ -3032,8 +3005,7 @@ impl<'a> Parser<'a> {
|
|||
let body = self.parse_expr();
|
||||
let fakeblock = P(ast::Block {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
view_items: Vec::new(),
|
||||
stmts: Vec::new(),
|
||||
stmts: vec![],
|
||||
span: body.span,
|
||||
expr: Some(body),
|
||||
rules: DefaultBlock,
|
||||
|
@ -3731,20 +3703,13 @@ impl<'a> Parser<'a> {
|
|||
} else {
|
||||
let found_attrs = !item_attrs.is_empty();
|
||||
let item_err = Parser::expected_item_err(&item_attrs[]);
|
||||
match self.parse_item_or_view_item(item_attrs, false) {
|
||||
IoviItem(i) => {
|
||||
match self.parse_item_(item_attrs, false) {
|
||||
Ok(i) => {
|
||||
let hi = i.span.hi;
|
||||
let decl = P(spanned(lo, hi, DeclItem(i)));
|
||||
P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
IoviViewItem(vi) => {
|
||||
self.span_fatal(vi.span,
|
||||
"view items must be declared at the top of the block");
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
self.fatal("foreign items are not allowed here");
|
||||
}
|
||||
IoviNone(_) => {
|
||||
Err(_) => {
|
||||
if found_attrs {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span, item_err);
|
||||
|
@ -3794,10 +3759,7 @@ impl<'a> Parser<'a> {
|
|||
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
|
||||
}
|
||||
|
||||
/// Precondition: already parsed the '{' or '#{'
|
||||
/// I guess that also means "already parsed the 'impure'" if
|
||||
/// necessary, and this should take a qualifier.
|
||||
/// Some blocks start with "#{"...
|
||||
/// Precondition: already parsed the '{'.
|
||||
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
||||
self.parse_block_tail_(lo, s, Vec::new())
|
||||
}
|
||||
|
@ -3805,25 +3767,9 @@ impl<'a> Parser<'a> {
|
|||
/// Parse the rest of a block expression or function body
|
||||
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
||||
first_item_attrs: Vec<Attribute>) -> P<Block> {
|
||||
let mut stmts = Vec::new();
|
||||
let mut stmts = vec![];
|
||||
let mut expr = None;
|
||||
|
||||
// wouldn't it be more uniform to parse view items only, here?
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items,
|
||||
..
|
||||
} = self.parse_items_and_view_items(first_item_attrs,
|
||||
false, false);
|
||||
|
||||
for item in items.into_iter() {
|
||||
let span = item.span;
|
||||
let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
|
||||
stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
|
||||
}
|
||||
|
||||
let mut attributes_box = attrs_remaining;
|
||||
let mut attributes_box = first_item_attrs;
|
||||
|
||||
while self.token != token::CloseDelim(token::Brace) {
|
||||
// parsing items even when they're not allowed lets us give
|
||||
|
@ -3932,7 +3878,6 @@ impl<'a> Parser<'a> {
|
|||
let hi = self.span.hi;
|
||||
self.bump();
|
||||
P(ast::Block {
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
expr: expr,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
|
@ -5031,39 +4976,34 @@ impl<'a> Parser<'a> {
|
|||
first_item_attrs: Vec<Attribute>,
|
||||
inner_lo: BytePos)
|
||||
-> Mod {
|
||||
// parse all of the items up to closing or an attribute.
|
||||
// view items are legal here.
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items: starting_items,
|
||||
..
|
||||
} = self.parse_items_and_view_items(first_item_attrs, true, true);
|
||||
let mut items: Vec<P<Item>> = starting_items;
|
||||
let attrs_remaining_len = attrs_remaining.len();
|
||||
// Parse all of the items up to closing or an attribute.
|
||||
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
let mut items = vec![];
|
||||
|
||||
loop {
|
||||
match self.parse_item_(attrs, true) {
|
||||
Err(returned_attrs) => {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
Ok(item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
items.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// don't think this other loop is even necessary....
|
||||
|
||||
let mut first = true;
|
||||
while self.token != term {
|
||||
let mut attrs = self.parse_outer_attributes();
|
||||
if first {
|
||||
let mut tmp = attrs_remaining.clone();
|
||||
tmp.push_all(&attrs[]);
|
||||
attrs = tmp;
|
||||
first = false;
|
||||
}
|
||||
debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
|
||||
attrs);
|
||||
match self.parse_item_or_view_item(attrs,
|
||||
true /* macros allowed */) {
|
||||
IoviItem(item) => items.push(item),
|
||||
IoviViewItem(view_item) => {
|
||||
self.span_fatal(view_item.span,
|
||||
"view items must be declared at the top of \
|
||||
the module");
|
||||
}
|
||||
_ => {
|
||||
let mut attrs = mem::replace(&mut attrs, vec![]);
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
|
||||
match self.parse_item_(attrs, true /* macros allowed */) {
|
||||
Ok(item) => items.push(item),
|
||||
Err(_) => {
|
||||
let token_str = self.this_token_to_string();
|
||||
self.fatal(&format!("expected item, found `{}`",
|
||||
token_str)[])
|
||||
|
@ -5071,16 +5011,15 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if first && attrs_remaining_len > 0us {
|
||||
if !attrs.is_empty() {
|
||||
// We parsed attributes for the first item but didn't find it
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs_remaining[]));
|
||||
Parser::expected_item_err(&attrs[]));
|
||||
}
|
||||
|
||||
ast::Mod {
|
||||
inner: mk_sp(inner_lo, self.span.lo),
|
||||
view_items: view_items,
|
||||
items: items
|
||||
}
|
||||
}
|
||||
|
@ -5300,21 +5239,10 @@ impl<'a> Parser<'a> {
|
|||
abi: abi::Abi,
|
||||
first_item_attrs: Vec<Attribute>)
|
||||
-> ForeignMod {
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items: _,
|
||||
foreign_items,
|
||||
} = self.parse_foreign_items(first_item_attrs, true);
|
||||
if !attrs_remaining.is_empty() {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs_remaining[]));
|
||||
}
|
||||
let foreign_items = self.parse_foreign_items(first_item_attrs);
|
||||
assert!(self.token == token::CloseDelim(token::Brace));
|
||||
ast::ForeignMod {
|
||||
abi: abi,
|
||||
view_items: view_items,
|
||||
items: foreign_items
|
||||
}
|
||||
}
|
||||
|
@ -5330,7 +5258,7 @@ impl<'a> Parser<'a> {
|
|||
lo: BytePos,
|
||||
visibility: Visibility,
|
||||
attrs: Vec<Attribute>)
|
||||
-> ItemOrViewItem {
|
||||
-> P<Item> {
|
||||
|
||||
let span = self.span;
|
||||
let (maybe_path, ident) = match self.token {
|
||||
|
@ -5374,12 +5302,13 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
};
|
||||
|
||||
IoviViewItem(ast::ViewItem {
|
||||
node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
})
|
||||
let last_span = self.last_span;
|
||||
self.mk_item(lo,
|
||||
last_span.hi,
|
||||
ident,
|
||||
ItemExternCrate(maybe_path),
|
||||
visibility,
|
||||
attrs)
|
||||
}
|
||||
|
||||
/// Parse `extern` for foreign ABIs
|
||||
|
@ -5397,7 +5326,7 @@ impl<'a> Parser<'a> {
|
|||
opt_abi: Option<abi::Abi>,
|
||||
visibility: Visibility,
|
||||
attrs: Vec<Attribute>)
|
||||
-> ItemOrViewItem {
|
||||
-> P<Item> {
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace));
|
||||
|
||||
|
@ -5408,13 +5337,12 @@ impl<'a> Parser<'a> {
|
|||
self.expect(&token::CloseDelim(token::Brace));
|
||||
|
||||
let last_span = self.last_span;
|
||||
let item = self.mk_item(lo,
|
||||
self.mk_item(lo,
|
||||
last_span.hi,
|
||||
special_idents::invalid,
|
||||
ItemForeignMod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner)));
|
||||
return IoviItem(item);
|
||||
maybe_append(attrs, Some(inner)))
|
||||
}
|
||||
|
||||
/// Parse type Foo = Bar;
|
||||
|
@ -5556,14 +5484,12 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Parse one of the items or view items allowed by the
|
||||
/// flags; on failure, return IoviNone.
|
||||
/// Parse one of the items allowed by the flags; on failure,
|
||||
/// return `Err(remaining_attrs)`.
|
||||
/// NB: this function no longer parses the items inside an
|
||||
/// extern crate.
|
||||
fn parse_item_or_view_item(&mut self,
|
||||
attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ItemOrViewItem {
|
||||
fn parse_item_(&mut self, attrs: Vec<Attribute>,
|
||||
macros_allowed: bool) -> MaybeItem {
|
||||
let nt_item = match self.token {
|
||||
token::Interpolated(token::NtItem(ref item)) => {
|
||||
Some((**item).clone())
|
||||
|
@ -5576,7 +5502,7 @@ impl<'a> Parser<'a> {
|
|||
let mut attrs = attrs;
|
||||
mem::swap(&mut item.attrs, &mut attrs);
|
||||
item.attrs.extend(attrs.into_iter());
|
||||
return IoviItem(P(item));
|
||||
return Ok(P(item));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
@ -5585,22 +5511,24 @@ impl<'a> Parser<'a> {
|
|||
|
||||
let visibility = self.parse_visibility();
|
||||
|
||||
// must be a view item:
|
||||
if self.eat_keyword(keywords::Use) {
|
||||
// USE ITEM (IoviViewItem)
|
||||
let view_item = self.parse_use();
|
||||
// USE ITEM
|
||||
let item_ = ItemUse(self.parse_view_path());
|
||||
self.expect(&token::Semi);
|
||||
return IoviViewItem(ast::ViewItem {
|
||||
node: view_item,
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
});
|
||||
|
||||
let last_span = self.last_span;
|
||||
let item = self.mk_item(lo,
|
||||
last_span.hi,
|
||||
token::special_idents::invalid,
|
||||
item_,
|
||||
visibility,
|
||||
attrs);
|
||||
return Ok(item);
|
||||
}
|
||||
// either a view item or an item:
|
||||
|
||||
if self.eat_keyword(keywords::Extern) {
|
||||
if self.eat_keyword(keywords::Crate) {
|
||||
return self.parse_item_extern_crate(lo, visibility, attrs);
|
||||
return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
|
||||
}
|
||||
|
||||
let opt_abi = self.parse_opt_abi();
|
||||
|
@ -5617,9 +5545,9 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
|
||||
return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
|
||||
}
|
||||
|
||||
let span = self.span;
|
||||
|
@ -5634,7 +5562,6 @@ impl<'a> Parser<'a> {
|
|||
self.span_err(span, "`virtual` structs have been removed from the language");
|
||||
}
|
||||
|
||||
// the rest are all guaranteed to be items:
|
||||
if self.token.is_keyword(keywords::Static) {
|
||||
// STATIC ITEM
|
||||
self.bump();
|
||||
|
@ -5647,7 +5574,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Const) {
|
||||
// CONST ITEM
|
||||
|
@ -5665,7 +5592,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe) &&
|
||||
self.look_ahead(1us, |t| t.is_keyword(keywords::Trait))
|
||||
|
@ -5682,7 +5609,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe) &&
|
||||
self.look_ahead(1us, |t| t.is_keyword(keywords::Impl))
|
||||
|
@ -5698,7 +5625,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Fn) {
|
||||
// FUNCTION ITEM
|
||||
|
@ -5712,7 +5639,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe)
|
||||
&& self.look_ahead(1us, |t| *t != token::OpenDelim(token::Brace)) {
|
||||
|
@ -5733,7 +5660,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Mod) {
|
||||
// MODULE ITEM
|
||||
|
@ -5746,7 +5673,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Type) {
|
||||
// TYPE ITEM
|
||||
|
@ -5758,7 +5685,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Enum) {
|
||||
// ENUM ITEM
|
||||
|
@ -5770,7 +5697,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Trait) {
|
||||
// TRAIT ITEM
|
||||
|
@ -5783,7 +5710,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Impl) {
|
||||
// IMPL ITEM
|
||||
|
@ -5795,7 +5722,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Struct) {
|
||||
// STRUCT ITEM
|
||||
|
@ -5807,32 +5734,30 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||
}
|
||||
|
||||
/// Parse a foreign item; on failure, return IoviNone.
|
||||
fn parse_foreign_item(&mut self,
|
||||
attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ItemOrViewItem {
|
||||
maybe_whole!(iovi self, NtItem);
|
||||
/// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
|
||||
fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
|
||||
-> Result<P<ForeignItem>, Vec<Attribute>> {
|
||||
let lo = self.span.lo;
|
||||
|
||||
let visibility = self.parse_visibility();
|
||||
|
||||
if self.token.is_keyword(keywords::Static) {
|
||||
// FOREIGN STATIC ITEM
|
||||
let item = self.parse_item_foreign_static(visibility, attrs);
|
||||
return IoviForeignItem(item);
|
||||
return Ok(self.parse_item_foreign_static(visibility, attrs));
|
||||
}
|
||||
if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
|
||||
// FOREIGN FUNCTION ITEM
|
||||
let item = self.parse_item_foreign_fn(visibility, attrs);
|
||||
return IoviForeignItem(item);
|
||||
return Ok(self.parse_item_foreign_fn(visibility, attrs));
|
||||
}
|
||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
|
||||
self.span_fatal(item.span, "macros cannot expand to foreign items");
|
||||
}
|
||||
|
||||
/// This is the fall-through for parsing items.
|
||||
|
@ -5842,7 +5767,7 @@ impl<'a> Parser<'a> {
|
|||
macros_allowed: bool,
|
||||
lo: BytePos,
|
||||
visibility: Visibility
|
||||
) -> ItemOrViewItem {
|
||||
) -> MaybeItem {
|
||||
if macros_allowed && !self.token.is_any_keyword()
|
||||
&& self.look_ahead(1, |t| *t == token::Not)
|
||||
&& (self.look_ahead(2, |t| t.is_plain_ident())
|
||||
|
@ -5891,7 +5816,7 @@ impl<'a> Parser<'a> {
|
|||
item_,
|
||||
visibility,
|
||||
attrs);
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
|
||||
// FAILURE TO PARSE ITEM
|
||||
|
@ -5902,7 +5827,7 @@ impl<'a> Parser<'a> {
|
|||
self.span_fatal(last_span, "unmatched visibility `pub`");
|
||||
}
|
||||
}
|
||||
return IoviNone(attrs);
|
||||
Err(attrs)
|
||||
}
|
||||
|
||||
pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
|
||||
|
@ -5911,29 +5836,8 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
|
||||
match self.parse_item_or_view_item(attrs, true) {
|
||||
IoviNone(_) => None,
|
||||
IoviViewItem(_) =>
|
||||
self.fatal("view items are not allowed here"),
|
||||
IoviForeignItem(_) =>
|
||||
self.fatal("foreign items are not allowed here"),
|
||||
IoviItem(item) => Some(item)
|
||||
self.parse_item_(attrs, true).ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a ViewItem, e.g. `use foo::bar` or `extern crate foo`
|
||||
pub fn parse_view_item(&mut self, attrs: Vec<Attribute>) -> ViewItem {
|
||||
match self.parse_item_or_view_item(attrs, false) {
|
||||
IoviViewItem(vi) => vi,
|
||||
_ => self.fatal("expected `use` or `extern crate`"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse, e.g., "use a::b::{z,y}"
|
||||
fn parse_use(&mut self) -> ViewItem_ {
|
||||
return ViewItemUse(self.parse_view_path());
|
||||
}
|
||||
|
||||
|
||||
/// Matches view_path : MOD? non_global_path as IDENT
|
||||
/// | MOD? non_global_path MOD_SEP LBRACE RBRACE
|
||||
|
@ -5959,8 +5863,7 @@ impl<'a> Parser<'a> {
|
|||
global: false,
|
||||
segments: Vec::new()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||
}
|
||||
|
||||
let first_ident = self.parse_ident();
|
||||
|
@ -5994,8 +5897,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}).collect()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||
}
|
||||
|
||||
// foo::bar::*
|
||||
|
@ -6011,8 +5913,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}).collect()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathGlob(path, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
|
||||
}
|
||||
|
||||
_ => break
|
||||
|
@ -6033,136 +5934,39 @@ impl<'a> Parser<'a> {
|
|||
if self.eat_keyword(keywords::As) {
|
||||
rename_to = self.parse_ident()
|
||||
}
|
||||
P(spanned(lo,
|
||||
self.last_span.hi,
|
||||
ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
|
||||
/// Parses a sequence of items. Stops when it finds program
|
||||
/// text that can't be parsed as an item
|
||||
/// - mod_items uses extern_mod_allowed = true
|
||||
/// - block_tail_ uses extern_mod_allowed = false
|
||||
fn parse_items_and_view_items(&mut self,
|
||||
first_item_attrs: Vec<Attribute> ,
|
||||
mut extern_mod_allowed: bool,
|
||||
macros_allowed: bool)
|
||||
-> ParsedItemsAndViewItems {
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
// First, parse view items.
|
||||
let mut view_items : Vec<ast::ViewItem> = Vec::new();
|
||||
let mut items = Vec::new();
|
||||
|
||||
// I think this code would probably read better as a single
|
||||
// loop with a mutable three-state-variable (for extern crates,
|
||||
// view items, and regular items) ... except that because
|
||||
// of macros, I'd like to delay that entire check until later.
|
||||
loop {
|
||||
match self.parse_item_or_view_item(attrs, macros_allowed) {
|
||||
IoviNone(attrs) => {
|
||||
return ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: view_items,
|
||||
items: items,
|
||||
foreign_items: Vec::new()
|
||||
}
|
||||
}
|
||||
IoviViewItem(view_item) => {
|
||||
match view_item.node {
|
||||
ViewItemUse(..) => {
|
||||
// `extern crate` must precede `use`.
|
||||
extern_mod_allowed = false;
|
||||
}
|
||||
ViewItemExternCrate(..) if !extern_mod_allowed => {
|
||||
self.span_err(view_item.span,
|
||||
"\"extern crate\" declarations are \
|
||||
not allowed here");
|
||||
}
|
||||
ViewItemExternCrate(..) => {}
|
||||
}
|
||||
view_items.push(view_item);
|
||||
}
|
||||
IoviItem(item) => {
|
||||
items.push(item);
|
||||
attrs = self.parse_outer_attributes();
|
||||
break;
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
|
||||
// Next, parse items.
|
||||
loop {
|
||||
match self.parse_item_or_view_item(attrs, macros_allowed) {
|
||||
IoviNone(returned_attrs) => {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
IoviViewItem(view_item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
self.span_err(view_item.span,
|
||||
"`use` and `extern crate` declarations must precede items");
|
||||
}
|
||||
IoviItem(item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
items.push(item)
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: view_items,
|
||||
items: items,
|
||||
foreign_items: Vec::new()
|
||||
}
|
||||
P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
|
||||
}
|
||||
|
||||
/// Parses a sequence of foreign items. Stops when it finds program
|
||||
/// text that can't be parsed as an item
|
||||
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ParsedItemsAndViewItems {
|
||||
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
|
||||
-> Vec<P<ForeignItem>> {
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
let mut foreign_items = Vec::new();
|
||||
loop {
|
||||
match self.parse_foreign_item(attrs, macros_allowed) {
|
||||
IoviNone(returned_attrs) => {
|
||||
match self.parse_foreign_item(attrs) {
|
||||
Ok(foreign_item) => {
|
||||
foreign_items.push(foreign_item);
|
||||
}
|
||||
Err(returned_attrs) => {
|
||||
if self.check(&token::CloseDelim(token::Brace)) {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
self.unexpected();
|
||||
},
|
||||
IoviViewItem(view_item) => {
|
||||
// I think this can't occur:
|
||||
self.span_err(view_item.span,
|
||||
"`use` and `extern crate` declarations must precede items");
|
||||
}
|
||||
IoviItem(item) => {
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
self.span_fatal(item.span, "macros cannot expand to foreign items");
|
||||
}
|
||||
IoviForeignItem(foreign_item) => {
|
||||
foreign_items.push(foreign_item);
|
||||
}
|
||||
}
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
|
||||
ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: Vec::new(),
|
||||
items: Vec::new(),
|
||||
foreign_items: foreign_items
|
||||
if !attrs.is_empty() {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs[]));
|
||||
}
|
||||
|
||||
foreign_items
|
||||
}
|
||||
|
||||
/// Parses a source module as a crate. This is the main
|
||||
|
|
|
@ -337,10 +337,6 @@ pub fn item_to_string(i: &ast::Item) -> String {
|
|||
$to_string(|s| s.print_item(i))
|
||||
}
|
||||
|
||||
pub fn view_item_to_string(i: &ast::ViewItem) -> String {
|
||||
$to_string(|s| s.print_view_item(i))
|
||||
}
|
||||
|
||||
pub fn generics_to_string(generics: &ast::Generics) -> String {
|
||||
$to_string(|s| s.print_generics(generics))
|
||||
}
|
||||
|
@ -638,9 +634,6 @@ impl<'a> State<'a> {
|
|||
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
||||
try!(self.print_inner_attributes(attrs));
|
||||
for vitem in _mod.view_items.iter() {
|
||||
try!(self.print_view_item(vitem));
|
||||
}
|
||||
for item in _mod.items.iter() {
|
||||
try!(self.print_item(&**item));
|
||||
}
|
||||
|
@ -650,9 +643,6 @@ impl<'a> State<'a> {
|
|||
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
||||
try!(self.print_inner_attributes(attrs));
|
||||
for vitem in nmod.view_items.iter() {
|
||||
try!(self.print_view_item(vitem));
|
||||
}
|
||||
for item in nmod.items.iter() {
|
||||
try!(self.print_foreign_item(&**item));
|
||||
}
|
||||
|
@ -809,6 +799,28 @@ impl<'a> State<'a> {
|
|||
try!(self.print_outer_attributes(&item.attrs[]));
|
||||
try!(self.ann.pre(self, NodeItem(item)));
|
||||
match item.node {
|
||||
ast::ItemExternCrate(ref optional_path) => {
|
||||
try!(self.head(&visibility_qualified(item.vis,
|
||||
"extern crate")[]));
|
||||
for &(ref p, style) in optional_path.iter() {
|
||||
try!(self.print_string(p.get(), style));
|
||||
try!(space(&mut self.s));
|
||||
try!(word(&mut self.s, "as"));
|
||||
try!(space(&mut self.s));
|
||||
}
|
||||
try!(self.print_ident(item.ident));
|
||||
try!(word(&mut self.s, ";"));
|
||||
try!(self.end()); // end inner head-block
|
||||
try!(self.end()); // end outer head-block
|
||||
}
|
||||
ast::ItemUse(ref vp) => {
|
||||
try!(self.head(&visibility_qualified(item.vis,
|
||||
"use")[]));
|
||||
try!(self.print_view_path(&**vp));
|
||||
try!(word(&mut self.s, ";"));
|
||||
try!(self.end()); // end inner head-block
|
||||
try!(self.end()); // end outer head-block
|
||||
}
|
||||
ast::ItemStatic(ref ty, m, ref expr) => {
|
||||
try!(self.head(&visibility_qualified(item.vis,
|
||||
"static")[]));
|
||||
|
@ -1380,9 +1392,6 @@ impl<'a> State<'a> {
|
|||
|
||||
try!(self.print_inner_attributes(attrs));
|
||||
|
||||
for vi in blk.view_items.iter() {
|
||||
try!(self.print_view_item(vi));
|
||||
}
|
||||
for st in blk.stmts.iter() {
|
||||
try!(self.print_stmt(&**st));
|
||||
}
|
||||
|
@ -2577,7 +2586,7 @@ impl<'a> State<'a> {
|
|||
|
||||
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
|
||||
match vp.node {
|
||||
ast::ViewPathSimple(ident, ref path, _) => {
|
||||
ast::ViewPathSimple(ident, ref path) => {
|
||||
try!(self.print_path(path, false));
|
||||
|
||||
// FIXME(#6993) can't compare identifiers directly here
|
||||
|
@ -2591,12 +2600,12 @@ impl<'a> State<'a> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
ast::ViewPathGlob(ref path, _) => {
|
||||
ast::ViewPathGlob(ref path) => {
|
||||
try!(self.print_path(path, false));
|
||||
word(&mut self.s, "::*")
|
||||
}
|
||||
|
||||
ast::ViewPathList(ref path, ref idents, _) => {
|
||||
ast::ViewPathList(ref path, ref idents) => {
|
||||
if path.segments.is_empty() {
|
||||
try!(word(&mut self.s, "{"));
|
||||
} else {
|
||||
|
@ -2618,33 +2627,6 @@ impl<'a> State<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn print_view_item(&mut self, item: &ast::ViewItem) -> IoResult<()> {
|
||||
try!(self.hardbreak_if_not_bol());
|
||||
try!(self.maybe_print_comment(item.span.lo));
|
||||
try!(self.print_outer_attributes(&item.attrs[]));
|
||||
try!(self.print_visibility(item.vis));
|
||||
match item.node {
|
||||
ast::ViewItemExternCrate(id, ref optional_path, _) => {
|
||||
try!(self.head("extern crate"));
|
||||
for &(ref p, style) in optional_path.iter() {
|
||||
try!(self.print_string(p.get(), style));
|
||||
try!(space(&mut self.s));
|
||||
try!(word(&mut self.s, "as"));
|
||||
try!(space(&mut self.s));
|
||||
}
|
||||
try!(self.print_ident(id));
|
||||
}
|
||||
|
||||
ast::ViewItemUse(ref vp) => {
|
||||
try!(self.head("use"));
|
||||
try!(self.print_view_path(&**vp));
|
||||
}
|
||||
}
|
||||
try!(word(&mut self.s, ";"));
|
||||
try!(self.end()); // end inner head-block
|
||||
self.end() // end outer head-block
|
||||
}
|
||||
|
||||
pub fn print_mutability(&mut self,
|
||||
mutbl: ast::Mutability) -> IoResult<()> {
|
||||
match mutbl {
|
||||
|
|
|
@ -20,8 +20,6 @@ use parse::token;
|
|||
use ptr::P;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::mem;
|
||||
|
||||
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
|
||||
-> ast::Crate {
|
||||
if use_std(&krate) {
|
||||
|
@ -60,20 +58,16 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
|||
None => token::intern_and_get_ident("std"),
|
||||
};
|
||||
|
||||
let mut vis = vec!(ast::ViewItem {
|
||||
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
|
||||
Some((actual_crate_name, ast::CookedStr)),
|
||||
ast::DUMMY_NODE_ID),
|
||||
krate.module.items.insert(0, P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: token::str_to_ident("std"),
|
||||
attrs: vec!(
|
||||
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
|
||||
InternedString::new("macro_use")))),
|
||||
node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP
|
||||
});
|
||||
|
||||
// `extern crate` must be precede `use` items
|
||||
mem::swap(&mut vis, &mut krate.module.view_items);
|
||||
krate.module.view_items.extend(vis.into_iter());
|
||||
}));
|
||||
|
||||
// don't add #![no_std] here, that will block the prelude injection later.
|
||||
// Add it during the prelude injection instead.
|
||||
|
@ -123,7 +117,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
|
||||
fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
|
||||
let prelude_path = ast::Path {
|
||||
span: DUMMY_SP,
|
||||
global: false,
|
||||
|
@ -143,18 +137,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
],
|
||||
};
|
||||
|
||||
let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| {
|
||||
match x.node {
|
||||
ast::ViewItemExternCrate(..) => true,
|
||||
_ => false,
|
||||
}
|
||||
});
|
||||
|
||||
// add prelude after any `extern crate` but before any `use`
|
||||
let mut view_items = crates;
|
||||
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID)));
|
||||
view_items.push(ast::ViewItem {
|
||||
node: ast::ViewItemUse(vp),
|
||||
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
|
||||
mod_.items.insert(0, P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: special_idents::invalid,
|
||||
node: ast::ItemUse(vp),
|
||||
attrs: vec![ast::Attribute {
|
||||
span: DUMMY_SP,
|
||||
node: ast::Attribute_ {
|
||||
|
@ -170,14 +157,9 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
|||
}],
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP,
|
||||
});
|
||||
view_items.extend(uses.into_iter());
|
||||
}));
|
||||
|
||||
fold::noop_fold_mod(ast::Mod {
|
||||
inner: inner,
|
||||
view_items: view_items,
|
||||
items: items
|
||||
}, self)
|
||||
fold::noop_fold_mod(mod_, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,11 +105,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
// Add a special __test module to the crate that will contain code
|
||||
// generated for the test harness
|
||||
let (mod_, reexport) = mk_test_module(&mut self.cx);
|
||||
folded.module.items.push(mod_);
|
||||
match reexport {
|
||||
Some(re) => folded.module.view_items.push(re),
|
||||
Some(re) => folded.module.items.push(re),
|
||||
None => {}
|
||||
}
|
||||
folded.module.items.push(mod_);
|
||||
folded
|
||||
}
|
||||
|
||||
|
@ -205,22 +205,19 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
|||
|
||||
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
||||
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
|
||||
let mut view_items = Vec::new();
|
||||
let super_ = token::str_to_ident("super");
|
||||
|
||||
view_items.extend(tests.into_iter().map(|r| {
|
||||
cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public,
|
||||
let items = tests.into_iter().map(|r| {
|
||||
cx.ext_cx.item_use_simple(DUMMY_SP, ast::Public,
|
||||
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
|
||||
}));
|
||||
view_items.extend(tested_submods.into_iter().map(|(r, sym)| {
|
||||
}).chain(tested_submods.into_iter().map(|(r, sym)| {
|
||||
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
|
||||
cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path)
|
||||
cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Public, r, path)
|
||||
}));
|
||||
|
||||
let reexport_mod = ast::Mod {
|
||||
inner: DUMMY_SP,
|
||||
view_items: view_items,
|
||||
items: Vec::new(),
|
||||
items: items.collect(),
|
||||
};
|
||||
|
||||
let sym = token::gensym_ident("__test_reexports");
|
||||
|
@ -388,29 +385,29 @@ mod __test {
|
|||
|
||||
*/
|
||||
|
||||
fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
|
||||
fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
|
||||
let id_test = token::str_to_ident("test");
|
||||
let (vi, vis) = if cx.is_test_crate {
|
||||
(ast::ViewItemUse(
|
||||
let (vi, vis, ident) = if cx.is_test_crate {
|
||||
(ast::ItemUse(
|
||||
P(nospan(ast::ViewPathSimple(id_test,
|
||||
path_node(vec!(id_test)),
|
||||
ast::DUMMY_NODE_ID)))),
|
||||
ast::Public)
|
||||
path_node(vec!(id_test)))))),
|
||||
ast::Public, token::special_idents::invalid)
|
||||
} else {
|
||||
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
|
||||
ast::Inherited)
|
||||
(ast::ItemExternCrate(None), ast::Inherited, id_test)
|
||||
};
|
||||
ast::ViewItem {
|
||||
P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: ident,
|
||||
node: vi,
|
||||
attrs: Vec::new(),
|
||||
attrs: vec![],
|
||||
vis: vis,
|
||||
span: DUMMY_SP
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
|
||||
fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
|
||||
// Link to test crate
|
||||
let view_items = vec!(mk_std(cx));
|
||||
let import = mk_std(cx);
|
||||
|
||||
// A constant vector of test descriptors.
|
||||
let tests = mk_tests(cx);
|
||||
|
@ -427,8 +424,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
|
|||
|
||||
let testmod = ast::Mod {
|
||||
inner: DUMMY_SP,
|
||||
view_items: view_items,
|
||||
items: vec!(mainfn, tests),
|
||||
items: vec![import, mainfn, tests],
|
||||
};
|
||||
let item_ = ast::ItemMod(testmod);
|
||||
|
||||
|
@ -439,34 +435,35 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
|
|||
vec![unstable])));
|
||||
attr::mk_attr_inner(attr::mk_attr_id(), allow)
|
||||
};
|
||||
let item = ast::Item {
|
||||
ident: mod_ident,
|
||||
let item = P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: mod_ident,
|
||||
attrs: vec![allow_unstable],
|
||||
node: item_,
|
||||
vis: ast::Public,
|
||||
span: DUMMY_SP,
|
||||
attrs: vec![allow_unstable],
|
||||
};
|
||||
});
|
||||
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
|
||||
// building `use <ident> = __test::main`
|
||||
let reexport_ident = token::str_to_ident(s.get());
|
||||
|
||||
let use_path =
|
||||
nospan(ast::ViewPathSimple(reexport_ident,
|
||||
path_node(vec![mod_ident, token::str_to_ident("main")]),
|
||||
ast::DUMMY_NODE_ID));
|
||||
path_node(vec![mod_ident, token::str_to_ident("main")])));
|
||||
|
||||
ast::ViewItem {
|
||||
node: ast::ViewItemUse(P(use_path)),
|
||||
P(ast::Item {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
ident: token::special_idents::invalid,
|
||||
attrs: vec![],
|
||||
node: ast::ItemUse(P(use_path)),
|
||||
vis: ast::Inherited,
|
||||
span: DUMMY_SP
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
|
||||
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&*item));
|
||||
|
||||
(P(item), reexport)
|
||||
(item, reexport)
|
||||
}
|
||||
|
||||
fn nospan<T>(t: T) -> codemap::Spanned<T> {
|
||||
|
|
|
@ -69,13 +69,6 @@ pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
|
|||
})
|
||||
}
|
||||
|
||||
/// Parse a string, return a view item
|
||||
pub fn string_to_view_item (source_str : String) -> ast::ViewItem {
|
||||
with_error_checking_parse(source_str, |p| {
|
||||
p.parse_view_item(Vec::new())
|
||||
})
|
||||
}
|
||||
|
||||
/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
|
||||
/// (currently) affect parsing.
|
||||
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
|
||||
|
|
|
@ -62,7 +62,6 @@ pub trait Visitor<'v> : Sized {
|
|||
self.visit_name(span, ident.name);
|
||||
}
|
||||
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
|
||||
fn visit_view_item(&mut self, i: &'v ViewItem) { walk_view_item(self, i) }
|
||||
fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) }
|
||||
fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) }
|
||||
fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
|
||||
|
@ -166,51 +165,11 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
|
|||
}
|
||||
|
||||
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
|
||||
for view_item in module.view_items.iter() {
|
||||
visitor.visit_view_item(view_item)
|
||||
}
|
||||
|
||||
for item in module.items.iter() {
|
||||
visitor.visit_item(&**item)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
|
||||
match vi.node {
|
||||
ViewItemExternCrate(name, _, _) => {
|
||||
visitor.visit_ident(vi.span, name)
|
||||
}
|
||||
ViewItemUse(ref vp) => {
|
||||
match vp.node {
|
||||
ViewPathSimple(ident, ref path, id) => {
|
||||
visitor.visit_ident(vp.span, ident);
|
||||
visitor.visit_path(path, id);
|
||||
}
|
||||
ViewPathGlob(ref path, id) => {
|
||||
visitor.visit_path(path, id);
|
||||
}
|
||||
ViewPathList(ref prefix, ref list, _) => {
|
||||
for id in list.iter() {
|
||||
match id.node {
|
||||
PathListIdent { name, .. } => {
|
||||
visitor.visit_ident(id.span, name);
|
||||
}
|
||||
PathListMod { .. } => ()
|
||||
}
|
||||
}
|
||||
|
||||
// Note that the `prefix` here is not a complete
|
||||
// path, so we don't use `visit_path`.
|
||||
walk_path(visitor, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for attr in vi.attrs.iter() {
|
||||
visitor.visit_attribute(attr);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
|
||||
visitor.visit_pat(&*local.pat);
|
||||
walk_ty_opt(visitor, &local.ty);
|
||||
|
@ -269,6 +228,32 @@ pub fn walk_trait_ref<'v,V>(visitor: &mut V,
|
|||
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||
visitor.visit_ident(item.span, item.ident);
|
||||
match item.node {
|
||||
ItemExternCrate(..) => {}
|
||||
ItemUse(ref vp) => {
|
||||
match vp.node {
|
||||
ViewPathSimple(ident, ref path) => {
|
||||
visitor.visit_ident(vp.span, ident);
|
||||
visitor.visit_path(path, item.id);
|
||||
}
|
||||
ViewPathGlob(ref path) => {
|
||||
visitor.visit_path(path, item.id);
|
||||
}
|
||||
ViewPathList(ref prefix, ref list) => {
|
||||
for id in list.iter() {
|
||||
match id.node {
|
||||
PathListIdent { name, .. } => {
|
||||
visitor.visit_ident(id.span, name);
|
||||
}
|
||||
PathListMod { .. } => ()
|
||||
}
|
||||
}
|
||||
|
||||
// Note that the `prefix` here is not a complete
|
||||
// path, so we don't use `visit_path`.
|
||||
walk_path(visitor, prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
ItemStatic(ref typ, _, ref expr) |
|
||||
ItemConst(ref typ, ref expr) => {
|
||||
visitor.visit_ty(&**typ);
|
||||
|
@ -285,9 +270,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
|||
visitor.visit_mod(module, item.span, item.id)
|
||||
}
|
||||
ItemForeignMod(ref foreign_module) => {
|
||||
for view_item in foreign_module.view_items.iter() {
|
||||
visitor.visit_view_item(view_item)
|
||||
}
|
||||
for foreign_item in foreign_module.items.iter() {
|
||||
visitor.visit_foreign_item(&**foreign_item)
|
||||
}
|
||||
|
@ -732,9 +714,6 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
|
|||
}
|
||||
|
||||
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
|
||||
for view_item in block.view_items.iter() {
|
||||
visitor.visit_view_item(view_item)
|
||||
}
|
||||
for statement in block.stmts.iter() {
|
||||
visitor.visit_stmt(&**statement)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -8,8 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub extern crate core; //~ ERROR: `pub` visibility is not allowed
|
||||
#![crate_type="lib"]
|
||||
|
||||
fn main() {
|
||||
pub use std::usize; //~ ERROR: imports in functions are never reachable
|
||||
}
|
||||
pub const X: () = ();
|
13
src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
Normal file
13
src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![crate_type="lib"]
|
||||
|
||||
pub const Y: () = ();
|
|
@ -11,8 +11,7 @@
|
|||
// aux-build:macro_crate_test.rs
|
||||
// ignore-stage1
|
||||
|
||||
#[plugin] #[no_link]
|
||||
#[plugin] #[no_link] extern crate macro_crate_test;
|
||||
//~^ ERROR compiler plugins are experimental and possibly buggy
|
||||
extern crate macro_crate_test;
|
||||
|
||||
fn main() {}
|
||||
|
|
20
src/test/compile-fail/blind-item-block-item-shadow.rs
Normal file
20
src/test/compile-fail/blind-item-block-item-shadow.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod foo { pub struct Bar; }
|
||||
|
||||
fn main() {
|
||||
{
|
||||
struct Bar;
|
||||
use foo::Bar;
|
||||
//~^ ERROR import `Bar` conflicts with type in this module
|
||||
//~^^ ERROR import `Bar` conflicts with value in this module
|
||||
}
|
||||
}
|
18
src/test/compile-fail/blind-item-block-middle.rs
Normal file
18
src/test/compile-fail/blind-item-block-middle.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod foo { struct bar; }
|
||||
|
||||
fn main() {
|
||||
let bar = 5;
|
||||
//~^ ERROR declaration of `bar` shadows an enum variant or unit-like struct in scope
|
||||
use foo::bar;
|
||||
//~^ ERROR imports are not allowed after non-item statements
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -8,12 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate test;
|
||||
mod foo { pub mod foo { } }
|
||||
|
||||
fn f() {
|
||||
}
|
||||
use foo::foo; //~ ERROR import `foo` conflicts with existing submodule
|
||||
|
||||
use test::net; //~ ERROR `use` and `extern crate` declarations must precede items
|
||||
|
||||
fn main() {
|
||||
}
|
||||
fn main() {}
|
20
src/test/compile-fail/blind-item-local-shadow.rs
Normal file
20
src/test/compile-fail/blind-item-local-shadow.rs
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod bar {
|
||||
pub fn foo() -> bool { true }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = |&:| false;
|
||||
use bar::foo;
|
||||
//~^ ERROR imports are not allowed after non-item statements
|
||||
assert_eq!(foo(), false);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -9,6 +9,7 @@
|
|||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
pub use std::uint; //~ ERROR: visibility has no effect
|
||||
pub struct A; //~ ERROR: visibility has no effect
|
||||
pub enum B {} //~ ERROR: visibility has no effect
|
||||
pub trait C { //~ ERROR: visibility has no effect
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#![no_std]
|
||||
#[macro_use]
|
||||
extern crate "std" as std;
|
||||
#[prelude_import]
|
||||
use std::prelude::v1::*;
|
||||
#[macro_use]
|
||||
extern crate "std" as std;
|
||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
|
|
33
src/test/run-pass/blind-item-mixed-crate-use-item.rs
Normal file
33
src/test/run-pass/blind-item-mixed-crate-use-item.rs
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// aux-build:blind-item-mixed-crate-use-item-foo.rs
|
||||
// aux-build:blind-item-mixed-crate-use-item-foo2.rs
|
||||
|
||||
mod m {
|
||||
pub fn f<T>(_: T, _: (), _: ()) { }
|
||||
pub fn g<T>(_: T, _: (), _: ()) { }
|
||||
}
|
||||
|
||||
const BAR: () = ();
|
||||
struct Data;
|
||||
use m::f;
|
||||
extern crate "blind-item-mixed-crate-use-item-foo" as foo;
|
||||
|
||||
fn main() {
|
||||
const BAR2: () = ();
|
||||
struct Data2;
|
||||
use m::g;
|
||||
|
||||
extern crate "blind-item-mixed-crate-use-item-foo2" as foo2;
|
||||
|
||||
f(Data, BAR, foo::X);
|
||||
g(Data2, BAR2, foo2::Y);
|
||||
}
|
27
src/test/run-pass/blind-item-mixed-use-item.rs
Normal file
27
src/test/run-pass/blind-item-mixed-use-item.rs
Normal file
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2015 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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod m {
|
||||
pub fn f<T>(_: T, _: ()) { }
|
||||
pub fn g<T>(_: T, _: ()) { }
|
||||
}
|
||||
|
||||
const BAR: () = ();
|
||||
struct Data;
|
||||
use m::f;
|
||||
|
||||
fn main() {
|
||||
const BAR2: () = ();
|
||||
struct Data2;
|
||||
use m::g;
|
||||
|
||||
f(Data, BAR);
|
||||
g(Data2, BAR2);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue