Skip to content

Commit 5ebe418

Browse files
committed
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
2 parents e7420fb + 65cb5f7 commit 5ebe418

30 files changed

+279
-172
lines changed

src/librustc/infer/error_reporting.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -482,10 +482,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
482482
trace.origin);
483483

484484
if !is_simple_error {
485-
err = err.note_expected_found(&"type", &expected, &found);
485+
err.note_expected_found(&"type", &expected, &found);
486486
}
487487

488-
err = err.span_label(trace.origin.span(), &terr);
488+
err.span_label(trace.origin.span(), &terr);
489489

490490
self.check_and_note_conflicting_crates(&mut err, terr, trace.origin.span());
491491

src/librustc_borrowck/borrowck/check_loans.rs

+93-67
Original file line numberDiff line numberDiff line change
@@ -475,99 +475,104 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
475475

476476
let mut err = match (new_loan.kind, old_loan.kind) {
477477
(ty::MutBorrow, ty::MutBorrow) => {
478-
struct_span_err!(self.bccx, new_loan.span, E0499,
479-
"cannot borrow `{}`{} as mutable \
480-
more than once at a time",
481-
nl, new_loan_msg)
482-
.span_label(
478+
let mut err = struct_span_err!(self.bccx, new_loan.span, E0499,
479+
"cannot borrow `{}`{} as mutable \
480+
more than once at a time",
481+
nl, new_loan_msg);
482+
err.span_label(
483483
old_loan.span,
484-
&format!("first mutable borrow occurs here{}", old_loan_msg))
485-
.span_label(
484+
&format!("first mutable borrow occurs here{}", old_loan_msg));
485+
err.span_label(
486486
new_loan.span,
487-
&format!("second mutable borrow occurs here{}", new_loan_msg))
488-
.span_label(
487+
&format!("second mutable borrow occurs here{}", new_loan_msg));
488+
err.span_label(
489489
previous_end_span,
490-
&format!("first borrow ends here"))
490+
&format!("first borrow ends here"));
491+
err
491492
}
492493

493494
(ty::UniqueImmBorrow, ty::UniqueImmBorrow) => {
494-
struct_span_err!(self.bccx, new_loan.span, E0524,
495+
let mut err = struct_span_err!(self.bccx, new_loan.span, E0524,
495496
"two closures require unique access to `{}` \
496497
at the same time",
497-
nl)
498-
.span_label(
498+
nl);
499+
err.span_label(
499500
old_loan.span,
500-
&format!("first closure is constructed here"))
501-
.span_label(
501+
&format!("first closure is constructed here"));
502+
err.span_label(
502503
new_loan.span,
503-
&format!("second closure is constructed here"))
504-
.span_label(
504+
&format!("second closure is constructed here"));
505+
err.span_label(
505506
previous_end_span,
506-
&format!("borrow from first closure ends here"))
507+
&format!("borrow from first closure ends here"));
508+
err
507509
}
508510

509511
(ty::UniqueImmBorrow, _) => {
510-
struct_span_err!(self.bccx, new_loan.span, E0500,
511-
"closure requires unique access to `{}` \
512-
but {} is already borrowed{}",
513-
nl, ol_pronoun, old_loan_msg)
514-
.span_label(
512+
let mut err = struct_span_err!(self.bccx, new_loan.span, E0500,
513+
"closure requires unique access to `{}` \
514+
but {} is already borrowed{}",
515+
nl, ol_pronoun, old_loan_msg);
516+
err.span_label(
515517
new_loan.span,
516-
&format!("closure construction occurs here{}", new_loan_msg))
517-
.span_label(
518+
&format!("closure construction occurs here{}", new_loan_msg));
519+
err.span_label(
518520
old_loan.span,
519-
&format!("borrow occurs here{}", old_loan_msg))
520-
.span_label(
521+
&format!("borrow occurs here{}", old_loan_msg));
522+
err.span_label(
521523
previous_end_span,
522-
&format!("borrow ends here"))
524+
&format!("borrow ends here"));
525+
err
523526
}
524527

525528
(_, ty::UniqueImmBorrow) => {
526-
struct_span_err!(self.bccx, new_loan.span, E0501,
527-
"cannot borrow `{}`{} as {} because \
528-
previous closure requires unique access",
529-
nl, new_loan_msg, new_loan.kind.to_user_str())
530-
.span_label(
529+
let mut err = struct_span_err!(self.bccx, new_loan.span, E0501,
530+
"cannot borrow `{}`{} as {} because \
531+
previous closure requires unique access",
532+
nl, new_loan_msg, new_loan.kind.to_user_str());
533+
err.span_label(
531534
new_loan.span,
532-
&format!("borrow occurs here{}", new_loan_msg))
533-
.span_label(
535+
&format!("borrow occurs here{}", new_loan_msg));
536+
err.span_label(
534537
old_loan.span,
535-
&format!("closure construction occurs here{}", old_loan_msg))
536-
.span_label(
538+
&format!("closure construction occurs here{}", old_loan_msg));
539+
err.span_label(
537540
previous_end_span,
538-
&format!("borrow from closure ends here"))
541+
&format!("borrow from closure ends here"));
542+
err
539543
}
540544

541545
(_, _) => {
542-
struct_span_err!(self.bccx, new_loan.span, E0502,
543-
"cannot borrow `{}`{} as {} because \
544-
{} is also borrowed as {}{}",
545-
nl,
546-
new_loan_msg,
547-
new_loan.kind.to_user_str(),
548-
ol_pronoun,
549-
old_loan.kind.to_user_str(),
550-
old_loan_msg)
551-
.span_label(
546+
let mut err = struct_span_err!(self.bccx, new_loan.span, E0502,
547+
"cannot borrow `{}`{} as {} because \
548+
{} is also borrowed as {}{}",
549+
nl,
550+
new_loan_msg,
551+
new_loan.kind.to_user_str(),
552+
ol_pronoun,
553+
old_loan.kind.to_user_str(),
554+
old_loan_msg);
555+
err.span_label(
552556
new_loan.span,
553557
&format!("{} borrow occurs here{}",
554558
new_loan.kind.to_user_str(),
555-
new_loan_msg))
556-
.span_label(
559+
new_loan_msg));
560+
err.span_label(
557561
old_loan.span,
558562
&format!("{} borrow occurs here{}",
559563
old_loan.kind.to_user_str(),
560-
old_loan_msg))
561-
.span_label(
564+
old_loan_msg));
565+
err.span_label(
562566
previous_end_span,
563567
&format!("{} borrow ends here",
564-
old_loan.kind.to_user_str()))
568+
old_loan.kind.to_user_str()));
569+
err
565570
}
566571
};
567572

568573
match new_loan.cause {
569574
euv::ClosureCapture(span) => {
570-
err = err.span_label(
575+
err.span_label(
571576
span,
572577
&format!("borrow occurs due to use of `{}` in closure", nl));
573578
}
@@ -576,7 +581,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
576581

577582
match old_loan.cause {
578583
euv::ClosureCapture(span) => {
579-
err = err.span_label(
584+
err.span_label(
580585
span,
581586
&format!("previous borrow occurs due to use of `{}` in closure",
582587
ol));
@@ -663,23 +668,41 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
663668
UseOk => { }
664669
UseWhileBorrowed(loan_path, loan_span) => {
665670
let mut err = match move_kind {
666-
move_data::Captured =>
667-
struct_span_err!(self.bccx, span, E0504,
671+
move_data::Captured => {
672+
let mut err = struct_span_err!(self.bccx, span, E0504,
668673
"cannot move `{}` into closure because it is borrowed",
669-
&self.bccx.loan_path_to_string(move_path)),
674+
&self.bccx.loan_path_to_string(move_path));
675+
err.span_label(
676+
loan_span,
677+
&format!("borrow of `{}` occurs here",
678+
&self.bccx.loan_path_to_string(&loan_path))
679+
);
680+
err.span_label(
681+
span,
682+
&format!("move into closure occurs here")
683+
);
684+
err
685+
}
670686
move_data::Declared |
671687
move_data::MoveExpr |
672-
move_data::MovePat =>
673-
struct_span_err!(self.bccx, span, E0505,
688+
move_data::MovePat => {
689+
let mut err = struct_span_err!(self.bccx, span, E0505,
674690
"cannot move out of `{}` because it is borrowed",
675-
&self.bccx.loan_path_to_string(move_path))
691+
&self.bccx.loan_path_to_string(move_path));
692+
err.span_label(
693+
loan_span,
694+
&format!("borrow of `{}` occurs here",
695+
&self.bccx.loan_path_to_string(&loan_path))
696+
);
697+
err.span_label(
698+
span,
699+
&format!("move out of `{}` occurs here",
700+
&self.bccx.loan_path_to_string(move_path))
701+
);
702+
err
703+
}
676704
};
677705

678-
err.span_note(
679-
loan_span,
680-
&format!("borrow of `{}` occurs here",
681-
&self.bccx.loan_path_to_string(&loan_path))
682-
);
683706
err.emit();
684707
}
685708
}
@@ -845,9 +868,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
845868
struct_span_err!(self.bccx, span, E0506,
846869
"cannot assign to `{}` because it is borrowed",
847870
self.bccx.loan_path_to_string(loan_path))
848-
.span_note(loan.span,
871+
.span_label(loan.span,
849872
&format!("borrow of `{}` occurs here",
850873
self.bccx.loan_path_to_string(loan_path)))
874+
.span_label(span,
875+
&format!("assignment to `{}` occurs here",
876+
self.bccx.loan_path_to_string(loan_path)))
851877
.emit();
852878
}
853879
}

src/librustc_borrowck/borrowck/gather_loans/move_error.rs

+26-15
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
7272
let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
7373
let mut is_first_note = true;
7474
for move_to in &error.move_to_places {
75-
note_move_destination(&mut err, move_to.span,
75+
err = note_move_destination(err, move_to.span,
7676
move_to.name, is_first_note);
7777
is_first_note = false;
7878
}
@@ -121,18 +121,25 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
121121
Categorization::Deref(_, _, mc::Implicit(..)) |
122122
Categorization::Deref(_, _, mc::UnsafePtr(..)) |
123123
Categorization::StaticItem => {
124-
struct_span_err!(bccx, move_from.span, E0507,
124+
let mut err = struct_span_err!(bccx, move_from.span, E0507,
125125
"cannot move out of {}",
126-
move_from.descriptive_string(bccx.tcx))
126+
move_from.descriptive_string(bccx.tcx));
127+
err.span_label(
128+
move_from.span,
129+
&format!("move occurs here")
130+
);
131+
err
127132
}
128133

129134
Categorization::Interior(ref b, mc::InteriorElement(Kind::Index, _)) => {
130135
let expr = bccx.tcx.map.expect_expr(move_from.id);
131136
if let hir::ExprIndex(..) = expr.node {
132-
struct_span_err!(bccx, move_from.span, E0508,
133-
"cannot move out of type `{}`, \
134-
a non-copy fixed-size array",
135-
b.ty)
137+
let mut err = struct_span_err!(bccx, move_from.span, E0508,
138+
"cannot move out of type `{}`, \
139+
a non-copy fixed-size array",
140+
b.ty);
141+
err.span_label(move_from.span, &format!("can not move out of here"));
142+
err
136143
} else {
137144
span_bug!(move_from.span, "this path should not cause illegal move");
138145
}
@@ -143,10 +150,12 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
143150
match b.ty.sty {
144151
ty::TyStruct(def, _) |
145152
ty::TyEnum(def, _) if def.has_dtor() => {
146-
struct_span_err!(bccx, move_from.span, E0509,
147-
"cannot move out of type `{}`, \
148-
which defines the `Drop` trait",
149-
b.ty)
153+
let mut err = struct_span_err!(bccx, move_from.span, E0509,
154+
"cannot move out of type `{}`, \
155+
which defines the `Drop` trait",
156+
b.ty);
157+
err.span_label(move_from.span, &format!("can not move out of here"));
158+
err
150159
},
151160
_ => {
152161
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>,
159168
}
160169
}
161170

162-
fn note_move_destination(err: &mut DiagnosticBuilder,
171+
fn note_move_destination(mut err: DiagnosticBuilder,
163172
move_to_span: codemap::Span,
164173
pat_name: ast::Name,
165-
is_first_note: bool) {
174+
is_first_note: bool) -> DiagnosticBuilder {
166175
if is_first_note {
167-
err.span_note(
176+
err.span_label(
168177
move_to_span,
169-
"attempting to move value to here");
178+
&format!("attempting to move value to here"));
170179
err.help(
171180
&format!("to prevent the move, \
172181
use `ref {0}` or `ref mut {0}` to capture value by \
173182
reference",
174183
pat_name));
184+
err
175185
} else {
176186
err.span_note(move_to_span,
177187
&format!("and here (use `ref {0}` or `ref mut {0}`)",
178188
pat_name));
189+
err
179190
}
180191
}

0 commit comments

Comments
 (0)