From 31f66a060ce5e0533c35768a5460fcfde3d600d5 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 22 Feb 2018 19:47:03 -0500 Subject: [PATCH] reset default binding mode when we pass through a `&` pattern Fixes #46688. --- src/librustc_typeck/check/_match.rs | 13 ++++++++++ .../reset-mode.rs | 25 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/test/run-pass/rfc-2005-default-binding-mode/reset-mode.rs diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index bf253a88d27c2..427641aaf0951 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 0000000000000..f980ef0ccddda --- /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 or the MIT license +// , 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); +}