diff --git a/src/doc/reference.md b/src/doc/reference.md index d3af4ab1c7467..8f76e2a1f3d5e 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -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} @@ -2891,13 +2878,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. diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 1ea79bdf606da..2602f38b3add3 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -52,6 +52,7 @@ register_diagnostics! { E0140, E0152, E0153, + E0154, E0157, E0158, E0161, diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 8a27cfc510f4a..ff6f67b186973 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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 { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index de4efe09f2725..4e675b32632e7 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -603,14 +603,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); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 826a35e3bb529..a4a3f485af1d1 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -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) { } diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 5de683f8a4f07..7b71120ba64a6 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -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,29 +176,10 @@ impl<'a> CrateReader<'a> { } } - fn process_view_item(&mut self, i: &ast::ViewItem) { - if !should_link(i) { - return; - } - - match self.extract_crate_info(i) { - Some(info) => { - let (cnum, _, _) = self.resolve_crate(&None, - &info.ident[], - &info.name[], - None, - i.span, - PathKind::Crate); - self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); - } - None => () - } - } - - fn extract_crate_info(&self, i: &ast::ViewItem) -> Option { + fn extract_crate_info(&self, i: &ast::Item) -> Option { match i.node { - ast::ViewItemExternCrate(ident, ref path_opt, id) => { - let ident = token::get_ident(ident); + 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 { @@ -218,7 +194,7 @@ impl<'a> CrateReader<'a> { Some(CrateInfo { ident: ident.get().to_string(), name: name, - id: id, + id: i.id, should_link: should_link(i), }) } @@ -226,8 +202,26 @@ impl<'a> CrateReader<'a> { } } - fn process_item(&self, i: &ast::Item) { + fn process_item(&mut self, i: &ast::Item) { match i.node { + ast::ItemExternCrate(_) => { + if !should_link(i) { + return; + } + + match self.extract_crate_info(i) { + Some(info) => { + let (cnum, _, _) = self.resolve_crate(&None, + &info.ident[], + &info.name[], + None, + i.span, + PathKind::Crate); + self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum); + } + None => () + } + } ast::ItemForeignMod(ref fm) => { 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) } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 5cbe97504281d..d0989160488f2 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -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 } } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 550c0f34cafec..ae5449f0ba657 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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, diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index d6e652f16c654..b93cde4bf6464 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -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(..) | diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index eff0018becc01..a3ede8b6a05de 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -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(..) | diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index ef8a89c40fb5a..c420d1f15b43b 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -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) { diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index b71e465b938f5..79d7a0ced393d 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -188,7 +188,6 @@ mod svh_visitor { SawLifetimeDef(token::InternedString), SawMod, - SawViewItem, SawForeignItem, SawItem, SawDecl, @@ -436,19 +435,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 diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 279442891bec0..582e10323248c 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop { e: Option>) -> P { 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, }) } diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index f68c76f4c4424..cd28a27f9886b 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -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 diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index e12c195a3afbc..414dbb9626347 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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) {} } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 21eec383df465..65bd83d7937fb 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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::>(); + 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) { - 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::>(); - 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(&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); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 18066a7b94bd8..97370112ab40f 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -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); } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 31999faa6dfea..b70980cf1ec0c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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}; @@ -1139,7 +1139,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) @@ -1748,10 +1748,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()); @@ -1791,10 +1787,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() @@ -1888,10 +1880,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) { self.session .span_err(span, @@ -1906,10 +1894,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) { self.session .span_err(span, @@ -2982,9 +2966,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); } - ItemMac(..) => { + ItemExternCrate(_) | ItemUse(_) | ItemMac(..) => { // do nothing, these are just around to be encoded - } + } } } @@ -3525,6 +3509,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); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index b12903c814cbf..8de7f82c9d366 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -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 diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index f52e7c0ec94c0..93076260349ab 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -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)[]) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 80c0a72db8387..329f86293774e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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!(), } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index 86447e76a898b..941f50c298ef3 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -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(..) | diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7342c9f3e81de..7cae1828ef624 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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::*; @@ -309,6 +308,8 @@ impl Item { #[derive(Clone, RustcEncodable, RustcDecodable)] pub enum ItemEnum { + ExternCrateItem(String, Option), + ImportItem(Import), StructItem(Struct), EnumItem(Enum), FunctionItem(Function), @@ -318,8 +319,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), @@ -349,27 +348,21 @@ impl Clean 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!( - 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 = + 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. @@ -395,9 +388,7 @@ impl Clean 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 }) } } @@ -2120,12 +2111,21 @@ impl Clean for doctree::Impl { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub struct ViewItem { - pub inner: ViewItemInner, +impl Clean 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> for ast::ViewItem { +impl Clean> for doctree::Import { fn clean(&self, cx: &DocContext) -> Vec { // We consider inlining the documentation of `pub use` statements, but we // forcefully don't inline if this is not public or if the @@ -2136,81 +2136,63 @@ impl Clean> 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) => { - // 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| { - match inline::try_inline(cx, path.node.id(), None) { - Some(items) => { - ret.extend(items.into_iter()); false - } - None => true, + 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 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()); + } + None => { + remaining.push(path.clean(cx)); } - }).map(|a| a.clone()).collect::>(); - 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)), } } - } - } - ref n => ret.push(convert(n)), - } - return ret; - } -} - -#[derive(Clone, RustcEncodable, RustcDecodable)] -pub enum ViewItemInner { - ExternCrate(String, Option, ast::NodeId), - Import(ViewPath) -} - -impl Clean 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()), + remaining + } else { + list.clean(cx) }; - ExternCrate(i.clean(cx), string, *id) + if remaining.is_empty() { + return ret; + } + (ret, ImportList(resolve_use_source(cx, p.clean(cx), self.id), + remaining)) } - &ast::ViewItemUse(ref vp) => { - Import(vp.clean(cx)) + 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))) } - } + }; + 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)] -pub enum ViewPath { +pub enum Import { // use source as str; SimpleImport(String, ImportSource), // use source::*; @@ -2225,21 +2207,6 @@ pub struct ImportSource { pub did: Option, } -impl Clean 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)] pub struct ViewListIdent { pub name: String, diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 99afef4173fdd..0e8ab594c20c1 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -25,6 +25,8 @@ pub struct Module { pub attrs: Vec, pub where_outer: Span, pub where_inner: Span, + pub extern_crates: Vec, + pub imports: Vec, pub structs: Vec, pub enums: Vec, pub fns: Vec, @@ -38,7 +40,6 @@ pub struct Module { pub stab: Option, pub impls: Vec, pub foreigns: Vec, - pub view_items: Vec, pub macros: Vec, 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, } +pub struct ExternCrate { + pub name: Ident, + pub path: Option, + pub vis: ast::Visibility, + pub attrs: Vec, + pub whence: Span, +} + +pub struct Import { + pub id: NodeId, + pub vis: ast::Visibility, + pub attrs: Vec, + 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 diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 57b8d666c95b7..c8efa4c57bb31 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -617,7 +617,7 @@ impl fmt::String for UnsafetySpace { } } -impl fmt::String for clean::ViewPath { +impl fmt::String for clean::Import { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { clean::SimpleImport(ref name, ref src) => { diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs index db3319eb7659c..ff7884a8616e4 100644 --- a/src/librustdoc/html/item_type.rs +++ b/src/librustdoc/html/item_type.rs @@ -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", diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ab9700d966aa5..6242b5d89002c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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, "")); } 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, _) => { - match *src { - Some(ref src) => - try!(write!(w, "extern crate \"{}\" as {}", - src.as_slice(), - name.as_slice())), - None => - try!(write!(w, "extern crate {}", - name.as_slice())), - } - try!(write!(w, ";")); + clean::ExternCrateItem(ref name, ref src) => { + match *src { + Some(ref src) => { + try!(write!(w, "{}extern crate \"{}\" as {};", + VisSpace(myitem.visibility), + src.as_slice(), + name.as_slice())) } - - clean::Import(ref import) => { - try!(write!(w, "{}{}", - VisSpace(myitem.visibility), - *import)); + None => { + try!(write!(w, "{}extern crate {};", + VisSpace(myitem.visibility), name.as_slice())) } } + try!(write!(w, "")); + } + clean::ImportItem(ref import) => { + try!(write!(w, "{}{}", + VisSpace(myitem.visibility), *import)); } _ => { diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css index 5951ac2bae71a..0914f93efd802 100644 --- a/src/librustdoc/html/static/main.css +++ b/src/librustdoc/html/static/main.css @@ -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 { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index f27f0cd70f4ef..1b0c3b0064099 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -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", diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 9a67b479106ee..0e60001e15ffd 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -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 } diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs index 451dbce568ee0..943bc6ec99634 100644 --- a/src/librustdoc/stability_summary.rs +++ b/src/librustdoc/stability_summary.rs @@ -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) { })) } // no stability information for the following items: - ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None), + ExternCrateItem(..) | ImportItem(_) | + PrimitiveItem(_) => (Counts::zero(), None), _ => (item_counts, None) } } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 428b4e92a681f..848205f589eda 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -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) -> 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> { - match path.node { - ast::ViewPathSimple(dst, _, id) => { + id: ast::NodeId, + please_inline: bool) -> Option { + match path { + ast::ViewPathSimple(dst, base) => { if self.resolve_id(id, Some(dst), false, om, please_inline) { - return None + None + } else { + Some(ast::ViewPathSimple(dst, base)) } } - ast::ViewPathList(ref p, ref paths, ref b) => { - 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()); - } - } + ast::ViewPathList(p, paths) => { + let mine = paths.into_iter().filter(|path| { + !self.resolve_id(path.node.id(), None, false, om, + please_inline) + }).collect::>(); - 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, @@ -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(), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index fcf80410da240..9d0675388131f 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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, pub stmts: Vec>, pub expr: Option>, pub id: NodeId, @@ -1452,14 +1450,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, pub items: Vec>, } #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] pub struct ForeignMod { pub abi: Abi, - pub view_items: Vec, pub items: Vec>, } @@ -1518,44 +1514,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 , NodeId) -} - -#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)] -pub struct ViewItem { - pub node: ViewItem_, - pub attrs: Vec, - 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), + ViewPathList(Path, Vec) } /// Meta-data associated with an item @@ -1677,6 +1642,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), + ItemStatic(P, Mutability, P), ItemConst(P, P), ItemFn(P, Unsafety, Abi, Generics, P), @@ -1703,6 +1674,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", diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index f462a730d3aa0..2d710e636d82b 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -107,7 +107,6 @@ pub fn path_to_string>(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 { 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> { 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 { 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) diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index bc7fbd46fd8ba..192af7bb789b9 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -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,10 +425,24 @@ 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 { - for variant in enum_definition.variants.iter() { - self.operation.visit_id(variant.node.id) + 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(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool { walk_pat_(pat, &mut it) } -pub trait EachViewItem { - fn each_view_item(&self, f: F) -> bool where F: FnMut(&ast::ViewItem) -> bool; -} - -struct EachViewItemData where F: FnMut(&ast::ViewItem) -> bool { - callback: F, -} - -impl<'v, F> Visitor<'v> for EachViewItemData 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(&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 { diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 3f91831a5df76..3eaac0fe333e8 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -63,28 +63,13 @@ pub fn strip_items(krate: ast::Crate, in_cfg: F) -> ast::Crate where ctxt.fold_crate(krate) } -fn filter_view_item(cx: &mut Context, - view_item: ast::ViewItem) - -> Option where - F: FnMut(&[ast::Attribute]) -> bool -{ - if view_item_in_cfg(cx, &view_item) { - Some(view_item) - } else { - None - } -} - fn fold_mod(cx: &mut Context, - 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(cx: &mut Context, } fn fold_foreign_mod(cx: &mut Context, - 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(cx: &mut Context, stmt: &ast::Stmt) -> bool where fn fold_block(cx: &mut Context, b: P) -> P 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> = 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(cx: &mut Context, item: &ast::ForeignItem) -> bool return (cx.in_cfg)(item.attrs.as_slice()); } -fn view_item_in_cfg(cx: &mut Context, item: &ast::ViewItem) -> bool where - F: FnMut(&[ast::Attribute]) -> bool -{ - return (cx.in_cfg)(item.attrs.as_slice()); -} - fn trait_method_in_cfg(cx: &mut Context, meth: &ast::TraitItem) -> bool where F: FnMut(&[ast::Attribute]) -> bool { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index c34142aec39c8..2adf0f1a1a2e0 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -97,7 +97,6 @@ pub trait AstBuilder { expr: Option>) -> P; fn block_expr(&self, expr: P) -> P; fn block_all(&self, span: Span, - view_items: Vec, stmts: Vec>, expr: Option>) -> P; @@ -242,7 +241,7 @@ pub trait AstBuilder { fn item_mod(&self, span: Span, inner_span: Span, name: Ident, attrs: Vec, - vi: Vec , items: Vec> ) -> P; + items: Vec>) -> P; fn item_static(&self, span: Span, @@ -280,15 +279,15 @@ pub trait AstBuilder { value: ast::Lit_) -> P; - fn view_use(&self, sp: Span, - vis: ast::Visibility, vp: P) -> 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 , imports: &[ast::Ident]) -> ast::ViewItem; - fn view_use_glob(&self, sp: Span, - vis: ast::Visibility, path: Vec ) -> ast::ViewItem; + fn item_use(&self, sp: Span, + vis: ast::Visibility, vp: P) -> P; + fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P; + fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, + ident: ast::Ident, path: ast::Path) -> P; + fn item_use_list(&self, sp: Span, vis: ast::Visibility, + path: Vec, imports: &[ast::Ident]) -> P; + fn item_use_glob(&self, sp: Span, + vis: ast::Visibility, path: Vec) -> P; } impl<'a> AstBuilder for ExtCtxt<'a> { @@ -519,7 +518,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn block(&self, span: Span, stmts: Vec>, expr: Option>) -> P { - self.block_all(span, Vec::new(), stmts, expr) + self.block_all(span, stmts, expr) } fn stmt_item(&self, sp: Span, item: P) -> P { @@ -528,15 +527,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn block_expr(&self, expr: P) -> P { - 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, stmts: Vec>, expr: Option>) -> P { 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 , - vi: Vec , - items: Vec> ) -> P { + attrs: Vec, + items: Vec>) -> P { 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::ViewItem { - ast::ViewItem { - node: ast::ViewItemUse(vp), - attrs: Vec::new(), + fn item_use(&self, sp: Span, + vis: ast::Visibility, vp: P) -> P { + 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 { 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 { + 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 , imports: &[ast::Ident]) -> ast::ViewItem { + fn item_use_list(&self, sp: Span, vis: ast::Visibility, + path: Vec, imports: &[ast::Ident]) -> P { 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::ViewItem { - self.view_use(sp, vis, + fn item_use_glob(&self, sp: Span, + vis: ast::Visibility, path: Vec) -> P { + self.item_use(sp, vis, P(respan(sp, - ast::ViewPathGlob(self.path(sp, path), ast::DUMMY_NODE_ID)))) + ast::ViewPathGlob(self.path(sp, path))))) } } diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 293e4befd3bb1..73d002172a980 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -1073,7 +1073,7 @@ impl<'a> MethodDef<'a> { // // } 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 = ...; diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index c95bdeefd4540..2aa5f72c0c408 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -206,7 +206,6 @@ pub fn expand_expr(e: P, fld: &mut MacroExpander) -> P { // 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, fld: &mut MacroExpander) -> P { // expand the elements of a block. pub fn expand_block_elts(b: P, fld: &mut MacroExpander) -> P { - 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, fld: &mut MacroExpander) -> P { }); Block { id: fld.new_id(id), - view_items: new_view_items, stmts: new_stmts, expr: new_expr, rules: rules, diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index c42b188302cc3..e63a920994b75 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -352,18 +352,11 @@ pub mod rt { impl<'a> ExtParseUtils for ExtCtxt<'a> { fn parse_item(&self, s: String) -> P { - let res = parse::parse_item_from_source_str( + parse::parse_item_from_source_str( "".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 { @@ -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, expr: P) -> P { - 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, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 13b7944998ad8..762a1dcbfc34b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -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(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"), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index f484650ad5b06..44ee17a0d9670 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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) -> P { noop_fold_foreign_item(ni, self) } @@ -349,16 +345,13 @@ pub fn noop_fold_meta_items(meta_items: Vec>, fld: &mut T pub fn noop_fold_view_path(view_path: P, fld: &mut T) -> P { 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(view_path: P, 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(qpath: P, fld: &mut T) -> P { }) } -pub fn noop_fold_foreign_mod(ForeignMod {abi, view_items, items}: ForeignMod, +pub fn noop_fold_foreign_mod(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(VariantArg {id, ty}: VariantArg, folder: &mu } } -pub fn noop_fold_view_item(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(b: P, folder: &mut T) -> P { - 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(b: P, folder: &mut T) -> P { pub fn noop_fold_item_underscore(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(m: TypeMethod, fld: &mut T) -> TypeMetho } } -pub fn noop_fold_mod(Mod {inner, view_items, items}: Mod, folder: &mut T) -> Mod { +pub fn noop_fold_mod(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(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() { diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index dd376fe9e10e8..8ac94a38273b1 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -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); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 83a7504bc4984..a474e4c2bad93 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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), - IoviItem(P), - IoviForeignItem(P), - IoviViewItem(ViewItem) -} +/// The `Err` case indicates a failure to parse any kind of item. +/// The attributes are returned. +type MaybeItem = Result, Vec>; /// 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, rhs: Option>) lhs } - -struct ParsedItemsAndViewItems { - attrs_remaining: Vec, - view_items: Vec, - items: Vec> , - foreign_items: Vec> -} - /* 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 { 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 ) -> P { - let mut stmts = Vec::new(); + first_item_attrs: Vec) -> P { + 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, 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> = 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 > 0u { + 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 ) + first_item_attrs: Vec) -> 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 ) - -> ItemOrViewItem { + attrs: Vec) + -> P { 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, visibility: Visibility, - attrs: Vec ) - -> ItemOrViewItem { + attrs: Vec) + -> P { 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, - last_span.hi, - special_idents::invalid, - ItemForeignMod(m), - visibility, - maybe_append(attrs, Some(inner))); - return IoviItem(item); + self.mk_item(lo, + last_span.hi, + special_idents::invalid, + ItemForeignMod(m), + visibility, + 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 , - macros_allowed: bool) - -> ItemOrViewItem { + fn parse_item_(&mut self, attrs: Vec, + 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(1u, |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(1u, |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(1u, |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 , - 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) + -> Result, Vec> { 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> { @@ -5911,30 +5836,9 @@ impl<'a> Parser<'a> { } pub fn parse_item(&mut self, attrs: Vec) -> Option> { - 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) -> 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 /// | MOD? non_global_path MOD_SEP LBRACE ident_seq 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 , - 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 = 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 , - macros_allowed: bool) - -> ParsedItemsAndViewItems { + fn parse_foreign_items(&mut self, first_item_attrs: Vec) + -> Vec> { 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 diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b59e770c6ba51..19499db28628b 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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 { diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index 28b9eaa54aabc..d75fbcf199dbe 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -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) -> 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) } } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index 5f869d5093fec..38aa7b1c76998 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -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, tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P, 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 { 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, Option) { +fn mk_test_module(cx: &mut TestCtxt) -> (P, Option>) { // 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, Option) { 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, Option) { 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 = __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) -> codemap::Spanned { diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs index 83bbff8473d04..4a288814b6b83 100644 --- a/src/libsyntax/util/parser_testing.rs +++ b/src/libsyntax/util/parser_testing.rs @@ -69,13 +69,6 @@ pub fn string_to_stmt(source_str : String) -> P { }) } -/// 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 { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 7778b4fa34aa1..eb906788aa7f4 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -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) } diff --git a/src/test/compile-fail/issue-9957.rs b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs similarity index 64% rename from src/test/compile-fail/issue-9957.rs rename to src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs index b1204e828900c..f129b4b77bb9f 100644 --- a/src/test/compile-fail/issue-9957.rs +++ b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo.rs @@ -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: () = (); diff --git a/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs new file mode 100644 index 0000000000000..91fa912455109 --- /dev/null +++ b/src/test/auxiliary/blind-item-mixed-crate-use-item-foo2.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type="lib"] + +pub const Y: () = (); diff --git a/src/test/compile-fail-fulldeps/gated-plugin.rs b/src/test/compile-fail-fulldeps/gated-plugin.rs index 89090d5f38abe..be9e57e2d1950 100644 --- a/src/test/compile-fail-fulldeps/gated-plugin.rs +++ b/src/test/compile-fail-fulldeps/gated-plugin.rs @@ -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() {} diff --git a/src/test/compile-fail/blind-item-block-item-shadow.rs b/src/test/compile-fail/blind-item-block-item-shadow.rs new file mode 100644 index 0000000000000..d4adaa042b2b5 --- /dev/null +++ b/src/test/compile-fail/blind-item-block-item-shadow.rs @@ -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 or the MIT license +// , 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 + } +} diff --git a/src/test/compile-fail/blind-item-block-middle.rs b/src/test/compile-fail/blind-item-block-middle.rs new file mode 100644 index 0000000000000..fbb0730f01461 --- /dev/null +++ b/src/test/compile-fail/blind-item-block-middle.rs @@ -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 or the MIT license +// , 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 +} diff --git a/src/test/compile-fail/view-items-at-top.rs b/src/test/compile-fail/blind-item-item-shadow.rs similarity index 67% rename from src/test/compile-fail/view-items-at-top.rs rename to src/test/compile-fail/blind-item-item-shadow.rs index 7b78a8d932b33..9f21d6a923408 100644 --- a/src/test/compile-fail/view-items-at-top.rs +++ b/src/test/compile-fail/blind-item-item-shadow.rs @@ -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() {} diff --git a/src/test/compile-fail/blind-item-local-shadow.rs b/src/test/compile-fail/blind-item-local-shadow.rs new file mode 100644 index 0000000000000..a28f5f6e55715 --- /dev/null +++ b/src/test/compile-fail/blind-item-local-shadow.rs @@ -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 or the MIT license +// , 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); +} diff --git a/src/test/compile-fail/unnecessary-private.rs b/src/test/compile-fail/unnecessary-private.rs index 6e6ffd23c4a87..e3707292f2495 100644 --- a/src/test/compile-fail/unnecessary-private.rs +++ b/src/test/compile-fail/unnecessary-private.rs @@ -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 diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index dac6e628d10d5..c18d076c0d318 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -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. diff --git a/src/test/run-pass/blind-item-mixed-crate-use-item.rs b/src/test/run-pass/blind-item-mixed-crate-use-item.rs new file mode 100644 index 0000000000000..80c73e5e60b53 --- /dev/null +++ b/src/test/run-pass/blind-item-mixed-crate-use-item.rs @@ -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 or the MIT license +// , 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, _: (), _: ()) { } + pub fn g(_: 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); +} diff --git a/src/test/run-pass/blind-item-mixed-use-item.rs b/src/test/run-pass/blind-item-mixed-use-item.rs new file mode 100644 index 0000000000000..a3dad01acf17b --- /dev/null +++ b/src/test/run-pass/blind-item-mixed-use-item.rs @@ -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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod m { + pub fn f(_: T, _: ()) { } + pub fn g(_: T, _: ()) { } +} + +const BAR: () = (); +struct Data; +use m::f; + +fn main() { + const BAR2: () = (); + struct Data2; + use m::g; + + f(Data, BAR); + g(Data2, BAR2); +}