diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/typecheck/rust-hir-type-check-expr.cc | 3 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.cc | 235 | ||||
-rw-r--r-- | gcc/rust/typecheck/rust-tyty.h | 43 | ||||
-rw-r--r-- | 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 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 +} |