about summary refs log tree commit diff
path: root/src/libsyntax/errors
diff options
context:
space:
mode:
authorJonathan Turner <jturner@mozilla.com>2016-06-21 18:08:13 -0400
committerJonathan Turner <jturner@mozilla.com>2016-06-23 08:07:35 -0400
commit6ae350213485f7c917113f3916e58c51cef97a76 (patch)
treef72d48a2dfcd24267bc1b8b0b0807ff07fac5a5d /src/libsyntax/errors
parent3908913db51d3b9d449206ab5b4a37cf3319d234 (diff)
downloadrust-6ae350213485f7c917113f3916e58c51cef97a76.tar.gz
rust-6ae350213485f7c917113f3916e58c51cef97a76.zip
Move errors from libsyntax to its own crate
Diffstat (limited to 'src/libsyntax/errors')
-rw-r--r--src/libsyntax/errors/emitter.rs871
-rw-r--r--src/libsyntax/errors/json.rs367
-rw-r--r--src/libsyntax/errors/mod.rs711
-rw-r--r--src/libsyntax/errors/snippet/mod.rs888
-rw-r--r--src/libsyntax/errors/snippet/test.rs597
5 files changed, 0 insertions, 3434 deletions
diff --git a/src/libsyntax/errors/emitter.rs b/src/libsyntax/errors/emitter.rs
deleted file mode 100644
index 71a03e846a2..00000000000
--- a/src/libsyntax/errors/emitter.rs
+++ /dev/null
@@ -1,871 +0,0 @@
-// Copyright 2012-2015 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 self::Destination::*;
-
-use codemap::{self, COMMAND_LINE_SP, DUMMY_SP, Span, MultiSpan};
-use diagnostics;
-
-use errors::check_old_skool;
-use errors::{Level, RenderSpan, CodeSuggestion, DiagnosticBuilder};
-use errors::RenderSpan::*;
-use errors::Level::*;
-use errors::snippet::{RenderedLineKind, SnippetData, Style};
-
-use std::{cmp, fmt};
-use std::io::prelude::*;
-use std::io;
-use std::rc::Rc;
-use term;
-
-/// Emitter trait for emitting errors. Do not implement this directly:
-/// implement `CoreEmitter` instead.
-pub trait Emitter {
-    /// Emit a standalone diagnostic message.
-    fn emit(&mut self, span: &MultiSpan, msg: &str, code: Option<&str>, lvl: Level);
-
-    /// Emit a structured diagnostic.
-    fn emit_struct(&mut self, db: &DiagnosticBuilder);
-}
-
-pub trait CoreEmitter {
-    fn emit_message(&mut self,
-                    rsp: &RenderSpan,
-                    msg: &str,
-                    code: Option<&str>,
-                    lvl: Level,
-                    is_header: bool,
-                    show_snippet: bool);
-}
-
-impl<T: CoreEmitter> Emitter for T {
-    fn emit(&mut self,
-            msp: &MultiSpan,
-            msg: &str,
-            code: Option<&str>,
-            lvl: Level) {
-        self.emit_message(&FullSpan(msp.clone()),
-                          msg,
-                          code,
-                          lvl,
-                          true,
-                          true);
-    }
-
-    fn emit_struct(&mut self, db: &DiagnosticBuilder) {
-        let old_school = check_old_skool();
-        let db_span = FullSpan(db.span.clone());
-        self.emit_message(&FullSpan(db.span.clone()),
-                          &db.message,
-                          db.code.as_ref().map(|s| &**s),
-                          db.level,
-                          true,
-                          true);
-        for child in &db.children {
-            let render_span = child.render_span
-                                   .clone()
-                                   .unwrap_or_else(
-                                       || FullSpan(child.span.clone()));
-
-            if !old_school {
-                self.emit_message(&render_span,
-                                    &child.message,
-                                    None,
-                                    child.level,
-                                    false,
-                                    true);
-            } else {
-                let (render_span, show_snippet) = match render_span.span().primary_span() {
-                    None => (db_span.clone(), false),
-                    _ => (render_span, true)
-                };
-                self.emit_message(&render_span,
-                                    &child.message,
-                                    None,
-                                    child.level,
-                                    false,
-                                    show_snippet);
-            }
-        }
-    }
-}
-
-/// maximum number of lines we will print for each error; arbitrary.
-pub const MAX_HIGHLIGHT_LINES: usize = 6;
-
-#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum ColorConfig {
-    Auto,
-    Always,
-    Never,
-}
-
-impl ColorConfig {
-    fn use_color(&self) -> bool {
-        match *self {
-            ColorConfig::Always => true,
-            ColorConfig::Never  => false,
-            ColorConfig::Auto   => stderr_isatty(),
-        }
-    }
-}
-
-/// A basic emitter for when we don't have access to a codemap or registry. Used
-/// for reporting very early errors, etc.
-pub struct BasicEmitter {
-    dst: Destination,
-}
-
-impl CoreEmitter for BasicEmitter {
-    fn emit_message(&mut self,
-                    _rsp: &RenderSpan,
-                    msg: &str,
-                    code: Option<&str>,
-                    lvl: Level,
-                    _is_header: bool,
-                    _show_snippet: bool) {
-        // we ignore the span as we have no access to a codemap at this point
-        if let Err(e) = print_diagnostic(&mut self.dst, "", lvl, msg, code) {
-            panic!("failed to print diagnostics: {:?}", e);
-        }
-    }
-}
-
-impl BasicEmitter {
-    pub fn stderr(color_config: ColorConfig) -> BasicEmitter {
-        if color_config.use_color() {
-            let dst = Destination::from_stderr();
-            BasicEmitter { dst: dst }
-        } else {
-            BasicEmitter { dst: Raw(Box::new(io::stderr())) }
-        }
-    }
-}
-
-pub struct EmitterWriter {
-    dst: Destination,
-    registry: Option<diagnostics::registry::Registry>,
-    cm: Rc<codemap::CodeMap>,
-
-    /// Is this the first error emitted thus far? If not, we emit a
-    /// `\n` before the top-level errors.
-    first: bool,
-
-    // For now, allow an old-school mode while we transition
-    old_school: bool,
-}
-
-impl CoreEmitter for EmitterWriter {
-    fn emit_message(&mut self,
-                    rsp: &RenderSpan,
-                    msg: &str,
-                    code: Option<&str>,
-                    lvl: Level,
-                    is_header: bool,
-                    show_snippet: bool) {
-        match self.emit_message_(rsp, msg, code, lvl, is_header, show_snippet) {
-            Ok(()) => { }
-            Err(e) => panic!("failed to emit error: {}", e)
-        }
-    }
-}
-
-/// Do not use this for messages that end in `\n` – use `println_maybe_styled` instead. See
-/// `EmitterWriter::print_maybe_styled` for details.
-macro_rules! print_maybe_styled {
-    ($dst: expr, $style: expr, $($arg: tt)*) => {
-        $dst.print_maybe_styled(format_args!($($arg)*), $style, false)
-    }
-}
-
-macro_rules! println_maybe_styled {
-    ($dst: expr, $style: expr, $($arg: tt)*) => {
-        $dst.print_maybe_styled(format_args!($($arg)*), $style, true)
-    }
-}
-
-impl EmitterWriter {
-    pub fn stderr(color_config: ColorConfig,
-                  registry: Option<diagnostics::registry::Registry>,
-                  code_map: Rc<codemap::CodeMap>)
-                  -> EmitterWriter {
-        let old_school = check_old_skool();
-        if color_config.use_color() {
-            let dst = Destination::from_stderr();
-            EmitterWriter { dst: dst,
-                            registry: registry,
-                            cm: code_map,
-                            first: true,
-                            old_school: old_school }
-        } else {
-            EmitterWriter { dst: Raw(Box::new(io::stderr())),
-                            registry: registry,
-                            cm: code_map,
-                            first: true,
-                            old_school: old_school }
-        }
-    }
-
-    pub fn new(dst: Box<Write + Send>,
-               registry: Option<diagnostics::registry::Registry>,
-               code_map: Rc<codemap::CodeMap>)
-               -> EmitterWriter {
-        let old_school = check_old_skool();
-        EmitterWriter { dst: Raw(dst),
-                        registry: registry,
-                        cm: code_map,
-                        first: true,
-                        old_school: old_school }
-    }
-
-    fn emit_message_(&mut self,
-                     rsp: &RenderSpan,
-                     msg: &str,
-                     code: Option<&str>,
-                     lvl: Level,
-                     is_header: bool,
-                     show_snippet: bool)
-                     -> io::Result<()> {
-        if is_header {
-            if self.first {
-                self.first = false;
-            } else {
-                if !self.old_school {
-                    write!(self.dst, "\n")?;
-                }
-            }
-        }
-
-        match code {
-            Some(code) if self.registry.as_ref()
-                                       .and_then(|registry| registry.find_description(code))
-                                       .is_some() => {
-                let code_with_explain = String::from("--explain ") + code;
-                if self.old_school {
-                    let loc = match rsp.span().primary_span() {
-                        Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
-                        Some(ps) => self.cm.span_to_string(ps),
-                        None => "".to_string()
-                    };
-                    print_diagnostic(&mut self.dst, &loc, lvl, msg, Some(code))?
-                }
-                else {
-                    print_diagnostic(&mut self.dst, "", lvl, msg, Some(&code_with_explain))?
-                }
-            }
-            _ => {
-                if self.old_school {
-                    let loc = match rsp.span().primary_span() {
-                        Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
-                        Some(ps) => self.cm.span_to_string(ps),
-                        None => "".to_string()
-                    };
-                    print_diagnostic(&mut self.dst, &loc, lvl, msg, code)?
-                }
-                else {
-                    print_diagnostic(&mut self.dst, "", lvl, msg, code)?
-                }
-            }
-        }
-
-        if !show_snippet {
-            return Ok(());
-        }
-
-        // Watch out for various nasty special spans; don't try to
-        // print any filename or anything for those.
-        match rsp.span().primary_span() {
-            Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => {
-                return Ok(());
-            }
-            _ => { }
-        }
-
-        // Otherwise, print out the snippet etc as needed.
-        match *rsp {
-            FullSpan(ref msp) => {
-                self.highlight_lines(msp, lvl)?;
-                if let Some(primary_span) = msp.primary_span() {
-                    self.print_macro_backtrace(primary_span)?;
-                }
-            }
-            Suggestion(ref suggestion) => {
-                self.highlight_suggestion(suggestion)?;
-                if let Some(primary_span) = rsp.span().primary_span() {
-                    self.print_macro_backtrace(primary_span)?;
-                }
-            }
-        }
-        if self.old_school {
-            match code {
-                Some(code) if self.registry.as_ref()
-                                        .and_then(|registry| registry.find_description(code))
-                                        .is_some() => {
-                    let loc = match rsp.span().primary_span() {
-                        Some(COMMAND_LINE_SP) | Some(DUMMY_SP) => "".to_string(),
-                        Some(ps) => self.cm.span_to_string(ps),
-                        None => "".to_string()
-                    };
-                    let msg = "run `rustc --explain ".to_string() + &code.to_string() +
-                        "` to see a detailed explanation";
-                    print_diagnostic(&mut self.dst, &loc, Level::Help, &msg,
-                        None)?
-                }
-                _ => ()
-            }
-        }
-        Ok(())
-    }
-
-    fn highlight_suggestion(&mut self, suggestion: &CodeSuggestion) -> io::Result<()>
-    {
-        let primary_span = suggestion.msp.primary_span().unwrap();
-        let lines = self.cm.span_to_lines(primary_span).unwrap();
-        assert!(!lines.lines.is_empty());
-
-        let complete = suggestion.splice_lines(&self.cm);
-        let line_count = cmp::min(lines.lines.len(), MAX_HIGHLIGHT_LINES);
-        let display_lines = &lines.lines[..line_count];
-
-        let fm = &*lines.file;
-        // Calculate the widest number to format evenly
-        let max_digits = line_num_max_digits(display_lines.last().unwrap());
-
-        // print the suggestion without any line numbers, but leave
-        // space for them. This helps with lining up with previous
-        // snippets from the actual error being reported.
-        let mut lines = complete.lines();
-        for line in lines.by_ref().take(MAX_HIGHLIGHT_LINES) {
-            write!(&mut self.dst, "{0}:{1:2$} {3}\n",
-                   fm.name, "", max_digits, line)?;
-        }
-
-        // if we elided some lines, add an ellipsis
-        if let Some(_) = lines.next() {
-            write!(&mut self.dst, "{0:1$} {0:2$} ...\n",
-                   "", fm.name.len(), max_digits)?;
-        }
-
-        Ok(())
-    }
-
-    fn highlight_lines(&mut self,
-                       msp: &MultiSpan,
-                       lvl: Level)
-                       -> io::Result<()>
-    {
-        let mut snippet_data = SnippetData::new(self.cm.clone(),
-                                                msp.primary_span());
-        if self.old_school {
-            let mut output_vec = vec![];
-
-            for span_label in msp.span_labels() {
-                let mut snippet_data = SnippetData::new(self.cm.clone(),
-                                                        Some(span_label.span));
-
-                snippet_data.push(span_label.span,
-                                  span_label.is_primary,
-                                  span_label.label);
-                if span_label.is_primary {
-                    output_vec.insert(0, snippet_data);
-                }
-                else {
-                    output_vec.push(snippet_data);
-                }
-            }
-
-            for snippet_data in output_vec.iter() {
-                let rendered_lines = snippet_data.render_lines();
-                for rendered_line in &rendered_lines {
-                    for styled_string in &rendered_line.text {
-                        self.dst.apply_style(lvl, &rendered_line.kind, styled_string.style)?;
-                        write!(&mut self.dst, "{}", styled_string.text)?;
-                        self.dst.reset_attrs()?;
-                    }
-                    write!(&mut self.dst, "\n")?;
-                }
-            }
-        }
-        else {
-            for span_label in msp.span_labels() {
-                snippet_data.push(span_label.span,
-                                  span_label.is_primary,
-                                  span_label.label);
-            }
-            let rendered_lines = snippet_data.render_lines();
-            for rendered_line in &rendered_lines {
-                for styled_string in &rendered_line.text {
-                    self.dst.apply_style(lvl, &rendered_line.kind, styled_string.style)?;
-                    write!(&mut self.dst, "{}", styled_string.text)?;
-                    self.dst.reset_attrs()?;
-                }
-                write!(&mut self.dst, "\n")?;
-            }
-        }
-        Ok(())
-    }
-
-    fn print_macro_backtrace(&mut self,
-                             sp: Span)
-                             -> io::Result<()> {
-        for trace in self.cm.macro_backtrace(sp) {
-            let mut diag_string =
-                format!("in this expansion of {}", trace.macro_decl_name);
-            if let Some(def_site_span) = trace.def_site_span {
-                diag_string.push_str(
-                    &format!(" (defined in {})",
-                        self.cm.span_to_filename(def_site_span)));
-            }
-            let snippet = self.cm.span_to_string(trace.call_site);
-            print_diagnostic(&mut self.dst, &snippet, Note, &diag_string, None)?;
-        }
-        Ok(())
-    }
-}
-
-fn line_num_max_digits(line: &codemap::LineInfo) -> usize {
-    let mut max_line_num = line.line_index + 1;
-    let mut digits = 0;
-    while max_line_num > 0 {
-        max_line_num /= 10;
-        digits += 1;
-    }
-    digits
-}
-
-fn print_diagnostic(dst: &mut Destination,
-                    topic: &str,
-                    lvl: Level,
-                    msg: &str,
-                    code: Option<&str>)
-                    -> io::Result<()> {
-    if !topic.is_empty() {
-        let old_school = check_old_skool();
-        if !old_school {
-            write!(dst, "{}: ", topic)?;
-        }
-        else {
-            write!(dst, "{} ", topic)?;
-        }
-        dst.reset_attrs()?;
-    }
-    dst.start_attr(term::Attr::Bold)?;
-    dst.start_attr(term::Attr::ForegroundColor(lvl.color()))?;
-    write!(dst, "{}", lvl.to_string())?;
-    dst.reset_attrs()?;
-    write!(dst, ": ")?;
-    dst.start_attr(term::Attr::Bold)?;
-    write!(dst, "{}", msg)?;
-
-    if let Some(code) = code {
-        let style = term::Attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-        print_maybe_styled!(dst, style, " [{}]", code.clone())?;
-    }
-
-    dst.reset_attrs()?;
-    write!(dst, "\n")?;
-    Ok(())
-}
-
-#[cfg(unix)]
-fn stderr_isatty() -> bool {
-    use libc;
-    unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
-}
-#[cfg(windows)]
-fn stderr_isatty() -> bool {
-    type DWORD = u32;
-    type BOOL = i32;
-    type HANDLE = *mut u8;
-    const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
-    extern "system" {
-        fn GetStdHandle(which: DWORD) -> HANDLE;
-        fn GetConsoleMode(hConsoleHandle: HANDLE,
-                          lpMode: *mut DWORD) -> BOOL;
-    }
-    unsafe {
-        let handle = GetStdHandle(STD_ERROR_HANDLE);
-        let mut out = 0;
-        GetConsoleMode(handle, &mut out) != 0
-    }
-}
-
-enum Destination {
-    Terminal(Box<term::StderrTerminal>),
-    Raw(Box<Write + Send>),
-}
-
-impl Destination {
-    fn from_stderr() -> Destination {
-        match term::stderr() {
-            Some(t) => Terminal(t),
-            None    => Raw(Box::new(io::stderr())),
-        }
-    }
-
-    fn apply_style(&mut self,
-                   lvl: Level,
-                   _kind: &RenderedLineKind,
-                   style: Style)
-                   -> io::Result<()> {
-        match style {
-            Style::FileNameStyle |
-            Style::LineAndColumn => {
-            }
-            Style::LineNumber => {
-                self.start_attr(term::Attr::Bold)?;
-                self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))?;
-            }
-            Style::Quotation => {
-            }
-            Style::OldSkoolNote => {
-                self.start_attr(term::Attr::Bold)?;
-                self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_GREEN))?;
-            }
-            Style::OldSkoolNoteText => {
-                self.start_attr(term::Attr::Bold)?;
-            }
-            Style::UnderlinePrimary | Style::LabelPrimary => {
-                self.start_attr(term::Attr::Bold)?;
-                self.start_attr(term::Attr::ForegroundColor(lvl.color()))?;
-            }
-            Style::UnderlineSecondary | Style::LabelSecondary => {
-                self.start_attr(term::Attr::Bold)?;
-                self.start_attr(term::Attr::ForegroundColor(term::color::BRIGHT_BLUE))?;
-            }
-            Style::NoStyle => {
-            }
-        }
-        Ok(())
-    }
-
-    fn start_attr(&mut self, attr: term::Attr) -> io::Result<()> {
-        match *self {
-            Terminal(ref mut t) => { t.attr(attr)?; }
-            Raw(_) => { }
-        }
-        Ok(())
-    }
-
-    fn reset_attrs(&mut self) -> io::Result<()> {
-        match *self {
-            Terminal(ref mut t) => { t.reset()?; }
-            Raw(_) => { }
-        }
-        Ok(())
-    }
-
-    fn print_maybe_styled(&mut self,
-                          args: fmt::Arguments,
-                          color: term::Attr,
-                          print_newline_at_end: bool)
-                          -> io::Result<()> {
-        match *self {
-            Terminal(ref mut t) => {
-                t.attr(color)?;
-                // If `msg` ends in a newline, we need to reset the color before
-                // the newline. We're making the assumption that we end up writing
-                // to a `LineBufferedWriter`, which means that emitting the reset
-                // after the newline ends up buffering the reset until we print
-                // another line or exit. Buffering the reset is a problem if we're
-                // sharing the terminal with any other programs (e.g. other rustc
-                // instances via `make -jN`).
-                //
-                // Note that if `msg` contains any internal newlines, this will
-                // result in the `LineBufferedWriter` flushing twice instead of
-                // once, which still leaves the opportunity for interleaved output
-                // to be miscolored. We assume this is rare enough that we don't
-                // have to worry about it.
-                t.write_fmt(args)?;
-                t.reset()?;
-                if print_newline_at_end {
-                    t.write_all(b"\n")
-                } else {
-                    Ok(())
-                }
-            }
-            Raw(ref mut w) => {
-                w.write_fmt(args)?;
-                if print_newline_at_end {
-                    w.write_all(b"\n")
-                } else {
-                    Ok(())
-                }
-            }
-        }
-    }
-}
-
-impl Write for Destination {
-    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
-        match *self {
-            Terminal(ref mut t) => t.write(bytes),
-            Raw(ref mut w) => w.write(bytes),
-        }
-    }
-    fn flush(&mut self) -> io::Result<()> {
-        match *self {
-            Terminal(ref mut t) => t.flush(),
-            Raw(ref mut w) => w.flush(),
-        }
-    }
-}
-
-
-#[cfg(test)]
-mod test {
-    use errors::{Level, CodeSuggestion};
-    use super::EmitterWriter;
-    use codemap::{mk_sp, CodeMap, Span, MultiSpan, BytePos, NO_EXPANSION};
-    use std::sync::{Arc, Mutex};
-    use std::io::{self, Write};
-    use std::str::from_utf8;
-    use std::rc::Rc;
-
-    struct Sink(Arc<Mutex<Vec<u8>>>);
-    impl Write for Sink {
-        fn write(&mut self, data: &[u8]) -> io::Result<usize> {
-            Write::write(&mut *self.0.lock().unwrap(), data)
-        }
-        fn flush(&mut self) -> io::Result<()> { Ok(()) }
-    }
-
-    /// Given a string like " ^~~~~~~~~~~~ ", produces a span
-    /// coverting that range. The idea is that the string has the same
-    /// length as the input, and we uncover the byte positions.  Note
-    /// that this can span lines and so on.
-    fn span_from_selection(input: &str, selection: &str) -> Span {
-        assert_eq!(input.len(), selection.len());
-        let left_index = selection.find('~').unwrap() as u32;
-        let right_index = selection.rfind('~').map(|x|x as u32).unwrap_or(left_index);
-        Span { lo: BytePos(left_index), hi: BytePos(right_index + 1), expn_id: NO_EXPANSION }
-    }
-
-    // Diagnostic doesn't align properly in span where line number increases by one digit
-    #[test]
-    fn test_hilight_suggestion_issue_11715() {
-        let data = Arc::new(Mutex::new(Vec::new()));
-        let cm = Rc::new(CodeMap::new());
-        let mut ew = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
-        let content = "abcdefg
-        koksi
-        line3
-        line4
-        cinq
-        line6
-        line7
-        line8
-        line9
-        line10
-        e-lä-vän
-        tolv
-        dreizehn
-        ";
-        let file = cm.new_filemap_and_lines("dummy.txt", None, content);
-        let start = file.lines.borrow()[10];
-        let end = file.lines.borrow()[11];
-        let sp = mk_sp(start, end);
-        let lvl = Level::Error;
-        println!("highlight_lines");
-        ew.highlight_lines(&sp.into(), lvl).unwrap();
-        println!("done");
-        let vec = data.lock().unwrap().clone();
-        let vec: &[u8] = &vec;
-        let str = from_utf8(vec).unwrap();
-        println!("r#\"\n{}\"#", str);
-        assert_eq!(str, &r#"
-  --> dummy.txt:11:1
-   |>
-11 |>         e-lä-vän
-   |> ^
-"#[1..]);
-    }
-
-    #[test]
-    fn test_single_span_splice() {
-        // Test that a `MultiSpan` containing a single span splices a substition correctly
-        let cm = CodeMap::new();
-        let inputtext = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
-        let selection = "     \n    ~~\n~~~\n~~~~~     \n   \n";
-        cm.new_filemap_and_lines("blork.rs", None, inputtext);
-        let sp = span_from_selection(inputtext, selection);
-        let msp: MultiSpan = sp.into();
-
-        // check that we are extracting the text we thought we were extracting
-        assert_eq!(&cm.span_to_snippet(sp).unwrap(), "BB\nCCC\nDDDDD");
-
-        let substitute = "ZZZZZZ".to_owned();
-        let expected = "bbbbZZZZZZddddd";
-        let suggest = CodeSuggestion {
-            msp: msp,
-            substitutes: vec![substitute],
-        };
-        assert_eq!(suggest.splice_lines(&cm), expected);
-    }
-
-    #[test]
-    fn test_multi_span_splice() {
-        // Test that a `MultiSpan` containing multiple spans splices a substition correctly
-        let cm = CodeMap::new();
-        let inputtext  = "aaaaa\nbbbbBB\nCCC\nDDDDDddddd\neee\n";
-        let selection1 = "     \n      \n   \n          \n ~ \n"; // intentionally out of order
-        let selection2 = "     \n    ~~\n~~~\n~~~~~     \n   \n";
-        cm.new_filemap_and_lines("blork.rs", None, inputtext);
-        let sp1 = span_from_selection(inputtext, selection1);
-        let sp2 = span_from_selection(inputtext, selection2);
-        let msp: MultiSpan = MultiSpan::from_spans(vec![sp1, sp2]);
-
-        let expected = "bbbbZZZZZZddddd\neXYZe";
-        let suggest = CodeSuggestion {
-            msp: msp,
-            substitutes: vec!["ZZZZZZ".to_owned(),
-                              "XYZ".to_owned()]
-        };
-
-        assert_eq!(suggest.splice_lines(&cm), expected);
-    }
-
-    #[test]
-    fn test_multispan_highlight() {
-        let data = Arc::new(Mutex::new(Vec::new()));
-        let cm = Rc::new(CodeMap::new());
-        let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
-
-        let inp =       "_____aaaaaa____bbbbbb__cccccdd_";
-        let sp1 =       "     ~~~~~~                    ";
-        let sp2 =       "               ~~~~~~          ";
-        let sp3 =       "                       ~~~~~   ";
-        let sp4 =       "                          ~~~~ ";
-        let sp34 =      "                       ~~~~~~~ ";
-
-        let expect_start = &r#"
- --> dummy.txt:1:6
-  |>
-1 |> _____aaaaaa____bbbbbb__cccccdd_
-  |>      ^^^^^^    ^^^^^^  ^^^^^^^
-"#[1..];
-
-        let span = |sp, expected| {
-            let sp = span_from_selection(inp, sp);
-            assert_eq!(&cm.span_to_snippet(sp).unwrap(), expected);
-            sp
-        };
-        cm.new_filemap_and_lines("dummy.txt", None, inp);
-        let sp1 = span(sp1, "aaaaaa");
-        let sp2 = span(sp2, "bbbbbb");
-        let sp3 = span(sp3, "ccccc");
-        let sp4 = span(sp4, "ccdd");
-        let sp34 = span(sp34, "cccccdd");
-
-        let spans = vec![sp1, sp2, sp3, sp4];
-
-        let test = |expected, highlight: &mut FnMut()| {
-            data.lock().unwrap().clear();
-            highlight();
-            let vec = data.lock().unwrap().clone();
-            let actual = from_utf8(&vec[..]).unwrap();
-            println!("actual=\n{}", actual);
-            assert_eq!(actual, expected);
-        };
-
-        let msp = MultiSpan::from_spans(vec![sp1, sp2, sp34]);
-        test(expect_start, &mut || {
-            diag.highlight_lines(&msp, Level::Error).unwrap();
-        });
-        test(expect_start, &mut || {
-            let msp = MultiSpan::from_spans(spans.clone());
-            diag.highlight_lines(&msp, Level::Error).unwrap();
-        });
-    }
-
-    #[test]
-    fn test_huge_multispan_highlight() {
-        let data = Arc::new(Mutex::new(Vec::new()));
-        let cm = Rc::new(CodeMap::new());
-        let mut diag = EmitterWriter::new(Box::new(Sink(data.clone())), None, cm.clone());
-
-        let inp = "aaaaa\n\
-                   aaaaa\n\
-                   aaaaa\n\
-                   bbbbb\n\
-                   ccccc\n\
-                   xxxxx\n\
-                   yyyyy\n\
-                   _____\n\
-                   ddd__eee_\n\
-                   elided\n\
-                   __f_gg";
-        let file = cm.new_filemap_and_lines("dummy.txt", None, inp);
-
-        let span = |lo, hi, (off_lo, off_hi)| {
-            let lines = file.lines.borrow();
-            let (mut lo, mut hi): (BytePos, BytePos) = (lines[lo], lines[hi]);
-            lo.0 += off_lo;
-            hi.0 += off_hi;
-            mk_sp(lo, hi)
-        };
-        let sp0 = span(4, 6, (0, 5));
-        let sp1 = span(0, 6, (0, 5));
-        let sp2 = span(8, 8, (0, 3));
-        let sp3 = span(8, 8, (5, 8));
-        let sp4 = span(10, 10, (2, 3));
-        let sp5 = span(10, 10, (4, 6));
-
-        let expect0 = &r#"
-   --> dummy.txt:5:1
-    |>
-5   |> ccccc
-    |> ^
-...
-9   |> ddd__eee_
-    |> ^^^  ^^^
-10  |> elided
-11  |> __f_gg
-    |>   ^ ^^
-"#[1..];
-
-        let expect = &r#"
-   --> dummy.txt:1:1
-    |>
-1   |> aaaaa
-    |> ^
-...
-9   |> ddd__eee_
-    |> ^^^  ^^^
-10  |> elided
-11  |> __f_gg
-    |>   ^ ^^
-"#[1..];
-
-        macro_rules! test {
-            ($expected: expr, $highlight: expr) => ({
-                data.lock().unwrap().clear();
-                $highlight();
-                let vec = data.lock().unwrap().clone();
-                let actual = from_utf8(&vec[..]).unwrap();
-                println!("actual:");
-                println!("{}", actual);
-                println!("expected:");
-                println!("{}", $expected);
-                assert_eq!(&actual[..], &$expected[..]);
-            });
-        }
-
-        let msp0 = MultiSpan::from_spans(vec![sp0, sp2, sp3, sp4, sp5]);
-        let msp = MultiSpan::from_spans(vec![sp1, sp2, sp3, sp4, sp5]);
-
-        test!(expect0, || {
-            diag.highlight_lines(&msp0, Level::Error).unwrap();
-        });
-        test!(expect, || {
-            diag.highlight_lines(&msp, Level::Error).unwrap();
-        });
-    }
-}
diff --git a/src/libsyntax/errors/json.rs b/src/libsyntax/errors/json.rs
deleted file mode 100644
index 93c6268ccae..00000000000
--- a/src/libsyntax/errors/json.rs
+++ /dev/null
@@ -1,367 +0,0 @@
-// Copyright 2012-2015 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.
-
-//! A JSON emitter for errors.
-//!
-//! This works by converting errors to a simplified structural format (see the
-//! structs at the start of the file) and then serialising them. These should
-//! contain as much information about the error as possible.
-//!
-//! The format of the JSON output should be considered *unstable*. For now the
-//! structs at the end of this file (Diagnostic*) specify the error format.
-
-// FIXME spec the JSON output properly.
-
-
-use codemap::{self, MacroBacktrace, Span, SpanLabel, MultiSpan, CodeMap};
-use diagnostics::registry::Registry;
-use errors::{Level, DiagnosticBuilder, SubDiagnostic, RenderSpan, CodeSuggestion};
-use errors::emitter::Emitter;
-
-use std::rc::Rc;
-use std::io::{self, Write};
-use std::vec;
-
-use rustc_serialize::json::as_json;
-
-pub struct JsonEmitter {
-    dst: Box<Write + Send>,
-    registry: Option<Registry>,
-    cm: Rc<CodeMap>,
-}
-
-impl JsonEmitter {
-    pub fn basic() -> JsonEmitter {
-        JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
-    }
-
-    pub fn stderr(registry: Option<Registry>,
-                  code_map: Rc<CodeMap>) -> JsonEmitter {
-        JsonEmitter {
-            dst: Box::new(io::stderr()),
-            registry: registry,
-            cm: code_map,
-        }
-    }
-}
-
-impl Emitter for JsonEmitter {
-    fn emit(&mut self, span: &MultiSpan, msg: &str, code: Option<&str>, level: Level) {
-        let data = Diagnostic::new(span, msg, code, level, self);
-        if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
-            panic!("failed to print diagnostics: {:?}", e);
-        }
-    }
-
-    fn emit_struct(&mut self, db: &DiagnosticBuilder) {
-        let data = Diagnostic::from_diagnostic_builder(db, self);
-        if let Err(e) = writeln!(&mut self.dst, "{}", as_json(&data)) {
-            panic!("failed to print diagnostics: {:?}", e);
-        }
-    }
-}
-
-// The following data types are provided just for serialisation.
-
-#[derive(RustcEncodable)]
-struct Diagnostic<'a> {
-    /// The primary error message.
-    message: &'a str,
-    code: Option<DiagnosticCode>,
-    /// "error: internal compiler error", "error", "warning", "note", "help".
-    level: &'static str,
-    spans: Vec<DiagnosticSpan>,
-    /// Associated diagnostic messages.
-    children: Vec<Diagnostic<'a>>,
-    /// The message as rustc would render it. Currently this is only
-    /// `Some` for "suggestions", but eventually it will include all
-    /// snippets.
-    rendered: Option<String>,
-}
-
-#[derive(RustcEncodable)]
-struct DiagnosticSpan {
-    file_name: String,
-    byte_start: u32,
-    byte_end: u32,
-    /// 1-based.
-    line_start: usize,
-    line_end: usize,
-    /// 1-based, character offset.
-    column_start: usize,
-    column_end: usize,
-    /// Is this a "primary" span -- meaning the point, or one of the points,
-    /// where the error occurred?
-    is_primary: bool,
-    /// Source text from the start of line_start to the end of line_end.
-    text: Vec<DiagnosticSpanLine>,
-    /// Label that should be placed at this location (if any)
-    label: Option<String>,
-    /// If we are suggesting a replacement, this will contain text
-    /// that should be sliced in atop this span. You may prefer to
-    /// load the fully rendered version from the parent `Diagnostic`,
-    /// however.
-    suggested_replacement: Option<String>,
-    /// Macro invocations that created the code at this span, if any.
-    expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
-}
-
-#[derive(RustcEncodable)]
-struct DiagnosticSpanLine {
-    text: String,
-
-    /// 1-based, character offset in self.text.
-    highlight_start: usize,
-
-    highlight_end: usize,
-}
-
-#[derive(RustcEncodable)]
-struct DiagnosticSpanMacroExpansion {
-    /// span where macro was applied to generate this code; note that
-    /// this may itself derive from a macro (if
-    /// `span.expansion.is_some()`)
-    span: DiagnosticSpan,
-
-    /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]")
-    macro_decl_name: String,
-
-    /// span where macro was defined (if known)
-    def_site_span: Option<DiagnosticSpan>,
-}
-
-#[derive(RustcEncodable)]
-struct DiagnosticCode {
-    /// The code itself.
-    code: String,
-    /// An explanation for the code.
-    explanation: Option<&'static str>,
-}
-
-impl<'a> Diagnostic<'a> {
-    fn new(msp: &MultiSpan,
-           msg: &'a str,
-           code: Option<&str>,
-           level: Level,
-           je: &JsonEmitter)
-           -> Diagnostic<'a> {
-        Diagnostic {
-            message: msg,
-            code: DiagnosticCode::map_opt_string(code.map(|c| c.to_owned()), je),
-            level: level.to_str(),
-            spans: DiagnosticSpan::from_multispan(msp, je),
-            children: vec![],
-            rendered: None,
-        }
-    }
-
-    fn from_diagnostic_builder<'c>(db: &'c DiagnosticBuilder,
-                                   je: &JsonEmitter)
-                                   -> Diagnostic<'c> {
-        Diagnostic {
-            message: &db.message,
-            code: DiagnosticCode::map_opt_string(db.code.clone(), je),
-            level: db.level.to_str(),
-            spans: DiagnosticSpan::from_multispan(&db.span, je),
-            children: db.children.iter().map(|c| {
-                Diagnostic::from_sub_diagnostic(c, je)
-            }).collect(),
-            rendered: None,
-        }
-    }
-
-    fn from_sub_diagnostic<'c>(db: &'c SubDiagnostic, je: &JsonEmitter) -> Diagnostic<'c> {
-        Diagnostic {
-            message: &db.message,
-            code: None,
-            level: db.level.to_str(),
-            spans: db.render_span.as_ref()
-                     .map(|sp| DiagnosticSpan::from_render_span(sp, je))
-                     .unwrap_or_else(|| DiagnosticSpan::from_multispan(&db.span, je)),
-            children: vec![],
-            rendered: db.render_span.as_ref()
-                                    .and_then(|rsp| je.render(rsp)),
-        }
-    }
-}
-
-impl DiagnosticSpan {
-    fn from_span_label(span: SpanLabel,
-                       suggestion: Option<&String>,
-                       je: &JsonEmitter)
-                       -> DiagnosticSpan {
-        Self::from_span_etc(span.span,
-                            span.is_primary,
-                            span.label,
-                            suggestion,
-                            je)
-    }
-
-    fn from_span_etc(span: Span,
-                     is_primary: bool,
-                     label: Option<String>,
-                     suggestion: Option<&String>,
-                     je: &JsonEmitter)
-                     -> DiagnosticSpan {
-        // obtain the full backtrace from the `macro_backtrace`
-        // helper; in some ways, it'd be better to expand the
-        // backtrace ourselves, but the `macro_backtrace` helper makes
-        // some decision, such as dropping some frames, and I don't
-        // want to duplicate that logic here.
-        let backtrace = je.cm.macro_backtrace(span).into_iter();
-        DiagnosticSpan::from_span_full(span,
-                                       is_primary,
-                                       label,
-                                       suggestion,
-                                       backtrace,
-                                       je)
-    }
-
-    fn from_span_full(span: Span,
-                      is_primary: bool,
-                      label: Option<String>,
-                      suggestion: Option<&String>,
-                      mut backtrace: vec::IntoIter<MacroBacktrace>,
-                      je: &JsonEmitter)
-                      -> DiagnosticSpan {
-        let start = je.cm.lookup_char_pos(span.lo);
-        let end = je.cm.lookup_char_pos(span.hi);
-        let backtrace_step = backtrace.next().map(|bt| {
-            let call_site =
-                Self::from_span_full(bt.call_site,
-                                     false,
-                                     None,
-                                     None,
-                                     backtrace,
-                                     je);
-            let def_site_span = bt.def_site_span.map(|sp| {
-                Self::from_span_full(sp,
-                                     false,
-                                     None,
-                                     None,
-                                     vec![].into_iter(),
-                                     je)
-            });
-            Box::new(DiagnosticSpanMacroExpansion {
-                span: call_site,
-                macro_decl_name: bt.macro_decl_name,
-                def_site_span: def_site_span,
-            })
-        });
-        DiagnosticSpan {
-            file_name: start.file.name.clone(),
-            byte_start: span.lo.0,
-            byte_end: span.hi.0,
-            line_start: start.line,
-            line_end: end.line,
-            column_start: start.col.0 + 1,
-            column_end: end.col.0 + 1,
-            is_primary: is_primary,
-            text: DiagnosticSpanLine::from_span(span, je),
-            suggested_replacement: suggestion.cloned(),
-            expansion: backtrace_step,
-            label: label,
-        }
-    }
-
-    fn from_multispan(msp: &MultiSpan, je: &JsonEmitter) -> Vec<DiagnosticSpan> {
-        msp.span_labels()
-           .into_iter()
-           .map(|span_str| Self::from_span_label(span_str, None, je))
-           .collect()
-    }
-
-    fn from_suggestion(suggestion: &CodeSuggestion, je: &JsonEmitter)
-                       -> Vec<DiagnosticSpan> {
-        assert_eq!(suggestion.msp.span_labels().len(), suggestion.substitutes.len());
-        suggestion.msp.span_labels()
-                      .into_iter()
-                      .zip(&suggestion.substitutes)
-                      .map(|(span_label, suggestion)| {
-                          DiagnosticSpan::from_span_label(span_label,
-                                                          Some(suggestion),
-                                                          je)
-                      })
-                      .collect()
-    }
-
-    fn from_render_span(rsp: &RenderSpan, je: &JsonEmitter) -> Vec<DiagnosticSpan> {
-        match *rsp {
-            RenderSpan::FullSpan(ref msp) =>
-                DiagnosticSpan::from_multispan(msp, je),
-            RenderSpan::Suggestion(ref suggestion) =>
-                DiagnosticSpan::from_suggestion(suggestion, je),
-        }
-    }
-}
-
-impl DiagnosticSpanLine {
-    fn line_from_filemap(fm: &codemap::FileMap,
-                         index: usize,
-                         h_start: usize,
-                         h_end: usize)
-                         -> DiagnosticSpanLine {
-        DiagnosticSpanLine {
-            text: fm.get_line(index).unwrap().to_owned(),
-            highlight_start: h_start,
-            highlight_end: h_end,
-        }
-    }
-
-    /// Create a list of DiagnosticSpanLines from span - each line with any part
-    /// of `span` gets a DiagnosticSpanLine, with the highlight indicating the
-    /// `span` within the line.
-    fn from_span(span: Span, je: &JsonEmitter) -> Vec<DiagnosticSpanLine> {
-        je.cm.span_to_lines(span)
-             .map(|lines| {
-                 let fm = &*lines.file;
-                 lines.lines
-                      .iter()
-                      .map(|line| {
-                          DiagnosticSpanLine::line_from_filemap(fm,
-                                                                line.line_index,
-                                                                line.start_col.0 + 1,
-                                                                line.end_col.0 + 1)
-                      })
-                     .collect()
-             })
-            .unwrap_or(vec![])
-    }
-}
-
-impl DiagnosticCode {
-    fn map_opt_string(s: Option<String>, je: &JsonEmitter) -> Option<DiagnosticCode> {
-        s.map(|s| {
-
-            let explanation = je.registry
-                                .as_ref()
-                                .and_then(|registry| registry.find_description(&s));
-
-            DiagnosticCode {
-                code: s,
-                explanation: explanation,
-            }
-        })
-    }
-}
-
-impl JsonEmitter {
-    fn render(&self, render_span: &RenderSpan) -> Option<String> {
-        match *render_span {
-            RenderSpan::FullSpan(_) => {
-                None
-            }
-            RenderSpan::Suggestion(ref suggestion) => {
-                Some(suggestion.splice_lines(&self.cm))
-            }
-        }
-    }
-}
-
diff --git a/src/libsyntax/errors/mod.rs b/src/libsyntax/errors/mod.rs
deleted file mode 100644
index f06672fe111..00000000000
--- a/src/libsyntax/errors/mod.rs
+++ /dev/null
@@ -1,711 +0,0 @@
-// Copyright 2012-2015 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.
-
-pub use errors::emitter::ColorConfig;
-
-use self::Level::*;
-use self::RenderSpan::*;
-
-use codemap::{self, CodeMap, MultiSpan, NO_EXPANSION, Span};
-use diagnostics;
-use errors::emitter::{Emitter, EmitterWriter};
-
-use std::cell::{RefCell, Cell};
-use std::{error, fmt};
-use std::rc::Rc;
-use std::thread::panicking;
-use term;
-
-pub mod emitter;
-pub mod json;
-pub mod snippet;
-
-#[derive(Clone)]
-pub enum RenderSpan {
-    /// A FullSpan renders with both with an initial line for the
-    /// message, prefixed by file:linenum, followed by a summary of
-    /// the source code covered by the span.
-    FullSpan(MultiSpan),
-
-    /// A suggestion renders with both with an initial line for the
-    /// message, prefixed by file:linenum, followed by a summary
-    /// of hypothetical source code, where each `String` is spliced
-    /// into the lines in place of the code covered by each span.
-    Suggestion(CodeSuggestion),
-}
-
-#[derive(Clone)]
-pub struct CodeSuggestion {
-    msp: MultiSpan,
-    substitutes: Vec<String>,
-}
-
-impl RenderSpan {
-    fn span(&self) -> &MultiSpan {
-        match *self {
-            FullSpan(ref msp) |
-            Suggestion(CodeSuggestion { ref msp, .. }) =>
-                msp
-        }
-    }
-}
-
-impl CodeSuggestion {
-    /// Returns the assembled code suggestion.
-    pub fn splice_lines(&self, cm: &CodeMap) -> String {
-        use codemap::{CharPos, Loc, Pos};
-
-        fn push_trailing(buf: &mut String, line_opt: Option<&str>,
-                         lo: &Loc, hi_opt: Option<&Loc>) {
-            let (lo, hi_opt) = (lo.col.to_usize(), hi_opt.map(|hi|hi.col.to_usize()));
-            if let Some(line) = line_opt {
-                if line.len() > lo {
-                    buf.push_str(match hi_opt {
-                        Some(hi) => &line[lo..hi],
-                        None => &line[lo..],
-                    });
-                }
-                if let None = hi_opt {
-                    buf.push('\n');
-                }
-            }
-        }
-
-        let mut primary_spans = self.msp.primary_spans().to_owned();
-
-        assert_eq!(primary_spans.len(), self.substitutes.len());
-        if primary_spans.is_empty() {
-            return format!("");
-        }
-
-        // Assumption: all spans are in the same file, and all spans
-        // are disjoint. Sort in ascending order.
-        primary_spans.sort_by_key(|sp| sp.lo);
-
-        // Find the bounding span.
-        let lo = primary_spans.iter().map(|sp| sp.lo).min().unwrap();
-        let hi = primary_spans.iter().map(|sp| sp.hi).min().unwrap();
-        let bounding_span = Span { lo: lo, hi: hi, expn_id: NO_EXPANSION };
-        let lines = cm.span_to_lines(bounding_span).unwrap();
-        assert!(!lines.lines.is_empty());
-
-        // To build up the result, we do this for each span:
-        // - push the line segment trailing the previous span
-        //   (at the beginning a "phantom" span pointing at the start of the line)
-        // - push lines between the previous and current span (if any)
-        // - if the previous and current span are not on the same line
-        //   push the line segment leading up to the current span
-        // - splice in the span substitution
-        //
-        // Finally push the trailing line segment of the last span
-        let fm = &lines.file;
-        let mut prev_hi = cm.lookup_char_pos(bounding_span.lo);
-        prev_hi.col = CharPos::from_usize(0);
-
-        let mut prev_line = fm.get_line(lines.lines[0].line_index);
-        let mut buf = String::new();
-
-        for (sp, substitute) in primary_spans.iter().zip(self.substitutes.iter()) {
-            let cur_lo = cm.lookup_char_pos(sp.lo);
-            if prev_hi.line == cur_lo.line {
-                push_trailing(&mut buf, prev_line, &prev_hi, Some(&cur_lo));
-            } else {
-                push_trailing(&mut buf, prev_line, &prev_hi, None);
-                // push lines between the previous and current span (if any)
-                for idx in prev_hi.line..(cur_lo.line - 1) {
-                    if let Some(line) = fm.get_line(idx) {
-                        buf.push_str(line);
-                        buf.push('\n');
-                    }
-                }
-                if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
-                    buf.push_str(&cur_line[.. cur_lo.col.to_usize()]);
-                }
-            }
-            buf.push_str(substitute);
-            prev_hi = cm.lookup_char_pos(sp.hi);
-            prev_line = fm.get_line(prev_hi.line - 1);
-        }
-        push_trailing(&mut buf, prev_line, &prev_hi, None);
-        // remove trailing newline
-        buf.pop();
-        buf
-    }
-}
-
-/// Used as a return value to signify a fatal error occurred. (It is also
-/// used as the argument to panic at the moment, but that will eventually
-/// not be true.)
-#[derive(Copy, Clone, Debug)]
-#[must_use]
-pub struct FatalError;
-
-impl fmt::Display for FatalError {
-    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(f, "parser fatal error")
-    }
-}
-
-impl error::Error for FatalError {
-    fn description(&self) -> &str {
-        "The parser has encountered a fatal error"
-    }
-}
-
-/// Signifies that the compiler died with an explicit call to `.bug`
-/// or `.span_bug` rather than a failed assertion, etc.
-#[derive(Copy, Clone, Debug)]
-pub struct ExplicitBug;
-
-impl fmt::Display for ExplicitBug {
-    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        write!(f, "parser internal bug")
-    }
-}
-
-impl error::Error for ExplicitBug {
-    fn description(&self) -> &str {
-        "The parser has encountered an internal bug"
-    }
-}
-
-/// Used for emitting structured error messages and other diagnostic information.
-#[must_use]
-#[derive(Clone)]
-pub struct DiagnosticBuilder<'a> {
-    handler: &'a Handler,
-    level: Level,
-    message: String,
-    code: Option<String>,
-    span: MultiSpan,
-    children: Vec<SubDiagnostic>,
-}
-
-/// For example a note attached to an error.
-#[derive(Clone)]
-struct SubDiagnostic {
-    level: Level,
-    message: String,
-    span: MultiSpan,
-    render_span: Option<RenderSpan>,
-}
-
-impl<'a> DiagnosticBuilder<'a> {
-    /// Emit the diagnostic.
-    pub fn emit(&mut self) {
-        if self.cancelled() {
-            return;
-        }
-
-        self.handler.emit.borrow_mut().emit_struct(&self);
-        self.cancel();
-        self.handler.panic_if_treat_err_as_bug();
-
-        // if self.is_fatal() {
-        //     panic!(FatalError);
-        // }
-    }
-
-    /// Cancel the diagnostic (a structured diagnostic must either be emitted or
-    /// cancelled or it will panic when dropped).
-    /// BEWARE: if this DiagnosticBuilder is an error, then creating it will
-    /// bump the error count on the Handler and cancelling it won't undo that.
-    /// If you want to decrement the error count you should use `Handler::cancel`.
-    pub fn cancel(&mut self) {
-        self.level = Level::Cancelled;
-    }
-
-    pub fn cancelled(&self) -> bool {
-        self.level == Level::Cancelled
-    }
-
-    pub fn is_fatal(&self) -> bool {
-        self.level == Level::Fatal
-    }
-
-    /// Add a span/label to be included in the resulting snippet.
-    /// This is pushed onto the `MultiSpan` that was created when the
-    /// diagnostic was first built. If you don't call this function at
-    /// all, and you just supplied a `Span` to create the diagnostic,
-    /// then the snippet will just include that `Span`, which is
-    /// called the primary span.
-    pub fn span_label(&mut self, span: Span, label: &fmt::Display)
-                      -> &mut DiagnosticBuilder<'a> {
-        self.span.push_span_label(span, format!("{}", label));
-        self
-    }
-
-    pub fn note_expected_found(&mut self,
-                               label: &fmt::Display,
-                               expected: &fmt::Display,
-                               found: &fmt::Display)
-                               -> &mut DiagnosticBuilder<'a>
-    {
-        // For now, just attach these as notes
-        self.note(&format!("expected {} `{}`", label, expected));
-        self.note(&format!("   found {} `{}`", label, found));
-        self
-    }
-
-    pub fn note(&mut self, msg: &str) -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Note, msg, MultiSpan::new(), None);
-        self
-    }
-    pub fn span_note<S: Into<MultiSpan>>(&mut self,
-                                         sp: S,
-                                         msg: &str)
-                                         -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Note, msg, sp.into(), None);
-        self
-    }
-    pub fn warn(&mut self, msg: &str) -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Warning, msg, MultiSpan::new(), None);
-        self
-    }
-    pub fn span_warn<S: Into<MultiSpan>>(&mut self,
-                                         sp: S,
-                                         msg: &str)
-                                         -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Warning, msg, sp.into(), None);
-        self
-    }
-    pub fn help(&mut self , msg: &str) -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Help, msg, MultiSpan::new(), None);
-        self
-    }
-    pub fn span_help<S: Into<MultiSpan>>(&mut self,
-                                         sp: S,
-                                         msg: &str)
-                                         -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Help, msg, sp.into(), None);
-        self
-    }
-    /// Prints out a message with a suggested edit of the code.
-    ///
-    /// See `diagnostic::RenderSpan::Suggestion` for more information.
-    pub fn span_suggestion<S: Into<MultiSpan>>(&mut self,
-                                               sp: S,
-                                               msg: &str,
-                                               suggestion: String)
-                                               -> &mut DiagnosticBuilder<'a> {
-        self.sub(Level::Help, msg, MultiSpan::new(), Some(Suggestion(CodeSuggestion {
-            msp: sp.into(),
-            substitutes: vec![suggestion],
-        })));
-        self
-    }
-
-    pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
-        self.span = sp.into();
-        self
-    }
-
-    pub fn code(&mut self, s: String) -> &mut Self {
-        self.code = Some(s);
-        self
-    }
-
-    pub fn message(&self) -> &str {
-        &self.message
-    }
-
-    pub fn level(&self) -> Level {
-        self.level
-    }
-
-    /// Convenience function for internal use, clients should use one of the
-    /// struct_* methods on Handler.
-    fn new(handler: &'a Handler,
-           level: Level,
-           message: &str) -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder {
-            handler: handler,
-            level: level,
-            message: message.to_owned(),
-            code: None,
-            span: MultiSpan::new(),
-            children: vec![],
-        }
-    }
-
-    /// Convenience function for internal use, clients should use one of the
-    /// public methods above.
-    fn sub(&mut self,
-           level: Level,
-           message: &str,
-           span: MultiSpan,
-           render_span: Option<RenderSpan>) {
-        let sub = SubDiagnostic {
-            level: level,
-            message: message.to_owned(),
-            span: span,
-            render_span: render_span,
-        };
-        self.children.push(sub);
-    }
-}
-
-impl<'a> fmt::Debug for DiagnosticBuilder<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.message.fmt(f)
-    }
-}
-
-/// Destructor bomb - a DiagnosticBuilder must be either emitted or cancelled or
-/// we emit a bug.
-impl<'a> Drop for DiagnosticBuilder<'a> {
-    fn drop(&mut self) {
-        if !panicking() && !self.cancelled() {
-            self.handler.emit.borrow_mut().emit(&MultiSpan::new(),
-                                                "Error constructed but not emitted",
-                                                None,
-                                                Bug);
-            panic!();
-        }
-    }
-}
-
-/// A handler deals with errors; certain errors
-/// (fatal, bug, unimpl) may cause immediate exit,
-/// others log errors for later reporting.
-pub struct Handler {
-    err_count: Cell<usize>,
-    emit: RefCell<Box<Emitter>>,
-    pub can_emit_warnings: bool,
-    treat_err_as_bug: bool,
-    continue_after_error: Cell<bool>,
-    delayed_span_bug: RefCell<Option<(MultiSpan, String)>>,
-}
-
-impl Handler {
-    pub fn with_tty_emitter(color_config: ColorConfig,
-                            registry: Option<diagnostics::registry::Registry>,
-                            can_emit_warnings: bool,
-                            treat_err_as_bug: bool,
-                            cm: Rc<codemap::CodeMap>)
-                            -> Handler {
-        let emitter = Box::new(EmitterWriter::stderr(color_config, registry, cm));
-        Handler::with_emitter(can_emit_warnings, treat_err_as_bug, emitter)
-    }
-
-    pub fn with_emitter(can_emit_warnings: bool,
-                        treat_err_as_bug: bool,
-                        e: Box<Emitter>) -> Handler {
-        Handler {
-            err_count: Cell::new(0),
-            emit: RefCell::new(e),
-            can_emit_warnings: can_emit_warnings,
-            treat_err_as_bug: treat_err_as_bug,
-            continue_after_error: Cell::new(true),
-            delayed_span_bug: RefCell::new(None),
-        }
-    }
-
-    pub fn set_continue_after_error(&self, continue_after_error: bool) {
-        self.continue_after_error.set(continue_after_error);
-    }
-
-    pub fn struct_dummy<'a>(&'a self) -> DiagnosticBuilder<'a> {
-        DiagnosticBuilder::new(self, Level::Cancelled, "")
-    }
-
-    pub fn struct_span_warn<'a, S: Into<MultiSpan>>(&'a self,
-                                                    sp: S,
-                                                    msg: &str)
-                                                    -> DiagnosticBuilder<'a> {
-        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
-        result.set_span(sp);
-        if !self.can_emit_warnings {
-            result.cancel();
-        }
-        result
-    }
-    pub fn struct_span_warn_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                              sp: S,
-                                                              msg: &str,
-                                                              code: &str)
-                                                              -> DiagnosticBuilder<'a> {
-        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
-        result.set_span(sp);
-        result.code(code.to_owned());
-        if !self.can_emit_warnings {
-            result.cancel();
-        }
-        result
-    }
-    pub fn struct_warn<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
-        let mut result = DiagnosticBuilder::new(self, Level::Warning, msg);
-        if !self.can_emit_warnings {
-            result.cancel();
-        }
-        result
-    }
-    pub fn struct_span_err<'a, S: Into<MultiSpan>>(&'a self,
-                                                   sp: S,
-                                                   msg: &str)
-                                                   -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
-        result.set_span(sp);
-        result
-    }
-    pub fn struct_span_err_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                             sp: S,
-                                                             msg: &str,
-                                                             code: &str)
-                                                             -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        let mut result = DiagnosticBuilder::new(self, Level::Error, msg);
-        result.set_span(sp);
-        result.code(code.to_owned());
-        result
-    }
-    pub fn struct_err<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        DiagnosticBuilder::new(self, Level::Error, msg)
-    }
-    pub fn struct_span_fatal<'a, S: Into<MultiSpan>>(&'a self,
-                                                     sp: S,
-                                                     msg: &str)
-                                                     -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
-        result.set_span(sp);
-        result
-    }
-    pub fn struct_span_fatal_with_code<'a, S: Into<MultiSpan>>(&'a self,
-                                                               sp: S,
-                                                               msg: &str,
-                                                               code: &str)
-                                                               -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        let mut result = DiagnosticBuilder::new(self, Level::Fatal, msg);
-        result.set_span(sp);
-        result.code(code.to_owned());
-        result
-    }
-    pub fn struct_fatal<'a>(&'a self, msg: &str) -> DiagnosticBuilder<'a> {
-        self.bump_err_count();
-        DiagnosticBuilder::new(self, Level::Fatal, msg)
-    }
-
-    pub fn cancel(&mut self, err: &mut DiagnosticBuilder) {
-        if err.level == Level::Error || err.level == Level::Fatal {
-            assert!(self.has_errors());
-            self.err_count.set(self.err_count.get() + 1);
-        }
-        err.cancel();
-    }
-
-    fn panic_if_treat_err_as_bug(&self) {
-        if self.treat_err_as_bug {
-            panic!("encountered error with `-Z treat_err_as_bug");
-        }
-    }
-
-    pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str)
-                                          -> FatalError {
-        self.emit(&sp.into(), msg, Fatal);
-        self.bump_err_count();
-        self.panic_if_treat_err_as_bug();
-        return FatalError;
-    }
-    pub fn span_fatal_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str)
-                                                    -> FatalError {
-        self.emit_with_code(&sp.into(), msg, code, Fatal);
-        self.bump_err_count();
-        self.panic_if_treat_err_as_bug();
-        return FatalError;
-    }
-    pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Error);
-        self.bump_err_count();
-        self.panic_if_treat_err_as_bug();
-    }
-    pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
-        self.emit_with_code(&sp.into(), msg, code, Error);
-        self.bump_err_count();
-        self.panic_if_treat_err_as_bug();
-    }
-    pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Warning);
-    }
-    pub fn span_warn_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: &str) {
-        self.emit_with_code(&sp.into(), msg, code, Warning);
-    }
-    pub fn span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.emit(&sp.into(), msg, Bug);
-        panic!(ExplicitBug);
-    }
-    pub fn delay_span_bug<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        let mut delayed = self.delayed_span_bug.borrow_mut();
-        *delayed = Some((sp.into(), msg.to_string()));
-    }
-    pub fn span_bug_no_panic<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit(&sp.into(), msg, Bug);
-        self.bump_err_count();
-    }
-    pub fn span_note_without_error<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
-        self.emit.borrow_mut().emit(&sp.into(), msg, None, Note);
-    }
-    pub fn span_unimpl<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
-        self.span_bug(sp, &format!("unimplemented {}", msg));
-    }
-    pub fn fatal(&self, msg: &str) -> FatalError {
-        if self.treat_err_as_bug {
-            self.bug(msg);
-        }
-        self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Fatal);
-        self.bump_err_count();
-        FatalError
-    }
-    pub fn err(&self, msg: &str) {
-        if self.treat_err_as_bug {
-            self.bug(msg);
-        }
-        self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Error);
-        self.bump_err_count();
-    }
-    pub fn warn(&self, msg: &str) {
-        self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Warning);
-    }
-    pub fn note_without_error(&self, msg: &str) {
-        self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Note);
-    }
-    pub fn bug(&self, msg: &str) -> ! {
-        self.emit.borrow_mut().emit(&MultiSpan::new(), msg, None, Bug);
-        panic!(ExplicitBug);
-    }
-    pub fn unimpl(&self, msg: &str) -> ! {
-        self.bug(&format!("unimplemented {}", msg));
-    }
-
-    pub fn bump_err_count(&self) {
-        self.err_count.set(self.err_count.get() + 1);
-    }
-
-    pub fn err_count(&self) -> usize {
-        self.err_count.get()
-    }
-
-    pub fn has_errors(&self) -> bool {
-        self.err_count.get() > 0
-    }
-    pub fn abort_if_errors(&self) {
-        let s;
-        match self.err_count.get() {
-            0 => {
-                let delayed_bug = self.delayed_span_bug.borrow();
-                match *delayed_bug {
-                    Some((ref span, ref errmsg)) => {
-                        self.span_bug(span.clone(), errmsg);
-                    },
-                    _ => {}
-                }
-
-                return;
-            }
-            1 => s = "aborting due to previous error".to_string(),
-            _  => {
-                s = format!("aborting due to {} previous errors",
-                            self.err_count.get());
-            }
-        }
-
-        panic!(self.fatal(&s));
-    }
-    pub fn emit(&self,
-                msp: &MultiSpan,
-                msg: &str,
-                lvl: Level) {
-        if lvl == Warning && !self.can_emit_warnings { return }
-        self.emit.borrow_mut().emit(&msp, msg, None, lvl);
-        if !self.continue_after_error.get() { self.abort_if_errors(); }
-    }
-    pub fn emit_with_code(&self,
-                          msp: &MultiSpan,
-                          msg: &str,
-                          code: &str,
-                          lvl: Level) {
-        if lvl == Warning && !self.can_emit_warnings { return }
-        self.emit.borrow_mut().emit(&msp, msg, Some(code), lvl);
-        if !self.continue_after_error.get() { self.abort_if_errors(); }
-    }
-}
-
-
-#[derive(Copy, PartialEq, Clone, Debug)]
-pub enum Level {
-    Bug,
-    Fatal,
-    // An error which while not immediately fatal, should stop the compiler
-    // progressing beyond the current phase.
-    PhaseFatal,
-    Error,
-    Warning,
-    Note,
-    Help,
-    Cancelled,
-}
-
-impl fmt::Display for Level {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.to_str().fmt(f)
-    }
-}
-
-impl Level {
-    fn color(self) -> term::color::Color {
-        match self {
-            Bug | Fatal | PhaseFatal | Error => term::color::BRIGHT_RED,
-            Warning => term::color::YELLOW,
-            Note => term::color::BRIGHT_GREEN,
-            Help => term::color::BRIGHT_CYAN,
-            Cancelled => unreachable!(),
-        }
-    }
-
-    fn to_str(self) -> &'static str {
-        match self {
-            Bug => "error: internal compiler error",
-            Fatal | PhaseFatal | Error => "error",
-            Warning => "warning",
-            Note => "note",
-            Help => "help",
-            Cancelled => panic!("Shouldn't call on cancelled error"),
-        }
-    }
-}
-
-pub fn expect<T, M>(diag: &Handler, opt: Option<T>, msg: M) -> T where
-    M: FnOnce() -> String,
-{
-    match opt {
-        Some(t) => t,
-        None => diag.bug(&msg()),
-    }
-}
-
-/// True if we should use the old-skool error format style. This is
-/// the default setting until the new errors are deemed stable enough
-/// for general use.
-///
-/// FIXME(#33240)
-#[cfg(not(test))]
-pub fn check_old_skool() -> bool {
-    use std::env;
-    env::var("RUST_NEW_ERROR_FORMAT").is_err()
-}
-
-/// For unit tests, use the new format.
-#[cfg(test)]
-pub fn check_old_skool() -> bool {
-    false
-}
diff --git a/src/libsyntax/errors/snippet/mod.rs b/src/libsyntax/errors/snippet/mod.rs
deleted file mode 100644
index 2a43a14ddf8..00000000000
--- a/src/libsyntax/errors/snippet/mod.rs
+++ /dev/null
@@ -1,888 +0,0 @@
-// Copyright 2012-2015 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.
-
-// Code for annotating snippets.
-
-use codemap::{CharPos, CodeMap, FileMap, LineInfo, Span};
-use errors::check_old_skool;
-use std::cmp;
-use std::rc::Rc;
-use std::mem;
-
-mod test;
-
-#[derive(Clone)]
-pub struct SnippetData {
-    codemap: Rc<CodeMap>,
-    files: Vec<FileInfo>,
-}
-
-#[derive(Clone)]
-pub struct FileInfo {
-    file: Rc<FileMap>,
-
-    /// The "primary file", if any, gets a `-->` marker instead of
-    /// `>>>`, and has a line-number/column printed and not just a
-    /// filename.  It appears first in the listing. It is known to
-    /// contain at least one primary span, though primary spans (which
-    /// are designated with `^^^`) may also occur in other files.
-    primary_span: Option<Span>,
-
-    lines: Vec<Line>,
-}
-
-#[derive(Clone, Debug)]
-struct Line {
-    line_index: usize,
-    annotations: Vec<Annotation>,
-}
-
-#[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
-struct Annotation {
-    /// Start column, 0-based indexing -- counting *characters*, not
-    /// utf-8 bytes. Note that it is important that this field goes
-    /// first, so that when we sort, we sort orderings by start
-    /// column.
-    start_col: usize,
-
-    /// End column within the line (exclusive)
-    end_col: usize,
-
-    /// Is this annotation derived from primary span
-    is_primary: bool,
-
-    /// Is this a large span minimized down to a smaller span
-    is_minimized: bool,
-
-    /// Optional label to display adjacent to the annotation.
-    label: Option<String>,
-}
-
-#[derive(Debug)]
-pub struct RenderedLine {
-    pub text: Vec<StyledString>,
-    pub kind: RenderedLineKind,
-}
-
-#[derive(Debug)]
-pub struct StyledString {
-    pub text: String,
-    pub style: Style,
-}
-
-#[derive(Debug)]
-pub struct StyledBuffer {
-    text: Vec<Vec<char>>,
-    styles: Vec<Vec<Style>>
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum Style {
-    FileNameStyle,
-    LineAndColumn,
-    LineNumber,
-    Quotation,
-    UnderlinePrimary,
-    UnderlineSecondary,
-    LabelPrimary,
-    LabelSecondary,
-    OldSkoolNoteText,
-    OldSkoolNote,
-    NoStyle,
-}
-
-#[derive(Debug, Clone)]
-pub enum RenderedLineKind {
-    PrimaryFileName,
-    OtherFileName,
-    SourceText {
-        file: Rc<FileMap>,
-        line_index: usize,
-    },
-    Annotations,
-    Elision,
-}
-
-impl SnippetData {
-    pub fn new(codemap: Rc<CodeMap>,
-               primary_span: Option<Span>) // (*)
-               -> Self {
-        // (*) The primary span indicates the file that must appear
-        // first, and which will have a line number etc in its
-        // name. Outside of tests, this is always `Some`, but for many
-        // tests it's not relevant to test this portion of the logic,
-        // and it's tedious to pick a primary span (read: tedious to
-        // port older tests that predate the existence of a primary
-        // span).
-
-        debug!("SnippetData::new(primary_span={:?})", primary_span);
-
-        let mut data = SnippetData {
-            codemap: codemap.clone(),
-            files: vec![]
-        };
-        if let Some(primary_span) = primary_span {
-            let lo = codemap.lookup_char_pos(primary_span.lo);
-            data.files.push(
-                FileInfo {
-                    file: lo.file,
-                    primary_span: Some(primary_span),
-                    lines: vec![],
-                });
-        }
-        data
-    }
-
-    pub fn push(&mut self, span: Span, is_primary: bool, label: Option<String>) {
-        debug!("SnippetData::push(span={:?}, is_primary={}, label={:?})",
-               span, is_primary, label);
-
-        let file_lines = match self.codemap.span_to_lines(span) {
-            Ok(file_lines) => file_lines,
-            Err(_) => {
-                // ignore unprintable spans completely.
-                return;
-            }
-        };
-
-        self.file(&file_lines.file)
-            .push_lines(&file_lines.lines, is_primary, label);
-    }
-
-    fn file(&mut self, file_map: &Rc<FileMap>) -> &mut FileInfo {
-        let index = self.files.iter().position(|f| f.file.name == file_map.name);
-        if let Some(index) = index {
-            return &mut self.files[index];
-        }
-
-        self.files.push(
-            FileInfo {
-                file: file_map.clone(),
-                lines: vec![],
-                primary_span: None,
-            });
-        self.files.last_mut().unwrap()
-    }
-
-    pub fn render_lines(&self) -> Vec<RenderedLine> {
-        debug!("SnippetData::render_lines()");
-
-        let mut rendered_lines: Vec<_> =
-            self.files.iter()
-                      .flat_map(|f| f.render_file_lines(&self.codemap))
-                      .collect();
-        prepend_prefixes(&mut rendered_lines);
-        trim_lines(&mut rendered_lines);
-        rendered_lines
-    }
-}
-
-pub trait StringSource {
-    fn make_string(self) -> String;
-}
-
-impl StringSource for String {
-    fn make_string(self) -> String {
-        self
-    }
-}
-
-impl StringSource for Vec<char> {
-    fn make_string(self) -> String {
-        self.into_iter().collect()
-    }
-}
-
-impl<S> From<(S, Style, RenderedLineKind)> for RenderedLine
-    where S: StringSource
-{
-    fn from((text, style, kind): (S, Style, RenderedLineKind)) -> Self {
-        RenderedLine {
-            text: vec![StyledString {
-                text: text.make_string(),
-                style: style,
-            }],
-            kind: kind,
-        }
-    }
-}
-
-impl<S1,S2> From<(S1, Style, S2, Style, RenderedLineKind)> for RenderedLine
-    where S1: StringSource, S2: StringSource
-{
-    fn from(tuple: (S1, Style, S2, Style, RenderedLineKind)) -> Self {
-        let (text1, style1, text2, style2, kind) = tuple;
-        RenderedLine {
-            text: vec![
-                StyledString {
-                    text: text1.make_string(),
-                    style: style1,
-                },
-                StyledString {
-                    text: text2.make_string(),
-                    style: style2,
-                }
-            ],
-            kind: kind,
-        }
-    }
-}
-
-impl RenderedLine {
-    fn trim_last(&mut self) {
-        if let Some(last_text) = self.text.last_mut() {
-            let len = last_text.text.trim_right().len();
-            last_text.text.truncate(len);
-        }
-    }
-}
-
-impl RenderedLineKind {
-    fn prefix(&self) -> StyledString {
-        match *self {
-            RenderedLineKind::SourceText { file: _, line_index } =>
-                StyledString {
-                    text: format!("{}", line_index + 1),
-                    style: Style::LineNumber,
-                },
-            RenderedLineKind::Elision =>
-                StyledString {
-                    text: String::from("..."),
-                    style: Style::LineNumber,
-                },
-            RenderedLineKind::PrimaryFileName |
-            RenderedLineKind::OtherFileName |
-            RenderedLineKind::Annotations =>
-                StyledString {
-                    text: String::from(""),
-                    style: Style::LineNumber,
-                },
-        }
-    }
-}
-
-impl StyledBuffer {
-    fn new() -> StyledBuffer {
-        StyledBuffer { text: vec![], styles: vec![] }
-    }
-
-    fn render(&self, source_kind: RenderedLineKind) -> Vec<RenderedLine> {
-        let mut output: Vec<RenderedLine> = vec![];
-        let mut styled_vec: Vec<StyledString> = vec![];
-
-        for (row, row_style) in self.text.iter().zip(&self.styles) {
-            let mut current_style = Style::NoStyle;
-            let mut current_text = String::new();
-
-            for (&c, &s) in row.iter().zip(row_style) {
-                if s != current_style {
-                    if !current_text.is_empty() {
-                        styled_vec.push(StyledString { text: current_text, style: current_style });
-                    }
-                    current_style = s;
-                    current_text = String::new();
-                }
-                current_text.push(c);
-            }
-            if !current_text.is_empty() {
-                styled_vec.push(StyledString { text: current_text, style: current_style });
-            }
-
-            if output.is_empty() {
-                //We know our first output line is source and the rest are highlights and labels
-                output.push(RenderedLine { text: styled_vec, kind: source_kind.clone() });
-            } else {
-                output.push(RenderedLine { text: styled_vec, kind: RenderedLineKind::Annotations });
-            }
-            styled_vec = vec![];
-        }
-
-        output
-    }
-
-    fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
-        while line >= self.text.len() {
-            self.text.push(vec![]);
-            self.styles.push(vec![]);
-        }
-
-        if col < self.text[line].len() {
-            self.text[line][col] = chr;
-            self.styles[line][col] = style;
-        } else {
-            let mut i = self.text[line].len();
-            while i < col {
-                let s = match self.text[0].get(i) {
-                    Some(&'\t') => '\t',
-                    _ => ' '
-                };
-                self.text[line].push(s);
-                self.styles[line].push(Style::NoStyle);
-                i += 1;
-            }
-            self.text[line].push(chr);
-            self.styles[line].push(style);
-        }
-    }
-
-    fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
-        let mut n = col;
-        for c in string.chars() {
-            self.putc(line, n, c, style);
-            n += 1;
-        }
-    }
-
-    fn set_style(&mut self, line: usize, col: usize, style: Style) {
-        if self.styles.len() > line && self.styles[line].len() > col {
-            self.styles[line][col] = style;
-        }
-    }
-
-    fn append(&mut self, line: usize, string: &str, style: Style) {
-        if line >= self.text.len() {
-            self.puts(line, 0, string, style);
-        } else {
-            let col = self.text[line].len();
-            self.puts(line, col, string, style);
-        }
-    }
-}
-
-impl FileInfo {
-    fn push_lines(&mut self,
-                  lines: &[LineInfo],
-                  is_primary: bool,
-                  label: Option<String>) {
-        assert!(lines.len() > 0);
-
-        // If a span covers multiple lines, we reduce it to a single
-        // point at the start of the span. This means that instead
-        // of producing output like this:
-        //
-        // ```
-        // --> foo.rs:2:1
-        // 2   |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
-        //     |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-        // 3   |>                               -> Set<LR0Item<'grammar>>
-        //     |> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-        // (and so on)
-        // ```
-        //
-        // we produce:
-        //
-        // ```
-        // --> foo.rs:2:1
-        // 2   |> fn conflicting_items<'grammar>(state: &LR0State<'grammar>)
-        //        ^
-        // ```
-        //
-        // Basically, although this loses information, multi-line spans just
-        // never look good.
-
-        let (line, start_col, mut end_col, is_minimized) = if lines.len() == 1 {
-            (lines[0].line_index, lines[0].start_col, lines[0].end_col, false)
-        } else {
-            (lines[0].line_index, lines[0].start_col, CharPos(lines[0].start_col.0 + 1), true)
-        };
-
-        // Watch out for "empty spans". If we get a span like 6..6, we
-        // want to just display a `^` at 6, so convert that to
-        // 6..7. This is degenerate input, but it's best to degrade
-        // gracefully -- and the parser likes to suply a span like
-        // that for EOF, in particular.
-        if start_col == end_col {
-            end_col.0 += 1;
-        }
-
-        let index = self.ensure_source_line(line);
-        self.lines[index].push_annotation(start_col,
-                                          end_col,
-                                          is_primary,
-                                          is_minimized,
-                                          label);
-    }
-
-    /// Ensure that we have a `Line` struct corresponding to
-    /// `line_index` in the file. If we already have some other lines,
-    /// then this will add the intervening lines to ensure that we
-    /// have a complete snippet. (Note that when we finally display,
-    /// some of those lines may be elided.)
-    fn ensure_source_line(&mut self, line_index: usize) -> usize {
-        if self.lines.is_empty() {
-            self.lines.push(Line::new(line_index));
-            return 0;
-        }
-
-        // Find the range of lines we have thus far.
-        let first_line_index = self.lines.first().unwrap().line_index;
-        let last_line_index = self.lines.last().unwrap().line_index;
-        assert!(first_line_index <= last_line_index);
-
-        // If the new line is lower than all the lines we have thus
-        // far, then insert the new line and any intervening lines at
-        // the front. In a silly attempt at micro-optimization, we
-        // don't just call `insert` repeatedly, but instead make a new
-        // (empty) vector, pushing the new lines onto it, and then
-        // appending the old vector.
-        if line_index < first_line_index {
-            let lines = mem::replace(&mut self.lines, vec![]);
-            self.lines.extend(
-                (line_index .. first_line_index)
-                    .map(|line| Line::new(line))
-                    .chain(lines));
-            return 0;
-        }
-
-        // If the new line comes after the ones we have so far, insert
-        // lines for it.
-        if line_index > last_line_index {
-            self.lines.extend(
-                (last_line_index+1 .. line_index+1)
-                    .map(|line| Line::new(line)));
-            return self.lines.len() - 1;
-        }
-
-        // Otherwise it should already exist.
-        return line_index - first_line_index;
-    }
-
-    fn render_file_lines(&self, codemap: &Rc<CodeMap>) -> Vec<RenderedLine> {
-        let old_school = check_old_skool();
-
-        // As a first step, we elide any instance of more than one
-        // continuous unannotated line.
-
-        let mut lines_iter = self.lines.iter();
-        let mut output = vec![];
-
-        // First insert the name of the file.
-        if !old_school {
-            match self.primary_span {
-                Some(span) => {
-                    let lo = codemap.lookup_char_pos(span.lo);
-                    output.push(RenderedLine {
-                        text: vec![StyledString {
-                            text: lo.file.name.clone(),
-                            style: Style::FileNameStyle,
-                        }, StyledString {
-                            text: format!(":{}:{}", lo.line, lo.col.0 + 1),
-                            style: Style::LineAndColumn,
-                        }],
-                        kind: RenderedLineKind::PrimaryFileName,
-                    });
-                    output.push(RenderedLine {
-                        text: vec![StyledString {
-                            text: "".to_string(),
-                            style: Style::FileNameStyle,
-                        }],
-                        kind: RenderedLineKind::Annotations,
-                    });
-                }
-                None => {
-                    output.push(RenderedLine {
-                        text: vec![StyledString {
-                            text: self.file.name.clone(),
-                            style: Style::FileNameStyle,
-                        }],
-                        kind: RenderedLineKind::OtherFileName,
-                    });
-                    output.push(RenderedLine {
-                        text: vec![StyledString {
-                            text: "".to_string(),
-                            style: Style::FileNameStyle,
-                        }],
-                        kind: RenderedLineKind::Annotations,
-                    });
-                }
-            }
-        }
-
-        let mut next_line = lines_iter.next();
-        while next_line.is_some() {
-            // Consume lines with annotations.
-            while let Some(line) = next_line {
-                if line.annotations.is_empty() { break; }
-
-                let mut rendered_lines = self.render_line(line);
-                assert!(!rendered_lines.is_empty());
-                if old_school {
-                    match self.primary_span {
-                        Some(span) => {
-                            let lo = codemap.lookup_char_pos(span.lo);
-                            let hi = codemap.lookup_char_pos(span.hi);
-                            //Before each secondary line in old skool-mode, print the label
-                            //as an old-style note
-                            if !line.annotations[0].is_primary {
-                                if let Some(ann) = line.annotations[0].label.clone() {
-                                    output.push(RenderedLine {
-                                        text: vec![StyledString {
-                                            text: lo.file.name.clone(),
-                                            style: Style::FileNameStyle,
-                                        }, StyledString {
-                                            text: format!(":{}:{}: {}:{} ", lo.line, lo.col.0 + 1,
-                                                hi.line, hi.col.0+1),
-                                            style: Style::LineAndColumn,
-                                        }, StyledString {
-                                            text: format!("note: "),
-                                            style: Style::OldSkoolNote,
-                                        }, StyledString {
-                                            text: format!("{}", ann),
-                                            style: Style::OldSkoolNoteText,
-                                        }],
-                                        kind: RenderedLineKind::Annotations,
-                                    });
-                                }
-                            }
-                            rendered_lines[0].text.insert(0, StyledString {
-                                text: format!(":{} ", lo.line),
-                                style: Style::LineAndColumn,
-                            });
-                            rendered_lines[0].text.insert(0, StyledString {
-                                text: lo.file.name.clone(),
-                                style: Style::FileNameStyle,
-                            });
-                            let gap_amount =
-                                rendered_lines[0].text[0].text.len() +
-                                rendered_lines[0].text[1].text.len();
-                            assert!(rendered_lines.len() >= 2,
-                                    "no annotations resulted from: {:?}",
-                                    line);
-                            for i in 1..rendered_lines.len() {
-                                rendered_lines[i].text.insert(0, StyledString {
-                                    text: vec![" "; gap_amount].join(""),
-                                    style: Style::NoStyle
-                                });
-                            }
-                        }
-                        _ =>()
-                    }
-                }
-                output.append(&mut rendered_lines);
-                next_line = lines_iter.next();
-            }
-
-            // Emit lines without annotations, but only if they are
-            // followed by a line with an annotation.
-            let unannotated_line = next_line;
-            let mut unannotated_lines = 0;
-            while let Some(line) = next_line {
-                if !line.annotations.is_empty() { break; }
-                unannotated_lines += 1;
-                next_line = lines_iter.next();
-            }
-            if unannotated_lines > 1 {
-                output.push(RenderedLine::from((String::new(),
-                                                Style::NoStyle,
-                                                RenderedLineKind::Elision)));
-            } else if let Some(line) = unannotated_line {
-                output.append(&mut self.render_line(line));
-            }
-        }
-
-        output
-    }
-
-    fn render_line(&self, line: &Line) -> Vec<RenderedLine> {
-        let old_school = check_old_skool();
-        let source_string = self.file.get_line(line.line_index)
-                                     .unwrap_or("");
-        let source_kind = RenderedLineKind::SourceText {
-            file: self.file.clone(),
-            line_index: line.line_index,
-        };
-
-        let mut styled_buffer = StyledBuffer::new();
-
-        // First create the source line we will highlight.
-        styled_buffer.append(0, &source_string, Style::Quotation);
-
-        if line.annotations.is_empty() {
-            return styled_buffer.render(source_kind);
-        }
-
-        // We want to display like this:
-        //
-        //      vec.push(vec.pop().unwrap());
-        //      ---      ^^^               _ previous borrow ends here
-        //      |        |
-        //      |        error occurs here
-        //      previous borrow of `vec` occurs here
-        //
-        // But there are some weird edge cases to be aware of:
-        //
-        //      vec.push(vec.pop().unwrap());
-        //      --------                    - previous borrow ends here
-        //      ||
-        //      |this makes no sense
-        //      previous borrow of `vec` occurs here
-        //
-        // For this reason, we group the lines into "highlight lines"
-        // and "annotations lines", where the highlight lines have the `~`.
-
-        //let mut highlight_line = Self::whitespace(&source_string);
-
-        // Sort the annotations by (start, end col)
-        let mut annotations = line.annotations.clone();
-        annotations.sort();
-
-        // Next, create the highlight line.
-        for annotation in &annotations {
-            if old_school {
-                for p in annotation.start_col .. annotation.end_col {
-                    if p == annotation.start_col {
-                        styled_buffer.putc(1, p, '^',
-                            if annotation.is_primary {
-                                Style::UnderlinePrimary
-                            } else {
-                                Style::OldSkoolNote
-                            });
-                    }
-                    else {
-                        styled_buffer.putc(1, p, '~',
-                            if annotation.is_primary {
-                                Style::UnderlinePrimary
-                            } else {
-                                Style::OldSkoolNote
-                            });
-                    }
-                }
-            }
-            else {
-                for p in annotation.start_col .. annotation.end_col {
-                    if annotation.is_primary {
-                        styled_buffer.putc(1, p, '^', Style::UnderlinePrimary);
-                        if !annotation.is_minimized {
-                            styled_buffer.set_style(0, p, Style::UnderlinePrimary);
-                        }
-                    } else {
-                        styled_buffer.putc(1, p, '-', Style::UnderlineSecondary);
-                        if !annotation.is_minimized {
-                            styled_buffer.set_style(0, p, Style::UnderlineSecondary);
-                        }
-                    }
-                }
-            }
-        }
-
-        // Now we are going to write labels in. To start, we'll exclude
-        // the annotations with no labels.
-        let (labeled_annotations, unlabeled_annotations): (Vec<_>, _) =
-            annotations.into_iter()
-                       .partition(|a| a.label.is_some());
-
-        // If there are no annotations that need text, we're done.
-        if labeled_annotations.is_empty() {
-            return styled_buffer.render(source_kind);
-        }
-        if old_school {
-            return styled_buffer.render(source_kind);
-        }
-
-        // Now add the text labels. We try, when possible, to stick the rightmost
-        // annotation at the end of the highlight line:
-        //
-        //      vec.push(vec.pop().unwrap());
-        //      ---      ---               - previous borrow ends here
-        //
-        // But sometimes that's not possible because one of the other
-        // annotations overlaps it. For example, from the test
-        // `span_overlap_label`, we have the following annotations
-        // (written on distinct lines for clarity):
-        //
-        //      fn foo(x: u32) {
-        //      --------------
-        //             -
-        //
-        // In this case, we can't stick the rightmost-most label on
-        // the highlight line, or we would get:
-        //
-        //      fn foo(x: u32) {
-        //      -------- x_span
-        //      |
-        //      fn_span
-        //
-        // which is totally weird. Instead we want:
-        //
-        //      fn foo(x: u32) {
-        //      --------------
-        //      |      |
-        //      |      x_span
-        //      fn_span
-        //
-        // which is...less weird, at least. In fact, in general, if
-        // the rightmost span overlaps with any other span, we should
-        // use the "hang below" version, so we can at least make it
-        // clear where the span *starts*.
-        let mut labeled_annotations = &labeled_annotations[..];
-        match labeled_annotations.split_last().unwrap() {
-            (last, previous) => {
-                if previous.iter()
-                           .chain(&unlabeled_annotations)
-                           .all(|a| !overlaps(a, last))
-                {
-                    // append the label afterwards; we keep it in a separate
-                    // string
-                    let highlight_label: String = format!(" {}", last.label.as_ref().unwrap());
-                    if last.is_primary {
-                        styled_buffer.append(1, &highlight_label, Style::LabelPrimary);
-                    } else {
-                        styled_buffer.append(1, &highlight_label, Style::LabelSecondary);
-                    }
-                    labeled_annotations = previous;
-                }
-            }
-        }
-
-        // If that's the last annotation, we're done
-        if labeled_annotations.is_empty() {
-            return styled_buffer.render(source_kind);
-        }
-
-        for (index, annotation) in labeled_annotations.iter().enumerate() {
-            // Leave:
-            // - 1 extra line
-            // - One line for each thing that comes after
-            let comes_after = labeled_annotations.len() - index - 1;
-            let blank_lines = 3 + comes_after;
-
-            // For each blank line, draw a `|` at our column. The
-            // text ought to be long enough for this.
-            for index in 2..blank_lines {
-                if annotation.is_primary {
-                    styled_buffer.putc(index, annotation.start_col, '|', Style::UnderlinePrimary);
-                } else {
-                    styled_buffer.putc(index, annotation.start_col, '|', Style::UnderlineSecondary);
-                }
-            }
-
-            if annotation.is_primary {
-                styled_buffer.puts(blank_lines, annotation.start_col,
-                    annotation.label.as_ref().unwrap(), Style::LabelPrimary);
-            } else {
-                styled_buffer.puts(blank_lines, annotation.start_col,
-                    annotation.label.as_ref().unwrap(), Style::LabelSecondary);
-            }
-        }
-
-        styled_buffer.render(source_kind)
-    }
-}
-
-fn prepend_prefixes(rendered_lines: &mut [RenderedLine]) {
-    let old_school = check_old_skool();
-    if old_school {
-        return;
-    }
-
-    let prefixes: Vec<_> =
-        rendered_lines.iter()
-                      .map(|rl| rl.kind.prefix())
-                      .collect();
-
-    // find the max amount of spacing we need; add 1 to
-    // p.text.len() to leave space between the prefix and the
-    // source text
-    let padding_len =
-        prefixes.iter()
-                .map(|p| if p.text.len() == 0 { 0 } else { p.text.len() + 1 })
-                .max()
-                .unwrap_or(0);
-
-    // Ensure we insert at least one character of padding, so that the
-    // `-->` arrows can fit etc.
-    let padding_len = cmp::max(padding_len, 1);
-
-    for (mut prefix, line) in prefixes.into_iter().zip(rendered_lines) {
-        let extra_spaces = (prefix.text.len() .. padding_len).map(|_| ' ');
-        prefix.text.extend(extra_spaces);
-        match line.kind {
-            RenderedLineKind::Elision => {
-                line.text.insert(0, prefix);
-            }
-            RenderedLineKind::PrimaryFileName => {
-                //   --> filename
-                // 22 |>
-                //   ^
-                //   padding_len
-                let dashes = (0..padding_len - 1).map(|_| ' ')
-                                                 .chain(Some('-'))
-                                                 .chain(Some('-'))
-                                                 .chain(Some('>'))
-                                                 .chain(Some(' '));
-                line.text.insert(0, StyledString {text: dashes.collect(),
-                                                  style: Style::LineNumber})
-            }
-            RenderedLineKind::OtherFileName => {
-                //   ::: filename
-                // 22 |>
-                //   ^
-                //   padding_len
-                let dashes = (0..padding_len - 1).map(|_| ' ')
-                                                 .chain(Some(':'))
-                                                 .chain(Some(':'))
-                                                 .chain(Some(':'))
-                                                 .chain(Some(' '));
-                line.text.insert(0, StyledString {text: dashes.collect(),
-                                                  style: Style::LineNumber})
-            }
-            _ => {
-                line.text.insert(0, prefix);
-                line.text.insert(1, StyledString {text: String::from("|> "),
-                                                  style: Style::LineNumber})
-            }
-        }
-    }
-}
-
-fn trim_lines(rendered_lines: &mut [RenderedLine]) {
-    for line in rendered_lines {
-        while !line.text.is_empty() {
-            line.trim_last();
-            if line.text.last().unwrap().text.is_empty() {
-                line.text.pop();
-            } else {
-                break;
-            }
-        }
-    }
-}
-
-impl Line {
-    fn new(line_index: usize) -> Line {
-        Line {
-            line_index: line_index,
-            annotations: vec![]
-        }
-    }
-
-    fn push_annotation(&mut self,
-                       start: CharPos,
-                       end: CharPos,
-                       is_primary: bool,
-                       is_minimized: bool,
-                       label: Option<String>) {
-        self.annotations.push(Annotation {
-            start_col: start.0,
-            end_col: end.0,
-            is_primary: is_primary,
-            is_minimized: is_minimized,
-            label: label,
-        });
-    }
-}
-
-fn overlaps(a1: &Annotation,
-            a2: &Annotation)
-            -> bool
-{
-    (a2.start_col .. a2.end_col).contains(a1.start_col) ||
-        (a1.start_col .. a1.end_col).contains(a2.start_col)
-}
diff --git a/src/libsyntax/errors/snippet/test.rs b/src/libsyntax/errors/snippet/test.rs
deleted file mode 100644
index 79e40a09165..00000000000
--- a/src/libsyntax/errors/snippet/test.rs
+++ /dev/null
@@ -1,597 +0,0 @@
-// Copyright 2016 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.
-
-// Code for testing annotated snippets.
-
-#![cfg(test)]
-
-use codemap::{BytePos, CodeMap, FileMap, NO_EXPANSION, Span};
-use std::rc::Rc;
-use super::{RenderedLine, SnippetData};
-
-/// Returns the span corresponding to the `n`th occurrence of
-/// `substring` in `source_text`.
-trait CodeMapExtension {
-    fn span_substr(&self,
-                   file: &Rc<FileMap>,
-                   source_text: &str,
-                   substring: &str,
-                   n: usize)
-                   -> Span;
-}
-
-impl CodeMapExtension for CodeMap {
-    fn span_substr(&self,
-                   file: &Rc<FileMap>,
-                   source_text: &str,
-                   substring: &str,
-                   n: usize)
-                   -> Span
-    {
-        println!("span_substr(file={:?}/{:?}, substring={:?}, n={})",
-                 file.name, file.start_pos, substring, n);
-        let mut i = 0;
-        let mut hi = 0;
-        loop {
-            let offset = source_text[hi..].find(substring).unwrap_or_else(|| {
-                panic!("source_text `{}` does not have {} occurrences of `{}`, only {}",
-                       source_text, n, substring, i);
-            });
-            let lo = hi + offset;
-            hi = lo + substring.len();
-            if i == n {
-                let span = Span {
-                    lo: BytePos(lo as u32 + file.start_pos.0),
-                    hi: BytePos(hi as u32 + file.start_pos.0),
-                    expn_id: NO_EXPANSION,
-                };
-                assert_eq!(&self.span_to_snippet(span).unwrap()[..],
-                           substring);
-                return span;
-            }
-            i += 1;
-        }
-    }
-}
-
-fn splice(start: Span, end: Span) -> Span {
-    Span {
-        lo: start.lo,
-        hi: end.hi,
-        expn_id: NO_EXPANSION,
-    }
-}
-
-fn make_string(lines: &[RenderedLine]) -> String {
-    lines.iter()
-         .flat_map(|rl| {
-             rl.text.iter()
-                    .map(|s| &s.text[..])
-                    .chain(Some("\n"))
-         })
-         .collect()
-}
-
-#[test]
-fn tab() {
-    let file_text = "
-fn foo() {
-\tbar;
-}
-";
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span_bar = cm.span_substr(&foo, file_text, "bar", 0);
-
-    let mut snippet = SnippetData::new(cm, Some(span_bar));
-    snippet.push(span_bar, true, None);
-
-    let lines = snippet.render_lines();
-    let text = make_string(&lines);
-    assert_eq!(&text[..], &"
- --> foo.rs:3:2
-  |>
-3 |> \tbar;
-  |> \t^^^
-"[1..]);
-}
-
-#[test]
-fn one_line() {
-    let file_text = r#"
-fn foo() {
-    vec.push(vec.pop().unwrap());
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0);
-    let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1);
-    let span_semi = cm.span_substr(&foo, file_text, ";", 0);
-
-    let mut snippet = SnippetData::new(cm, None);
-    snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here")));
-    snippet.push(span_vec1, false, Some(format!("error occurs here")));
-    snippet.push(span_semi, false, Some(format!("previous borrow ends here")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-
-    let text: String = make_string(&lines);
-
-    println!("text=\n{}", text);
-    assert_eq!(&text[..], &r#"
- ::: foo.rs
-  |>
-3 |>     vec.push(vec.pop().unwrap());
-  |>     ---      ---                - previous borrow ends here
-  |>     |        |
-  |>     |        error occurs here
-  |>     previous borrow of `vec` occurs here
-"#[1..]);
-}
-
-#[test]
-fn two_files() {
-    let file_text_foo = r#"
-fn foo() {
-    vec.push(vec.pop().unwrap());
-}
-"#;
-
-    let file_text_bar = r#"
-fn bar() {
-    // these blank links here
-    // serve to ensure that the line numbers
-    // from bar.rs
-    // require more digits
-
-
-
-
-
-
-
-
-
-
-    vec.push();
-
-    // this line will get elided
-
-    vec.pop().unwrap());
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo_map = cm.new_filemap_and_lines("foo.rs", None, file_text_foo);
-    let span_foo_vec0 = cm.span_substr(&foo_map, file_text_foo, "vec", 0);
-    let span_foo_vec1 = cm.span_substr(&foo_map, file_text_foo, "vec", 1);
-    let span_foo_semi = cm.span_substr(&foo_map, file_text_foo, ";", 0);
-
-    let bar_map = cm.new_filemap_and_lines("bar.rs", None, file_text_bar);
-    let span_bar_vec0 = cm.span_substr(&bar_map, file_text_bar, "vec", 0);
-    let span_bar_vec1 = cm.span_substr(&bar_map, file_text_bar, "vec", 1);
-    let span_bar_semi = cm.span_substr(&bar_map, file_text_bar, ";", 0);
-
-    let mut snippet = SnippetData::new(cm, Some(span_foo_vec1));
-    snippet.push(span_foo_vec0, false, Some(format!("a")));
-    snippet.push(span_foo_vec1, true, Some(format!("b")));
-    snippet.push(span_foo_semi, false, Some(format!("c")));
-    snippet.push(span_bar_vec0, false, Some(format!("d")));
-    snippet.push(span_bar_vec1, false, Some(format!("e")));
-    snippet.push(span_bar_semi, false, Some(format!("f")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-
-    let text: String = make_string(&lines);
-
-    println!("text=\n{}", text);
-
-    // Note that the `|>` remain aligned across both files:
-    assert_eq!(&text[..], &r#"
-   --> foo.rs:3:14
-    |>
-3   |>     vec.push(vec.pop().unwrap());
-    |>     ---      ^^^                - c
-    |>     |        |
-    |>     |        b
-    |>     a
-   ::: bar.rs
-    |>
-17  |>     vec.push();
-    |>     ---       - f
-    |>     |
-    |>     d
-...
-21  |>     vec.pop().unwrap());
-    |>     --- e
-"#[1..]);
-}
-
-#[test]
-fn multi_line() {
-    let file_text = r#"
-fn foo() {
-    let name = find_id(&data, 22).unwrap();
-
-    // Add one more item we forgot to the vector. Silly us.
-    data.push(Data { name: format!("Hera"), id: 66 });
-
-    // Print everything out.
-    println!("Name: {:?}", name);
-    println!("Data: {:?}", data);
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span_data0 = cm.span_substr(&foo, file_text, "data", 0);
-    let span_data1 = cm.span_substr(&foo, file_text, "data", 1);
-    let span_rbrace = cm.span_substr(&foo, file_text, "}", 3);
-
-    let mut snippet = SnippetData::new(cm, None);
-    snippet.push(span_data0, false, Some(format!("immutable borrow begins here")));
-    snippet.push(span_data1, false, Some(format!("mutable borrow occurs here")));
-    snippet.push(span_rbrace, false, Some(format!("immutable borrow ends here")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-
-    let text: String = make_string(&lines);
-
-    println!("text=\n{}", text);
-    assert_eq!(&text[..], &r#"
-   ::: foo.rs
-    |>
-3   |>     let name = find_id(&data, 22).unwrap();
-    |>                         ---- immutable borrow begins here
-...
-6   |>     data.push(Data { name: format!("Hera"), id: 66 });
-    |>     ---- mutable borrow occurs here
-...
-11  |> }
-    |> - immutable borrow ends here
-"#[1..]);
-}
-
-#[test]
-fn overlapping() {
-    let file_text = r#"
-fn foo() {
-    vec.push(vec.pop().unwrap());
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span0 = cm.span_substr(&foo, file_text, "vec.push", 0);
-    let span1 = cm.span_substr(&foo, file_text, "vec", 0);
-    let span2 = cm.span_substr(&foo, file_text, "ec.push", 0);
-    let span3 = cm.span_substr(&foo, file_text, "unwrap", 0);
-
-    let mut snippet = SnippetData::new(cm, None);
-    snippet.push(span0, false, Some(format!("A")));
-    snippet.push(span1, false, Some(format!("B")));
-    snippet.push(span2, false, Some(format!("C")));
-    snippet.push(span3, false, Some(format!("D")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-    let text: String = make_string(&lines);
-
-    println!("text=r#\"\n{}\".trim_left()", text);
-    assert_eq!(&text[..], &r#"
- ::: foo.rs
-  |>
-3 |>     vec.push(vec.pop().unwrap());
-  |>     --------           ------ D
-  |>     ||
-  |>     |C
-  |>     A
-  |>     B
-"#[1..]);
-}
-
-#[test]
-fn one_line_out_of_order() {
-    let file_text = r#"
-fn foo() {
-    vec.push(vec.pop().unwrap());
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span_vec0 = cm.span_substr(&foo, file_text, "vec", 0);
-    let span_vec1 = cm.span_substr(&foo, file_text, "vec", 1);
-    let span_semi = cm.span_substr(&foo, file_text, ";", 0);
-
-    // intentionally don't push the snippets left to right
-    let mut snippet = SnippetData::new(cm, None);
-    snippet.push(span_vec1, false, Some(format!("error occurs here")));
-    snippet.push(span_vec0, false, Some(format!("previous borrow of `vec` occurs here")));
-    snippet.push(span_semi, false, Some(format!("previous borrow ends here")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-    let text: String = make_string(&lines);
-
-    println!("text=r#\"\n{}\".trim_left()", text);
-    assert_eq!(&text[..], &r#"
- ::: foo.rs
-  |>
-3 |>     vec.push(vec.pop().unwrap());
-  |>     ---      ---                - previous borrow ends here
-  |>     |        |
-  |>     |        error occurs here
-  |>     previous borrow of `vec` occurs here
-"#[1..]);
-}
-
-#[test]
-fn elide_unnecessary_lines() {
-    let file_text = r#"
-fn foo() {
-    let mut vec = vec![0, 1, 2];
-    let mut vec2 = vec;
-    vec2.push(3);
-    vec2.push(4);
-    vec2.push(5);
-    vec2.push(6);
-    vec.push(7);
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-    let span_vec0 = cm.span_substr(&foo, file_text, "vec", 3);
-    let span_vec1 = cm.span_substr(&foo, file_text, "vec", 8);
-
-    let mut snippet = SnippetData::new(cm, None);
-    snippet.push(span_vec0, false, Some(format!("`vec` moved here because it \
-        has type `collections::vec::Vec<i32>`")));
-    snippet.push(span_vec1, false, Some(format!("use of moved value: `vec`")));
-
-    let lines = snippet.render_lines();
-    println!("{:#?}", lines);
-    let text: String = make_string(&lines);
-    println!("text=r#\"\n{}\".trim_left()", text);
-    assert_eq!(&text[..], &r#"
-   ::: foo.rs
-    |>
-4   |>     let mut vec2 = vec;
-    |>                    --- `vec` moved here because it has type `collections::vec::Vec<i32>`
-...
-9   |>     vec.push(7);
-    |>     --- use of moved value: `vec`
-"#[1..]);
-}
-
-#[test]
-fn spans_without_labels() {
-    let file_text = r#"
-fn foo() {
-    let mut vec = vec![0, 1, 2];
-    let mut vec2 = vec;
-    vec2.push(3);
-    vec2.push(4);
-    vec2.push(5);
-    vec2.push(6);
-    vec.push(7);
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut snippet = SnippetData::new(cm.clone(), None);
-    for i in 0..4 {
-        let span_veci = cm.span_substr(&foo, file_text, "vec", i);
-        snippet.push(span_veci, false, None);
-    }
-
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("text=&r#\"\n{}\n\"#[1..]", text);
-    assert_eq!(text, &r#"
- ::: foo.rs
-  |>
-3 |>     let mut vec = vec![0, 1, 2];
-  |>             ---   ---
-4 |>     let mut vec2 = vec;
-  |>             ---    ---
-"#[1..]);
-}
-
-#[test]
-fn span_long_selection() {
-    let file_text = r#"
-impl SomeTrait for () {
-    fn foo(x: u32) {
-        // impl 1
-        // impl 2
-        // impl 3
-    }
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut snippet = SnippetData::new(cm.clone(), None);
-    let fn_span = cm.span_substr(&foo, file_text, "fn", 0);
-    let rbrace_span = cm.span_substr(&foo, file_text, "}", 0);
-    snippet.push(splice(fn_span, rbrace_span), false, None);
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("r#\"\n{}\"", text);
-    assert_eq!(text, &r#"
- ::: foo.rs
-  |>
-3 |>     fn foo(x: u32) {
-  |>     -
-"#[1..]);
-}
-
-#[test]
-fn span_overlap_label() {
-    // Test that we don't put `x_span` to the right of its highlight,
-    // since there is another highlight that overlaps it.
-
-    let file_text = r#"
-    fn foo(x: u32) {
-    }
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut snippet = SnippetData::new(cm.clone(), None);
-    let fn_span = cm.span_substr(&foo, file_text, "fn foo(x: u32)", 0);
-    let x_span = cm.span_substr(&foo, file_text, "x", 0);
-    snippet.push(fn_span, false, Some(format!("fn_span")));
-    snippet.push(x_span, false, Some(format!("x_span")));
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("r#\"\n{}\"", text);
-    assert_eq!(text, &r#"
- ::: foo.rs
-  |>
-2 |>     fn foo(x: u32) {
-  |>     --------------
-  |>     |      |
-  |>     |      x_span
-  |>     fn_span
-"#[1..]);
-}
-
-#[test]
-fn span_overlap_label2() {
-    // Test that we don't put `x_span` to the right of its highlight,
-    // since there is another highlight that overlaps it. In this
-    // case, the overlap is only at the beginning, but it's still
-    // better to show the beginning more clearly.
-
-    let file_text = r#"
-    fn foo(x: u32) {
-    }
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut snippet = SnippetData::new(cm.clone(), None);
-    let fn_span = cm.span_substr(&foo, file_text, "fn foo(x", 0);
-    let x_span = cm.span_substr(&foo, file_text, "x: u32)", 0);
-    snippet.push(fn_span, false, Some(format!("fn_span")));
-    snippet.push(x_span, false, Some(format!("x_span")));
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("r#\"\n{}\"", text);
-    assert_eq!(text, &r#"
- ::: foo.rs
-  |>
-2 |>     fn foo(x: u32) {
-  |>     --------------
-  |>     |      |
-  |>     |      x_span
-  |>     fn_span
-"#[1..]);
-}
-
-#[test]
-fn span_overlap_label3() {
-    // Test that we don't put `x_span` to the right of its highlight,
-    // since there is another highlight that overlaps it. In this
-    // case, the overlap is only at the beginning, but it's still
-    // better to show the beginning more clearly.
-
-    let file_text = r#"
-    fn foo() {
-       let closure = || {
-           inner
-       };
-    }
-}
-"#;
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut snippet = SnippetData::new(cm.clone(), None);
-
-    let closure_span = {
-        let closure_start_span = cm.span_substr(&foo, file_text, "||", 0);
-        let closure_end_span = cm.span_substr(&foo, file_text, "}", 0);
-        splice(closure_start_span, closure_end_span)
-    };
-
-    let inner_span = cm.span_substr(&foo, file_text, "inner", 0);
-
-    snippet.push(closure_span, false, Some(format!("foo")));
-    snippet.push(inner_span, false, Some(format!("bar")));
-
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("r#\"\n{}\"", text);
-    assert_eq!(text, &r#"
- ::: foo.rs
-  |>
-3 |>        let closure = || {
-  |>                      - foo
-4 |>            inner
-  |>            ----- bar
-"#[1..]);
-}
-
-#[test]
-fn span_empty() {
-    // In one of the unit tests, we found that the parser sometimes
-    // gives empty spans, and in particular it supplied an EOF span
-    // like this one, which points at the very end. We want to
-    // fallback gracefully in this case.
-
-    let file_text = r#"
-fn main() {
-    struct Foo;
-
-    impl !Sync for Foo {}
-
-    unsafe impl Send for &'static Foo {
-    // error: cross-crate traits with a default impl, like `core::marker::Send`,
-    //        can only be implemented for a struct/enum type, not
-    //        `&'static Foo`
-}"#;
-
-
-    let cm = Rc::new(CodeMap::new());
-    let foo = cm.new_filemap_and_lines("foo.rs", None, file_text);
-
-    let mut rbrace_span = cm.span_substr(&foo, file_text, "}", 1);
-    rbrace_span.lo = rbrace_span.hi;
-
-    let mut snippet = SnippetData::new(cm.clone(), Some(rbrace_span));
-    snippet.push(rbrace_span, false, None);
-    let lines = snippet.render_lines();
-    let text: String = make_string(&lines);
-    println!("r#\"\n{}\"", text);
-    assert_eq!(text, &r#"
-  --> foo.rs:11:2
-   |>
-11 |> }
-   |>  -
-"#[1..]);
-}