diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs
index a8c81b4fc9f..0ad22f91855 100644
--- a/src/librustc_mir/borrow_check.rs
+++ b/src/librustc_mir/borrow_check.rs
@@ -385,7 +385,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
         // borrow of immutable ref, moves through non-`Box`-ref)
         let (sd, rw) = kind;
         self.each_borrow_involving_path(
-            context, (sd, lvalue_span.0), flow_state, |this, _index, borrow| {
+            context, (sd, lvalue_span.0), flow_state, |this, _index, borrow, common_prefix| {
                 match (rw, borrow.kind) {
                     (Read(_), BorrowKind::Shared) => {
                         Control::Continue
@@ -399,6 +399,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                             ReadKind::Borrow(bk) =>
                                 this.report_conflicting_borrow(
                                     context, lvalue_span,
+                                    common_prefix,
                                     (lvalue_span.0, bk), (&borrow.lvalue, borrow.kind)),
                         }
                         Control::Break
@@ -408,6 +409,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                             WriteKind::MutableBorrow(bk) =>
                                 this.report_conflicting_borrow(
                                     context, lvalue_span,
+                                    common_prefix,
                                     (lvalue_span.0, bk), (&borrow.lvalue, borrow.kind)),
                             WriteKind::StorageDead |
                             WriteKind::Mutate =>
@@ -704,7 +706,7 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
                                      access_lvalue: (ShallowOrDeep, &Lvalue<'gcx>),
                                      flow_state: &InProgress<'b, 'gcx>,
                                      mut op: F)
-        where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'gcx>) -> Control
+        where F: FnMut(&mut Self, BorrowIndex, &BorrowData<'gcx>, &Lvalue) -> Control
     {
         let (access, lvalue) = access_lvalue;
 
@@ -726,9 +728,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
             // to #38899. Will probably need back-compat mode flag.
             for accessed_prefix in self.prefixes(lvalue, PrefixSet::All) {
                 if *accessed_prefix == borrowed.lvalue {
-                    // FIXME: pass in prefix here too? And/or enum
-                    // describing case we are in?
-                    let ctrl = op(self, i, borrowed);
+                    // FIXME: pass in enum describing case we are in?
+                    let ctrl = op(self, i, borrowed, accessed_prefix);
                     if ctrl == Control::Break { return; }
                 }
             }
@@ -753,9 +754,8 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
 
             for borrowed_prefix in self.prefixes(&borrowed.lvalue, prefix_kind) {
                 if borrowed_prefix == lvalue {
-                    // FIXME: pass in prefix here too? And/or enum
-                    // describing case we are in?
-                    let ctrl = op(self, i, borrowed);
+                    // FIXME: pass in enum describing case we are in?
+                    let ctrl = op(self, i, borrowed, borrowed_prefix);
                     if ctrl == Control::Break { return; }
                 }
             }
@@ -780,6 +780,30 @@ mod prefixes {
     use rustc::ty::{self, TyCtxt};
     use rustc::mir::{Lvalue, Mir, ProjectionElem};
 
+    pub trait IsPrefixOf<'tcx> {
+        fn is_prefix_of(&self, other: &Lvalue<'tcx>) -> bool;
+    }
+
+    impl<'tcx> IsPrefixOf<'tcx> for Lvalue<'tcx> {
+        fn is_prefix_of(&self, other: &Lvalue<'tcx>) -> bool {
+            let mut cursor = other;
+            loop {
+                if self == cursor {
+                    return true;
+                }
+
+                match *cursor {
+                    Lvalue::Local(_) |
+                    Lvalue::Static(_) => return false,
+                    Lvalue::Projection(ref proj) => {
+                        cursor = &proj.base;
+                    }
+                }
+            }
+        }
+    }
+
+
     pub(super) struct Prefixes<'c, 'tcx: 'c> {
         mir: &'c Mir<'tcx>,
         tcx: TyCtxt<'c, 'tcx, 'tcx>,
@@ -943,12 +967,16 @@ impl<'c, 'b, 'a: 'b+'c, 'gcx, 'tcx: 'a> MirBorrowckCtxt<'c, 'b, 'a, 'gcx, 'tcx>
     fn report_conflicting_borrow(&mut self,
                                  _context: Context,
                                  (lvalue, span): (&Lvalue, Span),
+                                 common_prefix: &Lvalue,
                                  loan1: (&Lvalue, BorrowKind),
                                  loan2: (&Lvalue, BorrowKind)) {
+        use self::prefixes::IsPrefixOf;
+
         let (loan1_lvalue, loan1_kind) = loan1;
         let (loan2_lvalue, loan2_kind) = loan2;
-        // FIXME: obviously falsifiable. Generalize for non-eq lvalues later.
-        assert_eq!(loan1_lvalue, loan2_lvalue);
+
+        assert!(common_prefix.is_prefix_of(loan1_lvalue));
+        assert!(common_prefix.is_prefix_of(loan2_lvalue));
 
         // FIXME: supply non-"" `opt_via` when appropriate
         let mut err = match (loan1_kind, "immutable", "mutable",