Skip to content

Commit 4694b99

Browse files
committed
auto merge of #16855 : P1start/rust/help-messages, r=brson
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. They look like this: ``` match.rs:10:13: 10:14 error: unreachable pattern [E0001] match.rs:10 1 => {}, ^ match.rs:3:1: 3:38 note: in expansion of foo! match.rs:7:5: 20:2 note: expansion site match.rs:10:13: 10:14 help: pass `--explain E0001` to see a detailed explanation ``` (`help` is coloured cyan.) Adding these errors on a separate line stops the lines from being too long, as discussed in #16619.
2 parents 97bf93e + 06d9cc1 commit 4694b99

10 files changed

+52
-22
lines changed

src/librustc/driver/session.rs

+6
Original file line numberDiff line numberDiff line change
@@ -96,12 +96,18 @@ impl Session {
9696
pub fn span_end_note(&self, sp: Span, msg: &str) {
9797
self.diagnostic().span_end_note(sp, msg)
9898
}
99+
pub fn span_help(&self, sp: Span, msg: &str) {
100+
self.diagnostic().span_help(sp, msg)
101+
}
99102
pub fn fileline_note(&self, sp: Span, msg: &str) {
100103
self.diagnostic().fileline_note(sp, msg)
101104
}
102105
pub fn note(&self, msg: &str) {
103106
self.diagnostic().handler().note(msg)
104107
}
108+
pub fn help(&self, msg: &str) {
109+
self.diagnostic().handler().note(msg)
110+
}
105111
pub fn span_bug(&self, sp: Span, msg: &str) -> ! {
106112
self.diagnostic().span_bug(sp, msg)
107113
}

src/librustc/middle/borrowck/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
618618
self.tcx.sess.span_end_note(s, m);
619619
}
620620

621+
pub fn span_help(&self, s: Span, m: &str) {
622+
self.tcx.sess.span_help(s, m);
623+
}
624+
621625
pub fn bckerr_to_string(&self, err: &BckError) -> String {
622626
match err.code {
623627
err_mutbl => {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ impl<'a, 'tcx> ErrorReportingHelpers for InferCtxt<'a, 'tcx> {
14171417
opt_explicit_self, generics);
14181418
let msg = format!("consider using an explicit lifetime \
14191419
parameter as shown: {}", suggested_fn);
1420-
self.tcx.sess.span_note(span, msg.as_slice());
1420+
self.tcx.sess.span_help(span, msg.as_slice());
14211421
}
14221422

14231423
fn report_inference_failure(&self,

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use middle::typeck::infer::lub::Lub;
3434
use middle::typeck::infer::glb::Glb;
3535
use syntax::codemap;
3636
use syntax::codemap::{Span, CodeMap, DUMMY_SP};
37-
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note};
37+
use syntax::diagnostic::{Level, RenderSpan, Bug, Fatal, Error, Warning, Note, Help};
3838
use syntax::{ast, ast_map};
3939
use util::ppaux::{ty_to_string, UserString};
4040

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

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

src/libsyntax/diagnostic.rs

+24-11
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

+4
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,10 @@ impl<'a> ExtCtxt<'a> {
620620
self.print_backtrace();
621621
self.parse_sess.span_diagnostic.span_note(sp, msg);
622622
}
623+
pub fn span_help(&self, sp: Span, msg: &str) {
624+
self.print_backtrace();
625+
self.parse_sess.span_diagnostic.span_help(sp, msg);
626+
}
623627
pub fn bug(&self, msg: &str) -> ! {
624628
self.print_backtrace();
625629
self.parse_sess.span_diagnostic.handler().bug(msg);

src/libsyntax/parse/parser.rs

+3
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

+1-1
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

+2-2
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

+5-5
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)