about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2018-07-25 01:34:17 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-07-26 13:17:55 +0200
commit91dc3e5b56ec36dcebbb982c4cfebb9541d14684 (patch)
tree5608798470bb9788c1ed41518e7013862f638114 /src
parent346011515760dd552bd41d4abf8a2a55471a9e84 (diff)
downloadrust-91dc3e5b56ec36dcebbb982c4cfebb9541d14684.tar.gz
rust-91dc3e5b56ec36dcebbb982c4cfebb9541d14684.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/borrow_check/mod.rs58
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs9
2 files changed, 53 insertions, 14 deletions
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index ad663000f93..beedcac02f6 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -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;
             }
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index ab1ff1fa347..571a1188d49 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -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);