Skip to content

Commit 4ad272b

Browse files
implement tainted_by_errors in mir borrowck
1 parent 6499c5e commit 4ad272b

File tree

9 files changed

+68
-52
lines changed

9 files changed

+68
-52
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ impl<'tcx> UniverseInfo<'tcx> {
5555
found,
5656
TypeError::RegionsPlaceholderMismatch,
5757
);
58-
err.buffer(&mut mbcx.errors_buffer);
58+
mbcx.buffer_error(err);
5959
}
6060
UniverseInfoInner::TypeOp(ref type_op_info) => {
6161
type_op_info.report_error(mbcx, placeholder, error_element, cause);
@@ -64,11 +64,9 @@ impl<'tcx> UniverseInfo<'tcx> {
6464
// FIXME: This error message isn't great, but it doesn't show
6565
// up in the existing UI tests. Consider investigating this
6666
// some more.
67-
mbcx.infcx
68-
.tcx
69-
.sess
70-
.struct_span_err(cause.span, "higher-ranked subtype error")
71-
.buffer(&mut mbcx.errors_buffer);
67+
mbcx.buffer_error(
68+
mbcx.infcx.tcx.sess.struct_span_err(cause.span, "higher-ranked subtype error"),
69+
);
7270
}
7371
}
7472
}
@@ -149,7 +147,7 @@ trait TypeOpInfo<'tcx> {
149147
{
150148
adjusted
151149
} else {
152-
self.fallback_error(tcx, cause.span).buffer(&mut mbcx.errors_buffer);
150+
mbcx.buffer_error(self.fallback_error(tcx, cause.span));
153151
return;
154152
};
155153

@@ -178,9 +176,9 @@ trait TypeOpInfo<'tcx> {
178176
let nice_error = self.nice_error(tcx, cause, placeholder_region, error_region);
179177

180178
if let Some(nice_error) = nice_error {
181-
nice_error.buffer(&mut mbcx.errors_buffer);
179+
mbcx.buffer_error(nice_error);
182180
} else {
183-
self.fallback_error(tcx, span).buffer(&mut mbcx.errors_buffer);
181+
mbcx.buffer_error(self.fallback_error(tcx, span));
184182
}
185183
}
186184
}

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
7777
if move_out_indices.is_empty() {
7878
let root_place = PlaceRef { projection: &[], ..used_place };
7979

80+
self.set_tainted_by_errors();
8081
if !self.uninitialized_error_reported.insert(root_place) {
8182
debug!(
8283
"report_use_of_moved_or_uninitialized place: error about {:?} suppressed",
@@ -104,7 +105,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
104105
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
105106
);
106107

107-
err.buffer(&mut self.errors_buffer);
108+
self.buffer_error(err);
108109
} else {
109110
if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
110111
if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
@@ -216,6 +217,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
216217
place_name, partially_str, loop_message
217218
),
218219
);
220+
self.set_tainted_by_errors();
219221
if self.fn_self_span_reported.insert(fn_span) {
220222
err.span_note(
221223
// Check whether the source is accessible
@@ -297,6 +299,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
297299
}
298300
// Avoid pointing to the same function in multiple different
299301
// error messages.
302+
self.set_tainted_by_errors();
300303
if span != DUMMY_SP && self.fn_self_span_reported.insert(self_arg.span)
301304
{
302305
err.span_note(
@@ -449,6 +452,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
449452
}
450453
}
451454

455+
self.set_tainted_by_errors();
452456
if let Some((_, mut old_err)) =
453457
self.move_error_reported.insert(move_out_indices, (used_place, err))
454458
{
@@ -503,7 +507,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
503507
Some(borrow_span),
504508
None,
505509
);
506-
err.buffer(&mut self.errors_buffer);
510+
self.buffer_error(err);
507511
}
508512

509513
pub(crate) fn report_use_while_mutably_borrowed(
@@ -1012,6 +1016,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10121016
return;
10131017
}
10141018

1019+
self.set_tainted_by_errors();
10151020
self.access_place_error_reported.insert((
10161021
Place { local: root_place.local, projection: root_place_projection },
10171022
borrow_span,
@@ -1021,7 +1026,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10211026
if self.body.local_decls[borrowed_local].is_ref_to_thread_local() {
10221027
let err =
10231028
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
1024-
err.buffer(&mut self.errors_buffer);
1029+
self.buffer_error(err);
10251030
return;
10261031
}
10271032

@@ -1113,7 +1118,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11131118
),
11141119
};
11151120

1116-
err.buffer(&mut self.errors_buffer);
1121+
self.buffer_error(err);
11171122
}
11181123

11191124
fn report_local_value_does_not_live_long_enough(
@@ -1295,7 +1300,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12951300
None,
12961301
);
12971302

1298-
err.buffer(&mut self.errors_buffer);
1303+
self.buffer_error(err);
12991304
}
13001305

13011306
fn report_thread_local_value_does_not_live_long_enough(
@@ -1810,7 +1815,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
18101815
loan.kind.describe_mutability(),
18111816
);
18121817

1813-
err.buffer(&mut self.errors_buffer);
1818+
self.buffer_error(err);
18141819

18151820
return;
18161821
}
@@ -1836,7 +1841,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
18361841

18371842
self.explain_deref_coercion(loan, &mut err);
18381843

1839-
err.buffer(&mut self.errors_buffer);
1844+
self.buffer_error(err);
18401845
}
18411846

18421847
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut DiagnosticBuilder<'_>) {
@@ -1938,7 +1943,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
19381943
}
19391944
}
19401945
err.span_label(span, msg);
1941-
err.buffer(&mut self.errors_buffer);
1946+
self.buffer_error(err);
19421947
}
19431948

19441949
fn classify_drop_access_kind(&self, place: PlaceRef<'tcx>) -> StorageDeadOrDrop<'tcx> {

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
264264
};
265265

266266
self.add_move_hints(error, &mut err, err_span);
267-
err.buffer(&mut self.errors_buffer);
267+
self.buffer_error(err);
268268
}
269269

270270
fn report_cannot_move_from_static(

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
626626
}
627627
}
628628

629-
err.buffer(&mut self.errors_buffer);
629+
self.buffer_error(err);
630630
}
631631

632632
/// User cannot make signature of a trait mutable without changing the

compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,6 @@ impl OutlivesSuggestionBuilder {
256256
diag.sort_span = mir_span.shrink_to_hi();
257257

258258
// Buffer the diagnostic
259-
diag.buffer(&mut mbcx.errors_buffer);
259+
mbcx.buffer_error(diag);
260260
}
261261
}

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
168168
let type_test_span = type_test.locations.span(&self.body);
169169

170170
if let Some(lower_bound_region) = lower_bound_region {
171-
self.infcx
172-
.construct_generic_bound_failure(
173-
type_test_span,
174-
None,
175-
type_test.generic_kind,
176-
lower_bound_region,
177-
)
178-
.buffer(&mut self.errors_buffer);
171+
self.buffer_error(self.infcx.construct_generic_bound_failure(
172+
type_test_span,
173+
None,
174+
type_test.generic_kind,
175+
lower_bound_region,
176+
));
179177
} else {
180178
// FIXME. We should handle this case better. It
181179
// indicates that we have e.g., some region variable
@@ -186,27 +184,22 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
186184
// to report it; we could probably handle it by
187185
// iterating over the universal regions and reporting
188186
// an error that multiple bounds are required.
189-
self.infcx
190-
.tcx
191-
.sess
192-
.struct_span_err(
193-
type_test_span,
194-
&format!("`{}` does not live long enough", type_test.generic_kind),
195-
)
196-
.buffer(&mut self.errors_buffer);
187+
self.buffer_error(self.infcx.tcx.sess.struct_span_err(
188+
type_test_span,
189+
&format!("`{}` does not live long enough", type_test.generic_kind),
190+
));
197191
}
198192
}
199193

200194
RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
201195
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
202196
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
203-
unexpected_hidden_region_diagnostic(
197+
self.buffer_error(unexpected_hidden_region_diagnostic(
204198
self.infcx.tcx,
205199
span,
206200
named_ty,
207201
named_region,
208-
)
209-
.buffer(&mut self.errors_buffer);
202+
));
210203
}
211204

212205
RegionErrorKind::BoundUniversalRegionError {
@@ -285,7 +278,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
285278
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
286279
let nice = NiceRegionError::new_from_span(self.infcx, cause.span, o, f);
287280
if let Some(diag) = nice.try_report_from_nll() {
288-
diag.buffer(&mut self.errors_buffer);
281+
self.buffer_error(diag);
289282
return;
290283
}
291284
}
@@ -375,7 +368,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
375368
}
376369
}
377370

378-
diag.buffer(&mut self.errors_buffer);
371+
self.buffer_error(diag);
379372
}
380373

381374
/// Report a specialized error when `FnMut` closures return a reference to a captured variable.

compiler/rustc_borrowck/src/lib.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ fn do_mir_borrowck<'a, 'tcx>(
313313
move_error_reported: BTreeMap::new(),
314314
uninitialized_error_reported: Default::default(),
315315
errors_buffer,
316+
tainted_by_errors: false,
316317
regioncx: regioncx.clone(),
317318
used_mut: Default::default(),
318319
used_mut_upvars: SmallVec::new(),
@@ -346,6 +347,7 @@ fn do_mir_borrowck<'a, 'tcx>(
346347
move_error_reported: BTreeMap::new(),
347348
uninitialized_error_reported: Default::default(),
348349
errors_buffer,
350+
tainted_by_errors: false,
349351
regioncx: Rc::clone(&regioncx),
350352
used_mut: Default::default(),
351353
used_mut_upvars: SmallVec::new(),
@@ -398,7 +400,7 @@ fn do_mir_borrowck<'a, 'tcx>(
398400
diag.message = initial_diag.styled_message().clone();
399401
diag.span = initial_diag.span.clone();
400402

401-
diag.buffer(&mut mbcx.errors_buffer);
403+
mbcx.buffer_error(diag);
402404
},
403405
);
404406
initial_diag.cancel();
@@ -423,7 +425,7 @@ fn do_mir_borrowck<'a, 'tcx>(
423425
mbcx.gather_used_muts(temporary_used_locals, unused_mut_locals);
424426

425427
debug!("mbcx.used_mut: {:?}", mbcx.used_mut);
426-
let used_mut = mbcx.used_mut;
428+
let used_mut = std::mem::take(&mut mbcx.used_mut);
427429
for local in mbcx.body.mut_vars_and_args_iter().filter(|local| !used_mut.contains(local)) {
428430
let local_decl = &mbcx.body.local_decls[local];
429431
let lint_root = match &mbcx.body.source_scopes[local_decl.source_info.scope].local_data {
@@ -461,8 +463,8 @@ fn do_mir_borrowck<'a, 'tcx>(
461463
}
462464

463465
// Buffer any move errors that we collected and de-duplicated.
464-
for (_, (_, diag)) in mbcx.move_error_reported {
465-
diag.buffer(&mut mbcx.errors_buffer);
466+
for (_, (_, diag)) in std::mem::take(&mut mbcx.move_error_reported) {
467+
mbcx.buffer_error(diag);
466468
}
467469

468470
if !mbcx.errors_buffer.is_empty() {
@@ -477,6 +479,7 @@ fn do_mir_borrowck<'a, 'tcx>(
477479
concrete_opaque_types: opaque_type_values,
478480
closure_requirements: opt_closure_req,
479481
used_mut_upvars: mbcx.used_mut_upvars,
482+
tainted_by_errors: mbcx.tainted_by_errors,
480483
};
481484

482485
let body_with_facts = if return_body_with_facts {
@@ -573,6 +576,8 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
573576
uninitialized_error_reported: FxHashSet<PlaceRef<'tcx>>,
574577
/// Errors to be reported buffer
575578
errors_buffer: Vec<Diagnostic>,
579+
/// Set to true if we emit an error during borrowck
580+
tainted_by_errors: bool,
576581
/// This field keeps track of all the local variables that are declared mut and are mutated.
577582
/// Used for the warning issued by an unused mutable local variable.
578583
used_mut: FxHashSet<Local>,
@@ -1028,6 +1033,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10281033
if conflict_error || mutability_error {
10291034
debug!("access_place: logging error place_span=`{:?}` kind=`{:?}`", place_span, kind);
10301035

1036+
self.set_tainted_by_errors();
10311037
self.access_place_error_reported.insert((place_span.0, place_span.1));
10321038
}
10331039
}
@@ -1107,12 +1113,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11071113
error_reported = true;
11081114
match kind {
11091115
ReadKind::Copy => {
1110-
this.report_use_while_mutably_borrowed(location, place_span, borrow)
1111-
.buffer(&mut this.errors_buffer);
1116+
let err = this
1117+
.report_use_while_mutably_borrowed(location, place_span, borrow);
1118+
this.buffer_error(err);
11121119
}
11131120
ReadKind::Borrow(bk) => {
1114-
this.report_conflicting_borrow(location, place_span, bk, borrow)
1115-
.buffer(&mut this.errors_buffer);
1121+
let err =
1122+
this.report_conflicting_borrow(location, place_span, bk, borrow);
1123+
this.buffer_error(err);
11161124
}
11171125
}
11181126
Control::Break
@@ -1162,8 +1170,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
11621170
error_reported = true;
11631171
match kind {
11641172
WriteKind::MutableBorrow(bk) => {
1165-
this.report_conflicting_borrow(location, place_span, bk, borrow)
1166-
.buffer(&mut this.errors_buffer);
1173+
let err =
1174+
this.report_conflicting_borrow(location, place_span, bk, borrow);
1175+
this.buffer_error(err);
11671176
}
11681177
WriteKind::StorageDeadOrDrop => this
11691178
.report_borrowed_value_does_not_live_long_enough(
@@ -1570,7 +1579,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
15701579
yield_span,
15711580
);
15721581

1573-
err.buffer(&mut self.errors_buffer);
1582+
self.buffer_error(err);
15741583
}
15751584
}
15761585

@@ -2299,6 +2308,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
22992308
fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option<Field> {
23002309
path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body())
23012310
}
2311+
2312+
pub fn buffer_error(&mut self, t: DiagnosticBuilder<'_>) {
2313+
self.tainted_by_errors = true;
2314+
t.buffer(&mut self.errors_buffer);
2315+
}
2316+
2317+
pub fn set_tainted_by_errors(&mut self) {
2318+
self.tainted_by_errors = true;
2319+
}
23022320
}
23032321

23042322
/// The degree of overlap between 2 places for borrow-checking.

compiler/rustc_borrowck/src/nll.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ pub(super) fn dump_annotation<'a, 'tcx>(
418418
err.note(&format!("Inferred opaque type values:\n{:#?}", opaque_type_values));
419419
}
420420

421+
// FIXME(compiler-errors): Maybe we need to set tainted here
421422
err.buffer(errors_buffer);
422423
}
423424

compiler/rustc_middle/src/mir/query.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ pub struct BorrowCheckResult<'tcx> {
214214
pub concrete_opaque_types: VecMap<OpaqueTypeKey<'tcx>, Ty<'tcx>>,
215215
pub closure_requirements: Option<ClosureRegionRequirements<'tcx>>,
216216
pub used_mut_upvars: SmallVec<[Field; 8]>,
217+
pub tainted_by_errors: bool,
217218
}
218219

219220
/// The result of the `mir_const_qualif` query.

0 commit comments

Comments
 (0)