use symbol::Symbol;
use util::small_vector::SmallVector;
+use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;
use std::default::Default;
///
/// The `bool` dictates whether the contents of the macro can
/// directly use `#[unstable]` things (true == yes).
- NormalTT(Box<TTMacroExpander>, Option<Span>, bool),
+ NormalTT(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>, bool),
/// A function-like syntax extension that has an extra ident before
/// the block.
-> Result<Option<Rc<SyntaxExtension>>, Determinacy>;
fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, kind: MacroKind, force: bool)
-> Result<Rc<SyntaxExtension>, Determinacy>;
+ fn check_unused_macros(&self);
}
#[derive(Copy, Clone, Debug)]
_force: bool) -> Result<Rc<SyntaxExtension>, Determinacy> {
Err(Determinacy::Determined)
}
+ fn check_unused_macros(&self) {}
}
#[derive(Clone)]
}
/// One of these is made during expansion and incrementally updated as we go;
-/// when a macro expansion occurs, the resulting nodes have the backtrace()
-/// -> expn_info of their expansion context stored into their span.
+/// when a macro expansion occurs, the resulting nodes have the `backtrace()
+/// -> expn_info` of their expansion context stored into their span.
pub struct ExtCtxt<'a> {
pub parse_sess: &'a parse::ParseSess,
pub ecfg: expand::ExpansionConfig<'a>,
pub resolver: &'a mut Resolver,
pub resolve_err_count: usize,
pub current_expansion: ExpansionData,
+ pub expansions: HashMap<Span, Vec<String>>,
}
impl<'a> ExtCtxt<'a> {
module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
directory_ownership: DirectoryOwnership::Owned,
},
+ expansions: HashMap::new(),
}
}
/// Returns span for the macro which originally caused the current expansion to happen.
///
/// Stops backtracing at include! boundary.
- pub fn expansion_cause(&self) -> Span {
+ pub fn expansion_cause(&self) -> Option<Span> {
let mut ctxt = self.backtrace();
let mut last_macro = None;
loop {
}
ctxt = info.call_site.ctxt;
last_macro = Some(info.call_site);
- return Some(());
+ Some(())
}).is_none() {
break
}
}
- last_macro.expect("missing expansion backtrace")
+ last_macro
}
pub fn struct_span_warn(&self,
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
self.parse_sess.span_diagnostic.span_bug(sp, msg);
}
+ pub fn trace_macros_diag(&self) {
+ for (sp, notes) in self.expansions.iter() {
+ let mut db = self.parse_sess.span_diagnostic.span_note_diag(*sp, "trace_macro");
+ for note in notes {
+ db.note(note);
+ }
+ db.emit();
+ }
+ }
pub fn bug(&self, msg: &str) -> ! {
self.parse_sess.span_diagnostic.bug(msg);
}
v.push(self.ident_of(s));
}
v.extend(components.iter().map(|s| self.ident_of(s)));
- return v
+ v
}
pub fn name_of(&self, st: &str) -> ast::Name {
Symbol::intern(st)
}
+
+ pub fn check_unused_macros(&self) {
+ self.resolver.check_unused_macros();
+ }
}
/// Extract a string literal from the macro expanded version of `expr`,
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "line!");
- let topmost = cx.expansion_cause();
+ let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "column!");
- let topmost = cx.expansion_cause();
+ let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32))
-> Box<base::MacResult+'static> {
base::check_zero_tts(cx, sp, tts, "file!");
- let topmost = cx.expansion_cause();
+ let topmost = cx.expansion_cause().unwrap_or(sp);
let loc = cx.codemap().lookup_char_pos(topmost.lo);
base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name)))
}
cx.span_err(sp,
&format!("{} wasn't a utf-8 file",
file.display()));
- return DummyResult::expr(sp);
+ DummyResult::expr(sp)
}
}
}
Err(e) => {
cx.span_err(sp,
&format!("couldn't read {}: {}", file.display(), e));
- return DummyResult::expr(sp);
+ DummyResult::expr(sp)
}
Ok(..) => {
// Add this input file to the code map to make it available as