Skip to content

Commit 06d9cc1

Browse files
committed
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.
1 parent 19311b6 commit 06d9cc1

File tree

10 files changed

+52
-22
lines changed

10 files changed

+52
-22
lines changed

src/librustc/driver/session.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,18 @@ impl Session {
9797
pub fn span_end_note(&self, sp: Span, msg: &str) {
9898
self.diagnostic().span_end_note(sp, msg)
9999
}
100+
pub fn span_help(&self, sp: Span, msg: &str) {
101+
self.diagnostic().span_help(sp, msg)
102+
}
100103
pub fn fileline_note(&self, sp: Span, msg: &str) {
101104
self.diagnostic().fileline_note(sp, msg)
102105
}
103106
pub fn note(&self, msg: &str) {
104107
self.diagnostic().handler().note(msg)
105108
}
109+
pub fn help(&self, msg: &str) {
110+
self.diagnostic().handler().note(msg)
111+
}
106112
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
107113
self.diagnostic().span_bug(sp, msg)
108114
}

src/librustc/middle/borrowck/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
624624
self.tcx.sess.span_end_note(s, m);
625625
}
626626

627+
pub fn span_help(&self, s: Span, m: &str) {
628+
self.tcx.sess.span_help(s, m);
629+
}
630+
627631
pub fn bckerr_to_string(&self, err: &BckError) -> String {
628632
match err.code {
629633
err_mutbl => {

src/librustc/middle/typeck/infer/error_reporting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ impl<'a, 'tcx> ErrorReportingHelpers for InferCtxt<'a, 'tcx> {
14071407
opt_explicit_self, generics);
14081408
let msg = format!("consider using an explicit lifetime \
14091409
parameter as shown: {}", suggested_fn);
1410-
self.tcx.sess.span_note(span, msg.as_slice());
1410+
self.tcx.sess.span_help(span, msg.as_slice());
14111411
}
14121412

14131413
fn report_inference_failure(&self,

src/librustc/middle/typeck/infer/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use middle::typeck::infer::lub::Lub;
3535
use middle::typeck::infer::glb::Glb;
3636
use syntax::codemap;
3737
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
38-
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
38+
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
3939
use syntax::{ast, ast_map};
4040
use util::ppaux::{ty_to_string, UserString};
4141

@@ -59,7 +59,7 @@ struct ExpectErrorEmitter {
5959
fn remove_message(e: &mut ExpectErrorEmitter, msg: &str, lvl: Level) {
6060
match lvl {
6161
Bug | Fatal | Error => { }
62-
Warning | Note => { return; }
62+
Warning | Note | Help => { return; }
6363
}
6464

6565
debug!("Error: {}", msg);

src/libsyntax/diagnostic.rs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ impl SpanHandler {
105105
pub fn span_end_note(&self, sp: Span, msg: &str) {
106106
self.handler.custom_emit(&self.cm, FullSpan(sp), msg, Note);
107107
}
108+
pub fn span_help(&self, sp: Span, msg: &str) {
109+
self.handler.emit(Some((&self.cm, sp)), msg, Help);
110+
}
108111
pub fn fileline_note(&self, sp: Span, msg: &str) {
109112
self.handler.custom_emit(&self.cm, FileLine(sp), msg, Note);
110113
}
@@ -164,6 +167,9 @@ impl Handler {
164167
pub fn note(&self, msg: &str) {
165168
self.emit.borrow_mut().emit(None, msg, None, Note);
166169
}
170+
pub fn help(&self, msg: &str) {
171+
self.emit.borrow_mut().emit(None, msg, None, Help);
172+
}
167173
pub fn bug(&self, msg: &str) -> ! {
168174
self.emit.borrow_mut().emit(None, msg, None, Bug);
169175
fail!(ExplicitBug);
@@ -216,6 +222,7 @@ pub enum Level {
216222
Error,
217223
Warning,
218224
Note,
225+
Help,
219226
}
220227

221228
impl fmt::Show for Level {
@@ -227,6 +234,7 @@ impl fmt::Show for Level {
227234
Fatal | Error => "error".fmt(f),
228235
Warning => "warning".fmt(f),
229236
Note => "note".fmt(f),
237+
Help => "help".fmt(f),
230238
}
231239
}
232240
}
@@ -236,7 +244,8 @@ impl Level {
236244
match self {
237245
Bug | Fatal | Error => term::color::BRIGHT_RED,
238246
Warning => term::color::BRIGHT_YELLOW,
239-
Note => term::color::BRIGHT_GREEN
247+
Note => term::color::BRIGHT_GREEN,
248+
Help => term::color::BRIGHT_CYAN,
240249
}
241250
}
242251
}
@@ -293,15 +302,6 @@ fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
293302
Some(code) => {
294303
let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
295304
try!(print_maybe_styled(dst, format!(" [{}]", code.clone()).as_slice(), style));
296-
match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
297-
Some(_) => {
298-
try!(write!(&mut dst.dst,
299-
" (pass `--explain {}` to see a detailed explanation)",
300-
code
301-
));
302-
}
303-
None => ()
304-
}
305305
}
306306
None => ()
307307
}
@@ -401,7 +401,20 @@ fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
401401
try!(highlight_lines(dst, cm, sp, lvl, lines));
402402
}
403403
}
404-
print_macro_backtrace(dst, cm, sp)
404+
try!(print_macro_backtrace(dst, cm, sp));
405+
match code {
406+
Some(code) =>
407+
match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
408+
Some(_) => {
409+
try!(print_diagnostic(dst, ss.as_slice(), Help,
410+
format!("pass `--explain {}` to see a detailed \
411+
explanation", code).as_slice(), None));
412+
}
413+
None => ()
414+
},
415+
None => (),
416+
}
417+
Ok(())
405418
}
406419

407420
fn highlight_lines(err: &mut EmitterWriter,

src/libsyntax/ext/base.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ impl<'a> ExtCtxt<'a> {
575575
self.print_backtrace();
576576
self.parse_sess.span_diagnostic.span_note(sp, msg);
577577
}
578+
pub fn span_help(&self, sp: Span, msg: &str) {
579+
self.print_backtrace();
580+
self.parse_sess.span_diagnostic.span_help(sp, msg);
581+
}
578582
pub fn bug(&self, msg: &str) -> ! {
579583
self.print_backtrace();
580584
self.parse_sess.span_diagnostic.handler().bug(msg);

src/libsyntax/parse/parser.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,9 @@ impl<'a> Parser<'a> {
959959
pub fn span_note(&mut self, sp: Span, m: &str) {
960960
self.sess.span_diagnostic.span_note(sp, m)
961961
}
962+
pub fn span_help(&mut self, sp: Span, m: &str) {
963+
self.sess.span_diagnostic.span_help(sp, m)
964+
}
962965
pub fn bug(&mut self, m: &str) -> ! {
963966
self.sess.span_diagnostic.span_bug(self.span, m)
964967
}

src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'r> Itble<'r, uint, Range<uint>> for (uint, uint) {
2222
}
2323

2424
fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &T) -> bool {
25-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &'r T) -> bool
25+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn check<'r, I: Iterator<uint>, T: Itble<'r, uint, I>>(cont: &'r T) -> bool
2626
let cont_iter = cont.iter(); //~ ERROR: cannot infer
2727
let result = cont_iter.fold(Some(0u16), |state, val| {
2828
state.map_or(None, |mask| {

src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@
1212

1313
struct Bar<'x, 'y, 'z> { bar: &'y int, baz: int }
1414
fn bar1<'a>(x: &Bar) -> (&'a int, &'a int, &'a int) {
15-
//~^ 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)
15+
//~^ 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)
1616
(x.bar, &x.baz, &x.baz)
1717
//~^ ERROR: cannot infer
1818
//~^^ ERROR: cannot infer
1919
//~^^^ ERROR: cannot infer
2020
}
2121

2222
fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a int, &'a int, &'a int) {
23-
//~^ 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)
23+
//~^ 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)
2424
(x.bar, &x.baz, &x.baz)
2525
//~^ ERROR: cannot infer
2626
//~^^ ERROR: cannot infer

src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@
1212

1313
struct Foo<'x> { bar: int }
1414
fn foo1<'a>(x: &Foo) -> &'a int {
15-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int
15+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo1<'a>(x: &'a Foo) -> &'a int
1616
&x.bar //~ ERROR: cannot infer
1717
}
1818

1919
fn foo2<'a, 'b>(x: &'a Foo) -> &'b int {
20-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo2<'a>(x: &'a Foo) -> &'a int
20+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo2<'a>(x: &'a Foo) -> &'a int
2121
&x.bar //~ ERROR: cannot infer
2222
}
2323

2424
fn foo3<'a>(x: &Foo) -> (&'a int, &'a int) {
25-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a int, &'a int)
25+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo3<'a>(x: &'a Foo) -> (&'a int, &'a int)
2626
(&x.bar, &x.bar) //~ ERROR: cannot infer
2727
//~^ ERROR: cannot infer
2828
}
2929

3030
fn foo4<'a, 'b>(x: &'a Foo) -> (&'b int, &'a int, &'b int) {
31-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a int, &'a int, &'a int)
31+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn foo4<'a>(x: &'a Foo) -> (&'a int, &'a int, &'a int)
3232
(&x.bar, &x.bar, &x.bar) //~ ERROR: cannot infer
3333
//~^ ERROR: cannot infer
3434
}
@@ -37,7 +37,7 @@ struct Cat<'x, T> { cat: &'x int, t: T }
3737
struct Dog<'y> { dog: &'y int }
3838

3939
fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x int {
40-
//~^ NOTE: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x int
40+
//~^ HELP: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x int
4141
x.t.dog //~ ERROR: cannot infer
4242
}
4343

0 commit comments

Comments
 (0)