diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 367b85ac726db..a52628ceb47ab 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -21,6 +21,8 @@ use std::io::prelude::*;
 use std::io;
 use std::rc::Rc;
 use term;
+use std::collections::HashMap;
+use std::cmp::min;
 
 /// Emitter trait for emitting errors.
 pub trait Emitter {
@@ -156,15 +158,6 @@ impl EmitterWriter {
                 }
                 let lo = cm.lookup_char_pos(span_label.span.lo);
                 let mut hi = cm.lookup_char_pos(span_label.span.hi);
-                let mut is_minimized = false;
-
-                // If the span is long multi-line, simplify down to the span of one character
-                let max_multiline_span_length = 8;
-                if lo.line != hi.line && (hi.line - lo.line) > max_multiline_span_length {
-                    hi.line = lo.line;
-                    hi.col = CharPos(lo.col.0 + 1);
-                    is_minimized = 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
@@ -175,16 +168,7 @@ impl EmitterWriter {
                     hi.col = CharPos(lo.col.0 + 1);
                 }
 
-                let mut ann = Annotation {
-                    start_col: lo.col.0,
-                    end_col: hi.col.0,
-                    is_primary: span_label.is_primary,
-                    label: span_label.label.clone(),
-                    annotation_type: AnnotationType::Singleline,
-                };
-                if is_minimized {
-                    ann.annotation_type = AnnotationType::Minimized;
-                } else if lo.line != hi.line {
+                let ann_type = if lo.line != hi.line {
                     let ml = MultilineAnnotation {
                         depth: 1,
                         line_start: lo.line,
@@ -194,8 +178,17 @@ impl EmitterWriter {
                         is_primary: span_label.is_primary,
                         label: span_label.label.clone(),
                     };
-                    ann.annotation_type = AnnotationType::Multiline(ml.clone());
-                    multiline_annotations.push((lo.file.clone(), ml));
+                    multiline_annotations.push((lo.file.clone(), ml.clone()));
+                    AnnotationType::Multiline(ml)
+                } else {
+                    AnnotationType::Singleline
+                };
+                let ann = Annotation {
+                    start_col: lo.col.0,
+                    end_col: hi.col.0,
+                    is_primary: span_label.is_primary,
+                    label: span_label.label.clone(),
+                    annotation_type: ann_type,
                 };
 
                 if !ann.is_multiline() {
@@ -233,9 +226,15 @@ impl EmitterWriter {
                 max_depth = ann.depth;
             }
             add_annotation_to_file(&mut output, file.clone(), ann.line_start, ann.as_start());
-            for line in ann.line_start + 1..ann.line_end {
+            let middle = min(ann.line_start + 4, ann.line_end);
+            for line in ann.line_start + 1..middle {
                 add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
             }
+            if middle < ann.line_end - 1 {
+                for line in ann.line_end - 1..ann.line_end {
+                    add_annotation_to_file(&mut output, file.clone(), line, ann.as_line());
+                }
+            }
             add_annotation_to_file(&mut output, file, ann.line_end, ann.as_end());
         }
         for file_vec in output.iter_mut() {
@@ -249,16 +248,11 @@ impl EmitterWriter {
                           file: Rc<FileMap>,
                           line: &Line,
                           width_offset: usize,
-                          multiline_depth: usize) {
+                          code_offset: usize) -> Vec<(usize, Style)> {
         let source_string = file.get_line(line.line_index - 1)
             .unwrap_or("");
 
         let line_offset = buffer.num_lines();
-        let code_offset = if multiline_depth == 0 {
-            width_offset
-        } else {
-            width_offset + multiline_depth + 1
-        };
 
         // First create the source line we will highlight.
         buffer.puts(line_offset, code_offset, &source_string, Style::Quotation);
@@ -286,7 +280,7 @@ impl EmitterWriter {
         //      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 `~`.
+        // and "annotations lines", where the highlight lines have the `^`.
 
         // Sort the annotations by (start, end col)
         let mut annotations = line.annotations.clone();
@@ -410,25 +404,9 @@ impl EmitterWriter {
         // If there are no annotations or the only annotations on this line are
         // MultilineLine, then there's only code being shown, stop processing.
         if line.annotations.is_empty() || line.annotations.iter()
-            .filter(|a| {
-                // Set the multiline annotation vertical lines to the left of
-                // the code in this line.
-                if let AnnotationType::MultilineLine(depth) = a.annotation_type {
-                    buffer.putc(line_offset,
-                                width_offset + depth - 1,
-                                '|',
-                                if a.is_primary {
-                                    Style::UnderlinePrimary
-                                } else {
-                                    Style::UnderlineSecondary
-                                });
-                    false
-                } else {
-                    true
-                }
-            }).collect::<Vec<_>>().len() == 0
+            .filter(|a| !a.is_line()).collect::<Vec<_>>().len() == 0
         {
-            return;
+            return vec![];
         }
 
         // Write the colunmn separator.
@@ -483,8 +461,7 @@ impl EmitterWriter {
             }
         }
 
-        // Write the vertical lines for multiline spans and for labels that are
-        // on a different line as the underline.
+        // Write the vertical lines for labels that are on a different line as the underline.
         //
         // After this we will have:
         //
@@ -492,7 +469,7 @@ impl EmitterWriter {
         //   |  __________
         //   | |    |
         //   | |
-        // 3 | |
+        // 3 |
         // 4 | | }
         //   | |_
         for &(pos, annotation) in &annotations_position {
@@ -528,16 +505,6 @@ impl EmitterWriter {
                                     style);
                     }
                 }
-                AnnotationType::MultilineLine(depth) => {
-                    // the first line will have already be filled when we checked
-                    // wether there were any annotations for this line.
-                    for p in line_offset + 1..line_offset + line_len + 2 {
-                        buffer.putc(p,
-                                    width_offset + depth - 1,
-                                    '|',
-                                    style);
-                    }
-                }
                 _ => (),
             }
         }
@@ -548,11 +515,11 @@ impl EmitterWriter {
         //
         // 2 |   fn foo() {
         //   |  __________ starting here...
-        //   | |    |
-        //   | |    something about `foo`
-        // 3 | |
-        // 4 | | }
-        //   | |_  ...ending here: test
+        //   |      |
+        //   |      something about `foo`
+        // 3 |
+        // 4 |   }
+        //   |  _  ...ending here: test
         for &(pos, annotation) in &annotations_position {
             let style = if annotation.is_primary {
                 Style::LabelPrimary
@@ -591,11 +558,11 @@ impl EmitterWriter {
         //
         // 2 |   fn foo() {
         //   |  ____-_____^ starting here...
-        //   | |    |
-        //   | |    something about `foo`
-        // 3 | |
-        // 4 | | }
-        //   | |_^  ...ending here: test
+        //   |      |
+        //   |      something about `foo`
+        // 3 |
+        // 4 |   }
+        //   |  _^  ...ending here: test
         for &(_, annotation) in &annotations_position {
             let (underline, style) = if annotation.is_primary {
                 ('^', Style::UnderlinePrimary)
@@ -609,6 +576,20 @@ impl EmitterWriter {
                             style);
             }
         }
+        annotations_position.iter().filter_map(|&(_, annotation)| {
+            match annotation.annotation_type {
+                AnnotationType::MultilineStart(p) | AnnotationType::MultilineEnd(p) => {
+                    let style = if annotation.is_primary {
+                        Style::LabelPrimary
+                    } else {
+                        Style::LabelSecondary
+                    };
+                    Some((p, style))
+                },
+                _ => None
+            }
+
+        }).collect::<Vec<_>>()
     }
 
     fn get_multispan_max_line_num(&mut self, msp: &MultiSpan) -> usize {
@@ -902,22 +883,64 @@ impl EmitterWriter {
             let buffer_msg_line_offset = buffer.num_lines();
             draw_col_separator_no_space(&mut buffer, buffer_msg_line_offset, max_line_num_len + 1);
 
+            // Contains the vertical lines' positions for active multiline annotations
+            let mut multilines = HashMap::new();
+
             // Next, output the annotate source for this file
             for line_idx in 0..annotated_file.lines.len() {
-                self.render_source_line(&mut buffer,
-                                        annotated_file.file.clone(),
-                                        &annotated_file.lines[line_idx],
-                                        3 + max_line_num_len,
-                                        annotated_file.multiline_depth);
+                let previous_buffer_line = buffer.num_lines();
+
+                let width_offset = 3 + max_line_num_len;
+                let code_offset = if annotated_file.multiline_depth == 0 {
+                    width_offset
+                } else {
+                    width_offset + annotated_file.multiline_depth + 1
+                };
+
+                let depths = self.render_source_line(&mut buffer,
+                                                     annotated_file.file.clone(),
+                                                     &annotated_file.lines[line_idx],
+                                                     width_offset,
+                                                     code_offset);
 
+                let mut to_add = HashMap::new();
+
+                for (depth, style) in depths {
+                    if multilines.get(&depth).is_some() {
+                        multilines.remove(&depth);
+                    } else {
+                        to_add.insert(depth, style);
+                    }
+                }
+
+                // Set the multiline annotation vertical lines to the left of
+                // the code in this line.
+                for (depth, style) in &multilines {
+                    for line in previous_buffer_line..buffer.num_lines() {
+                        draw_multiline_line(&mut buffer,
+                                            line,
+                                            width_offset,
+                                            *depth,
+                                            *style);
+                    }
+                }
                 // check to see if we need to print out or elide lines that come between
-                // this annotated line and the next one
+                // this annotated line and the next one.
                 if line_idx < (annotated_file.lines.len() - 1) {
                     let line_idx_delta = annotated_file.lines[line_idx + 1].line_index -
                                          annotated_file.lines[line_idx].line_index;
                     if line_idx_delta > 2 {
                         let last_buffer_line_num = buffer.num_lines();
                         buffer.puts(last_buffer_line_num, 0, "...", Style::LineNumber);
+
+                        // Set the multiline annotation vertical lines on `...` bridging line.
+                        for (depth, style) in &multilines {
+                            draw_multiline_line(&mut buffer,
+                                                last_buffer_line_num,
+                                                width_offset,
+                                                *depth,
+                                                *style);
+                        }
                     } else if line_idx_delta == 2 {
                         let unannotated_line = annotated_file.file
                             .get_line(annotated_file.lines[line_idx].line_index)
@@ -932,11 +955,21 @@ impl EmitterWriter {
                                     Style::LineNumber);
                         draw_col_separator(&mut buffer, last_buffer_line_num, 1 + max_line_num_len);
                         buffer.puts(last_buffer_line_num,
-                                    3 + max_line_num_len,
+                                    code_offset,
                                     &unannotated_line,
                                     Style::Quotation);
+
+                        for (depth, style) in &multilines {
+                            draw_multiline_line(&mut buffer,
+                                                last_buffer_line_num,
+                                                width_offset,
+                                                *depth,
+                                                *style);
+                        }
                     }
                 }
+
+                multilines.extend(&to_add);
             }
         }
 
@@ -1085,6 +1118,15 @@ fn draw_note_separator(buffer: &mut StyledBuffer, line: usize, col: usize) {
     buffer.puts(line, col, "= ", Style::LineNumber);
 }
 
+fn draw_multiline_line(buffer: &mut StyledBuffer,
+                       line: usize,
+                       offset: usize,
+                       depth: usize,
+                       style: Style)
+{
+    buffer.putc(line, offset + depth - 1, '|', style);
+}
+
 fn num_overlap(a_start: usize, a_end: usize, b_start: usize, b_end:usize, inclusive: bool) -> bool {
     let extra = if inclusive {
         1
diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs
index 5debbf4d37c20..9aa4682e1afcb 100644
--- a/src/librustc_errors/snippet.rs
+++ b/src/librustc_errors/snippet.rs
@@ -97,9 +97,6 @@ pub enum AnnotationType {
     /// Annotation under a single line of code
     Singleline,
 
-    /// Annotation under the first character of a multiline span
-    Minimized,
-
     /// Annotation enclosing the first and last character of a multiline span
     Multiline(MultilineAnnotation),
 
@@ -118,6 +115,9 @@ pub enum AnnotationType {
     /// Annotation marking the last character of a fully shown multiline span
     MultilineEnd(usize),
     /// Line at the left enclosing the lines of a fully shown multiline span
+    // Just a placeholder for the drawing algorithm, to know that it shouldn't skip the first 4
+    // and last 2 lines of code. The actual line is drawn in `emit_message_default` and not in
+    // `draw_multiline_line`.
     MultilineLine(usize),
 }
 
@@ -144,13 +144,6 @@ pub struct Annotation {
 }
 
 impl Annotation {
-    pub fn is_minimized(&self) -> bool {
-        match self.annotation_type {
-            AnnotationType::Minimized => true,
-            _ => false,
-        }
-    }
-
     /// Wether this annotation is a vertical line placeholder.
     pub fn is_line(&self) -> bool {
         if let AnnotationType::MultilineLine(_) = self.annotation_type {
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index c537a0ee16644..a74f59b004bb7 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -932,3 +932,137 @@ error: foo
 
 "#);
 }
+
+#[test]
+fn long_snippet() {
+    test_harness(r#"
+fn foo() {
+  X0 Y0 Z0
+  X1 Y1 Z1
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+  X2 Y2 Z2
+  X3 Y3 Z3
+}
+"#,
+    vec![
+        SpanLabel {
+            start: Position {
+                string: "Y0",
+                count: 1,
+            },
+            end: Position {
+                string: "X1",
+                count: 1,
+            },
+            label: "`X` is a good letter",
+        },
+        SpanLabel {
+            start: Position {
+                string: "Z1",
+                count: 1,
+            },
+            end: Position {
+                string: "Z3",
+                count: 1,
+            },
+            label: "`Y` is a good letter too",
+        },
+    ],
+    r#"
+error: foo
+  --> test.rs:3:6
+   |
+3  |      X0 Y0 Z0
+   |   ______^ starting here...
+4  |  |   X1 Y1 Z1
+   |  |____^____- starting here...
+   | ||____|
+   | |     ...ending here: `X` is a good letter
+5  | |  1
+6  | |  2
+7  | |  3
+...  |
+15 | |    X2 Y2 Z2
+16 | |    X3 Y3 Z3
+   | |___________- ...ending here: `Y` is a good letter too
+
+"#);
+}
+
+#[test]
+fn long_snippet_multiple_spans() {
+    test_harness(r#"
+fn foo() {
+  X0 Y0 Z0
+1
+2
+3
+  X1 Y1 Z1
+4
+5
+6
+  X2 Y2 Z2
+7
+8
+9
+10
+  X3 Y3 Z3
+}
+"#,
+    vec![
+        SpanLabel {
+            start: Position {
+                string: "Y0",
+                count: 1,
+            },
+            end: Position {
+                string: "Y3",
+                count: 1,
+            },
+            label: "`Y` is a good letter",
+        },
+        SpanLabel {
+            start: Position {
+                string: "Z1",
+                count: 1,
+            },
+            end: Position {
+                string: "Z2",
+                count: 1,
+            },
+            label: "`Z` is a good letter too",
+        },
+    ],
+    r#"
+error: foo
+  --> test.rs:3:6
+   |
+3  |      X0 Y0 Z0
+   |   ______^ starting here...
+4  |  | 1
+5  |  | 2
+6  |  | 3
+7  |  |   X1 Y1 Z1
+   |  |_________- starting here...
+8  | || 4
+9  | || 5
+10 | || 6
+11 | ||   X2 Y2 Z2
+   | ||__________- ...ending here: `Z` is a good letter too
+...   |
+15 |  | 10
+16 |  |   X3 Y3 Z3
+   |  |_______^ ...ending here: `Y` is a good letter
+
+"#);
+}
+
diff --git a/src/test/ui/span/impl-wrong-item-for-trait.stderr b/src/test/ui/span/impl-wrong-item-for-trait.stderr
index 717f5ee200c74..367af12bb6b1c 100644
--- a/src/test/ui/span/impl-wrong-item-for-trait.stderr
+++ b/src/test/ui/span/impl-wrong-item-for-trait.stderr
@@ -24,8 +24,7 @@ error[E0046]: not all trait items implemented, missing: `bar`
 23 | |     //~^ ERROR E0046
 24 | |     //~| NOTE missing `bar` in implementation
 25 | |     const bar: u64 = 1;
-26 | |     //~^ ERROR E0323
-27 | |     //~| NOTE does not match trait
+...  |
 28 | |     const MY_CONST: u32 = 1;
 29 | | }
    | |_^ ...ending here: missing `bar` in implementation
@@ -50,8 +49,7 @@ error[E0046]: not all trait items implemented, missing: `MY_CONST`
 34 | |     //~^ ERROR E0046
 35 | |     //~| NOTE missing `MY_CONST` in implementation
 36 | |     fn bar(&self) {}
-37 | |     fn MY_CONST() {}
-38 | |     //~^ ERROR E0324
+...  |
 39 | |     //~| NOTE does not match trait
 40 | | }
    | |_^ ...ending here: missing `MY_CONST` in implementation
@@ -76,8 +74,7 @@ error[E0046]: not all trait items implemented, missing: `bar`
 45 | |     //~^ ERROR E0046
 46 | |     //~| NOTE missing `bar` in implementation
 47 | |     type bar = u64;
-48 | |     //~^ ERROR E0325
-49 | |     //~| NOTE does not match trait
+...  |
 50 | |     const MY_CONST: u32 = 1;
 51 | | }
    | |_^ ...ending here: missing `bar` in implementation
diff --git a/src/test/ui/span/issue-23729.stderr b/src/test/ui/span/issue-23729.stderr
index 493ca01778bc1..701576ff6f475 100644
--- a/src/test/ui/span/issue-23729.stderr
+++ b/src/test/ui/span/issue-23729.stderr
@@ -1,8 +1,15 @@
 error[E0046]: not all trait items implemented, missing: `Item`
   --> $DIR/issue-23729.rs:20:9
    |
-20 |         impl Iterator for Recurrence {
-   |         ^ missing `Item` in implementation
+20 |           impl Iterator for Recurrence {
+   |  _________^ starting here...
+21 | |             //~^ ERROR E0046
+22 | |             //~| NOTE missing `Item` in implementation
+23 | |             //~| NOTE `Item` from trait: `type Item;`
+...  |
+36 | |             }
+37 | |         }
+   | |_________^ ...ending here: missing `Item` in implementation
    |
    = note: `Item` from trait: `type Item;`
 
diff --git a/src/test/ui/span/issue-23827.stderr b/src/test/ui/span/issue-23827.stderr
index 6c1c246753011..457fed34ff1ad 100644
--- a/src/test/ui/span/issue-23827.stderr
+++ b/src/test/ui/span/issue-23827.stderr
@@ -6,8 +6,7 @@ error[E0046]: not all trait items implemented, missing: `Output`
 37 | |     //~^ ERROR E0046
 38 | |     //~| NOTE missing `Output` in implementation
 39 | |     //~| NOTE `Output` from trait: `type Output;`
-40 | |     extern "rust-call" fn call_once(self, (comp,): (C,)) -> Prototype {
-41 | |         Fn::call(&self, (comp,))
+...  |
 42 | |     }
 43 | | }
    | |_^ ...ending here: missing `Output` in implementation