about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-04 03:36:55 +0000
committerbors <bors@rust-lang.org>2014-11-04 03:36:55 +0000
commitec28b4a6c8c0a249fe341afde55d026177aabac6 (patch)
treed233ebf5c906947f53f370bd8039bb004a5cbbdb
parent0a5e7f35949d18f312dca90af73e56aced6f2b0e (diff)
parent5bf9ef2122e2d9c872ea551d0561c9326940446f (diff)
downloadrust-ec28b4a6c8c0a249fe341afde55d026177aabac6.tar.gz
rust-ec28b4a6c8c0a249fe341afde55d026177aabac6.zip
auto merge of #18132 : P1start/rust/more-help, r=jakub-
Closes #18126.

At the moment this mostly only changes notes that are particularly help-oriented or directly suggest the user to do something to help messages, and does not change messages that simply explain an error message further. If it is decided that those messages should also be help messages, I can add them to this PR, but for now I’m excluding them as I believe that changing those messages might leave very few places where notes would be appropriate.
-rw-r--r--src/doc/guide.md2
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs2
-rw-r--r--src/librustc/middle/borrowck/gather_loans/move_error.rs7
-rw-r--r--src/librustc/middle/borrowck/mod.rs51
-rw-r--r--src/librustc/middle/dependency_format.rs2
-rw-r--r--src/librustc/middle/liveness.rs2
-rw-r--r--src/librustc/middle/resolve.rs2
-rw-r--r--src/librustc/middle/typeck/astconv.rs11
-rw-r--r--src/librustc/middle/typeck/check/mod.rs18
-rw-r--r--src/librustc/middle/typeck/check/vtable.rs2
-rw-r--r--src/librustc/middle/typeck/infer/error_reporting.rs27
-rw-r--r--src/librustc/util/ppaux.rs4
-rw-r--r--src/libsyntax/ext/bytes.rs4
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax/parse/parser.rs19
-rw-r--r--src/test/compile-fail/borrowck-let-suggestion.rs2
-rw-r--r--src/test/compile-fail/issue-11714.rs2
-rw-r--r--src/test/compile-fail/issue-13428.rs4
-rw-r--r--src/test/compile-fail/issue-16747.rs5
-rw-r--r--src/test/compile-fail/issue-17441.rs8
-rw-r--r--src/test/compile-fail/issue-17718-const-mut.rs3
-rw-r--r--src/test/compile-fail/issue-2354.rs2
-rw-r--r--src/test/compile-fail/issue-6702.rs2
-rw-r--r--src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs12
-rw-r--r--src/test/compile-fail/liveness-return-last-stmt-semi.rs4
-rw-r--r--src/test/compile-fail/method-missing-call.rs4
26 files changed, 123 insertions, 80 deletions
diff --git a/src/doc/guide.md b/src/doc/guide.md
index f6aa04df1b9..f1e01ce6660 100644
--- a/src/doc/guide.md
+++ b/src/doc/guide.md
@@ -777,7 +777,7 @@ fn add_one(x: int) -> int {
      x + 1;
 }
 
-note: consider removing this semicolon:
+help: consider removing this semicolon:
      x + 1;
           ^
 ```
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index de61f4f2b40..073b6dae0c3 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -789,7 +789,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         assignment_span,
                         format!("cannot assign to {}",
                                 self.bccx.cmt_to_string(&*assignee_cmt)).as_slice());
-                    self.bccx.span_note(
+                    self.bccx.span_help(
                         self.tcx().map.span(upvar_id.closure_expr_id),
                         "consider changing this closure to take self by mutable reference");
                 } else {
diff --git a/src/librustc/middle/borrowck/gather_loans/move_error.rs b/src/librustc/middle/borrowck/gather_loans/move_error.rs
index 9d4d9fcf9a9..ab6ff08c9d4 100644
--- a/src/librustc/middle/borrowck/gather_loans/move_error.rs
+++ b/src/librustc/middle/borrowck/gather_loans/move_error.rs
@@ -148,9 +148,12 @@ fn note_move_destination(bccx: &BorrowckCtxt,
     if is_first_note {
         bccx.span_note(
             move_to_span,
-            format!("attempting to move value to here (to prevent the move, \
+            "attempting to move value to here");
+        bccx.span_help(
+            move_to_span,
+            format!("to prevent the move, \
                      use `ref {0}` or `ref mut {0}` to capture value by \
-                     reference)",
+                     reference",
                     pat_name).as_slice());
     } else {
         bccx.span_note(move_to_span,
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index ae8e975e843..4e2b280eba6 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -527,8 +527,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                   r).as_slice())
                     }
                 };
-                let suggestion = move_suggestion(self.tcx, expr_ty,
-                        "moved by default (use `copy` to override)");
+                let (suggestion, _) = move_suggestion(self.tcx, expr_ty,
+                        ("moved by default", ""));
                 self.tcx.sess.span_note(
                     expr_span,
                     format!("`{}` moved here{} because it has type `{}`, which is {}",
@@ -540,13 +540,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
 
             move_data::MovePat => {
                 let pat_ty = ty::node_id_to_type(self.tcx, the_move.id);
-                self.tcx.sess.span_note(self.tcx.map.span(the_move.id),
+                let span = self.tcx.map.span(the_move.id);
+                self.tcx.sess.span_note(span,
                     format!("`{}` moved here{} because it has type `{}`, \
-                             which is moved by default (use `ref` to \
-                             override)",
+                             which is moved by default",
                             ol,
                             moved_lp_msg,
                             pat_ty.user_string(self.tcx)).as_slice());
+                self.tcx.sess.span_help(span,
+                    "use `ref` to override");
             }
 
             move_data::Captured => {
@@ -563,9 +565,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                   r).as_slice())
                     }
                 };
-                let suggestion = move_suggestion(self.tcx, expr_ty,
-                        "moved by default (make a copy and \
-                         capture that instead to override)");
+                let (suggestion, help) = move_suggestion(self.tcx, expr_ty,
+                        ("moved by default", "make a copy and \
+                         capture that instead to override"));
                 self.tcx.sess.span_note(
                     expr_span,
                     format!("`{}` moved into closure environment here{} because it \
@@ -574,21 +576,23 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             moved_lp_msg,
                             expr_ty.user_string(self.tcx),
                             suggestion).as_slice());
+                self.tcx.sess.span_help(expr_span, help);
             }
         }
 
-        fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msg: &'static str)
-                          -> &'static str {
+        fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msgs: (&'static str, &'static str))
+                          -> (&'static str, &'static str) {
             match ty::get(ty).sty {
                 ty::ty_closure(box ty::ClosureTy {
                         store: ty::RegionTraitStore(..),
                         ..
                     }) =>
-                    "a non-copyable stack closure (capture it in a new closure, \
-                     e.g. `|x| f(x)`, to override)",
+                    ("a non-copyable stack closure",
+                     "capture it in a new closure, e.g. `|x| f(x)`, to override"),
                 _ if ty::type_moves_by_default(tcx, ty) =>
-                    "non-copyable (perhaps you meant to use clone()?)",
-                _ => default_msg,
+                    ("non-copyable",
+                     "perhaps you meant to use `clone()`?"),
+                _ => default_msgs,
             }
         }
     }
@@ -733,7 +737,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 self.tcx.sess.span_err(span,
                                        format!("{} in a captured outer \
                                                variable in an `Fn` closure", prefix).as_slice());
-                span_note!(self.tcx.sess, self.tcx.map.span(id),
+                span_help!(self.tcx.sess, self.tcx.map.span(id),
                            "consider changing this closure to take self by mutable reference");
             }
             mc::AliasableStatic(..) |
@@ -750,7 +754,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         }
 
         if is_closure {
-            self.tcx.sess.span_note(
+            self.tcx.sess.span_help(
                 span,
                 "closures behind references must be called via `&mut`");
         }
@@ -770,7 +774,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             _ => unreachable!()
                         };
                         if kind == ty::FnUnboxedClosureKind {
-                            self.tcx.sess.span_note(
+                            self.tcx.sess.span_help(
                                 self.tcx.map.span(upvar_id.closure_expr_id),
                                 "consider changing this closure to take \
                                  self by mutable reference");
@@ -787,15 +791,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     sub_scope,
                     "...");
                 let suggestion = if is_statement_scope(self.tcx, super_scope) {
-                    "; consider using a `let` binding to increase its lifetime"
+                    Some("consider using a `let` binding to increase its lifetime")
                 } else {
-                    ""
+                    None
                 };
-                note_and_explain_region(
+                let span = note_and_explain_region(
                     self.tcx,
                     "...but borrowed value is only valid for ",
                     super_scope,
-                    suggestion);
+                    "");
+                match (span, suggestion) {
+                    (_, None) => {},
+                    (Some(span), Some(msg)) => self.tcx.sess.span_help(span, msg),
+                    (None, Some(msg)) => self.tcx.sess.help(msg),
+                }
             }
 
             err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index 3baa8eb0cc0..15ca00f6a7f 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -213,7 +213,7 @@ fn add_library(sess: &session::Session,
                 sess.err(format!("cannot satisfy dependencies so `{}` only \
                                   shows up once",
                                  data.name).as_slice());
-                sess.note("having upstream crates all available in one format \
+                sess.help("having upstream crates all available in one format \
                            will likely make this go away");
             }
         }
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 80eba56ea6c..a11d5f6604e 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -1568,7 +1568,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                             hi: original_span.hi,
                             expn_id: original_span.expn_id
                         };
-                        self.ir.tcx.sess.span_note(
+                        self.ir.tcx.sess.span_help(
                             span_semicolon, "consider removing this semicolon:");
                     }
                 }
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index a2bea790c9f..db695c38362 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -5868,7 +5868,7 @@ impl<'a> Resolver<'a> {
                                                  uses it like a function name",
                                                 wrong_name).as_slice());
 
-                                self.session.span_note(expr.span,
+                                self.session.span_help(expr.span,
                                     format!("Did you mean to write: \
                                             `{} {{ /* fields */ }}`?",
                                             wrong_name).as_slice());
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index dba1fe966f1..fb0406d83c6 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -172,18 +172,18 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
                                 }
                             }
                             if len == 1 {
-                                span_note!(this.tcx().sess, default_span,
+                                span_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      the signature does not say which {} it is borrowed from",
                                     m);
                             } else if len == 0 {
-                                span_note!(this.tcx().sess, default_span,
+                                span_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      there is no value for it to be borrowed from");
-                                span_note!(this.tcx().sess, default_span,
+                                span_help!(this.tcx().sess, default_span,
                                     "consider giving it a 'static lifetime");
                             } else {
-                                span_note!(this.tcx().sess, default_span,
+                                span_help!(this.tcx().sess, default_span,
                                     "this function's return type contains a borrowed value, but \
                                      the signature does not say whether it is borrowed from {}",
                                     m);
@@ -302,7 +302,7 @@ fn ast_path_substs<'tcx,AC,RS>(
         && !this.tcx().sess.features.borrow().default_type_params {
         span_err!(this.tcx().sess, path.span, E0108,
             "default type parameters are experimental and possibly buggy");
-        span_note!(this.tcx().sess, path.span,
+        span_help!(this.tcx().sess, path.span,
             "add #![feature(default_type_params)] to the crate attributes to enable");
     }
 
@@ -1168,6 +1168,7 @@ fn ty_of_method_or_bare_fn<'tcx, AC: AstConv<'tcx>>(
 
     let param_lifetimes: Vec<(String, uint)> = lifetimes_for_params.into_iter()
                                                                    .map(|(n, v)| (n, v.len()))
+                                                                   .filter(|&(_, l)| l != 0)
                                                                    .collect();
 
     let output_ty = match decl.output.node {
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index c280474a076..9a4a958f1af 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -1355,18 +1355,18 @@ fn check_cast(fcx: &FnCtxt,
                     ast::MutImmutable => ""
                 };
                 if ty::type_is_trait(t_1) {
-                    span_note!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr);
+                    span_help!(fcx.tcx().sess, t.span, "did you mean `&{}{}`?", mtstr, tstr);
                 } else {
-                    span_note!(fcx.tcx().sess, span,
+                    span_help!(fcx.tcx().sess, span,
                                "consider using an implicit coercion to `&{}{}` instead",
                                mtstr, tstr);
                 }
             }
             ty::ty_uniq(..) => {
-                span_note!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr);
+                span_help!(fcx.tcx().sess, t.span, "did you mean `Box<{}>`?", tstr);
             }
             _ => {
-                span_note!(fcx.tcx().sess, e.span,
+                span_help!(fcx.tcx().sess, e.span,
                            "consider using a box or reference as appropriate");
             }
         }
@@ -2142,7 +2142,7 @@ fn try_overloaded_call<'a>(fcx: &FnCtxt,
         if !fcx.tcx().sess.features.borrow().overloaded_calls {
             span_err!(fcx.tcx().sess, call_expression.span, E0056,
                 "overloaded calls are experimental");
-            span_note!(fcx.tcx().sess, call_expression.span,
+            span_help!(fcx.tcx().sess, call_expression.span,
                 "add `#![feature(overloaded_calls)]` to \
                 the crate attributes to enable");
         }
@@ -3479,8 +3479,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
                     },
                     expr_t, None);
 
-                tcx.sess.span_note(field.span,
-                    "maybe a missing `()` to call it? If not, try an anonymous function.");
+                tcx.sess.span_help(field.span,
+                    "maybe a `()` to call it is missing? \
+                     If not, try an anonymous function");
             }
 
             Err(_) => {
@@ -4787,7 +4788,8 @@ pub fn check_instantiable(tcx: &ty::ctxt,
     if !ty::is_instantiable(tcx, item_ty) {
         span_err!(tcx.sess, sp, E0073,
             "this type cannot be instantiated without an \
-             instance of itself; consider using `Option<{}>`",
+             instance of itself");
+        span_help!(tcx.sess, sp, "consider using `Option<{}>`",
             ppaux::ty_to_string(tcx, item_ty));
         false
     } else {
diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs
index 87b0aed4ac4..2fcce4cc3dc 100644
--- a/src/librustc/middle/typeck/check/vtable.rs
+++ b/src/librustc/middle/typeck/check/vtable.rs
@@ -525,7 +525,7 @@ fn note_obligation_cause(fcx: &FnCtxt,
             span_note!(tcx.sess, obligation.cause.span,
                       "cannot implement a destructor on a \
                       structure or enumeration that does not satisfy Send");
-            span_note!(tcx.sess, obligation.cause.span,
+            span_help!(tcx.sess, obligation.cause.span,
                        "use \"#[unsafe_destructor]\" on the implementation \
                        to force the compiler to allow this");
         }
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs
index 3baa9a7a5f9..bfa0f94a747 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/typeck/infer/error_reporting.rs
@@ -438,9 +438,12 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
                 self.tcx.sess.span_err(
                     origin.span(),
                     format!(
-                        "the parameter type `{}` may not live long enough; \
-                         consider adding an explicit lifetime bound `{}:{}`...",
-                        param_ty.user_string(self.tcx),
+                        "the parameter type `{}` may not live long enough",
+                        param_ty.user_string(self.tcx)).as_slice());
+                self.tcx.sess.span_help(
+                    origin.span(),
+                    format!(
+                        "consider adding an explicit lifetime bound `{}: {}`...",
                         param_ty.user_string(self.tcx),
                         sub.user_string(self.tcx)).as_slice());
             }
@@ -450,9 +453,12 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
                 self.tcx.sess.span_err(
                     origin.span(),
                     format!(
-                        "the parameter type `{}` may not live long enough; \
-                         consider adding an explicit lifetime bound `{}:'static`...",
-                        param_ty.user_string(self.tcx),
+                        "the parameter type `{}` may not live long enough",
+                        param_ty.user_string(self.tcx)).as_slice());
+                self.tcx.sess.span_help(
+                    origin.span(),
+                    format!(
+                        "consider adding an explicit lifetime bound `{}: 'static`...",
                         param_ty.user_string(self.tcx)).as_slice());
             }
 
@@ -461,9 +467,12 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
                 self.tcx.sess.span_err(
                     origin.span(),
                     format!(
-                        "the parameter type `{}` may not live long enough; \
-                         consider adding an explicit lifetime bound to `{}`",
-                        param_ty.user_string(self.tcx),
+                        "the parameter type `{}` may not live long enough",
+                        param_ty.user_string(self.tcx)).as_slice());
+                self.tcx.sess.span_help(
+                    origin.span(),
+                    format!(
+                        "consider adding an explicit lifetime bound to `{}`",
                         param_ty.user_string(self.tcx)).as_slice());
                 note_and_explain_region(
                     self.tcx,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 8befba00fd2..b820780dbf9 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -48,16 +48,18 @@ pub trait UserString {
 pub fn note_and_explain_region(cx: &ctxt,
                                prefix: &str,
                                region: ty::Region,
-                               suffix: &str) {
+                               suffix: &str) -> Option<Span> {
     match explain_region_and_span(cx, region) {
       (ref str, Some(span)) => {
         cx.sess.span_note(
             span,
             format!("{}{}{}", prefix, *str, suffix).as_slice());
+        Some(span)
       }
       (ref str, None) => {
         cx.sess.note(
             format!("{}{}{}", prefix, *str, suffix).as_slice());
+        None
       }
     }
 }
diff --git a/src/libsyntax/ext/bytes.rs b/src/libsyntax/ext/bytes.rs
index a93295815e0..2d1d13f16d0 100644
--- a/src/libsyntax/ext/bytes.rs
+++ b/src/libsyntax/ext/bytes.rs
@@ -22,10 +22,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
                               tts: &[ast::TokenTree])
                               -> Box<base::MacResult+'cx> {
     cx.span_warn(sp, "`bytes!` is deprecated, use `b\"foo\"` literals instead");
-    cx.parse_sess.span_diagnostic.span_note(sp,
+    cx.parse_sess.span_diagnostic.span_help(sp,
         "see http://doc.rust-lang.org/reference.html#byte-and-byte-string-literals \
          for documentation");
-    cx.parse_sess.span_diagnostic.span_note(sp,
+    cx.parse_sess.span_diagnostic.span_help(sp,
         "see https://github.com/rust-lang/rust/blob/master/src/etc/2014-06-rewrite-bytes-macros.py \
          for an automated migration");
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 54eaa308658..330e4552e2f 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -131,7 +131,7 @@ impl<'a> Context<'a> {
     fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
         if !self.has_feature(feature) {
             self.span_handler.span_err(span, explain);
-            self.span_handler.span_note(span, format!("add #![feature({})] to the \
+            self.span_handler.span_help(span, format!("add #![feature({})] to the \
                                                        crate attributes to enable",
                                                       feature).as_slice());
         }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index aa3b9668d46..5e18c6bae48 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2371,10 +2371,19 @@ impl<'a> Parser<'a> {
                   token::LitFloat(n) => {
                     self.bump();
                     let last_span = self.last_span;
+                    let fstr = n.as_str();
                     self.span_err(last_span,
                                   format!("unexpected token: `{}`", n.as_str()).as_slice());
-                    self.span_note(last_span,
-                                   "try parenthesizing the first index; e.g., `(foo.0).1`");
+                    if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
+                        let float = match from_str::<f64>(fstr) {
+                            Some(f) => f,
+                            None => continue,
+                        };
+                        self.span_help(last_span,
+                            format!("try parenthesizing the first index; e.g., `(foo.{}){}`",
+                                    float.trunc() as uint,
+                                    float.fract().to_string()[1..]).as_slice());
+                    }
                     self.abort_if_errors();
 
                   }
@@ -2578,7 +2587,7 @@ impl<'a> Parser<'a> {
             token::Eof => {
                 let open_braces = self.open_braces.clone();
                 for sp in open_braces.iter() {
-                    self.span_note(*sp, "Did you mean to close this delimiter?");
+                    self.span_help(*sp, "did you mean to close this delimiter?");
                 }
                 // There shouldn't really be a span, but it's easier for the test runner
                 // if we give it one
@@ -5352,8 +5361,8 @@ impl<'a> Parser<'a> {
             self.bump();
             if self.eat_keyword(keywords::Mut) {
                 let last_span = self.last_span;
-                self.span_err(last_span, "const globals cannot be mutable, \
-                                          did you mean to declare a static?");
+                self.span_err(last_span, "const globals cannot be mutable");
+                self.span_help(last_span, "did you mean to declare a static?");
             }
             let (ident, item_, extra_attrs) = self.parse_item_const(None);
             let last_span = self.last_span;
diff --git a/src/test/compile-fail/borrowck-let-suggestion.rs b/src/test/compile-fail/borrowck-let-suggestion.rs
index 385111170b1..cd1101c05d1 100644
--- a/src/test/compile-fail/borrowck-let-suggestion.rs
+++ b/src/test/compile-fail/borrowck-let-suggestion.rs
@@ -11,7 +11,7 @@
 fn f() {
     let x = [1i].iter(); //~ ERROR borrowed value does not live long enough
                          //~^^ NOTE reference must be valid for the block
-                         //~^^ NOTE consider using a `let` binding to increase its lifetime
+                         //~^^ HELP consider using a `let` binding to increase its lifetime
 }
 
 fn main() {
diff --git a/src/test/compile-fail/issue-11714.rs b/src/test/compile-fail/issue-11714.rs
index d57182e275b..ed00d4131db 100644
--- a/src/test/compile-fail/issue-11714.rs
+++ b/src/test/compile-fail/issue-11714.rs
@@ -11,7 +11,7 @@
 fn blah() -> int { //~ ERROR not all control paths return a value
     1i
 
-    ; //~ NOTE consider removing this semicolon:
+    ; //~ HELP consider removing this semicolon:
 }
 
 fn main() { }
diff --git a/src/test/compile-fail/issue-13428.rs b/src/test/compile-fail/issue-13428.rs
index de558401aa6..c771970650d 100644
--- a/src/test/compile-fail/issue-13428.rs
+++ b/src/test/compile-fail/issue-13428.rs
@@ -15,12 +15,12 @@ fn foo() -> String {  //~ ERROR not all control paths return a value
             "world")
     // Put the trailing semicolon on its own line to test that the
     // note message gets the offending semicolon exactly
-    ;   //~ NOTE consider removing this semicolon
+    ;   //~ HELP consider removing this semicolon
 }
 
 fn bar() -> String {  //~ ERROR not all control paths return a value
     "foobar".to_string()
-    ;   //~ NOTE consider removing this semicolon
+    ;   //~ HELP consider removing this semicolon
 }
 
 pub fn main() {}
diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs
index 134f58951ba..22e3e9ed09e 100644
--- a/src/test/compile-fail/issue-16747.rs
+++ b/src/test/compile-fail/issue-16747.rs
@@ -15,8 +15,9 @@ trait ListItem<'a> {
 trait Collection { fn len(&self) -> uint; }
 
 struct List<'a, T: ListItem<'a>> {
-//~^ ERROR the parameter type `T` may not live long enough; consider adding an explicit lifetime bo
-//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
+//~^ ERROR the parameter type `T` may not live long enough
+//~^^ HELP consider adding an explicit lifetime bound
+//~^^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
     slice: &'a [T]
 }
 
diff --git a/src/test/compile-fail/issue-17441.rs b/src/test/compile-fail/issue-17441.rs
index da5590971bc..11c815da1c7 100644
--- a/src/test/compile-fail/issue-17441.rs
+++ b/src/test/compile-fail/issue-17441.rs
@@ -11,14 +11,14 @@
 fn main() {
     let _foo = &[1u, 2] as [uint];
     //~^ ERROR cast to unsized type: `&[uint, ..2]` as `[uint]`
-    //~^^ NOTE consider using an implicit coercion to `&[uint]` instead
+    //~^^ HELP consider using an implicit coercion to `&[uint]` instead
     let _bar = box 1u as std::fmt::Show;
     //~^ ERROR cast to unsized type: `Box<uint>` as `core::fmt::Show`
-    //~^^ NOTE did you mean `Box<core::fmt::Show>`?
+    //~^^ HELP did you mean `Box<core::fmt::Show>`?
     let _baz = 1u as std::fmt::Show;
     //~^ ERROR cast to unsized type: `uint` as `core::fmt::Show`
-    //~^^ NOTE consider using a box or reference as appropriate
+    //~^^ HELP consider using a box or reference as appropriate
     let _quux = [1u, 2] as [uint];
     //~^ ERROR cast to unsized type: `[uint, ..2]` as `[uint]`
-    //~^^ NOTE consider using a box or reference as appropriate
+    //~^^ HELP consider using a box or reference as appropriate
 }
diff --git a/src/test/compile-fail/issue-17718-const-mut.rs b/src/test/compile-fail/issue-17718-const-mut.rs
index 31a5fee2044..12b9cf4ba8c 100644
--- a/src/test/compile-fail/issue-17718-const-mut.rs
+++ b/src/test/compile-fail/issue-17718-const-mut.rs
@@ -9,7 +9,8 @@
 // except according to those terms.
 
 const
-mut //~ ERROR: const globals cannot be mutable, did you mean to declare a static?
+mut //~ ERROR: const globals cannot be mutable
+//~^ HELP did you mean to declare a static?
 FOO: uint = 3;
 
 fn main() {
diff --git a/src/test/compile-fail/issue-2354.rs b/src/test/compile-fail/issue-2354.rs
index 93f38a50b05..cc219a6acb5 100644
--- a/src/test/compile-fail/issue-2354.rs
+++ b/src/test/compile-fail/issue-2354.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo() { //~ NOTE Did you mean to close this delimiter?
+fn foo() { //~ HELP did you mean to close this delimiter?
   match Some(x) {
       Some(y) { panic!(); }
       None    { panic!(); }
diff --git a/src/test/compile-fail/issue-6702.rs b/src/test/compile-fail/issue-6702.rs
index 168aa5f9d69..3e35e4a659d 100644
--- a/src/test/compile-fail/issue-6702.rs
+++ b/src/test/compile-fail/issue-6702.rs
@@ -15,5 +15,5 @@ struct Monster {
 
 fn main() {
     let _m = Monster(); //~ ERROR `Monster` is a structure name, but
-    //~^ NOTE Did you mean to write: `Monster { /* fields */ }`?
+    //~^ HELP Did you mean to write: `Monster { /* fields */ }`?
 }
diff --git a/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs
index 849f337743b..5d961764342 100644
--- a/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs
+++ b/src/test/compile-fail/lifetime-elision-return-type-requires-explicit-lifetime.rs
@@ -10,13 +10,13 @@
 
 // Lifetime annotation needed because we have no arguments.
 fn f() -> &int {    //~ ERROR missing lifetime specifier
-//~^ NOTE there is no value for it to be borrowed from
+//~^ HELP there is no value for it to be borrowed from
     panic!()
 }
 
 // Lifetime annotation needed because we have two by-reference parameters.
 fn g(_x: &int, _y: &int) -> &int {    //~ ERROR missing lifetime specifier
-//~^ NOTE the signature does not say whether it is borrowed from `_x` or `_y`
+//~^ HELP the signature does not say whether it is borrowed from `_x` or `_y`
     panic!()
 }
 
@@ -27,7 +27,13 @@ struct Foo<'a> {
 // Lifetime annotation needed because we have two lifetimes: one as a parameter
 // and one on the reference.
 fn h(_x: &Foo) -> &int { //~ ERROR missing lifetime specifier
-//~^ NOTE the signature does not say which one of `_x`'s 2 elided lifetimes it is borrowed from
+//~^ HELP the signature does not say which one of `_x`'s 2 elided lifetimes it is borrowed from
+    panic!()
+}
+
+fn i(_x: int) -> &int { //~ ERROR missing lifetime specifier
+//~^ HELP this function's return type contains a borrowed value
+//~^^ HELP consider giving it a 'static lifetime
     panic!()
 }
 
diff --git a/src/test/compile-fail/liveness-return-last-stmt-semi.rs b/src/test/compile-fail/liveness-return-last-stmt-semi.rs
index 8a6585f8bbc..f2ea2ca96a5 100644
--- a/src/test/compile-fail/liveness-return-last-stmt-semi.rs
+++ b/src/test/compile-fail/liveness-return-last-stmt-semi.rs
@@ -14,12 +14,12 @@
 
 macro_rules! test ( () => { fn foo() -> int { 1i; } } )
                                              //~^ ERROR not all control paths return a value
-                                             //~^^ NOTE consider removing this semicolon
+                                             //~^^ HELP consider removing this semicolon
 
 fn no_return() -> int {} //~ ERROR  not all control paths return a value
 
 fn bar(x: u32) -> u32 { //~ ERROR  not all control paths return a value
-    x * 2; //~ NOTE consider removing this semicolon
+    x * 2; //~ HELP consider removing this semicolon
 }
 
 fn baz(x: u64) -> u32 { //~ ERROR  not all control paths return a value
diff --git a/src/test/compile-fail/method-missing-call.rs b/src/test/compile-fail/method-missing-call.rs
index 1c8b7fbf85c..ddfa447f60e 100644
--- a/src/test/compile-fail/method-missing-call.rs
+++ b/src/test/compile-fail/method-missing-call.rs
@@ -30,7 +30,7 @@ fn main() {
     let point: Point = Point::new();
     let px: int =  point
                         .get_x;//~ ERROR attempted to take value of method `get_x` on type `Point`
-                        //~^ NOTE maybe a missing `()` to call it? If not, try an anonymous
+                        //~^ HELP maybe a `()` to call it is missing
 
     // Ensure the span is useful
     let ys = &[1i,2,3,4,5,6,7];
@@ -38,6 +38,6 @@ fn main() {
               .map(|x| x)
               .filter(|&&x| x == 1)
               .filter_map; //~ ERROR attempted to take value of method `filter_map` on type
-              //~^ NOTE maybe a missing `()` to call it? If not, try an anonymous function.
+              //~^ HELP maybe a `()` to call it is missing
 }