From: Yap Zhi Heng <[email protected]>
Generated GIMPLE for new issue-1133.rs testcase:
...
b = issue_1133::<impl XXX as issue_1133::Index>::index<i32, Range<usize>>
(D.5562, D.5561);
_1 = b.data;
c = MEM[(i32 *)_1 + 4B];
...
gcc/rust/ChangeLog:
* typecheck/rust-hir-type-check-expr.cc (visit(HIR::ArrayIndexExpr)):
Implement type check
support for slice types as well.
* backend/rust-compile-expr.cc (visit(HIR::ArrayIndexExpr)): Implement
intrinsic codegen
support for slice indexing.
gcc/testsuite/ChangeLog:
* rust/execute/torture/issue-1133.rs: Update index impl for SliceIndex
for usize.
* rust/execute/torture/issue-1232.rs: Likewise.
Signed-off-by: Yap Zhi Heng <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/096c89030e1c006f433023574bcf61137a72d82a
The commit has NOT been mentioned in any issue.
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/5045
gcc/rust/backend/rust-compile-expr.cc | 57 +++++++++++++------
.../typecheck/rust-hir-type-check-expr.cc | 26 +++++++--
.../rust/execute/torture/issue-1133.rs | 5 +-
.../rust/execute/torture/issue-1232.rs | 3 +-
4 files changed, 64 insertions(+), 27 deletions(-)
diff --git a/gcc/rust/backend/rust-compile-expr.cc
b/gcc/rust/backend/rust-compile-expr.cc
index 8c8268bc3..9798a9b30 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -2993,7 +2993,7 @@ CompileExpr::visit (HIR::RangeFullExpr &expr)
void
CompileExpr::visit (HIR::ArrayIndexExpr &expr)
{
- tree array_reference = CompileExpr::Compile (expr.get_array_expr (), ctx);
+ tree reference = CompileExpr::Compile (expr.get_array_expr (), ctx);
tree index = CompileExpr::Compile (expr.get_index_expr (), ctx);
// this might be an core::ops::index lang item situation
@@ -3004,8 +3004,8 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
{
auto lang_item_type = LangItem::Kind::INDEX;
tree operator_overload_call
- = resolve_operator_overload (lang_item_type, expr, array_reference,
- index, expr.get_array_expr (),
+ = resolve_operator_overload (lang_item_type, expr, reference, index,
+ expr.get_array_expr (),
expr.get_index_expr ());
tree actual_type = TREE_TYPE (operator_overload_call);
@@ -3024,29 +3024,52 @@ CompileExpr::visit (HIR::ArrayIndexExpr &expr)
return;
}
- // lets check if the array is a reference type then we can add an
+ // lets check if the array/slice is a reference type then we can add an
// indirection if required
- TyTy::BaseType *array_expr_ty = nullptr;
+ TyTy::BaseType *base_ty = nullptr;
bool ok = ctx->get_tyctx ()->lookup_type (
- expr.get_array_expr ().get_mappings ().get_hirid (), &array_expr_ty);
+ expr.get_array_expr ().get_mappings ().get_hirid (), &base_ty);
rust_assert (ok);
-
// do we need to add an indirect reference
- if (array_expr_ty->get_kind () == TyTy::TypeKind::REF)
+ if (base_ty->get_kind () == TyTy::TypeKind::REF)
{
- array_reference
- = indirect_expression (array_reference, expr.get_locus ());
+ auto ref = static_cast<TyTy::ReferenceType *> (base_ty);
+ base_ty = ref->get_base ();
+
+ if (base_ty->get_kind () == TyTy::TypeKind::ARRAY)
+ {
+ // only array box is further deferenced to the underlying array
+ // slice always uses fat ptr, which is handled in
+ // slice_index_expression
+ reference = indirect_expression (reference, expr.get_locus ());
+ }
}
- else if (TyTy::try_get_box_inner_type (array_expr_ty))
+ else if (auto inner = TyTy::try_get_box_inner_type (base_ty))
{
- array_reference
- = build_box_inner_ptr (array_reference, expr.get_locus ());
- array_reference
- = indirect_expression (array_reference, expr.get_locus ());
+ base_ty = *inner;
+ reference = build_box_inner_ptr (reference, expr.get_locus ());
+
+ if (base_ty->get_kind () == TyTy::TypeKind::ARRAY)
+ {
+ // only array box is further deferenced to the underlying array
+ // slice always uses fat ptr, which is handled in
+ // slice_index_expression
+ reference = indirect_expression (reference, expr.get_locus ());
+ }
}
- translated = Backend::array_index_expression (array_reference, index,
- expr.get_locus ());
+ if (base_ty->get_kind () == TyTy::TypeKind::ARRAY)
+ {
+ translated
+ = Backend::array_index_expression (reference, index, expr.get_locus ());
+ }
+ else
+ {
+ // it must be a slice here
+ rust_assert (base_ty->get_kind () == TyTy::TypeKind::SLICE);
+ translated
+ = Backend::slice_index_expression (reference, index, expr.get_locus ());
+ }
}
void
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 44487f532..b7acb787f 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1097,7 +1097,8 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
// lets try and deref it since rust allows this
auto ref = static_cast<TyTy::ReferenceType *> (direct_array_expr_ty);
auto base = ref->get_base ();
- if (base->get_kind () == TyTy::TypeKind::ARRAY)
+ if (base->get_kind () == TyTy::TypeKind::ARRAY
+ || base->get_kind () == TyTy::TypeKind::SLICE)
direct_array_expr_ty = base;
}
// Box<T> autoderef
@@ -1114,8 +1115,11 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
= types_compatable (TyTy::TyWithLocation (index_expr_ty),
TyTy::TyWithLocation (size_ty), expr.get_locus (),
false);
+
+ auto base_kind = direct_array_expr_ty->get_kind ();
if (maybe_simple_array_access
- && direct_array_expr_ty->get_kind () == TyTy::TypeKind::ARRAY)
+ && (base_kind == TyTy::TypeKind::ARRAY
+ || base_kind == TyTy::TypeKind::SLICE))
{
unify_site (expr.get_index_expr ().get_mappings ().get_hirid (),
TyTy::TyWithLocation (size_ty),
@@ -1123,9 +1127,21 @@ TypeCheckExpr::visit (HIR::ArrayIndexExpr &expr)
expr.get_index_expr ().get_locus ()),
expr.get_locus ());
- TyTy::ArrayType *array_type
- = static_cast<TyTy::ArrayType *> (direct_array_expr_ty);
- infered = array_type->get_element_type ()->clone ();
+ if (base_kind == TyTy::TypeKind::ARRAY)
+ {
+ TyTy::ArrayType *array_type
+ = static_cast<TyTy::ArrayType *> (direct_array_expr_ty);
+ infered = array_type->get_element_type ()->clone ();
+ }
+ else
+ {
+ // is slice type instead
+ rust_assert (base_kind == TyTy::TypeKind::SLICE);
+ TyTy::SliceType *slice_type
+ = static_cast<TyTy::SliceType *> (direct_array_expr_ty);
+ infered = slice_type->get_element_type ()->clone ();
+ }
+
return;
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs
b/gcc/testsuite/rust/execute/torture/issue-1133.rs
index 5363e1c86..fc744d127 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1133.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs
@@ -102,8 +102,7 @@ unsafe impl<T> SliceIndex<[T]> for usize {
fn index(self, slice: &[T]) -> &T {
// N.B., use intrinsic indexing
- // &(*slice)[self]
- unsafe { &*self.get_unchecked(slice) }
+ &(*slice)[self]
}
}
@@ -149,5 +148,5 @@ fn main() -> i32 {
let b = &a[1..3];
let c = b[1];
- 0
+ c - 3
}
diff --git a/gcc/testsuite/rust/execute/torture/issue-1232.rs
b/gcc/testsuite/rust/execute/torture/issue-1232.rs
index 5bb867972..fb0e6fd43 100644
--- a/gcc/testsuite/rust/execute/torture/issue-1232.rs
+++ b/gcc/testsuite/rust/execute/torture/issue-1232.rs
@@ -107,8 +107,7 @@ unsafe impl<T> SliceIndex<[T]> for usize {
fn index(self, slice: &[T]) -> &T {
// N.B., use intrinsic indexing
- // &(*slice)[self]
- unsafe { &*self.get_unchecked(slice) }
+ &(*slice)[self]
}
}
--
2.56.0