From fc774e629fd805ef46566894da482ed8be680303 Mon Sep 17 00:00:00 2001 From: Esteban Küber Date: Wed, 11 Jan 2017 13:55:41 -0800 Subject: Teach Diagnostics to highlight text --- src/librustc_errors/diagnostic.rs | 56 ++++++++++++++++++--- src/librustc_errors/emitter.rs | 101 ++++++++++++++++++++++++++++---------- src/librustc_errors/snippet.rs | 1 + 3 files changed, 125 insertions(+), 33 deletions(-) (limited to 'src/librustc_errors') diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs index 730ca8f9e2e..ac39af20189 100644 --- a/src/librustc_errors/diagnostic.rs +++ b/src/librustc_errors/diagnostic.rs @@ -14,12 +14,13 @@ use RenderSpan; use RenderSpan::Suggestion; use std::fmt; use syntax_pos::{MultiSpan, Span}; +use snippet::Style; #[must_use] #[derive(Clone, Debug, PartialEq)] pub struct Diagnostic { pub level: Level, - pub message: String, + pub message: Vec<(String, Style)>, pub code: Option, pub span: MultiSpan, pub children: Vec, @@ -29,7 +30,7 @@ pub struct Diagnostic { #[derive(Clone, Debug, PartialEq)] pub struct SubDiagnostic { pub level: Level, - pub message: String, + pub message: Vec<(String, Style)>, pub span: MultiSpan, pub render_span: Option, } @@ -42,7 +43,7 @@ impl Diagnostic { pub fn new_with_code(level: Level, code: Option, message: &str) -> Self { Diagnostic { level: level, - message: message.to_owned(), + message: vec![(message.to_owned(), Style::NoStyle)], code: code, span: MultiSpan::new(), children: vec![], @@ -96,8 +97,14 @@ impl Diagnostic { -> &mut Self { // For now, just attach these as notes - self.note(&format!("expected {} `{}`{}", label, expected, expected_extra)); - self.note(&format!(" found {} `{}`{}", label, found, found_extra)); + self.highlighted_note(vec![ + (format!("expected {} `", label), Style::NoStyle), + (format!("{}", expected), Style::Highlight), + (format!("`{}\n", expected_extra), Style::NoStyle), + (format!(" found {} `", label), Style::NoStyle), + (format!("{}", found), Style::Highlight), + (format!("`{}", found_extra), Style::NoStyle), + ]); self } @@ -106,6 +113,11 @@ impl Diagnostic { self } + pub fn highlighted_note(&mut self, msg: Vec<(String, Style)>) -> &mut Self { + self.sub_with_highlights(Level::Note, msg, MultiSpan::new(), None); + self + } + pub fn span_note>(&mut self, sp: S, msg: &str) @@ -168,7 +180,11 @@ impl Diagnostic { self } - pub fn message(&self) -> &str { + pub fn message(&self) -> String { + self.message.iter().map(|i| i.0.to_owned()).collect::() + } + + pub fn styled_message(&self) -> &Vec<(String, Style)> { &self.message } @@ -193,10 +209,36 @@ impl Diagnostic { render_span: Option) { let sub = SubDiagnostic { level: level, - message: message.to_owned(), + message: vec![(message.to_owned(), Style::NoStyle)], span: span, render_span: render_span, }; self.children.push(sub); } + + /// Convenience function for internal use, clients should use one of the + /// public methods above. + fn sub_with_highlights(&mut self, + level: Level, + message: Vec<(String, Style)>, + span: MultiSpan, + render_span: Option) { + let sub = SubDiagnostic { + level: level, + message: message, + span: span, + render_span: render_span, + }; + self.children.push(sub); + } +} + +impl SubDiagnostic { + pub fn message(&self) -> String { + self.message.iter().map(|i| i.0.to_owned()).collect::() + } + + pub fn styled_message(&self) -> &Vec<(String, Style)> { + &self.message + } } diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 77c6c368364..5d758d322c7 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -33,7 +33,11 @@ impl Emitter for EmitterWriter { let mut primary_span = db.span.clone(); let mut children = db.children.clone(); self.fix_multispans_in_std_macros(&mut primary_span, &mut children); - self.emit_messages_default(&db.level, &db.message, &db.code, &primary_span, &children); + self.emit_messages_default(&db.level, + &db.styled_message(), + &db.code, + &primary_span, + &children); } } @@ -695,8 +699,8 @@ impl EmitterWriter { if spans_updated { children.push(SubDiagnostic { level: Level::Note, - message: "this error originates in a macro outside of the current crate" - .to_string(), + message: vec![("this error originates in a macro outside of the current crate" + .to_string(), Style::NoStyle)], span: MultiSpan::new(), render_span: None, }); @@ -704,8 +708,14 @@ impl EmitterWriter { } /// Add a left margin to every line but the first, given a padding length and the label being - /// displayed. - fn msg_with_padding(&self, msg: &str, padding: usize, label: &str) -> String { + /// displayed, keeping the provided highlighting. + fn msg_to_buffer(&self, + buffer: &mut StyledBuffer, + msg: &Vec<(String, Style)>, + padding: usize, + label: &str, + override_style: Option