提交 06d9cc1d 编写于 作者: P P1start

Add help diagnostic messages

This adds ‘help’ diagnostic messages to rustc. This is used for anything that
provides help to the user, particularly the `--explain` messages that were
previously integrated into the relevant error message.
上级 19311b61
......@@ -97,12 +97,18 @@ pub fn span_note(&self, sp: Span, msg: &str) {
pub fn span_end_note(&self, sp: Span, msg: &str) {
self.diagnostic().span_end_note(sp, msg)
}
pub fn span_help(&self, sp: Span, msg: &str) {
self.diagnostic().span_help(sp, msg)
}
pub fn fileline_note(&self, sp: Span, msg: &str) {
self.diagnostic().fileline_note(sp, msg)
}
pub fn note(&self, msg: &str) {
self.diagnostic().handler().note(msg)
}
pub fn help(&self, msg: &str) {
self.diagnostic().handler().note(msg)
}
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
self.diagnostic().span_bug(sp, msg)
}
......
......@@ -624,6 +624,10 @@ pub fn span_end_note(&self, s: Span, m: &str) {
self.tcx.sess.span_end_note(s, m);
}
pub fn span_help(&self, s: Span, m: &str) {
self.tcx.sess.span_help(s, m);
}
pub fn bckerr_to_string(&self, err: &BckError) -> String {
match err.code {
err_mutbl => {
......
......@@ -1407,7 +1407,7 @@ fn give_expl_lifetime_param(&self,
opt_explicit_self, generics);
let msg = format!("consider using an explicit lifetime \
parameter as shown: {}", suggested_fn);
self.tcx.sess.span_note(span, msg.as_slice());
self.tcx.sess.span_help(span, msg.as_slice());
}
fn report_inference_failure(&self,
......
......@@ -35,7 +35,7 @@
use middle::typeck::infer::glb::Glb;
use syntax::codemap;
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
use syntax::{ast, ast_map};
use util::ppaux::{ty_to_string, UserString};
......@@ -59,7 +59,7 @@ struct ExpectErrorEmitter {
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
match lvl {
Bug | Fatal | Error => { }
Warning | Note => { return; }
Warning | Note | Help => { return; }
}
debug!("Error: {}", msg);
......
......@@ -105,6 +105,9 @@ pub fn span_note(&self, sp: Span, msg: &str) {
pub fn span_end_note(&self, sp: Span, msg: &str) {
self.handler.custom_emit(&self.cm, FullSpan(sp), msg, Note);
}
pub fn span_help(&self, sp: Span, msg: &str) {
self.handler.emit(Some((&self.cm, sp)), msg, Help);
}
pub fn fileline_note(&self, sp: Span, msg: &str) {
self.handler.custom_emit(&self.cm, FileLine(sp), msg, Note);
}
......@@ -164,6 +167,9 @@ pub fn warn(&self, msg: &str) {
pub fn note(&self, msg: &str) {
self.emit.borrow_mut().emit(None, msg, None, Note);
}
pub fn help(&self, msg: &str) {
self.emit.borrow_mut().emit(None, msg, None, Help);
}
pub fn bug(&self, msg: &str) -> ! {
self.emit.borrow_mut().emit(None, msg, None, Bug);
fail!(ExplicitBug);
......@@ -216,6 +222,7 @@ pub enum Level {
Error,
Warning,
Note,
Help,
}
impl fmt::Show for Level {
......@@ -227,6 +234,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Fatal | Error => "error".fmt(f),
Warning => "warning".fmt(f),
Note => "note".fmt(f),
Help => "help".fmt(f),
}
}
}
......@@ -236,7 +244,8 @@ fn color(self) -> term::color::Color {
match self {
Bug | Fatal | Error => term::color::BRIGHT_RED,
Warning => term::color::BRIGHT_YELLOW,
Note => term::color::BRIGHT_GREEN
Note => term::color::BRIGHT_GREEN,
Help => term::color::BRIGHT_CYAN,
}
}
}
......@@ -293,15 +302,6 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
Some(code) => {
let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
Some(_) => {
try!(write!(&mut dst.dst,
" (pass `--explain {}` to see a detailed explanation)",
code
));
}
None => ()
}
}
None => ()
}
......@@ -401,7 +401,20 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
try!(highlight_lines(dst, cm, sp, lvl, lines));
}
}
print_macro_backtrace(dst, cm, sp)
try!(print_macro_backtrace(dst, cm, sp));
match code {
Some(code) =>
match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
Some(_) => {
try!(print_diagnostic(dst, ss.as_slice(), Help,
format!("pass `--explain {}` to see a detailed \
explanation", code).as_slice(), None));
}
None => ()
},
None => (),
}
Ok(())
}
fn highlight_lines(err: &mut EmitterWriter,
......
......@@ -575,6 +575,10 @@ pub fn span_note(&self, sp: Span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_note(sp, msg);
}
pub fn span_help(&self, sp: Span, msg: &str) {
self.print_backtrace();
self.parse_sess.span_diagnostic.span_help(sp, msg);
}
pub fn bug(&self, msg: &str) -> ! {
self.print_backtrace();
self.parse_sess.span_diagnostic.handler().bug(msg);
......
......@@ -959,6 +959,9 @@ pub fn span_fatal(&mut self, sp: Span, m: &str) -> ! {
pub fn span_note(&mut self, sp: Span, m: &str) {
self.sess.span_diagnostic.span_note(sp, m)
}
pub fn span_help(&mut self, sp: Span, m: &str) {
self.sess.span_diagnostic.span_help(sp, m)
}
pub fn bug(&mut self, m: &str) -> ! {
self.sess.span_diagnostic.span_bug(self.span, m)
}
......
......@@ -22,7 +22,7 @@ fn iter(&'r self) -> Range<uint> {
}
fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &T) -> bool {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &'r T) -> bool
//~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &'r T) -> bool
let cont_iter = cont.iter(); //~ ERROR: cannot infer
let result = cont_iter.fold(Some(0u16), |state, val| {
state.map_or(None, |mask| {
......
......@@ -12,7 +12,7 @@
struct Bar<'x, 'y, 'z> { bar: &'y int, baz: int }
fn bar1<'a>(x: &Bar) -> (&'a int, &'a int, &'a int) {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a int, &'a int, &'a int)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a int, &'a int, &'a int)
(x.bar, &x.baz, &x.baz)
//~^ ERROR: cannot infer
//~^^ ERROR: cannot infer
......@@ -20,7 +20,7 @@ fn bar1<'a>(x: &Bar) -> (&'a int, &'a int, &'a int) {
}
fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a int, &'a int, &'a int) {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a int, &'a int, &'a int)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a int, &'a int, &'a int)
(x.bar, &x.baz, &x.baz)
//~^ ERROR: cannot infer
//~^^ ERROR: cannot infer
......
......@@ -12,23 +12,23 @@
struct Foo<'x> { bar: int }
fn foo1<'a>(x: &Foo) -> &'a int {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int
&x.bar //~ ERROR: cannot infer
}
fn foo2<'a, 'b>(x: &'a Foo) -> &'b int {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo2<'a>(x: &'a Foo) -> &'a int
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo2<'a>(x: &'a Foo) -> &'a int
&x.bar //~ ERROR: cannot infer
}
fn foo3<'a>(x: &Foo) -> (&'a int, &'a int) {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a int, &'a int)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a int, &'a int)
(&x.bar, &x.bar) //~ ERROR: cannot infer
//~^ ERROR: cannot infer
}
fn foo4<'a, 'b>(x: &'a Foo) -> (&'b int, &'a int, &'b int) {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a int, &'a int, &'a int)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a int, &'a int, &'a int)
(&x.bar, &x.bar, &x.bar) //~ ERROR: cannot infer
//~^ ERROR: cannot infer
}
......@@ -37,7 +37,7 @@ struct Cat<'x, T> { cat: &'x int, t: T }
struct Dog<'y> { dog: &'y int }
fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x int {
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x int
//~^ HELP: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x int
x.t.dog //~ ERROR: cannot infer
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册