aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-05-06 13:12:41 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-05-06 16:57:11 +0100
commitcb4d935508def8b250345ba5205a90ad9e177ab4 (patch)
tree12019e3e3380e793d0d435e59e00ca35d311ff1e
parent9ea940e4dcabbf99fbb44c125a0af7cf82e48146 (diff)
downloadgcc-cb4d935508def8b250345ba5205a90ad9e177ab4.zip
gcc-cb4d935508def8b250345ba5205a90ad9e177ab4.tar.gz
gcc-cb4d935508def8b250345ba5205a90ad9e177ab4.tar.bz2
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
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.cc3
-rw-r--r--gcc/rust/typecheck/rust-tyty.cc235
-rw-r--r--gcc/rust/typecheck/rust-tyty.h43
-rw-r--r--gcc/testsuite/rust/execute/torture/issue-1133.rs146
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 a3d911e..c499204 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 fcbf998..e2dacc9 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 b00237c..c0e4324 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 0000000..19d6690
--- /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
+}