diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs index 3cfa1d6797d1f098dd4ce6cc46fd5154e923a5a8..3577feaf90c1abb2b7a1040f6c61aa8b131f55bc 100644 --- a/src/librustc_const_eval/pattern.rs +++ b/src/librustc_const_eval/pattern.rs @@ -92,7 +92,9 @@ pub enum PatternKind<'tcx> { end: RangeEnd, }, - /// matches against a slice, checking the length and extracting elements + /// matches against a slice, checking the length and extracting elements. + /// irrefutable when there is a slice pattern and both `prefix` and `suffix` are empty. + /// e.g. `&[ref xs..]`. Slice { prefix: Vec>, slice: Option>, diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index 4ae373c7c8223c15e0edb37edf51d4fd7a984edd..b16d7ed236509e9eeaa6a48f2f3b9f6d88cc8b1f 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -92,11 +92,24 @@ fn simplify_match_pair<'pat>(&mut self, Err(match_pair) } - PatternKind::Range { .. } | - PatternKind::Slice { .. } => { + PatternKind::Range { .. } => { Err(match_pair) } + PatternKind::Slice { ref prefix, ref slice, ref suffix } => { + if prefix.is_empty() && slice.is_some() && suffix.is_empty() { + // irrefutable + self.prefix_slice_suffix(&mut candidate.match_pairs, + &match_pair.place, + prefix, + slice.as_ref(), + suffix); + Ok(()) + } else { + Err(match_pair) + } + } + PatternKind::Variant { adt_def, substs, variant_index, ref subpatterns } => { let irrefutable = adt_def.variants.iter().enumerate().all(|(i, v)| { i == variant_index || { diff --git a/src/test/run-pass/irrefutable-slice-patterns.rs b/src/test/run-pass/irrefutable-slice-patterns.rs new file mode 100644 index 0000000000000000000000000000000000000000..c2e95eb54f9012f8611418b56060a7a2ed576379 --- /dev/null +++ b/src/test/run-pass/irrefutable-slice-patterns.rs @@ -0,0 +1,24 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// #47096 + +#![feature(slice_patterns)] + +fn foo(s: &[i32]) -> &[i32] { + let &[ref xs..] = s; + xs +} + +fn main() { + let x = [1, 2, 3]; + let y = foo(&x); + assert_eq!(x, y); +}