]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #55517 - nikomatsakis:universes, r=scalexm
authorbors <bors@rust-lang.org>
Thu, 3 Jan 2019 17:18:15 +0000 (17:18 +0000)
committerbors <bors@rust-lang.org>
Thu, 3 Jan 2019 17:18:15 +0000 (17:18 +0000)
Universes

This PR transitions the compiler to use **universes** instead of the **leak-check**. It is marked as [WIP] for a few reasons:

- The diagnostics at present are terrible =)
- This changes the behavior of coherence, regressing some things that used to compile

The goals of this PR at present are:

- To start getting some eyes on the code
- To do a crater run
- To see the full travis results (due to https://github.com/rust-lang/rust/issues/52452, I am not able to run the full test suite locally anymore at present)

The first few commits in the PR are changing how `evaluate` treats regions. We now track whether region comparisons occurred, reverting the "staticized" query approach that @arielb1 put in. The problem with "staticized" queries is that it relied on the leak-check to get higher-ranked things correct, and we are removing the leak-check in this PR series, so that caused problems.

You can see at the end a collection of test updates. Mostly we behave the same but with atrocious diagnostics, but there are a number of cases where we used to error and now no longer do, as well as single case where we used to **not** error but we now do (the coherence-subtyping change).

(Note: it would be possible to do a version of leak-check that propagates universe information and recover the old behavior. I am reluctant to do so because I'd like to leave us room to get more precise -- e.g., I want to eventually handle things like `exists<'a> { for<'b> { if ('a: 'b) { 'a: 'b } } }` which presently the leak-check cannot cope with etc. Also because it seems more consistent to me: most folks I've talked to expect the new behavior and are surprised to learn that binding sites were so significant before when it comes to coherence. One question is, though, to what extent are people relying on this in the wild?)

Cargo.lock
src/librustc/Cargo.toml
src/librustc_mir/Cargo.toml
src/librustc_mir/borrow_check/nll/invalidation.rs
src/librustc_mir/borrow_check/nll/type_check/mod.rs
src/librustc_mir/interpret/machine.rs
src/test/ui/nll/issue-57265-return-type-wf-check.rs [new file with mode: 0644]
src/test/ui/nll/issue-57265-return-type-wf-check.stderr [new file with mode: 0644]

index 328c145edc4ddba35fa11980f8e83e9f6e889d60..041a24aae6c530d438f093d85bc98d531097b5b7 100644 (file)
@@ -617,7 +617,7 @@ dependencies = [
 
 [[package]]
 name = "datafrog"
-version = "0.1.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1622,10 +1622,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "polonius-engine"
-version = "0.5.0"
+version = "0.6.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "datafrog 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2071,7 +2071,7 @@ dependencies = [
  "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_apfloat 0.0.0",
@@ -2523,7 +2523,7 @@ dependencies = [
  "graphviz 0.0.0",
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log_settings 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc_apfloat 0.0.0",
  "rustc_data_structures 0.0.0",
@@ -3428,7 +3428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
 "checksum curl 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "c7c9d851c825e0c033979d4516c9173bc19a78a96eb4d6ae51d4045440eafa16"
 "checksum curl-sys 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "721c204978be2143fab0a84b708c49d79d1f6100b8785610f456043a90708870"
-"checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
+"checksum datafrog 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
 "checksum derive-new 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ca414e896ae072546f4d789f452daaecf60ddee4c9df5dc6d5936d769e3d87c"
 "checksum derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f57d78cf3bd45270dad4e70c21ec77a960b36c7a841ff9db76aaa775a8fb871"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
@@ -3537,7 +3537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum phf_generator 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "05a079dd052e7b674d21cb31cbb6c05efd56a2cd2827db7692e2f1a507ebd998"
 "checksum phf_shared 0.7.22 (registry+https://github.com/rust-lang/crates.io-index)" = "c2261d544c2bb6aa3b10022b0be371b9c7c64f762ef28c6f5d4f1ef6d97b5930"
 "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
-"checksum polonius-engine 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a5b6b0a7f5f4278b991ffd14abce1d01b013121ad297460237ef0a2f08d43201"
+"checksum polonius-engine 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2490c396085801abf88df91758bad806b0890354f0875d624e62ecf0579a8145"
 "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
 "checksum pretty_assertions 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a029430f0d744bc3d15dd474d591bed2402b645d024583082b9f63bb936dac6"
 "checksum pretty_env_logger 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df8b3f4e0475def7d9c2e5de8e5a1306949849761e107b360d03e98eafaffd61"
index 8604efbc5742dd4ae0d0898b4976079d0d9169bc..504e016e5b803b3ac2df4b14db00e04cc5c25157 100644 (file)
@@ -17,7 +17,7 @@ jobserver = "0.1"
 lazy_static = "1.0.0"
 scoped-tls = { version = "0.1.1", features = ["nightly"] }
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
-polonius-engine = "0.5.0"
+polonius-engine = "0.6.2"
 rustc-rayon = "0.1.1"
 rustc-rayon-core = "0.1.1"
 rustc_apfloat = { path = "../librustc_apfloat" }
index 5044e351962ed0227d8a4fe36014218014a53875..f0234c48c3eca97e0b9644a8b925e27b67fcf154 100644 (file)
@@ -15,7 +15,7 @@ either = "1.5.0"
 graphviz = { path = "../libgraphviz" }
 log = "0.4"
 log_settings = "0.1.1"
-polonius-engine = "0.5.0"
+polonius-engine = "0.6.2"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
index 76b516246f92aff05054298ba9a1e0f91db4d459..112b39952559b124770c456be2db7e84d9c1653d 100644 (file)
@@ -56,10 +56,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
 /// Visits the whole MIR and generates invalidates() facts
 /// Most of the code implementing this was stolen from borrow_check/mod.rs
 impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
-    fn visit_statement(&mut self,
-                       block: BasicBlock,
-                       statement: &Statement<'tcx>,
-                       location: Location) {
+    fn visit_statement(
+        &mut self,
+        block: BasicBlock,
+        statement: &Statement<'tcx>,
+        location: Location,
+    ) {
+        self.check_activations(location);
+
         match statement.kind {
             StatementKind::Assign(ref lhs, ref rhs) => {
                 self.consume_rvalue(
@@ -148,6 +152,8 @@ fn visit_terminator(
         terminator: &Terminator<'tcx>,
         location: Location
     ) {
+        self.check_activations(location);
+
         match terminator.kind {
             TerminatorKind::SwitchInt {
                 ref discr,
@@ -471,5 +477,41 @@ fn generate_invalidates(&mut self, b: BorrowIndex, l: Location) {
         let lidx = self.location_table.start_index(l);
         self.all_facts.invalidates.push((lidx, b));
     }
+
+    fn check_activations(
+        &mut self,
+        location: Location,
+    ) {
+        if !self.tcx.two_phase_borrows() {
+            return;
+        }
+
+        // Two-phase borrow support: For each activation that is newly
+        // generated at this statement, check if it interferes with
+        // another borrow.
+        for &borrow_index in self.borrow_set.activations_at_location(location) {
+            let borrow = &self.borrow_set[borrow_index];
+
+            // only mutable borrows should be 2-phase
+            assert!(match borrow.kind {
+                BorrowKind::Shared | BorrowKind::Shallow => false,
+                BorrowKind::Unique | BorrowKind::Mut { .. } => true,
+            });
+
+            self.access_place(
+                ContextKind::Activation.new(location),
+                &borrow.borrowed_place,
+                (
+                    Deep,
+                    Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
+                ),
+                LocalMutationIsAllowed::No,
+            );
+
+            // We do not need to call `check_if_path_or_subpath_is_moved`
+            // again, as we already called it when we made the
+            // initial reservation.
+        }
+    }
 }
 
index 59e9fa23ece46ebb5562279186d4cf2188c2e72b..b3e1237a4508778d3b4e917a7f7cb1dfa1979da4 100644 (file)
@@ -1456,7 +1456,7 @@ fn check_terminator(
                 self.check_call_dest(mir, term, &sig, destination, term_location);
 
                 self.prove_predicates(
-                    sig.inputs().iter().map(|ty| ty::Predicate::WellFormed(ty)),
+                    sig.inputs_and_output.iter().map(|ty| ty::Predicate::WellFormed(ty)),
                     term_location.to_locations(),
                     ConstraintCategory::Boring,
                 );
index 1242c41a3562b04764a4c1eb6dc12af35257ab66..26d526a6f5ff805775b83e997dc05d7c039782c3 100644 (file)
@@ -76,7 +76,7 @@ pub trait Machine<'a, 'mir, 'tcx>: Sized {
     type MemoryExtra: Default;
 
     /// Extra data stored in every allocation.
-    type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra>;
+    type AllocExtra: AllocationExtra<Self::PointerTag, Self::MemoryExtra> + 'static;
 
     /// Memory's allocation map
     type MemoryMap:
diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.rs b/src/test/ui/nll/issue-57265-return-type-wf-check.rs
new file mode 100644 (file)
index 0000000..24c61a4
--- /dev/null
@@ -0,0 +1,26 @@
+#![feature(nll)]
+
+use std::any::Any;
+
+#[derive(Debug, Clone)]
+struct S<T: 'static>(T);
+
+// S<&'a T> is in the return type, so we get an implied bound
+// &'a T: 'static
+fn foo<'a, T>(x: &'a T) -> (S<&'a T>, Box<dyn Any + 'static>) {
+    let y = S(x);
+
+    let z = Box::new(y.clone()) as Box<dyn Any + 'static>;
+    (y, z)
+}
+
+fn main() {
+    let x = 5;
+
+    // Check that we require that the argument is of type `&'static String`,
+    // so that the return type is well-formed.
+    let (_, z) = foo(&"hello".to_string());
+    //~^ ERROR temporary value dropped while borrowed
+
+    println!("{:?}", z.downcast_ref::<S<&'static String>>());
+}
diff --git a/src/test/ui/nll/issue-57265-return-type-wf-check.stderr b/src/test/ui/nll/issue-57265-return-type-wf-check.stderr
new file mode 100644 (file)
index 0000000..db01212
--- /dev/null
@@ -0,0 +1,12 @@
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/issue-57265-return-type-wf-check.rs:22:23
+   |
+LL |     let (_, z) = foo(&"hello".to_string());
+   |                  -----^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
+   |                  |    |
+   |                  |    creates a temporary which is freed while still in use
+   |                  argument requires that borrow lasts for `'static`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.