about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/test/ui/borrowck/two-phase-surprise-no-conflict.ast.stderr133
-rw-r--r--src/test/ui/borrowck/two-phase-surprise-no-conflict.nll.stderr165
-rw-r--r--src/test/ui/borrowck/two-phase-surprise-no-conflict.no2pb.stderr175
-rw-r--r--src/test/ui/borrowck/two-phase-surprise-no-conflict.rs219
4 files changed, 692 insertions, 0 deletions
diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.ast.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.ast.stderr
new file mode 100644
index 00000000000..6e7f35d1fda
--- /dev/null
+++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.ast.stderr
@@ -0,0 +1,133 @@
+error[E0503]: cannot use `self.cx` because it was mutably borrowed
+  --> $DIR/two-phase-surprise-no-conflict.rs:40:13
+   |
+LL |         let _mut_borrow = &mut *self;
+   |                                ----- borrow of `*self` occurs here
+LL |         let _access = self.cx;
+   |             ^^^^^^^ use of borrowed `*self`
+
+error[E0502]: cannot borrow `*self.cx_mut` as immutable because `*self` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:79:33
+   |
+LL |                 self.hash_expr(&self.cx_mut.body(eid).value);
+   |                 ----            ^^^^^^^^^^^                - mutable borrow ends here
+   |                 |               |
+   |                 |               immutable borrow occurs here
+   |                 mutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:131:52
+   |
+LL |     reg.register_static(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     ---                                            ^^^^^^^^^^^^  - mutable borrow ends here
+   |     |                                              |
+   |     mutable borrow occurs here                     immutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:135:51
+   |
+LL |     reg.register_bound(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     ---                                           ^^^^^^^^^^^^  - mutable borrow ends here
+   |     |                                             |
+   |     mutable borrow occurs here                    immutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:139:50
+   |
+LL |     reg.register_univ(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     ---                                          ^^^^^^^^^^^^  - mutable borrow ends here
+   |     |                                            |
+   |     mutable borrow occurs here                   immutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:143:41
+   |
+LL |     reg.register_ref(&TrivialPass::new(&reg.sess_mut));
+   |     ---                                 ^^^^^^^^^^^^ - mutable borrow ends here
+   |     |                                   |
+   |     mutable borrow occurs here          immutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:151:56
+   |
+LL |     reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut)));
+   |     ---                                                ^^^^^^^^^^^^  - first borrow ends here
+   |     |                                                  |
+   |     first mutable borrow occurs here                   second mutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:156:59
+   |
+LL |     reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     ---                                                   ^^^^^^^^^^^^  - first borrow ends here
+   |     |                                                     |
+   |     first mutable borrow occurs here                      second mutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:161:58
+   |
+LL |     reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     ---                                                  ^^^^^^^^^^^^  - first borrow ends here
+   |     |                                                    |
+   |     first mutable borrow occurs here                     second mutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:166:49
+   |
+LL |     reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut));
+   |     ---                                         ^^^^^^^^^^^^ - first borrow ends here
+   |     |                                           |
+   |     first mutable borrow occurs here            second mutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:178:51
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     ---                                           ^^^^^^^^^^^^  - mutable borrow ends here
+   |     |                                             |
+   |     mutable borrow occurs here                    immutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:183:50
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     ---                                          ^^^^^^^^^^^^  - mutable borrow ends here
+   |     |                                            |
+   |     mutable borrow occurs here                   immutable borrow occurs here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because `*reg` is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:188:41
+   |
+LL |     reg.register_ref(&CapturePass::new(&reg.sess_mut));
+   |     ---                                 ^^^^^^^^^^^^ - mutable borrow ends here
+   |     |                                   |
+   |     mutable borrow occurs here          immutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:200:59
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ---                                                   ^^^^^^^^^^^^  - first borrow ends here
+   |     |                                                     |
+   |     first mutable borrow occurs here                      second mutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:206:58
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ---                                                  ^^^^^^^^^^^^  - first borrow ends here
+   |     |                                                    |
+   |     first mutable borrow occurs here                     second mutable borrow occurs here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:212:49
+   |
+LL |     reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
+   |     ---                                         ^^^^^^^^^^^^ - first borrow ends here
+   |     |                                           |
+   |     first mutable borrow occurs here            second mutable borrow occurs here
+
+error: aborting due to 16 previous errors
+
+Some errors occurred: E0499, E0502, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.nll.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.nll.stderr
new file mode 100644
index 00000000000..1fcd9021341
--- /dev/null
+++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.nll.stderr
@@ -0,0 +1,165 @@
+error[E0503]: cannot use `self.cx` because it was mutably borrowed
+  --> $DIR/two-phase-surprise-no-conflict.rs:40:23
+   |
+LL |         let _mut_borrow = &mut *self;
+   |                           ---------- borrow of `*self` occurs here
+LL |         let _access = self.cx;
+   |                       ^^^^^^^ use of borrowed `*self`
+...
+LL |         _mut_borrow;
+   |         ----------- borrow later used here
+
+error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:79:17
+   |
+LL |                 self.hash_expr(&self.cx_mut.body(eid).value);
+   |                 ^^^^^^^^^^^^^^^^-----------^^^^^^^^^^^^^^^^^
+   |                 |               |
+   |                 |               immutable borrow occurs here
+   |                 mutable borrow occurs here
+   |                 borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:151:51
+   |
+LL |     reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut)));
+   |     ----------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                             |
+   |     |                                             second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:156:54
+   |
+LL |     reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     -------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                                |
+   |     |                                                second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:161:53
+   |
+LL |     reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     ------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                               |
+   |     |                                               second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:166:44
+   |
+LL |     reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut));
+   |     ---------------------------------------^^^^^^^^^^^^^^^^^--
+   |     |                                      |
+   |     |                                      second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:178:5
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^
+   |     |                                            |
+   |     |                                            immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:183:5
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^^
+   |     |                                           |
+   |     |                                           immutable borrow occurs here
+   |     mutable borrow occurs here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 122:21...
+  --> $DIR/two-phase-surprise-no-conflict.rs:122:21
+   |
+LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
+   |                     ^^
+
+error[E0502]: cannot borrow `*reg` as mutable because it is also borrowed as immutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:188:5
+   |
+LL |     reg.register_ref(&CapturePass::new(&reg.sess_mut));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-------------^^
+   |     |                                  |
+   |     |                                  immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `*reg` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:200:5
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^
+   |     |                                                |
+   |     |                                                first mutable borrow occurs here
+   |     second mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:200:54
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     -------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                                |
+   |     |                                                second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `*reg` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:206:5
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^^
+   |     |                                               |
+   |     |                                               first mutable borrow occurs here
+   |     second mutable borrow occurs here
+   |
+note: borrowed value must be valid for the lifetime 'a as defined on the function body at 122:21...
+  --> $DIR/two-phase-surprise-no-conflict.rs:122:21
+   |
+LL | fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
+   |                     ^^
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:206:53
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                               |
+   |     |                                               second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `*reg` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:212:5
+   |
+LL |     reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------------^^
+   |     |                                      |
+   |     |                                      first mutable borrow occurs here
+   |     second mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:212:44
+   |
+LL |     reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
+   |     ---------------------------------------^^^^^^^^^^^^^^^^^--
+   |     |                                      |
+   |     |                                      second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error: aborting due to 15 previous errors
+
+Some errors occurred: E0499, E0502, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.no2pb.stderr b/src/test/ui/borrowck/two-phase-surprise-no-conflict.no2pb.stderr
new file mode 100644
index 00000000000..f4fc7e54f80
--- /dev/null
+++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.no2pb.stderr
@@ -0,0 +1,175 @@
+error[E0503]: cannot use `self.cx` because it was mutably borrowed
+  --> $DIR/two-phase-surprise-no-conflict.rs:40:23
+   |
+LL |         let _mut_borrow = &mut *self;
+   |                           ---------- borrow of `*self` occurs here
+LL |         let _access = self.cx;
+   |                       ^^^^^^^ use of borrowed `*self`
+...
+LL |         _mut_borrow;
+   |         ----------- borrow later used here
+
+error[E0502]: cannot borrow `*self.cx` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:64:33
+   |
+LL |                 self.hash_expr(&self.cx.body(eid).value);
+   |                 ----------------^^^^^^^-----------------
+   |                 |               |
+   |                 |               immutable borrow occurs here
+   |                 mutable borrow occurs here
+   |                 borrow later used here
+
+error[E0502]: cannot borrow `*self.cx_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:79:33
+   |
+LL |                 self.hash_expr(&self.cx_mut.body(eid).value);
+   |                 ----------------^^^^^^^^^^^-----------------
+   |                 |               |
+   |                 |               immutable borrow occurs here
+   |                 mutable borrow occurs here
+   |                 borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:131:51
+   |
+LL |     reg.register_static(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     ----------------------------------------------^^^^^^^^^^^^^---
+   |     |                                             |
+   |     |                                             immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:135:50
+   |
+LL |     reg.register_bound(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     ---------------------------------------------^^^^^^^^^^^^^---
+   |     |                                            |
+   |     |                                            immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:139:49
+   |
+LL |     reg.register_univ(Box::new(TrivialPass::new(&reg.sess_mut)));
+   |     --------------------------------------------^^^^^^^^^^^^^---
+   |     |                                           |
+   |     |                                           immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:143:40
+   |
+LL |     reg.register_ref(&TrivialPass::new(&reg.sess_mut));
+   |     -----------------------------------^^^^^^^^^^^^^--
+   |     |                                  |
+   |     |                                  immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:151:51
+   |
+LL |     reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut)));
+   |     ----------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                             |
+   |     |                                             second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:156:54
+   |
+LL |     reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     -------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                                |
+   |     |                                                second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:161:53
+   |
+LL |     reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+   |     ------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                               |
+   |     |                                               second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:166:44
+   |
+LL |     reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut));
+   |     ---------------------------------------^^^^^^^^^^^^^^^^^--
+   |     |                                      |
+   |     |                                      second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:178:50
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     ---------------------------------------------^^^^^^^^^^^^^---
+   |     |                                            |
+   |     |                                            immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:183:49
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new(&reg.sess_mut)));
+   |     --------------------------------------------^^^^^^^^^^^^^---
+   |     |                                           |
+   |     |                                           immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0502]: cannot borrow `reg.sess_mut` as immutable because it is also borrowed as mutable
+  --> $DIR/two-phase-surprise-no-conflict.rs:188:40
+   |
+LL |     reg.register_ref(&CapturePass::new(&reg.sess_mut));
+   |     -----------------------------------^^^^^^^^^^^^^--
+   |     |                                  |
+   |     |                                  immutable borrow occurs here
+   |     mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:200:54
+   |
+LL |     reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     -------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                                |
+   |     |                                                second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:206:53
+   |
+LL |     reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+   |     ------------------------------------------------^^^^^^^^^^^^^^^^^---
+   |     |                                               |
+   |     |                                               second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error[E0499]: cannot borrow `reg.sess_mut` as mutable more than once at a time
+  --> $DIR/two-phase-surprise-no-conflict.rs:212:44
+   |
+LL |     reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
+   |     ---------------------------------------^^^^^^^^^^^^^^^^^--
+   |     |                                      |
+   |     |                                      second mutable borrow occurs here
+   |     first mutable borrow occurs here
+   |     borrow later used here
+
+error: aborting due to 17 previous errors
+
+Some errors occurred: E0499, E0502, E0503.
+For more information about an error, try `rustc --explain E0499`.
diff --git a/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs b/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs
new file mode 100644
index 00000000000..36bf44afb15
--- /dev/null
+++ b/src/test/ui/borrowck/two-phase-surprise-no-conflict.rs
@@ -0,0 +1,219 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This is a test adapted from a minimization of the code from
+// rust-lang/rust#52934, where an accidental disabling of
+// two-phase-borrows (in the initial 2018 edition integration) broke
+// Clippy, but the scenarios where it was breaking were subtle enough
+// that we decided it warranted its own unit test, and pnkfelix
+// decided to use that test as an opportunity to illustrate the cases.
+
+// revisions: ast no2pb nll
+//[ast]compile-flags: -Z borrowck=ast
+//[no2pb]compile-flags: -Z borrowck=mir
+//[nll]compile-flags: -Z borrowck=mir -Z two-phase-borrows
+
+// (Since we are manually toggling NLL variations on and off, don't
+// bother with compare-mode=nll)
+// ignore-compare-mode-nll
+
+#[derive(Copy, Clone)]
+struct BodyId;
+enum Expr { Closure(BodyId), Others }
+struct Body { value: Expr }
+
+struct Map { body: Body, }
+impl Map { fn body(&self, _: BodyId) -> &Body { unimplemented!() } }
+
+struct SpanlessHash<'a> { cx: &'a Map, cx_mut: &'a mut Map }
+
+impl <'a> SpanlessHash<'a> {
+    fn demo(&mut self) {
+        let _mut_borrow = &mut *self;
+        let _access = self.cx;
+        //[ast]~^ ERROR cannot use `self.cx` because it was mutably borrowed [E0503]
+        //[no2pb]~^^ ERROR cannot use `self.cx` because it was mutably borrowed [E0503]
+        //[nll]~^^^ ERROR cannot use `self.cx` because it was mutably borrowed [E0503]
+        _mut_borrow;
+    }
+
+    fn hash_expr(&mut self, e: &Expr) {
+        match *e {
+            Expr::Closure(eid) => {
+                // Accepted by AST-borrowck for erroneous reasons
+                // (rust-lang/rust#38899).
+                //
+                // Not okay without two-phase borrows: the implicit
+                // `&mut self` of the receiver is evaluated first, and
+                // that conflicts with the `self.cx`` access during
+                // argument evaluation, as demonstrated in `fn demo`
+                // above.
+                //
+                // Okay if we have two-phase borrows. Note that even
+                // if `self.cx.body(..)` holds onto a reference into
+                // `self.cx`, `self.cx` is an immutable-borrow, so
+                // nothing in the activation for `self.hash_expr(..)`
+                // can interfere with that immutable borrow.
+                self.hash_expr(&self.cx.body(eid).value);
+                //[no2pb]~^ ERROR cannot borrow `*self.cx`
+            },
+            _ => {}
+        }
+    }
+
+    fn hash_expr_mut(&mut self, e: &Expr) {
+        match *e {
+            Expr::Closure(eid) => {
+                // Not okay: the call to `self.cx_mut.body(eid)` might
+                // hold on to some mutably borrowed state in
+                // `self.cx_mut`, which would then interfere with the
+                // eventual activation of the `self` mutable borrow
+                // for `self.hash_expr(..)`
+                self.hash_expr(&self.cx_mut.body(eid).value);
+                //[ast]~^ ERROR cannot borrow `*self.cx_mut`
+                //[no2pb]~^^ ERROR cannot borrow `*self.cx_mut`
+                //[nll]~^^^ ERROR cannot borrow `*self`
+            },
+            _ => {}
+        }
+    }
+}
+
+struct Session;
+struct Config;
+trait LateLintPass<'a> { }
+
+struct TrivialPass;
+impl TrivialPass {
+    fn new(_: &Session) -> Self { TrivialPass }
+    fn new_mut(_: &mut Session) -> Self { TrivialPass }
+}
+
+struct CapturePass<'a> { s: &'a Session }
+impl<'a> CapturePass<'a> {
+    fn new(s: &'a Session) -> Self { CapturePass { s } }
+    fn new_mut(s: &'a mut Session) -> Self { CapturePass { s } }
+}
+
+impl<'a> LateLintPass<'a> for TrivialPass { }
+impl<'a, 'b> LateLintPass<'a> for CapturePass<'b> { }
+
+struct Registry<'a> { sess_mut: &'a mut Session }
+impl<'a> Registry<'a> {
+    fn register_static(&mut self, _: Box<dyn LateLintPass + 'static>) { }
+
+    // Note: there isn't an interesting distinction between these
+    // different methods explored by any of the cases in the test
+    // below. pnkfelix just happened to write these cases out while
+    // exploring variations on `dyn for <'a> Trait<'a> + 'static`, and
+    // then decided to keep these particular ones in.
+    fn register_bound(&mut self, _: Box<dyn LateLintPass + 'a>) { }
+    fn register_univ(&mut self, _: Box<dyn for <'b> LateLintPass<'b> + 'a>) { }
+    fn register_ref(&mut self, _: &dyn LateLintPass) { }
+}
+
+fn register_plugins<'a>(mk_reg: impl Fn() -> &'a mut Registry<'a>) {
+    // Not okay without two-phase borrows: The implicit `&mut reg` of
+    // the receiver is evaluaated first, and that conflicts with the
+    // `reg.sess_mut` access during argument evaluation.
+    //
+    // Okay if we have two-phase borrows: inner borrows do not survive
+    // to the actual method invocation, because `TrivialPass::new`
+    // cannot (according to its type) keep them alive.
+    let reg = mk_reg();
+    reg.register_static(Box::new(TrivialPass::new(&reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_bound(Box::new(TrivialPass::new(&reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_univ(Box::new(TrivialPass::new(&reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_ref(&TrivialPass::new(&reg.sess_mut));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+
+    // These are not okay: the inner mutable borrows immediately
+    // conflict with the outer borrow/reservation, even with support
+    // for two-phase borrows.
+    let reg = mk_reg();
+    reg.register_static(Box::new(TrivialPass::new(&mut reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_bound(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_univ(Box::new(TrivialPass::new_mut(&mut reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut`
+    let reg = mk_reg();
+    reg.register_ref(&TrivialPass::new_mut(&mut reg.sess_mut));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut`
+
+    // These are not okay: the inner borrows may reach the actual
+    // method invocation, because `CapturePass::new` might (according
+    // to its type) keep them alive.
+    //
+    // (Also, we don't test `register_static` on CapturePass because
+    // that will fail to get past lifetime inference.)
+    let reg = mk_reg();
+    reg.register_bound(Box::new(CapturePass::new(&reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `*reg` as mutable
+    let reg = mk_reg();
+    reg.register_univ(Box::new(CapturePass::new(&reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `*reg` as mutable
+    let reg = mk_reg();
+    reg.register_ref(&CapturePass::new(&reg.sess_mut));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `*reg` as mutable
+
+    // These are not okay: the inner mutable borrows immediately
+    // conflict with the outer borrow/reservation, even with support
+    // for two-phase borrows.
+    //
+    // (Again, we don't test `register_static` on CapturePass because
+    // that will fail to get past lifetime inference.)
+    let reg = mk_reg();
+    reg.register_bound(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut` as mutable more than once at a time
+    //[nll]~^^^^ ERROR cannot borrow `*reg` as mutable more than once at a time
+    let reg = mk_reg();
+    reg.register_univ(Box::new(CapturePass::new_mut(&mut reg.sess_mut)));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut` as mutable more than once at a time
+    //[nll]~^^^^ ERROR cannot borrow `*reg` as mutable more than once at a time
+    let reg = mk_reg();
+    reg.register_ref(&CapturePass::new_mut(&mut reg.sess_mut));
+    //[ast]~^ ERROR cannot borrow `reg.sess_mut`
+    //[no2pb]~^^ ERROR cannot borrow `reg.sess_mut`
+    //[nll]~^^^ ERROR cannot borrow `reg.sess_mut` as mutable more than once at a time
+    //[nll]~^^^^ ERROR cannot borrow `*reg` as mutable more than once at a time
+}
+
+fn main() { }