about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-02-22 19:47:03 -0500
committerNiko Matsakis <niko@alum.mit.edu>2018-02-22 19:47:03 -0500
commit31f66a060ce5e0533c35768a5460fcfde3d600d5 (patch)
treee3bfb88422b8cefd313b04c9ce94c27dc36b1c2d
parentb1f8e6fb06d7362eeb2065347a7db94e76b1cb2f (diff)
downloadrust-31f66a060ce5e0533c35768a5460fcfde3d600d5.tar.gz
rust-31f66a060ce5e0533c35768a5460fcfde3d600d5.zip
reset default binding mode when we pass through a `&` pattern
Fixes #46688.
-rw-r--r--src/librustc_typeck/check/_match.rs13
-rw-r--r--src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs25
2 files changed, 38 insertions, 0 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index bf253a88d27..427641aaf09 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -151,6 +151,19 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     err.emit();
                 }
             }
+        } else if let PatKind::Ref(..) = pat.node {
+            // When you encounter a `&pat` pattern, reset to "by
+            // value". This is so that `x` and `y` here are by value,
+            // as they appear to be:
+            //
+            // ```
+            // match &(&22, &44) {
+            //   (&x, &y) => ...
+            // }
+            // ```
+            //
+            // cc #46688
+            def_bm = ty::BindByValue(hir::MutImmutable);
         }
 
         // Lose mutability now that we know binding mode and discriminant type.
diff --git a/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs
new file mode 100644
index 00000000000..f980ef0ccdd
--- /dev/null
+++ b/src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs
@@ -0,0 +1,25 @@
+// Copyright 2017 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.
+
+#![feature(match_default_bindings)]
+
+// Test that we "reset" the mode as we pass through a `&` pattern.
+//
+// cc #46688
+
+fn surprise(x: i32) {
+    assert_eq!(x, 2);
+}
+
+fn main() {
+    let x = &(1, &2);
+    let (_, &b) = x;
+    surprise(b);
+}