diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index b2357b771572f..bdcbfc0bdd85e 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -174,12 +174,50 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         }
     }
 
+    /// Convert a byte array or byte slice to a byte slice.
+    fn to_slice_operand(&mut self,
+                        block: BasicBlock,
+                        source_info: SourceInfo,
+                        operand: Operand<'tcx>)
+                        -> Operand<'tcx>
+    {
+        let tcx = self.hir.tcx();
+        let ty = operand.ty(&self.local_decls, tcx);
+        debug!("to_slice_operand({:?}, {:?}: {:?})", block, operand, ty);
+        match ty.sty {
+            ty::TyRef(region, mt) => match mt.ty.sty {
+                ty::TyArray(ety, _) => {
+                    let ty = tcx.mk_imm_ref(region, tcx.mk_slice(ety));
+                    let temp = self.temp(ty, source_info.span);
+                    self.cfg.push_assign(block, source_info, &temp,
+                                         Rvalue::Cast(CastKind::Unsize, operand, ty));
+                    Operand::Move(temp)
+                }
+                ty::TySlice(_) => operand,
+                _ => {
+                    span_bug!(source_info.span,
+                              "bad operand {:?}: {:?} to `to_slice_operand`", operand, ty)
+                }
+            }
+            _ => {
+                span_bug!(source_info.span,
+                          "bad operand {:?}: {:?} to `to_slice_operand`", operand, ty)
+            }
+        }
+
+    }
+
     /// Generates the code to perform a test.
     pub fn perform_test(&mut self,
                         block: BasicBlock,
                         place: &Place<'tcx>,
                         test: &Test<'tcx>)
                         -> Vec<BasicBlock> {
+        debug!("perform_test({:?}, {:?}: {:?}, {:?})",
+               block,
+               place,
+               place.ty(&self.local_decls, self.hir.tcx()),
+               test);
         let source_info = self.source_info(test.span);
         match test.kind {
             TestKind::Switch { adt_def, ref variants } => {
@@ -258,45 +296,35 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 ret
             }
 
-            TestKind::Eq { value, mut ty } => {
+            TestKind::Eq { value, ty } => {
+                let tcx = self.hir.tcx();
                 let mut val = Operand::Copy(place.clone());
 
                 // If we're using b"..." as a pattern, we need to insert an
                 // unsizing coercion, as the byte string has the type &[u8; N].
-                let expect = if let ConstVal::ByteStr(bytes) = value.val {
-                    let tcx = self.hir.tcx();
-
-                    // Unsize the place to &[u8], too, if necessary.
-                    if let ty::TyRef(region, mt) = ty.sty {
-                        if let ty::TyArray(_, _) = mt.ty.sty {
-                            ty = tcx.mk_imm_ref(region, tcx.mk_slice(tcx.types.u8));
-                            let val_slice = self.temp(ty, test.span);
-                            self.cfg.push_assign(block, source_info, &val_slice,
-                                                 Rvalue::Cast(CastKind::Unsize, val, ty));
-                            val = Operand::Move(val_slice);
-                        }
-                    }
-
-                    assert!(ty.is_slice());
-
+                //
+                // We want to do this even when the scrutinee is a reference to an
+                // array, so we can call `<[u8]>::eq` rather than having to find an
+                // `<[u8; N]>::eq`.
+                let (expect, val) = if let ConstVal::ByteStr(bytes) = value.val {
                     let array_ty = tcx.mk_array(tcx.types.u8, bytes.data.len() as u64);
                     let array_ref = tcx.mk_imm_ref(tcx.types.re_static, array_ty);
                     let array = self.literal_operand(test.span, array_ref, Literal::Value {
                         value
                     });
 
-                    let slice = self.temp(ty, test.span);
-                    self.cfg.push_assign(block, source_info, &slice,
-                                         Rvalue::Cast(CastKind::Unsize, array, ty));
-                    Operand::Move(slice)
+                    let val = self.to_slice_operand(block, source_info, val);
+                    let slice = self.to_slice_operand(block, source_info, array);
+                    (slice, val)
                 } else {
-                    self.literal_operand(test.span, ty, Literal::Value {
+                    (self.literal_operand(test.span, ty, Literal::Value {
                         value
-                    })
+                    }), val)
                 };
 
                 // Use PartialEq::eq for &str and &[u8] slices, instead of BinOp::Eq.
                 let fail = self.cfg.start_new_block();
+                let ty = expect.ty(&self.local_decls, tcx);
                 if let ty::TyRef(_, mt) = ty.sty {
                     assert!(ty.is_slice());
                     let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
diff --git a/src/test/run-pass/issue-46920-byte-array-patterns.rs b/src/test/run-pass/issue-46920-byte-array-patterns.rs
new file mode 100644
index 0000000000000..236f6995c51b8
--- /dev/null
+++ b/src/test/run-pass/issue-46920-byte-array-patterns.rs
@@ -0,0 +1,37 @@
+// 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.
+
+const CURSOR_PARTITION_LABEL: &'static [u8] = b"partition";
+const CURSOR_EVENT_TYPE_LABEL: &'static [u8] = b"event_type";
+const BYTE_PATTERN: &'static [u8; 5] = b"hello";
+
+fn match_slice(x: &[u8]) -> u32 {
+    match x {
+        CURSOR_PARTITION_LABEL => 0,
+        CURSOR_EVENT_TYPE_LABEL => 1,
+        _ => 2,
+    }
+}
+
+fn match_array(x: &[u8; 5]) -> bool {
+    match x {
+        BYTE_PATTERN => true,
+        _ => false
+    }
+}
+
+fn main() {
+    assert_eq!(match_slice(b"abcde"), 2);
+    assert_eq!(match_slice(b"event_type"), 1);
+    assert_eq!(match_slice(b"partition"), 0);
+
+    assert_eq!(match_array(b"hello"), true);
+    assert_eq!(match_array(b"hella"), false);
+}