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
|
## Items
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
item : mod_item | fn_item | type_item | struct_item | enum_item
|
item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
|
||||||
| static_item | trait_item | impl_item | extern_block ;
|
| 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
|
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:
|
There are several kinds of item:
|
||||||
|
|
||||||
|
* [`extern crate` declarations](#extern-crate-declarations)
|
||||||
|
* [`use` declarations](#use-declarations)
|
||||||
* [modules](#modules)
|
* [modules](#modules)
|
||||||
* [functions](#functions)
|
* [functions](#functions)
|
||||||
* [type definitions](#type-definitions)
|
* [type definitions](#type-definitions)
|
||||||
|
@ -854,13 +857,10 @@ no notion of type abstraction: there are no first-class "forall" types.
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
mod_item : "mod" ident ( ';' | '{' mod '}' );
|
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
|
A module is a container for zero or more [items](#items).
|
||||||
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 item_ is a module, surrounded in braces, named, and prefixed with the
|
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
|
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
|
##### Extern crate declarations
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
|
@ -2887,13 +2874,12 @@ Point3d {y: 0, z: 10, .. base};
|
||||||
### Block expressions
|
### Block expressions
|
||||||
|
|
||||||
```{.ebnf .gram}
|
```{.ebnf .gram}
|
||||||
block_expr : '{' [ view_item ] *
|
block_expr : '{' [ stmt ';' | item ] *
|
||||||
[ stmt ';' | item ] *
|
|
||||||
[ expr ] '}' ;
|
[ expr ] '}' ;
|
||||||
```
|
```
|
||||||
|
|
||||||
A _block expression_ is similar to a module in terms of the declarations that
|
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
|
items can bring new names into scopes and declared items are in scope for only
|
||||||
the block itself.
|
the block itself.
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ register_diagnostics! {
|
||||||
E0138,
|
E0138,
|
||||||
E0139,
|
E0139,
|
||||||
E0152,
|
E0152,
|
||||||
|
E0153,
|
||||||
|
E0154,
|
||||||
|
E0157,
|
||||||
E0158,
|
E0158,
|
||||||
E0161,
|
E0161,
|
||||||
E0162,
|
E0162,
|
||||||
|
|
|
@ -1202,17 +1202,17 @@ impl LintPass for UnusedImportBraces {
|
||||||
lint_array!(UNUSED_IMPORT_BRACES)
|
lint_array!(UNUSED_IMPORT_BRACES)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
|
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
|
||||||
match view_item.node {
|
match item.node {
|
||||||
ast::ViewItemUse(ref view_path) => {
|
ast::ItemUse(ref view_path) => {
|
||||||
match view_path.node {
|
match view_path.node {
|
||||||
ast::ViewPathList(_, ref items, _) => {
|
ast::ViewPathList(_, ref items) => {
|
||||||
if items.len() == 1 {
|
if items.len() == 1 {
|
||||||
match items[0].node {
|
match items[0].node {
|
||||||
ast::PathListIdent {ref name, ..} => {
|
ast::PathListIdent {ref name, ..} => {
|
||||||
let m = format!("braces around {} is unnecessary",
|
let m = format!("braces around {} is unnecessary",
|
||||||
token::get_ident(*name).get());
|
token::get_ident(*name).get());
|
||||||
cx.span_lint(UNUSED_IMPORT_BRACES, view_item.span,
|
cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
|
||||||
&m[]);
|
&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) {
|
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
|
||||||
if self.is_internal(cx, e.span) { return; }
|
if self.is_internal(cx, e.span) { return; }
|
||||||
|
|
||||||
|
@ -1776,6 +1760,17 @@ impl LintPass for Stability {
|
||||||
if self.is_internal(cx, item.span) { return }
|
if self.is_internal(cx, item.span) { return }
|
||||||
|
|
||||||
match item.node {
|
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, _) => {
|
ast::ItemTrait(_, _, ref supertraits, _) => {
|
||||||
for t in supertraits.iter() {
|
for t in supertraits.iter() {
|
||||||
if let ast::TraitTyParamBound(ref t, _) = *t {
|
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) {
|
fn visit_pat(&mut self, p: &ast::Pat) {
|
||||||
run_lints!(self, check_pat, p);
|
run_lints!(self, check_pat, p);
|
||||||
visit::walk_pat(self, p);
|
visit::walk_pat(self, p);
|
||||||
|
|
|
@ -128,7 +128,6 @@ pub trait LintPass {
|
||||||
fn check_crate(&mut self, _: &Context, _: &ast::Crate) { }
|
fn check_crate(&mut self, _: &Context, _: &ast::Crate) { }
|
||||||
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
|
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
|
||||||
fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span, _: ast::NodeId) { }
|
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_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) { }
|
||||||
fn check_item(&mut self, _: &Context, _: &ast::Item) { }
|
fn check_item(&mut self, _: &Context, _: &ast::Item) { }
|
||||||
fn check_local(&mut self, _: &Context, _: &ast::Local) { }
|
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> {
|
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) {
|
fn visit_item(&mut self, a: &ast::Item) {
|
||||||
self.process_item(a);
|
self.process_item(a);
|
||||||
visit::walk_item(self, 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")
|
!attr::contains_name(&i.attrs[], "no_link")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CrateInfo {
|
struct CrateInfo {
|
||||||
|
@ -181,29 +176,10 @@ impl<'a> CrateReader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_view_item(&mut self, i: &ast::ViewItem) {
|
fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
|
||||||
if !should_link(i) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.extract_crate_info(i) {
|
|
||||||
Some(info) => {
|
|
||||||
let (cnum, _, _) = self.resolve_crate(&None,
|
|
||||||
&info.ident[],
|
|
||||||
&info.name[],
|
|
||||||
None,
|
|
||||||
i.span,
|
|
||||||
PathKind::Crate);
|
|
||||||
self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
|
||||||
}
|
|
||||||
None => ()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn extract_crate_info(&self, i: &ast::ViewItem) -> Option<CrateInfo> {
|
|
||||||
match i.node {
|
match i.node {
|
||||||
ast::ViewItemExternCrate(ident, ref path_opt, id) => {
|
ast::ItemExternCrate(ref path_opt) => {
|
||||||
let ident = token::get_ident(ident);
|
let ident = token::get_ident(i.ident);
|
||||||
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
|
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
|
||||||
ident, path_opt);
|
ident, path_opt);
|
||||||
let name = match *path_opt {
|
let name = match *path_opt {
|
||||||
|
@ -218,7 +194,7 @@ impl<'a> CrateReader<'a> {
|
||||||
Some(CrateInfo {
|
Some(CrateInfo {
|
||||||
ident: ident.get().to_string(),
|
ident: ident.get().to_string(),
|
||||||
name: name,
|
name: name,
|
||||||
id: id,
|
id: i.id,
|
||||||
should_link: should_link(i),
|
should_link: should_link(i),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -226,8 +202,26 @@ impl<'a> CrateReader<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_item(&self, i: &ast::Item) {
|
fn process_item(&mut self, i: &ast::Item) {
|
||||||
match i.node {
|
match i.node {
|
||||||
|
ast::ItemExternCrate(_) => {
|
||||||
|
if !should_link(i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match self.extract_crate_info(i) {
|
||||||
|
Some(info) => {
|
||||||
|
let (cnum, _, _) = self.resolve_crate(&None,
|
||||||
|
&info.ident[],
|
||||||
|
&info.name[],
|
||||||
|
None,
|
||||||
|
i.span,
|
||||||
|
PathKind::Crate);
|
||||||
|
self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||||
|
}
|
||||||
|
None => ()
|
||||||
|
}
|
||||||
|
}
|
||||||
ast::ItemForeignMod(ref fm) => {
|
ast::ItemForeignMod(ref fm) => {
|
||||||
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
|
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
|
||||||
return;
|
return;
|
||||||
|
@ -533,7 +527,7 @@ impl<'a> CrateReader<'a> {
|
||||||
|
|
||||||
#[derive(Copy)]
|
#[derive(Copy)]
|
||||||
pub enum CrateOrString<'a> {
|
pub enum CrateOrString<'a> {
|
||||||
Krate(&'a ast::ViewItem),
|
Krate(&'a ast::Item),
|
||||||
Str(&'a str)
|
Str(&'a str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1456,8 +1456,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
||||||
rbml_w.end_tag();
|
rbml_w.end_tag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ItemMac(..) => {
|
ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
|
||||||
// macros are encoded separately
|
// these are encoded separately
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -332,8 +332,6 @@ impl Folder for NestedItemsDropper {
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
let blk_sans_items = P(ast::Block {
|
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,
|
stmts: stmts_sans_items,
|
||||||
expr: expr,
|
expr: expr,
|
||||||
id: id,
|
id: id,
|
||||||
|
|
|
@ -297,6 +297,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
|
||||||
// These are normal, nothing reachable about these
|
// These are normal, nothing reachable about these
|
||||||
// inherently and their children are already in the
|
// inherently and their children are already in the
|
||||||
// worklist, as determined by the privacy pass
|
// worklist, as determined by the privacy pass
|
||||||
|
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||||
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
|
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
|
||||||
ast::ItemMod(..) | ast::ItemForeignMod(..) |
|
ast::ItemMod(..) | ast::ItemForeignMod(..) |
|
||||||
ast::ItemImpl(..) | ast::ItemTrait(..) |
|
ast::ItemImpl(..) | ast::ItemTrait(..) |
|
||||||
|
|
|
@ -94,6 +94,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
|
||||||
// Fn lifetimes get added in visit_fn below:
|
// Fn lifetimes get added in visit_fn below:
|
||||||
visit::walk_item(this, item);
|
visit::walk_item(this, item);
|
||||||
}
|
}
|
||||||
|
ast::ItemExternCrate(_) |
|
||||||
|
ast::ItemUse(_) |
|
||||||
ast::ItemMod(..) |
|
ast::ItemMod(..) |
|
||||||
ast::ItemMac(..) |
|
ast::ItemMac(..) |
|
||||||
ast::ItemForeignMod(..) |
|
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
|
// 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
|
// crate root, because `$crate` won't work properly. Identify these by
|
||||||
// spans, because the crate map isn't set up yet.
|
// spans, because the crate map isn't set up yet.
|
||||||
for vi in krate.module.view_items.iter() {
|
for item in krate.module.items.iter() {
|
||||||
loader.span_whitelist.insert(vi.span);
|
if let ast::ItemExternCrate(_) = item.node {
|
||||||
|
loader.span_whitelist.insert(item.span);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_crate(&mut loader, krate);
|
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.
|
// note that macros aren't expanded yet, and therefore macros can't add plugins.
|
||||||
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
|
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`.
|
// We're only interested in `extern crate`.
|
||||||
match vi.node {
|
match item.node {
|
||||||
ast::ViewItemExternCrate(..) => (),
|
ast::ItemExternCrate(_) => {}
|
||||||
_ => return,
|
_ => {
|
||||||
|
visit::walk_item(self, item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the attributes relating to macro / plugin loading.
|
// Parse the attributes relating to macro / plugin loading.
|
||||||
let mut plugin_attr = None;
|
let mut plugin_attr = None;
|
||||||
let mut macro_selection = Some(HashSet::new()); // None => load all
|
let mut macro_selection = Some(HashSet::new()); // None => load all
|
||||||
let mut reexport = HashSet::new();
|
let mut reexport = HashSet::new();
|
||||||
for attr in vi.attrs.iter() {
|
for attr in item.attrs.iter() {
|
||||||
let mut used = true;
|
let mut used = true;
|
||||||
match attr.name().get() {
|
match attr.name().get() {
|
||||||
"phase" => {
|
"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) {
|
fn visit_mac(&mut self, _: &ast::Mac) {
|
||||||
|
|
|
@ -182,7 +182,6 @@ mod svh_visitor {
|
||||||
SawLifetimeDef(token::InternedString),
|
SawLifetimeDef(token::InternedString),
|
||||||
|
|
||||||
SawMod,
|
SawMod,
|
||||||
SawViewItem,
|
|
||||||
SawForeignItem,
|
SawForeignItem,
|
||||||
SawItem,
|
SawItem,
|
||||||
SawDecl,
|
SawDecl,
|
||||||
|
@ -430,19 +429,6 @@ mod svh_visitor {
|
||||||
SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
|
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) {
|
fn visit_foreign_item(&mut self, i: &ForeignItem) {
|
||||||
// FIXME (#14132) ideally we would incorporate privacy (or
|
// FIXME (#14132) ideally we would incorporate privacy (or
|
||||||
// perhaps reachability) somewhere here, so foreign items
|
// perhaps reachability) somewhere here, so foreign items
|
||||||
|
|
|
@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
|
||||||
e: Option<P<ast::Expr>>) -> P<ast::Block> {
|
e: Option<P<ast::Expr>>) -> P<ast::Block> {
|
||||||
P(ast::Block {
|
P(ast::Block {
|
||||||
expr: e,
|
expr: e,
|
||||||
view_items: vec![], stmts: vec![], rules: rules,
|
stmts: vec![], rules: rules,
|
||||||
id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
|
id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return match it.node {
|
return match it.node {
|
||||||
|
ast::ItemUse(..) | ast::ItemExternCrate(..) |
|
||||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
|
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
|
||||||
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
|
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
|
||||||
None
|
None
|
||||||
|
|
|
@ -830,6 +830,38 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &ast::Item) {
|
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);
|
let orig_curitem = replace(&mut self.curitem, item.id);
|
||||||
visit::walk_item(self, item);
|
visit::walk_item(self, item);
|
||||||
self.curitem = orig_curitem;
|
self.curitem = orig_curitem;
|
||||||
|
@ -926,42 +958,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
||||||
visit::walk_expr(self, expr);
|
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) {
|
fn visit_pat(&mut self, pattern: &ast::Pat) {
|
||||||
// Foreign functions do not have their patterns mapped in the def_map,
|
// Foreign functions do not have their patterns mapped in the def_map,
|
||||||
// and there's nothing really relevant there anyway, so don't bother
|
// 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);
|
visit::walk_fn(self, fk, fd, b, s);
|
||||||
self.in_fn = orig_in_fn;
|
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> {
|
impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
|
@ -1162,7 +1141,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
|
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
|
||||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
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::ItemStatic(..) | ast::ItemConst(..) |
|
||||||
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
|
||||||
ast::ItemMac(..) => {}
|
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
|
// we don't need to introspect into these at all: an
|
||||||
// expression/block context can't possibly contain exported
|
// expression/block context can't possibly contain exported things.
|
||||||
// things, and neither do view_items. (Making them no-ops stops us
|
// (Making them no-ops stops us from traversing the whole AST without
|
||||||
// from traversing the whole AST without having to be super
|
// having to be super careful about our `walk_...` calls above.)
|
||||||
// careful about our `walk_...` calls above.)
|
|
||||||
fn visit_view_item(&mut self, _: &ast::ViewItem) {}
|
|
||||||
fn visit_block(&mut self, _: &ast::Block) {}
|
fn visit_block(&mut self, _: &ast::Block) {}
|
||||||
fn visit_expr(&mut self, _: &ast::Expr) {}
|
fn visit_expr(&mut self, _: &ast::Expr) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,9 +39,9 @@ use rustc::middle::subst::FnSpace;
|
||||||
use syntax::ast::{Block, Crate};
|
use syntax::ast::{Block, Crate};
|
||||||
use syntax::ast::{DeclItem, DefId};
|
use syntax::ast::{DeclItem, DefId};
|
||||||
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
|
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::{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::{MethodImplItem, Name, NamedField, NodeId};
|
||||||
use syntax::ast::{PathListIdent, PathListMod};
|
use syntax::ast::{PathListIdent, PathListMod};
|
||||||
use syntax::ast::{Public, SelfStatic};
|
use syntax::ast::{Public, SelfStatic};
|
||||||
|
@ -50,8 +50,7 @@ use syntax::ast::StructVariantKind;
|
||||||
use syntax::ast::TupleVariantKind;
|
use syntax::ast::TupleVariantKind;
|
||||||
use syntax::ast::TyObjectSum;
|
use syntax::ast::TyObjectSum;
|
||||||
use syntax::ast::{TypeImplItem, UnnamedField};
|
use syntax::ast::{TypeImplItem, UnnamedField};
|
||||||
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
|
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||||
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
|
|
||||||
use syntax::ast::{Visibility};
|
use syntax::ast::{Visibility};
|
||||||
use syntax::ast::TyPath;
|
use syntax::ast::TyPath;
|
||||||
use syntax::ast;
|
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 {
|
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.
|
// Check each statement.
|
||||||
for statement in block.stmts.iter() {
|
for statement in block.stmts.iter() {
|
||||||
match statement.node {
|
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.
|
// an anonymous module.
|
||||||
|
|
||||||
return false;
|
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;
|
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
|
||||||
|
|
||||||
match item.node {
|
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(..) => {
|
ItemMod(..) => {
|
||||||
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
|
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);
|
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.
|
/// Constructs the reduced graph for one foreign item.
|
||||||
fn build_reduced_graph_for_foreign_item<F>(&mut self,
|
fn build_reduced_graph_for_foreign_item<F>(&mut self,
|
||||||
foreign_item: &ForeignItem,
|
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) {
|
fn visit_block(&mut self, block: &Block) {
|
||||||
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
|
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
|
||||||
let old_parent = replace(&mut self.parent, np);
|
let old_parent = replace(&mut self.parent, np);
|
||||||
|
|
|
@ -25,7 +25,6 @@ use Namespace::{TypeNS, ValueNS};
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
|
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
|
|
||||||
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
|
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||||
use syntax::codemap::{Span, DUMMY_SP};
|
use syntax::codemap::{Span, DUMMY_SP};
|
||||||
use syntax::visit::{self, Visitor};
|
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> {
|
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
|
// 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
|
// 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
|
// because this means that they were generated in some fashion by the
|
||||||
// compiler and we don't need to consider them.
|
// compiler and we don't need to consider them.
|
||||||
if vi.vis == ast::Public || vi.span == DUMMY_SP {
|
if item.vis == ast::Public || item.span == DUMMY_SP {
|
||||||
visit::walk_view_item(self, vi);
|
visit::walk_item(self, item);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match vi.node {
|
match item.node {
|
||||||
ViewItemExternCrate(_, _, id) => {
|
ast::ItemExternCrate(_) => {
|
||||||
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
|
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
|
||||||
if !self.used_crates.contains(&crate_num) {
|
if !self.used_crates.contains(&crate_num) {
|
||||||
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
|
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
|
||||||
id,
|
item.id,
|
||||||
vi.span,
|
item.span,
|
||||||
"unused extern crate".to_string());
|
"unused extern crate".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ViewItemUse(ref p) => {
|
ast::ItemUse(ref p) => {
|
||||||
match p.node {
|
match p.node {
|
||||||
ViewPathSimple(_, _, id) => {
|
ViewPathSimple(_, _) => {
|
||||||
self.finalize_import(id, p.span)
|
self.finalize_import(item.id, p.span)
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewPathList(_, ref list, _) => {
|
ViewPathList(_, ref list) => {
|
||||||
for i in list.iter() {
|
for i in list.iter() {
|
||||||
self.finalize_import(i.node.id(), i.span);
|
self.finalize_import(i.node.id(), i.span);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ViewPathGlob(_, id) => {
|
ViewPathGlob(_) => {
|
||||||
if !self.used_imports.contains(&(id, TypeNS)) &&
|
if !self.used_imports.contains(&(item.id, TypeNS)) &&
|
||||||
!self.used_imports.contains(&(id, ValueNS)) {
|
!self.used_imports.contains(&(item.id, ValueNS)) {
|
||||||
self.session
|
self.session
|
||||||
.add_lint(lint::builtin::UNUSED_IMPORTS,
|
.add_lint(lint::builtin::UNUSED_IMPORTS,
|
||||||
id,
|
item.id,
|
||||||
p.span,
|
p.span,
|
||||||
"unused import".to_string());
|
"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::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
|
||||||
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
|
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
|
||||||
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
|
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
|
||||||
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
|
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
|
||||||
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
|
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
|
||||||
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
|
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
|
||||||
use syntax::ast::{MethodImplItem, Mod, Name, NodeId};
|
use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
|
||||||
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
|
||||||
use syntax::ast::{PatRange, PatStruct, Path};
|
use syntax::ast::{PatRange, PatStruct, Path};
|
||||||
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
|
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
|
||||||
|
@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_trait_name(&self, did: DefId) -> Name {
|
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
|
self.ast_map.expect_item(did.node).ident.name
|
||||||
} else {
|
} else {
|
||||||
csearch::get_trait_name(&self.session.cstore, did)
|
csearch::get_trait_name(&self.session.cstore, did)
|
||||||
|
@ -1752,10 +1752,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
import_span: Span,
|
import_span: Span,
|
||||||
name: Name,
|
name: Name,
|
||||||
namespace: Namespace) {
|
namespace: Namespace) {
|
||||||
if self.session.features.borrow().import_shadowing {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
debug!("check_for_conflicting_import: {}; target exists: {}",
|
debug!("check_for_conflicting_import: {}; target exists: {}",
|
||||||
token::get_name(name).get(),
|
token::get_name(name).get(),
|
||||||
target.is_some());
|
target.is_some());
|
||||||
|
@ -1795,10 +1791,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
&ImportResolution,
|
&ImportResolution,
|
||||||
import_span: Span,
|
import_span: Span,
|
||||||
name: Name) {
|
name: Name) {
|
||||||
if self.session.features.borrow().import_shadowing {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// First, check for conflicts between imports and `extern crate`s.
|
// First, check for conflicts between imports and `extern crate`s.
|
||||||
if module.external_module_children
|
if module.external_module_children
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -1892,10 +1884,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
module: &Module,
|
module: &Module,
|
||||||
name: Name,
|
name: Name,
|
||||||
span: Span) {
|
span: Span) {
|
||||||
if self.session.features.borrow().import_shadowing {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if module.external_module_children.borrow().contains_key(&name) {
|
if module.external_module_children.borrow().contains_key(&name) {
|
||||||
span_err!(self.session, span, E0259,
|
span_err!(self.session, span, E0259,
|
||||||
"an external crate named `{}` has already \
|
"an external crate named `{}` has already \
|
||||||
|
@ -1909,10 +1897,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
module: &Module,
|
module: &Module,
|
||||||
name: Name,
|
name: Name,
|
||||||
span: Span) {
|
span: Span) {
|
||||||
if self.session.features.borrow().import_shadowing {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if module.external_module_children.borrow().contains_key(&name) {
|
if module.external_module_children.borrow().contains_key(&name) {
|
||||||
span_err!(self.session, span, E0260,
|
span_err!(self.session, span, E0260,
|
||||||
"the name `{}` conflicts with an external \
|
"the name `{}` conflicts with an external \
|
||||||
|
@ -2984,9 +2968,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemMac(..) => {
|
ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
|
||||||
// do nothing, these are just around to be encoded
|
// 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.
|
// Descend into the block.
|
||||||
visit::walk_block(self, block);
|
visit::walk_block(self, block);
|
||||||
|
|
||||||
|
|
|
@ -1037,6 +1037,110 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
match item.node {
|
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) =>
|
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
|
||||||
self.process_fn(item, &**decl, ty_params, &**body),
|
self.process_fn(item, &**decl, ty_params, &**body),
|
||||||
ast::ItemStatic(ref typ, mt, ref expr) =>
|
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) {
|
fn visit_ty(&mut self, t: &ast::Ty) {
|
||||||
if generated_code(t.span) {
|
if generated_code(t.span) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -274,7 +274,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
ast_map::NodeArg(..) |
|
ast_map::NodeArg(..) |
|
||||||
ast_map::NodeBlock(..) |
|
ast_map::NodeBlock(..) |
|
||||||
ast_map::NodePat(..) |
|
ast_map::NodePat(..) |
|
||||||
ast_map::NodeViewItem(..) |
|
|
||||||
ast_map::NodeLocal(..) => {
|
ast_map::NodeLocal(..) => {
|
||||||
ccx.sess().bug(&format!("can't monomorphize a {:?}",
|
ccx.sess().bug(&format!("can't monomorphize a {:?}",
|
||||||
map_node)[])
|
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);
|
debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
|
||||||
match it.node {
|
match it.node {
|
||||||
// These don't define types.
|
// These don't define types.
|
||||||
|
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||||
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
|
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
|
||||||
ast::ItemEnum(ref enum_definition, ref generics) => {
|
ast::ItemEnum(ref enum_definition, ref generics) => {
|
||||||
let scheme = ty_of_item(ccx, it);
|
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());
|
tcx.tcache.borrow_mut().insert(local_def(it.id), scheme.clone());
|
||||||
return scheme;
|
return scheme;
|
||||||
}
|
}
|
||||||
|
ast::ItemExternCrate(_) | ast::ItemUse(_) |
|
||||||
ast::ItemImpl(..) | ast::ItemMod(_) |
|
ast::ItemImpl(..) | ast::ItemMod(_) |
|
||||||
ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
|
ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,6 +380,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
|
||||||
visit::walk_item(self, item);
|
visit::walk_item(self, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::ItemExternCrate(_) |
|
||||||
|
ast::ItemUse(_) |
|
||||||
ast::ItemImpl(..) |
|
ast::ItemImpl(..) |
|
||||||
ast::ItemStatic(..) |
|
ast::ItemStatic(..) |
|
||||||
ast::ItemConst(..) |
|
ast::ItemConst(..) |
|
||||||
|
@ -532,6 +534,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::ItemExternCrate(_) |
|
||||||
|
ast::ItemUse(_) |
|
||||||
ast::ItemStatic(..) |
|
ast::ItemStatic(..) |
|
||||||
ast::ItemConst(..) |
|
ast::ItemConst(..) |
|
||||||
ast::ItemFn(..) |
|
ast::ItemFn(..) |
|
||||||
|
|
|
@ -18,8 +18,7 @@ pub use self::TypeKind::*;
|
||||||
pub use self::StructField::*;
|
pub use self::StructField::*;
|
||||||
pub use self::VariantKind::*;
|
pub use self::VariantKind::*;
|
||||||
pub use self::Mutability::*;
|
pub use self::Mutability::*;
|
||||||
pub use self::ViewItemInner::*;
|
pub use self::Import::*;
|
||||||
pub use self::ViewPath::*;
|
|
||||||
pub use self::ItemEnum::*;
|
pub use self::ItemEnum::*;
|
||||||
pub use self::Attribute::*;
|
pub use self::Attribute::*;
|
||||||
pub use self::TyParamBound::*;
|
pub use self::TyParamBound::*;
|
||||||
|
@ -315,6 +314,8 @@ impl Item {
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||||
pub enum ItemEnum {
|
pub enum ItemEnum {
|
||||||
|
ExternCrateItem(String, Option<String>),
|
||||||
|
ImportItem(Import),
|
||||||
StructItem(Struct),
|
StructItem(Struct),
|
||||||
EnumItem(Enum),
|
EnumItem(Enum),
|
||||||
FunctionItem(Function),
|
FunctionItem(Function),
|
||||||
|
@ -324,8 +325,6 @@ pub enum ItemEnum {
|
||||||
ConstantItem(Constant),
|
ConstantItem(Constant),
|
||||||
TraitItem(Trait),
|
TraitItem(Trait),
|
||||||
ImplItem(Impl),
|
ImplItem(Impl),
|
||||||
/// `use` and `extern crate`
|
|
||||||
ViewItemItem(ViewItem),
|
|
||||||
/// A method signature only. Used for required methods in traits (ie,
|
/// A method signature only. Used for required methods in traits (ie,
|
||||||
/// non-default-methods).
|
/// non-default-methods).
|
||||||
TyMethodItem(TyMethod),
|
TyMethodItem(TyMethod),
|
||||||
|
@ -355,27 +354,21 @@ impl Clean<Item> for doctree::Module {
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
};
|
};
|
||||||
let mut foreigns = Vec::new();
|
let items: Vec<Item> =
|
||||||
for subforeigns in self.foreigns.clean(cx).into_iter() {
|
self.extern_crates.iter().map(|x| x.clean(cx))
|
||||||
for foreign in subforeigns.into_iter() {
|
.chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||||
foreigns.push(foreign)
|
.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)))
|
||||||
let items: Vec<Vec<Item> > = vec!(
|
.chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
|
||||||
self.structs.clean(cx),
|
.chain(self.mods.iter().map(|x| x.clean(cx)))
|
||||||
self.enums.clean(cx),
|
.chain(self.typedefs.iter().map(|x| x.clean(cx)))
|
||||||
self.fns.clean(cx),
|
.chain(self.statics.iter().map(|x| x.clean(cx)))
|
||||||
foreigns,
|
.chain(self.constants.iter().map(|x| x.clean(cx)))
|
||||||
self.mods.clean(cx),
|
.chain(self.traits.iter().map(|x| x.clean(cx)))
|
||||||
self.typedefs.clean(cx),
|
.chain(self.impls.iter().map(|x| x.clean(cx)))
|
||||||
self.statics.clean(cx),
|
.chain(self.macros.iter().map(|x| x.clean(cx)))
|
||||||
self.constants.clean(cx),
|
.collect();
|
||||||
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),
|
|
||||||
);
|
|
||||||
|
|
||||||
// determine if we should display the inner contents or
|
// determine if we should display the inner contents or
|
||||||
// the outer `mod` item for the source code.
|
// 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),
|
def_id: ast_util::local_def(self.id),
|
||||||
inner: ModuleItem(Module {
|
inner: ModuleItem(Module {
|
||||||
is_crate: self.is_crate,
|
is_crate: self.is_crate,
|
||||||
items: items.iter()
|
items: items
|
||||||
.flat_map(|x| x.iter().map(|x| (*x).clone()))
|
|
||||||
.collect(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2143,12 +2134,21 @@ impl Clean<Item> for doctree::Impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
impl Clean<Item> for doctree::ExternCrate {
|
||||||
pub struct ViewItem {
|
fn clean(&self, cx: &DocContext) -> Item {
|
||||||
pub inner: ViewItemInner,
|
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> {
|
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
||||||
// We consider inlining the documentation of `pub use` statements, but we
|
// We consider inlining the documentation of `pub use` statements, but we
|
||||||
// forcefully don't inline if this is not public or if the
|
// 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,
|
None => false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let convert = |&: node: &ast::ViewItem_| {
|
let (mut ret, inner) = match self.node {
|
||||||
Item {
|
ast::ViewPathGlob(ref p) => {
|
||||||
name: None,
|
(vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
|
||||||
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) }),
|
|
||||||
}
|
}
|
||||||
};
|
ast::ViewPathList(ref p, ref list) => {
|
||||||
let mut ret = Vec::new();
|
// Attempt to inline all reexported items, but be sure
|
||||||
match self.node {
|
// to keep any non-inlineable reexports so they can be
|
||||||
ast::ViewItemUse(ref path) if !denied => {
|
// listed in the documentation.
|
||||||
match path.node {
|
let mut ret = vec![];
|
||||||
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
|
let remaining = if !denied {
|
||||||
ast::ViewPathList(ref a, ref list, ref b) => {
|
let mut remaining = vec![];
|
||||||
// Attempt to inline all reexported items, but be sure
|
for path in list.iter() {
|
||||||
// to keep any non-inlineable reexports so they can be
|
match inline::try_inline(cx, path.node.id(), None) {
|
||||||
// listed in the documentation.
|
Some(items) => {
|
||||||
let remaining = list.iter().filter(|path| {
|
ret.extend(items.into_iter());
|
||||||
match inline::try_inline(cx, path.node.id(), None) {
|
}
|
||||||
Some(items) => {
|
None => {
|
||||||
ret.extend(items.into_iter()); false
|
remaining.push(path.clean(cx));
|
||||||
}
|
|
||||||
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) => {
|
remaining
|
||||||
match inline::try_inline(cx, id, Some(ident)) {
|
} else {
|
||||||
Some(items) => ret.extend(items.into_iter()),
|
list.clean(cx)
|
||||||
None => ret.push(convert(&self.node)),
|
};
|
||||||
}
|
if remaining.is_empty() {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
(ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id),
|
||||||
|
remaining))
|
||||||
|
}
|
||||||
|
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)))
|
||||||
}
|
}
|
||||||
ref n => ret.push(convert(n)),
|
};
|
||||||
}
|
ret.push(Item {
|
||||||
return ret;
|
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)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||||
pub enum ViewItemInner {
|
pub enum Import {
|
||||||
ExternCrate(String, Option<String>, ast::NodeId),
|
|
||||||
Import(ViewPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
|
||||||
pub enum ViewPath {
|
|
||||||
// use source as str;
|
// use source as str;
|
||||||
SimpleImport(String, ImportSource),
|
SimpleImport(String, ImportSource),
|
||||||
// use source::*;
|
// use source::*;
|
||||||
|
@ -2248,21 +2230,6 @@ pub struct ImportSource {
|
||||||
pub did: Option<ast::DefId>,
|
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)]
|
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
|
||||||
pub struct ViewListIdent {
|
pub struct ViewListIdent {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
@ -25,6 +25,8 @@ pub struct Module {
|
||||||
pub attrs: Vec<ast::Attribute>,
|
pub attrs: Vec<ast::Attribute>,
|
||||||
pub where_outer: Span,
|
pub where_outer: Span,
|
||||||
pub where_inner: Span,
|
pub where_inner: Span,
|
||||||
|
pub extern_crates: Vec<ExternCrate>,
|
||||||
|
pub imports: Vec<Import>,
|
||||||
pub structs: Vec<Struct>,
|
pub structs: Vec<Struct>,
|
||||||
pub enums: Vec<Enum>,
|
pub enums: Vec<Enum>,
|
||||||
pub fns: Vec<Function>,
|
pub fns: Vec<Function>,
|
||||||
|
@ -38,7 +40,6 @@ pub struct Module {
|
||||||
pub stab: Option<attr::Stability>,
|
pub stab: Option<attr::Stability>,
|
||||||
pub impls: Vec<Impl>,
|
pub impls: Vec<Impl>,
|
||||||
pub foreigns: Vec<ast::ForeignMod>,
|
pub foreigns: Vec<ast::ForeignMod>,
|
||||||
pub view_items: Vec<ast::ViewItem>,
|
|
||||||
pub macros: Vec<Macro>,
|
pub macros: Vec<Macro>,
|
||||||
pub is_crate: bool,
|
pub is_crate: bool,
|
||||||
}
|
}
|
||||||
|
@ -53,6 +54,8 @@ impl Module {
|
||||||
where_outer: syntax::codemap::DUMMY_SP,
|
where_outer: syntax::codemap::DUMMY_SP,
|
||||||
where_inner: syntax::codemap::DUMMY_SP,
|
where_inner: syntax::codemap::DUMMY_SP,
|
||||||
attrs : Vec::new(),
|
attrs : Vec::new(),
|
||||||
|
extern_crates: Vec::new(),
|
||||||
|
imports : Vec::new(),
|
||||||
structs : Vec::new(),
|
structs : Vec::new(),
|
||||||
enums : Vec::new(),
|
enums : Vec::new(),
|
||||||
fns : Vec::new(),
|
fns : Vec::new(),
|
||||||
|
@ -62,7 +65,6 @@ impl Module {
|
||||||
constants : Vec::new(),
|
constants : Vec::new(),
|
||||||
traits : Vec::new(),
|
traits : Vec::new(),
|
||||||
impls : Vec::new(),
|
impls : Vec::new(),
|
||||||
view_items : Vec::new(),
|
|
||||||
foreigns : Vec::new(),
|
foreigns : Vec::new(),
|
||||||
macros : Vec::new(),
|
macros : Vec::new(),
|
||||||
is_crate : false,
|
is_crate : false,
|
||||||
|
@ -202,6 +204,22 @@ pub struct Macro {
|
||||||
pub stab: Option<attr::Stability>,
|
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 {
|
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
|
||||||
if sd.ctor_id.is_some() {
|
if sd.ctor_id.is_some() {
|
||||||
// We are in a tuple-struct
|
// 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 {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
clean::SimpleImport(ref name, ref src) => {
|
clean::SimpleImport(ref name, ref src) => {
|
||||||
|
|
|
@ -22,29 +22,31 @@ use clean;
|
||||||
#[derive(Copy, PartialEq, Clone)]
|
#[derive(Copy, PartialEq, Clone)]
|
||||||
pub enum ItemType {
|
pub enum ItemType {
|
||||||
Module = 0,
|
Module = 0,
|
||||||
Struct = 1,
|
ExternCrate = 1,
|
||||||
Enum = 2,
|
Import = 2,
|
||||||
Function = 3,
|
Struct = 3,
|
||||||
Typedef = 4,
|
Enum = 4,
|
||||||
Static = 5,
|
Function = 5,
|
||||||
Trait = 6,
|
Typedef = 6,
|
||||||
Impl = 7,
|
Static = 7,
|
||||||
ViewItem = 8,
|
Trait = 8,
|
||||||
TyMethod = 9,
|
Impl = 9,
|
||||||
Method = 10,
|
TyMethod = 10,
|
||||||
StructField = 11,
|
Method = 11,
|
||||||
Variant = 12,
|
StructField = 12,
|
||||||
// we used to have ForeignFunction and ForeignStatic. they are retired now.
|
Variant = 13,
|
||||||
Macro = 15,
|
Macro = 14,
|
||||||
Primitive = 16,
|
Primitive = 15,
|
||||||
AssociatedType = 17,
|
AssociatedType = 16,
|
||||||
Constant = 18,
|
Constant = 17,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemType {
|
impl ItemType {
|
||||||
pub fn from_item(item: &clean::Item) -> ItemType {
|
pub fn from_item(item: &clean::Item) -> ItemType {
|
||||||
match item.inner {
|
match item.inner {
|
||||||
clean::ModuleItem(..) => ItemType::Module,
|
clean::ModuleItem(..) => ItemType::Module,
|
||||||
|
clean::ExternCrateItem(..) => ItemType::ExternCrate,
|
||||||
|
clean::ImportItem(..) => ItemType::Import,
|
||||||
clean::StructItem(..) => ItemType::Struct,
|
clean::StructItem(..) => ItemType::Struct,
|
||||||
clean::EnumItem(..) => ItemType::Enum,
|
clean::EnumItem(..) => ItemType::Enum,
|
||||||
clean::FunctionItem(..) => ItemType::Function,
|
clean::FunctionItem(..) => ItemType::Function,
|
||||||
|
@ -53,7 +55,6 @@ impl ItemType {
|
||||||
clean::ConstantItem(..) => ItemType::Constant,
|
clean::ConstantItem(..) => ItemType::Constant,
|
||||||
clean::TraitItem(..) => ItemType::Trait,
|
clean::TraitItem(..) => ItemType::Trait,
|
||||||
clean::ImplItem(..) => ItemType::Impl,
|
clean::ImplItem(..) => ItemType::Impl,
|
||||||
clean::ViewItemItem(..) => ItemType::ViewItem,
|
|
||||||
clean::TyMethodItem(..) => ItemType::TyMethod,
|
clean::TyMethodItem(..) => ItemType::TyMethod,
|
||||||
clean::MethodItem(..) => ItemType::Method,
|
clean::MethodItem(..) => ItemType::Method,
|
||||||
clean::StructFieldItem(..) => ItemType::StructField,
|
clean::StructFieldItem(..) => ItemType::StructField,
|
||||||
|
@ -83,6 +84,8 @@ impl ItemType {
|
||||||
pub fn to_static_str(&self) -> &'static str {
|
pub fn to_static_str(&self) -> &'static str {
|
||||||
match *self {
|
match *self {
|
||||||
ItemType::Module => "mod",
|
ItemType::Module => "mod",
|
||||||
|
ItemType::ExternCrate => "externcrate",
|
||||||
|
ItemType::Import => "import",
|
||||||
ItemType::Struct => "struct",
|
ItemType::Struct => "struct",
|
||||||
ItemType::Enum => "enum",
|
ItemType::Enum => "enum",
|
||||||
ItemType::Function => "fn",
|
ItemType::Function => "fn",
|
||||||
|
@ -90,7 +93,6 @@ impl ItemType {
|
||||||
ItemType::Static => "static",
|
ItemType::Static => "static",
|
||||||
ItemType::Trait => "trait",
|
ItemType::Trait => "trait",
|
||||||
ItemType::Impl => "impl",
|
ItemType::Impl => "impl",
|
||||||
ItemType::ViewItem => "viewitem",
|
|
||||||
ItemType::TyMethod => "tymethod",
|
ItemType::TyMethod => "tymethod",
|
||||||
ItemType::Method => "method",
|
ItemType::Method => "method",
|
||||||
ItemType::StructField => "structfield",
|
ItemType::StructField => "structfield",
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
pub use self::ExternalLocation::*;
|
pub use self::ExternalLocation::*;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::cmp::Ordering::{self, Less, Greater, Equal};
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
// the order of item types in the listing
|
// the order of item types in the listing
|
||||||
fn reorder(ty: ItemType) -> u8 {
|
fn reorder(ty: ItemType) -> u8 {
|
||||||
match ty {
|
match ty {
|
||||||
ItemType::ViewItem => 0,
|
ItemType::ExternCrate => 0,
|
||||||
ItemType::Primitive => 1,
|
ItemType::Import => 1,
|
||||||
ItemType::Module => 2,
|
ItemType::Primitive => 2,
|
||||||
ItemType::Macro => 3,
|
ItemType::Module => 3,
|
||||||
ItemType::Struct => 4,
|
ItemType::Macro => 4,
|
||||||
ItemType::Enum => 5,
|
ItemType::Struct => 5,
|
||||||
ItemType::Constant => 6,
|
ItemType::Enum => 6,
|
||||||
ItemType::Static => 7,
|
ItemType::Constant => 7,
|
||||||
ItemType::Trait => 8,
|
ItemType::Static => 8,
|
||||||
ItemType::Function => 9,
|
ItemType::Trait => 9,
|
||||||
ItemType::Typedef => 10,
|
ItemType::Function => 10,
|
||||||
_ => 11 + ty as u8,
|
ItemType::Typedef => 12,
|
||||||
|
_ => 13 + ty as u8,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1518,25 +1519,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
if ty1 == ty2 {
|
if ty1 == ty2 {
|
||||||
return i1.name.cmp(&i2.name);
|
return i1.name.cmp(&i2.name);
|
||||||
}
|
}
|
||||||
|
(reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
|
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 myitem = &items[idx];
|
||||||
|
|
||||||
let myty = Some(shortty(myitem));
|
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() {
|
if curty.is_some() {
|
||||||
try!(write!(w, "</table>"));
|
try!(write!(w, "</table>"));
|
||||||
}
|
}
|
||||||
curty = myty;
|
curty = myty;
|
||||||
let (short, name) = match myty.unwrap() {
|
let (short, name) = match myty.unwrap() {
|
||||||
|
ItemType::ExternCrate |
|
||||||
|
ItemType::Import => ("reexports", "Reexports"),
|
||||||
ItemType::Module => ("modules", "Modules"),
|
ItemType::Module => ("modules", "Modules"),
|
||||||
ItemType::Struct => ("structs", "Structs"),
|
ItemType::Struct => ("structs", "Structs"),
|
||||||
ItemType::Enum => ("enums", "Enums"),
|
ItemType::Enum => ("enums", "Enums"),
|
||||||
|
@ -1562,7 +1550,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
ItemType::Constant => ("constants", "Constants"),
|
ItemType::Constant => ("constants", "Constants"),
|
||||||
ItemType::Trait => ("traits", "Traits"),
|
ItemType::Trait => ("traits", "Traits"),
|
||||||
ItemType::Impl => ("impls", "Implementations"),
|
ItemType::Impl => ("impls", "Implementations"),
|
||||||
ItemType::ViewItem => ("reexports", "Reexports"),
|
|
||||||
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
ItemType::TyMethod => ("tymethods", "Type Methods"),
|
||||||
ItemType::Method => ("methods", "Methods"),
|
ItemType::Method => ("methods", "Methods"),
|
||||||
ItemType::StructField => ("fields", "Struct Fields"),
|
ItemType::StructField => ("fields", "Struct Fields"),
|
||||||
|
@ -1578,28 +1565,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
match myitem.inner {
|
match myitem.inner {
|
||||||
clean::ViewItemItem(ref item) => {
|
clean::ExternCrateItem(ref name, ref src) => {
|
||||||
match item.inner {
|
match *src {
|
||||||
clean::ExternCrate(ref name, ref src, _) => {
|
Some(ref src) => {
|
||||||
match *src {
|
try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
|
||||||
Some(ref src) =>
|
VisSpace(myitem.visibility),
|
||||||
try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}",
|
src.as_slice(),
|
||||||
src.as_slice(),
|
name.as_slice()))
|
||||||
name.as_slice())),
|
|
||||||
None =>
|
|
||||||
try!(write!(w, "<tr><td><code>extern crate {}",
|
|
||||||
name.as_slice())),
|
|
||||||
}
|
|
||||||
try!(write!(w, ";</code></td></tr>"));
|
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
clean::Import(ref import) => {
|
try!(write!(w, "<tr><td><code>{}extern crate {};",
|
||||||
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
|
VisSpace(myitem.visibility), name.as_slice()))
|
||||||
VisSpace(myitem.visibility),
|
|
||||||
*import));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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.method { background-color: #c6afb3; }
|
||||||
.content .highlighted.tymethod { background-color: #c6afb3; }
|
.content .highlighted.tymethod { background-color: #c6afb3; }
|
||||||
.content .highlighted.type { background-color: #c6afb3; }
|
.content .highlighted.type { background-color: #c6afb3; }
|
||||||
.content .highlighted.ffi { background-color: #c6afb3; }
|
|
||||||
|
|
||||||
.docblock.short.nowrap {
|
.docblock.short.nowrap {
|
||||||
display: block;
|
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.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
|
||||||
.content span.method, .content a.method, .block a.current.method { 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.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; }
|
.content .fnname { color: #8c6067; }
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
|
|
|
@ -555,6 +555,8 @@
|
||||||
// This mapping table should match the discriminants of
|
// This mapping table should match the discriminants of
|
||||||
// `rustdoc::html::item_type::ItemType` type in Rust.
|
// `rustdoc::html::item_type::ItemType` type in Rust.
|
||||||
var itemTypes = ["mod",
|
var itemTypes = ["mod",
|
||||||
|
"externcrate",
|
||||||
|
"import",
|
||||||
"struct",
|
"struct",
|
||||||
"enum",
|
"enum",
|
||||||
"fn",
|
"fn",
|
||||||
|
@ -562,13 +564,10 @@
|
||||||
"static",
|
"static",
|
||||||
"trait",
|
"trait",
|
||||||
"impl",
|
"impl",
|
||||||
"viewitem",
|
|
||||||
"tymethod",
|
"tymethod",
|
||||||
"method",
|
"method",
|
||||||
"structfield",
|
"structfield",
|
||||||
"variant",
|
"variant",
|
||||||
"ffi", // retained for backward compatibility
|
|
||||||
"ffs", // retained for backward compatibility
|
|
||||||
"macro",
|
"macro",
|
||||||
"primitive",
|
"primitive",
|
||||||
"associatedtype",
|
"associatedtype",
|
||||||
|
|
|
@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clean::ViewItemItem(..) => {
|
clean::ExternCrateItem(..) | clean::ImportItem(_) => {
|
||||||
if i.visibility != Some(ast::Public) {
|
if i.visibility != Some(ast::Public) {
|
||||||
return None
|
return None
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ use syntax::ast::Public;
|
||||||
|
|
||||||
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
|
||||||
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
|
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;
|
use html::render::cache;
|
||||||
|
|
||||||
|
@ -199,7 +199,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
// no stability information for the following items:
|
// no stability information for the following items:
|
||||||
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
|
ExternCrateItem(..) | ImportItem(_) |
|
||||||
|
PrimitiveItem(_) => (Counts::zero(), None),
|
||||||
_ => (item_counts, None)
|
_ => (item_counts, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,6 @@ use syntax::ast_map;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use syntax::attr::AttrMetaMethods;
|
use syntax::attr::AttrMetaMethods;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use syntax::ptr::P;
|
|
||||||
|
|
||||||
use rustc::middle::stability;
|
use rustc::middle::stability;
|
||||||
|
|
||||||
|
@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
m: &ast::Mod,
|
m: &ast::Mod,
|
||||||
name: Option<ast::Ident>) -> Module {
|
name: Option<ast::Ident>) -> Module {
|
||||||
let mut om = Module::new(name);
|
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_outer = span;
|
||||||
om.where_inner = m.inner;
|
om.where_inner = m.inner;
|
||||||
om.attrs = attrs;
|
om.attrs = attrs;
|
||||||
|
@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
om
|
om
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
|
fn visit_view_path(&mut self, path: ast::ViewPath_,
|
||||||
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,
|
|
||||||
om: &mut Module,
|
om: &mut Module,
|
||||||
please_inline: bool) -> Option<P<ast::ViewPath>> {
|
id: ast::NodeId,
|
||||||
match path.node {
|
please_inline: bool) -> Option<ast::ViewPath_> {
|
||||||
ast::ViewPathSimple(dst, _, id) => {
|
match path {
|
||||||
|
ast::ViewPathSimple(dst, base) => {
|
||||||
if self.resolve_id(id, Some(dst), false, om, please_inline) {
|
if self.resolve_id(id, Some(dst), false, om, please_inline) {
|
||||||
return None
|
None
|
||||||
|
} else {
|
||||||
|
Some(ast::ViewPathSimple(dst, base))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::ViewPathList(ref p, ref paths, ref b) => {
|
ast::ViewPathList(p, paths) => {
|
||||||
let mut mine = Vec::new();
|
let mine = paths.into_iter().filter(|path| {
|
||||||
for path in paths.iter() {
|
!self.resolve_id(path.node.id(), None, false, om,
|
||||||
if !self.resolve_id(path.node.id(), None, false, om,
|
please_inline)
|
||||||
please_inline) {
|
}).collect::<Vec<ast::PathListItem>>();
|
||||||
mine.push(path.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if mine.len() == 0 { return None }
|
if mine.len() == 0 {
|
||||||
return Some(P(::syntax::codemap::Spanned {
|
None
|
||||||
node: ast::ViewPathList(p.clone(), mine, b.clone()),
|
} else {
|
||||||
span: path.span,
|
Some(ast::ViewPathList(p, mine))
|
||||||
}))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// these are feature gated anyway
|
// these are feature gated anyway
|
||||||
ast::ViewPathGlob(_, id) => {
|
ast::ViewPathGlob(base) => {
|
||||||
if self.resolve_id(id, None, true, om, please_inline) {
|
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>,
|
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
|
||||||
|
@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
if glob {
|
if glob {
|
||||||
match it.node {
|
match it.node {
|
||||||
ast::ItemMod(ref m) => {
|
ast::ItemMod(ref m) => {
|
||||||
for vi in m.view_items.iter() {
|
|
||||||
self.visit_view_item(vi, om);
|
|
||||||
}
|
|
||||||
for i in m.items.iter() {
|
for i in m.items.iter() {
|
||||||
self.visit_item(&**i, None, om);
|
self.visit_item(&**i, None, om);
|
||||||
}
|
}
|
||||||
|
@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||||
debug!("Visiting item {:?}", item);
|
debug!("Visiting item {:?}", item);
|
||||||
let name = renamed.unwrap_or(item.ident);
|
let name = renamed.unwrap_or(item.ident);
|
||||||
match item.node {
|
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) => {
|
ast::ItemMod(ref m) => {
|
||||||
om.mods.push(self.visit_mod_contents(item.span,
|
om.mods.push(self.visit_mod_contents(item.span,
|
||||||
item.attrs.clone(),
|
item.attrs.clone(),
|
||||||
|
|
|
@ -53,7 +53,6 @@ pub use self::UnboxedClosureKind::*;
|
||||||
pub use self::UnOp::*;
|
pub use self::UnOp::*;
|
||||||
pub use self::UnsafeSource::*;
|
pub use self::UnsafeSource::*;
|
||||||
pub use self::VariantKind::*;
|
pub use self::VariantKind::*;
|
||||||
pub use self::ViewItem_::*;
|
|
||||||
pub use self::ViewPath_::*;
|
pub use self::ViewPath_::*;
|
||||||
pub use self::Visibility::*;
|
pub use self::Visibility::*;
|
||||||
pub use self::PathParameters::*;
|
pub use self::PathParameters::*;
|
||||||
|
@ -511,7 +510,6 @@ impl PartialEq for MetaItem_ {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
pub view_items: Vec<ViewItem>,
|
|
||||||
pub stmts: Vec<P<Stmt>>,
|
pub stmts: Vec<P<Stmt>>,
|
||||||
pub expr: Option<P<Expr>>,
|
pub expr: Option<P<Expr>>,
|
||||||
pub id: NodeId,
|
pub id: NodeId,
|
||||||
|
@ -1443,14 +1441,12 @@ pub struct Mod {
|
||||||
/// For `mod foo;`, the inner span ranges from the first token
|
/// For `mod foo;`, the inner span ranges from the first token
|
||||||
/// to the last token in the external file.
|
/// to the last token in the external file.
|
||||||
pub inner: Span,
|
pub inner: Span,
|
||||||
pub view_items: Vec<ViewItem>,
|
|
||||||
pub items: Vec<P<Item>>,
|
pub items: Vec<P<Item>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||||
pub struct ForeignMod {
|
pub struct ForeignMod {
|
||||||
pub abi: Abi,
|
pub abi: Abi,
|
||||||
pub view_items: Vec<ViewItem>,
|
|
||||||
pub items: Vec<P<ForeignItem>>,
|
pub items: Vec<P<ForeignItem>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1509,44 +1505,13 @@ pub enum ViewPath_ {
|
||||||
/// or just
|
/// or just
|
||||||
///
|
///
|
||||||
/// `foo::bar::baz` (with `as baz` implicitly on the right)
|
/// `foo::bar::baz` (with `as baz` implicitly on the right)
|
||||||
ViewPathSimple(Ident, Path, NodeId),
|
ViewPathSimple(Ident, Path),
|
||||||
|
|
||||||
/// `foo::bar::*`
|
/// `foo::bar::*`
|
||||||
ViewPathGlob(Path, NodeId),
|
ViewPathGlob(Path),
|
||||||
|
|
||||||
/// `foo::bar::{a,b,c}`
|
/// `foo::bar::{a,b,c}`
|
||||||
ViewPathList(Path, Vec<PathListItem> , NodeId)
|
ViewPathList(Path, Vec<PathListItem>)
|
||||||
}
|
|
||||||
|
|
||||||
#[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>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Meta-data associated with an item
|
/// Meta-data associated with an item
|
||||||
|
@ -1668,6 +1633,12 @@ pub struct Item {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||||
pub enum Item_ {
|
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>),
|
ItemStatic(P<Ty>, Mutability, P<Expr>),
|
||||||
ItemConst(P<Ty>, P<Expr>),
|
ItemConst(P<Ty>, P<Expr>),
|
||||||
ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
|
ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
|
||||||
|
@ -1694,6 +1665,8 @@ pub enum Item_ {
|
||||||
impl Item_ {
|
impl Item_ {
|
||||||
pub fn descriptive_variant(&self) -> &str {
|
pub fn descriptive_variant(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
|
ItemExternCrate(..) => "extern crate",
|
||||||
|
ItemUse(..) => "use",
|
||||||
ItemStatic(..) => "static item",
|
ItemStatic(..) => "static item",
|
||||||
ItemConst(..) => "constant item",
|
ItemConst(..) => "constant item",
|
||||||
ItemFn(..) => "function",
|
ItemFn(..) => "function",
|
||||||
|
|
|
@ -107,7 +107,6 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
|
||||||
#[derive(Copy, Show)]
|
#[derive(Copy, Show)]
|
||||||
pub enum Node<'ast> {
|
pub enum Node<'ast> {
|
||||||
NodeItem(&'ast Item),
|
NodeItem(&'ast Item),
|
||||||
NodeViewItem(&'ast ViewItem),
|
|
||||||
NodeForeignItem(&'ast ForeignItem),
|
NodeForeignItem(&'ast ForeignItem),
|
||||||
NodeTraitItem(&'ast TraitItem),
|
NodeTraitItem(&'ast TraitItem),
|
||||||
NodeImplItem(&'ast ImplItem),
|
NodeImplItem(&'ast ImplItem),
|
||||||
|
@ -134,7 +133,6 @@ enum MapEntry<'ast> {
|
||||||
|
|
||||||
/// All the node types, with a parent ID.
|
/// All the node types, with a parent ID.
|
||||||
EntryItem(NodeId, &'ast Item),
|
EntryItem(NodeId, &'ast Item),
|
||||||
EntryViewItem(NodeId, &'ast ViewItem),
|
|
||||||
EntryForeignItem(NodeId, &'ast ForeignItem),
|
EntryForeignItem(NodeId, &'ast ForeignItem),
|
||||||
EntryTraitItem(NodeId, &'ast TraitItem),
|
EntryTraitItem(NodeId, &'ast TraitItem),
|
||||||
EntryImplItem(NodeId, &'ast ImplItem),
|
EntryImplItem(NodeId, &'ast ImplItem),
|
||||||
|
@ -169,7 +167,6 @@ impl<'ast> MapEntry<'ast> {
|
||||||
fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
|
fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
|
||||||
match node {
|
match node {
|
||||||
NodeItem(n) => EntryItem(p, n),
|
NodeItem(n) => EntryItem(p, n),
|
||||||
NodeViewItem(n) => EntryViewItem(p, n),
|
|
||||||
NodeForeignItem(n) => EntryForeignItem(p, n),
|
NodeForeignItem(n) => EntryForeignItem(p, n),
|
||||||
NodeTraitItem(n) => EntryTraitItem(p, n),
|
NodeTraitItem(n) => EntryTraitItem(p, n),
|
||||||
NodeImplItem(n) => EntryImplItem(p, n),
|
NodeImplItem(n) => EntryImplItem(p, n),
|
||||||
|
@ -188,7 +185,6 @@ impl<'ast> MapEntry<'ast> {
|
||||||
fn parent(self) -> Option<NodeId> {
|
fn parent(self) -> Option<NodeId> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
EntryItem(id, _) => id,
|
EntryItem(id, _) => id,
|
||||||
EntryViewItem(id, _) => id,
|
|
||||||
EntryForeignItem(id, _) => id,
|
EntryForeignItem(id, _) => id,
|
||||||
EntryTraitItem(id, _) => id,
|
EntryTraitItem(id, _) => id,
|
||||||
EntryImplItem(id, _) => id,
|
EntryImplItem(id, _) => id,
|
||||||
|
@ -208,7 +204,6 @@ impl<'ast> MapEntry<'ast> {
|
||||||
fn to_node(self) -> Option<Node<'ast>> {
|
fn to_node(self) -> Option<Node<'ast>> {
|
||||||
Some(match self {
|
Some(match self {
|
||||||
EntryItem(_, n) => NodeItem(n),
|
EntryItem(_, n) => NodeItem(n),
|
||||||
EntryViewItem(_, n) => NodeViewItem(n),
|
|
||||||
EntryForeignItem(_, n) => NodeForeignItem(n),
|
EntryForeignItem(_, n) => NodeForeignItem(n),
|
||||||
EntryTraitItem(_, n) => NodeTraitItem(n),
|
EntryTraitItem(_, n) => NodeTraitItem(n),
|
||||||
EntryImplItem(_, n) => NodeImplItem(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 {
|
pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
|
||||||
match self.find(id) {
|
match self.find(id) {
|
||||||
Some(NodeItem(i)) => {
|
Some(NodeItem(i)) => {
|
||||||
|
@ -533,7 +521,6 @@ impl<'ast> Map<'ast> {
|
||||||
pub fn opt_span(&self, id: NodeId) -> Option<Span> {
|
pub fn opt_span(&self, id: NodeId) -> Option<Span> {
|
||||||
let sp = match self.find(id) {
|
let sp = match self.find(id) {
|
||||||
Some(NodeItem(item)) => item.span,
|
Some(NodeItem(item)) => item.span,
|
||||||
Some(NodeViewItem(item)) => item.span,
|
|
||||||
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
|
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
|
||||||
Some(NodeTraitItem(trait_method)) => {
|
Some(NodeTraitItem(trait_method)) => {
|
||||||
match *trait_method {
|
match *trait_method {
|
||||||
|
@ -826,11 +813,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
|
||||||
self.parent = parent;
|
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) {
|
fn visit_pat(&mut self, pat: &'ast Pat) {
|
||||||
self.insert(pat.id, match pat.node {
|
self.insert(pat.id, match pat.node {
|
||||||
// Note: this is at least *potentially* a pattern...
|
// 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 {
|
let krate = mem::replace(&mut forest.krate, Crate {
|
||||||
module: Mod {
|
module: Mod {
|
||||||
inner: DUMMY_SP,
|
inner: DUMMY_SP,
|
||||||
view_items: vec![],
|
|
||||||
items: vec![],
|
items: vec![],
|
||||||
},
|
},
|
||||||
attrs: vec![],
|
attrs: vec![],
|
||||||
|
@ -1036,7 +1017,6 @@ impl<'a> NodePrinter for pprust::State<'a> {
|
||||||
fn print_node(&mut self, node: &Node) -> IoResult<()> {
|
fn print_node(&mut self, node: &Node) -> IoResult<()> {
|
||||||
match *node {
|
match *node {
|
||||||
NodeItem(a) => self.print_item(&*a),
|
NodeItem(a) => self.print_item(&*a),
|
||||||
NodeViewItem(a) => self.print_view_item(&*a),
|
|
||||||
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
NodeForeignItem(a) => self.print_foreign_item(&*a),
|
||||||
NodeTraitItem(a) => self.print_trait_method(&*a),
|
NodeTraitItem(a) => self.print_trait_method(&*a),
|
||||||
NodeImplItem(a) => self.print_impl_item(&*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)) => {
|
Some(NodeItem(item)) => {
|
||||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||||
let item_str = match item.node {
|
let item_str = match item.node {
|
||||||
|
ItemExternCrate(..) => "extern crate",
|
||||||
|
ItemUse(..) => "use",
|
||||||
ItemStatic(..) => "static",
|
ItemStatic(..) => "static",
|
||||||
ItemConst(..) => "const",
|
ItemConst(..) => "const",
|
||||||
ItemFn(..) => "fn",
|
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)
|
format!("{} {}{}", item_str, path_str, id_str)
|
||||||
}
|
}
|
||||||
Some(NodeViewItem(item)) => {
|
|
||||||
format!("view item {}{}", pprust::view_item_to_string(&*item), id_str)
|
|
||||||
}
|
|
||||||
Some(NodeForeignItem(item)) => {
|
Some(NodeForeignItem(item)) => {
|
||||||
let path_str = map.path_to_str_with_ident(id, item.ident);
|
let path_str = map.path_to_str_with_ident(id, item.ident);
|
||||||
format!("foreign item {}{}", path_str, id_str)
|
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)
|
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) {
|
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||||
self.operation.visit_id(foreign_item.id);
|
self.operation.visit_id(foreign_item.id);
|
||||||
visit::walk_foreign_item(self, foreign_item)
|
visit::walk_foreign_item(self, foreign_item)
|
||||||
|
@ -456,10 +425,24 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.operation.visit_id(item.id);
|
self.operation.visit_id(item.id);
|
||||||
if let ItemEnum(ref enum_definition, _) = item.node {
|
match item.node {
|
||||||
for variant in enum_definition.variants.iter() {
|
ItemUse(ref view_path) => {
|
||||||
self.operation.visit_id(variant.node.id)
|
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);
|
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)
|
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
|
/// Returns true if the given struct def is tuple-like; i.e. that its fields
|
||||||
/// are unnamed.
|
/// are unnamed.
|
||||||
pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {
|
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)
|
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>,
|
fn fold_mod<F>(cx: &mut Context<F>,
|
||||||
ast::Mod {inner,
|
ast::Mod {inner, items}: ast::Mod)
|
||||||
view_items, items}: ast::Mod) -> ast::Mod where
|
-> ast::Mod where
|
||||||
F: FnMut(&[ast::Attribute]) -> bool
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
{
|
{
|
||||||
ast::Mod {
|
ast::Mod {
|
||||||
inner: inner,
|
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| {
|
items: items.into_iter().flat_map(|a| {
|
||||||
cx.fold_item(a).into_iter()
|
cx.fold_item(a).into_iter()
|
||||||
}).collect()
|
}).collect()
|
||||||
|
@ -104,15 +89,12 @@ fn filter_foreign_item<F>(cx: &mut Context<F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_foreign_mod<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
|
-> ast::ForeignMod where
|
||||||
F: FnMut(&[ast::Attribute]) -> bool
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
{
|
{
|
||||||
ast::ForeignMod {
|
ast::ForeignMod {
|
||||||
abi: abi,
|
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()
|
items: items.into_iter()
|
||||||
.filter_map(|a| filter_foreign_item(cx, a))
|
.filter_map(|a| filter_foreign_item(cx, a))
|
||||||
.collect()
|
.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
|
fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
|
||||||
F: FnMut(&[ast::Attribute]) -> bool
|
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>> =
|
let resulting_stmts: Vec<P<ast::Stmt>> =
|
||||||
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
|
||||||
let resulting_stmts = resulting_stmts.into_iter()
|
let resulting_stmts = resulting_stmts.into_iter()
|
||||||
.flat_map(|stmt| cx.fold_stmt(stmt).into_iter())
|
.flat_map(|stmt| cx.fold_stmt(stmt).into_iter())
|
||||||
.collect();
|
.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 {
|
ast::Block {
|
||||||
id: id,
|
id: id,
|
||||||
view_items: filtered_view_items,
|
|
||||||
stmts: resulting_stmts,
|
stmts: resulting_stmts,
|
||||||
expr: expr.map(|x| cx.fold_expr(x)),
|
expr: expr.map(|x| cx.fold_expr(x)),
|
||||||
rules: rules,
|
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());
|
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
|
fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
|
||||||
F: FnMut(&[ast::Attribute]) -> bool
|
F: FnMut(&[ast::Attribute]) -> bool
|
||||||
{
|
{
|
||||||
|
|
|
@ -97,7 +97,6 @@ pub trait AstBuilder {
|
||||||
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
||||||
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
|
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
|
||||||
fn block_all(&self, span: Span,
|
fn block_all(&self, span: Span,
|
||||||
view_items: Vec<ast::ViewItem>,
|
|
||||||
stmts: Vec<P<ast::Stmt>>,
|
stmts: Vec<P<ast::Stmt>>,
|
||||||
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
|
||||||
|
|
||||||
|
@ -242,7 +241,7 @@ pub trait AstBuilder {
|
||||||
|
|
||||||
fn item_mod(&self, span: Span, inner_span: Span,
|
fn item_mod(&self, span: Span, inner_span: Span,
|
||||||
name: Ident, attrs: Vec<ast::Attribute>,
|
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,
|
fn item_static(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
@ -280,15 +279,15 @@ pub trait AstBuilder {
|
||||||
value: ast::Lit_)
|
value: ast::Lit_)
|
||||||
-> P<ast::MetaItem>;
|
-> P<ast::MetaItem>;
|
||||||
|
|
||||||
fn view_use(&self, sp: Span,
|
fn item_use(&self, sp: Span,
|
||||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem;
|
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
|
||||||
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>;
|
||||||
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||||
ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
|
ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
|
||||||
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
|
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||||
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem;
|
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
|
||||||
fn view_use_glob(&self, sp: Span,
|
fn item_use_glob(&self, sp: Span,
|
||||||
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem;
|
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AstBuilder for ExtCtxt<'a> {
|
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>>,
|
fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>,
|
||||||
expr: Option<P<Expr>>) -> P<ast::Block> {
|
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> {
|
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> {
|
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,
|
fn block_all(&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
view_items: Vec<ast::ViewItem>,
|
|
||||||
stmts: Vec<P<ast::Stmt>>,
|
stmts: Vec<P<ast::Stmt>>,
|
||||||
expr: Option<P<ast::Expr>>) -> P<ast::Block> {
|
expr: Option<P<ast::Expr>>) -> P<ast::Block> {
|
||||||
P(ast::Block {
|
P(ast::Block {
|
||||||
view_items: view_items,
|
|
||||||
stmts: stmts,
|
stmts: stmts,
|
||||||
expr: expr,
|
expr: expr,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -1031,16 +1028,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
|
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
|
||||||
attrs: Vec<ast::Attribute> ,
|
attrs: Vec<ast::Attribute>,
|
||||||
vi: Vec<ast::ViewItem> ,
|
items: Vec<P<ast::Item>>) -> P<ast::Item> {
|
||||||
items: Vec<P<ast::Item>> ) -> P<ast::Item> {
|
|
||||||
self.item(
|
self.item(
|
||||||
span,
|
span,
|
||||||
name,
|
name,
|
||||||
attrs,
|
attrs,
|
||||||
ast::ItemMod(ast::Mod {
|
ast::ItemMod(ast::Mod {
|
||||||
inner: inner_span,
|
inner: inner_span,
|
||||||
view_items: vi,
|
|
||||||
items: items,
|
items: items,
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
@ -1101,47 +1096,47 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
|
||||||
P(respan(sp, ast::MetaNameValue(name, respan(sp, value))))
|
P(respan(sp, ast::MetaNameValue(name, respan(sp, value))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_use(&self, sp: Span,
|
fn item_use(&self, sp: Span,
|
||||||
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem {
|
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> {
|
||||||
ast::ViewItem {
|
P(ast::Item {
|
||||||
node: ast::ViewItemUse(vp),
|
id: ast::DUMMY_NODE_ID,
|
||||||
attrs: Vec::new(),
|
ident: special_idents::invalid,
|
||||||
|
attrs: vec![],
|
||||||
|
node: ast::ItemUse(vp),
|
||||||
vis: vis,
|
vis: vis,
|
||||||
span: sp
|
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;
|
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,
|
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
|
||||||
ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
|
ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
|
||||||
self.view_use(sp, vis,
|
self.item_use(sp, vis,
|
||||||
P(respan(sp,
|
P(respan(sp,
|
||||||
ast::ViewPathSimple(ident,
|
ast::ViewPathSimple(ident,
|
||||||
path,
|
path))))
|
||||||
ast::DUMMY_NODE_ID))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
|
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
|
||||||
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem {
|
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
|
||||||
let imports = imports.iter().map(|id| {
|
let imports = imports.iter().map(|id| {
|
||||||
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
|
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
self.view_use(sp, vis,
|
self.item_use(sp, vis,
|
||||||
P(respan(sp,
|
P(respan(sp,
|
||||||
ast::ViewPathList(self.path(sp, path),
|
ast::ViewPathList(self.path(sp, path),
|
||||||
imports,
|
imports))))
|
||||||
ast::DUMMY_NODE_ID))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_use_glob(&self, sp: Span,
|
fn item_use_glob(&self, sp: Span,
|
||||||
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
|
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
|
||||||
self.view_use(sp, vis,
|
self.item_use(sp, vis,
|
||||||
P(respan(sp,
|
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.>
|
// <delegated expression referring to __self0_vi, et al.>
|
||||||
// }
|
// }
|
||||||
let arm_expr = cx.expr_block(
|
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:
|
// Builds arm:
|
||||||
// _ => { let __self0_vi = ...;
|
// _ => { 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
|
// wrap the if-let expr in a block
|
||||||
let span = els.span;
|
let span = els.span;
|
||||||
let blk = P(ast::Block {
|
let blk = P(ast::Block {
|
||||||
view_items: vec![],
|
|
||||||
stmts: vec![],
|
stmts: vec![],
|
||||||
expr: Some(P(els)),
|
expr: Some(P(els)),
|
||||||
id: ast::DUMMY_NODE_ID,
|
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.
|
// expand the elements of a block.
|
||||||
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
||||||
b.map(|Block {id, view_items, stmts, expr, rules, span}| {
|
b.map(|Block {id, stmts, expr, rules, span}| {
|
||||||
let new_view_items = view_items.into_iter().map(|x| fld.fold_view_item(x)).collect();
|
|
||||||
let new_stmts = stmts.into_iter().flat_map(|x| {
|
let new_stmts = stmts.into_iter().flat_map(|x| {
|
||||||
// perform all pending renames
|
// perform all pending renames
|
||||||
let renamed_stmt = {
|
let renamed_stmt = {
|
||||||
|
@ -821,7 +819,6 @@ pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
|
||||||
});
|
});
|
||||||
Block {
|
Block {
|
||||||
id: fld.new_id(id),
|
id: fld.new_id(id),
|
||||||
view_items: new_view_items,
|
|
||||||
stmts: new_stmts,
|
stmts: new_stmts,
|
||||||
expr: new_expr,
|
expr: new_expr,
|
||||||
rules: rules,
|
rules: rules,
|
||||||
|
|
|
@ -352,18 +352,11 @@ pub mod rt {
|
||||||
impl<'a> ExtParseUtils for ExtCtxt<'a> {
|
impl<'a> ExtParseUtils for ExtCtxt<'a> {
|
||||||
|
|
||||||
fn parse_item(&self, s: String) -> P<ast::Item> {
|
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(),
|
"<quote expansion>".to_string(),
|
||||||
s,
|
s,
|
||||||
self.cfg(),
|
self.cfg(),
|
||||||
self.parse_sess());
|
self.parse_sess()).expect("parse error")
|
||||||
match res {
|
|
||||||
Some(ast) => ast,
|
|
||||||
None => {
|
|
||||||
error!("parse error");
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_stmt(&self, s: String) -> P<ast::Stmt> {
|
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());
|
vector.extend(mk_tts(cx, &tts[]).into_iter());
|
||||||
let block = cx.expr_block(
|
let block = cx.expr_block(
|
||||||
cx.block_all(sp,
|
cx.block_all(sp,
|
||||||
Vec::new(),
|
|
||||||
vector,
|
vector,
|
||||||
Some(cx.expr_ident(sp, id_ext("tt")))));
|
Some(cx.expr_ident(sp, id_ext("tt")))));
|
||||||
|
|
||||||
|
@ -778,18 +770,18 @@ fn expand_wrapper(cx: &ExtCtxt,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
cx_expr: P<ast::Expr>,
|
cx_expr: P<ast::Expr>,
|
||||||
expr: P<ast::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)
|
// 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 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);
|
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,
|
fn expand_parse_call(cx: &ExtCtxt,
|
||||||
|
|
|
@ -64,7 +64,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
|
||||||
|
|
||||||
("rustc_diagnostic_macros", Active),
|
("rustc_diagnostic_macros", Active),
|
||||||
("unboxed_closures", Active),
|
("unboxed_closures", Active),
|
||||||
("import_shadowing", Active),
|
("import_shadowing", Removed),
|
||||||
("advanced_slice_patterns", Active),
|
("advanced_slice_patterns", Active),
|
||||||
("tuple_indexing", Accepted),
|
("tuple_indexing", Accepted),
|
||||||
("associated_types", Accepted),
|
("associated_types", Accepted),
|
||||||
|
@ -127,7 +127,6 @@ enum Status {
|
||||||
pub struct Features {
|
pub struct Features {
|
||||||
pub unboxed_closures: bool,
|
pub unboxed_closures: bool,
|
||||||
pub rustc_diagnostic_macros: bool,
|
pub rustc_diagnostic_macros: bool,
|
||||||
pub import_shadowing: bool,
|
|
||||||
pub visible_private_types: bool,
|
pub visible_private_types: bool,
|
||||||
pub quote: bool,
|
pub quote: bool,
|
||||||
pub old_orphan_check: bool,
|
pub old_orphan_check: bool,
|
||||||
|
@ -139,7 +138,6 @@ impl Features {
|
||||||
Features {
|
Features {
|
||||||
unboxed_closures: false,
|
unboxed_closures: false,
|
||||||
rustc_diagnostic_macros: false,
|
rustc_diagnostic_macros: false,
|
||||||
import_shadowing: false,
|
|
||||||
visible_private_types: false,
|
visible_private_types: false,
|
||||||
quote: false,
|
quote: false,
|
||||||
old_orphan_check: 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) {
|
fn visit_item(&mut self, i: &ast::Item) {
|
||||||
for attr in i.attrs.iter() {
|
for attr in i.attrs.iter() {
|
||||||
if attr.name() == "thread_local" {
|
if attr.name() == "thread_local" {
|
||||||
|
@ -262,6 +244,14 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
match i.node {
|
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) => {
|
ast::ItemForeignMod(ref foreign_module) => {
|
||||||
if attr::contains_name(&i.attrs[], "link_args") {
|
if attr::contains_name(&i.attrs[], "link_args") {
|
||||||
self.gate_feature("link_args", i.span,
|
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 {
|
(Features {
|
||||||
unboxed_closures: cx.has_feature("unboxed_closures"),
|
unboxed_closures: cx.has_feature("unboxed_closures"),
|
||||||
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
|
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"),
|
visible_private_types: cx.has_feature("visible_private_types"),
|
||||||
quote: cx.has_feature("quote"),
|
quote: cx.has_feature("quote"),
|
||||||
old_orphan_check: cx.has_feature("old_orphan_check"),
|
old_orphan_check: cx.has_feature("old_orphan_check"),
|
||||||
|
|
|
@ -78,10 +78,6 @@ pub trait Folder : Sized {
|
||||||
noop_fold_view_path(view_path, self)
|
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> {
|
fn fold_foreign_item(&mut self, ni: P<ForeignItem>) -> P<ForeignItem> {
|
||||||
noop_fold_foreign_item(ni, self)
|
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> {
|
pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
|
||||||
view_path.map(|Spanned {node, span}| Spanned {
|
view_path.map(|Spanned {node, span}| Spanned {
|
||||||
node: match node {
|
node: match node {
|
||||||
ViewPathSimple(ident, path, node_id) => {
|
ViewPathSimple(ident, path) => {
|
||||||
let id = fld.new_id(node_id);
|
ViewPathSimple(ident, fld.fold_path(path))
|
||||||
ViewPathSimple(ident, fld.fold_path(path), id)
|
|
||||||
}
|
}
|
||||||
ViewPathGlob(path, node_id) => {
|
ViewPathGlob(path) => {
|
||||||
let id = fld.new_id(node_id);
|
ViewPathGlob(fld.fold_path(path))
|
||||||
ViewPathGlob(fld.fold_path(path), id)
|
|
||||||
}
|
}
|
||||||
ViewPathList(path, path_list_idents, node_id) => {
|
ViewPathList(path, path_list_idents) => {
|
||||||
let id = fld.new_id(node_id);
|
|
||||||
ViewPathList(fld.fold_path(path),
|
ViewPathList(fld.fold_path(path),
|
||||||
path_list_idents.move_map(|path_list_ident| {
|
path_list_idents.move_map(|path_list_ident| {
|
||||||
Spanned {
|
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)
|
span: fld.new_span(path_list_ident.span)
|
||||||
}
|
}
|
||||||
}),
|
}))
|
||||||
id)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
span: fld.new_span(span)
|
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 {
|
fld: &mut T) -> ForeignMod {
|
||||||
ForeignMod {
|
ForeignMod {
|
||||||
abi: abi,
|
abi: abi,
|
||||||
view_items: view_items.move_map(|x| fld.fold_view_item(x)),
|
|
||||||
items: items.move_map(|x| fld.fold_foreign_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> {
|
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),
|
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(),
|
stmts: stmts.into_iter().flat_map(|s| folder.fold_stmt(s).into_iter()).collect(),
|
||||||
expr: expr.map(|x| folder.fold_expr(x)),
|
expr: expr.map(|x| folder.fold_expr(x)),
|
||||||
rules: rules,
|
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_ {
|
pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
|
||||||
match i {
|
match i {
|
||||||
|
ItemExternCrate(string) => ItemExternCrate(string),
|
||||||
|
ItemUse(view_path) => {
|
||||||
|
ItemUse(folder.fold_view_path(view_path))
|
||||||
|
}
|
||||||
ItemStatic(t, m, e) => {
|
ItemStatic(t, m, e) => {
|
||||||
ItemStatic(folder.fold_ty(t), m, folder.fold_expr(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 {
|
Mod {
|
||||||
inner: folder.new_span(inner),
|
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(),
|
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 {
|
None => (ast::Mod {
|
||||||
inner: span,
|
inner: span,
|
||||||
view_items: Vec::new(),
|
items: vec![],
|
||||||
items: Vec::new(),
|
}, vec![], span)
|
||||||
}, Vec::new(), span)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for def in exported_macros.iter_mut() {
|
for def in exported_macros.iter_mut() {
|
||||||
|
|
|
@ -757,11 +757,10 @@ mod test {
|
||||||
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
|
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
|
||||||
use parse::parser::Parser;
|
use parse::parser::Parser;
|
||||||
use parse::token::{str_to_ident};
|
use parse::token::{str_to_ident};
|
||||||
use print::pprust::view_item_to_string;
|
use print::pprust::item_to_string;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use util::parser_testing::{string_to_tts, string_to_parser};
|
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_expr, string_to_item, string_to_stmt};
|
||||||
use util::parser_testing::{string_to_stmt, string_to_view_item};
|
|
||||||
|
|
||||||
// produce a codemap::span
|
// produce a codemap::span
|
||||||
fn sp(a: u32, b: u32) -> Span {
|
fn sp(a: u32, b: u32) -> Span {
|
||||||
|
@ -1079,7 +1078,6 @@ mod test {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
P(ast::Block {
|
P(ast::Block {
|
||||||
view_items: Vec::new(),
|
|
||||||
stmts: vec!(P(Spanned{
|
stmts: vec!(P(Spanned{
|
||||||
node: ast::StmtSemi(P(ast::Expr{
|
node: ast::StmtSemi(P(ast::Expr{
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -1111,25 +1109,25 @@ mod test {
|
||||||
|
|
||||||
#[test] fn parse_use() {
|
#[test] fn parse_use() {
|
||||||
let use_s = "use foo::bar::baz;";
|
let use_s = "use foo::bar::baz;";
|
||||||
let vitem = string_to_view_item(use_s.to_string());
|
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||||
let vitem_s = view_item_to_string(&vitem);
|
let vitem_s = item_to_string(&*vitem);
|
||||||
assert_eq!(&vitem_s[], use_s);
|
assert_eq!(&vitem_s[], use_s);
|
||||||
|
|
||||||
let use_s = "use foo::bar as baz;";
|
let use_s = "use foo::bar as baz;";
|
||||||
let vitem = string_to_view_item(use_s.to_string());
|
let vitem = string_to_item(use_s.to_string()).unwrap();
|
||||||
let vitem_s = view_item_to_string(&vitem);
|
let vitem_s = item_to_string(&*vitem);
|
||||||
assert_eq!(&vitem_s[], use_s);
|
assert_eq!(&vitem_s[], use_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test] fn parse_extern_crate() {
|
#[test] fn parse_extern_crate() {
|
||||||
let ex_s = "extern crate foo;";
|
let ex_s = "extern crate foo;";
|
||||||
let vitem = string_to_view_item(ex_s.to_string());
|
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||||
let vitem_s = view_item_to_string(&vitem);
|
let vitem_s = item_to_string(&*vitem);
|
||||||
assert_eq!(&vitem_s[], ex_s);
|
assert_eq!(&vitem_s[], ex_s);
|
||||||
|
|
||||||
let ex_s = "extern crate \"foo\" as bar;";
|
let ex_s = "extern crate \"foo\" as bar;";
|
||||||
let vitem = string_to_view_item(ex_s.to_string());
|
let vitem = string_to_item(ex_s.to_string()).unwrap();
|
||||||
let vitem_s = view_item_to_string(&vitem);
|
let vitem_s = item_to_string(&*vitem);
|
||||||
assert_eq!(&vitem_s[], ex_s);
|
assert_eq!(&vitem_s[], ex_s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
pub use self::PathParsingMode::*;
|
pub use self::PathParsingMode::*;
|
||||||
use self::ItemOrViewItem::*;
|
|
||||||
|
|
||||||
use abi;
|
use abi;
|
||||||
use ast::{AssociatedType, BareFnTy};
|
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::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
||||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
||||||
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
|
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
|
||||||
|
use ast::{ItemExternCrate, ItemUse};
|
||||||
use ast::{LifetimeDef, Lit, Lit_};
|
use ast::{LifetimeDef, Lit, Lit_};
|
||||||
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||||
use ast::{LitStr, LitInt, Local, LocalLet};
|
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::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||||
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
|
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
|
||||||
use ast::{UnnamedField, UnsafeBlock};
|
use ast::{UnnamedField, UnsafeBlock};
|
||||||
use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
|
|
||||||
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||||
use ast::{Visibility, WhereClause};
|
use ast::{Visibility, WhereClause};
|
||||||
use ast;
|
use ast;
|
||||||
|
@ -122,14 +121,9 @@ pub enum BoundParsingMode {
|
||||||
Modified,
|
Modified,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ItemOrViewItem {
|
/// The `Err` case indicates a failure to parse any kind of item.
|
||||||
/// Indicates a failure to parse any kind of item. The attributes are
|
/// The attributes are returned.
|
||||||
/// returned.
|
type MaybeItem = Result<P<Item>, Vec<Attribute>>;
|
||||||
IoviNone(Vec<Attribute>),
|
|
||||||
IoviItem(P<Item>),
|
|
||||||
IoviForeignItem(P<ForeignItem>),
|
|
||||||
IoviViewItem(ViewItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
|
/// 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) => (
|
(pair_empty $p:expr, $constructor:ident) => (
|
||||||
{
|
{
|
||||||
let found = match ($p).token {
|
let found = match ($p).token {
|
||||||
|
@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
|
||||||
lhs
|
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 */
|
/* ident is handled by common.rs */
|
||||||
|
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
|
@ -3032,8 +3005,7 @@ impl<'a> Parser<'a> {
|
||||||
let body = self.parse_expr();
|
let body = self.parse_expr();
|
||||||
let fakeblock = P(ast::Block {
|
let fakeblock = P(ast::Block {
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
view_items: Vec::new(),
|
stmts: vec![],
|
||||||
stmts: Vec::new(),
|
|
||||||
span: body.span,
|
span: body.span,
|
||||||
expr: Some(body),
|
expr: Some(body),
|
||||||
rules: DefaultBlock,
|
rules: DefaultBlock,
|
||||||
|
@ -3731,20 +3703,13 @@ impl<'a> Parser<'a> {
|
||||||
} else {
|
} else {
|
||||||
let found_attrs = !item_attrs.is_empty();
|
let found_attrs = !item_attrs.is_empty();
|
||||||
let item_err = Parser::expected_item_err(&item_attrs[]);
|
let item_err = Parser::expected_item_err(&item_attrs[]);
|
||||||
match self.parse_item_or_view_item(item_attrs, false) {
|
match self.parse_item_(item_attrs, false) {
|
||||||
IoviItem(i) => {
|
Ok(i) => {
|
||||||
let hi = i.span.hi;
|
let hi = i.span.hi;
|
||||||
let decl = P(spanned(lo, hi, DeclItem(i)));
|
let decl = P(spanned(lo, hi, DeclItem(i)));
|
||||||
P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
|
P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
|
||||||
}
|
}
|
||||||
IoviViewItem(vi) => {
|
Err(_) => {
|
||||||
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(_) => {
|
|
||||||
if found_attrs {
|
if found_attrs {
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
self.span_err(last_span, item_err);
|
self.span_err(last_span, item_err);
|
||||||
|
@ -3794,36 +3759,17 @@ impl<'a> Parser<'a> {
|
||||||
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
|
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Precondition: already parsed the '{' or '#{'
|
/// Precondition: already parsed the '{'.
|
||||||
/// I guess that also means "already parsed the 'impure'" if
|
|
||||||
/// necessary, and this should take a qualifier.
|
|
||||||
/// Some blocks start with "#{"...
|
|
||||||
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
||||||
self.parse_block_tail_(lo, s, Vec::new())
|
self.parse_block_tail_(lo, s, Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse the rest of a block expression or function body
|
/// Parse the rest of a block expression or function body
|
||||||
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
||||||
first_item_attrs: Vec<Attribute> ) -> P<Block> {
|
first_item_attrs: Vec<Attribute>) -> P<Block> {
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = vec![];
|
||||||
let mut expr = None;
|
let mut expr = None;
|
||||||
|
let mut attributes_box = first_item_attrs;
|
||||||
// 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;
|
|
||||||
|
|
||||||
while self.token != token::CloseDelim(token::Brace) {
|
while self.token != token::CloseDelim(token::Brace) {
|
||||||
// parsing items even when they're not allowed lets us give
|
// parsing items even when they're not allowed lets us give
|
||||||
|
@ -3932,7 +3878,6 @@ impl<'a> Parser<'a> {
|
||||||
let hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
self.bump();
|
self.bump();
|
||||||
P(ast::Block {
|
P(ast::Block {
|
||||||
view_items: view_items,
|
|
||||||
stmts: stmts,
|
stmts: stmts,
|
||||||
expr: expr,
|
expr: expr,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
@ -5031,39 +4976,34 @@ impl<'a> Parser<'a> {
|
||||||
first_item_attrs: Vec<Attribute>,
|
first_item_attrs: Vec<Attribute>,
|
||||||
inner_lo: BytePos)
|
inner_lo: BytePos)
|
||||||
-> Mod {
|
-> Mod {
|
||||||
// parse all of the items up to closing or an attribute.
|
// Parse all of the items up to closing or an attribute.
|
||||||
// view items are legal here.
|
|
||||||
let ParsedItemsAndViewItems {
|
let mut attrs = first_item_attrs;
|
||||||
attrs_remaining,
|
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||||
view_items,
|
let mut items = vec![];
|
||||||
items: starting_items,
|
|
||||||
..
|
loop {
|
||||||
} = self.parse_items_and_view_items(first_item_attrs, true, true);
|
match self.parse_item_(attrs, true) {
|
||||||
let mut items: Vec<P<Item>> = starting_items;
|
Err(returned_attrs) => {
|
||||||
let attrs_remaining_len = attrs_remaining.len();
|
attrs = returned_attrs;
|
||||||
|
break
|
||||||
|
}
|
||||||
|
Ok(item) => {
|
||||||
|
attrs = self.parse_outer_attributes();
|
||||||
|
items.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// don't think this other loop is even necessary....
|
// don't think this other loop is even necessary....
|
||||||
|
|
||||||
let mut first = true;
|
|
||||||
while self.token != term {
|
while self.token != term {
|
||||||
let mut attrs = self.parse_outer_attributes();
|
let mut attrs = mem::replace(&mut attrs, vec![]);
|
||||||
if first {
|
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||||
let mut tmp = attrs_remaining.clone();
|
debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
|
||||||
tmp.push_all(&attrs[]);
|
match self.parse_item_(attrs, true /* macros allowed */) {
|
||||||
attrs = tmp;
|
Ok(item) => items.push(item),
|
||||||
first = false;
|
Err(_) => {
|
||||||
}
|
|
||||||
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 token_str = self.this_token_to_string();
|
let token_str = self.this_token_to_string();
|
||||||
self.fatal(&format!("expected item, found `{}`",
|
self.fatal(&format!("expected item, found `{}`",
|
||||||
token_str)[])
|
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
|
// We parsed attributes for the first item but didn't find it
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
self.span_err(last_span,
|
self.span_err(last_span,
|
||||||
Parser::expected_item_err(&attrs_remaining[]));
|
Parser::expected_item_err(&attrs[]));
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::Mod {
|
ast::Mod {
|
||||||
inner: mk_sp(inner_lo, self.span.lo),
|
inner: mk_sp(inner_lo, self.span.lo),
|
||||||
view_items: view_items,
|
|
||||||
items: items
|
items: items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5298,23 +5237,12 @@ impl<'a> Parser<'a> {
|
||||||
/// parse_foreign_items.
|
/// parse_foreign_items.
|
||||||
fn parse_foreign_mod_items(&mut self,
|
fn parse_foreign_mod_items(&mut self,
|
||||||
abi: abi::Abi,
|
abi: abi::Abi,
|
||||||
first_item_attrs: Vec<Attribute> )
|
first_item_attrs: Vec<Attribute>)
|
||||||
-> ForeignMod {
|
-> ForeignMod {
|
||||||
let ParsedItemsAndViewItems {
|
let foreign_items = self.parse_foreign_items(first_item_attrs);
|
||||||
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[]));
|
|
||||||
}
|
|
||||||
assert!(self.token == token::CloseDelim(token::Brace));
|
assert!(self.token == token::CloseDelim(token::Brace));
|
||||||
ast::ForeignMod {
|
ast::ForeignMod {
|
||||||
abi: abi,
|
abi: abi,
|
||||||
view_items: view_items,
|
|
||||||
items: foreign_items
|
items: foreign_items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5329,8 +5257,8 @@ impl<'a> Parser<'a> {
|
||||||
fn parse_item_extern_crate(&mut self,
|
fn parse_item_extern_crate(&mut self,
|
||||||
lo: BytePos,
|
lo: BytePos,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
attrs: Vec<Attribute> )
|
attrs: Vec<Attribute>)
|
||||||
-> ItemOrViewItem {
|
-> P<Item> {
|
||||||
|
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
let (maybe_path, ident) = match self.token {
|
let (maybe_path, ident) = match self.token {
|
||||||
|
@ -5374,12 +5302,13 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
IoviViewItem(ast::ViewItem {
|
let last_span = self.last_span;
|
||||||
node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
|
self.mk_item(lo,
|
||||||
attrs: attrs,
|
last_span.hi,
|
||||||
vis: visibility,
|
ident,
|
||||||
span: mk_sp(lo, self.last_span.hi)
|
ItemExternCrate(maybe_path),
|
||||||
})
|
visibility,
|
||||||
|
attrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse `extern` for foreign ABIs
|
/// Parse `extern` for foreign ABIs
|
||||||
|
@ -5396,8 +5325,8 @@ impl<'a> Parser<'a> {
|
||||||
lo: BytePos,
|
lo: BytePos,
|
||||||
opt_abi: Option<abi::Abi>,
|
opt_abi: Option<abi::Abi>,
|
||||||
visibility: Visibility,
|
visibility: Visibility,
|
||||||
attrs: Vec<Attribute> )
|
attrs: Vec<Attribute>)
|
||||||
-> ItemOrViewItem {
|
-> P<Item> {
|
||||||
|
|
||||||
self.expect(&token::OpenDelim(token::Brace));
|
self.expect(&token::OpenDelim(token::Brace));
|
||||||
|
|
||||||
|
@ -5408,13 +5337,12 @@ impl<'a> Parser<'a> {
|
||||||
self.expect(&token::CloseDelim(token::Brace));
|
self.expect(&token::CloseDelim(token::Brace));
|
||||||
|
|
||||||
let last_span = self.last_span;
|
let last_span = self.last_span;
|
||||||
let item = self.mk_item(lo,
|
self.mk_item(lo,
|
||||||
last_span.hi,
|
last_span.hi,
|
||||||
special_idents::invalid,
|
special_idents::invalid,
|
||||||
ItemForeignMod(m),
|
ItemForeignMod(m),
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, Some(inner)));
|
maybe_append(attrs, Some(inner)))
|
||||||
return IoviItem(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse type Foo = Bar;
|
/// Parse type Foo = Bar;
|
||||||
|
@ -5556,14 +5484,12 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse one of the items or view items allowed by the
|
/// Parse one of the items allowed by the flags; on failure,
|
||||||
/// flags; on failure, return IoviNone.
|
/// return `Err(remaining_attrs)`.
|
||||||
/// NB: this function no longer parses the items inside an
|
/// NB: this function no longer parses the items inside an
|
||||||
/// extern crate.
|
/// extern crate.
|
||||||
fn parse_item_or_view_item(&mut self,
|
fn parse_item_(&mut self, attrs: Vec<Attribute>,
|
||||||
attrs: Vec<Attribute> ,
|
macros_allowed: bool) -> MaybeItem {
|
||||||
macros_allowed: bool)
|
|
||||||
-> ItemOrViewItem {
|
|
||||||
let nt_item = match self.token {
|
let nt_item = match self.token {
|
||||||
token::Interpolated(token::NtItem(ref item)) => {
|
token::Interpolated(token::NtItem(ref item)) => {
|
||||||
Some((**item).clone())
|
Some((**item).clone())
|
||||||
|
@ -5576,7 +5502,7 @@ impl<'a> Parser<'a> {
|
||||||
let mut attrs = attrs;
|
let mut attrs = attrs;
|
||||||
mem::swap(&mut item.attrs, &mut attrs);
|
mem::swap(&mut item.attrs, &mut attrs);
|
||||||
item.attrs.extend(attrs.into_iter());
|
item.attrs.extend(attrs.into_iter());
|
||||||
return IoviItem(P(item));
|
return Ok(P(item));
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
@ -5585,22 +5511,24 @@ impl<'a> Parser<'a> {
|
||||||
|
|
||||||
let visibility = self.parse_visibility();
|
let visibility = self.parse_visibility();
|
||||||
|
|
||||||
// must be a view item:
|
|
||||||
if self.eat_keyword(keywords::Use) {
|
if self.eat_keyword(keywords::Use) {
|
||||||
// USE ITEM (IoviViewItem)
|
// USE ITEM
|
||||||
let view_item = self.parse_use();
|
let item_ = ItemUse(self.parse_view_path());
|
||||||
self.expect(&token::Semi);
|
self.expect(&token::Semi);
|
||||||
return IoviViewItem(ast::ViewItem {
|
|
||||||
node: view_item,
|
let last_span = self.last_span;
|
||||||
attrs: attrs,
|
let item = self.mk_item(lo,
|
||||||
vis: visibility,
|
last_span.hi,
|
||||||
span: mk_sp(lo, self.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::Extern) {
|
||||||
if self.eat_keyword(keywords::Crate) {
|
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();
|
let opt_abi = self.parse_opt_abi();
|
||||||
|
@ -5617,9 +5545,9 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
} 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;
|
let span = self.span;
|
||||||
|
@ -5634,7 +5562,6 @@ impl<'a> Parser<'a> {
|
||||||
self.span_err(span, "`virtual` structs have been removed from the language");
|
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) {
|
if self.token.is_keyword(keywords::Static) {
|
||||||
// STATIC ITEM
|
// STATIC ITEM
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -5647,7 +5574,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Const) {
|
if self.token.is_keyword(keywords::Const) {
|
||||||
// CONST ITEM
|
// CONST ITEM
|
||||||
|
@ -5665,7 +5592,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Unsafe) &&
|
if self.token.is_keyword(keywords::Unsafe) &&
|
||||||
self.look_ahead(1us, |t| t.is_keyword(keywords::Trait))
|
self.look_ahead(1us, |t| t.is_keyword(keywords::Trait))
|
||||||
|
@ -5682,7 +5609,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Unsafe) &&
|
if self.token.is_keyword(keywords::Unsafe) &&
|
||||||
self.look_ahead(1us, |t| t.is_keyword(keywords::Impl))
|
self.look_ahead(1us, |t| t.is_keyword(keywords::Impl))
|
||||||
|
@ -5698,7 +5625,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Fn) {
|
if self.token.is_keyword(keywords::Fn) {
|
||||||
// FUNCTION ITEM
|
// FUNCTION ITEM
|
||||||
|
@ -5712,7 +5639,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Unsafe)
|
if self.token.is_keyword(keywords::Unsafe)
|
||||||
&& self.look_ahead(1us, |t| *t != token::OpenDelim(token::Brace)) {
|
&& self.look_ahead(1us, |t| *t != token::OpenDelim(token::Brace)) {
|
||||||
|
@ -5733,7 +5660,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Mod) {
|
if self.eat_keyword(keywords::Mod) {
|
||||||
// MODULE ITEM
|
// MODULE ITEM
|
||||||
|
@ -5746,7 +5673,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Type) {
|
if self.eat_keyword(keywords::Type) {
|
||||||
// TYPE ITEM
|
// TYPE ITEM
|
||||||
|
@ -5758,7 +5685,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Enum) {
|
if self.eat_keyword(keywords::Enum) {
|
||||||
// ENUM ITEM
|
// ENUM ITEM
|
||||||
|
@ -5770,7 +5697,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Trait) {
|
if self.eat_keyword(keywords::Trait) {
|
||||||
// TRAIT ITEM
|
// TRAIT ITEM
|
||||||
|
@ -5783,7 +5710,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Impl) {
|
if self.eat_keyword(keywords::Impl) {
|
||||||
// IMPL ITEM
|
// IMPL ITEM
|
||||||
|
@ -5795,7 +5722,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Struct) {
|
if self.eat_keyword(keywords::Struct) {
|
||||||
// STRUCT ITEM
|
// STRUCT ITEM
|
||||||
|
@ -5807,32 +5734,30 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs));
|
maybe_append(attrs, extra_attrs));
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a foreign item; on failure, return IoviNone.
|
/// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
|
||||||
fn parse_foreign_item(&mut self,
|
fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
|
||||||
attrs: Vec<Attribute> ,
|
-> Result<P<ForeignItem>, Vec<Attribute>> {
|
||||||
macros_allowed: bool)
|
|
||||||
-> ItemOrViewItem {
|
|
||||||
maybe_whole!(iovi self, NtItem);
|
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
let visibility = self.parse_visibility();
|
let visibility = self.parse_visibility();
|
||||||
|
|
||||||
if self.token.is_keyword(keywords::Static) {
|
if self.token.is_keyword(keywords::Static) {
|
||||||
// FOREIGN STATIC ITEM
|
// FOREIGN STATIC ITEM
|
||||||
let item = self.parse_item_foreign_static(visibility, attrs);
|
return Ok(self.parse_item_foreign_static(visibility, attrs));
|
||||||
return IoviForeignItem(item);
|
|
||||||
}
|
}
|
||||||
if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
|
if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
|
||||||
// FOREIGN FUNCTION ITEM
|
// FOREIGN FUNCTION ITEM
|
||||||
let item = self.parse_item_foreign_fn(visibility, attrs);
|
return Ok(self.parse_item_foreign_fn(visibility, attrs));
|
||||||
return IoviForeignItem(item);
|
|
||||||
}
|
}
|
||||||
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.
|
/// This is the fall-through for parsing items.
|
||||||
|
@ -5842,7 +5767,7 @@ impl<'a> Parser<'a> {
|
||||||
macros_allowed: bool,
|
macros_allowed: bool,
|
||||||
lo: BytePos,
|
lo: BytePos,
|
||||||
visibility: Visibility
|
visibility: Visibility
|
||||||
) -> ItemOrViewItem {
|
) -> MaybeItem {
|
||||||
if macros_allowed && !self.token.is_any_keyword()
|
if macros_allowed && !self.token.is_any_keyword()
|
||||||
&& self.look_ahead(1, |t| *t == token::Not)
|
&& self.look_ahead(1, |t| *t == token::Not)
|
||||||
&& (self.look_ahead(2, |t| t.is_plain_ident())
|
&& (self.look_ahead(2, |t| t.is_plain_ident())
|
||||||
|
@ -5891,7 +5816,7 @@ impl<'a> Parser<'a> {
|
||||||
item_,
|
item_,
|
||||||
visibility,
|
visibility,
|
||||||
attrs);
|
attrs);
|
||||||
return IoviItem(item);
|
return Ok(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAILURE TO PARSE ITEM
|
// FAILURE TO PARSE ITEM
|
||||||
|
@ -5902,7 +5827,7 @@ impl<'a> Parser<'a> {
|
||||||
self.span_fatal(last_span, "unmatched visibility `pub`");
|
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>> {
|
pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
|
||||||
|
@ -5911,30 +5836,9 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
|
pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
|
||||||
match self.parse_item_or_view_item(attrs, true) {
|
self.parse_item_(attrs, true).ok()
|
||||||
IoviNone(_) => None,
|
|
||||||
IoviViewItem(_) =>
|
|
||||||
self.fatal("view items are not allowed here"),
|
|
||||||
IoviForeignItem(_) =>
|
|
||||||
self.fatal("foreign items are not allowed here"),
|
|
||||||
IoviItem(item) => Some(item)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
/// Matches view_path : MOD? non_global_path as IDENT
|
||||||
/// | MOD? non_global_path MOD_SEP LBRACE RBRACE
|
/// | MOD? non_global_path MOD_SEP LBRACE RBRACE
|
||||||
/// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
|
/// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
|
||||||
|
@ -5959,8 +5863,7 @@ impl<'a> Parser<'a> {
|
||||||
global: false,
|
global: false,
|
||||||
segments: Vec::new()
|
segments: Vec::new()
|
||||||
};
|
};
|
||||||
return P(spanned(lo, self.span.hi,
|
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let first_ident = self.parse_ident();
|
let first_ident = self.parse_ident();
|
||||||
|
@ -5994,8 +5897,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}).collect()
|
}).collect()
|
||||||
};
|
};
|
||||||
return P(spanned(lo, self.span.hi,
|
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// foo::bar::*
|
// foo::bar::*
|
||||||
|
@ -6011,8 +5913,7 @@ impl<'a> Parser<'a> {
|
||||||
}
|
}
|
||||||
}).collect()
|
}).collect()
|
||||||
};
|
};
|
||||||
return P(spanned(lo, self.span.hi,
|
return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
|
||||||
ViewPathGlob(path, ast::DUMMY_NODE_ID)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => break
|
_ => break
|
||||||
|
@ -6033,136 +5934,39 @@ impl<'a> Parser<'a> {
|
||||||
if self.eat_keyword(keywords::As) {
|
if self.eat_keyword(keywords::As) {
|
||||||
rename_to = self.parse_ident()
|
rename_to = self.parse_ident()
|
||||||
}
|
}
|
||||||
P(spanned(lo,
|
P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a sequence of foreign items. Stops when it finds program
|
/// Parses a sequence of foreign items. Stops when it finds program
|
||||||
/// text that can't be parsed as an item
|
/// text that can't be parsed as an item
|
||||||
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
|
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
|
||||||
macros_allowed: bool)
|
-> Vec<P<ForeignItem>> {
|
||||||
-> ParsedItemsAndViewItems {
|
|
||||||
let mut attrs = first_item_attrs;
|
let mut attrs = first_item_attrs;
|
||||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||||
let mut foreign_items = Vec::new();
|
let mut foreign_items = Vec::new();
|
||||||
loop {
|
loop {
|
||||||
match self.parse_foreign_item(attrs, macros_allowed) {
|
match self.parse_foreign_item(attrs) {
|
||||||
IoviNone(returned_attrs) => {
|
Ok(foreign_item) => {
|
||||||
|
foreign_items.push(foreign_item);
|
||||||
|
}
|
||||||
|
Err(returned_attrs) => {
|
||||||
if self.check(&token::CloseDelim(token::Brace)) {
|
if self.check(&token::CloseDelim(token::Brace)) {
|
||||||
attrs = returned_attrs;
|
attrs = returned_attrs;
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
self.unexpected();
|
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();
|
attrs = self.parse_outer_attributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
ParsedItemsAndViewItems {
|
if !attrs.is_empty() {
|
||||||
attrs_remaining: attrs,
|
let last_span = self.last_span;
|
||||||
view_items: Vec::new(),
|
self.span_err(last_span,
|
||||||
items: Vec::new(),
|
Parser::expected_item_err(&attrs[]));
|
||||||
foreign_items: foreign_items
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreign_items
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a source module as a crate. This is the main
|
/// 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))
|
$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 {
|
pub fn generics_to_string(generics: &ast::Generics) -> String {
|
||||||
$to_string(|s| s.print_generics(generics))
|
$to_string(|s| s.print_generics(generics))
|
||||||
}
|
}
|
||||||
|
@ -638,9 +634,6 @@ impl<'a> State<'a> {
|
||||||
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
pub fn print_mod(&mut self, _mod: &ast::Mod,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
||||||
try!(self.print_inner_attributes(attrs));
|
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() {
|
for item in _mod.items.iter() {
|
||||||
try!(self.print_item(&**item));
|
try!(self.print_item(&**item));
|
||||||
}
|
}
|
||||||
|
@ -650,9 +643,6 @@ impl<'a> State<'a> {
|
||||||
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
|
||||||
attrs: &[ast::Attribute]) -> IoResult<()> {
|
attrs: &[ast::Attribute]) -> IoResult<()> {
|
||||||
try!(self.print_inner_attributes(attrs));
|
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() {
|
for item in nmod.items.iter() {
|
||||||
try!(self.print_foreign_item(&**item));
|
try!(self.print_foreign_item(&**item));
|
||||||
}
|
}
|
||||||
|
@ -809,6 +799,28 @@ impl<'a> State<'a> {
|
||||||
try!(self.print_outer_attributes(&item.attrs[]));
|
try!(self.print_outer_attributes(&item.attrs[]));
|
||||||
try!(self.ann.pre(self, NodeItem(item)));
|
try!(self.ann.pre(self, NodeItem(item)));
|
||||||
match item.node {
|
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) => {
|
ast::ItemStatic(ref ty, m, ref expr) => {
|
||||||
try!(self.head(&visibility_qualified(item.vis,
|
try!(self.head(&visibility_qualified(item.vis,
|
||||||
"static")[]));
|
"static")[]));
|
||||||
|
@ -1380,9 +1392,6 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
try!(self.print_inner_attributes(attrs));
|
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() {
|
for st in blk.stmts.iter() {
|
||||||
try!(self.print_stmt(&**st));
|
try!(self.print_stmt(&**st));
|
||||||
}
|
}
|
||||||
|
@ -2577,7 +2586,7 @@ impl<'a> State<'a> {
|
||||||
|
|
||||||
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
|
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
|
||||||
match vp.node {
|
match vp.node {
|
||||||
ast::ViewPathSimple(ident, ref path, _) => {
|
ast::ViewPathSimple(ident, ref path) => {
|
||||||
try!(self.print_path(path, false));
|
try!(self.print_path(path, false));
|
||||||
|
|
||||||
// FIXME(#6993) can't compare identifiers directly here
|
// FIXME(#6993) can't compare identifiers directly here
|
||||||
|
@ -2591,12 +2600,12 @@ impl<'a> State<'a> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ViewPathGlob(ref path, _) => {
|
ast::ViewPathGlob(ref path) => {
|
||||||
try!(self.print_path(path, false));
|
try!(self.print_path(path, false));
|
||||||
word(&mut self.s, "::*")
|
word(&mut self.s, "::*")
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ViewPathList(ref path, ref idents, _) => {
|
ast::ViewPathList(ref path, ref idents) => {
|
||||||
if path.segments.is_empty() {
|
if path.segments.is_empty() {
|
||||||
try!(word(&mut self.s, "{"));
|
try!(word(&mut self.s, "{"));
|
||||||
} else {
|
} 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,
|
pub fn print_mutability(&mut self,
|
||||||
mutbl: ast::Mutability) -> IoResult<()> {
|
mutbl: ast::Mutability) -> IoResult<()> {
|
||||||
match mutbl {
|
match mutbl {
|
||||||
|
|
|
@ -20,8 +20,6 @@ use parse::token;
|
||||||
use ptr::P;
|
use ptr::P;
|
||||||
use util::small_vector::SmallVector;
|
use util::small_vector::SmallVector;
|
||||||
|
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
|
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
|
||||||
-> ast::Crate {
|
-> ast::Crate {
|
||||||
if use_std(&krate) {
|
if use_std(&krate) {
|
||||||
|
@ -60,20 +58,16 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
|
||||||
None => token::intern_and_get_ident("std"),
|
None => token::intern_and_get_ident("std"),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut vis = vec!(ast::ViewItem {
|
krate.module.items.insert(0, P(ast::Item {
|
||||||
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
|
id: ast::DUMMY_NODE_ID,
|
||||||
Some((actual_crate_name, ast::CookedStr)),
|
ident: token::str_to_ident("std"),
|
||||||
ast::DUMMY_NODE_ID),
|
|
||||||
attrs: vec!(
|
attrs: vec!(
|
||||||
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
|
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
|
||||||
InternedString::new("macro_use")))),
|
InternedString::new("macro_use")))),
|
||||||
|
node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
|
||||||
vis: ast::Inherited,
|
vis: ast::Inherited,
|
||||||
span: DUMMY_SP
|
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.
|
// don't add #![no_std] here, that will block the prelude injection later.
|
||||||
// Add it during the prelude injection instead.
|
// 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 {
|
let prelude_path = ast::Path {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
global: false,
|
global: false,
|
||||||
|
@ -143,18 +137,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| {
|
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
|
||||||
match x.node {
|
mod_.items.insert(0, P(ast::Item {
|
||||||
ast::ViewItemExternCrate(..) => true,
|
id: ast::DUMMY_NODE_ID,
|
||||||
_ => false,
|
ident: special_idents::invalid,
|
||||||
}
|
node: ast::ItemUse(vp),
|
||||||
});
|
|
||||||
|
|
||||||
// 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),
|
|
||||||
attrs: vec![ast::Attribute {
|
attrs: vec![ast::Attribute {
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
node: ast::Attribute_ {
|
node: ast::Attribute_ {
|
||||||
|
@ -170,14 +157,9 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
|
||||||
}],
|
}],
|
||||||
vis: ast::Inherited,
|
vis: ast::Inherited,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
});
|
}));
|
||||||
view_items.extend(uses.into_iter());
|
|
||||||
|
|
||||||
fold::noop_fold_mod(ast::Mod {
|
fold::noop_fold_mod(mod_, self)
|
||||||
inner: inner,
|
|
||||||
view_items: view_items,
|
|
||||||
items: items
|
|
||||||
}, self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,11 +105,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||||
// Add a special __test module to the crate that will contain code
|
// Add a special __test module to the crate that will contain code
|
||||||
// generated for the test harness
|
// generated for the test harness
|
||||||
let (mod_, reexport) = mk_test_module(&mut self.cx);
|
let (mod_, reexport) = mk_test_module(&mut self.cx);
|
||||||
folded.module.items.push(mod_);
|
|
||||||
match reexport {
|
match reexport {
|
||||||
Some(re) => folded.module.view_items.push(re),
|
Some(re) => folded.module.items.push(re),
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
folded.module.items.push(mod_);
|
||||||
folded
|
folded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,22 +205,19 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
|
||||||
|
|
||||||
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
|
||||||
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, 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");
|
let super_ = token::str_to_ident("super");
|
||||||
|
|
||||||
view_items.extend(tests.into_iter().map(|r| {
|
let items = tests.into_iter().map(|r| {
|
||||||
cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public,
|
cx.ext_cx.item_use_simple(DUMMY_SP, ast::Public,
|
||||||
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
|
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
|
||||||
}));
|
}).chain(tested_submods.into_iter().map(|(r, sym)| {
|
||||||
view_items.extend(tested_submods.into_iter().map(|(r, sym)| {
|
|
||||||
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, 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 {
|
let reexport_mod = ast::Mod {
|
||||||
inner: DUMMY_SP,
|
inner: DUMMY_SP,
|
||||||
view_items: view_items,
|
items: items.collect(),
|
||||||
items: Vec::new(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let sym = token::gensym_ident("__test_reexports");
|
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 id_test = token::str_to_ident("test");
|
||||||
let (vi, vis) = if cx.is_test_crate {
|
let (vi, vis, ident) = if cx.is_test_crate {
|
||||||
(ast::ViewItemUse(
|
(ast::ItemUse(
|
||||||
P(nospan(ast::ViewPathSimple(id_test,
|
P(nospan(ast::ViewPathSimple(id_test,
|
||||||
path_node(vec!(id_test)),
|
path_node(vec!(id_test)))))),
|
||||||
ast::DUMMY_NODE_ID)))),
|
ast::Public, token::special_idents::invalid)
|
||||||
ast::Public)
|
|
||||||
} else {
|
} else {
|
||||||
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
|
(ast::ItemExternCrate(None), ast::Inherited, id_test)
|
||||||
ast::Inherited)
|
|
||||||
};
|
};
|
||||||
ast::ViewItem {
|
P(ast::Item {
|
||||||
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
ident: ident,
|
||||||
node: vi,
|
node: vi,
|
||||||
attrs: Vec::new(),
|
attrs: vec![],
|
||||||
vis: vis,
|
vis: vis,
|
||||||
span: DUMMY_SP
|
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
|
// Link to test crate
|
||||||
let view_items = vec!(mk_std(cx));
|
let import = mk_std(cx);
|
||||||
|
|
||||||
// A constant vector of test descriptors.
|
// A constant vector of test descriptors.
|
||||||
let tests = mk_tests(cx);
|
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 {
|
let testmod = ast::Mod {
|
||||||
inner: DUMMY_SP,
|
inner: DUMMY_SP,
|
||||||
view_items: view_items,
|
items: vec![import, mainfn, tests],
|
||||||
items: vec!(mainfn, tests),
|
|
||||||
};
|
};
|
||||||
let item_ = ast::ItemMod(testmod);
|
let item_ = ast::ItemMod(testmod);
|
||||||
|
|
||||||
|
@ -439,34 +435,35 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
|
||||||
vec![unstable])));
|
vec![unstable])));
|
||||||
attr::mk_attr_inner(attr::mk_attr_id(), allow)
|
attr::mk_attr_inner(attr::mk_attr_id(), allow)
|
||||||
};
|
};
|
||||||
let item = ast::Item {
|
let item = P(ast::Item {
|
||||||
ident: mod_ident,
|
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
ident: mod_ident,
|
||||||
|
attrs: vec![allow_unstable],
|
||||||
node: item_,
|
node: item_,
|
||||||
vis: ast::Public,
|
vis: ast::Public,
|
||||||
span: DUMMY_SP,
|
span: DUMMY_SP,
|
||||||
attrs: vec![allow_unstable],
|
});
|
||||||
};
|
|
||||||
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
|
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
|
||||||
// building `use <ident> = __test::main`
|
// building `use <ident> = __test::main`
|
||||||
let reexport_ident = token::str_to_ident(s.get());
|
let reexport_ident = token::str_to_ident(s.get());
|
||||||
|
|
||||||
let use_path =
|
let use_path =
|
||||||
nospan(ast::ViewPathSimple(reexport_ident,
|
nospan(ast::ViewPathSimple(reexport_ident,
|
||||||
path_node(vec![mod_ident, token::str_to_ident("main")]),
|
path_node(vec![mod_ident, token::str_to_ident("main")])));
|
||||||
ast::DUMMY_NODE_ID));
|
|
||||||
|
|
||||||
ast::ViewItem {
|
P(ast::Item {
|
||||||
node: ast::ViewItemUse(P(use_path)),
|
id: ast::DUMMY_NODE_ID,
|
||||||
|
ident: token::special_idents::invalid,
|
||||||
attrs: vec![],
|
attrs: vec![],
|
||||||
|
node: ast::ItemUse(P(use_path)),
|
||||||
vis: ast::Inherited,
|
vis: ast::Inherited,
|
||||||
span: DUMMY_SP
|
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> {
|
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
|
/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
|
||||||
/// (currently) affect parsing.
|
/// (currently) affect parsing.
|
||||||
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
|
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);
|
self.visit_name(span, ident.name);
|
||||||
}
|
}
|
||||||
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
|
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_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_item(&mut self, i: &'v Item) { walk_item(self, i) }
|
||||||
fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
|
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) {
|
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() {
|
for item in module.items.iter() {
|
||||||
visitor.visit_item(&**item)
|
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) {
|
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
|
||||||
visitor.visit_pat(&*local.pat);
|
visitor.visit_pat(&*local.pat);
|
||||||
walk_ty_opt(visitor, &local.ty);
|
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) {
|
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
|
||||||
visitor.visit_ident(item.span, item.ident);
|
visitor.visit_ident(item.span, item.ident);
|
||||||
match item.node {
|
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) |
|
ItemStatic(ref typ, _, ref expr) |
|
||||||
ItemConst(ref typ, ref expr) => {
|
ItemConst(ref typ, ref expr) => {
|
||||||
visitor.visit_ty(&**typ);
|
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)
|
visitor.visit_mod(module, item.span, item.id)
|
||||||
}
|
}
|
||||||
ItemForeignMod(ref foreign_module) => {
|
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() {
|
for foreign_item in foreign_module.items.iter() {
|
||||||
visitor.visit_foreign_item(&**foreign_item)
|
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) {
|
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() {
|
for statement in block.stmts.iter() {
|
||||||
visitor.visit_stmt(&**statement)
|
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
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
@ -8,8 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
pub extern crate core; //~ ERROR: `pub` visibility is not allowed
|
#![crate_type="lib"]
|
||||||
|
|
||||||
fn main() {
|
pub const X: () = ();
|
||||||
pub use std::usize; //~ ERROR: imports in functions are never reachable
|
|
||||||
}
|
|
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
|
// aux-build:macro_crate_test.rs
|
||||||
// ignore-stage1
|
// ignore-stage1
|
||||||
|
|
||||||
#[plugin] #[no_link]
|
#[plugin] #[no_link] extern crate macro_crate_test;
|
||||||
//~^ ERROR compiler plugins are experimental and possibly buggy
|
//~^ ERROR compiler plugins are experimental and possibly buggy
|
||||||
extern crate macro_crate_test;
|
|
||||||
|
|
||||||
fn main() {}
|
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
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
@ -8,12 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// 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
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
//
|
//
|
||||||
|
@ -9,6 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
pub use std::uint; //~ ERROR: visibility has no effect
|
||||||
pub struct A; //~ ERROR: visibility has no effect
|
pub struct A; //~ ERROR: visibility has no effect
|
||||||
pub enum B {} //~ ERROR: visibility has no effect
|
pub enum B {} //~ ERROR: visibility has no effect
|
||||||
pub trait C { //~ ERROR: visibility has no effect
|
pub trait C { //~ ERROR: visibility has no effect
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#[macro_use]
|
|
||||||
extern crate "std" as std;
|
|
||||||
#[prelude_import]
|
#[prelude_import]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate "std" as std;
|
||||||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
// file at the top-level directory of this distribution and at
|
// file at the top-level directory of this distribution and at
|
||||||
// http://rust-lang.org/COPYRIGHT.
|
// 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