about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-25 11:36:13 +0000
committerbors <bors@rust-lang.org>2018-06-25 11:36:13 +0000
commitecfe37056fa2abc79a4b97ff1c651fae47f66845 (patch)
tree60283817562185e9feb4db4448003e81618c8f07 /src
parent446aef691e7223f31b18236fb9bf2d08bc25ba46 (diff)
parente14e48bfaa36bda05a467dca0743dab5b10de097 (diff)
downloadrust-ecfe37056fa2abc79a4b97ff1c651fae47f66845.tar.gz
rust-ecfe37056fa2abc79a4b97ff1c651fae47f66845.zip
Auto merge of #51733 - varkor:ice-match-slice, r=oli-obk
Fix an ICE when matching over const slices

Fixes #51655. I'm not super familiar with this code, so tell me if this is the wrong approach 😅

r? @oli-obk
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/hair/pattern/_match.rs13
-rw-r--r--src/test/run-pass/issue-51655.rs23
2 files changed, 32 insertions, 4 deletions
diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index a7b2e205d00..41024e60202 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -25,6 +25,7 @@ use rustc::hir::RangeEnd;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
 
 use rustc::mir::Field;
+use rustc::mir::interpret::ConstValue;
 use rustc::util::common::ErrorReported;
 
 use syntax_pos::{Span, DUMMY_SP};
@@ -932,16 +933,20 @@ fn slice_pat_covered_by_constructor<'tcx>(
     suffix: &[Pattern<'tcx>]
 ) -> Result<bool, ErrorReported> {
     let data: &[u8] = match *ctor {
-        ConstantValue(const_val @ &ty::Const { val: ConstVal::Value(..), .. }) => {
-            if let Some(ptr) = const_val.to_ptr() {
-                let is_array_ptr = const_val.ty
+        ConstantValue(&ty::Const { val: ConstVal::Value(const_val), ty }) => {
+            let val = match const_val {
+                ConstValue::ByRef(..) => bug!("unexpected ConstValue::ByRef"),
+                ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val,
+            };
+            if let Ok(ptr) = val.to_ptr() {
+                let is_array_ptr = ty
                     .builtin_deref(true)
                     .and_then(|t| t.ty.builtin_index())
                     .map_or(false, |t| t == tcx.types.u8);
                 assert!(is_array_ptr);
                 tcx.alloc_map.lock().unwrap_memory(ptr.alloc_id).bytes.as_ref()
             } else {
-                bug!()
+                bug!("unexpected non-ptr ConstantValue")
             }
         }
         _ => bug!()
diff --git a/src/test/run-pass/issue-51655.rs b/src/test/run-pass/issue-51655.rs
new file mode 100644
index 00000000000..b5b89ede91b
--- /dev/null
+++ b/src/test/run-pass/issue-51655.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+#![allow(dead_code)]
+
+const PATH_DOT: &[u8] = &[b'.'];
+
+fn match_slice(element: &[u8]) {
+    match element {
+        &[] => {}
+        PATH_DOT => {}
+        _ => {}
+    }
+}
+
+fn main() {}