Add scary warnings to errors-downgraded-to-warnings in borrowck=migrate.

Also convert an ICE that became reachable code under borrowck=migrate
into a normally reported error (which is then downgraded to a
warning). This actually has a nice side benefit of providing a
somewhat more useful error message, at least in the particular case of
the example from issue #27282.
This commit is contained in:
Felix S. Klock II 2018-07-25 01:34:17 +02:00
parent 3460115157
commit 91dc3e5b56
2 changed files with 53 additions and 14 deletions

View File

@ -338,7 +338,13 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
// downgrade all the buffered MIR-borrowck errors
// to warnings.
for err in &mut mbcx.errors_buffer {
if err.is_error() { err.level = Level::Warning; }
if err.is_error() {
err.level = Level::Warning;
err.warn("This error has been downgraded to a warning \
for backwards compatibility with previous releases.\n\
It represents potential unsoundness in your code.\n\
This warning will become a hard error in the future.");
}
}
}
SignalledError::SawSomeError => {
@ -1768,20 +1774,44 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
}
}
Reservation(WriteKind::Move)
| Write(WriteKind::Move)
| Reservation(WriteKind::StorageDeadOrDrop)
| Reservation(WriteKind::MutableBorrow(BorrowKind::Shared))
| Write(WriteKind::StorageDeadOrDrop)
| Write(WriteKind::MutableBorrow(BorrowKind::Shared)) => {
Reservation(wk @ WriteKind::Move)
| Write(wk @ WriteKind::Move)
| Reservation(wk @ WriteKind::StorageDeadOrDrop)
| Reservation(wk @ WriteKind::MutableBorrow(BorrowKind::Shared))
| Write(wk @ WriteKind::StorageDeadOrDrop)
| Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) => {
if let Err(_place_err) = self.is_mutable(place, is_local_mutation_allowed) {
self.tcx.sess.delay_span_bug(
span,
&format!(
"Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
place, kind
),
);
if self.tcx.migrate_borrowck() {
// rust-lang/rust#46908: In pure NLL mode this
// code path should be unreachable (and thus
// we signal an ICE in the else branch
// here). But we can legitimately get here
// under borrowck=migrate mode, so instead of
// ICE'ing we instead report a legitimate
// error (which will then be downgraded to a
// warning by the migrate machinery).
error_access = match wk {
WriteKind::MutableBorrow(_) => AccessKind::MutableBorrow,
WriteKind::Move => AccessKind::Move,
WriteKind::StorageDeadOrDrop |
WriteKind::Mutate => AccessKind::Mutate,
};
self.report_mutability_error(
place,
span,
_place_err,
error_access,
location,
);
} else {
self.tcx.sess.delay_span_bug(
span,
&format!(
"Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
place, kind
),
);
}
}
return false;
}

View File

@ -24,6 +24,7 @@ use util::suggest_ref_mut;
pub(super) enum AccessKind {
MutableBorrow,
Mutate,
Move,
}
impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
@ -110,6 +111,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
if let Some(desc) = access_place_desc {
item_msg = format!("`{}`", desc);
reason = match error_access {
AccessKind::Move |
AccessKind::Mutate => format!(" which is behind a {}", pointer_type),
AccessKind::MutableBorrow => {
format!(", as it is behind a {}", pointer_type)
@ -160,6 +162,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
let span = match error_access {
AccessKind::Move => {
err = self.tcx
.cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir);
act = "move";
acted_on = "moved";
span
}
AccessKind::Mutate => {
err = self.tcx
.cannot_assign(span, &(item_msg + &reason), Origin::Mir);