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.
This commit is contained in:
parent
19311b6103
commit
06d9cc1d7a
10 changed files with 52 additions and 22 deletions
|
@ -97,12 +97,18 @@ impl Session {
|
||||||
pub fn span_end_note(&self, sp: Span, msg: &str) {
|
pub fn span_end_note(&self, sp: Span, msg: &str) {
|
||||||
self.diagnostic().span_end_note(sp, msg)
|
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) {
|
pub fn fileline_note(&self, sp: Span, msg: &str) {
|
||||||
self.diagnostic().fileline_note(sp, msg)
|
self.diagnostic().fileline_note(sp, msg)
|
||||||
}
|
}
|
||||||
pub fn note(&self, msg: &str) {
|
pub fn note(&self, msg: &str) {
|
||||||
self.diagnostic().handler().note(msg)
|
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) -> ! {
|
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
|
||||||
self.diagnostic().span_bug(sp, msg)
|
self.diagnostic().span_bug(sp, msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -624,6 +624,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
|
||||||
self.tcx.sess.span_end_note(s, m);
|
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 {
|
pub fn bckerr_to_string(&self, err: &BckError) -> String {
|
||||||
match err.code {
|
match err.code {
|
||||||
err_mutbl => {
|
err_mutbl => {
|
||||||
|
|
|
@ -1407,7 +1407,7 @@ impl<'a, 'tcx> ErrorReportingHelpers for InferCtxt<'a, 'tcx> {
|
||||||
opt_explicit_self, generics);
|
opt_explicit_self, generics);
|
||||||
let msg = format!("consider using an explicit lifetime \
|
let msg = format!("consider using an explicit lifetime \
|
||||||
parameter as shown: {}", suggested_fn);
|
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,
|
fn report_inference_failure(&self,
|
||||||
|
|
|
@ -35,7 +35,7 @@ use middle::typeck::infer::lub::Lub;
|
||||||
use middle::typeck::infer::glb::Glb;
|
use middle::typeck::infer::glb::Glb;
|
||||||
use syntax::codemap;
|
use syntax::codemap;
|
||||||
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
|
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 syntax::{ast, ast_map};
|
||||||
use util::ppaux::{ty_to_string, UserString};
|
use util::ppaux::{ty_to_string, UserString};
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ struct ExpectErrorEmitter {
|
||||||
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
|
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
|
||||||
match lvl {
|
match lvl {
|
||||||
Bug | Fatal | Error => { }
|
Bug | Fatal | Error => { }
|
||||||
Warning | Note => { return; }
|
Warning | Note | Help => { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("Error: {}", msg);
|
debug!("Error: {}", msg);
|
||||||
|
|
|
@ -105,6 +105,9 @@ impl SpanHandler {
|
||||||
pub fn span_end_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);
|
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) {
|
pub fn fileline_note(&self, sp: Span, msg: &str) {
|
||||||
self.handler.custom_emit(&self.cm, FileLine(sp), msg, Note);
|
self.handler.custom_emit(&self.cm, FileLine(sp), msg, Note);
|
||||||
}
|
}
|
||||||
|
@ -164,6 +167,9 @@ impl Handler {
|
||||||
pub fn note(&self, msg: &str) {
|
pub fn note(&self, msg: &str) {
|
||||||
self.emit.borrow_mut().emit(None, msg, None, Note);
|
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) -> ! {
|
pub fn bug(&self, msg: &str) -> ! {
|
||||||
self.emit.borrow_mut().emit(None, msg, None, Bug);
|
self.emit.borrow_mut().emit(None, msg, None, Bug);
|
||||||
fail!(ExplicitBug);
|
fail!(ExplicitBug);
|
||||||
|
@ -216,6 +222,7 @@ pub enum Level {
|
||||||
Error,
|
Error,
|
||||||
Warning,
|
Warning,
|
||||||
Note,
|
Note,
|
||||||
|
Help,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Show for Level {
|
impl fmt::Show for Level {
|
||||||
|
@ -227,6 +234,7 @@ impl fmt::Show for Level {
|
||||||
Fatal | Error => "error".fmt(f),
|
Fatal | Error => "error".fmt(f),
|
||||||
Warning => "warning".fmt(f),
|
Warning => "warning".fmt(f),
|
||||||
Note => "note".fmt(f),
|
Note => "note".fmt(f),
|
||||||
|
Help => "help".fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -236,7 +244,8 @@ impl Level {
|
||||||
match self {
|
match self {
|
||||||
Bug | Fatal | Error => term::color::BRIGHT_RED,
|
Bug | Fatal | Error => term::color::BRIGHT_RED,
|
||||||
Warning => term::color::BRIGHT_YELLOW,
|
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) => {
|
Some(code) => {
|
||||||
let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
|
let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
|
||||||
try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
|
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 => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
@ -401,7 +401,20 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
|
||||||
try!(highlight_lines(dst, cm, sp, lvl, lines));
|
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,
|
fn highlight_lines(err: &mut EmitterWriter,
|
||||||
|
|
|
@ -575,6 +575,10 @@ impl<'a> ExtCtxt<'a> {
|
||||||
self.print_backtrace();
|
self.print_backtrace();
|
||||||
self.parse_sess.span_diagnostic.span_note(sp, msg);
|
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) -> ! {
|
pub fn bug(&self, msg: &str) -> ! {
|
||||||
self.print_backtrace();
|
self.print_backtrace();
|
||||||
self.parse_sess.span_diagnostic.handler().bug(msg);
|
self.parse_sess.span_diagnostic.handler().bug(msg);
|
||||||
|
|
|
@ -959,6 +959,9 @@ impl<'a> Parser<'a> {
|
||||||
pub fn span_note(&mut self, sp: Span, m: &str) {
|
pub fn span_note(&mut self, sp: Span, m: &str) {
|
||||||
self.sess.span_diagnostic.span_note(sp, m)
|
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) -> ! {
|
pub fn bug(&mut self, m: &str) -> ! {
|
||||||
self.sess.span_diagnostic.span_bug(self.span, m)
|
self.sess.span_diagnostic.span_bug(self.span, m)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl<'r> Itble<'r, uint, Range<uint>> for (uint, uint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &T) -> bool {
|
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 cont_iter = cont.iter(); //~ ERROR: cannot infer
|
||||||
let result = cont_iter.fold(Some(0u16), |state, val| {
|
let result = cont_iter.fold(Some(0u16), |state, val| {
|
||||||
state.map_or(None, |mask| {
|
state.map_or(None, |mask| {
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
struct Bar<'x, 'y, 'z> { bar: &'y int, baz: int }
|
struct Bar<'x, 'y, 'z> { bar: &'y int, baz: int }
|
||||||
fn bar1<'a>(x: &Bar) -> (&'a int, &'a int, &'a 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)
|
(x.bar, &x.baz, &x.baz)
|
||||||
//~^ ERROR: cannot infer
|
//~^ ERROR: cannot infer
|
||||||
//~^^ 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) {
|
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)
|
(x.bar, &x.baz, &x.baz)
|
||||||
//~^ ERROR: cannot infer
|
//~^ ERROR: cannot infer
|
||||||
//~^^ ERROR: cannot infer
|
//~^^ ERROR: cannot infer
|
||||||
|
|
|
@ -12,23 +12,23 @@
|
||||||
|
|
||||||
struct Foo<'x> { bar: int }
|
struct Foo<'x> { bar: int }
|
||||||
fn foo1<'a>(x: &Foo) -> &'a 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
|
&x.bar //~ ERROR: cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo2<'a, 'b>(x: &'a Foo) -> &'b int {
|
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
|
&x.bar //~ ERROR: cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo3<'a>(x: &Foo) -> (&'a int, &'a int) {
|
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
|
(&x.bar, &x.bar) //~ ERROR: cannot infer
|
||||||
//~^ ERROR: cannot infer
|
//~^ ERROR: cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
fn foo4<'a, 'b>(x: &'a Foo) -> (&'b int, &'a int, &'b int) {
|
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
|
(&x.bar, &x.bar, &x.bar) //~ ERROR: cannot infer
|
||||||
//~^ 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 }
|
struct Dog<'y> { dog: &'y int }
|
||||||
|
|
||||||
fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x 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
|
x.t.dog //~ ERROR: cannot infer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue