about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/diagnostic.rs87
-rw-r--r--src/libsyntax/diagnostics/macros.rs51
-rw-r--r--src/libsyntax/diagnostics/plugin.rs132
-rw-r--r--src/libsyntax/diagnostics/registry.rs25
-rw-r--r--src/libsyntax/ext/build.rs6
-rw-r--r--src/libsyntax/ext/expand.rs4
-rw-r--r--src/libsyntax/lib.rs61
-rw-r--r--src/libsyntax/parse/lexer/mod.rs2
-rw-r--r--src/libsyntax/parse/mod.rs2
9 files changed, 307 insertions, 63 deletions
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index e469f327ae8..9bb5eae2ed2 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -12,6 +12,7 @@ extern crate libc;
 
 use codemap::{Pos, Span};
 use codemap;
+use diagnostics;
 
 use std::cell::{RefCell, Cell};
 use std::fmt;
@@ -59,7 +60,7 @@ pub enum ColorConfig {
 
 pub trait Emitter {
     fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str, lvl: Level);
+            msg: &str, code: Option<&str>, lvl: Level);
     fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level);
 }
@@ -90,6 +91,10 @@ impl SpanHandler {
         self.handler.emit(Some((&self.cm, sp)), msg, Error);
         self.handler.bump_err_count();
     }
+    pub fn span_err_with_code(&self, sp: Span, msg: &str, code: &str) {
+        self.handler.emit_with_code(Some((&self.cm, sp)), msg, code, Error);
+        self.handler.bump_err_count();
+    }
     pub fn span_warn(&self, sp: Span, msg: &str) {
         self.handler.emit(Some((&self.cm, sp)), msg, Warning);
     }
@@ -124,11 +129,11 @@ pub struct Handler {
 
 impl Handler {
     pub fn fatal(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(None, msg, Fatal);
+        self.emit.borrow_mut().emit(None, msg, None, Fatal);
         fail!(FatalError);
     }
     pub fn err(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Error);
+        self.emit.borrow_mut().emit(None, msg, None, Error);
         self.bump_err_count();
     }
     pub fn bump_err_count(&self) {
@@ -153,13 +158,13 @@ impl Handler {
         self.fatal(s.as_slice());
     }
     pub fn warn(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Warning);
+        self.emit.borrow_mut().emit(None, msg, None, Warning);
     }
     pub fn note(&self, msg: &str) {
-        self.emit.borrow_mut().emit(None, msg, Note);
+        self.emit.borrow_mut().emit(None, msg, None, Note);
     }
     pub fn bug(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(None, msg, Bug);
+        self.emit.borrow_mut().emit(None, msg, None, Bug);
         fail!(ExplicitBug);
     }
     pub fn unimpl(&self, msg: &str) -> ! {
@@ -169,7 +174,14 @@ impl Handler {
                 cmsp: Option<(&codemap::CodeMap, Span)>,
                 msg: &str,
                 lvl: Level) {
-        self.emit.borrow_mut().emit(cmsp, msg, lvl);
+        self.emit.borrow_mut().emit(cmsp, msg, None, lvl);
+    }
+    pub fn emit_with_code(&self,
+                          cmsp: Option<(&codemap::CodeMap, Span)>,
+                          msg: &str,
+                          code: &str,
+                          lvl: Level) {
+        self.emit.borrow_mut().emit(cmsp, msg, Some(code), lvl);
     }
     pub fn custom_emit(&self, cm: &codemap::CodeMap,
                        sp: RenderSpan, msg: &str, lvl: Level) {
@@ -184,8 +196,9 @@ pub fn mk_span_handler(handler: Handler, cm: codemap::CodeMap) -> SpanHandler {
     }
 }
 
-pub fn default_handler(color_config: ColorConfig) -> Handler {
-    mk_handler(box EmitterWriter::stderr(color_config))
+pub fn default_handler(color_config: ColorConfig,
+                       registry: Option<diagnostics::registry::Registry>) -> Handler {
+    mk_handler(box EmitterWriter::stderr(color_config, registry))
 }
 
 pub fn mk_handler(e: Box<Emitter + Send>) -> Handler {
@@ -262,8 +275,8 @@ fn print_maybe_styled(w: &mut EmitterWriter,
     }
 }
 
-fn print_diagnostic(dst: &mut EmitterWriter,
-                    topic: &str, lvl: Level, msg: &str) -> io::IoResult<()> {
+fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
+                    msg: &str, code: Option<&str>) -> io::IoResult<()> {
     if !topic.is_empty() {
         try!(write!(&mut dst.dst, "{} ", topic));
     }
@@ -272,13 +285,32 @@ fn print_diagnostic(dst: &mut EmitterWriter,
                             format!("{}: ", lvl.to_string()).as_slice(),
                             term::attr::ForegroundColor(lvl.color())));
     try!(print_maybe_styled(dst,
-                            format!("{}\n", msg).as_slice(),
+                            format!("{}", msg).as_slice(),
                             term::attr::Bold));
+
+    match code {
+        Some(code) => {
+            let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
+            try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
+            match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
+                Some(_) => {
+                    try!(write!(&mut dst.dst,
+                        " (pass `--explain {}` to see a detailed explanation)",
+                        code
+                    ));
+                }
+                None => ()
+            }
+        }
+        None => ()
+    }
+    try!(dst.dst.write_char('\n'));
     Ok(())
 }
 
 pub struct EmitterWriter {
     dst: Destination,
+    registry: Option<diagnostics::registry::Registry>
 }
 
 enum Destination {
@@ -287,7 +319,8 @@ enum Destination {
 }
 
 impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig) -> EmitterWriter {
+    pub fn stderr(color_config: ColorConfig,
+                  registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
         let stderr = io::stderr();
 
         let use_color = match color_config {
@@ -301,14 +334,15 @@ impl EmitterWriter {
                 Some(t) => Terminal(t),
                 None    => Raw(box stderr),
             };
-            EmitterWriter { dst: dst }
+            EmitterWriter { dst: dst, registry: registry }
         } else {
-            EmitterWriter { dst: Raw(box stderr) }
+            EmitterWriter { dst: Raw(box stderr), registry: registry }
         }
     }
 
-    pub fn new(dst: Box<Writer + Send>) -> EmitterWriter {
-        EmitterWriter { dst: Raw(dst) }
+    pub fn new(dst: Box<Writer + Send>,
+               registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
+        EmitterWriter { dst: Raw(dst), registry: registry }
     }
 }
 
@@ -324,11 +358,10 @@ impl Writer for Destination {
 impl Emitter for EmitterWriter {
     fn emit(&mut self,
             cmsp: Option<(&codemap::CodeMap, Span)>,
-            msg: &str,
-            lvl: Level) {
+            msg: &str, code: Option<&str>, lvl: Level) {
         let error = match cmsp {
-            Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, lvl, false),
-            None => print_diagnostic(self, "", lvl, msg),
+            Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, code, lvl, false),
+            None => print_diagnostic(self, "", lvl, msg, code),
         };
 
         match error {
@@ -339,7 +372,7 @@ impl Emitter for EmitterWriter {
 
     fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level) {
-        match emit(self, cm, sp, msg, lvl, true) {
+        match emit(self, cm, sp, msg, None, lvl, true) {
             Ok(()) => {}
             Err(e) => fail!("failed to print diagnostics: {}", e),
         }
@@ -347,7 +380,7 @@ impl Emitter for EmitterWriter {
 }
 
 fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
-        msg: &str, lvl: Level, custom: bool) -> io::IoResult<()> {
+        msg: &str, code: Option<&str>, lvl: Level, custom: bool) -> io::IoResult<()> {
     let sp = rsp.span();
     let ss = cm.span_to_string(sp);
     let lines = cm.span_to_lines(sp);
@@ -357,12 +390,12 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
         // the span)
         let span_end = Span { lo: sp.hi, hi: sp.hi, expn_info: sp.expn_info};
         let ses = cm.span_to_string(span_end);
-        try!(print_diagnostic(dst, ses.as_slice(), lvl, msg));
+        try!(print_diagnostic(dst, ses.as_slice(), lvl, msg, code));
         if rsp.is_full_span() {
             try!(custom_highlight_lines(dst, cm, sp, lvl, lines));
         }
     } else {
-        try!(print_diagnostic(dst, ss.as_slice(), lvl, msg));
+        try!(print_diagnostic(dst, ss.as_slice(), lvl, msg, code));
         if rsp.is_full_span() {
             try!(highlight_lines(dst, cm, sp, lvl, lines));
         }
@@ -501,9 +534,9 @@ fn print_macro_backtrace(w: &mut EmitterWriter,
         try!(print_diagnostic(w, ss.as_slice(), Note,
                               format!("in expansion of {}{}{}", pre,
                                       ei.callee.name,
-                                      post).as_slice()));
+                                      post).as_slice(), None));
         let ss = cm.span_to_string(ei.call_site);
-        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site"));
+        try!(print_diagnostic(w, ss.as_slice(), Note, "expansion site", None));
         try!(print_macro_backtrace(w, cm, ei.call_site));
     }
     Ok(())
diff --git a/src/libsyntax/diagnostics/macros.rs b/src/libsyntax/diagnostics/macros.rs
new file mode 100644
index 00000000000..b0260e1180f
--- /dev/null
+++ b/src/libsyntax/diagnostics/macros.rs
@@ -0,0 +1,51 @@
+// 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.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![macro_escape]
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __register_diagnostic(
+    ($code:tt, $description:tt) => ();
+    ($code:tt) => ()
+)
+
+#[macro_export]
+macro_rules! register_diagnostic(
+    ($code:tt, $description:tt) => (__register_diagnostic!($code, $description));
+    ($code:tt) => (__register_diagnostic!($code))
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __build_diagnostic_array(
+    ($name:ident) => {
+        pub static $name: [(&'static str, &'static str), ..0] = [];
+    }
+)
+
+// NOTE: remove after next snapshot
+#[cfg(stage0)]
+#[macro_export]
+macro_rules! __diagnostic_used(
+    ($code:ident) => {
+        ()
+    }
+)
+
+#[macro_export]
+macro_rules! span_err(
+    ($session:expr, $span:expr, $code:ident, $($arg:expr),*) => ({
+        __diagnostic_used!($code);
+        ($session).span_err_with_code($span, format!($($arg),*).as_slice(), stringify!($code))
+    })
+)
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
new file mode 100644
index 00000000000..6582d2e44c8
--- /dev/null
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -0,0 +1,132 @@
+// 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.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::collections::HashMap;
+use std::gc::Gc;
+use ast;
+use ast::{Ident, Name, TokenTree};
+use codemap::Span;
+use ext::base::{ExtCtxt, MacExpr, MacItem, MacResult};
+use ext::build::AstBuilder;
+use parse::token;
+
+local_data_key!(registered_diagnostics: RefCell<HashMap<Name, Option<Name>>>)
+local_data_key!(used_diagnostics: RefCell<HashMap<Name, Span>>)
+
+fn with_registered_diagnostics<T>(f: |&mut HashMap<Name, Option<Name>>| -> T) -> T {
+    match registered_diagnostics.get() {
+        Some(cell) => f(cell.borrow_mut().deref_mut()),
+        None => {
+            let mut map = HashMap::new();
+            let value = f(&mut map);
+            registered_diagnostics.replace(Some(RefCell::new(map)));
+            value
+        }
+    }
+}
+
+fn with_used_diagnostics<T>(f: |&mut HashMap<Name, Span>| -> T) -> T {
+    match used_diagnostics.get() {
+        Some(cell) => f(cell.borrow_mut().deref_mut()),
+        None => {
+            let mut map = HashMap::new();
+            let value = f(&mut map);
+            used_diagnostics.replace(Some(RefCell::new(map)));
+            value
+        }
+    }
+}
+
+pub fn expand_diagnostic_used(ecx: &mut ExtCtxt, span: Span,
+                              token_tree: &[TokenTree]) -> Box<MacResult> {
+    let code = match token_tree {
+        [ast::TTTok(_, token::IDENT(code, _))] => code,
+        _ => unreachable!()
+    };
+    with_registered_diagnostics(|diagnostics| {
+        if !diagnostics.contains_key(&code.name) {
+            ecx.span_err(span, format!(
+                "unknown diagnostic code {}", token::get_ident(code).get()
+            ).as_slice());
+        }
+        ()
+    });
+    with_used_diagnostics(|diagnostics| {
+        match diagnostics.swap(code.name, span) {
+            Some(previous_span) => {
+                ecx.span_warn(span, format!(
+                    "diagnostic code {} already used", token::get_ident(code).get()
+                ).as_slice());
+                ecx.span_note(previous_span, "previous invocation");
+            },
+            None => ()
+        }
+        ()
+    });
+    MacExpr::new(quote_expr!(ecx, ()))
+}
+
+pub fn expand_register_diagnostic(ecx: &mut ExtCtxt, span: Span,
+                                  token_tree: &[TokenTree]) -> Box<MacResult> {
+    let (code, description) = match token_tree {
+        [ast::TTTok(_, token::IDENT(ref code, _))] => {
+            (code, None)
+        },
+        [ast::TTTok(_, token::IDENT(ref code, _)),
+         ast::TTTok(_, token::COMMA),
+         ast::TTTok(_, token::LIT_STR_RAW(description, _))] => {
+            (code, Some(description))
+        }
+        _ => unreachable!()
+    };
+    with_registered_diagnostics(|diagnostics| {
+        if !diagnostics.insert(code.name, description) {
+            ecx.span_err(span, format!(
+                "diagnostic code {} already registered", token::get_ident(*code).get()
+            ).as_slice());
+        }
+    });
+    let sym = Ident::new(token::gensym((
+        "__register_diagnostic_".to_string() + token::get_ident(*code).get()
+    ).as_slice()));
+    MacItem::new(quote_item!(ecx, mod $sym {}).unwrap())
+}
+
+pub fn expand_build_diagnostic_array(ecx: &mut ExtCtxt, span: Span,
+                                     token_tree: &[TokenTree]) -> Box<MacResult> {
+    let name = match token_tree {
+        [ast::TTTok(_, token::IDENT(ref name, _))] => name,
+        _ => unreachable!()
+    };
+
+    let (count, expr) = with_used_diagnostics(|diagnostics_in_use| {
+        with_registered_diagnostics(|diagnostics| {
+            let descriptions: Vec<Gc<ast::Expr>> = diagnostics
+                .iter().filter_map(|(code, description)| {
+                if !diagnostics_in_use.contains_key(code) {
+                    ecx.span_warn(span, format!(
+                        "diagnostic code {} never used", token::get_name(*code).get()
+                    ).as_slice());
+                }
+                description.map(|description| {
+                    ecx.expr_tuple(span, vec![
+                        ecx.expr_str(span, token::get_name(*code)),
+                        ecx.expr_str(span, token::get_name(description))
+                    ])
+                })
+            }).collect();
+            (descriptions.len(), ecx.expr_vec(span, descriptions))
+        })
+    });
+    MacItem::new(quote_item!(ecx,
+        pub static $name: [(&'static str, &'static str), ..$count] = $expr;
+    ).unwrap())
+}
diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs
new file mode 100644
index 00000000000..7bc191df55a
--- /dev/null
+++ b/src/libsyntax/diagnostics/registry.rs
@@ -0,0 +1,25 @@
+// 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.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::HashMap;
+
+pub struct Registry {
+    descriptions: HashMap<&'static str, &'static str>
+}
+
+impl Registry {
+    pub fn new(descriptions: &[(&'static str, &'static str)]) -> Registry {
+        Registry { descriptions: descriptions.iter().map(|&tuple| tuple).collect() }
+    }
+
+    pub fn find_description(&self, code: &str) -> Option<&'static str> {
+        self.descriptions.find_equiv(&code).map(|desc| *desc)
+    }
+}
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 4d79ff3257a..4d3913da365 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -148,6 +148,8 @@ pub trait AstBuilder {
     fn expr_some(&self, sp: Span, expr: Gc<ast::Expr>) -> Gc<ast::Expr>;
     fn expr_none(&self, sp: Span) -> Gc<ast::Expr>;
 
+    fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr>;
+
     fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr>;
     fn expr_unreachable(&self, span: Span) -> Gc<ast::Expr>;
 
@@ -674,6 +676,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr_path(none)
     }
 
+    fn expr_tuple(&self, sp: Span, exprs: Vec<Gc<ast::Expr>>) -> Gc<ast::Expr> {
+        self.expr(sp, ast::ExprTup(exprs))
+    }
+
     fn expr_fail(&self, span: Span, msg: InternedString) -> Gc<ast::Expr> {
         let loc = self.codemap().lookup_char_pos(span.lo);
         self.expr_call_global(
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index b7d72ae4deb..b5f7005c2a3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -58,7 +58,7 @@ pub fn expand_expr(e: Gc<ast::Expr>, fld: &mut MacroExpander) -> Gc<ast::Expr> {
                         None => {
                             fld.cx.span_err(
                                 pth.span,
-                                format!("macro undefined: '{}'",
+                                format!("macro undefined: '{}!'",
                                         extnamestr.get()).as_slice());
 
                             // let compilation continue
@@ -567,7 +567,7 @@ fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<Gc<Stmt>> {
     let marked_after = match fld.extsbox.find(&extname.name) {
         None => {
             fld.cx.span_err(pth.span,
-                            format!("macro undefined: '{}'",
+                            format!("macro undefined: '{}!'",
                                     extnamestr).as_slice());
             return SmallVector::zero();
         }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 1ef376c6615..184ce39aaf2 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -27,12 +27,11 @@
 #![feature(quote, unsafe_destructor)]
 #![allow(deprecated)]
 
-extern crate serialize;
-extern crate term;
-#[phase(plugin, link)] extern crate log;
-
 extern crate fmt_macros;
 extern crate debug;
+#[phase(plugin, link)] extern crate log;
+extern crate serialize;
+extern crate term;
 
 pub mod util {
     pub mod interner;
@@ -41,26 +40,30 @@ pub mod util {
     pub mod small_vector;
 }
 
+pub mod diagnostics {
+    pub mod macros;
+    pub mod plugin;
+    pub mod registry;
+}
+
 pub mod syntax {
     pub use ext;
     pub use parse;
     pub use ast;
 }
 
-pub mod owned_slice;
-pub mod attr;
-pub mod diagnostic;
-pub mod codemap;
 pub mod abi;
 pub mod ast;
-pub mod ast_util;
 pub mod ast_map;
-pub mod visit;
+pub mod ast_util;
+pub mod attr;
+pub mod codemap;
+pub mod crateid;
+pub mod diagnostic;
 pub mod fold;
-
-
+pub mod owned_slice;
 pub mod parse;
-pub mod crateid;
+pub mod visit;
 
 pub mod print {
     pub mod pp;
@@ -70,31 +73,25 @@ pub mod print {
 pub mod ext {
     pub mod asm;
     pub mod base;
+    pub mod build;
+    pub mod bytes;
+    pub mod cfg;
+    pub mod concat;
+    pub mod concat_idents;
+    pub mod deriving;
+    pub mod env;
     pub mod expand;
-
+    pub mod fmt;
+    pub mod format;
+    pub mod log_syntax;
+    pub mod mtwt;
     pub mod quote;
-
-    pub mod deriving;
-
-    pub mod build;
+    pub mod source_util;
+    pub mod trace_macros;
 
     pub mod tt {
         pub mod transcribe;
         pub mod macro_parser;
         pub mod macro_rules;
     }
-
-    pub mod mtwt;
-
-    pub mod cfg;
-    pub mod fmt;
-    pub mod format;
-    pub mod env;
-    pub mod bytes;
-    pub mod concat;
-    pub mod concat_idents;
-    pub mod log_syntax;
-    pub mod source_util;
-
-    pub mod trace_macros;
 }
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index 0aaddacfab6..5c5943f0cd4 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -1308,7 +1308,7 @@ mod test {
     use std::io::util;
 
     fn mk_sh() -> diagnostic::SpanHandler {
-        let emitter = diagnostic::EmitterWriter::new(box util::NullWriter);
+        let emitter = diagnostic::EmitterWriter::new(box util::NullWriter, None);
         let handler = diagnostic::mk_handler(box emitter);
         diagnostic::mk_span_handler(handler, CodeMap::new())
     }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 37c84c95af6..a3e169cd511 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -40,7 +40,7 @@ pub struct ParseSess {
 
 pub fn new_parse_sess() -> ParseSess {
     ParseSess {
-        span_diagnostic: mk_span_handler(default_handler(Auto), CodeMap::new()),
+        span_diagnostic: mk_span_handler(default_handler(Auto, None), CodeMap::new()),
         included_mod_stack: RefCell::new(Vec::new()),
     }
 }