]> git.proxmox.com Git - rustc.git/commitdiff
New upstream version 1.26.2+dfsg1
authorXimin Luo <infinity0@debian.org>
Sat, 16 Jun 2018 19:36:34 +0000 (12:36 -0700)
committerXimin Luo <infinity0@debian.org>
Sat, 16 Jun 2018 19:36:34 +0000 (12:36 -0700)
16 files changed:
RELEASES.md
git-commit-hash
src/bootstrap/channel.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/mem_categorization.rs
src/librustc/traits/project.rs
src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs
src/librustc_borrowck/borrowck/gather_loans/lifetime.rs
src/librustc_borrowck/borrowck/gather_loans/move_error.rs
src/librustc_borrowck/borrowck/gather_loans/restrictions.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/upvar.rs
src/test/ui/borrowck/issue-51117.rs [new file with mode: 0644]
src/test/ui/borrowck/issue-51117.stderr [new file with mode: 0644]
version

index 758de62a8482333adeb765e1fedff8c56e7ac712..0403a2ac1feb3c71f6f3e42f1c948bd5908ce067 100644 (file)
@@ -1,3 +1,13 @@
+Version 1.26.2 (2018-06-05)
+==========================
+
+Compatibility Notes
+-------------------
+
+- [The borrow checker was fixed to avoid unsoundness when using match ergonomics][51117]
+
+[51117]: https://github.com/rust-lang/rust/issues/51117
+
 Version 1.26.1 (2018-05-29)
 ==========================
 
index eb4ad2e657fa56fbc6271b01d8066381145c3abf..101529709552d5a3cd05c250a1a05264377ee409 100644 (file)
@@ -1 +1 @@
-827013a31b88e536e85b8e6ceb5b9988042ec335
\ No newline at end of file
+594fb253c2b02b320c728391a425d028e6dc7a09
\ No newline at end of file
index 6b25a130ae0244c973d00eda79eff84dc6948ce0..fae79730669a671df71cc3f985b67023d93aca91 100644 (file)
@@ -24,7 +24,7 @@ use Build;
 use config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.26.1";
+pub const CFG_RELEASE_NUM: &str = "1.26.2";
 
 pub struct GitInfo {
     inner: Option<Info>,
index 28524678e9916bcc8f3bc35e590da1d9d6cfc7b1..a7e68d807d07481521b83ace120a256a9f398807 100644 (file)
@@ -845,17 +845,24 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
     /// established up front, e.g. via `determine_pat_move_mode` (see
     /// also `walk_irrefutable_pat` for patterns that stand alone).
     fn walk_pat(&mut self, cmt_discr: mc::cmt<'tcx>, pat: &hir::Pat, match_mode: MatchMode) {
-        debug!("walk_pat cmt_discr={:?} pat={:?}", cmt_discr, pat);
+        debug!("walk_pat(cmt_discr={:?}, pat={:?})", cmt_discr, pat);
 
         let ExprUseVisitor { ref mc, ref mut delegate, param_env } = *self;
         return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |cmt_pat, pat| {
             if let PatKind::Binding(_, canonical_id, ..) = pat.node {
-                debug!("binding cmt_pat={:?} pat={:?} match_mode={:?}", cmt_pat, pat, match_mode);
+                debug!(
+                    "walk_pat: binding cmt_pat={:?} pat={:?} match_mode={:?}",
+                    cmt_pat,
+                    pat,
+                    match_mode,
+                );
                 let bm = *mc.tables.pat_binding_modes().get(pat.hir_id)
                                                      .expect("missing binding mode");
+                debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
 
                 // pat_ty: the type of the binding being produced.
                 let pat_ty = return_if_err!(mc.node_ty(pat.hir_id));
+                debug!("walk_pat: pat_ty={:?}", pat_ty);
 
                 // Each match binding is effectively an assignment to the
                 // binding being produced.
index 5875e5e4097af496036aaa5b221866ffa5fc6e1a..4aaa791cc2e2e1491288b6a48b8a014d11fecb1c 100644 (file)
@@ -95,7 +95,7 @@ pub enum Categorization<'tcx> {
     StaticItem,
     Upvar(Upvar),                          // upvar referenced by closure env
     Local(ast::NodeId),                    // local variable
-    Deref(cmt<'tcx>, PointerKind<'tcx>),   // deref of a ptr
+    Deref(cmt<'tcx>, PointerKind<'tcx>), // deref of a ptr
     Interior(cmt<'tcx>, InteriorKind),     // something interior: field, tuple, etc
     Downcast(cmt<'tcx>, DefId),            // selects a particular enum variant (*1)
 
@@ -120,9 +120,6 @@ pub enum PointerKind<'tcx> {
 
     /// `*T`
     UnsafePtr(hir::Mutability),
-
-    /// Implicit deref of the `&T` that results from an overloaded index `[]`.
-    Implicit(ty::BorrowKind, ty::Region<'tcx>),
 }
 
 // We use the term "interior" to mean "something reachable from the
@@ -161,6 +158,7 @@ pub enum MutabilityCategory {
 pub enum Note {
     NoteClosureEnv(ty::UpvarId), // Deref through closure env
     NoteUpvarRef(ty::UpvarId),   // Deref through by-ref upvar
+    NoteIndex,                   // Deref as part of desugaring `x[]` into its two components
     NoteNone                     // Nothing special
 }
 
@@ -224,8 +222,7 @@ impl<'tcx> cmt_<'tcx> {
 
     pub fn immutability_blame(&self) -> Option<ImmutabilityBlame<'tcx>> {
         match self.cat {
-            Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) |
-            Categorization::Deref(ref base_cmt, Implicit(ty::ImmBorrow, _)) => {
+            Categorization::Deref(ref base_cmt, BorrowedPtr(ty::ImmBorrow, _)) => {
                 // try to figure out where the immutable reference came from
                 match base_cmt.cat {
                     Categorization::Local(node_id) =>
@@ -321,7 +318,7 @@ impl MutabilityCategory {
             Unique => {
                 base_mutbl.inherit()
             }
-            BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => {
+            BorrowedPtr(borrow_kind, _) => {
                 MutabilityCategory::from_borrow_kind(borrow_kind)
             }
             UnsafePtr(m) => {
@@ -610,7 +607,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 } else {
                     previous()?
                 };
-                self.cat_deref(expr, base, false)
+                self.cat_deref(expr, base, NoteNone)
             }
 
             adjustment::Adjust::NeverToAny |
@@ -633,10 +630,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         match expr.node {
           hir::ExprUnary(hir::UnDeref, ref e_base) => {
             if self.tables.is_method_call(expr) {
-                self.cat_overloaded_place(expr, e_base, false)
+                self.cat_overloaded_place(expr, e_base, NoteNone)
             } else {
                 let base_cmt = self.cat_expr(&e_base)?;
-                self.cat_deref(expr, base_cmt, false)
+                self.cat_deref(expr, base_cmt, NoteNone)
             }
           }
 
@@ -661,7 +658,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                 // The call to index() returns a `&T` value, which
                 // is an rvalue. That is what we will be
                 // dereferencing.
-                self.cat_overloaded_place(expr, base, true)
+                self.cat_overloaded_place(expr, base, NoteIndex)
             } else {
                 let base_cmt = self.cat_expr(&base)?;
                 self.cat_index(expr, base_cmt, expr_ty, InteriorOffsetKind::Index)
@@ -1012,12 +1009,18 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         ret
     }
 
-    fn cat_overloaded_place(&self,
-                             expr: &hir::Expr,
-                             base: &hir::Expr,
-                             implicit: bool)
-                             -> McResult<cmt<'tcx>> {
-        debug!("cat_overloaded_place: implicit={}", implicit);
+    fn cat_overloaded_place(
+        &self,
+        expr: &hir::Expr,
+        base: &hir::Expr,
+        note: Note,
+    ) -> McResult<cmt<'tcx>> {
+        debug!(
+            "cat_overloaded_place(expr={:?}, base={:?}, note={:?})",
+            expr,
+            base,
+            note,
+        );
 
         // Reconstruct the output assuming it's a reference with the
         // same region and mutability as the receiver. This holds for
@@ -1037,14 +1040,15 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         });
 
         let base_cmt = self.cat_rvalue_node(expr.id, expr.span, ref_ty);
-        self.cat_deref(expr, base_cmt, implicit)
+        self.cat_deref(expr, base_cmt, note)
     }
 
-    pub fn cat_deref<N:ast_node>(&self,
-                                 node: &N,
-                                 base_cmt: cmt<'tcx>,
-                                 implicit: bool)
-                                 -> McResult<cmt<'tcx>> {
+    pub fn cat_deref(
+        &self,
+        node: &impl ast_node,
+        base_cmt: cmt<'tcx>,
+        note: Note,
+    ) -> McResult<cmt<'tcx>> {
         debug!("cat_deref: base_cmt={:?}", base_cmt);
 
         let base_cmt_ty = base_cmt.ty;
@@ -1060,9 +1064,9 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         let ptr = match base_cmt.ty.sty {
             ty::TyAdt(def, ..) if def.is_box() => Unique,
             ty::TyRawPtr(ref mt) => UnsafePtr(mt.mutbl),
-            ty::TyRef(r, mt) => {
-                let bk = ty::BorrowKind::from_mutbl(mt.mutbl);
-                if implicit { Implicit(bk, r) } else { BorrowedPtr(bk, r) }
+            ty::TyRef(r, ty) => {
+                let bk = ty::BorrowKind::from_mutbl(ty.mutbl);
+                BorrowedPtr(bk, r)
             }
             ref ty => bug!("unexpected type in cat_deref: {:?}", ty)
         };
@@ -1073,7 +1077,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             mutbl: MutabilityCategory::from_pointer_kind(base_cmt.mutbl, ptr),
             cat: Categorization::Deref(base_cmt, ptr),
             ty: deref_ty,
-            note: NoteNone
+            note: note,
         });
         debug!("cat_deref ret {:?}", ret);
         Ok(ret)
@@ -1207,7 +1211,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
         // step out of sync again. So you'll see below that we always
         // get the type of the *subpattern* and use that.
 
-        debug!("cat_pattern: {:?} cmt={:?}", pat, cmt);
+        debug!("cat_pattern(pat={:?}, cmt={:?})", pat, cmt);
 
         // If (pattern) adjustments are active for this pattern, adjust the `cmt` correspondingly.
         // `cmt`s are constructed differently from patterns. For example, in
@@ -1245,10 +1249,13 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
                         .pat_adjustments()
                         .get(pat.hir_id)
                         .map(|v| v.len())
-                        .unwrap_or(0) {
-            cmt = self.cat_deref(pat, cmt, true /* implicit */)?;
+                        .unwrap_or(0)
+        {
+            debug!("cat_pattern: applying adjustment to cmt={:?}", cmt);
+            cmt = self.cat_deref(pat, cmt, NoteNone)?;
         }
         let cmt = cmt; // lose mutability
+        debug!("cat_pattern: applied adjustment derefs to get cmt={:?}", cmt);
 
         // Invoke the callback, but only now, after the `cmt` has adjusted.
         //
@@ -1342,7 +1349,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             // box p1, &p1, &mut p1.  we can ignore the mutability of
             // PatKind::Ref since that information is already contained
             // in the type.
-            let subcmt = self.cat_deref(pat, cmt, false)?;
+            let subcmt = self.cat_deref(pat, cmt, NoteNone)?;
             self.cat_pattern_(subcmt, &subpat, op)?;
           }
 
@@ -1403,7 +1410,6 @@ impl<'tcx> cmt_<'tcx> {
             Categorization::Local(..) |
             Categorization::Deref(_, UnsafePtr(..)) |
             Categorization::Deref(_, BorrowedPtr(..)) |
-            Categorization::Deref(_, Implicit(..)) |
             Categorization::Upvar(..) => {
                 Rc::new((*self).clone())
             }
@@ -1423,9 +1429,7 @@ impl<'tcx> cmt_<'tcx> {
 
         match self.cat {
             Categorization::Deref(ref b, BorrowedPtr(ty::MutBorrow, _)) |
-            Categorization::Deref(ref b, Implicit(ty::MutBorrow, _)) |
             Categorization::Deref(ref b, BorrowedPtr(ty::UniqueImmBorrow, _)) |
-            Categorization::Deref(ref b, Implicit(ty::UniqueImmBorrow, _)) |
             Categorization::Deref(ref b, Unique) |
             Categorization::Downcast(ref b, _) |
             Categorization::Interior(ref b, _) => {
@@ -1448,8 +1452,7 @@ impl<'tcx> cmt_<'tcx> {
                 }
             }
 
-            Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) |
-            Categorization::Deref(_, Implicit(ty::ImmBorrow, _)) => {
+            Categorization::Deref(_, BorrowedPtr(ty::ImmBorrow, _)) => {
                 FreelyAliasable(AliasableBorrowed)
             }
         }
@@ -1471,7 +1474,7 @@ impl<'tcx> cmt_<'tcx> {
                     _ => bug!()
                 })
             }
-            NoteNone => None
+            NoteIndex | NoteNone => None
         }
     }
 
@@ -1500,9 +1503,6 @@ impl<'tcx> cmt_<'tcx> {
                     Some(_) => bug!(),
                     None => {
                         match pk {
-                            Implicit(..) => {
-                                format!("indexed content")
-                            }
                             Unique => {
                                 format!("`Box` content")
                             }
@@ -1510,7 +1510,10 @@ impl<'tcx> cmt_<'tcx> {
                                 format!("dereference of raw pointer")
                             }
                             BorrowedPtr(..) => {
-                                format!("borrowed content")
+                                match self.note {
+                                    NoteIndex => format!("indexed content"),
+                                    _ => format!("borrowed content"),
+                                }
                             }
                         }
                     }
@@ -1541,12 +1544,9 @@ impl<'tcx> cmt_<'tcx> {
 pub fn ptr_sigil(ptr: PointerKind) -> &'static str {
     match ptr {
         Unique => "Box",
-        BorrowedPtr(ty::ImmBorrow, _) |
-        Implicit(ty::ImmBorrow, _) => "&",
-        BorrowedPtr(ty::MutBorrow, _) |
-        Implicit(ty::MutBorrow, _) => "&mut",
-        BorrowedPtr(ty::UniqueImmBorrow, _) |
-        Implicit(ty::UniqueImmBorrow, _) => "&unique",
+        BorrowedPtr(ty::ImmBorrow, _) => "&",
+        BorrowedPtr(ty::MutBorrow, _) => "&mut",
+        BorrowedPtr(ty::UniqueImmBorrow, _) => "&unique",
         UnsafePtr(_) => "*",
     }
 }
index de336c29229409d90d5fd0dc482923a11f3873b7..441089250a1300f9d5404e2703c9ec1c13f4a640 100644 (file)
@@ -137,17 +137,30 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
     fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
         use self::ProjectionTyCandidateSet::*;
         use self::ProjectionTyCandidate::*;
+
+        // This wacky variable is just used to try and
+        // make code readable and avoid confusing paths.
+        // It is assigned a "value" of `()` only on those
+        // paths in which we wish to convert `*self` to
+        // ambiguous (and return false, because the candidate
+        // was not used). On other paths, it is not assigned,
+        // and hence if those paths *could* reach the code that
+        // comes after the match, this fn would not compile.
+        let convert_to_ambigious;
+
         match self {
             None => {
                 *self = Single(candidate);
-                true
+                return true;
             }
+
             Single(current) => {
                 // Duplicates can happen inside ParamEnv. In the case, we
                 // perform a lazy deduplication.
                 if current == &candidate {
                     return false;
                 }
+
                 // Prefer where-clauses. As in select, if there are multiple
                 // candidates, we prefer where-clause candidates over impls.  This
                 // may seem a bit surprising, since impls are the source of
@@ -156,17 +169,23 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
                 // clauses are the safer choice. See the comment on
                 // `select::SelectionCandidate` and #21974 for more details.
                 match (current, candidate) {
-                    (ParamEnv(..), ParamEnv(..)) => { *self = Ambiguous; }
-                    (ParamEnv(..), _) => {}
+                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
+                    (ParamEnv(..), _) => return false,
                     (_, ParamEnv(..)) => { unreachable!(); }
-                    (_, _) => { *self = Ambiguous; }
+                    (_, _) => convert_to_ambigious = (),
                 }
-                false
             }
+
             Ambiguous | Error(..) => {
-                false
+                return false;
             }
         }
+
+        // We only ever get here when we moved from a single candidate
+        // to ambiguous.
+        let () = convert_to_ambigious;
+        *self = Ambiguous;
+        false
     }
 }
 
index 465457f5ab39a56a01e54412945bf2969d32c73a..766c38160ee6dc736e05f1ad3322880d53b4db68 100644 (file)
@@ -181,7 +181,6 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                                -> Option<mc::cmt<'tcx>> {
     match cmt.cat {
         Categorization::Deref(_, mc::BorrowedPtr(..)) |
-        Categorization::Deref(_, mc::Implicit(..)) |
         Categorization::Deref(_, mc::UnsafePtr(..)) |
         Categorization::StaticItem => {
             Some(cmt.clone())
index 97fa94b5e5cf9c159ccba5baaec181549904f300..d7bd4762e1ab979a461e6829da90c71161084b45 100644 (file)
@@ -75,7 +75,6 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
             Categorization::Local(..) |                     // L-Local
             Categorization::Upvar(..) |
             Categorization::Deref(_, mc::BorrowedPtr(..)) | // L-Deref-Borrowed
-            Categorization::Deref(_, mc::Implicit(..)) |
             Categorization::Deref(_, mc::UnsafePtr(..)) => {
                 self.check_scope(self.scope(cmt))
             }
@@ -123,8 +122,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
             Categorization::Deref(_, mc::UnsafePtr(..)) => {
                 self.bccx.tcx.types.re_static
             }
-            Categorization::Deref(_, mc::BorrowedPtr(_, r)) |
-            Categorization::Deref(_, mc::Implicit(_, r)) => {
+            Categorization::Deref(_, mc::BorrowedPtr(_, r)) => {
                 r
             }
             Categorization::Downcast(ref cmt, _) |
index 1f2b917bdb9943154cd6ca5fc5e269f7c00a06e3..18026a14259ded975c73512e48f7fdb634cc91dc 100644 (file)
@@ -140,7 +140,6 @@ fn report_cannot_move_out_of<'a, 'tcx>(bccx: &'a BorrowckCtxt<'a, 'tcx>,
                                        -> DiagnosticBuilder<'a> {
     match move_from.cat {
         Categorization::Deref(_, mc::BorrowedPtr(..)) |
-        Categorization::Deref(_, mc::Implicit(..)) |
         Categorization::Deref(_, mc::UnsafePtr(..)) |
         Categorization::StaticItem => {
             bccx.cannot_move_out_of(
index 5cfbe49f77f11bb266aca3e92971ec71af00cc83..fc502978685df7c4433ce32d6b03af521123453e 100644 (file)
@@ -147,7 +147,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
                         let result = self.restrict(cmt_base);
                         self.extend(result, &cmt, LpDeref(pk))
                     }
-                    mc::Implicit(bk, lt) | mc::BorrowedPtr(bk, lt) => {
+                    mc::BorrowedPtr(bk, lt) => {
                         // R-Deref-[Mut-]Borrowed
                         if !self.bccx.is_subregion_of(self.loan_region, lt) {
                             self.bccx.report(
index ae373fbad22465cc034cc68c644883cdd2ab99ea..35870432d82acd2c759c60c5ae91c32e25f5408a 100644 (file)
@@ -236,6 +236,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     .borrow_mut()
                     .pat_binding_modes_mut()
                     .insert(pat.hir_id, bm);
+                debug!("check_pat_walk: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
                 let typ = self.local_ty(pat.span, pat.id);
                 match bm {
                     ty::BindByReference(mutbl) => {
index 9ed4ab45a1ba7dd19c22d9a5e3ebd95e76107e9f..4e9dbd52e5e635d91d60e9162e68f647b80e5607 100644 (file)
@@ -1114,7 +1114,6 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
                    borrow_kind,
                    borrow_cmt);
             match borrow_cmt.cat.clone() {
-                Categorization::Deref(ref_cmt, mc::Implicit(ref_kind, ref_region)) |
                 Categorization::Deref(ref_cmt, mc::BorrowedPtr(ref_kind, ref_region)) => {
                     match self.link_reborrowed_region(span,
                                                       borrow_region, borrow_kind,
index 4fc3344dab2a919dd796d84de0e27e70fe9cdf8c..56e088fcb227fa5a64e0dc89d9b60807064ce44b 100644 (file)
@@ -328,8 +328,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
             guarantor.cat
         );
         match guarantor.cat {
-            Categorization::Deref(_, mc::BorrowedPtr(..)) |
-            Categorization::Deref(_, mc::Implicit(..)) => {
+            Categorization::Deref(_, mc::BorrowedPtr(..)) => {
                 debug!(
                     "adjust_upvar_borrow_kind_for_consume: found deref with note {:?}",
                     cmt.note
@@ -367,7 +366,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                             var_name(tcx, upvar_id.var_id),
                         );
                     }
-                    mc::NoteNone => {}
+                    mc::NoteIndex | mc::NoteNone => {}
                 }
             }
             _ => {}
@@ -389,8 +388,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                 self.adjust_upvar_borrow_kind_for_mut(base);
             }
 
-            Categorization::Deref(base, mc::BorrowedPtr(..)) |
-            Categorization::Deref(base, mc::Implicit(..)) => {
+            Categorization::Deref(base, mc::BorrowedPtr(..)) => {
                 if !self.try_adjust_upvar_deref(cmt, ty::MutBorrow) {
                     // assignment to deref of an `&mut`
                     // borrowed pointer implies that the
@@ -422,8 +420,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
                 self.adjust_upvar_borrow_kind_for_unique(base);
             }
 
-            Categorization::Deref(base, mc::BorrowedPtr(..)) |
-            Categorization::Deref(base, mc::Implicit(..)) => {
+            Categorization::Deref(base, mc::BorrowedPtr(..)) => {
                 if !self.try_adjust_upvar_deref(cmt, ty::UniqueImmBorrow) {
                     // for a borrowed pointer to be unique, its
                     // base must be unique
@@ -481,7 +478,7 @@ impl<'a, 'gcx, 'tcx> InferBorrowKind<'a, 'gcx, 'tcx> {
 
                 true
             }
-            mc::NoteNone => false,
+            mc::NoteIndex | mc::NoteNone => false,
         }
     }
 
diff --git a/src/test/ui/borrowck/issue-51117.rs b/src/test/ui/borrowck/issue-51117.rs
new file mode 100644 (file)
index 0000000..0a1e672
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 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.
+
+// Regression test for #51117 in borrowck interaction with match
+// default bindings. The borrow of `*bar` created by `baz` was failing
+// to register as a conflict with `bar.take()`.
+
+fn main() {
+    let mut foo = Some("foo".to_string());
+    let bar = &mut foo;
+    match bar {
+        Some(baz) => {
+            bar.take(); //~ ERROR cannot borrow
+            drop(baz);
+        },
+        None => unreachable!(),
+    }
+}
diff --git a/src/test/ui/borrowck/issue-51117.stderr b/src/test/ui/borrowck/issue-51117.stderr
new file mode 100644 (file)
index 0000000..cb434f9
--- /dev/null
@@ -0,0 +1,14 @@
+error[E0499]: cannot borrow `*bar` as mutable more than once at a time
+  --> $DIR/issue-51117.rs:20:13
+   |
+LL |         Some(baz) => {
+   |              --- first mutable borrow occurs here
+LL |             bar.take(); //~ ERROR cannot borrow
+   |             ^^^ second mutable borrow occurs here
+...
+LL |     }
+   |     - first borrow ends here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/version b/version
index fdfd6ae4312266523f05bd716a42f8ad5ce4ce72..760a7ee79fe7ea4694c82ca7a9cd6df572b4886b 100644 (file)
--- a/version
+++ b/version
@@ -1 +1 @@
-1.26.1 (827013a31 2018-05-25)
\ No newline at end of file
+1.26.2 (594fb253c 2018-06-01)
\ No newline at end of file