public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add new monomorphize_clone interface
@ 2022-06-08 12:44 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 12:44 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:cb4d935508def8b250345ba5205a90ad9e177ab4

commit cb4d935508def8b250345ba5205a90ad9e177ab4
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Fri May 6 13:12:41 2022 +0100

    Add new monomorphize_clone interface
    
    This interface is required when we monomorphize since types might be
    
     placeholder -> projection -> param -> actual-type
    
    This gives us a clean clone interface to destructure this into its actual
    type. This is important so for example if we have a generic trait function
    and resolve the function for a specific set of generics we update the
    associated types. This works, then when we go to subsitute the same
    generic trait again the placeholders are again updated throwing off the
    typing for the first type.
    
    Fixes #1133

Diff:
---
 gcc/rust/typecheck/rust-hir-type-check-expr.cc   |   3 +-
 gcc/rust/typecheck/rust-tyty.cc                  | 235 ++++++++++++++++++++++-
 gcc/rust/typecheck/rust-tyty.h                   |  43 +++++
 gcc/testsuite/rust/execute/torture/issue-1133.rs | 146 ++++++++++++++
 4 files changed, 417 insertions(+), 10 deletions(-)

diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index a3d911efd79..c499204a40c 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -469,7 +469,8 @@ TypeCheckExpr::resolve_operator_overload (
   fn->monomorphize ();
 
   // get the return type
-  TyTy::BaseType *function_ret_tyty = type->get_return_type ()->clone ();
+  TyTy::BaseType *function_ret_tyty
+    = type->get_return_type ()->monomorphized_clone ();
 
   // store the expected fntype
   context->insert_operator_overload (expr.get_mappings ().get_hirid (), type);
diff --git a/gcc/rust/typecheck/rust-tyty.cc b/gcc/rust/typecheck/rust-tyty.cc
index fcbf9986d7d..e2dacc9c42d 100644
--- a/gcc/rust/typecheck/rust-tyty.cc
+++ b/gcc/rust/typecheck/rust-tyty.cc
@@ -284,6 +284,32 @@ TyVar::subst_covariant_var (TyTy::BaseType *orig, TyTy::BaseType *subst)
   return TyVar (subst->get_ref ());
 }
 
+TyVar
+TyVar::clone () const
+{
+  TyTy::BaseType *c = get_tyty ()->clone ();
+  return TyVar (c->get_ref ());
+}
+
+TyVar
+TyVar::monomorphized_clone () const
+{
+  auto mappings = Analysis::Mappings::get ();
+  auto context = Resolver::TypeCheckContext::get ();
+
+  // this needs a new hirid
+  TyTy::BaseType *c = get_tyty ()->monomorphized_clone ();
+  c->set_ref (mappings->get_next_hir_id ());
+
+  // insert it
+  context->insert_type (Analysis::NodeMapping (mappings->get_current_crate (),
+					       UNKNOWN_NODEID, c->get_ref (),
+					       UNKNOWN_LOCAL_DEFID),
+			c);
+
+  return TyVar (c->get_ref ());
+}
+
 void
 InferType::accept_vis (TyVisitor &vis)
 {
@@ -372,6 +398,12 @@ InferType::clone () const
   return clone;
 }
 
+BaseType *
+InferType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 bool
 InferType::default_type (BaseType **type) const
 {
@@ -445,6 +477,12 @@ ErrorType::clone () const
   return new ErrorType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+ErrorType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 std::string
 StructFieldType::as_string () const
 {
@@ -475,6 +513,13 @@ StructFieldType::clone () const
 			      get_field_type ()->clone ());
 }
 
+StructFieldType *
+StructFieldType::monomorphized_clone () const
+{
+  return new StructFieldType (get_ref (), get_name (),
+			      get_field_type ()->monomorphized_clone ());
+}
+
 bool
 SubstitutionParamMapping::need_substitution () const
 {
@@ -965,6 +1010,19 @@ ADTType::clone () const
 		      get_combined_refs ());
 }
 
+BaseType *
+ADTType::monomorphized_clone () const
+{
+  std::vector<VariantDef *> cloned_variants;
+  for (auto &variant : variants)
+    cloned_variants.push_back (variant->monomorphized_clone ());
+
+  return new ADTType (get_ref (), get_ty_ref (), identifier, ident,
+		      get_adt_kind (), cloned_variants, clone_substs (),
+		      get_repr_options (), used_arguments,
+		      get_combined_refs ());
+}
+
 static bool
 handle_substitions (SubstitutionArgumentMappings &subst_mappings,
 		    StructFieldType *field)
@@ -1127,8 +1185,23 @@ TupleType::is_equal (const BaseType &other) const
 BaseType *
 TupleType::clone () const
 {
-  return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus, fields,
-			get_combined_refs ());
+  std::vector<TyVar> cloned_fields;
+  for (const auto &f : fields)
+    cloned_fields.push_back (f.clone ());
+
+  return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus,
+			cloned_fields, get_combined_refs ());
+}
+
+BaseType *
+TupleType::monomorphized_clone () const
+{
+  std::vector<TyVar> cloned_fields;
+  for (const auto &f : fields)
+    cloned_fields.push_back (f.monomorphized_clone ());
+
+  return new TupleType (get_ref (), get_ty_ref (), get_ident ().locus,
+			cloned_fields, get_combined_refs ());
 }
 
 TupleType *
@@ -1265,8 +1338,20 @@ FnType::clone () const
 {
   std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
   for (auto &p : params)
-    cloned_params.push_back (
-      std::pair<HIR::Pattern *, BaseType *> (p.first, p.second->clone ()));
+    cloned_params.push_back ({p.first, p.second->clone ()});
+
+  return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
+		     ident, flags, abi, std::move (cloned_params),
+		     get_return_type ()->clone (), clone_substs (),
+		     get_combined_refs ());
+}
+
+BaseType *
+FnType::monomorphized_clone () const
+{
+  std::vector<std::pair<HIR::Pattern *, BaseType *>> cloned_params;
+  for (auto &p : params)
+    cloned_params.push_back ({p.first, p.second->monomorphized_clone ()});
 
   return new FnType (get_ref (), get_ty_ref (), get_id (), get_identifier (),
 		     ident, flags, abi, std::move (cloned_params),
@@ -1480,6 +1565,18 @@ FnPtr::clone () const
 		    get_combined_refs ());
 }
 
+BaseType *
+FnPtr::monomorphized_clone () const
+{
+  std::vector<TyVar> cloned_params;
+  for (auto &p : params)
+    cloned_params.push_back (p.monomorphized_clone ());
+
+  return new FnPtr (get_ref (), get_ty_ref (), ident.locus,
+		    std::move (cloned_params), result_type,
+		    get_combined_refs ());
+}
+
 void
 ClosureType::accept_vis (TyVisitor &vis)
 {
@@ -1540,6 +1637,12 @@ ClosureType::clone () const
 			  result_type, clone_substs (), get_combined_refs ());
 }
 
+BaseType *
+ClosureType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 ClosureType *
 ClosureType::handle_substitions (SubstitutionArgumentMappings mappings)
 {
@@ -1620,6 +1723,14 @@ ArrayType::clone () const
 			element_type, get_combined_refs ());
 }
 
+BaseType *
+ArrayType::monomorphized_clone () const
+{
+  return new ArrayType (get_ref (), get_ty_ref (), ident.locus, capacity_expr,
+			element_type.monomorphized_clone (),
+			get_combined_refs ());
+}
+
 ArrayType *
 ArrayType::handle_substitions (SubstitutionArgumentMappings mappings)
 {
@@ -1705,7 +1816,15 @@ SliceType::get_element_type () const
 BaseType *
 SliceType::clone () const
 {
-  return new SliceType (get_ref (), get_ty_ref (), ident.locus, element_type,
+  return new SliceType (get_ref (), get_ty_ref (), ident.locus,
+			element_type.clone (), get_combined_refs ());
+}
+
+BaseType *
+SliceType::monomorphized_clone () const
+{
+  return new SliceType (get_ref (), get_ty_ref (), ident.locus,
+			element_type.monomorphized_clone (),
 			get_combined_refs ());
 }
 
@@ -1777,6 +1896,12 @@ BoolType::clone () const
   return new BoolType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+BoolType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 void
 IntType::accept_vis (TyVisitor &vis)
 {
@@ -1844,6 +1969,12 @@ IntType::clone () const
 		      get_combined_refs ());
 }
 
+BaseType *
+IntType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 bool
 IntType::is_equal (const BaseType &other) const
 {
@@ -1921,6 +2052,12 @@ UintType::clone () const
 		       get_combined_refs ());
 }
 
+BaseType *
+UintType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 bool
 UintType::is_equal (const BaseType &other) const
 {
@@ -1992,6 +2129,12 @@ FloatType::clone () const
 			get_combined_refs ());
 }
 
+BaseType *
+FloatType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 bool
 FloatType::is_equal (const BaseType &other) const
 {
@@ -2054,6 +2197,12 @@ USizeType::clone () const
   return new USizeType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+USizeType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 void
 ISizeType::accept_vis (TyVisitor &vis)
 {
@@ -2106,6 +2255,12 @@ ISizeType::clone () const
   return new ISizeType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+ISizeType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 void
 CharType::accept_vis (TyVisitor &vis)
 {
@@ -2158,6 +2313,12 @@ CharType::clone () const
   return new CharType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+CharType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 void
 ReferenceType::accept_vis (TyVisitor &vis)
 {
@@ -2228,6 +2389,14 @@ ReferenceType::clone () const
 			    get_combined_refs ());
 }
 
+BaseType *
+ReferenceType::monomorphized_clone () const
+{
+  return new ReferenceType (get_ref (), get_ty_ref (),
+			    base.monomorphized_clone (), mutability (),
+			    get_combined_refs ());
+}
+
 ReferenceType *
 ReferenceType::handle_substitions (SubstitutionArgumentMappings mappings)
 {
@@ -2314,6 +2483,14 @@ PointerType::clone () const
 			  get_combined_refs ());
 }
 
+BaseType *
+PointerType::monomorphized_clone () const
+{
+  return new PointerType (get_ref (), get_ty_ref (),
+			  base.monomorphized_clone (), mutability (),
+			  get_combined_refs ());
+}
+
 PointerType *
 PointerType::handle_substitions (SubstitutionArgumentMappings mappings)
 {
@@ -2398,6 +2575,12 @@ ParamType::clone () const
 			param, get_specified_bounds (), get_combined_refs ());
 }
 
+BaseType *
+ParamType::monomorphized_clone () const
+{
+  return resolve ()->clone ();
+}
+
 std::string
 ParamType::get_symbol () const
 {
@@ -2479,6 +2662,12 @@ StrType::clone () const
   return new StrType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+StrType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 void
 StrType::accept_vis (TyVisitor &vis)
 {
@@ -2583,6 +2772,12 @@ NeverType::clone () const
   return new NeverType (get_ref (), get_ty_ref (), get_combined_refs ());
 }
 
+BaseType *
+NeverType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 // placeholder type
 
 void
@@ -2639,6 +2834,15 @@ PlaceholderType::clone () const
 			      get_combined_refs ());
 }
 
+BaseType *
+PlaceholderType::monomorphized_clone () const
+{
+  if (can_resolve ())
+    return resolve ()->monomorphized_clone ();
+
+  return clone ();
+}
+
 void
 PlaceholderType::set_associated_type (HirId ref)
 {
@@ -2734,11 +2938,17 @@ ProjectionType::can_eq (const BaseType *other, bool emit_errors) const
 BaseType *
 ProjectionType::clone () const
 {
-  return new ProjectionType (get_ref (), get_ty_ref (), base, trait, item,
-			     clone_substs (), used_arguments,
+  return new ProjectionType (get_ref (), get_ty_ref (), base->clone (), trait,
+			     item, clone_substs (), used_arguments,
 			     get_combined_refs ());
 }
 
+BaseType *
+ProjectionType::monomorphized_clone () const
+{
+  return get ()->monomorphized_clone ();
+}
+
 ProjectionType *
 ProjectionType::handle_substitions (SubstitutionArgumentMappings subst_mappings)
 {
@@ -2864,6 +3074,12 @@ DynamicObjectType::clone () const
 				specified_bounds, get_combined_refs ());
 }
 
+BaseType *
+DynamicObjectType::monomorphized_clone () const
+{
+  return clone ();
+}
+
 std::string
 DynamicObjectType::get_name () const
 {
@@ -3087,7 +3303,7 @@ TypeCheckCallExpr::visit (FnPtr &type)
       return;
     }
 
-  resolved = type.get_return_type ()->clone ();
+  resolved = type.get_return_type ()->monomorphized_clone ();
 }
 
 // method call checker
@@ -3143,7 +3359,8 @@ TypeCheckMethodCallExpr::visit (FnType &type)
     }
 
   type.monomorphize ();
-  resolved = type.get_return_type ()->clone ();
+
+  resolved = type.get_return_type ()->monomorphized_clone ();
 }
 
 } // namespace TyTy
diff --git a/gcc/rust/typecheck/rust-tyty.h b/gcc/rust/typecheck/rust-tyty.h
index b00237c1c27..c0e432486ad 100644
--- a/gcc/rust/typecheck/rust-tyty.h
+++ b/gcc/rust/typecheck/rust-tyty.h
@@ -212,6 +212,9 @@ public:
    * releasing the memory of the returned ty. */
   virtual BaseType *clone () const = 0;
 
+  // TODO
+  virtual BaseType *monomorphized_clone () const = 0;
+
   // get_combined_refs returns the chain of node refs involved in unification
   std::set<HirId> get_combined_refs () const { return combined; }
 
@@ -293,6 +296,10 @@ public:
 
   BaseType *get_tyty () const;
 
+  TyVar clone () const;
+
+  TyVar monomorphized_clone () const;
+
   static TyVar get_implicit_infer_var (Location locus);
 
   static TyVar subst_covariant_var (TyTy::BaseType *orig,
@@ -339,6 +346,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   InferTypeKind get_infer_kind () const { return infer_kind; }
 
@@ -378,6 +386,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_name () const override final { return as_string (); }
 
@@ -421,6 +430,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_symbol () const;
 
@@ -471,6 +481,8 @@ public:
 
   StructFieldType *clone () const;
 
+  StructFieldType *monomorphized_clone () const;
+
   bool is_concrete () const { return ty->is_concrete (); }
 
   void debug () const { rust_debug ("%s", as_string ().c_str ()); }
@@ -524,6 +536,7 @@ public:
   BaseType *get_field (size_t index) const;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const override final
   {
@@ -1235,6 +1248,16 @@ public:
 			   cloned_fields);
   }
 
+  VariantDef *monomorphized_clone () const
+  {
+    std::vector<StructFieldType *> cloned_fields;
+    for (auto &f : fields)
+      cloned_fields.push_back ((StructFieldType *) f->monomorphized_clone ());
+
+    return new VariantDef (id, identifier, ident, type, discriminant,
+			   cloned_fields);
+  }
+
   const RustIdent &get_ident () const { return ident; }
 
 private:
@@ -1358,6 +1381,7 @@ public:
   }
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool needs_generic_substitutions () const override final
   {
@@ -1530,6 +1554,7 @@ public:
   BaseType *get_return_type () const { return type; }
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool needs_generic_substitutions () const override final
   {
@@ -1595,6 +1620,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   void iterate_params (std::function<bool (BaseType *)> cb) const
   {
@@ -1668,6 +1694,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const override final
   {
@@ -1735,6 +1762,7 @@ public:
   BaseType *get_element_type () const;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const final override
   {
@@ -1784,6 +1812,7 @@ public:
   BaseType *get_element_type () const;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const final override
   {
@@ -1826,6 +1855,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
   bool is_concrete () const override final { return true; }
 };
 
@@ -1873,6 +1903,7 @@ public:
   IntKind get_int_kind () const { return int_kind; }
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_equal (const BaseType &other) const override;
   bool is_concrete () const override final { return true; }
@@ -1925,6 +1956,7 @@ public:
   UintKind get_uint_kind () const { return uint_kind; }
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_equal (const BaseType &other) const override;
   bool is_concrete () const override final { return true; }
@@ -1975,6 +2007,7 @@ public:
   FloatKind get_float_kind () const { return float_kind; }
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_equal (const BaseType &other) const override;
   bool is_concrete () const override final { return true; }
@@ -2013,6 +2046,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
   bool is_concrete () const override final { return true; }
 };
 
@@ -2046,6 +2080,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
   bool is_concrete () const override final { return true; }
 };
 
@@ -2079,6 +2114,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
   bool is_concrete () const override final { return true; }
 };
 
@@ -2123,6 +2159,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const override final
   {
@@ -2181,6 +2218,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   bool is_concrete () const override final
   {
@@ -2232,6 +2270,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
   bool is_concrete () const override final { return true; }
 };
 
@@ -2273,6 +2312,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_name () const override final { return as_string (); }
 
@@ -2314,6 +2354,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_name () const override final { return as_string (); }
 
@@ -2389,6 +2430,7 @@ public:
   BaseType *cast (BaseType *other) override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_name () const override final { return as_string (); }
 
@@ -2447,6 +2489,7 @@ public:
   bool is_equal (const BaseType &other) const override;
 
   BaseType *clone () const final override;
+  BaseType *monomorphized_clone () const final override;
 
   std::string get_name () const override final;
 
diff --git a/gcc/testsuite/rust/execute/torture/issue-1133.rs b/gcc/testsuite/rust/execute/torture/issue-1133.rs
new file mode 100644
index 00000000000..19d66904d15
--- /dev/null
+++ b/gcc/testsuite/rust/execute/torture/issue-1133.rs
@@ -0,0 +1,146 @@
+// { dg-additional-options "-w" }
+extern "rust-intrinsic" {
+    pub fn offset<T>(dst: *const T, offset: isize) -> *const T;
+}
+
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
+}
+
+pub union Repr<T> {
+    rust: *const [T],
+    rust_mut: *mut [T],
+    raw: FatPtr<T>,
+}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+
+#[lang = "Range"]
+pub struct Range<Idx> {
+    pub start: Idx,
+    pub end: Idx,
+}
+
+#[lang = "const_slice_ptr"]
+impl<T> *const [T] {
+    pub const fn len(self) -> usize {
+        let a = unsafe { Repr { rust: self }.raw };
+        a.len
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+#[lang = "const_ptr"]
+impl<T> *const T {
+    pub const unsafe fn offset(self, count: isize) -> *const T {
+        unsafe { offset(self, count) }
+    }
+
+    pub const unsafe fn add(self, count: usize) -> Self {
+        unsafe { self.offset(count as isize) }
+    }
+
+    pub const fn as_ptr(self) -> *const T {
+        self as *const T
+    }
+}
+
+const fn slice_from_raw_parts<T>(data: *const T, len: usize) -> *const [T] {
+    unsafe {
+        Repr {
+            raw: FatPtr { data, len },
+        }
+        .rust
+    }
+}
+
+#[lang = "index"]
+trait Index<Idx> {
+    type Output;
+
+    fn index(&self, index: Idx) -> &Self::Output;
+}
+
+pub unsafe trait SliceIndex<T> {
+    type Output;
+
+    fn get(self, slice: &T) -> Option<&Self::Output>;
+
+    unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
+
+    fn index(self, slice: &T) -> &Self::Output;
+}
+
+unsafe impl<T> SliceIndex<[T]> for usize {
+    type Output = T;
+
+    fn get(self, slice: &[T]) -> Option<&T> {
+        unsafe { Option::Some(&*self.get_unchecked(slice)) }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
+        // SAFETY: the caller guarantees that `slice` is not dangling, so it
+        // cannot be longer than `isize::MAX`. They also guarantee that
+        // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
+        // so the call to `add` is safe.
+        unsafe { slice.as_ptr().add(self) }
+    }
+
+    fn index(self, slice: &[T]) -> &T {
+        // N.B., use intrinsic indexing
+        // &(*slice)[self]
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+unsafe impl<T> SliceIndex<[T]> for Range<usize> {
+    type Output = [T];
+
+    fn get(self, slice: &[T]) -> Option<&[T]> {
+        if self.start > self.end
+        /* || self.end > slice.len() */
+        {
+            Option::None
+        } else {
+            unsafe { Option::Some(&*self.get_unchecked(slice)) }
+        }
+    }
+
+    unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
+        unsafe {
+            let a: *const T = slice.as_ptr();
+            let b: *const T = a.add(self.start);
+            slice_from_raw_parts(b, self.end - self.start)
+        }
+    }
+
+    fn index(self, slice: &[T]) -> &[T] {
+        unsafe { &*self.get_unchecked(slice) }
+    }
+}
+
+impl<T, I> Index<I> for [T]
+where
+    I: SliceIndex<[T]>,
+{
+    type Output = I::Output;
+
+    fn index(&self, index: I) -> &I::Output {
+        index.index(self)
+    }
+}
+
+fn main() -> i32 {
+    let a = [1, 2, 3, 4, 5];
+    let b = &a[1..3];
+    let c = b[1];
+
+    0
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 12:44 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 12:44 [gcc/devel/rust/master] Add new monomorphize_clone interface Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).