From e80e577df7ca410eac549da61f9a9fd702dc55ea Mon Sep 17 00:00:00 2001 From: Yap Zhi Heng Date: Wed, 23 Jul 2025 08:24:18 +0800 Subject: gccrs: Implement compilation for SlicePattern against SliceType scrutinee 006t.original output from compiling testsuite/rust/compile/match-slicepattern-slice.rs: ... RUSTTMP.3 = slice; if (RUSTTMP.3.len == 1 && *(RUSTTMP.3.data + 0 * 4) == 1) { { struct () RUSTTMP.4; { } goto ; } } if (RUSTTMP.3.len == 2 && *(RUSTTMP.3.data + 1 * 4) == 2) { { struct () RUSTTMP.5; { } goto ; } } if (1) { { struct () RUSTTMP.6; { } goto ; } } :; ... gcc/rust/ChangeLog: * rust-backend.h: New slice_index_expression function. * rust-gcc.cc: Implementation of slice_index_expression to generate tree node for accessing slice elements. * backend/rust-compile-pattern.cc: Implement SlicePattern check expression & binding compilation against SliceType scrutinee. Signed-off-by: Yap Zhi Heng --- gcc/rust/rust-gcc.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'gcc/rust/rust-gcc.cc') diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index c5fda5c..0f9ccfb 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -1504,6 +1504,34 @@ array_index_expression (tree array_tree, tree index_tree, location_t location) return ret; } +// Return an expression representing SLICE[INDEX] + +tree +slice_index_expression (tree slice_tree, tree index_tree, location_t location) +{ + if (error_operand_p (slice_tree) || error_operand_p (index_tree)) + return error_mark_node; + + // A slice is created in TyTyResolvecompile::create_slice_type_record + // For example: + // &[i32] is turned directly into a struct { i32* data, usize len }; + // [i32] is also turned into struct { i32* data, usize len } + + // it should have RS_DST_FLAG set to 1 + rust_assert (RS_DST_FLAG_P (TREE_TYPE (slice_tree))); + + tree data_field = struct_field_expression (slice_tree, 0, location); + tree data_field_deref = build_fold_indirect_ref_loc (location, data_field); + + tree element_type = TREE_TYPE (data_field_deref); + tree data_pointer = TREE_OPERAND (data_field_deref, 0); + rust_assert (POINTER_TYPE_P (TREE_TYPE (data_pointer))); + tree data_offset_expr + = Rust::pointer_offset_expression (data_pointer, index_tree, location); + + return build1_loc (location, INDIRECT_REF, element_type, data_offset_expr); +} + // Create an expression for a call to FN_EXPR with FN_ARGS. tree call_expression (tree fn, const std::vector &fn_args, tree chain_expr, -- cgit v1.1