Skip to content

Commit

Permalink
Auto merge of rust-lang#93691 - compiler-errors:mir-tainted-by-errors…
Browse files Browse the repository at this point in the history
…, r=oli-obk

Implement `tainted_by_errors` in MIR borrowck, use it to skip CTFE

Putting this up for initial review. The issue that I found is when we're evaluating a const, we're doing borrowck, but doing nothing with the fact that borrowck fails.

This implements a `tainted_by_errors` field for MIR borrowck like we have in infcx, so we can use that information to return an `Err` during const eval if our const fails to borrowck.

This PR needs some cleaning up. I should probably just use `Result` in more places, instead of `.expect`ing in the places I am, but I just wanted it to compile so I could see if it worked!

Fixes rust-lang#93646

r? `@oli-obk`
feel free to reassign
  • Loading branch information
bors committed Feb 12, 2022
2 parents fc32303 + 67ad0ff commit 9cdefd7
Show file tree
Hide file tree
Showing 32 changed files with 255 additions and 213 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/borrowck_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
verb: &str,
optional_adverb_for_moved: &str,
moved_path: Option<String>,
) -> DiagnosticBuilder<'cx> {
) -> DiagnosticBuilder<'tcx> {
let moved_path = moved_path.map(|mp| format!(": `{}`", mp)).unwrap_or_default();

struct_span_err!(
Expand Down
16 changes: 7 additions & 9 deletions compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl<'tcx> UniverseInfo<'tcx> {
found,
TypeError::RegionsPlaceholderMismatch,
);
err.buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(err);
}
UniverseInfoInner::TypeOp(ref type_op_info) => {
type_op_info.report_error(mbcx, placeholder, error_element, cause);
Expand All @@ -64,11 +64,9 @@ impl<'tcx> UniverseInfo<'tcx> {
// FIXME: This error message isn't great, but it doesn't show
// up in the existing UI tests. Consider investigating this
// some more.
mbcx.infcx
.tcx
.sess
.struct_span_err(cause.span, "higher-ranked subtype error")
.buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(
mbcx.infcx.tcx.sess.struct_span_err(cause.span, "higher-ranked subtype error"),
);
}
}
}
Expand Down Expand Up @@ -149,7 +147,7 @@ trait TypeOpInfo<'tcx> {
{
adjusted
} else {
self.fallback_error(tcx, cause.span).buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(self.fallback_error(tcx, cause.span));
return;
};

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

if let Some(nice_error) = nice_error {
nice_error.buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(nice_error);
} else {
self.fallback_error(tcx, span).buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(self.fallback_error(tcx, span));
}
}
}
Expand Down
25 changes: 10 additions & 15 deletions compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()),
);

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
} else {
if let Some((reported_place, _)) = self.move_error_reported.get(&move_out_indices) {
if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) {
if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) {
debug!(
"report_use_of_moved_or_uninitialized place: error suppressed \
Expand Down Expand Up @@ -449,12 +449,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}

if let Some((_, mut old_err)) =
self.move_error_reported.insert(move_out_indices, (used_place, err))
{
// Cancel the old error so it doesn't ICE.
old_err.cancel();
}
self.buffer_move_error(move_out_indices, (used_place, err));
}
}

Expand Down Expand Up @@ -503,7 +498,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
Some(borrow_span),
None,
);
err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

pub(crate) fn report_use_while_mutably_borrowed(
Expand Down Expand Up @@ -1021,7 +1016,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
if self.body.local_decls[borrowed_local].is_ref_to_thread_local() {
let err =
self.report_thread_local_value_does_not_live_long_enough(drop_span, borrow_span);
err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
return;
}

Expand Down Expand Up @@ -1113,7 +1108,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
),
};

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

fn report_local_value_does_not_live_long_enough(
Expand Down Expand Up @@ -1295,7 +1290,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
None,
);

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

fn report_thread_local_value_does_not_live_long_enough(
Expand Down Expand Up @@ -1810,7 +1805,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
loan.kind.describe_mutability(),
);

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);

return;
}
Expand All @@ -1836,7 +1831,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {

self.explain_deref_coercion(loan, &mut err);

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut DiagnosticBuilder<'_>) {
Expand Down Expand Up @@ -1938,7 +1933,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}
}
err.span_label(span, msg);
err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

fn classify_drop_access_kind(&self, place: PlaceRef<'tcx>) -> StorageDeadOrDrop<'tcx> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/diagnostics/move_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
};

self.add_move_hints(error, &mut err, err_span);
err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

fn report_cannot_move_from_static(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}

err.buffer(&mut self.errors_buffer);
self.buffer_error(err);
}

/// User cannot make signature of a trait mutable without changing the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,6 @@ impl OutlivesSuggestionBuilder {
diag.sort_span = mir_span.shrink_to_hi();

// Buffer the diagnostic
diag.buffer(&mut mbcx.errors_buffer);
mbcx.buffer_error(diag);
}
}
35 changes: 14 additions & 21 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,14 +168,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let type_test_span = type_test.locations.span(&self.body);

if let Some(lower_bound_region) = lower_bound_region {
self.infcx
.construct_generic_bound_failure(
type_test_span,
None,
type_test.generic_kind,
lower_bound_region,
)
.buffer(&mut self.errors_buffer);
self.buffer_error(self.infcx.construct_generic_bound_failure(
type_test_span,
None,
type_test.generic_kind,
lower_bound_region,
));
} else {
// FIXME. We should handle this case better. It
// indicates that we have e.g., some region variable
Expand All @@ -186,27 +184,22 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// to report it; we could probably handle it by
// iterating over the universal regions and reporting
// an error that multiple bounds are required.
self.infcx
.tcx
.sess
.struct_span_err(
type_test_span,
&format!("`{}` does not live long enough", type_test.generic_kind),
)
.buffer(&mut self.errors_buffer);
self.buffer_error(self.infcx.tcx.sess.struct_span_err(
type_test_span,
&format!("`{}` does not live long enough", type_test.generic_kind),
));
}
}

RegionErrorKind::UnexpectedHiddenRegion { span, hidden_ty, member_region } => {
let named_ty = self.regioncx.name_regions(self.infcx.tcx, hidden_ty);
let named_region = self.regioncx.name_regions(self.infcx.tcx, member_region);
unexpected_hidden_region_diagnostic(
self.buffer_error(unexpected_hidden_region_diagnostic(
self.infcx.tcx,
span,
named_ty,
named_region,
)
.buffer(&mut self.errors_buffer);
));
}

RegionErrorKind::BoundUniversalRegionError {
Expand Down Expand Up @@ -285,7 +278,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) {
let nice = NiceRegionError::new_from_span(self.infcx, cause.span, o, f);
if let Some(diag) = nice.try_report_from_nll() {
diag.buffer(&mut self.errors_buffer);
self.buffer_error(diag);
return;
}
}
Expand Down Expand Up @@ -375,7 +368,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
}
}

diag.buffer(&mut self.errors_buffer);
self.buffer_error(diag);
}

/// Report a specialized error when `FnMut` closures return a reference to a captured variable.
Expand Down
Loading

0 comments on commit 9cdefd7

Please sign in to comment.