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]>

Tested on x86_64-pc-linux-gnu.

---
 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 8c8268bc31e..9798a9b309c 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 44487f53267..b7acb787fc6 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 5363e1c860f..fc744d12748 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 5bb86797226..fb0e6fd4321 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.55.0

Reply via email to