From 2a082209a68703915ffe10c913d30f274bf76fa7 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 11 Jan 2020 14:15:24 +0100 Subject: [PATCH] Fix PlaceElem::Subslice length computation --- example/subslice-patterns-const-eval.rs | 99 +++++++++++++++++++++++++ src/base.rs | 2 +- test.sh | 4 + 3 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 example/subslice-patterns-const-eval.rs diff --git a/example/subslice-patterns-const-eval.rs b/example/subslice-patterns-const-eval.rs new file mode 100644 index 00000000000..ec3614bb34a --- /dev/null +++ b/example/subslice-patterns-const-eval.rs @@ -0,0 +1,99 @@ +// Based on https://github.com/rust-lang/rust/blob/c5840f9d252c2f5cc16698dbf385a29c5de3ca07/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs + +// Test that array subslice patterns are correctly handled in const evaluation. + +// run-pass + +#![feature(slice_patterns)] + +#[derive(PartialEq, Debug, Clone)] +struct N(u8); + +#[derive(PartialEq, Debug, Clone)] +struct Z; + +macro_rules! n { + ($($e:expr),* $(,)?) => { + [$(N($e)),*] + } +} + +// This macro has an unused variable so that it can be repeated base on the +// number of times a repeated variable (`$e` in `z`) occurs. +macro_rules! zed { + ($e:expr) => { Z } +} + +macro_rules! z { + ($($e:expr),* $(,)?) => { + [$(zed!($e)),*] + } +} + +// Compare constant evaluation and runtime evaluation of a given expression. +macro_rules! compare_evaluation { + ($e:expr, $t:ty $(,)?) => {{ + const CONST_EVAL: $t = $e; + const fn const_eval() -> $t { $e } + static CONST_EVAL2: $t = const_eval(); + let runtime_eval = $e; + assert_eq!(CONST_EVAL, runtime_eval); + assert_eq!(CONST_EVAL2, runtime_eval); + }} +} + +// Repeat `$test`, substituting the given macro variables with the given +// identifiers. +// +// For example: +// +// repeat! { +// ($name); X; Y: +// struct $name; +// } +// +// Expands to: +// +// struct X; struct Y; +// +// This is used to repeat the tests using both the `N` and `Z` +// types. +macro_rules! repeat { + (($($dollar:tt $placeholder:ident)*); $($($values:ident),+);*: $($test:tt)*) => { + macro_rules! single { + ($($dollar $placeholder:ident),*) => { $($test)* } + } + $(single!($($values),+);)* + } +} + +fn main() { + repeat! { + ($arr $Ty); n, N; z, Z: + compare_evaluation!({ let [_, x @ .., _] = $arr!(1, 2, 3, 4); x }, [$Ty; 2]); + compare_evaluation!({ let [_, ref x @ .., _] = $arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]); + compare_evaluation!({ let [_, x @ .., _] = &$arr!(1, 2, 3, 4); x }, &'static [$Ty; 2]); + + compare_evaluation!({ let [_, _, x @ .., _, _] = $arr!(1, 2, 3, 4); x }, [$Ty; 0]); + compare_evaluation!( + { let [_, _, ref x @ .., _, _] = $arr!(1, 2, 3, 4); x }, + &'static [$Ty; 0], + ); + compare_evaluation!( + { let [_, _, x @ .., _, _] = &$arr!(1, 2, 3, 4); x }, + &'static [$Ty; 0], + ); + + compare_evaluation!({ let [_, .., x] = $arr!(1, 2, 3, 4); x }, $Ty); + compare_evaluation!({ let [_, .., ref x] = $arr!(1, 2, 3, 4); x }, &'static $Ty); + compare_evaluation!({ let [_, _y @ .., x] = &$arr!(1, 2, 3, 4); x }, &'static $Ty); + } + + compare_evaluation!({ let [_, .., N(x)] = n!(1, 2, 3, 4); x }, u8); + compare_evaluation!({ let [_, .., N(ref x)] = n!(1, 2, 3, 4); x }, &'static u8); + compare_evaluation!({ let [_, .., N(x)] = &n!(1, 2, 3, 4); x }, &'static u8); + + compare_evaluation!({ let [N(x), .., _] = n!(1, 2, 3, 4); x }, u8); + compare_evaluation!({ let [N(ref x), .., _] = n!(1, 2, 3, 4); x }, &'static u8); + compare_evaluation!({ let [N(x), .., _] = &n!(1, 2, 3, 4); x }, &'static u8); +} diff --git a/src/base.rs b/src/base.rs index 4d1d5df8a89..663e312a424 100644 --- a/src/base.rs +++ b/src/base.rs @@ -688,7 +688,7 @@ pub fn trans_place<'tcx>( .eval_usize(fx.tcx, ParamEnv::reveal_all()); cplace = CPlace::for_ptr( ptr.offset_i64(fx, elem_layout.size.bytes() as i64 * from as i64), - fx.layout_of(fx.tcx.mk_array(elem_ty, len - from as u64 - to as u64)), + fx.layout_of(fx.tcx.mk_array(elem_ty, to as u64 - from as u64)), ); } ty::Slice(elem_ty) => { diff --git a/test.sh b/test.sh index 2990a9c03eb..d73badad957 100755 --- a/test.sh +++ b/test.sh @@ -60,6 +60,10 @@ echo "[AOT] std_example" $RUSTC example/std_example.rs --crate-type bin ./target/out/std_example +echo "[AOT] subslice-patterns-const-eval" +$RUSTC example/subslice-patterns-const-eval.rs --crate-type bin -Cpanic=abort +./target/out/subslice-patterns-const-eval + echo "[BUILD] mod_bench" $RUSTC example/mod_bench.rs --crate-type bin