Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macro reform #20482

Closed
wants to merge 24 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d1cf1b1
Don't test codegen-units errors on stage1 (c.f. #20184)
kmcallister Jan 1, 2015
5e5924b
Replace LetSyntaxTT with MacroRulesTT
kmcallister Sep 15, 2014
ad7c647
Add a special macro nonterminal $crate
kmcallister Sep 16, 2014
e2a9c04
Allow leading :: in use items
kmcallister Dec 10, 2014
5382881
Implement macro re-export
kmcallister Sep 16, 2014
1c2fddc
Remove unused if_ok! macro
kmcallister Dec 10, 2014
73806dd
Use $crate and macro reexport to reduce duplicated code
kmcallister Sep 16, 2014
fc58479
Stop using macro_escape as an inner attribute
kmcallister Dec 19, 2014
5bf385b
Rename macro_escape to macro_use
kmcallister Dec 19, 2014
5171b32
creader: Convert free functions to Env methods
kmcallister Dec 21, 2014
24aa7f0
creader: Use a single struct
kmcallister Dec 21, 2014
677b7ca
Reformat metadata for exported macros
kmcallister Dec 31, 2014
f314e2c
creader: Load parts of plugin metadata on demand
kmcallister Jan 1, 2015
60be2f5
Replace #[phase] with #[plugin] / #[macro_use] / #[no_link]
kmcallister Jan 1, 2015
0816255
Move #[macro_reexport] to extern crate
kmcallister Jan 2, 2015
aa69cbd
Allow selective macro import
kmcallister Jan 2, 2015
c9f0ff3
Reserve the keyword 'macro'
kmcallister Jan 2, 2015
416137e
Modernize macro_rules! invocations
kmcallister Jan 2, 2015
d0163d3
Pass the #[plugin(...)] meta item to the registrar
kmcallister Jan 3, 2015
c2e2697
Un-gate macro_rules
kmcallister Jan 3, 2015
bbbb85a
Forbid '#[macro_use] extern crate' outside the crate root
kmcallister Jan 3, 2015
34b995d
Add a test case for accidental macro re-export
kmcallister Jan 3, 2015
78e841d
Update docs
kmcallister Jan 3, 2015
2167e5b
Add missing #[no_link]
kmcallister Jan 6, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
creader: Use a single struct
  • Loading branch information
Keegan McAllister committed Jan 5, 2015
commit 24aa7f0e387e2a04795e80bc91b8b8adf6a1c98f
94 changes: 41 additions & 53 deletions src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
@@ -37,32 +37,12 @@ use syntax::visit;
use util::fs;
use log;

struct Env<'a> {
pub struct CrateReader<'a> {
sess: &'a Session,
next_crate_num: ast::CrateNum,
}

// Traverses an AST, reading all the information about use'd crates and extern
// libraries necessary for later resolving, typechecking, linking, etc.
pub fn read_crates(sess: &Session,
krate: &ast::Crate) {
let mut e = Env {
sess: sess,
next_crate_num: sess.cstore.next_crate_num(),
};
e.visit_crate(krate);
visit::walk_crate(&mut e, krate);
if log_enabled!(log::DEBUG) {
dump_crates(&sess.cstore);
}
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore);

for &(ref name, kind) in sess.opts.libs.iter() {
register_native_lib(sess, None, name.clone(), kind);
}
}

impl<'a, 'v> visit::Visitor<'v> for Env<'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);
@@ -173,8 +153,31 @@ fn register_native_lib(sess: &Session,
sess.cstore.add_used_library(name, kind);
}

impl<'a> Env<'a> {
fn visit_crate(&self, c: &ast::Crate) {
impl<'a> CrateReader<'a> {
pub fn new(sess: &'a Session) -> CrateReader<'a> {
CrateReader {
sess: sess,
next_crate_num: sess.cstore.next_crate_num(),
}
}

// Traverses an AST, reading all the information about use'd crates and extern
// libraries necessary for later resolving, typechecking, linking, etc.
pub fn read_crates(&mut self, krate: &ast::Crate) {
self.process_crate(krate);
visit::walk_crate(self, krate);

if log_enabled!(log::DEBUG) {
dump_crates(&self.sess.cstore);
}
warn_if_multiple_versions(self.sess.diagnostic(), &self.sess.cstore);

for &(ref name, kind) in self.sess.opts.libs.iter() {
register_native_lib(self.sess, None, name.clone(), kind);
}
}

fn process_crate(&self, c: &ast::Crate) {
for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
match a.value_str() {
Some(ref linkarg) => self.sess.cstore.add_used_link_args(linkarg.get()),
@@ -445,35 +448,20 @@ impl<'a> Env<'a> {
(dep.cnum, local_cnum)
}).collect()
}
}

pub struct PluginMetadataReader<'a> {
env: Env<'a>,
}

impl<'a> PluginMetadataReader<'a> {
pub fn new(sess: &'a Session) -> PluginMetadataReader<'a> {
PluginMetadataReader {
env: Env {
sess: sess,
next_crate_num: sess.cstore.next_crate_num(),
}
}
}

pub fn read_plugin_metadata(&mut self,
krate: &ast::ViewItem) -> PluginMetadata {
let info = self.env.extract_crate_info(krate).unwrap();
let target_triple = self.env.sess.opts.target_triple[];
let info = self.extract_crate_info(krate).unwrap();
let target_triple = self.sess.opts.target_triple[];
let is_cross = target_triple != config::host_triple();
let mut should_link = info.should_link && !is_cross;
let mut load_ctxt = loader::Context {
sess: self.env.sess,
sess: self.sess,
span: krate.span,
ident: info.ident[],
crate_name: info.name[],
hash: None,
filesearch: self.env.sess.host_filesearch(PathKind::Crate),
filesearch: self.sess.host_filesearch(PathKind::Crate),
triple: config::host_triple(),
root: &None,
rejected_via_hash: vec!(),
@@ -486,17 +474,17 @@ impl<'a> PluginMetadataReader<'a> {
// try loading from target crates (only valid if there are
// no syntax extensions)
load_ctxt.triple = target_triple;
load_ctxt.filesearch = self.env.sess.target_filesearch(PathKind::Crate);
load_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate);
let lib = load_ctxt.load_library_crate();
if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
let message = format!("crate `{}` contains a plugin_registrar fn but \
only a version for triple `{}` could be found (need {})",
info.ident, target_triple, config::host_triple());
self.env.sess.span_err(krate.span, message[]);
only a version for triple `{}` could be found (need {})",
info.ident, target_triple, config::host_triple());
self.sess.span_err(krate.span, message[]);
// need to abort now because the syntax expansion
// code will shortly attempt to load and execute
// code from the found library.
self.env.sess.abort_if_errors();
self.sess.abort_if_errors();
}
should_link = info.should_link;
lib
@@ -510,8 +498,8 @@ impl<'a> PluginMetadataReader<'a> {
if library.dylib.is_none() && registrar.is_some() {
let message = format!("plugin crate `{}` only found in rlib format, \
but must be available in dylib format",
info.ident);
self.env.sess.span_err(krate.span, message[]);
info.ident);
self.sess.span_err(krate.span, message[]);
// No need to abort because the loading code will just ignore this
// empty dylib.
}
@@ -520,10 +508,10 @@ impl<'a> PluginMetadataReader<'a> {
macros: macros,
registrar_symbol: registrar,
};
if should_link && self.env.existing_match(info.name[], None).is_none() {
if should_link && self.existing_match(info.name[], None).is_none() {
// register crate now to avoid double-reading metadata
self.env.register_crate(&None, info.ident[],
info.name[], krate.span, library);
self.register_crate(&None, info.ident[],
info.name[], krate.span, library);
}
pc
}
6 changes: 3 additions & 3 deletions src/librustc/plugin/load.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@
//! Used by `rustc` when loading a plugin.

use session::Session;
use metadata::creader::PluginMetadataReader;
use metadata::creader::CrateReader;
use plugin::registry::Registry;

use std::mem;
@@ -48,15 +48,15 @@ pub struct Plugins {

struct PluginLoader<'a> {
sess: &'a Session,
reader: PluginMetadataReader<'a>,
reader: CrateReader<'a>,
plugins: Plugins,
}

impl<'a> PluginLoader<'a> {
fn new(sess: &'a Session) -> PluginLoader<'a> {
PluginLoader {
sess: sess,
reader: PluginMetadataReader::new(sess),
reader: CrateReader::new(sess),
plugins: Plugins {
macros: vec!(),
registrars: vec!(),
4 changes: 2 additions & 2 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ use rustc::session::Session;
use rustc::session::config::{self, Input, OutputFilenames};
use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::metadata::creader;
use rustc::metadata::creader::CrateReader;
use rustc::middle::{stability, ty, reachable};
use rustc::middle::dependency_format;
use rustc::middle;
@@ -354,7 +354,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
let krate = ast_map.krate();

time(time_passes, "external crate/lib resolution", (), |_|
creader::read_crates(&sess, krate));
CrateReader::new(&sess).read_crates(krate));

let lang_items = time(time_passes, "language item collection", (), |_|
middle::lang_items::collect_language_items(krate, &sess));