1
Fork 0

Convert some notes to help messages

Closes #18126.
This commit is contained in:
P1start 2014-10-18 15:39:44 +13:00
parent 3327ecca42
commit 5bf9ef2122
26 changed files with 123 additions and 80 deletions

View file

@ -777,7 +777,7 @@ fn add_one(x: int) -> int {
x + 1; x + 1;
} }
note: consider removing this semicolon: help: consider removing this semicolon:
x + 1; x + 1;
^ ^
``` ```

View file

@ -789,7 +789,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
assignment_span, assignment_span,
format!("cannot assign to {}", format!("cannot assign to {}",
self.bccx.cmt_to_string(&*assignee_cmt)).as_slice()); 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), self.tcx().map.span(upvar_id.closure_expr_id),
"consider changing this closure to take self by mutable reference"); "consider changing this closure to take self by mutable reference");
} else { } else {

View file

@ -148,9 +148,12 @@ fn note_move_destination(bccx: &BorrowckCtxt,
if is_first_note { if is_first_note {
bccx.span_note( bccx.span_note(
move_to_span, 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 \ use `ref {0}` or `ref mut {0}` to capture value by \
reference)", reference",
pat_name).as_slice()); pat_name).as_slice());
} else { } else {
bccx.span_note(move_to_span, bccx.span_note(move_to_span,

View file

@ -527,8 +527,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
r).as_slice()) r).as_slice())
} }
}; };
let suggestion = move_suggestion(self.tcx, expr_ty, let (suggestion, _) = move_suggestion(self.tcx, expr_ty,
"moved by default (use `copy` to override)"); ("moved by default", ""));
self.tcx.sess.span_note( self.tcx.sess.span_note(
expr_span, expr_span,
format!("`{}` moved here{} because it has type `{}`, which is {}", format!("`{}` moved here{} because it has type `{}`, which is {}",
@ -540,13 +540,15 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
move_data::MovePat => { move_data::MovePat => {
let pat_ty = ty::node_id_to_type(self.tcx, the_move.id); 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 `{}`, \ format!("`{}` moved here{} because it has type `{}`, \
which is moved by default (use `ref` to \ which is moved by default",
override)",
ol, ol,
moved_lp_msg, moved_lp_msg,
pat_ty.user_string(self.tcx)).as_slice()); pat_ty.user_string(self.tcx)).as_slice());
self.tcx.sess.span_help(span,
"use `ref` to override");
} }
move_data::Captured => { move_data::Captured => {
@ -563,9 +565,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
r).as_slice()) r).as_slice())
} }
}; };
let suggestion = move_suggestion(self.tcx, expr_ty, let (suggestion, help) = move_suggestion(self.tcx, expr_ty,
"moved by default (make a copy and \ ("moved by default", "make a copy and \
capture that instead to override)"); capture that instead to override"));
self.tcx.sess.span_note( self.tcx.sess.span_note(
expr_span, expr_span,
format!("`{}` moved into closure environment here{} because it \ format!("`{}` moved into closure environment here{} because it \
@ -574,21 +576,23 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
moved_lp_msg, moved_lp_msg,
expr_ty.user_string(self.tcx), expr_ty.user_string(self.tcx),
suggestion).as_slice()); suggestion).as_slice());
self.tcx.sess.span_help(expr_span, help);
} }
} }
fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msg: &'static str) fn move_suggestion(tcx: &ty::ctxt, ty: ty::t, default_msgs: (&'static str, &'static str))
-> &'static str { -> (&'static str, &'static str) {
match ty::get(ty).sty { match ty::get(ty).sty {
ty::ty_closure(box ty::ClosureTy { ty::ty_closure(box ty::ClosureTy {
store: ty::RegionTraitStore(..), store: ty::RegionTraitStore(..),
.. ..
}) => }) =>
"a non-copyable stack closure (capture it in a new closure, \ ("a non-copyable stack closure",
e.g. `|x| f(x)`, to override)", "capture it in a new closure, e.g. `|x| f(x)`, to override"),
_ if ty::type_moves_by_default(tcx, ty) => _ if ty::type_moves_by_default(tcx, ty) =>
"non-copyable (perhaps you meant to use clone()?)", ("non-copyable",
_ => default_msg, "perhaps you meant to use `clone()`?"),
_ => default_msgs,
} }
} }
} }
@ -733,7 +737,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.tcx.sess.span_err(span, self.tcx.sess.span_err(span,
format!("{} in a captured outer \ format!("{} in a captured outer \
variable in an `Fn` closure", prefix).as_slice()); 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"); "consider changing this closure to take self by mutable reference");
} }
mc::AliasableStatic(..) | mc::AliasableStatic(..) |
@ -750,7 +754,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
} }
if is_closure { if is_closure {
self.tcx.sess.span_note( self.tcx.sess.span_help(
span, span,
"closures behind references must be called via `&mut`"); "closures behind references must be called via `&mut`");
} }
@ -770,7 +774,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
_ => unreachable!() _ => unreachable!()
}; };
if kind == ty::FnUnboxedClosureKind { if kind == ty::FnUnboxedClosureKind {
self.tcx.sess.span_note( self.tcx.sess.span_help(
self.tcx.map.span(upvar_id.closure_expr_id), self.tcx.map.span(upvar_id.closure_expr_id),
"consider changing this closure to take \ "consider changing this closure to take \
self by mutable reference"); self by mutable reference");
@ -787,15 +791,20 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
sub_scope, sub_scope,
"..."); "...");
let suggestion = if is_statement_scope(self.tcx, super_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 { } else {
"" None
}; };
note_and_explain_region( let span = note_and_explain_region(
self.tcx, self.tcx,
"...but borrowed value is only valid for ", "...but borrowed value is only valid for ",
super_scope, 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) => { err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {

View file

@ -213,7 +213,7 @@ fn add_library(sess: &session::Session,
sess.err(format!("cannot satisfy dependencies so `{}` only \ sess.err(format!("cannot satisfy dependencies so `{}` only \
shows up once", shows up once",
data.name).as_slice()); 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"); will likely make this go away");
} }
} }

View file

@ -1568,7 +1568,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
hi: original_span.hi, hi: original_span.hi,
expn_id: original_span.expn_id expn_id: original_span.expn_id
}; };
self.ir.tcx.sess.span_note( self.ir.tcx.sess.span_help(
span_semicolon, "consider removing this semicolon:"); span_semicolon, "consider removing this semicolon:");
} }
} }

View file

@ -5744,7 +5744,7 @@ impl<'a> Resolver<'a> {
uses it like a function name", uses it like a function name",
wrong_name).as_slice()); wrong_name).as_slice());
self.session.span_note(expr.span, self.session.span_help(expr.span,
format!("Did you mean to write: \ format!("Did you mean to write: \
`{} {{ /* fields */ }}`?", `{} {{ /* fields */ }}`?",
wrong_name).as_slice()); wrong_name).as_slice());

View file

@ -172,18 +172,18 @@ pub fn opt_ast_region_to_region<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
} }
} }
if len == 1 { 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 \ "this function's return type contains a borrowed value, but \
the signature does not say which {} it is borrowed from", the signature does not say which {} it is borrowed from",
m); m);
} else if len == 0 { } 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 \ "this function's return type contains a borrowed value, but \
there is no value for it to be borrowed from"); 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"); "consider giving it a 'static lifetime");
} else { } 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 \ "this function's return type contains a borrowed value, but \
the signature does not say whether it is borrowed from {}", the signature does not say whether it is borrowed from {}",
m); m);
@ -302,7 +302,7 @@ fn ast_path_substs<'tcx,AC,RS>(
&& !this.tcx().sess.features.borrow().default_type_params { && !this.tcx().sess.features.borrow().default_type_params {
span_err!(this.tcx().sess, path.span, E0108, span_err!(this.tcx().sess, path.span, E0108,
"default type parameters are experimental and possibly buggy"); "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"); "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() let param_lifetimes: Vec<(String, uint)> = lifetimes_for_params.into_iter()
.map(|(n, v)| (n, v.len())) .map(|(n, v)| (n, v.len()))
.filter(|&(_, l)| l != 0)
.collect(); .collect();
let output_ty = match decl.output.node { let output_ty = match decl.output.node {

View file

@ -1355,18 +1355,18 @@ fn check_cast(fcx: &FnCtxt,
ast::MutImmutable => "" ast::MutImmutable => ""
}; };
if ty::type_is_trait(t_1) { 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 { } else {
span_note!(fcx.tcx().sess, span, span_help!(fcx.tcx().sess, span,
"consider using an implicit coercion to `&{}{}` instead", "consider using an implicit coercion to `&{}{}` instead",
mtstr, tstr); mtstr, tstr);
} }
} }
ty::ty_uniq(..) => { 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"); "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 { if !fcx.tcx().sess.features.borrow().overloaded_calls {
span_err!(fcx.tcx().sess, call_expression.span, E0056, span_err!(fcx.tcx().sess, call_expression.span, E0056,
"overloaded calls are experimental"); "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 \ "add `#![feature(overloaded_calls)]` to \
the crate attributes to enable"); the crate attributes to enable");
} }
@ -3479,8 +3479,9 @@ fn check_expr_with_unifier(fcx: &FnCtxt,
}, },
expr_t, None); expr_t, None);
tcx.sess.span_note(field.span, tcx.sess.span_help(field.span,
"maybe a missing `()` to call it? If not, try an anonymous function."); "maybe a `()` to call it is missing? \
If not, try an anonymous function");
} }
Err(_) => { Err(_) => {
@ -4787,7 +4788,8 @@ pub fn check_instantiable(tcx: &ty::ctxt,
if !ty::is_instantiable(tcx, item_ty) { if !ty::is_instantiable(tcx, item_ty) {
span_err!(tcx.sess, sp, E0073, span_err!(tcx.sess, sp, E0073,
"this type cannot be instantiated without an \ "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)); ppaux::ty_to_string(tcx, item_ty));
false false
} else { } else {

View file

@ -521,7 +521,7 @@ fn note_obligation_cause(fcx: &FnCtxt,
span_note!(tcx.sess, obligation.cause.span, span_note!(tcx.sess, obligation.cause.span,
"cannot implement a destructor on a \ "cannot implement a destructor on a \
structure or enumeration that does not satisfy Send"); 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 \ "use \"#[unsafe_destructor]\" on the implementation \
to force the compiler to allow this"); to force the compiler to allow this");
} }

View file

@ -438,9 +438,12 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
self.tcx.sess.span_err( self.tcx.sess.span_err(
origin.span(), origin.span(),
format!( format!(
"the parameter type `{}` may not live long enough; \ "the parameter type `{}` may not live long enough",
consider adding an explicit lifetime bound `{}:{}`...", param_ty.user_string(self.tcx)).as_slice());
param_ty.user_string(self.tcx), self.tcx.sess.span_help(
origin.span(),
format!(
"consider adding an explicit lifetime bound `{}: {}`...",
param_ty.user_string(self.tcx), param_ty.user_string(self.tcx),
sub.user_string(self.tcx)).as_slice()); sub.user_string(self.tcx)).as_slice());
} }
@ -450,9 +453,12 @@ impl<'a, 'tcx> ErrorReporting for InferCtxt<'a, 'tcx> {
self.tcx.sess.span_err( self.tcx.sess.span_err(
origin.span(), origin.span(),
format!( format!(
"the parameter type `{}` may not live long enough; \ "the parameter type `{}` may not live long enough",
consider adding an explicit lifetime bound `{}:'static`...", param_ty.user_string(self.tcx)).as_slice());
param_ty.user_string(self.tcx), self.tcx.sess.span_help(
origin.span(),
format!(
"consider adding an explicit lifetime bound `{}: 'static`...",
param_ty.user_string(self.tcx)).as_slice()); 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( self.tcx.sess.span_err(
origin.span(), origin.span(),
format!( format!(
"the parameter type `{}` may not live long enough; \ "the parameter type `{}` may not live long enough",
consider adding an explicit lifetime bound to `{}`", param_ty.user_string(self.tcx)).as_slice());
param_ty.user_string(self.tcx), self.tcx.sess.span_help(
origin.span(),
format!(
"consider adding an explicit lifetime bound to `{}`",
param_ty.user_string(self.tcx)).as_slice()); param_ty.user_string(self.tcx)).as_slice());
note_and_explain_region( note_and_explain_region(
self.tcx, self.tcx,

View file

@ -48,16 +48,18 @@ pub trait UserString {
pub fn note_and_explain_region(cx: &ctxt, pub fn note_and_explain_region(cx: &ctxt,
prefix: &str, prefix: &str,
region: ty::Region, region: ty::Region,
suffix: &str) { suffix: &str) -> Option<Span> {
match explain_region_and_span(cx, region) { match explain_region_and_span(cx, region) {
(ref str, Some(span)) => { (ref str, Some(span)) => {
cx.sess.span_note( cx.sess.span_note(
span, span,
format!("{}{}{}", prefix, *str, suffix).as_slice()); format!("{}{}{}", prefix, *str, suffix).as_slice());
Some(span)
} }
(ref str, None) => { (ref str, None) => {
cx.sess.note( cx.sess.note(
format!("{}{}{}", prefix, *str, suffix).as_slice()); format!("{}{}{}", prefix, *str, suffix).as_slice());
None
} }
} }
} }

View file

@ -22,10 +22,10 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt,
tts: &[ast::TokenTree]) tts: &[ast::TokenTree])
-> Box<base::MacResult+'cx> { -> Box<base::MacResult+'cx> {
cx.span_warn(sp, "`bytes!` is deprecated, use `b\"foo\"` literals instead"); 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 \ "see http://doc.rust-lang.org/reference.html#byte-and-byte-string-literals \
for documentation"); 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 \ "see https://github.com/rust-lang/rust/blob/master/src/etc/2014-06-rewrite-bytes-macros.py \
for an automated migration"); for an automated migration");

View file

@ -131,7 +131,7 @@ impl<'a> Context<'a> {
fn gate_feature(&self, feature: &str, span: Span, explain: &str) { fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
if !self.has_feature(feature) { if !self.has_feature(feature) {
self.span_handler.span_err(span, explain); 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", crate attributes to enable",
feature).as_slice()); feature).as_slice());
} }

View file

@ -2371,10 +2371,19 @@ impl<'a> Parser<'a> {
token::LitFloat(n) => { token::LitFloat(n) => {
self.bump(); self.bump();
let last_span = self.last_span; let last_span = self.last_span;
let fstr = n.as_str();
self.span_err(last_span, self.span_err(last_span,
format!("unexpected token: `{}`", n.as_str()).as_slice()); format!("unexpected token: `{}`", n.as_str()).as_slice());
self.span_note(last_span, if fstr.chars().all(|x| "0123456789.".contains_char(x)) {
"try parenthesizing the first index; e.g., `(foo.0).1`"); 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(); self.abort_if_errors();
} }
@ -2578,7 +2587,7 @@ impl<'a> Parser<'a> {
token::Eof => { token::Eof => {
let open_braces = self.open_braces.clone(); let open_braces = self.open_braces.clone();
for sp in open_braces.iter() { 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 // There shouldn't really be a span, but it's easier for the test runner
// if we give it one // if we give it one
@ -5352,8 +5361,8 @@ impl<'a> Parser<'a> {
self.bump(); self.bump();
if self.eat_keyword(keywords::Mut) { if self.eat_keyword(keywords::Mut) {
let last_span = self.last_span; let last_span = self.last_span;
self.span_err(last_span, "const globals cannot be mutable, \ self.span_err(last_span, "const globals cannot be mutable");
did you mean to declare a static?"); self.span_help(last_span, "did you mean to declare a static?");
} }
let (ident, item_, extra_attrs) = self.parse_item_const(None); let (ident, item_, extra_attrs) = self.parse_item_const(None);
let last_span = self.last_span; let last_span = self.last_span;

View file

@ -11,7 +11,7 @@
fn f() { fn f() {
let x = [1i].iter(); //~ ERROR borrowed value does not live long enough let x = [1i].iter(); //~ ERROR borrowed value does not live long enough
//~^^ NOTE reference must be valid for the block //~^^ 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() { fn main() {

View file

@ -11,7 +11,7 @@
fn blah() -> int { //~ ERROR not all control paths return a value fn blah() -> int { //~ ERROR not all control paths return a value
1i 1i
; //~ NOTE consider removing this semicolon: ; //~ HELP consider removing this semicolon:
} }
fn main() { } fn main() { }

View file

@ -15,12 +15,12 @@ fn foo() -> String { //~ ERROR not all control paths return a value
"world") "world")
// Put the trailing semicolon on its own line to test that the // Put the trailing semicolon on its own line to test that the
// note message gets the offending semicolon exactly // 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 fn bar() -> String { //~ ERROR not all control paths return a value
"foobar".to_string() "foobar".to_string()
; //~ NOTE consider removing this semicolon ; //~ HELP consider removing this semicolon
} }
pub fn main() {} pub fn main() {}

View file

@ -15,8 +15,9 @@ trait ListItem<'a> {
trait Collection { fn len(&self) -> uint; } trait Collection { fn len(&self) -> uint; }
struct List<'a, T: ListItem<'a>> { struct List<'a, T: ListItem<'a>> {
//~^ ERROR the parameter type `T` may not live long enough; consider adding an explicit lifetime bo //~^ ERROR the parameter type `T` may not live long enough
//~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at //~^^ 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] slice: &'a [T]
} }

View file

@ -11,14 +11,14 @@
fn main() { fn main() {
let _foo = &[1u, 2] as [uint]; let _foo = &[1u, 2] as [uint];
//~^ ERROR cast to unsized type: `&[uint, ..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; let _bar = box 1u as std::fmt::Show;
//~^ ERROR cast to unsized type: `Box<uint>` as `core::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; let _baz = 1u as std::fmt::Show;
//~^ ERROR cast to unsized type: `uint` as `core::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]; let _quux = [1u, 2] as [uint];
//~^ ERROR cast to unsized type: `[uint, ..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
} }

View file

@ -9,7 +9,8 @@
// except according to those terms. // except according to those terms.
const 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; FOO: uint = 3;
fn main() { fn main() {

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // 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) { match Some(x) {
Some(y) { panic!(); } Some(y) { panic!(); }
None { panic!(); } None { panic!(); }

View file

@ -15,5 +15,5 @@ struct Monster {
fn main() { fn main() {
let _m = Monster(); //~ ERROR `Monster` is a structure name, but 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 */ }`?
} }

View file

@ -10,13 +10,13 @@
// Lifetime annotation needed because we have no arguments. // Lifetime annotation needed because we have no arguments.
fn f() -> &int { //~ ERROR missing lifetime specifier 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!() panic!()
} }
// Lifetime annotation needed because we have two by-reference parameters. // Lifetime annotation needed because we have two by-reference parameters.
fn g(_x: &int, _y: &int) -> &int { //~ ERROR missing lifetime specifier 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!() panic!()
} }
@ -27,7 +27,13 @@ struct Foo<'a> {
// Lifetime annotation needed because we have two lifetimes: one as a parameter // Lifetime annotation needed because we have two lifetimes: one as a parameter
// and one on the reference. // and one on the reference.
fn h(_x: &Foo) -> &int { //~ ERROR missing lifetime specifier 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!() panic!()
} }

View file

@ -14,12 +14,12 @@
macro_rules! test ( () => { fn foo() -> int { 1i; } } ) macro_rules! test ( () => { fn foo() -> int { 1i; } } )
//~^ ERROR not all control paths return a value //~^ 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 no_return() -> int {} //~ ERROR not all control paths return a value
fn bar(x: u32) -> u32 { //~ 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 fn baz(x: u64) -> u32 { //~ ERROR not all control paths return a value

View file

@ -30,7 +30,7 @@ fn main() {
let point: Point = Point::new(); let point: Point = Point::new();
let px: int = point let px: int = point
.get_x;//~ ERROR attempted to take value of method `get_x` on type `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 // Ensure the span is useful
let ys = &[1i,2,3,4,5,6,7]; let ys = &[1i,2,3,4,5,6,7];
@ -38,6 +38,6 @@ fn main() {
.map(|x| x) .map(|x| x)
.filter(|&&x| x == 1) .filter(|&&x| x == 1)
.filter_map; //~ ERROR attempted to take value of method `filter_map` on type .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
} }