Skip to content

Commit 8dbbd81

Browse files
committed
Auto merge of #52566 - pnkfelix:buffer-nll-errors-for-z-borrowck-migrate, r=nikomatsakis
Buffer NLL errors Buffer the errors generated during MIR-borrowck (aka NLL). This is the first big step towards resolving issue #46908.
2 parents 6bb50f5 + 1a0294b commit 8dbbd81

File tree

15 files changed

+161
-81
lines changed

15 files changed

+161
-81
lines changed

src/librustc/infer/error_reporting/mod.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,23 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
10861086
bound_kind: GenericKind<'tcx>,
10871087
sub: Region<'tcx>,
10881088
) {
1089+
self.construct_generic_bound_failure(region_scope_tree,
1090+
span,
1091+
origin,
1092+
bound_kind,
1093+
sub)
1094+
.emit()
1095+
}
1096+
1097+
pub fn construct_generic_bound_failure(
1098+
&self,
1099+
region_scope_tree: &region::ScopeTree,
1100+
span: Span,
1101+
origin: Option<SubregionOrigin<'tcx>>,
1102+
bound_kind: GenericKind<'tcx>,
1103+
sub: Region<'tcx>,
1104+
) -> DiagnosticBuilder<'a>
1105+
{
10891106
// Attempt to obtain the span of the parameter so we can
10901107
// suggest adding an explicit lifetime bound to it.
10911108
let type_param_span = match (self.in_progress_tables, bound_kind) {
@@ -1139,14 +1156,13 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
11391156
trait_item_def_id,
11401157
}) = origin
11411158
{
1142-
self.report_extra_impl_obligation(
1159+
return self.report_extra_impl_obligation(
11431160
span,
11441161
item_name,
11451162
impl_item_def_id,
11461163
trait_item_def_id,
11471164
&format!("`{}: {}`", bound_kind, sub),
1148-
).emit();
1149-
return;
1165+
);
11501166
}
11511167

11521168
fn binding_suggestion<'tcx, S: fmt::Display>(
@@ -1229,7 +1245,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12291245
if let Some(origin) = origin {
12301246
self.note_region_origin(&mut err, &origin);
12311247
}
1232-
err.emit();
1248+
err
12331249
}
12341250

12351251
fn report_sub_sup_conflict(

src/librustc/ty/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ impl<'tcx> CommonTypes<'tcx> {
849849
///
850850
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/ty.html
851851
#[derive(Copy, Clone)]
852-
pub struct TyCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
852+
pub struct TyCtxt<'a, 'gcx: 'tcx, 'tcx: 'a> {
853853
gcx: &'a GlobalCtxt<'gcx>,
854854
interners: &'a CtxtInterners<'tcx>
855855
}

src/librustc_errors/diagnostic_builder.rs

+12
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ impl<'a> DiagnosticBuilder<'a> {
8888
self.cancel();
8989
}
9090

91+
/// Buffers the diagnostic for later emission.
92+
pub fn buffer(self, buffered_diagnostics: &mut Vec<Diagnostic>) {
93+
// We need to use `ptr::read` because `DiagnosticBuilder`
94+
// implements `Drop`.
95+
let diagnostic;
96+
unsafe {
97+
diagnostic = ::std::ptr::read(&self.diagnostic);
98+
::std::mem::forget(self);
99+
};
100+
buffered_diagnostics.push(diagnostic);
101+
}
102+
91103
pub fn is_error(&self) -> bool {
92104
match self.level {
93105
Level::Bug |

src/librustc_mir/borrow_check/error_reporting.rs

+14-15
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
5858
Some(name) => format!("`{}`", name),
5959
None => "value".to_owned(),
6060
};
61-
self.tcx
61+
let mut err = self.tcx
6262
.cannot_act_on_uninitialized_variable(
6363
span,
6464
desired_action.as_noun(),
6565
&self
6666
.describe_place_with_options(place, IncludingDowncast(true))
6767
.unwrap_or("_".to_owned()),
6868
Origin::Mir,
69-
)
70-
.span_label(span, format!("use of possibly uninitialized {}", item_msg))
71-
.emit();
69+
);
70+
err.span_label(span, format!("use of possibly uninitialized {}", item_msg));
71+
err.buffer(&mut self.errors_buffer);
7272
} else {
7373
let msg = ""; //FIXME: add "partially " or "collaterally "
7474

@@ -143,7 +143,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
143143
}
144144
}
145145

146-
err.emit();
146+
err.buffer(&mut self.errors_buffer);
147147
}
148148
}
149149

@@ -173,7 +173,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
173173
);
174174
err.span_label(span, format!("move out of {} occurs here", value_msg));
175175
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
176-
err.emit();
176+
err.buffer(&mut self.errors_buffer);
177177
}
178178

179179
pub(super) fn report_use_while_mutably_borrowed(
@@ -194,8 +194,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
194194
);
195195

196196
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
197-
198-
err.emit();
197+
err.buffer(&mut self.errors_buffer);
199198
}
200199

201200
/// Finds the span of arguments of a closure (within `maybe_closure_span`) and its usage of
@@ -391,7 +390,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
391390

392391
self.explain_why_borrow_contains_point(context, issued_borrow, None, &mut err);
393392

394-
err.emit();
393+
err.buffer(&mut self.errors_buffer);
395394
}
396395

397396
pub(super) fn report_borrowed_value_does_not_live_long_enough(
@@ -513,7 +512,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
513512
format!("`{}` dropped here while still borrowed", name),
514513
);
515514
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
516-
err.emit();
515+
err.buffer(&mut self.errors_buffer);
517516
}
518517

519518
fn report_scoped_temporary_value_does_not_live_long_enough(
@@ -535,7 +534,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
535534
);
536535
err.note("consider using a `let` binding to increase its lifetime");
537536
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
538-
err.emit();
537+
err.buffer(&mut self.errors_buffer);
539538
}
540539

541540
fn report_unscoped_local_value_does_not_live_long_enough(
@@ -563,7 +562,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
563562
err.span_label(drop_span, "borrowed value only lives until here");
564563

565564
self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err);
566-
err.emit();
565+
err.buffer(&mut self.errors_buffer);
567566
}
568567

569568
fn report_unscoped_temporary_value_does_not_live_long_enough(
@@ -589,7 +588,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
589588
err.span_label(drop_span, "temporary value only lives until here");
590589

591590
self.explain_why_borrow_contains_point(context, borrow, None, &mut err);
592-
err.emit();
591+
err.buffer(&mut self.errors_buffer);
593592
}
594593

595594
pub(super) fn report_illegal_mutation_of_borrowed(
@@ -608,7 +607,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
608607

609608
self.explain_why_borrow_contains_point(context, loan, None, &mut err);
610609

611-
err.emit();
610+
err.buffer(&mut self.errors_buffer);
612611
}
613612

614613
/// Reports an illegal reassignment; for example, an assignment to
@@ -679,7 +678,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
679678
}
680679
}
681680
err.span_label(span, msg);
682-
err.emit();
681+
err.buffer(&mut self.errors_buffer);
683682
}
684683
}
685684

src/librustc_mir/borrow_check/mod.rs

+23-9
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc::mir::{Terminator, TerminatorKind};
2323
use rustc::ty::query::Providers;
2424
use rustc::ty::{self, ParamEnv, TyCtxt};
2525

26+
use rustc_errors::{Diagnostic, DiagnosticBuilder};
2627
use rustc_data_structures::graph::dominators::Dominators;
2728
use rustc_data_structures::fx::FxHashSet;
2829
use rustc_data_structures::indexed_set::IdxSetBuf;
@@ -148,6 +149,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
148149
let mir = &mir; // no further changes
149150
let location_table = &LocationTable::new(mir);
150151

152+
let mut errors_buffer = Vec::new();
151153
let (move_data, move_errors): (MoveData<'tcx>, Option<Vec<MoveError<'tcx>>>) =
152154
match MoveData::gather_moves(mir, tcx) {
153155
Ok(move_data) => (move_data, None),
@@ -214,6 +216,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
214216
&mut flow_inits,
215217
&mdpe.move_data,
216218
&borrow_set,
219+
&mut errors_buffer,
217220
);
218221
let regioncx = Rc::new(regioncx);
219222

@@ -252,6 +255,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
252255
access_place_error_reported: FxHashSet(),
253256
reservation_error_reported: FxHashSet(),
254257
moved_error_reported: FxHashSet(),
258+
errors_buffer,
255259
nonlexical_regioncx: regioncx,
256260
used_mut: FxHashSet(),
257261
used_mut_upvars: SmallVec::new(),
@@ -287,10 +291,12 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
287291

288292
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
289293

294+
let used_mut = mbcx.used_mut;
295+
290296
for local in mbcx
291297
.mir
292298
.mut_vars_and_args_iter()
293-
.filter(|local| !mbcx.used_mut.contains(local))
299+
.filter(|local| !used_mut.contains(local))
294300
{
295301
if let ClearCrossCrate::Set(ref vsi) = mbcx.mir.source_scope_local_data {
296302
let local_decl = &mbcx.mir.local_decls[local];
@@ -311,16 +317,22 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
311317
let span = local_decl.source_info.span;
312318
let mut_span = tcx.sess.codemap().span_until_non_whitespace(span);
313319

314-
tcx.struct_span_lint_node(
320+
let mut err = tcx.struct_span_lint_node(
315321
UNUSED_MUT,
316322
vsi[local_decl.source_info.scope].lint_root,
317323
span,
318324
"variable does not need to be mutable",
319-
).span_suggestion_short(mut_span, "remove this `mut`", "".to_owned())
320-
.emit();
325+
);
326+
err.span_suggestion_short(mut_span, "remove this `mut`", "".to_owned());
327+
328+
err.buffer(&mut mbcx.errors_buffer);
321329
}
322330
}
323331

332+
for diag in mbcx.errors_buffer.drain(..) {
333+
DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit();
334+
}
335+
324336
let result = BorrowCheckResult {
325337
closure_requirements: opt_closure_req,
326338
used_mut_upvars: mbcx.used_mut_upvars,
@@ -331,7 +343,6 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
331343
result
332344
}
333345

334-
#[allow(dead_code)]
335346
pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
336347
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
337348
mir: &'cx Mir<'tcx>,
@@ -366,8 +377,10 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
366377
/// at the time we detect and report a reservation error.
367378
reservation_error_reported: FxHashSet<Place<'tcx>>,
368379
/// This field keeps track of errors reported in the checking of moved variables,
369-
/// so that we don't report report seemingly duplicate errors.
380+
/// so that we don't report seemingly duplicate errors.
370381
moved_error_reported: FxHashSet<Place<'tcx>>,
382+
/// Errors to be reported buffer
383+
errors_buffer: Vec<Diagnostic>,
371384
/// This field keeps track of all the local variables that are declared mut and are mutated.
372385
/// Used for the warning issued by an unused mutable local variable.
373386
used_mut: FxHashSet<Local>,
@@ -1354,13 +1367,14 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
13541367
debug!("check_for_local_borrow({:?})", borrow);
13551368

13561369
if borrow_of_local_data(&borrow.borrowed_place) {
1357-
self.tcx
1370+
let err = self.tcx
13581371
.cannot_borrow_across_generator_yield(
13591372
self.retrieve_borrow_span(borrow),
13601373
yield_span,
13611374
Origin::Mir,
1362-
)
1363-
.emit();
1375+
);
1376+
1377+
err.buffer(&mut self.errors_buffer);
13641378
}
13651379
}
13661380

src/librustc_mir/borrow_check/move_errors.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ enum GroupedMoveError<'tcx> {
5959
}
6060

6161
impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
62-
pub(crate) fn report_move_errors(&self, move_errors: Vec<MoveError<'tcx>>) {
62+
pub(crate) fn report_move_errors(&mut self, move_errors: Vec<MoveError<'tcx>>) {
6363
let grouped_errors = self.group_move_errors(move_errors);
6464
for error in grouped_errors {
6565
self.report(error);
@@ -218,7 +218,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
218218
};
219219
}
220220

221-
fn report(&self, error: GroupedMoveError<'tcx>) {
221+
fn report(&mut self, error: GroupedMoveError<'tcx>) {
222222
let (mut err, err_span) = {
223223
let (span, kind): (Span, &IllegalMoveOriginKind) = match error {
224224
GroupedMoveError::MovesFromMatchPlace { span, ref kind, .. }
@@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
286286
};
287287

288288
self.add_move_hints(error, &mut err, err_span);
289-
err.emit();
289+
err.buffer(&mut self.errors_buffer);
290290
}
291291

292292
fn add_move_hints(

src/librustc_mir/borrow_check/mutability_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
378378
}
379379
}
380380

381-
err.emit();
381+
err.buffer(&mut self.errors_buffer);
382382
}
383383

384384
// Does this place refer to what the user sees as an upvar

src/librustc_mir/borrow_check/nll/explain_borrow/find_use.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ use rustc::ty::{RegionVid, TyCtxt};
1919
use rustc_data_structures::fx::FxHashSet;
2020
use util::liveness::{self, DefUse, LivenessMode};
2121

22-
crate fn find<'cx, 'gcx: 'tcx, 'tcx: 'cx>(
23-
mir: &'cx Mir<'tcx>,
24-
regioncx: &'cx Rc<RegionInferenceContext<'tcx>>,
25-
tcx: TyCtxt<'cx, 'gcx, 'tcx>,
22+
crate fn find<'tcx>(
23+
mir: &Mir<'tcx>,
24+
regioncx: &Rc<RegionInferenceContext<'tcx>>,
25+
tcx: TyCtxt<'_, '_, 'tcx>,
2626
region_vid: RegionVid,
2727
start_point: Location,
2828
) -> Option<Cause> {

0 commit comments

Comments
 (0)