Skip to content

Commit

Permalink
Auto merge of #20179 - eddyb:blind-items, r=alexcrichton
Browse files Browse the repository at this point in the history
This implements an important part of RFC PR 385 (see #18219).
  • Loading branch information
bors committed Jan 21, 2015
2 parents 6869645 + 7136938 commit 27ac518
Show file tree
Hide file tree
Showing 59 changed files with 1,095 additions and 1,519 deletions.
32 changes: 9 additions & 23 deletions src/doc/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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.

Expand Down
1 change: 1 addition & 0 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ register_diagnostics! {
E0140,
E0152,
E0153,
E0154,
E0157,
E0158,
E0161,
Expand Down
37 changes: 16 additions & 21 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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[]);
},
_ => ()
Expand Down Expand Up @@ -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; }

Expand Down Expand Up @@ -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 {
Expand Down
8 changes: 0 additions & 8 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 0 additions & 1 deletion src/librustc/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) { }
Expand Down
56 changes: 25 additions & 31 deletions src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 {
Expand Down Expand Up @@ -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<CrateInfo> {
fn extract_crate_info(&self, i: &ast::Item) -> Option<CrateInfo> {
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 {
Expand All @@ -218,16 +194,34 @@ impl<'a> CrateReader<'a> {
Some(CrateInfo {
ident: ident.get().to_string(),
name: name,
id: id,
id: i.id,
should_link: should_link(i),
})
}
_ => None
}
}

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;
Expand Down Expand Up @@ -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)
}

Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..) |
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/middle/resolve_lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..) |
Expand Down
24 changes: 16 additions & 8 deletions src/librustc/plugin/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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" => {
Expand Down Expand Up @@ -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) {
Expand Down
14 changes: 0 additions & 14 deletions src/librustc_back/svh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ mod svh_visitor {
SawLifetimeDef(token::InternedString),

SawMod,
SawViewItem,
SawForeignItem,
SawItem,
SawDecl,
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_driver/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ impl fold::Folder for ReplaceBodyWithLoop {
e: Option<P<ast::Expr>>) -> P<ast::Block> {
P(ast::Block {
expr: e,
view_items: vec![], stmts: vec![], rules: rules,
stmts: vec![], rules: rules,
id: ast::DUMMY_NODE_ID, span: codemap::DUMMY_SP,
})
}
Expand Down
Loading

0 comments on commit 27ac518

Please sign in to comment.