Auto merge of #33619 - jonathandturner:improve_structured_errors, r=nikomatsakis

Batch of improvements to errors for new error format

This is a batch of improvements to existing errors to help get the most out of the new error format.

* Added labels to primary spans (^^^) for a set of errors that didn't currently have them
* Highlight the source blue under the secondary notes for better readability
* Move some of the "Note:" into secondary spans+labels
* Fix span_label to take &mut instead, which makes it work the same as other methods in that set
This commit is contained in:
bors 2016-05-15 15:08:46 -07:00
commit 5ebe41835f
30 changed files with 279 additions and 172 deletions

View File

@ -482,10 +482,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
trace.origin);
if !is_simple_error {
err = err.note_expected_found(&"type", &expected, &found);
err.note_expected_found(&"type", &expected, &found);
}
err = err.span_label(trace.origin.span(), &terr);
err.span_label(trace.origin.span(), &terr);
self.check_and_note_conflicting_crates(&mut err, terr, trace.origin.span());

View File

@ -475,99 +475,104 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
let mut err = match (new_loan.kind, old_loan.kind) {
(ty::MutBorrow, ty::MutBorrow) => {
struct_span_err!(self.bccx, new_loan.span, E0499,
"cannot borrow `{}`{} as mutable \
more than once at a time",
nl, new_loan_msg)
.span_label(
let mut err = struct_span_err!(self.bccx, new_loan.span, E0499,
"cannot borrow `{}`{} as mutable \
more than once at a time",
nl, new_loan_msg);
err.span_label(
old_loan.span,
&format!("first mutable borrow occurs here{}", old_loan_msg))
.span_label(
&format!("first mutable borrow occurs here{}", old_loan_msg));
err.span_label(
new_loan.span,
&format!("second mutable borrow occurs here{}", new_loan_msg))
.span_label(
&format!("second mutable borrow occurs here{}", new_loan_msg));
err.span_label(
previous_end_span,
&format!("first borrow ends here"))
&format!("first borrow ends here"));
err
}
(ty::UniqueImmBorrow, ty::UniqueImmBorrow) => {
struct_span_err!(self.bccx, new_loan.span, E0524,
let mut err = struct_span_err!(self.bccx, new_loan.span, E0524,
"two closures require unique access to `{}` \
at the same time",
nl)
.span_label(
nl);
err.span_label(
old_loan.span,
&format!("first closure is constructed here"))
.span_label(
&format!("first closure is constructed here"));
err.span_label(
new_loan.span,
&format!("second closure is constructed here"))
.span_label(
&format!("second closure is constructed here"));
err.span_label(
previous_end_span,
&format!("borrow from first closure ends here"))
&format!("borrow from first closure ends here"));
err
}
(ty::UniqueImmBorrow, _) => {
struct_span_err!(self.bccx, new_loan.span, E0500,
"closure requires unique access to `{}` \
but {} is already borrowed{}",
nl, ol_pronoun, old_loan_msg)
.span_label(
let mut err = struct_span_err!(self.bccx, new_loan.span, E0500,
"closure requires unique access to `{}` \
but {} is already borrowed{}",
nl, ol_pronoun, old_loan_msg);
err.span_label(
new_loan.span,
&format!("closure construction occurs here{}", new_loan_msg))
.span_label(
&format!("closure construction occurs here{}", new_loan_msg));
err.span_label(
old_loan.span,
&format!("borrow occurs here{}", old_loan_msg))
.span_label(
&format!("borrow occurs here{}", old_loan_msg));
err.span_label(
previous_end_span,
&format!("borrow ends here"))
&format!("borrow ends here"));
err
}
(_, ty::UniqueImmBorrow) => {
struct_span_err!(self.bccx, new_loan.span, E0501,
"cannot borrow `{}`{} as {} because \
previous closure requires unique access",
nl, new_loan_msg, new_loan.kind.to_user_str())
.span_label(
let mut err = struct_span_err!(self.bccx, new_loan.span, E0501,
"cannot borrow `{}`{} as {} because \
previous closure requires unique access",
nl, new_loan_msg, new_loan.kind.to_user_str());
err.span_label(
new_loan.span,
&format!("borrow occurs here{}", new_loan_msg))
.span_label(
&format!("borrow occurs here{}", new_loan_msg));
err.span_label(
old_loan.span,
&format!("closure construction occurs here{}", old_loan_msg))
.span_label(
&format!("closure construction occurs here{}", old_loan_msg));
err.span_label(
previous_end_span,
&format!("borrow from closure ends here"))
&format!("borrow from closure ends here"));
err
}
(_, _) => {
struct_span_err!(self.bccx, new_loan.span, E0502,
"cannot borrow `{}`{} as {} because \
{} is also borrowed as {}{}",
nl,
new_loan_msg,
new_loan.kind.to_user_str(),
ol_pronoun,
old_loan.kind.to_user_str(),
old_loan_msg)
.span_label(
let mut err = struct_span_err!(self.bccx, new_loan.span, E0502,
"cannot borrow `{}`{} as {} because \
{} is also borrowed as {}{}",
nl,
new_loan_msg,
new_loan.kind.to_user_str(),
ol_pronoun,
old_loan.kind.to_user_str(),
old_loan_msg);
err.span_label(
new_loan.span,
&format!("{} borrow occurs here{}",
new_loan.kind.to_user_str(),
new_loan_msg))
.span_label(
new_loan_msg));
err.span_label(
old_loan.span,
&format!("{} borrow occurs here{}",
old_loan.kind.to_user_str(),
old_loan_msg))
.span_label(
old_loan_msg));
err.span_label(
previous_end_span,
&format!("{} borrow ends here",
old_loan.kind.to_user_str()))
old_loan.kind.to_user_str()));
err
}
};
match new_loan.cause {
euv::ClosureCapture(span) => {
err = err.span_label(
err.span_label(
span,
&format!("borrow occurs due to use of `{}` in closure", nl));
}
@ -576,7 +581,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
match old_loan.cause {
euv::ClosureCapture(span) => {
err = err.span_label(
err.span_label(
span,
&format!("previous borrow occurs due to use of `{}` in closure",
ol));
@ -663,23 +668,41 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
UseOk => { }
UseWhileBorrowed(loan_path, loan_span) => {
let mut err = match move_kind {
move_data::Captured =>
struct_span_err!(self.bccx, span, E0504,
move_data::Captured => {
let mut err = struct_span_err!(self.bccx, span, E0504,
"cannot move `{}` into closure because it is borrowed",
&self.bccx.loan_path_to_string(move_path)),
&self.bccx.loan_path_to_string(move_path));
err.span_label(
loan_span,
&format!("borrow of `{}` occurs here",
&self.bccx.loan_path_to_string(&loan_path))
);
err.span_label(
span,
&format!("move into closure occurs here")
);
err
}
move_data::Declared |
move_data::MoveExpr |
move_data::MovePat =>
struct_span_err!(self.bccx, span, E0505,
move_data::MovePat => {
let mut err = struct_span_err!(self.bccx, span, E0505,
"cannot move out of `{}` because it is borrowed",
&self.bccx.loan_path_to_string(move_path))
&self.bccx.loan_path_to_string(move_path));
err.span_label(
loan_span,
&format!("borrow of `{}` occurs here",
&self.bccx.loan_path_to_string(&loan_path))
);
err.span_label(
span,
&format!("move out of `{}` occurs here",
&self.bccx.loan_path_to_string(move_path))
);
err
}
};
err.span_note(
loan_span,
&format!("borrow of `{}` occurs here",
&self.bccx.loan_path_to_string(&loan_path))
);
err.emit();
}
}
@ -845,9 +868,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
struct_span_err!(self.bccx, span, E0506,
"cannot assign to `{}` because it is borrowed",
self.bccx.loan_path_to_string(loan_path))
.span_note(loan.span,
.span_label(loan.span,
&format!("borrow of `{}` occurs here",
self.bccx.loan_path_to_string(loan_path)))
.span_label(span,
&format!("assignment to `{}` occurs here",
self.bccx.loan_path_to_string(loan_path)))
.emit();
}
}

View File

@ -72,7 +72,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
let mut is_first_note = true;
for move_to in &error.move_to_places {
note_move_destination(&mut err, move_to.span,
err = note_move_destination(err, move_to.span,
move_to.name, is_first_note);
is_first_note = false;
}
@ -121,18 +121,25 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
Categorization::Deref(_, _, mc::Implicit(..)) |
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
Categorization::StaticItem => {
struct_span_err!(bccx, move_from.span, E0507,
let mut err = struct_span_err!(bccx, move_from.span, E0507,
"cannot move out of {}",
move_from.descriptive_string(bccx.tcx))
move_from.descriptive_string(bccx.tcx));
err.span_label(
move_from.span,
&format!("move occurs here")
);
err
}
Categorization::Interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
let expr = bccx.tcx.map.expect_expr(move_from.id);
if let hir::ExprIndex(..) = expr.node {
struct_span_err!(bccx, move_from.span, E0508,
"cannot move out of type `{}`, \
a non-copy fixed-size array",
b.ty)
let mut err = struct_span_err!(bccx, move_from.span, E0508,
"cannot move out of type `{}`, \
a non-copy fixed-size array",
b.ty);
err.span_label(move_from.span, &format!("can not move out of here"));
err
} else {
span_bug!(move_from.span, "this path should not cause illegal move");
}
@ -143,10 +150,12 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
match b.ty.sty {
ty::TyStruct(def, _) |
ty::TyEnum(def, _) if def.has_dtor() => {
struct_span_err!(bccx, move_from.span, E0509,
"cannot move out of type `{}`, \
which defines the `Drop` trait",
b.ty)
let mut err = struct_span_err!(bccx, move_from.span, E0509,
"cannot move out of type `{}`, \
which defines the `Drop` trait",
b.ty);
err.span_label(move_from.span, &format!("can not move out of here"));
err
},
_ => {
span_bug!(move_from.span, "this path should not cause illegal move");
@ -159,22 +168,24 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
}
}
fn note_move_destination(err: &mut DiagnosticBuilder,
fn note_move_destination(mut err: DiagnosticBuilder,
move_to_span: codemap::Span,
pat_name: ast::Name,
is_first_note: bool) {
is_first_note: bool) -> DiagnosticBuilder {
if is_first_note {
err.span_note(
err.span_label(
move_to_span,
"attempting to move value to here");
&format!("attempting to move value to here"));
err.help(
&format!("to prevent the move, \
use `ref {0}` or `ref mut {0}` to capture value by \
reference",
pat_name));
err
} else {
err.span_note(move_to_span,
&format!("and here (use `ref {0}` or `ref mut {0}`)",
pat_name));
err
}
}

View File

@ -620,10 +620,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
}
// General fallback.
let span = err.span.clone();
let mut db = self.struct_span_err(
err.span,
&self.bckerr_to_string(&err));
self.note_and_explain_bckerr(&mut db, err);
self.note_and_explain_bckerr(&mut db, err, span);
db.emit();
}
@ -647,7 +648,10 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
self.tcx.sess, use_span, E0381,
"{} of possibly uninitialized variable: `{}`",
verb,
self.loan_path_to_string(lp)).emit();
self.loan_path_to_string(lp))
.span_label(use_span, &format!("use of possibly uninitialized `{}`",
self.loan_path_to_string(lp)))
.emit();
return;
}
_ => {
@ -716,10 +720,12 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
err.span_label(
use_span,
&format!("value moved{} here in previous iteration of loop",
move_note))
move_note));
err
} else {
err.span_label(use_span, &format!("value {} here after move", verb_participle))
.span_label(move_span, &format!("value moved{} here", move_note))
.span_label(move_span, &format!("value moved{} here", move_note));
err
};
err.note(&format!("move occurs because `{}` has type `{}`, \
@ -946,7 +952,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
.emit();
}
pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>) {
pub fn note_and_explain_bckerr(&self, db: &mut DiagnosticBuilder, err: BckError<'tcx>,
error_span: Span) {
let code = err.code;
match code {
err_mutbl => {
@ -971,13 +978,11 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
let span = self.tcx.map.span(local_id);
if let Ok(snippet) = self.tcx.sess.codemap().span_to_snippet(span) {
if snippet != "self" {
db.span_suggestion(
span,
&format!("to make the {} mutable, use `mut` as shown:",
self.cmt_to_string(&err.cmt)),
format!("mut {}", snippet));
db.span_label(span,
&format!("use `mut {}` here to make mutable", snippet));
}
}
db.span_label(error_span, &format!("cannot borrow mutably"));
}
}
}
@ -995,6 +1000,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
super_scope,
"");
if let Some(span) = statement_scope_span(self.tcx, super_scope) {
db.span_label(error_span, &format!("does not live long enough"));
db.span_help(span,
"consider using a `let` binding to increase its lifetime");
}

View File

@ -123,7 +123,7 @@ enum ResolutionError<'a> {
SelfUsedOutsideImplOrTrait,
/// error E0412: use of undeclared
UseOfUndeclared(&'a str, &'a str, SuggestedCandidates),
/// error E0413: declaration shadows an enum variant or unit-like struct in scope
/// error E0413: cannot be named the same as an enum variant or unit-like struct in scope
DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
/// error E0414: only irrefutable patterns allowed here
ConstantForIrrefutableBinding(Name),
@ -200,11 +200,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
match resolution_error {
ResolutionError::TypeParametersFromOuterFunction => {
struct_span_err!(resolver.session,
span,
E0401,
"can't use type parameters from outer function; try using a local \
type parameter instead")
let mut err = struct_span_err!(resolver.session,
span,
E0401,
"can't use type parameters from outer function; \
try using a local type parameter instead");
err.span_label(span, &format!("use of type variable from outer function"));
err
}
ResolutionError::OuterTypeParameterContext => {
struct_span_err!(resolver.session,
@ -230,6 +232,7 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
"trait `{}` is not in scope",
name);
show_candidates(&mut err, &candidates);
err.span_label(span, &format!("`{}` is not in scope", name));
err
}
ResolutionError::UndeclaredAssociatedType => {
@ -278,10 +281,12 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
pattern_number)
}
ResolutionError::SelfUsedOutsideImplOrTrait => {
struct_span_err!(resolver.session,
span,
E0411,
"use of `Self` outside of an impl or trait")
let mut err = struct_span_err!(resolver.session,
span,
E0411,
"use of `Self` outside of an impl or trait");
err.span_label(span, &format!("used outside of impl or trait"));
err
}
ResolutionError::UseOfUndeclared(kind, name, candidates) => {
let mut err = struct_span_err!(resolver.session,
@ -291,44 +296,52 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
kind,
name);
show_candidates(&mut err, &candidates);
err.span_label(span, &format!("undefined or not in scope"));
err
}
ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
struct_span_err!(resolver.session,
let mut err = struct_span_err!(resolver.session,
span,
E0413,
"declaration of `{}` shadows an enum variant \
"`{}` cannot be named the same as an enum variant \
or unit-like struct in scope",
name)
name);
err.span_label(span,
&format!("has same name as enum variant or unit-like struct"));
err
}
ResolutionError::ConstantForIrrefutableBinding(name) => {
let mut err = struct_span_err!(resolver.session,
span,
E0414,
"variable bindings cannot shadow constants");
err.span_note(span,
"there already is a constant in scope sharing the same \
name as this pattern");
"let variables cannot be named the same as const variables");
err.span_label(span,
&format!("cannot be named the same as a const variable"));
if let Some(binding) = resolver.current_module
.resolve_name_in_lexical_scope(name, ValueNS) {
let participle = if binding.is_import() { "imported" } else { "defined" };
err.span_note(binding.span, &format!("constant {} here", participle));
err.span_label(binding.span, &format!("a constant `{}` is {} here",
name, participle));
}
err
}
ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
struct_span_err!(resolver.session,
let mut err = struct_span_err!(resolver.session,
span,
E0415,
"identifier `{}` is bound more than once in this parameter list",
identifier)
identifier);
err.span_label(span, &format!("used as parameter more than once"));
err
}
ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
struct_span_err!(resolver.session,
let mut err = struct_span_err!(resolver.session,
span,
E0416,
"identifier `{}` is bound more than once in the same pattern",
identifier)
identifier);
err.span_label(span, &format!("used in a pattern more than once"));
err
}
ResolutionError::StaticVariableReference(binding) => {
let mut err = struct_span_err!(resolver.session,
@ -336,9 +349,10 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
E0417,
"static variables cannot be referenced in a \
pattern, use a `const` instead");
err.span_label(span, &format!("static variable used in pattern"));
if binding.span != codemap::DUMMY_SP {
let participle = if binding.is_import() { "imported" } else { "defined" };
err.span_note(binding.span, &format!("static variable {} here", participle));
err.span_label(binding.span, &format!("static variable {} here", participle));
}
err
}
@ -1804,7 +1818,9 @@ impl<'a> Resolver<'a> {
// If it's a typedef, give a note
if let Def::TyAlias(..) = path_res.base_def {
err.note("`type` aliases cannot be used for traits");
let trait_name = trait_path.segments.last().unwrap().identifier.name;
err.span_label(trait_path.span,
&format!("`{}` is not a trait", trait_name));
let definition_site = {
let segments = &trait_path.segments;
@ -1816,7 +1832,8 @@ impl<'a> Resolver<'a> {
};
if definition_site != codemap::DUMMY_SP {
err.span_note(definition_site, "type defined here");
err.span_label(definition_site,
&format!("type aliases cannot be used for traits"));
}
}
err.emit();
@ -3462,12 +3479,16 @@ impl<'a> Resolver<'a> {
_ => match (old_binding.is_import(), binding.is_import()) {
(false, false) => struct_span_err!(self.session, span, E0428, "{}", msg),
(true, true) => struct_span_err!(self.session, span, E0252, "{}", msg),
_ => struct_span_err!(self.session, span, E0255, "{}", msg),
_ => {
let mut e = struct_span_err!(self.session, span, E0255, "{}", msg);
e.span_label(span, &format!("`{}` was already imported", name));
e
}
},
};
if old_binding.span != codemap::DUMMY_SP {
err.span_note(old_binding.span, &format!("previous {} of `{}` here", noun, name));
err.span_label(old_binding.span, &format!("previous {} of `{}` here", noun, name));
}
err.emit();
}

View File

@ -202,8 +202,8 @@ pub fn emit_type_err<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
terr: &ty::error::TypeError<'tcx>,
msg: &str) {
let mut err = struct_span_err!(tcx.sess, span, E0211, "{}", msg);
err = err.span_label(span, &terr);
err = err.note_expected_found(&"type", &expected_ty, &found_ty);
err.span_label(span, &terr);
err.note_expected_found(&"type", &expected_ty, &found_ty);
tcx.note_and_explain_type_err(&mut err, terr, span);
err.emit();
}

View File

@ -235,17 +235,17 @@ impl<'a> DiagnosticBuilder<'a> {
/// all, and you just supplied a `Span` to create the diagnostic,
/// then the snippet will just include that `Span`, which is
/// called the primary span.
pub fn span_label(mut self, span: Span, label: &fmt::Display)
-> DiagnosticBuilder<'a> {
pub fn span_label(&mut self, span: Span, label: &fmt::Display)
-> &mut DiagnosticBuilder<'a> {
self.span.push_span_label(span, format!("{}", label));
self
}
pub fn note_expected_found(mut self,
pub fn note_expected_found(&mut self,
label: &fmt::Display,
expected: &fmt::Display,
found: &fmt::Display)
-> DiagnosticBuilder<'a>
-> &mut DiagnosticBuilder<'a>
{
// For now, just attach these as notes
self.note(&format!("expected {} `{}`", label, expected));

View File

@ -618,6 +618,7 @@ impl FileInfo {
styled_buffer.set_style(0, p, Style::UnderlinePrimary);
} else {
styled_buffer.putc(1, p, '-', Style::UnderlineSecondary);
styled_buffer.set_style(0, p, Style::UnderlineSecondary);
}
}
}

View File

@ -27,7 +27,9 @@ fn main() {
x; //~ value moved here
let y = Int(2);
//~^use `mut y` here to make mutable
y //~ error: cannot borrow immutable local variable `y` as mutable
//~| cannot borrow
+=
Int(1);
}

View File

@ -12,6 +12,6 @@ mod foo { pub struct bar; }
fn main() {
let bar = 5;
//~^ ERROR declaration of `bar` shadows an enum variant or unit-like struct in scope
//~^ ERROR cannot be named the same
use foo::bar;
}

View File

@ -10,6 +10,8 @@
mod foo { pub mod foo { } } //~ NOTE previous definition of `foo` here
use foo::foo; //~ ERROR a module named `foo` has already been defined in this module
use foo::foo;
//~^ ERROR a module named `foo` has already been defined in this module
//~| was already imported
fn main() {}

View File

@ -61,7 +61,9 @@ fn move_after_borrow() {
let a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &a.x;
//~^ NOTE borrow of `a.x` occurs here
let _y = a.y; //~ ERROR cannot move
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
}
fn copy_after_mut_borrow() {
@ -75,7 +77,9 @@ fn move_after_mut_borrow() {
let mut a: Box<_> = box B { x: box 0, y: box 1 };
let _x = &mut a.x;
//~^ NOTE borrow of `a.x` occurs here
let _y = a.y; //~ ERROR cannot move
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
}
fn borrow_after_mut_borrow() {
@ -127,7 +131,9 @@ fn move_after_borrow_nested() {
let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &a.x.x;
//~^ borrow of `a.x.x` occurs here
let _y = a.y; //~ ERROR cannot move
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
}
fn copy_after_mut_borrow_nested() {
@ -141,7 +147,9 @@ fn move_after_mut_borrow_nested() {
let mut a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
let _x = &mut a.x.x;
//~^ NOTE borrow of `a.x.x` occurs here
let _y = a.y; //~ ERROR cannot move
let _y = a.y;
//~^ ERROR cannot move
//~| move out of
}
fn borrow_after_mut_borrow_nested() {

View File

@ -26,6 +26,7 @@ fn f() {
v3.push(&'x'); // statement 6
//~^ ERROR borrowed value does not live long enough
//~| does not live long enough
//~| NOTE ...but borrowed value is only valid for the statement
//~| HELP consider using a `let` binding to increase its lifetime
@ -36,6 +37,7 @@ fn f() {
v4.push(&'y');
//~^ ERROR borrowed value does not live long enough
//~| does not live long enough
//~| NOTE ...but borrowed value is only valid for the statement
//~| HELP consider using a `let` binding to increase its lifetime
@ -46,6 +48,7 @@ fn f() {
v5.push(&'z');
//~^ ERROR borrowed value does not live long enough
//~| does not live long enough
//~| NOTE ...but borrowed value is only valid for the statement
//~| HELP consider using a `let` binding to increase its lifetime

View File

@ -9,10 +9,12 @@
// except according to those terms.
fn f() {
let x = [1].iter(); //~ ERROR borrowed value does not live long enough
//~^ NOTE reference must be valid for the block suffix following statement
//~^^ HELP consider using a `let` binding to increase its lifetime
//~^^^ NOTE ...but borrowed value is only valid for the statement at 12:4
let x = [1].iter();
//~^ ERROR borrowed value does not live long enough
//~|does not live long enough
//~| NOTE reference must be valid for the block suffix following statement
//~| HELP consider using a `let` binding to increase its lifetime
//~| NOTE ...but borrowed value is only valid for the statement at 12:4
}
fn main() {

View File

@ -19,6 +19,7 @@ enum Foo {
fn blah() {
let f = &Foo::Foo1(box 1, box 2);
match *f { //~ ERROR cannot move out of
//~| move occurs here
Foo::Foo1(num1, //~ NOTE attempting to move value to here
num2) => (), //~ NOTE and here
Foo::Foo2(num) => (), //~ NOTE and here
@ -37,6 +38,7 @@ impl Drop for S {
fn move_in_match() {
match (S {f: "foo".to_string(), g: "bar".to_string()}) {
S { //~ ERROR cannot move out of type `S`, which defines the `Drop` trait
//~| can not move out of here
f: _s, //~ NOTE attempting to move value to here
g: _t //~ NOTE and here
} => {}
@ -53,6 +55,7 @@ fn free<T>(_: T) {}
fn blah2() {
let a = &A { a: box 1 };
match a.a { //~ ERROR cannot move out of
//~| move occurs here
n => { //~ NOTE attempting to move value to here
free(n)
}

View File

@ -27,10 +27,12 @@ pub fn main() {
match x {
[_, tail..] => {
match tail {
[Foo { string: a }, //~ ERROR cannot move out of borrowed content
[Foo { string: a },
//~^ ERROR cannot move out of borrowed content
//~| move occurs here
//~| attempting to move value to here
Foo { string: b }] => {
//~^^ NOTE attempting to move value to here
//~^^ NOTE and here
//~^ NOTE and here
}
_ => {
unreachable!();

View File

@ -19,6 +19,7 @@ fn a() {
[box ref _a, _, _] => {
//~^ borrow of `vec[..]` occurs here
vec[0] = box 4; //~ ERROR cannot assign
//~^ assignment to `vec[..]` occurs here
}
}
}
@ -30,6 +31,7 @@ fn b() {
[_b..] => {
//~^ borrow of `vec[..]` occurs here
vec[0] = box 4; //~ ERROR cannot assign
//~^ assignment to `vec[..]` occurs here
}
}
}
@ -39,8 +41,9 @@ fn c() {
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_a, //~ ERROR cannot move out
_b..] => { //~^ NOTE attempting to move value to here
//~| move occurs here
//~| attempting to move value to here
_b..] => {
// Note: `_a` is *moved* here, but `b` is borrowing,
// hence illegal.
//
@ -51,6 +54,7 @@ fn c() {
}
let a = vec[0]; //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
//~| can not move out of here
}
fn d() {
@ -58,11 +62,13 @@ fn d() {
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_a.., //~ ERROR cannot move out
//~^ move occurs here
_b] => {} //~ NOTE attempting to move value to here
_ => {}
}
let a = vec[0]; //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
//~| can not move out of here
}
fn e() {
@ -70,13 +76,15 @@ fn e() {
let vec: &mut [Box<isize>] = &mut vec;
match vec {
[_a, _b, _c] => {} //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
//~^^ NOTE and here
//~^^^ NOTE and here
//~| move occurs here
//~| NOTE attempting to move value to here
//~| NOTE and here
//~| NOTE and here
_ => {}
}
let a = vec[0]; //~ ERROR cannot move out
//~^ NOTE attempting to move value to here
//~| can not move out of here
}
fn main() {}

View File

@ -13,16 +13,16 @@ mod foo {
pub const d: u8 = 2;
}
use foo::b as c; //~ NOTE constant imported here
use foo::d; //~ NOTE constant imported here
use foo::b as c; //~ NOTE is imported here
use foo::d; //~ NOTE is imported here
const a: u8 = 2; //~ NOTE constant defined here
const a: u8 = 2; //~ NOTE is defined here
fn main() {
let a = 4; //~ ERROR variable bindings cannot
//~^ NOTE there already is a constant in scope
let c = 4; //~ ERROR variable bindings cannot
//~^ NOTE there already is a constant in scope
let d = 4; //~ ERROR variable bindings cannot
//~^ NOTE there already is a constant in scope
let a = 4; //~ ERROR let variables cannot
//~^ NOTE cannot be named the same as a const variable
let c = 4; //~ ERROR let variables cannot
//~^ NOTE cannot be named the same as a const variable
let d = 4; //~ ERROR let variables cannot
//~^ NOTE cannot be named the same as a const variable
}

View File

@ -11,5 +11,5 @@
struct hello(isize);
fn main() {
let hello = 0; //~ERROR declaration of `hello` shadows
let hello = 0; //~ERROR cannot be named the same
}

View File

@ -11,11 +11,13 @@
use self::A; //~ NOTE previous import of `A` here
use self::B; //~ NOTE previous import of `B` here
mod A {} //~ ERROR a module named `A` has already been imported in this module
//~| `A` was already imported
pub mod B {} //~ ERROR a module named `B` has already been imported in this module
//~| `B` was already imported
mod C {
use C::D; //~ NOTE previous import of `D` here
mod D {} //~ ERROR a module named `D` has already been imported in this module
//~| `D` was already imported
}
fn main() {}

View File

@ -13,6 +13,7 @@ static foo: i32 = 0;
fn bar(foo: i32) {}
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
//~| static variable used in pattern
mod submod {
pub static answer: i32 = 42;
@ -23,6 +24,6 @@ use self::submod::answer;
fn question(answer: i32) {}
//~^ ERROR static variables cannot be referenced in a pattern, use a `const` instead
//~| static variable used in pattern
fn main() {
}

View File

@ -15,9 +15,14 @@ use std::ops::Div; //~ NOTE previous import
use std::ops::Rem; //~ NOTE previous import
type Add = bool; //~ ERROR a trait named `Add` has already been imported in this module
//~| was already imported
struct Sub { x: f32 } //~ ERROR a trait named `Sub` has already been imported in this module
//~| was already imported
enum Mul { A, B } //~ ERROR a trait named `Mul` has already been imported in this module
//~| was already imported
mod Div { } //~ ERROR a trait named `Div` has already been imported in this module
//~| was already imported
trait Rem { } //~ ERROR a trait named `Rem` has already been imported in this module
//~| was already imported
fn main() {}

View File

@ -10,11 +10,11 @@
fn main() {
match Some(1) {
None @ _ => {} //~ ERROR declaration of `None` shadows an enum variant
None @ _ => {} //~ ERROR cannot be named the same
};
const C: u8 = 1;
match 1 {
C @ 2 => { //~ ERROR variable bindings cannot shadow constants
C @ 2 => { //~ ERROR cannot be named the same
println!("{}", C);
}
_ => {}

View File

@ -11,14 +11,14 @@
// aux-build:issue_3907.rs
extern crate issue_3907;
type Foo = issue_3907::Foo; //~ NOTE: type defined here
type Foo = issue_3907::Foo; //~ NOTE: type aliases cannot be used for traits
struct S {
name: isize
}
impl Foo for S { //~ ERROR: `Foo` is not a trait
//~^ NOTE: `type` aliases cannot be used for traits
//~| `Foo` is not a trait
fn bar() { }
}

View File

@ -9,7 +9,8 @@
// except according to those terms.
trait I {}
type K = I; //~ NOTE: type defined here
type K = I;
//~^ NOTE: aliases cannot be used for traits
impl K for isize {} //~ ERROR: `K` is not a trait
//~^ NOTE: `type` aliases cannot be used for traits
//~| is not a trait
fn main() {}

View File

@ -32,6 +32,7 @@ fn main() {
loop {
f(&s, |hellothere| {
match hellothere.x { //~ ERROR cannot move out
//~| move occurs here
box E::Foo(_) => {}
box E::Bar(x) => println!("{}", x.to_string()), //~ NOTE attempting to move value to here
box E::Baz => {}

View File

@ -17,14 +17,16 @@ impl S {
}
fn func(arg: S) {
//~^ HELP use `mut` as shown
//~| SUGGESTION fn func(mut arg: S) {
arg.mutate(); //~ ERROR cannot borrow immutable argument
//~^ here to make mutable
arg.mutate();
//~^ ERROR cannot borrow immutable argument
//~| cannot borrow mutably
}
fn main() {
let local = S;
//~^ HELP use `mut` as shown
//~| SUGGESTION let mut local = S;
local.mutate(); //~ ERROR cannot borrow immutable local variable
//~^ here to make mutable
local.mutate();
//~^ ERROR cannot borrow immutable local variable
//~| cannot borrow mutably
}

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// error-pattern:declaration of `None` shadows
// error-pattern:cannot be named the same
use std::option::*;
fn main() {

View File

@ -11,5 +11,5 @@
struct foo(usize);
fn main() {
let (foo, _) = (2, 3); //~ ERROR declaration of `foo` shadows
let (foo, _) = (2, 3); //~ ERROR `foo` cannot be named the same as
}

View File

@ -13,6 +13,6 @@ use std::mem::transmute;
fn transmute() {}
//~^ ERROR a value named `transmute` has already been imported in this module
//~| was already imported
fn main() {
}