name = "rustc_driver"
version = "0.0.0"
dependencies = [
- "arena 0.0.0",
"env_logger 0.5.13 (registry+https://github.com/rust-lang/crates.io-index)",
"graphviz 0.0.0",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc 0.0.0",
- "rustc-rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_ast_borrowck 0.0.0",
"rustc_codegen_utils 0.0.0",
"rustc_data_structures 0.0.0",
"rustc_errors 0.0.0",
- "rustc_incremental 0.0.0",
"rustc_interface 0.0.0",
- "rustc_lint 0.0.0",
"rustc_metadata 0.0.0",
"rustc_mir 0.0.0",
- "rustc_passes 0.0.0",
- "rustc_plugin 0.0.0",
- "rustc_privacy 0.0.0",
- "rustc_resolve 0.0.0",
"rustc_save_analysis 0.0.0",
"rustc_target 0.0.0",
- "rustc_traits 0.0.0",
- "rustc_typeck 0.0.0",
"serialize 0.0.0",
- "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syntax 0.0.0",
"syntax_pos 0.0.0",
]
"rustc_errors 0.0.0",
"rustc_mir 0.0.0",
"syntax 0.0.0",
- "syntax_ext 0.0.0",
"syntax_pos 0.0.0",
]
crate-type = ["dylib"]
[dependencies]
-arena = { path = "../libarena" }
graphviz = { path = "../libgraphviz" }
log = "0.4"
env_logger = { version = "0.5", default-features = false }
-rayon = { version = "0.2.0", package = "rustc-rayon" }
rustc = { path = "../librustc" }
rustc_target = { path = "../librustc_target" }
rustc_ast_borrowck = { path = "../librustc_ast_borrowck" }
rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
-rustc_incremental = { path = "../librustc_incremental" }
-rustc_lint = { path = "../librustc_lint" }
rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" }
-rustc_passes = { path = "../librustc_passes" }
-rustc_plugin = { path = "../librustc_plugin" }
-rustc_privacy = { path = "../librustc_privacy" }
-rustc_resolve = { path = "../librustc_resolve" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
-rustc_traits = { path = "../librustc_traits" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
-rustc_typeck = { path = "../librustc_typeck" }
rustc_interface = { path = "../librustc_interface" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
syntax = { path = "../libsyntax" }
-smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
syntax_pos = { path = "../libsyntax_pos" }
rustc_mir = { path = "../librustc_mir"}
rustc_data_structures = { path = "../librustc_data_structures" }
syntax = { path = "../libsyntax" }
-syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
use rustc_data_structures::fx::FxHashMap;
use syntax::ast::*;
use syntax::attr;
+use syntax::ext::proc_macro::is_proc_macro_attr;
use syntax::feature_gate::is_builtin_attr;
use syntax::source_map::Spanned;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
use syntax::{span_err, struct_span_err, walk_list};
-use syntax_ext::proc_macro_decls::is_proc_macro_attr;
use syntax_pos::{Span, MultiSpan};
use errors::{Applicability, FatalError};
use errors::{DiagnosticBuilder, DiagnosticId};
use smallvec::{smallvec, SmallVec};
-use syntax_pos::{Span, MultiSpan, DUMMY_SP};
+use syntax_pos::{FileName, Span, MultiSpan, DUMMY_SP};
use syntax_pos::hygiene::{ExpnInfo, ExpnKind};
use rustc_data_structures::fx::FxHashMap;
--- /dev/null
+use crate::ast::Attribute;
+use crate::symbol::sym;
+
+pub fn is_proc_macro_attr(attr: &Attribute) -> bool {
+ [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive]
+ .iter().any(|kind| attr.check_name(*kind))
+}
+++ /dev/null
-use crate::ast;
-use crate::ext::base::{self, *};
-use crate::ext::build::AstBuilder;
-use crate::parse::{self, token, DirectoryOwnership};
-use crate::print::pprust;
-use crate::ptr::P;
-use crate::symbol::Symbol;
-use crate::tokenstream;
-
-use smallvec::SmallVec;
-use syntax_pos::{self, Pos, Span};
-
-use std::fs;
-use std::io::ErrorKind;
-use rustc_data_structures::sync::Lrc;
-
-// These macros all relate to the file system; they either return
-// the column/row/filename of the expression, or they include
-// a given file into the current one.
-
-/// line!(): expands to the current line number
-pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- base::check_zero_tts(cx, sp, tts, "line!");
-
- let topmost = cx.expansion_cause().unwrap_or(sp);
- let loc = cx.source_map().lookup_char_pos(topmost.lo());
-
- base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
-}
-
-/* column!(): expands to the current column number */
-pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- base::check_zero_tts(cx, sp, tts, "column!");
-
- let topmost = cx.expansion_cause().unwrap_or(sp);
- let loc = cx.source_map().lookup_char_pos(topmost.lo());
-
- base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
-}
-
-/// file!(): expands to the current filename */
-/// The source_file (`loc.file`) contains a bunch more information we could spit
-/// out if we wanted.
-pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- base::check_zero_tts(cx, sp, tts, "file!");
-
- let topmost = cx.expansion_cause().unwrap_or(sp);
- let loc = cx.source_map().lookup_char_pos(topmost.lo());
- base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name.to_string())))
-}
-
-pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- let s = pprust::tts_to_string(tts);
- base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
-}
-
-pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- base::check_zero_tts(cx, sp, tts, "module_path!");
- let mod_path = &cx.current_expansion.module.mod_path;
- let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
-
- base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
-}
-
-/// include! : parse the given file as an expr
-/// This is generally a bad idea because it's going to behave
-/// unhygienically.
-pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'cx> {
- let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
- Some(f) => f,
- None => return DummyResult::any(sp),
- };
- // The file will be added to the code map by the parser
- let file = cx.resolve_path(file, sp);
- let directory_ownership = DirectoryOwnership::Owned { relative: None };
- let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
-
- struct ExpandResult<'a> {
- p: parse::parser::Parser<'a>,
- }
- impl<'a> base::MacResult for ExpandResult<'a> {
- fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
- Some(panictry!(self.p.parse_expr()))
- }
-
- fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
- let mut ret = SmallVec::new();
- while self.p.token != token::Eof {
- match panictry!(self.p.parse_item()) {
- Some(item) => ret.push(item),
- None => self.p.diagnostic().span_fatal(self.p.token.span,
- &format!("expected item, found `{}`",
- self.p.this_token_to_string()))
- .raise()
- }
- }
- Some(ret)
- }
- }
-
- Box::new(ExpandResult { p })
-}
-
-// include_str! : read the given file, insert it as a literal string expr
-pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
- Some(f) => f,
- None => return DummyResult::expr(sp)
- };
- let file = cx.resolve_path(file, sp);
- match fs::read_to_string(&file) {
- Ok(src) => {
- let interned_src = Symbol::intern(&src);
-
- // Add this input file to the code map to make it available as
- // dependency information
- cx.source_map().new_source_file(file.into(), src);
-
- base::MacEager::expr(cx.expr_str(sp, interned_src))
- },
- Err(ref e) if e.kind() == ErrorKind::InvalidData => {
- cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
- DummyResult::expr(sp)
- }
- Err(e) => {
- cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
- DummyResult::expr(sp)
- }
- }
-}
-
-pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
- -> Box<dyn base::MacResult+'static> {
- let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
- Some(f) => f,
- None => return DummyResult::expr(sp)
- };
- let file = cx.resolve_path(file, sp);
- match fs::read(&file) {
- Ok(bytes) => {
- // Add the contents to the source map if it contains UTF-8.
- let (contents, bytes) = match String::from_utf8(bytes) {
- Ok(s) => {
- let bytes = s.as_bytes().to_owned();
- (s, bytes)
- },
- Err(e) => (String::new(), e.into_bytes()),
- };
- cx.source_map().new_source_file(file.into(), contents);
-
- base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
- },
- Err(e) => {
- cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
- DummyResult::expr(sp)
- }
- }
-}
// way towards a non-panic!-prone parser. It should be used for fatal parsing
// errors; eventually we plan to convert all code using panictry to just use
// normal try.
+#[macro_export]
macro_rules! panictry {
($e:expr) => ({
use std::result::Result::{Ok, Err};
pub mod derive;
pub mod expand;
pub mod placeholders;
- pub mod source_util;
+ pub mod proc_macro;
pub mod tt {
pub mod transcribe;
mod global_asm;
mod log_syntax;
mod proc_macro_server;
+mod source_util;
mod test;
mod test_case;
mod trace_macros;
use syntax::ext::build::AstBuilder;
use syntax::ext::expand::ExpansionConfig;
use syntax::ext::hygiene::ExpnId;
+use syntax::ext::proc_macro::is_proc_macro_attr;
use syntax::mut_visit::MutVisitor;
use syntax::parse::ParseSess;
use syntax::ptr::P;
-use syntax::symbol::Symbol;
use syntax::symbol::{kw, sym};
use syntax::visit::{self, Visitor};
use syntax_pos::{Span, DUMMY_SP};
-const PROC_MACRO_KINDS: [Symbol; 3] = [
- sym::proc_macro_derive,
- sym::proc_macro_attribute,
- sym::proc_macro
-];
-
struct ProcMacroDerive {
trait_name: ast::Name,
function_name: Ident,
krate
}
-pub fn is_proc_macro_attr(attr: &ast::Attribute) -> bool {
- PROC_MACRO_KINDS.iter().any(|kind| attr.check_name(*kind))
-}
-
impl<'a> CollectProcMacros<'a> {
fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) {
if self.is_proc_macro_crate && self.in_root && vis.node.is_pub() {
--- /dev/null
+use syntax::{ast, panictry};
+use syntax::ext::base::{self, *};
+use syntax::ext::build::AstBuilder;
+use syntax::parse::{self, token, DirectoryOwnership};
+use syntax::print::pprust;
+use syntax::ptr::P;
+use syntax::symbol::Symbol;
+use syntax::tokenstream;
+
+use smallvec::SmallVec;
+use syntax_pos::{self, Pos, Span};
+
+use std::fs;
+use std::io::ErrorKind;
+use rustc_data_structures::sync::Lrc;
+
+// These macros all relate to the file system; they either return
+// the column/row/filename of the expression, or they include
+// a given file into the current one.
+
+/// line!(): expands to the current line number
+pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ base::check_zero_tts(cx, sp, tts, "line!");
+
+ let topmost = cx.expansion_cause().unwrap_or(sp);
+ let loc = cx.source_map().lookup_char_pos(topmost.lo());
+
+ base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
+}
+
+/* column!(): expands to the current column number */
+pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ base::check_zero_tts(cx, sp, tts, "column!");
+
+ let topmost = cx.expansion_cause().unwrap_or(sp);
+ let loc = cx.source_map().lookup_char_pos(topmost.lo());
+
+ base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
+}
+
+/// file!(): expands to the current filename */
+/// The source_file (`loc.file`) contains a bunch more information we could spit
+/// out if we wanted.
+pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ base::check_zero_tts(cx, sp, tts, "file!");
+
+ let topmost = cx.expansion_cause().unwrap_or(sp);
+ let loc = cx.source_map().lookup_char_pos(topmost.lo());
+ base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name.to_string())))
+}
+
+pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ let s = pprust::tts_to_string(tts);
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
+}
+
+pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ base::check_zero_tts(cx, sp, tts, "module_path!");
+ let mod_path = &cx.current_expansion.module.mod_path;
+ let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
+
+ base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
+}
+
+/// include! : parse the given file as an expr
+/// This is generally a bad idea because it's going to behave
+/// unhygienically.
+pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'cx> {
+ let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
+ Some(f) => f,
+ None => return DummyResult::any(sp),
+ };
+ // The file will be added to the code map by the parser
+ let file = cx.resolve_path(file, sp);
+ let directory_ownership = DirectoryOwnership::Owned { relative: None };
+ let p = parse::new_sub_parser_from_file(cx.parse_sess(), &file, directory_ownership, None, sp);
+
+ struct ExpandResult<'a> {
+ p: parse::parser::Parser<'a>,
+ }
+ impl<'a> base::MacResult for ExpandResult<'a> {
+ fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
+ Some(panictry!(self.p.parse_expr()))
+ }
+
+ fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
+ let mut ret = SmallVec::new();
+ while self.p.token != token::Eof {
+ match panictry!(self.p.parse_item()) {
+ Some(item) => ret.push(item),
+ None => self.p.sess.span_diagnostic.span_fatal(self.p.token.span,
+ &format!("expected item, found `{}`",
+ self.p.this_token_to_string()))
+ .raise()
+ }
+ }
+ Some(ret)
+ }
+ }
+
+ Box::new(ExpandResult { p })
+}
+
+// include_str! : read the given file, insert it as a literal string expr
+pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
+ Some(f) => f,
+ None => return DummyResult::expr(sp)
+ };
+ let file = cx.resolve_path(file, sp);
+ match fs::read_to_string(&file) {
+ Ok(src) => {
+ let interned_src = Symbol::intern(&src);
+
+ // Add this input file to the code map to make it available as
+ // dependency information
+ cx.source_map().new_source_file(file.into(), src);
+
+ base::MacEager::expr(cx.expr_str(sp, interned_src))
+ },
+ Err(ref e) if e.kind() == ErrorKind::InvalidData => {
+ cx.span_err(sp, &format!("{} wasn't a utf-8 file", file.display()));
+ DummyResult::expr(sp)
+ }
+ Err(e) => {
+ cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
+ DummyResult::expr(sp)
+ }
+ }
+}
+
+pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+ -> Box<dyn base::MacResult+'static> {
+ let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
+ Some(f) => f,
+ None => return DummyResult::expr(sp)
+ };
+ let file = cx.resolve_path(file, sp);
+ match fs::read(&file) {
+ Ok(bytes) => {
+ // Add the contents to the source map if it contains UTF-8.
+ let (contents, bytes) = match String::from_utf8(bytes) {
+ Ok(s) => {
+ let bytes = s.as_bytes().to_owned();
+ (s, bytes)
+ },
+ Err(e) => (String::new(), e.into_bytes()),
+ };
+ cx.source_map().new_source_file(file.into(), contents);
+
+ base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
+ },
+ Err(e) => {
+ cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));
+ DummyResult::expr(sp)
+ }
+ }
+}