From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1643) id 589703819EBA; Wed, 8 Jun 2022 12:44:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 589703819EBA Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Thomas Schwinge To: gcc-cvs@gcc.gnu.org Subject: [gcc/devel/rust/master] Add new monomorphize_clone interface X-Act-Checkin: gcc X-Git-Author: Philip Herron X-Git-Refname: refs/heads/devel/rust/master X-Git-Oldrev: 9ea940e4dcabbf99fbb44c125a0af7cf82e48146 X-Git-Newrev: cb4d935508def8b250345ba5205a90ad9e177ab4 Message-Id: <20220608124444.589703819EBA@sourceware.org> Date: Wed, 8 Jun 2022 12:44:44 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 Jun 2022 12:44:44 -0000 https://gcc.gnu.org/g:cb4d935508def8b250345ba5205a90ad9e177ab4 commit cb4d935508def8b250345ba5205a90ad9e177ab4 Author: Philip Herron 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 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 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 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> cloned_params; for (auto &p : params) - cloned_params.push_back ( - std::pair (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> 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 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 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 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 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(dst: *const T, offset: isize) -> *const T; +} + +struct FatPtr { + data: *const T, + len: usize, +} + +pub union Repr { + rust: *const [T], + rust_mut: *mut [T], + raw: FatPtr, +} + +pub enum Option { + None, + Some(T), +} + +#[lang = "Range"] +pub struct Range { + pub start: Idx, + pub end: Idx, +} + +#[lang = "const_slice_ptr"] +impl *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 *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(data: *const T, len: usize) -> *const [T] { + unsafe { + Repr { + raw: FatPtr { data, len }, + } + .rust + } +} + +#[lang = "index"] +trait Index { + type Output; + + fn index(&self, index: Idx) -> &Self::Output; +} + +pub unsafe trait SliceIndex { + 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 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 SliceIndex<[T]> for Range { + 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 Index 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 +}