1
Fork 0

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:
Alex Crichton 2015-01-21 11:56:00 -08:00
commit df1cddf20a
60 changed files with 1098 additions and 1520 deletions

View file

@ -803,8 +803,9 @@ Crates contain [items](#items), each of which may have some number of
## Items
```{.ebnf .gram}
item : mod_item | fn_item | type_item | struct_item | enum_item
| static_item | trait_item | impl_item | extern_block ;
item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
| struct_item | enum_item | static_item | trait_item | impl_item
| extern_block ;
```
An _item_ is a component of a crate; some module items can be defined in crate
@ -818,6 +819,8 @@ execution, and may reside in read-only memory.
There are several kinds of item:
* [`extern crate` declarations](#extern-crate-declarations)
* [`use` declarations](#use-declarations)
* [modules](#modules)
* [functions](#functions)
* [type definitions](#type-definitions)
@ -854,13 +857,10 @@ no notion of type abstraction: there are no first-class "forall" types.
```{.ebnf .gram}
mod_item : "mod" ident ( ';' | '{' mod '}' );
mod : [ view_item | item ] * ;
mod : item * ;
```
A module is a container for zero or more [view items](#view-items) and zero or
more [items](#items). The view items manage the visibility of the items defined
within the module, as well as the visibility of names from outside the module
when referenced from inside the module.
A module is a container for zero or more [items](#items).
A _module item_ is a module, surrounded in braces, named, and prefixed with the
keyword `mod`. A module item introduces a new, named module into the tree of
@ -918,19 +918,6 @@ mod thread {
}
```
#### View items
```{.ebnf .gram}
view_item : extern_crate_decl | use_decl ;
```
A view item manages the namespace of a module. View items do not define new
items, but rather, simply change other items' visibility. There are two
kinds of view items:
* [`extern crate` declarations](#extern-crate-declarations)
* [`use` declarations](#use-declarations)
##### Extern crate declarations
```{.ebnf .gram}
@ -2887,13 +2874,12 @@ Point3d {y: 0, z: 10, .. base};
### Block expressions
```{.ebnf .gram}
block_expr : '{' [ view_item ] *
[ stmt ';' | item ] *
block_expr : '{' [ stmt ';' | item ] *
[ expr ] '}' ;
```
A _block expression_ is similar to a module in terms of the declarations that
are possible. Each block conceptually introduces a new namespace scope. View
are possible. Each block conceptually introduces a new namespace scope. Use
items can bring new names into scopes and declared items are in scope for only
the block itself.

View file

@ -77,6 +77,9 @@ register_diagnostics! {
E0138,
E0139,
E0152,
E0153,
E0154,
E0157,
E0158,
E0161,
E0162,

View file

@ -1202,17 +1202,17 @@ impl LintPass for UnusedImportBraces {
lint_array!(UNUSED_IMPORT_BRACES)
}
fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
match view_item.node {
ast::ViewItemUse(ref view_path) => {
fn check_item(&mut self, cx: &Context, item: &ast::Item) {
match item.node {
ast::ItemUse(ref view_path) => {
match view_path.node {
ast::ViewPathList(_, ref items, _) => {
ast::ViewPathList(_, ref items) => {
if items.len() == 1 {
match items[0].node {
ast::PathListIdent {ref name, ..} => {
let m = format!("braces around {} is unnecessary",
token::get_ident(*name).get());
cx.span_lint(UNUSED_IMPORT_BRACES, view_item.span,
cx.span_lint(UNUSED_IMPORT_BRACES, item.span,
&m[]);
},
_ => ()
@ -1709,22 +1709,6 @@ impl LintPass for Stability {
}
}
fn check_view_item(&mut self, cx: &Context, item: &ast::ViewItem) {
// compiler-generated `extern crate` statements have a dummy span.
if item.span == DUMMY_SP { return }
let id = match item.node {
ast::ViewItemExternCrate(_, _, id) => id,
ast::ViewItemUse(..) => return,
};
let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(id) {
Some(cnum) => cnum,
None => return,
};
let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
self.lint(cx, id, item.span);
}
fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
if self.is_internal(cx, e.span) { return; }
@ -1776,6 +1760,17 @@ impl LintPass for Stability {
if self.is_internal(cx, item.span) { return }
match item.node {
ast::ItemExternCrate(_) => {
// compiler-generated `extern crate` items have a dummy span.
if item.span == DUMMY_SP { return }
let cnum = match cx.tcx.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
Some(cnum) => cnum,
None => return,
};
let id = ast::DefId { krate: cnum, node: ast::CRATE_NODE_ID };
self.lint(cx, id, item.span);
}
ast::ItemTrait(_, _, ref supertraits, _) => {
for t in supertraits.iter() {
if let ast::TraitTyParamBound(ref t, _) = *t {

View file

@ -580,14 +580,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
})
}
fn visit_view_item(&mut self, i: &ast::ViewItem) {
self.with_lint_attrs(&i.attrs[], |cx| {
run_lints!(cx, check_view_item, i);
cx.visit_ids(|v| v.visit_view_item(i));
visit::walk_view_item(cx, i);
})
}
fn visit_pat(&mut self, p: &ast::Pat) {
run_lints!(self, check_pat, p);
visit::walk_pat(self, p);

View file

@ -128,7 +128,6 @@ pub trait LintPass {
fn check_crate(&mut self, _: &Context, _: &ast::Crate) { }
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
fn check_mod(&mut self, _: &Context, _: &ast::Mod, _: Span, _: ast::NodeId) { }
fn check_view_item(&mut self, _: &Context, _: &ast::ViewItem) { }
fn check_foreign_item(&mut self, _: &Context, _: &ast::ForeignItem) { }
fn check_item(&mut self, _: &Context, _: &ast::Item) { }
fn check_local(&mut self, _: &Context, _: &ast::Local) { }

View file

@ -40,10 +40,6 @@ pub struct CrateReader<'a> {
}
impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> {
fn visit_view_item(&mut self, a: &ast::ViewItem) {
self.process_view_item(a);
visit::walk_view_item(self, a);
}
fn visit_item(&mut self, a: &ast::Item) {
self.process_item(a);
visit::walk_item(self, a);
@ -64,9 +60,8 @@ fn dump_crates(cstore: &CStore) {
})
}
fn should_link(i: &ast::ViewItem) -> bool {
fn should_link(i: &ast::Item) -> bool {
!attr::contains_name(&i.attrs[], "no_link")
}
struct CrateInfo {
@ -181,7 +176,35 @@ impl<'a> CrateReader<'a> {
}
}
fn process_view_item(&mut self, i: &ast::ViewItem) {
fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
match i.node {
ast::ItemExternCrate(ref path_opt) => {
let ident = token::get_ident(i.ident);
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
ident, path_opt);
let name = match *path_opt {
Some((ref path_str, _)) => {
let name = path_str.get().to_string();
validate_crate_name(Some(self.sess), &name[],
Some(i.span));
name
}
None => ident.get().to_string(),
};
Some(CrateInfo {
ident: ident.get().to_string(),
name: name,
id: i.id,
should_link: should_link(i),
})
}
_ => None
}
}
fn process_item(&mut self, i: &ast::Item) {
match i.node {
ast::ItemExternCrate(_) => {
if !should_link(i) {
return;
}
@ -199,35 +222,6 @@ impl<'a> CrateReader<'a> {
None => ()
}
}
fn extract_crate_info(&self, i: &ast::ViewItem) -> Option<CrateInfo> {
match i.node {
ast::ViewItemExternCrate(ident, ref path_opt, id) => {
let ident = token::get_ident(ident);
debug!("resolving extern crate stmt. ident: {} path_opt: {:?}",
ident, path_opt);
let name = match *path_opt {
Some((ref path_str, _)) => {
let name = path_str.get().to_string();
validate_crate_name(Some(self.sess), &name[],
Some(i.span));
name
}
None => ident.get().to_string(),
};
Some(CrateInfo {
ident: ident.get().to_string(),
name: name,
id: id,
should_link: should_link(i),
})
}
_ => None
}
}
fn process_item(&self, i: &ast::Item) {
match i.node {
ast::ItemForeignMod(ref fm) => {
if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
return;
@ -533,7 +527,7 @@ impl<'a> CrateReader<'a> {
#[derive(Copy)]
pub enum CrateOrString<'a> {
Krate(&'a ast::ViewItem),
Krate(&'a ast::Item),
Str(&'a str)
}

View file

@ -1456,8 +1456,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag();
}
}
ast::ItemMac(..) => {
// macros are encoded separately
ast::ItemExternCrate(_) | ast::ItemUse(_) |ast::ItemMac(..) => {
// these are encoded separately
}
}
}

View file

@ -332,8 +332,6 @@ impl Folder for NestedItemsDropper {
}
}).collect();
let blk_sans_items = P(ast::Block {
view_items: Vec::new(), // I don't know if we need the view_items
// here, but it doesn't break tests!
stmts: stmts_sans_items,
expr: expr,
id: id,

View file

@ -297,6 +297,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// These are normal, nothing reachable about these
// inherently and their children are already in the
// worklist, as determined by the privacy pass
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemTy(..) | ast::ItemStatic(_, _, _) |
ast::ItemMod(..) | ast::ItemForeignMod(..) |
ast::ItemImpl(..) | ast::ItemTrait(..) |

View file

@ -94,6 +94,8 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
// Fn lifetimes get added in visit_fn below:
visit::walk_item(this, item);
}
ast::ItemExternCrate(_) |
ast::ItemUse(_) |
ast::ItemMod(..) |
ast::ItemMac(..) |
ast::ItemForeignMod(..) |

View file

@ -73,8 +73,10 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
// We need to error on `#[macro_use] extern crate` when it isn't at the
// crate root, because `$crate` won't work properly. Identify these by
// spans, because the crate map isn't set up yet.
for vi in krate.module.view_items.iter() {
loader.span_whitelist.insert(vi.span);
for item in krate.module.items.iter() {
if let ast::ItemExternCrate(_) = item.node {
loader.span_whitelist.insert(item.span);
}
}
visit::walk_crate(&mut loader, krate);
@ -91,18 +93,21 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
// note that macros aren't expanded yet, and therefore macros can't add plugins.
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem) {
fn visit_item(&mut self, item: &ast::Item) {
// We're only interested in `extern crate`.
match vi.node {
ast::ViewItemExternCrate(..) => (),
_ => return,
match item.node {
ast::ItemExternCrate(_) => {}
_ => {
visit::walk_item(self, item);
return;
}
}
// Parse the attributes relating to macro / plugin loading.
let mut plugin_attr = None;
let mut macro_selection = Some(HashSet::new()); // None => load all
let mut reexport = HashSet::new();
for attr in vi.attrs.iter() {
for attr in item.attrs.iter() {
let mut used = true;
match attr.name().get() {
"phase" => {
@ -155,7 +160,10 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
}
}
self.load_plugin(CrateOrString::Krate(vi), plugin_attr, macro_selection, Some(reexport))
self.load_plugin(CrateOrString::Krate(item),
plugin_attr,
macro_selection,
Some(reexport))
}
fn visit_mac(&mut self, _: &ast::Mac) {

View file

@ -182,7 +182,6 @@ mod svh_visitor {
SawLifetimeDef(token::InternedString),
SawMod,
SawViewItem,
SawForeignItem,
SawItem,
SawDecl,
@ -430,19 +429,6 @@ mod svh_visitor {
SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
}
fn visit_view_item(&mut self, i: &ViewItem) {
// Two kinds of view items can affect the ABI for a crate:
// exported `pub use` view items (since that may expose
// items that downstream crates can call), and `use
// foo::Trait`, since changing that may affect method
// resolution.
//
// The simplest approach to handling both of the above is
// just to adopt the same simple-minded (fine-grained)
// hash that I am deploying elsewhere here.
SawViewItem.hash(self.st); visit::walk_view_item(self, i)
}
fn visit_foreign_item(&mut self, i: &ForeignItem) {
// FIXME (#14132) ideally we would incorporate privacy (or
// perhaps reachability) somewhere here, so foreign items

View file

@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
e: Option<P<ast::Expr>>) -> P<ast::Block> {
P(ast::Block {
expr: e,
view_items: vec![], stmts: vec![], rules: rules,
stmts: vec![], rules: rules,
id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
})
}

View file

@ -200,6 +200,7 @@ impl<'a, 'tcx> Env<'a, 'tcx> {
}
return match it.node {
ast::ItemUse(..) | ast::ItemExternCrate(..) |
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemFn(..) |
ast::ItemForeignMod(..) | ast::ItemTy(..) => {
None

View file

@ -830,6 +830,38 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
match item.node {
ast::ItemUse(ref vpath) => {
match vpath.node {
ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
ast::ViewPathList(ref prefix, ref list) => {
for pid in list.iter() {
match pid.node {
ast::PathListIdent { id, name } => {
debug!("privacy - ident item {}", id);
let seg = ast::PathSegment {
identifier: name,
parameters: ast::PathParameters::none(),
};
let segs = vec![seg];
let path = ast::Path {
global: false,
span: pid.span,
segments: segs,
};
self.check_path(pid.span, id, &path);
}
ast::PathListMod { id } => {
debug!("privacy - mod item {}", id);
self.check_path(pid.span, id, prefix);
}
}
}
}
}
}
_ => {}
}
let orig_curitem = replace(&mut self.curitem, item.id);
visit::walk_item(self, item);
self.curitem = orig_curitem;
@ -926,42 +958,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
visit::walk_expr(self, expr);
}
fn visit_view_item(&mut self, a: &ast::ViewItem) {
match a.node {
ast::ViewItemExternCrate(..) => {}
ast::ViewItemUse(ref vpath) => {
match vpath.node {
ast::ViewPathSimple(..) | ast::ViewPathGlob(..) => {}
ast::ViewPathList(ref prefix, ref list, _) => {
for pid in list.iter() {
match pid.node {
ast::PathListIdent { id, name } => {
debug!("privacy - ident item {}", id);
let seg = ast::PathSegment {
identifier: name,
parameters: ast::PathParameters::none(),
};
let segs = vec![seg];
let path = ast::Path {
global: false,
span: pid.span,
segments: segs,
};
self.check_path(pid.span, id, &path);
}
ast::PathListMod { id } => {
debug!("privacy - mod item {}", id);
self.check_path(pid.span, id, prefix);
}
}
}
}
}
}
}
visit::walk_view_item(self, a);
}
fn visit_pat(&mut self, pattern: &ast::Pat) {
// Foreign functions do not have their patterns mapped in the def_map,
// and there's nothing really relevant there anyway, so don't bother
@ -1069,23 +1065,6 @@ impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
visit::walk_fn(self, fk, fd, b, s);
self.in_fn = orig_in_fn;
}
fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.vis {
ast::Inherited => {}
ast::Public => {
if self.in_fn {
self.tcx.sess.span_err(i.span, "unnecessary `pub`, imports \
in functions are never \
reachable");
} else if let ast::ViewItemExternCrate(..) = i.node {
self.tcx.sess.span_err(i.span, "`pub` visibility \
is not allowed");
}
}
}
visit::walk_view_item(self, i);
}
}
impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
@ -1162,7 +1141,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
ast::ItemConst(..) | ast::ItemStatic(..) | ast::ItemStruct(..) |
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
ast::ItemMac(..) => {}
ast::ItemExternCrate(_) | ast::ItemUse(_) | ast::ItemMac(..) => {}
}
}
@ -1219,6 +1198,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
}
}
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemStatic(..) | ast::ItemConst(..) |
ast::ItemFn(..) | ast::ItemMod(..) | ast::ItemTy(..) |
ast::ItemMac(..) => {}
@ -1521,11 +1501,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// we don't need to introspect into these at all: an
// expression/block context can't possibly contain exported
// things, and neither do view_items. (Making them no-ops stops us
// from traversing the whole AST without having to be super
// careful about our `walk_...` calls above.)
fn visit_view_item(&mut self, _: &ast::ViewItem) {}
// expression/block context can't possibly contain exported things.
// (Making them no-ops stops us from traversing the whole AST without
// having to be super careful about our `walk_...` calls above.)
fn visit_block(&mut self, _: &ast::Block) {}
fn visit_expr(&mut self, _: &ast::Expr) {}
}

View file

@ -39,9 +39,9 @@ use rustc::middle::subst::FnSpace;
use syntax::ast::{Block, Crate};
use syntax::ast::{DeclItem, DefId};
use syntax::ast::{ForeignItem, ForeignItemFn, ForeignItemStatic};
use syntax::ast::{Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{MethodImplItem, Name, NamedField, NodeId};
use syntax::ast::{PathListIdent, PathListMod};
use syntax::ast::{Public, SelfStatic};
@ -50,8 +50,7 @@ use syntax::ast::StructVariantKind;
use syntax::ast::TupleVariantKind;
use syntax::ast::TyObjectSum;
use syntax::ast::{TypeImplItem, UnnamedField};
use syntax::ast::{Variant, ViewItem, ViewItemExternCrate};
use syntax::ast::{ViewItemUse, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ast::{Visibility};
use syntax::ast::TyPath;
use syntax::ast;
@ -238,11 +237,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
// If the block has view items, we need an anonymous module.
if block.view_items.len() > 0 {
return true;
}
// Check each statement.
for statement in block.stmts.iter() {
match statement.node {
@ -262,7 +256,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
}
// If we found neither view items nor items, we don't need to create
// If we found no items, we don't need to create
// an anonymous module.
return false;
@ -280,6 +274,133 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
match item.node {
ItemUse(ref view_path) => {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path = match view_path.node {
ViewPathSimple(_, ref full_path) => {
full_path.segments
.init()
.iter().map(|ident| ident.identifier.name)
.collect()
}
ViewPathGlob(ref module_ident_path) |
ViewPathList(ref module_ident_path, _) => {
module_ident_path.segments
.iter().map(|ident| ident.identifier.name).collect()
}
};
// Build up the import directives.
let shadowable = item.attrs.iter().any(|attr| {
attr.name() == token::get_name(special_idents::prelude_import.name)
});
let shadowable = if shadowable {
Shadowable::Always
} else {
Shadowable::Never
};
match view_path.node {
ViewPathSimple(binding, ref full_path) => {
let source_name =
full_path.segments.last().unwrap().identifier.name;
if token::get_name(source_name).get() == "mod" ||
token::get_name(source_name).get() == "self" {
self.resolve_error(view_path.span,
"`self` imports are only allowed within a { } list");
}
let subclass = SingleImport(binding.name,
source_name);
self.build_import_directive(&**parent,
module_path,
subclass,
view_path.span,
item.id,
is_public,
shadowable);
}
ViewPathList(_, ref source_items) => {
// Make sure there's at most one `mod` import in the list.
let mod_spans = source_items.iter().filter_map(|item| match item.node {
PathListMod { .. } => Some(item.span),
_ => None
}).collect::<Vec<Span>>();
if mod_spans.len() > 1 {
self.resolve_error(mod_spans[0],
"`self` import can only appear once in the list");
for other_span in mod_spans.iter().skip(1) {
self.session.span_note(*other_span,
"another `self` import appears here");
}
}
for source_item in source_items.iter() {
let (module_path, name) = match source_item.node {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let name = match module_path.last() {
Some(name) => *name,
None => {
self.resolve_error(source_item.span,
"`self` import can only appear in an import list \
with a non-empty prefix");
continue;
}
};
let module_path = module_path.init();
(module_path.to_vec(), name)
}
};
self.build_import_directive(
&**parent,
module_path,
SingleImport(name, name),
source_item.span,
source_item.node.id(),
is_public,
shadowable);
}
}
ViewPathGlob(_) => {
self.build_import_directive(&**parent,
module_path,
GlobImport,
view_path.span,
item.id,
is_public,
shadowable);
}
}
parent.clone()
}
ItemExternCrate(_) => {
// n.b. we don't need to look at the path option here, because cstore already did
for &crate_id in self.session.cstore
.find_extern_mod_stmt_cnum(item.id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(parent.downgrade(), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
parent.external_module_children.borrow_mut()
.insert(name, external_module.clone());
self.build_reduced_graph_for_external_crate(&external_module);
}
parent.clone()
}
ItemMod(..) => {
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
@ -650,145 +771,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
variant.span, PUBLIC | IMPORTABLE);
}
/// Constructs the reduced graph for one 'view item'. View items consist
/// of imports and use directives.
fn build_reduced_graph_for_view_item(&mut self, view_item: &ViewItem, parent: &Rc<Module>) {
match view_item.node {
ViewItemUse(ref view_path) => {
// Extract and intern the module part of the path. For
// globs and lists, the path is found directly in the AST;
// for simple paths we have to munge the path a little.
let module_path = match view_path.node {
ViewPathSimple(_, ref full_path, _) => {
full_path.segments
.init()
.iter().map(|ident| ident.identifier.name)
.collect()
}
ViewPathGlob(ref module_ident_path, _) |
ViewPathList(ref module_ident_path, _, _) => {
module_ident_path.segments
.iter().map(|ident| ident.identifier.name).collect()
}
};
// Build up the import directives.
let is_public = view_item.vis == ast::Public;
let shadowable =
view_item.attrs
.iter()
.any(|attr| {
attr.name() == token::get_name(
special_idents::prelude_import.name)
});
let shadowable = if shadowable {
Shadowable::Always
} else {
Shadowable::Never
};
match view_path.node {
ViewPathSimple(binding, ref full_path, id) => {
let source_name =
full_path.segments.last().unwrap().identifier.name;
if token::get_name(source_name).get() == "mod" ||
token::get_name(source_name).get() == "self" {
self.resolve_error(view_path.span,
"`self` imports are only allowed within a { } list");
}
let subclass = SingleImport(binding.name,
source_name);
self.build_import_directive(&**parent,
module_path,
subclass,
view_path.span,
id,
is_public,
shadowable);
}
ViewPathList(_, ref source_items, _) => {
// Make sure there's at most one `mod` import in the list.
let mod_spans = source_items.iter().filter_map(|item| match item.node {
PathListMod { .. } => Some(item.span),
_ => None
}).collect::<Vec<Span>>();
if mod_spans.len() > 1 {
self.resolve_error(mod_spans[0],
"`self` import can only appear once in the list");
for other_span in mod_spans.iter().skip(1) {
self.session.span_note(*other_span,
"another `self` import appears here");
}
}
for source_item in source_items.iter() {
let (module_path, name) = match source_item.node {
PathListIdent { name, .. } =>
(module_path.clone(), name.name),
PathListMod { .. } => {
let name = match module_path.last() {
Some(name) => *name,
None => {
self.resolve_error(source_item.span,
"`self` import can only appear in an import list \
with a non-empty prefix");
continue;
}
};
let module_path = module_path.init();
(module_path.to_vec(), name)
}
};
self.build_import_directive(
&**parent,
module_path,
SingleImport(name, name),
source_item.span,
source_item.node.id(),
is_public,
shadowable);
}
}
ViewPathGlob(_, id) => {
self.build_import_directive(&**parent,
module_path,
GlobImport,
view_path.span,
id,
is_public,
shadowable);
}
}
}
ViewItemExternCrate(name, _, node_id) => {
// n.b. we don't need to look at the path option here, because cstore already did
for &crate_id in self.session.cstore
.find_extern_mod_stmt_cnum(node_id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(parent.downgrade(), name.name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(
&**parent,
name.name,
view_item.span);
parent.external_module_children.borrow_mut()
.insert(name.name, external_module.clone());
self.build_reduced_graph_for_external_crate(&external_module);
}
}
}
}
/// Constructs the reduced graph for one foreign item.
fn build_reduced_graph_for_foreign_item<F>(&mut self,
foreign_item: &ForeignItem,
@ -1270,10 +1252,6 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> {
})
}
fn visit_view_item(&mut self, view_item: &ViewItem) {
self.builder.build_reduced_graph_for_view_item(view_item, &self.parent);
}
fn visit_block(&mut self, block: &Block) {
let np = self.builder.build_reduced_graph_for_block(block, &self.parent);
let old_parent = replace(&mut self.parent, np);

View file

@ -25,7 +25,6 @@ use Namespace::{TypeNS, ValueNS};
use rustc::lint;
use rustc::middle::privacy::{DependsOn, LastImport, Used, Unused};
use syntax::ast;
use syntax::ast::{ViewItem, ViewItemExternCrate, ViewItemUse};
use syntax::ast::{ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::visit::{self, Visitor};
@ -109,53 +108,54 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
}
impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
fn visit_view_item(&mut self, vi: &ViewItem) {
fn visit_item(&mut self, item: &ast::Item) {
// Ignore is_public import statements because there's no way to be sure
// whether they're used or not. Also ignore imports with a dummy span
// because this means that they were generated in some fashion by the
// compiler and we don't need to consider them.
if vi.vis == ast::Public || vi.span == DUMMY_SP {
visit::walk_view_item(self, vi);
if item.vis == ast::Public || item.span == DUMMY_SP {
visit::walk_item(self, item);
return;
}
match vi.node {
ViewItemExternCrate(_, _, id) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(id) {
match item.node {
ast::ItemExternCrate(_) => {
if let Some(crate_num) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
if !self.used_crates.contains(&crate_num) {
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
id,
vi.span,
item.id,
item.span,
"unused extern crate".to_string());
}
}
},
ViewItemUse(ref p) => {
ast::ItemUse(ref p) => {
match p.node {
ViewPathSimple(_, _, id) => {
self.finalize_import(id, p.span)
ViewPathSimple(_, _) => {
self.finalize_import(item.id, p.span)
}
ViewPathList(_, ref list, _) => {
ViewPathList(_, ref list) => {
for i in list.iter() {
self.finalize_import(i.node.id(), i.span);
}
}
ViewPathGlob(_, id) => {
if !self.used_imports.contains(&(id, TypeNS)) &&
!self.used_imports.contains(&(id, ValueNS)) {
ViewPathGlob(_) => {
if !self.used_imports.contains(&(item.id, TypeNS)) &&
!self.used_imports.contains(&(item.id, ValueNS)) {
self.session
.add_lint(lint::builtin::UNUSED_IMPORTS,
id,
item.id,
p.span,
"unused import".to_string());
}
}
}
}
_ => {}
}
visit::walk_view_item(self, vi);
visit::walk_item(self, item);
}
}

View file

@ -65,10 +65,10 @@ use syntax::ast::{DefId, Expr, ExprAgain, ExprBreak, ExprField};
use syntax::ast::{ExprClosure, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
use syntax::ast::{ExprPath, ExprQPath, ExprStruct, FnDecl};
use syntax::ast::{ForeignItemFn, ForeignItemStatic, Generics};
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemFn};
use syntax::ast::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, Local, LOCAL_CRATE};
use syntax::ast::{MethodImplItem, Mod, Name, NodeId};
use syntax::ast::{Ident, ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate};
use syntax::ast::{ItemFn, ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic};
use syntax::ast::{ItemStruct, ItemTrait, ItemTy, ItemUse};
use syntax::ast::{Local, MethodImplItem, Mod, Name, NodeId};
use syntax::ast::{Pat, PatEnum, PatIdent, PatLit};
use syntax::ast::{PatRange, PatStruct, Path};
use syntax::ast::{PolyTraitRef, PrimTy, SelfExplicit};
@ -1143,7 +1143,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
fn get_trait_name(&self, did: DefId) -> Name {
if did.krate == LOCAL_CRATE {
if did.krate == ast::LOCAL_CRATE {
self.ast_map.expect_item(did.node).ident.name
} else {
csearch::get_trait_name(&self.session.cstore, did)
@ -1752,10 +1752,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
import_span: Span,
name: Name,
namespace: Namespace) {
if self.session.features.borrow().import_shadowing {
return
}
debug!("check_for_conflicting_import: {}; target exists: {}",
token::get_name(name).get(),
target.is_some());
@ -1795,10 +1791,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
&ImportResolution,
import_span: Span,
name: Name) {
if self.session.features.borrow().import_shadowing {
return
}
// First, check for conflicts between imports and `extern crate`s.
if module.external_module_children
.borrow()
@ -1892,10 +1884,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module: &Module,
name: Name,
span: Span) {
if self.session.features.borrow().import_shadowing {
return
}
if module.external_module_children.borrow().contains_key(&name) {
span_err!(self.session, span, E0259,
"an external crate named `{}` has already \
@ -1909,10 +1897,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
module: &Module,
name: Name,
span: Span) {
if self.session.features.borrow().import_shadowing {
return
}
if module.external_module_children.borrow().contains_key(&name) {
span_err!(self.session, span, E0260,
"the name `{}` conflicts with an external \
@ -2984,7 +2968,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
});
}
ItemMac(..) => {
ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => {
// do nothing, these are just around to be encoded
}
}
@ -3527,6 +3511,26 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
}
}
// Check for imports appearing after non-item statements.
let mut found_non_item = false;
for statement in block.stmts.iter() {
if let ast::StmtDecl(ref declaration, _) = statement.node {
if let ast::DeclItem(ref i) = declaration.node {
match i.node {
ItemExternCrate(_) | ItemUse(_) if found_non_item => {
span_err!(self.session, i.span, E0154,
"imports are not allowed after non-item statements");
}
_ => {}
}
} else {
found_non_item = true
}
} else {
found_non_item = true;
}
}
// Descend into the block.
visit::walk_block(self, block);

View file

@ -1037,6 +1037,110 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
}
match item.node {
ast::ItemUse(ref use_item) => {
match use_item.node {
ast::ViewPathSimple(ident, ref path) => {
let sub_span = self.span.span_for_last_ident(path.span);
let mod_id = match self.lookup_type_ref(item.id) {
Some(def_id) => {
match self.lookup_def_kind(item.id, path.span) {
Some(kind) => self.fmt.ref_str(kind,
path.span,
sub_span,
def_id,
self.cur_scope),
None => {},
}
Some(def_id)
},
None => None,
};
// 'use' always introduces an alias, if there is not an explicit
// one, there is an implicit one.
let sub_span =
match self.span.sub_span_after_keyword(use_item.span, keywords::As) {
Some(sub_span) => Some(sub_span),
None => sub_span,
};
self.fmt.use_alias_str(path.span,
sub_span,
item.id,
mod_id,
get_ident(ident).get(),
self.cur_scope);
self.write_sub_paths_truncated(path);
}
ast::ViewPathGlob(ref path) => {
// Make a comma-separated list of names of imported modules.
let mut name_string = String::new();
let glob_map = &self.analysis.glob_map;
let glob_map = glob_map.as_ref().unwrap();
if glob_map.contains_key(&item.id) {
for n in glob_map[item.id].iter() {
if name_string.len() > 0 {
name_string.push_str(", ");
}
name_string.push_str(n.as_str());
}
}
let sub_span = self.span.sub_span_of_token(path.span,
token::BinOp(token::Star));
self.fmt.use_glob_str(path.span,
sub_span,
item.id,
name_string.as_slice(),
self.cur_scope);
self.write_sub_paths(path);
}
ast::ViewPathList(ref path, ref list) => {
for plid in list.iter() {
match plid.node {
ast::PathListIdent { id, .. } => {
match self.lookup_type_ref(id) {
Some(def_id) =>
match self.lookup_def_kind(id, plid.span) {
Some(kind) => {
self.fmt.ref_str(
kind, plid.span,
Some(plid.span),
def_id, self.cur_scope);
}
None => ()
},
None => ()
}
},
ast::PathListMod { .. } => ()
}
}
self.write_sub_paths(path);
}
}
}
ast::ItemExternCrate(ref s) => {
let name = get_ident(item.ident);
let name = name.get();
let s = match *s {
Some((ref s, _)) => s.get().to_string(),
None => name.to_string(),
};
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Crate);
let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(item.id) {
Some(cnum) => cnum,
None => 0,
};
self.fmt.extern_crate_str(item.span,
sub_span,
item.id,
cnum,
name,
&s[],
self.cur_scope);
}
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
self.process_fn(item, &**decl, ty_params, &**body),
ast::ItemStatic(ref typ, mt, ref expr) =>
@ -1160,119 +1264,6 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
}
}
fn visit_view_item(&mut self, i: &ast::ViewItem) {
if generated_code(i.span) {
return
}
match i.node {
ast::ViewItemUse(ref item) => {
match item.node {
ast::ViewPathSimple(ident, ref path, id) => {
let sub_span = self.span.span_for_last_ident(path.span);
let mod_id = match self.lookup_type_ref(id) {
Some(def_id) => {
match self.lookup_def_kind(id, path.span) {
Some(kind) => self.fmt.ref_str(kind,
path.span,
sub_span,
def_id,
self.cur_scope),
None => {},
}
Some(def_id)
},
None => None,
};
// 'use' always introduces an alias, if there is not an explicit
// one, there is an implicit one.
let sub_span =
match self.span.sub_span_after_keyword(item.span, keywords::As) {
Some(sub_span) => Some(sub_span),
None => sub_span,
};
self.fmt.use_alias_str(path.span,
sub_span,
id,
mod_id,
get_ident(ident).get(),
self.cur_scope);
self.write_sub_paths_truncated(path);
}
ast::ViewPathGlob(ref path, id) => {
// Make a comma-separated list of names of imported modules.
let mut name_string = String::new();
let glob_map = &self.analysis.glob_map;
let glob_map = glob_map.as_ref().unwrap();
if glob_map.contains_key(&id) {
for n in glob_map[id].iter() {
if name_string.len() > 0 {
name_string.push_str(", ");
}
name_string.push_str(n.as_str());
}
}
let sub_span = self.span.sub_span_of_token(path.span,
token::BinOp(token::Star));
self.fmt.use_glob_str(path.span,
sub_span,
id,
name_string.as_slice(),
self.cur_scope);
self.write_sub_paths(path);
}
ast::ViewPathList(ref path, ref list, _) => {
for plid in list.iter() {
match plid.node {
ast::PathListIdent { id, .. } => {
match self.lookup_type_ref(id) {
Some(def_id) =>
match self.lookup_def_kind(id, plid.span) {
Some(kind) => {
self.fmt.ref_str(
kind, plid.span,
Some(plid.span),
def_id, self.cur_scope);
}
None => ()
},
None => ()
}
},
ast::PathListMod { .. } => ()
}
}
self.write_sub_paths(path);
}
}
},
ast::ViewItemExternCrate(ident, ref s, id) => {
let name = get_ident(ident);
let name = name.get();
let s = match *s {
Some((ref s, _)) => s.get().to_string(),
None => name.to_string(),
};
let sub_span = self.span.sub_span_after_keyword(i.span, keywords::Crate);
let cnum = match self.sess.cstore.find_extern_mod_stmt_cnum(id) {
Some(cnum) => cnum,
None => 0,
};
self.fmt.extern_crate_str(i.span,
sub_span,
id,
cnum,
name,
&s[],
self.cur_scope);
},
}
}
fn visit_ty(&mut self, t: &ast::Ty) {
if generated_code(t.span) {
return

View file

@ -274,7 +274,6 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ast_map::NodeArg(..) |
ast_map::NodeBlock(..) |
ast_map::NodePat(..) |
ast_map::NodeViewItem(..) |
ast_map::NodeLocal(..) => {
ccx.sess().bug(&format!("can't monomorphize a {:?}",
map_node)[])

View file

@ -555,6 +555,7 @@ fn convert(ccx: &CollectCtxt, it: &ast::Item) {
debug!("convert: item {} with id {}", token::get_ident(it.ident), it.id);
match it.node {
// These don't define types.
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
ast::ItemEnum(ref enum_definition, ref generics) => {
let scheme = ty_of_item(ccx, it);
@ -1004,6 +1005,7 @@ fn ty_of_item<'a, 'tcx>(ccx: &CollectCtxt<'a, 'tcx>, it: &ast::Item)
tcx.tcache.borrow_mut().insert(local_def(it.id), scheme.clone());
return scheme;
}
ast::ItemExternCrate(_) | ast::ItemUse(_) |
ast::ItemImpl(..) | ast::ItemMod(_) |
ast::ItemForeignMod(_) | ast::ItemMac(_) => panic!(),
}

View file

@ -380,6 +380,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
visit::walk_item(self, item);
}
ast::ItemExternCrate(_) |
ast::ItemUse(_) |
ast::ItemImpl(..) |
ast::ItemStatic(..) |
ast::ItemConst(..) |
@ -532,6 +534,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
}
}
ast::ItemExternCrate(_) |
ast::ItemUse(_) |
ast::ItemStatic(..) |
ast::ItemConst(..) |
ast::ItemFn(..) |

View file

@ -18,8 +18,7 @@ pub use self::TypeKind::*;
pub use self::StructField::*;
pub use self::VariantKind::*;
pub use self::Mutability::*;
pub use self::ViewItemInner::*;
pub use self::ViewPath::*;
pub use self::Import::*;
pub use self::ItemEnum::*;
pub use self::Attribute::*;
pub use self::TyParamBound::*;
@ -315,6 +314,8 @@ impl Item {
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
pub enum ItemEnum {
ExternCrateItem(String, Option<String>),
ImportItem(Import),
StructItem(Struct),
EnumItem(Enum),
FunctionItem(Function),
@ -324,8 +325,6 @@ pub enum ItemEnum {
ConstantItem(Constant),
TraitItem(Trait),
ImplItem(Impl),
/// `use` and `extern crate`
ViewItemItem(ViewItem),
/// A method signature only. Used for required methods in traits (ie,
/// non-default-methods).
TyMethodItem(TyMethod),
@ -355,27 +354,21 @@ impl Clean<Item> for doctree::Module {
} else {
"".to_string()
};
let mut foreigns = Vec::new();
for subforeigns in self.foreigns.clean(cx).into_iter() {
for foreign in subforeigns.into_iter() {
foreigns.push(foreign)
}
}
let items: Vec<Vec<Item> > = vec!(
self.structs.clean(cx),
self.enums.clean(cx),
self.fns.clean(cx),
foreigns,
self.mods.clean(cx),
self.typedefs.clean(cx),
self.statics.clean(cx),
self.constants.clean(cx),
self.traits.clean(cx),
self.impls.clean(cx),
self.view_items.clean(cx).into_iter()
.flat_map(|s| s.into_iter()).collect(),
self.macros.clean(cx),
);
let items: Vec<Item> =
self.extern_crates.iter().map(|x| x.clean(cx))
.chain(self.imports.iter().flat_map(|x| x.clean(cx).into_iter()))
.chain(self.structs.iter().map(|x| x.clean(cx)))
.chain(self.enums.iter().map(|x| x.clean(cx)))
.chain(self.fns.iter().map(|x| x.clean(cx)))
.chain(self.foreigns.iter().flat_map(|x| x.clean(cx).into_iter()))
.chain(self.mods.iter().map(|x| x.clean(cx)))
.chain(self.typedefs.iter().map(|x| x.clean(cx)))
.chain(self.statics.iter().map(|x| x.clean(cx)))
.chain(self.constants.iter().map(|x| x.clean(cx)))
.chain(self.traits.iter().map(|x| x.clean(cx)))
.chain(self.impls.iter().map(|x| x.clean(cx)))
.chain(self.macros.iter().map(|x| x.clean(cx)))
.collect();
// determine if we should display the inner contents or
// the outer `mod` item for the source code.
@ -401,9 +394,7 @@ impl Clean<Item> for doctree::Module {
def_id: ast_util::local_def(self.id),
inner: ModuleItem(Module {
is_crate: self.is_crate,
items: items.iter()
.flat_map(|x| x.iter().map(|x| (*x).clone()))
.collect(),
items: items
})
}
}
@ -2143,12 +2134,21 @@ impl Clean<Item> for doctree::Impl {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
pub struct ViewItem {
pub inner: ViewItemInner,
impl Clean<Item> for doctree::ExternCrate {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(cx),
stability: None,
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
}
}
}
impl Clean<Vec<Item>> for ast::ViewItem {
impl Clean<Vec<Item>> for doctree::Import {
fn clean(&self, cx: &DocContext) -> Vec<Item> {
// We consider inlining the documentation of `pub use` statements, but we
// forcefully don't inline if this is not public or if the
@ -2159,81 +2159,63 @@ impl Clean<Vec<Item>> for ast::ViewItem {
None => false,
}
});
let convert = |&: node: &ast::ViewItem_| {
Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(cx),
stability: None,
inner: ViewItemItem(ViewItem { inner: node.clean(cx) }),
let (mut ret, inner) = match self.node {
ast::ViewPathGlob(ref p) => {
(vec![], GlobImport(resolve_use_source(cx, p.clean(cx), self.id)))
}
};
let mut ret = Vec::new();
match self.node {
ast::ViewItemUse(ref path) if !denied => {
match path.node {
ast::ViewPathGlob(..) => ret.push(convert(&self.node)),
ast::ViewPathList(ref a, ref list, ref b) => {
ast::ViewPathList(ref p, ref list) => {
// Attempt to inline all reexported items, but be sure
// to keep any non-inlineable reexports so they can be
// listed in the documentation.
let remaining = list.iter().filter(|path| {
let mut ret = vec![];
let remaining = if !denied {
let mut remaining = vec![];
for path in list.iter() {
match inline::try_inline(cx, path.node.id(), None) {
Some(items) => {
ret.extend(items.into_iter()); false
ret.extend(items.into_iter());
}
None => true,
}
}).map(|a| a.clone()).collect::<Vec<ast::PathListItem>>();
if remaining.len() > 0 {
let path = ast::ViewPathList(a.clone(),
remaining,
b.clone());
let path = syntax::codemap::dummy_spanned(path);
ret.push(convert(&ast::ViewItemUse(P(path))));
}
}
ast::ViewPathSimple(ident, _, id) => {
match inline::try_inline(cx, id, Some(ident)) {
Some(items) => ret.extend(items.into_iter()),
None => ret.push(convert(&self.node)),
None => {
remaining.push(path.clean(cx));
}
}
}
}
ref n => ret.push(convert(n)),
}
remaining
} else {
list.clean(cx)
};
if remaining.is_empty() {
return ret;
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
pub enum ViewItemInner {
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()),
(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)))
}
};
ExternCrate(i.clean(cx), string, *id)
}
&ast::ViewItemUse(ref vp) => {
Import(vp.clean(cx))
}
}
ret.push(Item {
name: None,
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: ast_util::local_def(0),
visibility: self.vis.clean(cx),
stability: None,
inner: ImportItem(inner)
});
ret
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
pub enum ViewPath {
pub enum Import {
// use source as str;
SimpleImport(String, ImportSource),
// use source::*;
@ -2248,21 +2230,6 @@ pub struct ImportSource {
pub did: Option<ast::DefId>,
}
impl Clean<ViewPath> for ast::ViewPath {
fn clean(&self, cx: &DocContext) -> ViewPath {
match self.node {
ast::ViewPathSimple(ref i, ref p, id) =>
SimpleImport(i.clean(cx), resolve_use_source(cx, p.clean(cx), id)),
ast::ViewPathGlob(ref p, id) =>
GlobImport(resolve_use_source(cx, p.clean(cx), id)),
ast::ViewPathList(ref p, ref pl, id) => {
ImportList(resolve_use_source(cx, p.clean(cx), id),
pl.clean(cx))
}
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Show)]
pub struct ViewListIdent {
pub name: String,

View file

@ -25,6 +25,8 @@ pub struct Module {
pub attrs: Vec<ast::Attribute>,
pub where_outer: Span,
pub where_inner: Span,
pub extern_crates: Vec<ExternCrate>,
pub imports: Vec<Import>,
pub structs: Vec<Struct>,
pub enums: Vec<Enum>,
pub fns: Vec<Function>,
@ -38,7 +40,6 @@ pub struct Module {
pub stab: Option<attr::Stability>,
pub impls: Vec<Impl>,
pub foreigns: Vec<ast::ForeignMod>,
pub view_items: Vec<ast::ViewItem>,
pub macros: Vec<Macro>,
pub is_crate: bool,
}
@ -53,6 +54,8 @@ impl Module {
where_outer: syntax::codemap::DUMMY_SP,
where_inner: syntax::codemap::DUMMY_SP,
attrs : Vec::new(),
extern_crates: Vec::new(),
imports : Vec::new(),
structs : Vec::new(),
enums : Vec::new(),
fns : Vec::new(),
@ -62,7 +65,6 @@ impl Module {
constants : Vec::new(),
traits : Vec::new(),
impls : Vec::new(),
view_items : Vec::new(),
foreigns : Vec::new(),
macros : Vec::new(),
is_crate : false,
@ -202,6 +204,22 @@ pub struct Macro {
pub stab: Option<attr::Stability>,
}
pub struct ExternCrate {
pub name: Ident,
pub path: Option<String>,
pub vis: ast::Visibility,
pub attrs: Vec<ast::Attribute>,
pub whence: Span,
}
pub struct Import {
pub id: NodeId,
pub vis: ast::Visibility,
pub attrs: Vec<ast::Attribute>,
pub node: ast::ViewPath_,
pub whence: Span,
}
pub fn struct_type_from_def(sd: &ast::StructDef) -> StructType {
if sd.ctor_id.is_some() {
// We are in a tuple-struct

View file

@ -617,7 +617,7 @@ impl fmt::Display for UnsafetySpace {
}
}
impl fmt::Display for clean::ViewPath {
impl fmt::Display for clean::Import {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
clean::SimpleImport(ref name, ref src) => {

View file

@ -22,29 +22,31 @@ use clean;
#[derive(Copy, PartialEq, Clone)]
pub enum ItemType {
Module = 0,
Struct = 1,
Enum = 2,
Function = 3,
Typedef = 4,
Static = 5,
Trait = 6,
Impl = 7,
ViewItem = 8,
TyMethod = 9,
Method = 10,
StructField = 11,
Variant = 12,
// we used to have ForeignFunction and ForeignStatic. they are retired now.
Macro = 15,
Primitive = 16,
AssociatedType = 17,
Constant = 18,
ExternCrate = 1,
Import = 2,
Struct = 3,
Enum = 4,
Function = 5,
Typedef = 6,
Static = 7,
Trait = 8,
Impl = 9,
TyMethod = 10,
Method = 11,
StructField = 12,
Variant = 13,
Macro = 14,
Primitive = 15,
AssociatedType = 16,
Constant = 17,
}
impl ItemType {
pub fn from_item(item: &clean::Item) -> ItemType {
match item.inner {
clean::ModuleItem(..) => ItemType::Module,
clean::ExternCrateItem(..) => ItemType::ExternCrate,
clean::ImportItem(..) => ItemType::Import,
clean::StructItem(..) => ItemType::Struct,
clean::EnumItem(..) => ItemType::Enum,
clean::FunctionItem(..) => ItemType::Function,
@ -53,7 +55,6 @@ impl ItemType {
clean::ConstantItem(..) => ItemType::Constant,
clean::TraitItem(..) => ItemType::Trait,
clean::ImplItem(..) => ItemType::Impl,
clean::ViewItemItem(..) => ItemType::ViewItem,
clean::TyMethodItem(..) => ItemType::TyMethod,
clean::MethodItem(..) => ItemType::Method,
clean::StructFieldItem(..) => ItemType::StructField,
@ -83,6 +84,8 @@ impl ItemType {
pub fn to_static_str(&self) -> &'static str {
match *self {
ItemType::Module => "mod",
ItemType::ExternCrate => "externcrate",
ItemType::Import => "import",
ItemType::Struct => "struct",
ItemType::Enum => "enum",
ItemType::Function => "fn",
@ -90,7 +93,6 @@ impl ItemType {
ItemType::Static => "static",
ItemType::Trait => "trait",
ItemType::Impl => "impl",
ItemType::ViewItem => "viewitem",
ItemType::TyMethod => "tymethod",
ItemType::Method => "method",
ItemType::StructField => "structfield",

View file

@ -35,7 +35,7 @@
pub use self::ExternalLocation::*;
use std::cell::RefCell;
use std::cmp::Ordering::{self, Less, Greater, Equal};
use std::cmp::Ordering;
use std::collections::{HashMap, HashSet};
use std::default::Default;
use std::fmt;
@ -1497,18 +1497,19 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
// the order of item types in the listing
fn reorder(ty: ItemType) -> u8 {
match ty {
ItemType::ViewItem => 0,
ItemType::Primitive => 1,
ItemType::Module => 2,
ItemType::Macro => 3,
ItemType::Struct => 4,
ItemType::Enum => 5,
ItemType::Constant => 6,
ItemType::Static => 7,
ItemType::Trait => 8,
ItemType::Function => 9,
ItemType::Typedef => 10,
_ => 11 + ty as u8,
ItemType::ExternCrate => 0,
ItemType::Import => 1,
ItemType::Primitive => 2,
ItemType::Module => 3,
ItemType::Macro => 4,
ItemType::Struct => 5,
ItemType::Enum => 6,
ItemType::Constant => 7,
ItemType::Static => 8,
ItemType::Trait => 9,
ItemType::Function => 10,
ItemType::Typedef => 12,
_ => 13 + ty as u8,
}
}
@ -1518,25 +1519,7 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
if ty1 == ty2 {
return i1.name.cmp(&i2.name);
}
let tycmp = reorder(ty1).cmp(&reorder(ty2));
if let Equal = tycmp {
// for reexports, `extern crate` takes precedence.
match (&i1.inner, &i2.inner) {
(&clean::ViewItemItem(ref a), &clean::ViewItemItem(ref b)) => {
match (&a.inner, &b.inner) {
(&clean::ExternCrate(..), _) => return Less,
(_, &clean::ExternCrate(..)) => return Greater,
_ => {}
}
}
(_, _) => {}
}
idx1.cmp(&idx2)
} else {
tycmp
}
(reorder(ty1), idx1).cmp(&(reorder(ty2), idx2))
}
indices.sort_by(|&i1, &i2| cmp(&items[i1], &items[i2], i1, i2));
@ -1547,12 +1530,17 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
let myitem = &items[idx];
let myty = Some(shortty(myitem));
if myty != curty {
if curty == Some(ItemType::ExternCrate) && myty == Some(ItemType::Import) {
// Put `extern crate` and `use` re-exports in the same section.
curty = myty;
} else if myty != curty {
if curty.is_some() {
try!(write!(w, "</table>"));
}
curty = myty;
let (short, name) = match myty.unwrap() {
ItemType::ExternCrate |
ItemType::Import => ("reexports", "Reexports"),
ItemType::Module => ("modules", "Modules"),
ItemType::Struct => ("structs", "Structs"),
ItemType::Enum => ("enums", "Enums"),
@ -1562,7 +1550,6 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
ItemType::Constant => ("constants", "Constants"),
ItemType::Trait => ("traits", "Traits"),
ItemType::Impl => ("impls", "Implementations"),
ItemType::ViewItem => ("reexports", "Reexports"),
ItemType::TyMethod => ("tymethods", "Type Methods"),
ItemType::Method => ("methods", "Methods"),
ItemType::StructField => ("fields", "Struct Fields"),
@ -1578,28 +1565,25 @@ fn item_module(w: &mut fmt::Formatter, cx: &Context,
}
match myitem.inner {
clean::ViewItemItem(ref item) => {
match item.inner {
clean::ExternCrate(ref name, ref src, _) => {
clean::ExternCrateItem(ref name, ref src) => {
match *src {
Some(ref src) =>
try!(write!(w, "<tr><td><code>extern crate \"{}\" as {}",
src.as_slice(),
name.as_slice())),
None =>
try!(write!(w, "<tr><td><code>extern crate {}",
name.as_slice())),
}
try!(write!(w, ";</code></td></tr>"));
}
clean::Import(ref import) => {
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
Some(ref src) => {
try!(write!(w, "<tr><td><code>{}extern crate \"{}\" as {};",
VisSpace(myitem.visibility),
*import));
src.as_slice(),
name.as_slice()))
}
None => {
try!(write!(w, "<tr><td><code>{}extern crate {};",
VisSpace(myitem.visibility), name.as_slice()))
}
}
try!(write!(w, "</code></td></tr>"));
}
clean::ImportItem(ref import) => {
try!(write!(w, "<tr><td><code>{}{}</code></td></tr>",
VisSpace(myitem.visibility), *import));
}
_ => {

View file

@ -245,7 +245,6 @@ nav.sub {
.content .highlighted.method { background-color: #c6afb3; }
.content .highlighted.tymethod { background-color: #c6afb3; }
.content .highlighted.type { background-color: #c6afb3; }
.content .highlighted.ffi { background-color: #c6afb3; }
.docblock.short.nowrap {
display: block;
@ -365,7 +364,6 @@ p a:hover { text-decoration: underline; }
.content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
.content span.method, .content a.method, .block a.current.method { color: #8c6067; }
.content span.tymethod, .content a.tymethod, .block a.current.tymethod { color: #8c6067; }
.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
.content .fnname { color: #8c6067; }
.search-input {

View file

@ -555,6 +555,8 @@
// This mapping table should match the discriminants of
// `rustdoc::html::item_type::ItemType` type in Rust.
var itemTypes = ["mod",
"externcrate",
"import",
"struct",
"enum",
"fn",
@ -562,13 +564,10 @@
"static",
"trait",
"impl",
"viewitem",
"tymethod",
"method",
"structfield",
"variant",
"ffi", // retained for backward compatibility
"ffs", // retained for backward compatibility
"macro",
"primitive",
"associatedtype",

View file

@ -149,7 +149,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
}
}
clean::ViewItemItem(..) => {
clean::ExternCrateItem(..) | clean::ImportItem(_) => {
if i.visibility != Some(ast::Public) {
return None
}

View file

@ -21,7 +21,7 @@ use syntax::ast::Public;
use clean::{Crate, Item, ModuleItem, Module, EnumItem, Enum};
use clean::{ImplItem, Impl, Trait, TraitItem, TraitMethod, ProvidedMethod, RequiredMethod};
use clean::{TypeTraitItem, ViewItemItem, PrimitiveItem, Stability};
use clean::{TypeTraitItem, ExternCrateItem, ImportItem, PrimitiveItem, Stability};
use html::render::cache;
@ -199,7 +199,8 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
}))
}
// no stability information for the following items:
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
ExternCrateItem(..) | ImportItem(_) |
PrimitiveItem(_) => (Counts::zero(), None),
_ => (item_counts, None)
}
}

View file

@ -20,7 +20,6 @@ use syntax::ast_map;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;
use syntax::ptr::P;
use rustc::middle::stability;
@ -142,9 +141,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
m: &ast::Mod,
name: Option<ast::Ident>) -> Module {
let mut om = Module::new(name);
for item in m.view_items.iter() {
self.visit_view_item(item, &mut om);
}
om.where_outer = span;
om.where_inner = m.inner;
om.attrs = attrs;
@ -157,68 +153,41 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om
}
pub fn visit_view_item(&mut self, item: &ast::ViewItem, om: &mut Module) {
if item.vis != ast::Public {
return om.view_items.push(item.clone());
}
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
Some(list) => {
list.iter().any(|i| i.name().get() == "inline")
}
None => false,
}
});
let item = match item.node {
ast::ViewItemUse(ref vpath) => {
match self.visit_view_path(&**vpath, om, please_inline) {
None => return,
Some(path) => {
ast::ViewItem {
node: ast::ViewItemUse(path),
.. item.clone()
}
}
}
}
ast::ViewItemExternCrate(..) => item.clone()
};
om.view_items.push(item);
}
fn visit_view_path(&mut self, path: &ast::ViewPath,
fn visit_view_path(&mut self, path: ast::ViewPath_,
om: &mut Module,
please_inline: bool) -> Option<P<ast::ViewPath>> {
match path.node {
ast::ViewPathSimple(dst, _, id) => {
id: ast::NodeId,
please_inline: bool) -> Option<ast::ViewPath_> {
match path {
ast::ViewPathSimple(dst, base) => {
if self.resolve_id(id, Some(dst), false, om, please_inline) {
return None
}
}
ast::ViewPathList(ref p, ref paths, ref b) => {
let mut mine = Vec::new();
for path in paths.iter() {
if !self.resolve_id(path.node.id(), None, false, om,
please_inline) {
mine.push(path.clone());
None
} else {
Some(ast::ViewPathSimple(dst, base))
}
}
ast::ViewPathList(p, paths) => {
let mine = paths.into_iter().filter(|path| {
!self.resolve_id(path.node.id(), None, false, om,
please_inline)
}).collect::<Vec<ast::PathListItem>>();
if mine.len() == 0 { return None }
return Some(P(::syntax::codemap::Spanned {
node: ast::ViewPathList(p.clone(), mine, b.clone()),
span: path.span,
}))
if mine.len() == 0 {
None
} else {
Some(ast::ViewPathList(p, mine))
}
}
// these are feature gated anyway
ast::ViewPathGlob(_, id) => {
ast::ViewPathGlob(base) => {
if self.resolve_id(id, None, true, om, please_inline) {
return None
None
} else {
Some(ast::ViewPathGlob(base))
}
}
}
Some(P(path.clone()))
}
fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
@ -242,9 +211,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
if glob {
match it.node {
ast::ItemMod(ref m) => {
for vi in m.view_items.iter() {
self.visit_view_item(vi, om);
}
for i in m.items.iter() {
self.visit_item(&**i, None, om);
}
@ -268,6 +234,45 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
debug!("Visiting item {:?}", item);
let name = renamed.unwrap_or(item.ident);
match item.node {
ast::ItemExternCrate(ref p) => {
let path = match *p {
None => None,
Some((ref x, _)) => Some(x.get().to_string()),
};
om.extern_crates.push(ExternCrate {
name: name,
path: path,
vis: item.vis,
attrs: item.attrs.clone(),
whence: item.span,
})
}
ast::ItemUse(ref vpath) => {
let node = vpath.node.clone();
let node = if item.vis == ast::Public {
let please_inline = item.attrs.iter().any(|item| {
match item.meta_item_list() {
Some(list) => {
list.iter().any(|i| i.name().get() == "inline")
}
None => false,
}
});
match self.visit_view_path(node, om, item.id, please_inline) {
None => return,
Some(p) => p
}
} else {
node
};
om.imports.push(Import {
id: item.id,
vis: item.vis,
attrs: item.attrs.clone(),
node: node,
whence: item.span,
});
}
ast::ItemMod(ref m) => {
om.mods.push(self.visit_mod_contents(item.span,
item.attrs.clone(),

View file

@ -53,7 +53,6 @@ pub use self::UnboxedClosureKind::*;
pub use self::UnOp::*;
pub use self::UnsafeSource::*;
pub use self::VariantKind::*;
pub use self::ViewItem_::*;
pub use self::ViewPath_::*;
pub use self::Visibility::*;
pub use self::PathParameters::*;
@ -511,7 +510,6 @@ impl PartialEq for MetaItem_ {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub struct Block {
pub view_items: Vec<ViewItem>,
pub stmts: Vec<P<Stmt>>,
pub expr: Option<P<Expr>>,
pub id: NodeId,
@ -1443,14 +1441,12 @@ pub struct Mod {
/// For `mod foo;`, the inner span ranges from the first token
/// to the last token in the external file.
pub inner: Span,
pub view_items: Vec<ViewItem>,
pub items: Vec<P<Item>>,
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub struct ForeignMod {
pub abi: Abi,
pub view_items: Vec<ViewItem>,
pub items: Vec<P<ForeignItem>>,
}
@ -1509,44 +1505,13 @@ pub enum ViewPath_ {
/// or just
///
/// `foo::bar::baz` (with `as baz` implicitly on the right)
ViewPathSimple(Ident, Path, NodeId),
ViewPathSimple(Ident, Path),
/// `foo::bar::*`
ViewPathGlob(Path, NodeId),
ViewPathGlob(Path),
/// `foo::bar::{a,b,c}`
ViewPathList(Path, Vec<PathListItem> , NodeId)
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub struct ViewItem {
pub node: ViewItem_,
pub attrs: Vec<Attribute>,
pub vis: Visibility,
pub span: Span,
}
impl ViewItem {
pub fn id(&self) -> NodeId {
match self.node {
ViewItemExternCrate(_, _, id) => id,
ViewItemUse(ref vp) => match vp.node {
ViewPathSimple(_, _, id) => id,
ViewPathGlob(_, id) => id,
ViewPathList(_, _, id) => id,
}
}
}
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub enum ViewItem_ {
/// Ident: name used to refer to this crate in the code
/// optional (InternedString,StrStyle): if present, this is a location
/// (containing arbitrary characters) from which to fetch the crate sources
/// For example, extern crate whatever = "github.com/rust-lang/rust"
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
ViewItemUse(P<ViewPath>),
ViewPathList(Path, Vec<PathListItem>)
}
/// Meta-data associated with an item
@ -1668,6 +1633,12 @@ pub struct Item {
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
pub enum Item_ {
// Optional location (containing arbitrary characters) from which
// to fetch the crate sources.
// For example, extern crate whatever = "github.com/rust-lang/rust".
ItemExternCrate(Option<(InternedString, StrStyle)>),
ItemUse(P<ViewPath>),
ItemStatic(P<Ty>, Mutability, P<Expr>),
ItemConst(P<Ty>, P<Expr>),
ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
@ -1694,6 +1665,8 @@ pub enum Item_ {
impl Item_ {
pub fn descriptive_variant(&self) -> &str {
match *self {
ItemExternCrate(..) => "extern crate",
ItemUse(..) => "use",
ItemStatic(..) => "static item",
ItemConst(..) => "constant item",
ItemFn(..) => "function",

View file

@ -107,7 +107,6 @@ pub fn path_to_string<PI: Iterator<Item=PathElem>>(path: PI) -> String {
#[derive(Copy, Show)]
pub enum Node<'ast> {
NodeItem(&'ast Item),
NodeViewItem(&'ast ViewItem),
NodeForeignItem(&'ast ForeignItem),
NodeTraitItem(&'ast TraitItem),
NodeImplItem(&'ast ImplItem),
@ -134,7 +133,6 @@ enum MapEntry<'ast> {
/// All the node types, with a parent ID.
EntryItem(NodeId, &'ast Item),
EntryViewItem(NodeId, &'ast ViewItem),
EntryForeignItem(NodeId, &'ast ForeignItem),
EntryTraitItem(NodeId, &'ast TraitItem),
EntryImplItem(NodeId, &'ast ImplItem),
@ -169,7 +167,6 @@ impl<'ast> MapEntry<'ast> {
fn from_node(p: NodeId, node: Node<'ast>) -> MapEntry<'ast> {
match node {
NodeItem(n) => EntryItem(p, n),
NodeViewItem(n) => EntryViewItem(p, n),
NodeForeignItem(n) => EntryForeignItem(p, n),
NodeTraitItem(n) => EntryTraitItem(p, n),
NodeImplItem(n) => EntryImplItem(p, n),
@ -188,7 +185,6 @@ impl<'ast> MapEntry<'ast> {
fn parent(self) -> Option<NodeId> {
Some(match self {
EntryItem(id, _) => id,
EntryViewItem(id, _) => id,
EntryForeignItem(id, _) => id,
EntryTraitItem(id, _) => id,
EntryImplItem(id, _) => id,
@ -208,7 +204,6 @@ impl<'ast> MapEntry<'ast> {
fn to_node(self) -> Option<Node<'ast>> {
Some(match self {
EntryItem(_, n) => NodeItem(n),
EntryViewItem(_, n) => NodeViewItem(n),
EntryForeignItem(_, n) => NodeForeignItem(n),
EntryTraitItem(_, n) => NodeTraitItem(n),
EntryImplItem(_, n) => NodeImplItem(n),
@ -341,13 +336,6 @@ impl<'ast> Map<'ast> {
}
}
pub fn expect_view_item(&self, id: NodeId) -> &'ast ViewItem {
match self.find(id) {
Some(NodeViewItem(view_item)) => view_item,
_ => panic!("expected view item, found {}", self.node_to_string(id))
}
}
pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
match self.find(id) {
Some(NodeItem(i)) => {
@ -533,7 +521,6 @@ impl<'ast> Map<'ast> {
pub fn opt_span(&self, id: NodeId) -> Option<Span> {
let sp = match self.find(id) {
Some(NodeItem(item)) => item.span,
Some(NodeViewItem(item)) => item.span,
Some(NodeForeignItem(foreign_item)) => foreign_item.span,
Some(NodeTraitItem(trait_method)) => {
match *trait_method {
@ -826,11 +813,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
self.parent = parent;
}
fn visit_view_item(&mut self, item: &'ast ViewItem) {
self.insert(item.id(), NodeViewItem(item));
visit::walk_view_item(self, item);
}
fn visit_pat(&mut self, pat: &'ast Pat) {
self.insert(pat.id, match pat.node {
// Note: this is at least *potentially* a pattern...
@ -904,7 +886,6 @@ pub fn map_crate<'ast, F: FoldOps>(forest: &'ast mut Forest, fold_ops: F) -> Map
let krate = mem::replace(&mut forest.krate, Crate {
module: Mod {
inner: DUMMY_SP,
view_items: vec![],
items: vec![],
},
attrs: vec![],
@ -1036,7 +1017,6 @@ impl<'a> NodePrinter for pprust::State<'a> {
fn print_node(&mut self, node: &Node) -> IoResult<()> {
match *node {
NodeItem(a) => self.print_item(&*a),
NodeViewItem(a) => self.print_view_item(&*a),
NodeForeignItem(a) => self.print_foreign_item(&*a),
NodeTraitItem(a) => self.print_trait_method(&*a),
NodeImplItem(a) => self.print_impl_item(&*a),
@ -1065,6 +1045,8 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
Some(NodeItem(item)) => {
let path_str = map.path_to_str_with_ident(id, item.ident);
let item_str = match item.node {
ItemExternCrate(..) => "extern crate",
ItemUse(..) => "use",
ItemStatic(..) => "static",
ItemConst(..) => "const",
ItemFn(..) => "fn",
@ -1079,9 +1061,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
};
format!("{} {}{}", item_str, path_str, id_str)
}
Some(NodeViewItem(item)) => {
format!("view item {}{}", pprust::view_item_to_string(&*item), id_str)
}
Some(NodeForeignItem(item)) => {
let path_str = map.path_to_str_with_ident(id, item.ident);
format!("foreign item {}{}", path_str, id_str)

View file

@ -410,37 +410,6 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
visit::walk_mod(self, module)
}
fn visit_view_item(&mut self, view_item: &ViewItem) {
if !self.pass_through_items {
if self.visited_outermost {
return;
} else {
self.visited_outermost = true;
}
}
match view_item.node {
ViewItemExternCrate(_, _, node_id) => {
self.operation.visit_id(node_id)
}
ViewItemUse(ref view_path) => {
match view_path.node {
ViewPathSimple(_, _, node_id) |
ViewPathGlob(_, node_id) => {
self.operation.visit_id(node_id)
}
ViewPathList(_, ref paths, node_id) => {
self.operation.visit_id(node_id);
for path in paths.iter() {
self.operation.visit_id(path.node.id())
}
}
}
}
}
visit::walk_view_item(self, view_item);
self.visited_outermost = false;
}
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
self.operation.visit_id(foreign_item.id);
visit::walk_foreign_item(self, foreign_item)
@ -456,11 +425,25 @@ impl<'a, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
}
self.operation.visit_id(item.id);
if let ItemEnum(ref enum_definition, _) = item.node {
match item.node {
ItemUse(ref view_path) => {
match view_path.node {
ViewPathSimple(_, _) |
ViewPathGlob(_) => {}
ViewPathList(_, ref paths) => {
for path in paths.iter() {
self.operation.visit_id(path.node.id())
}
}
}
}
ItemEnum(ref enum_definition, _) => {
for variant in enum_definition.variants.iter() {
self.operation.visit_id(variant.node.id)
}
}
_ => {}
}
visit::walk_item(self, item);
@ -662,37 +645,6 @@ pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
walk_pat_(pat, &mut it)
}
pub trait EachViewItem {
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool;
}
struct EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
callback: F,
}
impl<'v, F> Visitor<'v> for EachViewItemData<F> where F: FnMut(&ast::ViewItem) -> bool {
fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
let _ = (self.callback)(view_item);
}
}
impl EachViewItem for ast::Crate {
fn each_view_item<F>(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool {
let mut visit = EachViewItemData {
callback: f,
};
visit::walk_crate(&mut visit, self);
true
}
}
pub fn view_path_id(p: &ViewPath) -> NodeId {
match p.node {
ViewPathSimple(_, _, id) | ViewPathGlob(_, id)
| ViewPathList(_, _, id) => id
}
}
/// Returns true if the given struct def is tuple-like; i.e. that its fields
/// are unnamed.
pub fn struct_def_is_tuple_like(struct_def: &ast::StructDef) -> bool {

View file

@ -63,28 +63,13 @@ pub fn strip_items<F>(krate: ast::Crate, in_cfg: F) -> ast::Crate where
ctxt.fold_crate(krate)
}
fn filter_view_item<F>(cx: &mut Context<F>,
view_item: ast::ViewItem)
-> Option<ast::ViewItem> where
F: FnMut(&[ast::Attribute]) -> bool
{
if view_item_in_cfg(cx, &view_item) {
Some(view_item)
} else {
None
}
}
fn fold_mod<F>(cx: &mut Context<F>,
ast::Mod {inner,
view_items, items}: ast::Mod) -> ast::Mod where
ast::Mod {inner, items}: ast::Mod)
-> ast::Mod where
F: FnMut(&[ast::Attribute]) -> bool
{
ast::Mod {
inner: inner,
view_items: view_items.into_iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect(),
items: items.into_iter().flat_map(|a| {
cx.fold_item(a).into_iter()
}).collect()
@ -104,15 +89,12 @@ fn filter_foreign_item<F>(cx: &mut Context<F>,
}
fn fold_foreign_mod<F>(cx: &mut Context<F>,
ast::ForeignMod {abi, view_items, items}: ast::ForeignMod)
ast::ForeignMod {abi, items}: ast::ForeignMod)
-> ast::ForeignMod where
F: FnMut(&[ast::Attribute]) -> bool
{
ast::ForeignMod {
abi: abi,
view_items: view_items.into_iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect(),
items: items.into_iter()
.filter_map(|a| filter_foreign_item(cx, a))
.collect()
@ -216,18 +198,14 @@ fn retain_stmt<F>(cx: &mut Context<F>, stmt: &ast::Stmt) -> bool where
fn fold_block<F>(cx: &mut Context<F>, b: P<ast::Block>) -> P<ast::Block> where
F: FnMut(&[ast::Attribute]) -> bool
{
b.map(|ast::Block {id, view_items, stmts, expr, rules, span}| {
b.map(|ast::Block {id, stmts, expr, rules, span}| {
let resulting_stmts: Vec<P<ast::Stmt>> =
stmts.into_iter().filter(|a| retain_stmt(cx, &**a)).collect();
let resulting_stmts = resulting_stmts.into_iter()
.flat_map(|stmt| cx.fold_stmt(stmt).into_iter())
.collect();
let filtered_view_items = view_items.into_iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect();
ast::Block {
id: id,
view_items: filtered_view_items,
stmts: resulting_stmts,
expr: expr.map(|x| cx.fold_expr(x)),
rules: rules,
@ -267,12 +245,6 @@ fn foreign_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ForeignItem) -> bool
return (cx.in_cfg)(item.attrs.as_slice());
}
fn view_item_in_cfg<F>(cx: &mut Context<F>, item: &ast::ViewItem) -> bool where
F: FnMut(&[ast::Attribute]) -> bool
{
return (cx.in_cfg)(item.attrs.as_slice());
}
fn trait_method_in_cfg<F>(cx: &mut Context<F>, meth: &ast::TraitItem) -> bool where
F: FnMut(&[ast::Attribute]) -> bool
{

View file

@ -97,7 +97,6 @@ pub trait AstBuilder {
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block>;
fn block_all(&self, span: Span,
view_items: Vec<ast::ViewItem>,
stmts: Vec<P<ast::Stmt>>,
expr: Option<P<ast::Expr>>) -> P<ast::Block>;
@ -242,7 +241,7 @@ pub trait AstBuilder {
fn item_mod(&self, span: Span, inner_span: Span,
name: Ident, attrs: Vec<ast::Attribute>,
vi: Vec<ast::ViewItem> , items: Vec<P<ast::Item>> ) -> P<ast::Item>;
items: Vec<P<ast::Item>>) -> P<ast::Item>;
fn item_static(&self,
span: Span,
@ -280,15 +279,15 @@ pub trait AstBuilder {
value: ast::Lit_)
-> P<ast::MetaItem>;
fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem;
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem;
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem;
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem;
fn view_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem;
fn item_use(&self, sp: Span,
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item>;
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item>;
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> P<ast::Item>;
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item>;
fn item_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item>;
}
impl<'a> AstBuilder for ExtCtxt<'a> {
@ -519,7 +518,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
fn block(&self, span: Span, stmts: Vec<P<ast::Stmt>>,
expr: Option<P<Expr>>) -> P<ast::Block> {
self.block_all(span, Vec::new(), stmts, expr)
self.block_all(span, stmts, expr)
}
fn stmt_item(&self, sp: Span, item: P<ast::Item>) -> P<ast::Stmt> {
@ -528,15 +527,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn block_expr(&self, expr: P<ast::Expr>) -> P<ast::Block> {
self.block_all(expr.span, Vec::new(), Vec::new(), Some(expr))
self.block_all(expr.span, Vec::new(), Some(expr))
}
fn block_all(&self,
span: Span,
view_items: Vec<ast::ViewItem>,
stmts: Vec<P<ast::Stmt>>,
expr: Option<P<ast::Expr>>) -> P<ast::Block> {
P(ast::Block {
view_items: view_items,
stmts: stmts,
expr: expr,
id: ast::DUMMY_NODE_ID,
@ -1031,16 +1028,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
}
fn item_mod(&self, span: Span, inner_span: Span, name: Ident,
attrs: Vec<ast::Attribute> ,
vi: Vec<ast::ViewItem> ,
items: Vec<P<ast::Item>> ) -> P<ast::Item> {
attrs: Vec<ast::Attribute>,
items: Vec<P<ast::Item>>) -> P<ast::Item> {
self.item(
span,
name,
attrs,
ast::ItemMod(ast::Mod {
inner: inner_span,
view_items: vi,
items: items,
})
)
@ -1101,47 +1096,47 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
P(respan(sp, ast::MetaNameValue(name, respan(sp, value))))
}
fn view_use(&self, sp: Span,
vis: ast::Visibility, vp: P<ast::ViewPath>) -> ast::ViewItem {
ast::ViewItem {
node: ast::ViewItemUse(vp),
attrs: Vec::new(),
fn item_use(&self, sp: Span,
vis: ast::Visibility, vp: P<ast::ViewPath>) -> P<ast::Item> {
P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: special_idents::invalid,
attrs: vec![],
node: ast::ItemUse(vp),
vis: vis,
span: sp
}
})
}
fn view_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> ast::ViewItem {
fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P<ast::Item> {
let last = path.segments.last().unwrap().identifier;
self.view_use_simple_(sp, vis, last, path)
self.item_use_simple_(sp, vis, last, path)
}
fn view_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> ast::ViewItem {
self.view_use(sp, vis,
fn item_use_simple_(&self, sp: Span, vis: ast::Visibility,
ident: ast::Ident, path: ast::Path) -> P<ast::Item> {
self.item_use(sp, vis,
P(respan(sp,
ast::ViewPathSimple(ident,
path,
ast::DUMMY_NODE_ID))))
path))))
}
fn view_use_list(&self, sp: Span, vis: ast::Visibility,
path: Vec<ast::Ident> , imports: &[ast::Ident]) -> ast::ViewItem {
fn item_use_list(&self, sp: Span, vis: ast::Visibility,
path: Vec<ast::Ident>, imports: &[ast::Ident]) -> P<ast::Item> {
let imports = imports.iter().map(|id| {
respan(sp, ast::PathListIdent { name: *id, id: ast::DUMMY_NODE_ID })
}).collect();
self.view_use(sp, vis,
self.item_use(sp, vis,
P(respan(sp,
ast::ViewPathList(self.path(sp, path),
imports,
ast::DUMMY_NODE_ID))))
imports))))
}
fn view_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident> ) -> ast::ViewItem {
self.view_use(sp, vis,
fn item_use_glob(&self, sp: Span,
vis: ast::Visibility, path: Vec<ast::Ident>) -> P<ast::Item> {
self.item_use(sp, vis,
P(respan(sp,
ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID))))
ast::ViewPathGlob(self.path(sp, path)))))
}
}

View file

@ -1073,7 +1073,7 @@ impl<'a> MethodDef<'a> {
// <delegated expression referring to __self0_vi, et al.>
// }
let arm_expr = cx.expr_block(
cx.block_all(sp, Vec::new(), index_let_stmts, Some(arm_expr)));
cx.block_all(sp, index_let_stmts, Some(arm_expr)));
// Builds arm:
// _ => { let __self0_vi = ...;

View file

@ -206,7 +206,6 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
// wrap the if-let expr in a block
let span = els.span;
let blk = P(ast::Block {
view_items: vec![],
stmts: vec![],
expr: Some(P(els)),
id: ast::DUMMY_NODE_ID,
@ -799,8 +798,7 @@ pub fn expand_block(blk: P<Block>, fld: &mut MacroExpander) -> P<Block> {
// expand the elements of a block.
pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
b.map(|Block {id, view_items, stmts, expr, rules, span}| {
let new_view_items = view_items.into_iter().map(|x| fld.fold_view_item(x)).collect();
b.map(|Block {id, stmts, expr, rules, span}| {
let new_stmts = stmts.into_iter().flat_map(|x| {
// perform all pending renames
let renamed_stmt = {
@ -821,7 +819,6 @@ pub fn expand_block_elts(b: P<Block>, fld: &mut MacroExpander) -> P<Block> {
});
Block {
id: fld.new_id(id),
view_items: new_view_items,
stmts: new_stmts,
expr: new_expr,
rules: rules,

View file

@ -352,18 +352,11 @@ pub mod rt {
impl<'a> ExtParseUtils for ExtCtxt<'a> {
fn parse_item(&self, s: String) -> P<ast::Item> {
let res = parse::parse_item_from_source_str(
parse::parse_item_from_source_str(
"<quote expansion>".to_string(),
s,
self.cfg(),
self.parse_sess());
match res {
Some(ast) => ast,
None => {
error!("parse error");
panic!()
}
}
self.parse_sess()).expect("parse error")
}
fn parse_stmt(&self, s: String) -> P<ast::Stmt> {
@ -767,7 +760,6 @@ fn expand_tts(cx: &ExtCtxt, sp: Span, tts: &[ast::TokenTree])
vector.extend(mk_tts(cx, &tts[]).into_iter());
let block = cx.expr_block(
cx.block_all(sp,
Vec::new(),
vector,
Some(cx.expr_ident(sp, id_ext("tt")))));
@ -778,18 +770,18 @@ fn expand_wrapper(cx: &ExtCtxt,
sp: Span,
cx_expr: P<ast::Expr>,
expr: P<ast::Expr>) -> P<ast::Expr> {
let uses = [
&["syntax", "ext", "quote", "rt"],
].iter().map(|path| {
let path = path.iter().map(|s| s.to_string()).collect();
cx.view_use_glob(sp, ast::Inherited, ids_ext(path))
}).collect();
// Explicitly borrow to avoid moving from the invoker (#16992)
let cx_expr_borrow = cx.expr_addr_of(sp, cx.expr_deref(sp, cx_expr));
let stmt_let_ext_cx = cx.stmt_let(sp, false, id_ext("ext_cx"), cx_expr_borrow);
cx.expr_block(cx.block_all(sp, uses, vec!(stmt_let_ext_cx), Some(expr)))
let stmts = [
&["syntax", "ext", "quote", "rt"],
].iter().map(|path| {
let path = path.iter().map(|s| s.to_string()).collect();
cx.stmt_item(sp, cx.item_use_glob(sp, ast::Inherited, ids_ext(path)))
}).chain(Some(stmt_let_ext_cx).into_iter()).collect();
cx.expr_block(cx.block_all(sp, stmts, Some(expr)))
}
fn expand_parse_call(cx: &ExtCtxt,

View file

@ -64,7 +64,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
("rustc_diagnostic_macros", Active),
("unboxed_closures", Active),
("import_shadowing", Active),
("import_shadowing", Removed),
("advanced_slice_patterns", Active),
("tuple_indexing", Accepted),
("associated_types", Accepted),
@ -127,7 +127,6 @@ enum Status {
pub struct Features {
pub unboxed_closures: bool,
pub rustc_diagnostic_macros: bool,
pub import_shadowing: bool,
pub visible_private_types: bool,
pub quote: bool,
pub old_orphan_check: bool,
@ -139,7 +138,6 @@ impl Features {
Features {
unboxed_closures: false,
rustc_diagnostic_macros: false,
import_shadowing: false,
visible_private_types: false,
quote: false,
old_orphan_check: false,
@ -228,22 +226,6 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
}
fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.node {
ast::ViewItemUse(..) => {}
ast::ViewItemExternCrate(..) => {
for attr in i.attrs.iter() {
if attr.check_name("plugin") {
self.gate_feature("plugin", attr.span,
"compiler plugins are experimental \
and possibly buggy");
}
}
}
}
visit::walk_view_item(self, i)
}
fn visit_item(&mut self, i: &ast::Item) {
for attr in i.attrs.iter() {
if attr.name() == "thread_local" {
@ -262,6 +244,14 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
}
}
match i.node {
ast::ItemExternCrate(_) => {
if attr::contains_name(&i.attrs[], "plugin") {
self.gate_feature("plugin", i.span,
"compiler plugins are experimental \
and possibly buggy");
}
}
ast::ItemForeignMod(ref foreign_module) => {
if attr::contains_name(&i.attrs[], "link_args") {
self.gate_feature("link_args", i.span,
@ -537,7 +527,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
(Features {
unboxed_closures: cx.has_feature("unboxed_closures"),
rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
import_shadowing: cx.has_feature("import_shadowing"),
visible_private_types: cx.has_feature("visible_private_types"),
quote: cx.has_feature("quote"),
old_orphan_check: cx.has_feature("old_orphan_check"),

View file

@ -78,10 +78,6 @@ pub trait Folder : Sized {
noop_fold_view_path(view_path, self)
}
fn fold_view_item(&mut self, vi: ViewItem) -> ViewItem {
noop_fold_view_item(vi, self)
}
fn fold_foreign_item(&mut self, ni: P<ForeignItem>) -> P<ForeignItem> {
noop_fold_foreign_item(ni, self)
}
@ -349,16 +345,13 @@ pub fn noop_fold_meta_items<T: Folder>(meta_items: Vec<P<MetaItem>>, fld: &mut T
pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<ViewPath> {
view_path.map(|Spanned {node, span}| Spanned {
node: match node {
ViewPathSimple(ident, path, node_id) => {
let id = fld.new_id(node_id);
ViewPathSimple(ident, fld.fold_path(path), id)
ViewPathSimple(ident, path) => {
ViewPathSimple(ident, fld.fold_path(path))
}
ViewPathGlob(path, node_id) => {
let id = fld.new_id(node_id);
ViewPathGlob(fld.fold_path(path), id)
ViewPathGlob(path) => {
ViewPathGlob(fld.fold_path(path))
}
ViewPathList(path, path_list_idents, node_id) => {
let id = fld.new_id(node_id);
ViewPathList(path, path_list_idents) => {
ViewPathList(fld.fold_path(path),
path_list_idents.move_map(|path_list_ident| {
Spanned {
@ -373,8 +366,7 @@ pub fn noop_fold_view_path<T: Folder>(view_path: P<ViewPath>, fld: &mut T) -> P<
},
span: fld.new_span(path_list_ident.span)
}
}),
id)
}))
}
},
span: fld.new_span(span)
@ -470,11 +462,10 @@ pub fn noop_fold_qpath<T: Folder>(qpath: P<QPath>, fld: &mut T) -> P<QPath> {
})
}
pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, view_items, items}: ForeignMod,
pub fn noop_fold_foreign_mod<T: Folder>(ForeignMod {abi, items}: ForeignMod,
fld: &mut T) -> ForeignMod {
ForeignMod {
abi: abi,
view_items: view_items.move_map(|x| fld.fold_view_item(x)),
items: items.move_map(|x| fld.fold_foreign_item(x)),
}
}
@ -953,28 +944,9 @@ fn noop_fold_variant_arg<T: Folder>(VariantArg {id, ty}: VariantArg, folder: &mu
}
}
pub fn noop_fold_view_item<T: Folder>(ViewItem {node, attrs, vis, span}: ViewItem,
folder: &mut T) -> ViewItem {
ViewItem {
node: match node {
ViewItemExternCrate(ident, string, node_id) => {
ViewItemExternCrate(ident, string,
folder.new_id(node_id))
}
ViewItemUse(view_path) => {
ViewItemUse(folder.fold_view_path(view_path))
}
},
attrs: attrs.move_map(|a| folder.fold_attribute(a)),
vis: vis,
span: folder.new_span(span)
}
}
pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
b.map(|Block {id, view_items, stmts, expr, rules, span}| Block {
b.map(|Block {id, stmts, expr, rules, span}| Block {
id: folder.new_id(id),
view_items: view_items.move_map(|x| folder.fold_view_item(x)),
stmts: stmts.into_iter().flat_map(|s| folder.fold_stmt(s).into_iter()).collect(),
expr: expr.map(|x| folder.fold_expr(x)),
rules: rules,
@ -984,6 +956,10 @@ pub fn noop_fold_block<T: Folder>(b: P<Block>, folder: &mut T) -> P<Block> {
pub fn noop_fold_item_underscore<T: Folder>(i: Item_, folder: &mut T) -> Item_ {
match i {
ItemExternCrate(string) => ItemExternCrate(string),
ItemUse(view_path) => {
ItemUse(folder.fold_view_path(view_path))
}
ItemStatic(t, m, e) => {
ItemStatic(folder.fold_ty(t), m, folder.fold_expr(e))
}
@ -1103,10 +1079,9 @@ pub fn noop_fold_type_method<T: Folder>(m: TypeMethod, fld: &mut T) -> TypeMetho
}
}
pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mut T) -> Mod {
pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod {
Mod {
inner: folder.new_span(inner),
view_items: view_items.move_map(|x| folder.fold_view_item(x)),
items: items.into_iter().flat_map(|x| folder.fold_item(x).into_iter()).collect(),
}
}
@ -1137,9 +1112,8 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac
}
None => (ast::Mod {
inner: span,
view_items: Vec::new(),
items: Vec::new(),
}, Vec::new(), span)
items: vec![],
}, vec![], span)
};
for def in exported_macros.iter_mut() {

View file

@ -757,11 +757,10 @@ mod test {
use attr::{first_attr_value_str_by_name, AttrMetaMethods};
use parse::parser::Parser;
use parse::token::{str_to_ident};
use print::pprust::view_item_to_string;
use print::pprust::item_to_string;
use ptr::P;
use util::parser_testing::{string_to_tts, string_to_parser};
use util::parser_testing::{string_to_expr, string_to_item};
use util::parser_testing::{string_to_stmt, string_to_view_item};
use util::parser_testing::{string_to_expr, string_to_item, string_to_stmt};
// produce a codemap::span
fn sp(a: u32, b: u32) -> Span {
@ -1079,7 +1078,6 @@ mod test {
}
},
P(ast::Block {
view_items: Vec::new(),
stmts: vec!(P(Spanned{
node: ast::StmtSemi(P(ast::Expr{
id: ast::DUMMY_NODE_ID,
@ -1111,25 +1109,25 @@ mod test {
#[test] fn parse_use() {
let use_s = "use foo::bar::baz;";
let vitem = string_to_view_item(use_s.to_string());
let vitem_s = view_item_to_string(&vitem);
let vitem = string_to_item(use_s.to_string()).unwrap();
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[], use_s);
let use_s = "use foo::bar as baz;";
let vitem = string_to_view_item(use_s.to_string());
let vitem_s = view_item_to_string(&vitem);
let vitem = string_to_item(use_s.to_string()).unwrap();
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[], use_s);
}
#[test] fn parse_extern_crate() {
let ex_s = "extern crate foo;";
let vitem = string_to_view_item(ex_s.to_string());
let vitem_s = view_item_to_string(&vitem);
let vitem = string_to_item(ex_s.to_string()).unwrap();
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[], ex_s);
let ex_s = "extern crate \"foo\" as bar;";
let vitem = string_to_view_item(ex_s.to_string());
let vitem_s = view_item_to_string(&vitem);
let vitem = string_to_item(ex_s.to_string()).unwrap();
let vitem_s = item_to_string(&*vitem);
assert_eq!(&vitem_s[], ex_s);
}

View file

@ -9,7 +9,6 @@
// except according to those terms.
pub use self::PathParsingMode::*;
use self::ItemOrViewItem::*;
use abi;
use ast::{AssociatedType, BareFnTy};
@ -35,6 +34,7 @@ use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, ForeignMod, FunctionRet
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
use ast::{ItemExternCrate, ItemUse};
use ast::{LifetimeDef, Lit, Lit_};
use ast::{LitBool, LitChar, LitByte, LitBinary};
use ast::{LitStr, LitInt, Local, LocalLet};
@ -59,7 +59,6 @@ use ast::{TyParam, TyParamBound, TyParen, TyPath, TyPolyTraitRef, TyPtr, TyQPath
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
use ast::{UnnamedField, UnsafeBlock};
use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
use ast::{Visibility, WhereClause};
use ast;
@ -122,14 +121,9 @@ pub enum BoundParsingMode {
Modified,
}
enum ItemOrViewItem {
/// Indicates a failure to parse any kind of item. The attributes are
/// returned.
IoviNone(Vec<Attribute>),
IoviItem(P<Item>),
IoviForeignItem(P<ForeignItem>),
IoviViewItem(ViewItem)
}
/// The `Err` case indicates a failure to parse any kind of item.
/// The attributes are returned.
type MaybeItem = Result<P<Item>, Vec<Attribute>>;
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
@ -231,19 +225,6 @@ macro_rules! maybe_whole {
}
}
);
(iovi $p:expr, $constructor:ident) => (
{
let found = match ($p).token {
token::Interpolated(token::$constructor(_)) => {
Some(($p).bump_and_get())
}
_ => None
};
if let Some(token::Interpolated(token::$constructor(x))) = found {
return IoviItem(x.clone());
}
}
);
(pair_empty $p:expr, $constructor:ident) => (
{
let found = match ($p).token {
@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
lhs
}
struct ParsedItemsAndViewItems {
attrs_remaining: Vec<Attribute>,
view_items: Vec<ViewItem>,
items: Vec<P<Item>> ,
foreign_items: Vec<P<ForeignItem>>
}
/* ident is handled by common.rs */
pub struct Parser<'a> {
@ -3032,8 +3005,7 @@ impl<'a> Parser<'a> {
let body = self.parse_expr();
let fakeblock = P(ast::Block {
id: ast::DUMMY_NODE_ID,
view_items: Vec::new(),
stmts: Vec::new(),
stmts: vec![],
span: body.span,
expr: Some(body),
rules: DefaultBlock,
@ -3731,20 +3703,13 @@ impl<'a> Parser<'a> {
} else {
let found_attrs = !item_attrs.is_empty();
let item_err = Parser::expected_item_err(&item_attrs[]);
match self.parse_item_or_view_item(item_attrs, false) {
IoviItem(i) => {
match self.parse_item_(item_attrs, false) {
Ok(i) => {
let hi = i.span.hi;
let decl = P(spanned(lo, hi, DeclItem(i)));
P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
}
IoviViewItem(vi) => {
self.span_fatal(vi.span,
"view items must be declared at the top of the block");
}
IoviForeignItem(_) => {
self.fatal("foreign items are not allowed here");
}
IoviNone(_) => {
Err(_) => {
if found_attrs {
let last_span = self.last_span;
self.span_err(last_span, item_err);
@ -3794,36 +3759,17 @@ impl<'a> Parser<'a> {
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
}
/// Precondition: already parsed the '{' or '#{'
/// I guess that also means "already parsed the 'impure'" if
/// necessary, and this should take a qualifier.
/// Some blocks start with "#{"...
/// Precondition: already parsed the '{'.
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
self.parse_block_tail_(lo, s, Vec::new())
}
/// Parse the rest of a block expression or function body
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
first_item_attrs: Vec<Attribute> ) -> P<Block> {
let mut stmts = Vec::new();
first_item_attrs: Vec<Attribute>) -> P<Block> {
let mut stmts = vec![];
let mut expr = None;
// wouldn't it be more uniform to parse view items only, here?
let ParsedItemsAndViewItems {
attrs_remaining,
view_items,
items,
..
} = self.parse_items_and_view_items(first_item_attrs,
false, false);
for item in items.into_iter() {
let span = item.span;
let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
}
let mut attributes_box = attrs_remaining;
let mut attributes_box = first_item_attrs;
while self.token != token::CloseDelim(token::Brace) {
// parsing items even when they're not allowed lets us give
@ -3932,7 +3878,6 @@ impl<'a> Parser<'a> {
let hi = self.span.hi;
self.bump();
P(ast::Block {
view_items: view_items,
stmts: stmts,
expr: expr,
id: ast::DUMMY_NODE_ID,
@ -5031,39 +4976,34 @@ impl<'a> Parser<'a> {
first_item_attrs: Vec<Attribute>,
inner_lo: BytePos)
-> Mod {
// parse all of the items up to closing or an attribute.
// view items are legal here.
let ParsedItemsAndViewItems {
attrs_remaining,
view_items,
items: starting_items,
..
} = self.parse_items_and_view_items(first_item_attrs, true, true);
let mut items: Vec<P<Item>> = starting_items;
let attrs_remaining_len = attrs_remaining.len();
// Parse all of the items up to closing or an attribute.
let mut attrs = first_item_attrs;
attrs.push_all(&self.parse_outer_attributes()[]);
let mut items = vec![];
loop {
match self.parse_item_(attrs, true) {
Err(returned_attrs) => {
attrs = returned_attrs;
break
}
Ok(item) => {
attrs = self.parse_outer_attributes();
items.push(item)
}
}
}
// don't think this other loop is even necessary....
let mut first = true;
while self.token != term {
let mut attrs = self.parse_outer_attributes();
if first {
let mut tmp = attrs_remaining.clone();
tmp.push_all(&attrs[]);
attrs = tmp;
first = false;
}
debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
attrs);
match self.parse_item_or_view_item(attrs,
true /* macros allowed */) {
IoviItem(item) => items.push(item),
IoviViewItem(view_item) => {
self.span_fatal(view_item.span,
"view items must be declared at the top of \
the module");
}
_ => {
let mut attrs = mem::replace(&mut attrs, vec![]);
attrs.push_all(&self.parse_outer_attributes()[]);
debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
match self.parse_item_(attrs, true /* macros allowed */) {
Ok(item) => items.push(item),
Err(_) => {
let token_str = self.this_token_to_string();
self.fatal(&format!("expected item, found `{}`",
token_str)[])
@ -5071,16 +5011,15 @@ impl<'a> Parser<'a> {
}
}
if first && attrs_remaining_len > 0us {
if !attrs.is_empty() {
// We parsed attributes for the first item but didn't find it
let last_span = self.last_span;
self.span_err(last_span,
Parser::expected_item_err(&attrs_remaining[]));
Parser::expected_item_err(&attrs[]));
}
ast::Mod {
inner: mk_sp(inner_lo, self.span.lo),
view_items: view_items,
items: items
}
}
@ -5298,23 +5237,12 @@ impl<'a> Parser<'a> {
/// parse_foreign_items.
fn parse_foreign_mod_items(&mut self,
abi: abi::Abi,
first_item_attrs: Vec<Attribute> )
first_item_attrs: Vec<Attribute>)
-> ForeignMod {
let ParsedItemsAndViewItems {
attrs_remaining,
view_items,
items: _,
foreign_items,
} = self.parse_foreign_items(first_item_attrs, true);
if !attrs_remaining.is_empty() {
let last_span = self.last_span;
self.span_err(last_span,
Parser::expected_item_err(&attrs_remaining[]));
}
let foreign_items = self.parse_foreign_items(first_item_attrs);
assert!(self.token == token::CloseDelim(token::Brace));
ast::ForeignMod {
abi: abi,
view_items: view_items,
items: foreign_items
}
}
@ -5329,8 +5257,8 @@ impl<'a> Parser<'a> {
fn parse_item_extern_crate(&mut self,
lo: BytePos,
visibility: Visibility,
attrs: Vec<Attribute> )
-> ItemOrViewItem {
attrs: Vec<Attribute>)
-> P<Item> {
let span = self.span;
let (maybe_path, ident) = match self.token {
@ -5374,12 +5302,13 @@ impl<'a> Parser<'a> {
}
};
IoviViewItem(ast::ViewItem {
node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
attrs: attrs,
vis: visibility,
span: mk_sp(lo, self.last_span.hi)
})
let last_span = self.last_span;
self.mk_item(lo,
last_span.hi,
ident,
ItemExternCrate(maybe_path),
visibility,
attrs)
}
/// Parse `extern` for foreign ABIs
@ -5396,8 +5325,8 @@ impl<'a> Parser<'a> {
lo: BytePos,
opt_abi: Option<abi::Abi>,
visibility: Visibility,
attrs: Vec<Attribute> )
-> ItemOrViewItem {
attrs: Vec<Attribute>)
-> P<Item> {
self.expect(&token::OpenDelim(token::Brace));
@ -5408,13 +5337,12 @@ impl<'a> Parser<'a> {
self.expect(&token::CloseDelim(token::Brace));
let last_span = self.last_span;
let item = self.mk_item(lo,
self.mk_item(lo,
last_span.hi,
special_idents::invalid,
ItemForeignMod(m),
visibility,
maybe_append(attrs, Some(inner)));
return IoviItem(item);
maybe_append(attrs, Some(inner)))
}
/// Parse type Foo = Bar;
@ -5556,14 +5484,12 @@ impl<'a> Parser<'a> {
}
}
/// Parse one of the items or view items allowed by the
/// flags; on failure, return IoviNone.
/// Parse one of the items allowed by the flags; on failure,
/// return `Err(remaining_attrs)`.
/// NB: this function no longer parses the items inside an
/// extern crate.
fn parse_item_or_view_item(&mut self,
attrs: Vec<Attribute> ,
macros_allowed: bool)
-> ItemOrViewItem {
fn parse_item_(&mut self, attrs: Vec<Attribute>,
macros_allowed: bool) -> MaybeItem {
let nt_item = match self.token {
token::Interpolated(token::NtItem(ref item)) => {
Some((**item).clone())
@ -5576,7 +5502,7 @@ impl<'a> Parser<'a> {
let mut attrs = attrs;
mem::swap(&mut item.attrs, &mut attrs);
item.attrs.extend(attrs.into_iter());
return IoviItem(P(item));
return Ok(P(item));
}
None => {}
}
@ -5585,22 +5511,24 @@ impl<'a> Parser<'a> {
let visibility = self.parse_visibility();
// must be a view item:
if self.eat_keyword(keywords::Use) {
// USE ITEM (IoviViewItem)
let view_item = self.parse_use();
// USE ITEM
let item_ = ItemUse(self.parse_view_path());
self.expect(&token::Semi);
return IoviViewItem(ast::ViewItem {
node: view_item,
attrs: attrs,
vis: visibility,
span: mk_sp(lo, self.last_span.hi)
});
let last_span = self.last_span;
let item = self.mk_item(lo,
last_span.hi,
token::special_idents::invalid,
item_,
visibility,
attrs);
return Ok(item);
}
// either a view item or an item:
if self.eat_keyword(keywords::Extern) {
if self.eat_keyword(keywords::Crate) {
return self.parse_item_extern_crate(lo, visibility, attrs);
return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
}
let opt_abi = self.parse_opt_abi();
@ -5617,9 +5545,9 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
} else if self.check(&token::OpenDelim(token::Brace)) {
return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
}
let span = self.span;
@ -5634,7 +5562,6 @@ impl<'a> Parser<'a> {
self.span_err(span, "`virtual` structs have been removed from the language");
}
// the rest are all guaranteed to be items:
if self.token.is_keyword(keywords::Static) {
// STATIC ITEM
self.bump();
@ -5647,7 +5574,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.token.is_keyword(keywords::Const) {
// CONST ITEM
@ -5665,7 +5592,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.token.is_keyword(keywords::Unsafe) &&
self.look_ahead(1us, |t| t.is_keyword(keywords::Trait))
@ -5682,7 +5609,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.token.is_keyword(keywords::Unsafe) &&
self.look_ahead(1us, |t| t.is_keyword(keywords::Impl))
@ -5698,7 +5625,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.token.is_keyword(keywords::Fn) {
// FUNCTION ITEM
@ -5712,7 +5639,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.token.is_keyword(keywords::Unsafe)
&& self.look_ahead(1us, |t| *t != token::OpenDelim(token::Brace)) {
@ -5733,7 +5660,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Mod) {
// MODULE ITEM
@ -5746,7 +5673,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Type) {
// TYPE ITEM
@ -5758,7 +5685,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Enum) {
// ENUM ITEM
@ -5770,7 +5697,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Trait) {
// TRAIT ITEM
@ -5783,7 +5710,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Impl) {
// IMPL ITEM
@ -5795,7 +5722,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
if self.eat_keyword(keywords::Struct) {
// STRUCT ITEM
@ -5807,32 +5734,30 @@ impl<'a> Parser<'a> {
item_,
visibility,
maybe_append(attrs, extra_attrs));
return IoviItem(item);
return Ok(item);
}
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
}
/// Parse a foreign item; on failure, return IoviNone.
fn parse_foreign_item(&mut self,
attrs: Vec<Attribute> ,
macros_allowed: bool)
-> ItemOrViewItem {
maybe_whole!(iovi self, NtItem);
/// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
-> Result<P<ForeignItem>, Vec<Attribute>> {
let lo = self.span.lo;
let visibility = self.parse_visibility();
if self.token.is_keyword(keywords::Static) {
// FOREIGN STATIC ITEM
let item = self.parse_item_foreign_static(visibility, attrs);
return IoviForeignItem(item);
return Ok(self.parse_item_foreign_static(visibility, attrs));
}
if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
// FOREIGN FUNCTION ITEM
let item = self.parse_item_foreign_fn(visibility, attrs);
return IoviForeignItem(item);
return Ok(self.parse_item_foreign_fn(visibility, attrs));
}
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
// FIXME #5668: this will occur for a macro invocation:
let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
self.span_fatal(item.span, "macros cannot expand to foreign items");
}
/// This is the fall-through for parsing items.
@ -5842,7 +5767,7 @@ impl<'a> Parser<'a> {
macros_allowed: bool,
lo: BytePos,
visibility: Visibility
) -> ItemOrViewItem {
) -> MaybeItem {
if macros_allowed && !self.token.is_any_keyword()
&& self.look_ahead(1, |t| *t == token::Not)
&& (self.look_ahead(2, |t| t.is_plain_ident())
@ -5891,7 +5816,7 @@ impl<'a> Parser<'a> {
item_,
visibility,
attrs);
return IoviItem(item);
return Ok(item);
}
// FAILURE TO PARSE ITEM
@ -5902,7 +5827,7 @@ impl<'a> Parser<'a> {
self.span_fatal(last_span, "unmatched visibility `pub`");
}
}
return IoviNone(attrs);
Err(attrs)
}
pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
@ -5911,29 +5836,8 @@ impl<'a> Parser<'a> {
}
pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
match self.parse_item_or_view_item(attrs, true) {
IoviNone(_) => None,
IoviViewItem(_) =>
self.fatal("view items are not allowed here"),
IoviForeignItem(_) =>
self.fatal("foreign items are not allowed here"),
IoviItem(item) => Some(item)
self.parse_item_(attrs, true).ok()
}
}
/// Parse a ViewItem, e.g. `use foo::bar` or `extern crate foo`
pub fn parse_view_item(&mut self, attrs: Vec<Attribute>) -> ViewItem {
match self.parse_item_or_view_item(attrs, false) {
IoviViewItem(vi) => vi,
_ => self.fatal("expected `use` or `extern crate`"),
}
}
/// Parse, e.g., "use a::b::{z,y}"
fn parse_use(&mut self) -> ViewItem_ {
return ViewItemUse(self.parse_view_path());
}
/// Matches view_path : MOD? non_global_path as IDENT
/// | MOD? non_global_path MOD_SEP LBRACE RBRACE
@ -5959,8 +5863,7 @@ impl<'a> Parser<'a> {
global: false,
segments: Vec::new()
};
return P(spanned(lo, self.span.hi,
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
}
let first_ident = self.parse_ident();
@ -5994,8 +5897,7 @@ impl<'a> Parser<'a> {
}
}).collect()
};
return P(spanned(lo, self.span.hi,
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
}
// foo::bar::*
@ -6011,8 +5913,7 @@ impl<'a> Parser<'a> {
}
}).collect()
};
return P(spanned(lo, self.span.hi,
ViewPathGlob(path, ast::DUMMY_NODE_ID)));
return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
}
_ => break
@ -6033,136 +5934,39 @@ impl<'a> Parser<'a> {
if self.eat_keyword(keywords::As) {
rename_to = self.parse_ident()
}
P(spanned(lo,
self.last_span.hi,
ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
}
/// Parses a sequence of items. Stops when it finds program
/// text that can't be parsed as an item
/// - mod_items uses extern_mod_allowed = true
/// - block_tail_ uses extern_mod_allowed = false
fn parse_items_and_view_items(&mut self,
first_item_attrs: Vec<Attribute> ,
mut extern_mod_allowed: bool,
macros_allowed: bool)
-> ParsedItemsAndViewItems {
let mut attrs = first_item_attrs;
attrs.push_all(&self.parse_outer_attributes()[]);
// First, parse view items.
let mut view_items : Vec<ast::ViewItem> = Vec::new();
let mut items = Vec::new();
// I think this code would probably read better as a single
// loop with a mutable three-state-variable (for extern crates,
// view items, and regular items) ... except that because
// of macros, I'd like to delay that entire check until later.
loop {
match self.parse_item_or_view_item(attrs, macros_allowed) {
IoviNone(attrs) => {
return ParsedItemsAndViewItems {
attrs_remaining: attrs,
view_items: view_items,
items: items,
foreign_items: Vec::new()
}
}
IoviViewItem(view_item) => {
match view_item.node {
ViewItemUse(..) => {
// `extern crate` must precede `use`.
extern_mod_allowed = false;
}
ViewItemExternCrate(..) if !extern_mod_allowed => {
self.span_err(view_item.span,
"\"extern crate\" declarations are \
not allowed here");
}
ViewItemExternCrate(..) => {}
}
view_items.push(view_item);
}
IoviItem(item) => {
items.push(item);
attrs = self.parse_outer_attributes();
break;
}
IoviForeignItem(_) => {
panic!();
}
}
attrs = self.parse_outer_attributes();
}
// Next, parse items.
loop {
match self.parse_item_or_view_item(attrs, macros_allowed) {
IoviNone(returned_attrs) => {
attrs = returned_attrs;
break
}
IoviViewItem(view_item) => {
attrs = self.parse_outer_attributes();
self.span_err(view_item.span,
"`use` and `extern crate` declarations must precede items");
}
IoviItem(item) => {
attrs = self.parse_outer_attributes();
items.push(item)
}
IoviForeignItem(_) => {
panic!();
}
}
}
ParsedItemsAndViewItems {
attrs_remaining: attrs,
view_items: view_items,
items: items,
foreign_items: Vec::new()
}
P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
}
/// Parses a sequence of foreign items. Stops when it finds program
/// text that can't be parsed as an item
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
macros_allowed: bool)
-> ParsedItemsAndViewItems {
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
-> Vec<P<ForeignItem>> {
let mut attrs = first_item_attrs;
attrs.push_all(&self.parse_outer_attributes()[]);
let mut foreign_items = Vec::new();
loop {
match self.parse_foreign_item(attrs, macros_allowed) {
IoviNone(returned_attrs) => {
match self.parse_foreign_item(attrs) {
Ok(foreign_item) => {
foreign_items.push(foreign_item);
}
Err(returned_attrs) => {
if self.check(&token::CloseDelim(token::Brace)) {
attrs = returned_attrs;
break
}
self.unexpected();
},
IoviViewItem(view_item) => {
// I think this can't occur:
self.span_err(view_item.span,
"`use` and `extern crate` declarations must precede items");
}
IoviItem(item) => {
// FIXME #5668: this will occur for a macro invocation:
self.span_fatal(item.span, "macros cannot expand to foreign items");
}
IoviForeignItem(foreign_item) => {
foreign_items.push(foreign_item);
}
}
attrs = self.parse_outer_attributes();
}
ParsedItemsAndViewItems {
attrs_remaining: attrs,
view_items: Vec::new(),
items: Vec::new(),
foreign_items: foreign_items
if !attrs.is_empty() {
let last_span = self.last_span;
self.span_err(last_span,
Parser::expected_item_err(&attrs[]));
}
foreign_items
}
/// Parses a source module as a crate. This is the main

View file

@ -337,10 +337,6 @@ pub fn item_to_string(i: &ast::Item) -> String {
$to_string(|s| s.print_item(i))
}
pub fn view_item_to_string(i: &ast::ViewItem) -> String {
$to_string(|s| s.print_view_item(i))
}
pub fn generics_to_string(generics: &ast::Generics) -> String {
$to_string(|s| s.print_generics(generics))
}
@ -638,9 +634,6 @@ impl<'a> State<'a> {
pub fn print_mod(&mut self, _mod: &ast::Mod,
attrs: &[ast::Attribute]) -> IoResult<()> {
try!(self.print_inner_attributes(attrs));
for vitem in _mod.view_items.iter() {
try!(self.print_view_item(vitem));
}
for item in _mod.items.iter() {
try!(self.print_item(&**item));
}
@ -650,9 +643,6 @@ impl<'a> State<'a> {
pub fn print_foreign_mod(&mut self, nmod: &ast::ForeignMod,
attrs: &[ast::Attribute]) -> IoResult<()> {
try!(self.print_inner_attributes(attrs));
for vitem in nmod.view_items.iter() {
try!(self.print_view_item(vitem));
}
for item in nmod.items.iter() {
try!(self.print_foreign_item(&**item));
}
@ -809,6 +799,28 @@ impl<'a> State<'a> {
try!(self.print_outer_attributes(&item.attrs[]));
try!(self.ann.pre(self, NodeItem(item)));
match item.node {
ast::ItemExternCrate(ref optional_path) => {
try!(self.head(&visibility_qualified(item.vis,
"extern crate")[]));
for &(ref p, style) in optional_path.iter() {
try!(self.print_string(p.get(), style));
try!(space(&mut self.s));
try!(word(&mut self.s, "as"));
try!(space(&mut self.s));
}
try!(self.print_ident(item.ident));
try!(word(&mut self.s, ";"));
try!(self.end()); // end inner head-block
try!(self.end()); // end outer head-block
}
ast::ItemUse(ref vp) => {
try!(self.head(&visibility_qualified(item.vis,
"use")[]));
try!(self.print_view_path(&**vp));
try!(word(&mut self.s, ";"));
try!(self.end()); // end inner head-block
try!(self.end()); // end outer head-block
}
ast::ItemStatic(ref ty, m, ref expr) => {
try!(self.head(&visibility_qualified(item.vis,
"static")[]));
@ -1380,9 +1392,6 @@ impl<'a> State<'a> {
try!(self.print_inner_attributes(attrs));
for vi in blk.view_items.iter() {
try!(self.print_view_item(vi));
}
for st in blk.stmts.iter() {
try!(self.print_stmt(&**st));
}
@ -2577,7 +2586,7 @@ impl<'a> State<'a> {
pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
match vp.node {
ast::ViewPathSimple(ident, ref path, _) => {
ast::ViewPathSimple(ident, ref path) => {
try!(self.print_path(path, false));
// FIXME(#6993) can't compare identifiers directly here
@ -2591,12 +2600,12 @@ impl<'a> State<'a> {
Ok(())
}
ast::ViewPathGlob(ref path, _) => {
ast::ViewPathGlob(ref path) => {
try!(self.print_path(path, false));
word(&mut self.s, "::*")
}
ast::ViewPathList(ref path, ref idents, _) => {
ast::ViewPathList(ref path, ref idents) => {
if path.segments.is_empty() {
try!(word(&mut self.s, "{"));
} else {
@ -2618,33 +2627,6 @@ impl<'a> State<'a> {
}
}
pub fn print_view_item(&mut self, item: &ast::ViewItem) -> IoResult<()> {
try!(self.hardbreak_if_not_bol());
try!(self.maybe_print_comment(item.span.lo));
try!(self.print_outer_attributes(&item.attrs[]));
try!(self.print_visibility(item.vis));
match item.node {
ast::ViewItemExternCrate(id, ref optional_path, _) => {
try!(self.head("extern crate"));
for &(ref p, style) in optional_path.iter() {
try!(self.print_string(p.get(), style));
try!(space(&mut self.s));
try!(word(&mut self.s, "as"));
try!(space(&mut self.s));
}
try!(self.print_ident(id));
}
ast::ViewItemUse(ref vp) => {
try!(self.head("use"));
try!(self.print_view_path(&**vp));
}
}
try!(word(&mut self.s, ";"));
try!(self.end()); // end inner head-block
self.end() // end outer head-block
}
pub fn print_mutability(&mut self,
mutbl: ast::Mutability) -> IoResult<()> {
match mutbl {

View file

@ -20,8 +20,6 @@ use parse::token;
use ptr::P;
use util::small_vector::SmallVector;
use std::mem;
pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
-> ast::Crate {
if use_std(&krate) {
@ -60,20 +58,16 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> {
None => token::intern_and_get_ident("std"),
};
let mut vis = vec!(ast::ViewItem {
node: ast::ViewItemExternCrate(token::str_to_ident("std"),
Some((actual_crate_name, ast::CookedStr)),
ast::DUMMY_NODE_ID),
krate.module.items.insert(0, P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: token::str_to_ident("std"),
attrs: vec!(
attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
InternedString::new("macro_use")))),
node: ast::ItemExternCrate(Some((actual_crate_name, ast::CookedStr))),
vis: ast::Inherited,
span: DUMMY_SP
});
// `extern crate` must be precede `use` items
mem::swap(&mut vis, &mut krate.module.view_items);
krate.module.view_items.extend(vis.into_iter());
}));
// don't add #![no_std] here, that will block the prelude injection later.
// Add it during the prelude injection instead.
@ -123,7 +117,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
}
}
fn fold_mod(&mut self, ast::Mod {inner, view_items, items}: ast::Mod) -> ast::Mod {
fn fold_mod(&mut self, mut mod_: ast::Mod) -> ast::Mod {
let prelude_path = ast::Path {
span: DUMMY_SP,
global: false,
@ -143,18 +137,11 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
],
};
let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| {
match x.node {
ast::ViewItemExternCrate(..) => true,
_ => false,
}
});
// add prelude after any `extern crate` but before any `use`
let mut view_items = crates;
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path, ast::DUMMY_NODE_ID)));
view_items.push(ast::ViewItem {
node: ast::ViewItemUse(vp),
let vp = P(codemap::dummy_spanned(ast::ViewPathGlob(prelude_path)));
mod_.items.insert(0, P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: special_idents::invalid,
node: ast::ItemUse(vp),
attrs: vec![ast::Attribute {
span: DUMMY_SP,
node: ast::Attribute_ {
@ -170,14 +157,9 @@ impl<'a> fold::Folder for PreludeInjector<'a> {
}],
vis: ast::Inherited,
span: DUMMY_SP,
});
view_items.extend(uses.into_iter());
}));
fold::noop_fold_mod(ast::Mod {
inner: inner,
view_items: view_items,
items: items
}, self)
fold::noop_fold_mod(mod_, self)
}
}

View file

@ -105,11 +105,11 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
// Add a special __test module to the crate that will contain code
// generated for the test harness
let (mod_, reexport) = mk_test_module(&mut self.cx);
folded.module.items.push(mod_);
match reexport {
Some(re) => folded.module.view_items.push(re),
Some(re) => folded.module.items.push(re),
None => {}
}
folded.module.items.push(mod_);
folded
}
@ -205,22 +205,19 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> {
fn mk_reexport_mod(cx: &mut TestCtxt, tests: Vec<ast::Ident>,
tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
let mut view_items = Vec::new();
let super_ = token::str_to_ident("super");
view_items.extend(tests.into_iter().map(|r| {
cx.ext_cx.view_use_simple(DUMMY_SP, ast::Public,
let items = tests.into_iter().map(|r| {
cx.ext_cx.item_use_simple(DUMMY_SP, ast::Public,
cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
}));
view_items.extend(tested_submods.into_iter().map(|(r, sym)| {
}).chain(tested_submods.into_iter().map(|(r, sym)| {
let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
cx.ext_cx.view_use_simple_(DUMMY_SP, ast::Public, r, path)
cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Public, r, path)
}));
let reexport_mod = ast::Mod {
inner: DUMMY_SP,
view_items: view_items,
items: Vec::new(),
items: items.collect(),
};
let sym = token::gensym_ident("__test_reexports");
@ -388,29 +385,29 @@ mod __test {
*/
fn mk_std(cx: &TestCtxt) -> ast::ViewItem {
fn mk_std(cx: &TestCtxt) -> P<ast::Item> {
let id_test = token::str_to_ident("test");
let (vi, vis) = if cx.is_test_crate {
(ast::ViewItemUse(
let (vi, vis, ident) = if cx.is_test_crate {
(ast::ItemUse(
P(nospan(ast::ViewPathSimple(id_test,
path_node(vec!(id_test)),
ast::DUMMY_NODE_ID)))),
ast::Public)
path_node(vec!(id_test)))))),
ast::Public, token::special_idents::invalid)
} else {
(ast::ViewItemExternCrate(id_test, None, ast::DUMMY_NODE_ID),
ast::Inherited)
(ast::ItemExternCrate(None), ast::Inherited, id_test)
};
ast::ViewItem {
P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: ident,
node: vi,
attrs: Vec::new(),
attrs: vec![],
vis: vis,
span: DUMMY_SP
}
})
}
fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<P<ast::Item>>) {
// Link to test crate
let view_items = vec!(mk_std(cx));
let import = mk_std(cx);
// A constant vector of test descriptors.
let tests = mk_tests(cx);
@ -427,8 +424,7 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
let testmod = ast::Mod {
inner: DUMMY_SP,
view_items: view_items,
items: vec!(mainfn, tests),
items: vec![import, mainfn, tests],
};
let item_ = ast::ItemMod(testmod);
@ -439,34 +435,35 @@ fn mk_test_module(cx: &mut TestCtxt) -> (P<ast::Item>, Option<ast::ViewItem>) {
vec![unstable])));
attr::mk_attr_inner(attr::mk_attr_id(), allow)
};
let item = ast::Item {
ident: mod_ident,
let item = P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: mod_ident,
attrs: vec![allow_unstable],
node: item_,
vis: ast::Public,
span: DUMMY_SP,
attrs: vec![allow_unstable],
};
});
let reexport = cx.reexport_test_harness_main.as_ref().map(|s| {
// building `use <ident> = __test::main`
let reexport_ident = token::str_to_ident(s.get());
let use_path =
nospan(ast::ViewPathSimple(reexport_ident,
path_node(vec![mod_ident, token::str_to_ident("main")]),
ast::DUMMY_NODE_ID));
path_node(vec![mod_ident, token::str_to_ident("main")])));
ast::ViewItem {
node: ast::ViewItemUse(P(use_path)),
P(ast::Item {
id: ast::DUMMY_NODE_ID,
ident: token::special_idents::invalid,
attrs: vec![],
node: ast::ItemUse(P(use_path)),
vis: ast::Inherited,
span: DUMMY_SP
}
})
});
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&item));
debug!("Synthetic test module:\n{}\n", pprust::item_to_string(&*item));
(P(item), reexport)
(item, reexport)
}
fn nospan<T>(t: T) -> codemap::Spanned<T> {

View file

@ -69,13 +69,6 @@ pub fn string_to_stmt(source_str : String) -> P<ast::Stmt> {
})
}
/// Parse a string, return a view item
pub fn string_to_view_item (source_str : String) -> ast::ViewItem {
with_error_checking_parse(source_str, |p| {
p.parse_view_item(Vec::new())
})
}
/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
/// (currently) affect parsing.
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {

View file

@ -62,7 +62,6 @@ pub trait Visitor<'v> : Sized {
self.visit_name(span, ident.name);
}
fn visit_mod(&mut self, m: &'v Mod, _s: Span, _n: NodeId) { walk_mod(self, m) }
fn visit_view_item(&mut self, i: &'v ViewItem) { walk_view_item(self, i) }
fn visit_foreign_item(&mut self, i: &'v ForeignItem) { walk_foreign_item(self, i) }
fn visit_item(&mut self, i: &'v Item) { walk_item(self, i) }
fn visit_local(&mut self, l: &'v Local) { walk_local(self, l) }
@ -166,51 +165,11 @@ pub fn walk_crate<'v, V: Visitor<'v>>(visitor: &mut V, krate: &'v Crate) {
}
pub fn walk_mod<'v, V: Visitor<'v>>(visitor: &mut V, module: &'v Mod) {
for view_item in module.view_items.iter() {
visitor.visit_view_item(view_item)
}
for item in module.items.iter() {
visitor.visit_item(&**item)
}
}
pub fn walk_view_item<'v, V: Visitor<'v>>(visitor: &mut V, vi: &'v ViewItem) {
match vi.node {
ViewItemExternCrate(name, _, _) => {
visitor.visit_ident(vi.span, name)
}
ViewItemUse(ref vp) => {
match vp.node {
ViewPathSimple(ident, ref path, id) => {
visitor.visit_ident(vp.span, ident);
visitor.visit_path(path, id);
}
ViewPathGlob(ref path, id) => {
visitor.visit_path(path, id);
}
ViewPathList(ref prefix, ref list, _) => {
for id in list.iter() {
match id.node {
PathListIdent { name, .. } => {
visitor.visit_ident(id.span, name);
}
PathListMod { .. } => ()
}
}
// Note that the `prefix` here is not a complete
// path, so we don't use `visit_path`.
walk_path(visitor, prefix);
}
}
}
}
for attr in vi.attrs.iter() {
visitor.visit_attribute(attr);
}
}
pub fn walk_local<'v, V: Visitor<'v>>(visitor: &mut V, local: &'v Local) {
visitor.visit_pat(&*local.pat);
walk_ty_opt(visitor, &local.ty);
@ -269,6 +228,32 @@ pub fn walk_trait_ref<'v,V>(visitor: &mut V,
pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ident(item.span, item.ident);
match item.node {
ItemExternCrate(..) => {}
ItemUse(ref vp) => {
match vp.node {
ViewPathSimple(ident, ref path) => {
visitor.visit_ident(vp.span, ident);
visitor.visit_path(path, item.id);
}
ViewPathGlob(ref path) => {
visitor.visit_path(path, item.id);
}
ViewPathList(ref prefix, ref list) => {
for id in list.iter() {
match id.node {
PathListIdent { name, .. } => {
visitor.visit_ident(id.span, name);
}
PathListMod { .. } => ()
}
}
// Note that the `prefix` here is not a complete
// path, so we don't use `visit_path`.
walk_path(visitor, prefix);
}
}
}
ItemStatic(ref typ, _, ref expr) |
ItemConst(ref typ, ref expr) => {
visitor.visit_ty(&**typ);
@ -285,9 +270,6 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_mod(module, item.span, item.id)
}
ItemForeignMod(ref foreign_module) => {
for view_item in foreign_module.view_items.iter() {
visitor.visit_view_item(view_item)
}
for foreign_item in foreign_module.items.iter() {
visitor.visit_foreign_item(&**foreign_item)
}
@ -732,9 +714,6 @@ pub fn walk_struct_field<'v, V: Visitor<'v>>(visitor: &mut V,
}
pub fn walk_block<'v, V: Visitor<'v>>(visitor: &mut V, block: &'v Block) {
for view_item in block.view_items.iter() {
visitor.visit_view_item(view_item)
}
for statement in block.stmts.iter() {
visitor.visit_stmt(&**statement)
}

View file

@ -1,4 +1,4 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -8,8 +8,6 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub extern crate core; //~ ERROR: `pub` visibility is not allowed
#![crate_type="lib"]
fn main() {
pub use std::usize; //~ ERROR: imports in functions are never reachable
}
pub const X: () = ();

View 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: () = ();

View file

@ -11,8 +11,7 @@
// aux-build:macro_crate_test.rs
// ignore-stage1
#[plugin] #[no_link]
#[plugin] #[no_link] extern crate macro_crate_test;
//~^ ERROR compiler plugins are experimental and possibly buggy
extern crate macro_crate_test;
fn main() {}

View 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
}
}

View 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
}

View file

@ -1,4 +1,4 @@
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -8,12 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
extern crate test;
mod foo { pub mod foo { } }
fn f() {
}
use foo::foo; //~ ERROR import `foo` conflicts with existing submodule
use test::net; //~ ERROR `use` and `extern crate` declarations must precede items
fn main() {
}
fn main() {}

View 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);
}

View file

@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
@ -9,6 +9,7 @@
// except according to those terms.
fn main() {
pub use std::uint; //~ ERROR: visibility has no effect
pub struct A; //~ ERROR: visibility has no effect
pub enum B {} //~ ERROR: visibility has no effect
pub trait C { //~ ERROR: visibility has no effect

View file

@ -1,8 +1,8 @@
#![no_std]
#[macro_use]
extern crate "std" as std;
#[prelude_import]
use std::prelude::v1::*;
#[macro_use]
extern crate "std" as std;
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.

View 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);
}

View 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);
}