aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-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
+}