From c8188a347e2d066a646be1a325f2cd330e4808a8 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Tue, 20 May 2025 14:25:07 +0200 Subject: [PATCH 1/5] ast: reconstruct: Add base for reconstructing and asserting different IDs gcc/rust/ChangeLog: * ast/rust-ast.h (reconstruct): New function for calling the `reconstruct_*_impl` method and asserting that the new NodeId is different, and then wrap it in a unique_ptr. (reconstruct_vec): Likewise, but for vectors of unique_ptr --- gcc/rust/ast/rust-ast.h | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index cd586c6aa7d3..1cc10c90ee85 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -83,6 +83,42 @@ class Visitable virtual void accept_vis (ASTVisitor &vis) = 0; }; +/** + * Base function for reconstructing and asserting that the new NodeId is + * different from the old NodeId. It then wraps the given pointer into a unique + * pointer and returns it. + */ +template +std::unique_ptr +reconstruct (const T *instance, F method) +{ + auto *reconstructed = (instance->*method) (); + + rust_assert (reconstructed->get_node_id () != instance->get_node_id ()); + + return std::unique_ptr (reconstructed); +} + +/** + * Reconstruct multiple items in a vector + */ +template +std::vector> +reconstruct_vec (const std::vector> &to_reconstruct, + F method) +{ + std::vector> reconstructed; + + for (const auto &elt : to_reconstruct) + { + auto new_elt = (elt.get ()->*method) (); + + reconstructed.emplace_back (std::move (new_elt)); + } + + return reconstructed; +} + // Delimiter types - used in macros and whatever. enum DelimType { From 1c26c18414c678b3f550b1738a3e70e023e05e99 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Tue, 20 May 2025 14:59:28 +0200 Subject: [PATCH 2/5] ast: Add reconstruct() method for Type nodes gcc/rust/ChangeLog: * ast/rust-ast.h: Add reconstruct() and reconstruct_impl() for Type nodes. * ast/rust-type.h: Implement them. * ast/rust-macro.h: Likewise. * ast/rust-path.h: Likewise. --- gcc/rust/ast/rust-ast.h | 45 ++++++++++++----- gcc/rust/ast/rust-macro.h | 20 +++++--- gcc/rust/ast/rust-path.h | 30 +++++++++++ gcc/rust/ast/rust-type.h | 103 +++++++++++++++++++++++++++++++++----- 4 files changed, 167 insertions(+), 31 deletions(-) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 1cc10c90ee85..ecbc29181300 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -88,11 +88,11 @@ class Visitable * different from the old NodeId. It then wraps the given pointer into a unique * pointer and returns it. */ -template +template std::unique_ptr -reconstruct (const T *instance, F method) +reconstruct_base (const T *instance) { - auto *reconstructed = (instance->*method) (); + auto *reconstructed = instance->reconstruct_impl (); rust_assert (reconstructed->get_node_id () != instance->get_node_id ()); @@ -102,19 +102,14 @@ reconstruct (const T *instance, F method) /** * Reconstruct multiple items in a vector */ -template +template std::vector> -reconstruct_vec (const std::vector> &to_reconstruct, - F method) +reconstruct_vec (const std::vector> &to_reconstruct) { std::vector> reconstructed; for (const auto &elt : to_reconstruct) - { - auto new_elt = (elt.get ()->*method) (); - - reconstructed.emplace_back (std::move (new_elt)); - } + reconstructed.emplace_back (std::unique_ptr (elt->reconstruct_impl ())); return reconstructed; } @@ -1516,6 +1511,10 @@ class Type : public Visitable return std::unique_ptr (clone_type_impl ()); } + // Similar to `clone_type`, but generates a new instance of the node with a + // different NodeId + std::unique_ptr reconstruct () const { return reconstruct_base (this); } + // virtual destructor virtual ~Type () {} @@ -1534,11 +1533,13 @@ class Type : public Visitable virtual location_t get_locus () const = 0; NodeId get_node_id () const { return node_id; } + virtual Type *reconstruct_impl () const = 0; protected: Type () : node_id (Analysis::Mappings::get ().get_next_node_id ()) {} + Type (NodeId node_id) : node_id (node_id) {} - // Clone function implementation as pure virtual method + // Clone and reconstruct function implementations as pure virtual methods virtual Type *clone_type_impl () const = 0; NodeId node_id; @@ -1554,6 +1555,13 @@ class TypeNoBounds : public Type return std::unique_ptr (clone_type_no_bounds_impl ()); } + std::unique_ptr reconstruct () const + { + return reconstruct_base (this); + } + + virtual TypeNoBounds *reconstruct_impl () const override = 0; + protected: // Clone function implementation as pure virtual method virtual TypeNoBounds *clone_type_no_bounds_impl () const = 0; @@ -1588,6 +1596,11 @@ class TypeParamBound : public Visitable return std::unique_ptr (clone_type_param_bound_impl ()); } + std::unique_ptr reconstruct () const + { + return reconstruct_base (this); + } + virtual std::string as_string () const = 0; NodeId get_node_id () const { return node_id; } @@ -1596,10 +1609,14 @@ class TypeParamBound : public Visitable virtual TypeParamBoundType get_bound_type () const = 0; + virtual TypeParamBound *reconstruct_impl () const = 0; + protected: // Clone function implementation as pure virtual method virtual TypeParamBound *clone_type_param_bound_impl () const = 0; + TypeParamBound () : node_id (Analysis::Mappings::get ().get_next_node_id ()) + {} TypeParamBound (NodeId node_id) : node_id (node_id) {} NodeId node_id; @@ -1661,6 +1678,10 @@ class Lifetime : public TypeParamBound { return new Lifetime (node_id, lifetime_type, lifetime_name, locus); } + Lifetime *reconstruct_impl () const override + { + return new Lifetime (lifetime_type, lifetime_name, locus); + } }; /* Base generic parameter in AST. Abstract - can be represented by a Lifetime diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index fc01e571b916..e8f377c001ec 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -756,22 +756,16 @@ class MacroInvocation : public TypeNoBounds, std::vector> pending_eager_invocs; protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ MacroInvocation *clone_pattern_impl () const final override { return clone_macro_invocation_impl (); } - /* Use covariance to implement clone function as returning this object rather - * than base */ MacroInvocation *clone_expr_without_block_impl () const final override { return clone_macro_invocation_impl (); } - /* Use covariance to implement clone function as returning this object rather - * than base */ MacroInvocation *clone_type_no_bounds_impl () const final override { return clone_macro_invocation_impl (); @@ -788,6 +782,20 @@ class MacroInvocation : public TypeNoBounds, return new MacroInvocation (*this); } + std::unique_ptr reconstruct_macro_invocation () const + { + return nullptr; + // return reconstruct (this, + // &MacroInvocation::reconstruct_macro_invocation_impl); + } + + MacroInvocation *reconstruct_impl () const override + { + return new MacroInvocation (kind, builtin_kind, invoc_data, outer_attrs, + locus, is_semi_coloned, + reconstruct_vec (pending_eager_invocs)); + } + void add_semicolon () override { is_semi_coloned = true; } Pattern::Kind get_pattern_kind () override diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index de895a2f8384..a1b19d559c33 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -786,6 +786,11 @@ class TypePathSegment { return new TypePathSegment (*this); } + virtual TypePathSegment *reconstruct_impl () const + { + return new TypePathSegment (lang_item, ident_segment, + has_separating_scope_resolution, locus); + } public: virtual ~TypePathSegment () {} @@ -797,6 +802,11 @@ class TypePathSegment { return std::unique_ptr (clone_type_path_segment_impl ()); } + // Unique pointer custom reconstruct function + std::unique_ptr reconstruct () const + { + return reconstruct_base (this); + } TypePathSegment (PathIdentSegment ident_segment, bool has_separating_scope_resolution, location_t locus) @@ -821,6 +831,15 @@ class TypePathSegment node_id (Analysis::Mappings::get ().get_next_node_id ()) {} + // General constructor + TypePathSegment (tl::optional lang_item, + tl::optional ident_segment, + bool has_separating_scope_resolution, location_t locus) + : lang_item (lang_item), ident_segment (ident_segment), locus (locus), + has_separating_scope_resolution (has_separating_scope_resolution), + node_id (Analysis::Mappings::get ().get_next_node_id ()) + {} + TypePathSegment (TypePathSegment const &other) : lang_item (other.lang_item), ident_segment (other.ident_segment), locus (other.locus), @@ -1152,6 +1171,11 @@ class TypePath : public TypeNoBounds { return new TypePath (*this); } + TypePath *reconstruct_impl () const override + { + return new TypePath (reconstruct_vec (segments), locus, + has_opening_scope_resolution); + } public: /* Returns whether the TypePath has an opening scope resolution operator @@ -1443,6 +1467,12 @@ class QualifiedPathInType : public TypeNoBounds { return new QualifiedPathInType (*this); } + QualifiedPathInType *reconstruct_impl () const override + { + return new QualifiedPathInType (path_type, + associated_segment->reconstruct (), + reconstruct_vec (segments), locus); + } public: QualifiedPathInType ( diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index 6c0652a013f9..abbfd36a6f57 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -19,6 +19,7 @@ #ifndef RUST_AST_TYPE_H #define RUST_AST_TYPE_H +#include "optional.h" #include "rust-ast.h" #include "rust-path.h" @@ -106,6 +107,11 @@ class TraitBound : public TypeParamBound return new TraitBound (node_id, type_path, locus, in_parens, opening_question_mark, for_lifetimes); } + TraitBound *reconstruct_impl () const override + { + return new TraitBound (type_path, locus, in_parens, opening_question_mark, + for_lifetimes); + } }; // definition moved to rust-ast.h @@ -127,6 +133,10 @@ class ImplTraitType : public Type { return new ImplTraitType (*this); } + ImplTraitType *reconstruct_impl () const override + { + return new ImplTraitType (reconstruct_vec (type_param_bounds), locus); + } public: ImplTraitType ( @@ -136,7 +146,8 @@ class ImplTraitType : public Type {} // copy constructor with vector clone - ImplTraitType (ImplTraitType const &other) : locus (other.locus) + ImplTraitType (ImplTraitType const &other) + : Type (other.node_id), locus (other.locus) { type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) @@ -191,6 +202,11 @@ class TraitObjectType : public Type { return new TraitObjectType (*this); } + TraitObjectType *reconstruct_impl () const override + { + return new TraitObjectType (reconstruct_vec (type_param_bounds), locus, + has_dyn); + } public: TraitObjectType ( @@ -202,7 +218,7 @@ class TraitObjectType : public Type // copy constructor with vector clone TraitObjectType (TraitObjectType const &other) - : has_dyn (other.has_dyn), locus (other.locus) + : Type (other.node_id), has_dyn (other.has_dyn), locus (other.locus) { type_param_bounds.reserve (other.type_param_bounds.size ()); for (const auto &e : other.type_param_bounds) @@ -258,6 +274,10 @@ class ParenthesisedType : public TypeNoBounds { return new ParenthesisedType (*this); } + ParenthesisedType *reconstruct_impl () const override + { + return new ParenthesisedType (type_in_parens->reconstruct (), locus); + } public: // Constructor uses Type pointer for polymorphism @@ -338,6 +358,10 @@ class ImplTraitTypeOneBound : public TypeNoBounds { return new ImplTraitTypeOneBound (*this); } + TypeNoBounds *reconstruct_impl () const override + { + return new ImplTraitTypeOneBound (trait_bound->reconstruct (), locus); + } }; /* A trait object with a single trait bound. The "trait bound" is really just @@ -355,6 +379,10 @@ class TraitObjectTypeOneBound : public TypeNoBounds { return new TraitObjectTypeOneBound (*this); } + TraitObjectTypeOneBound *reconstruct_impl () const override + { + return new TraitObjectTypeOneBound (trait_bound, locus, has_dyn); + } public: TraitObjectTypeOneBound (TraitBound trait_bound, location_t locus, @@ -448,6 +476,10 @@ class TupleType : public TypeNoBounds { return new TupleType (*this); } + TupleType *reconstruct_impl () const override + { + return new TupleType (reconstruct_vec (elems), locus); + } }; /* A type with no values, representing the result of computations that never @@ -464,6 +496,10 @@ class NeverType : public TypeNoBounds { return new NeverType (*this); } + NeverType *reconstruct_impl () const override + { + return new NeverType (locus); + } public: NeverType (location_t locus) : locus (locus) {} @@ -544,6 +580,10 @@ class RawPointerType : public TypeNoBounds { return new RawPointerType (*this); } + RawPointerType *reconstruct_impl () const override + { + return new RawPointerType (pointer_type, type->reconstruct (), locus); + } }; // A type pointing to memory owned by another value @@ -622,6 +662,16 @@ class ReferenceType : public TypeNoBounds { return new ReferenceType (*this); } + ReferenceType *reconstruct_impl () const override + { + return new ReferenceType (has_mut, type->reconstruct (), locus, + // TODO: Improve this - it's ugly! + has_lifetime () ? tl::make_optional ( + lifetime->get_lifetime_type (), + lifetime->get_lifetime_name (), + lifetime->get_locus ()) + : tl::nullopt); + } }; // A fixed-size sequence of elements of a specified type @@ -689,6 +739,13 @@ class ArrayType : public TypeNoBounds { return new ArrayType (*this); } + ArrayType *reconstruct_impl () const override + { + return new ArrayType ( + elem_type->reconstruct (), + size->clone_expr () /* FIXME: This should be `reconstruct_expr()` */, + locus); + } }; /* A dynamically-sized type representing a "view" into a sequence of elements of @@ -739,12 +796,16 @@ class SliceType : public TypeNoBounds std::unique_ptr &get_elem_type_ptr () { return elem_type; } protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ + /* Use covariance to implement clone function as returning this object + * rather than base */ SliceType *clone_type_no_bounds_impl () const override { return new SliceType (*this); } + SliceType *reconstruct_impl () const override + { + return new SliceType (elem_type->reconstruct (), locus); + } }; /* Type used in generic arguments to explicitly request type inference (wildcard @@ -755,13 +816,21 @@ class InferredType : public TypeNoBounds // e.g. Vec<_> = whatever protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ + /* Use covariance to implement clone function as returning this object + * rather than base */ InferredType *clone_type_no_bounds_impl () const override { + // This goes through the copy constructor return new InferredType (*this); } + InferredType *reconstruct_impl () const override + { + // This goes through the base constructor which calls the base + // TypeNoBounds constructor, which allocates a new NodeId + return new InferredType (locus); + } + public: InferredType (location_t locus) : locus (locus) {} @@ -980,9 +1049,17 @@ class BareFunctionType : public TypeNoBounds FunctionQualifiers &get_function_qualifiers () { return function_qualifiers; } + BareFunctionType *reconstruct_impl () const override + { + return new BareFunctionType ( + for_lifetimes, function_qualifiers, params, + /* FIXME: Should params be reconstruct() as well? */ + _is_variadic, variadic_attrs, return_type->reconstruct (), locus); + } + protected: - /* Use covariance to implement clone function as returning this object rather - * than base */ + /* Use covariance to implement clone function as returning this object + * rather than base */ BareFunctionType *clone_type_no_bounds_impl () const override { return new BareFunctionType (*this); @@ -999,13 +1076,13 @@ class MacroInvocation; * function item type? * closure expression types? * primitive types (bool, int, float, char, str (the slice)) - * Although supposedly TypePaths are used to reference these types (including - * primitives) */ + * Although supposedly TypePaths are used to reference these types + * (including primitives) */ /* FIXME: Incomplete spec references: - * anonymous type parameters, aka "impl Trait in argument position" - impl then - * trait bounds abstract return types, aka "impl Trait in return position" - - * impl then trait bounds */ + * anonymous type parameters, aka "impl Trait in argument position" - impl + * then trait bounds abstract return types, aka "impl Trait in return + * position" - impl then trait bounds */ } // namespace AST } // namespace Rust From 64e97924d7f6340bb928609a848624acdb53ec16 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Tue, 20 May 2025 15:08:06 +0200 Subject: [PATCH 3/5] ast: builder: Remove ASTTypeBuilder gcc/rust/ChangeLog: * Make-lang.in: Remove object file for ASTTypeBuilder. * ast/rust-ast-builder.h: Remove function. * ast/rust-ast-builder.cc (Builder::new_type): Likewise. (Builder::new_const_param): Use reconstruct_type() instead. (Builder::new_generic_args): Likewise. * expand/rust-derive-default.cc (DeriveDefault::visit_struct): Likewise. (DeriveDefault::visit_tuple): Likewise. * expand/rust-derive-eq.cc (DeriveEq::visit_tuple): Likewise. (DeriveEq::visit_struct): Likewise. (DeriveEq::visit_enum): Likewise. (DeriveEq::visit_union): Likewise. * ast/rust-ast-builder-type.cc: Removed. * ast/rust-ast-builder-type.h: Removed. --- gcc/rust/Make-lang.in | 1 - gcc/rust/ast/rust-ast-builder-type.cc | 166 ------------------------- gcc/rust/ast/rust-ast-builder-type.h | 57 --------- gcc/rust/ast/rust-ast-builder.cc | 33 +++-- gcc/rust/ast/rust-ast-builder.h | 2 - gcc/rust/expand/rust-derive-default.cc | 4 +- gcc/rust/expand/rust-derive-eq.cc | 25 +--- 7 files changed, 22 insertions(+), 266 deletions(-) delete mode 100644 gcc/rust/ast/rust-ast-builder-type.cc delete mode 100644 gcc/rust/ast/rust-ast-builder-type.h diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 2a2e79d29f5f..c7846892d895 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -93,7 +93,6 @@ GRS_OBJS = \ rust/rust-cfg-strip.o \ rust/rust-expand-visitor.o \ rust/rust-ast-builder.o \ - rust/rust-ast-builder-type.o \ rust/rust-derive.o \ rust/rust-derive-cmp-common.o \ rust/rust-derive-clone.o \ diff --git a/gcc/rust/ast/rust-ast-builder-type.cc b/gcc/rust/ast/rust-ast-builder-type.cc deleted file mode 100644 index 7f8571ac89f1..000000000000 --- a/gcc/rust/ast/rust-ast-builder-type.cc +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright (C) 2020-2024 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-builder-type.h" -#include "rust-ast-builder.h" -#include "rust-ast-full.h" -#include "rust-common.h" - -namespace Rust { -namespace AST { - -ASTTypeBuilder::ASTTypeBuilder () : translated (nullptr) {} - -Type * -ASTTypeBuilder::build (Type &type) -{ - ASTTypeBuilder builder; - type.accept_vis (builder); - rust_assert (builder.translated != nullptr); - return builder.translated; -} - -void -ASTTypeBuilder::visit (BareFunctionType &fntype) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (TupleType &tuple) -{ - std::vector > elems; - for (auto &elem : tuple.get_elems ()) - { - Type *t = ASTTypeBuilder::build (*elem.get ()); - std::unique_ptr ty (t); - elems.push_back (std::move (ty)); - } - translated = new TupleType (std::move (elems), tuple.get_locus ()); -} - -void -ASTTypeBuilder::visit (TypePath &path) -{ - std::vector > segments; - for (auto &seg : path.get_segments ()) - { - switch (seg->get_type ()) - { - case TypePathSegment::REG: - { - const TypePathSegment &segment - = (const TypePathSegment &) (*seg.get ()); - TypePathSegment *s - = new TypePathSegment (segment.get_ident_segment (), - segment.get_separating_scope_resolution (), - segment.get_locus ()); - std::unique_ptr sg (s); - segments.push_back (std::move (sg)); - } - break; - - case TypePathSegment::GENERIC: - { - TypePathSegmentGeneric &generic - = (TypePathSegmentGeneric &) (*seg.get ()); - - GenericArgs args - = Builder::new_generic_args (generic.get_generic_args ()); - TypePathSegmentGeneric *s - = new TypePathSegmentGeneric (generic.get_ident_segment (), false, - std::move (args), - generic.get_locus ()); - std::unique_ptr sg (s); - segments.push_back (std::move (sg)); - } - break; - - case TypePathSegment::FUNCTION: - { - rust_unreachable (); - // TODO - // const TypePathSegmentFunction &fn - // = (const TypePathSegmentFunction &) (*seg.get ()); - } - break; - } - } - - translated = new TypePath (std::move (segments), path.get_locus (), - path.has_opening_scope_resolution_op ()); -} - -void -ASTTypeBuilder::visit (QualifiedPathInType &path) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (ArrayType &type) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (ReferenceType &type) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (RawPointerType &type) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (SliceType &type) -{ - Type *t = ASTTypeBuilder::build (type.get_elem_type ()); - std::unique_ptr ty (t); - translated = new SliceType (std::move (ty), type.get_locus ()); -} - -void -ASTTypeBuilder::visit (InferredType &type) -{ - translated = new InferredType (type.get_locus ()); -} - -void -ASTTypeBuilder::visit (NeverType &type) -{ - translated = new NeverType (type.get_locus ()); -} - -void -ASTTypeBuilder::visit (TraitObjectTypeOneBound &type) -{ - /* TODO */ -} - -void -ASTTypeBuilder::visit (TraitObjectType &type) -{ - /* TODO */ -} - -} // namespace AST -} // namespace Rust diff --git a/gcc/rust/ast/rust-ast-builder-type.h b/gcc/rust/ast/rust-ast-builder-type.h deleted file mode 100644 index b67ae3b553ff..000000000000 --- a/gcc/rust/ast/rust-ast-builder-type.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2020-2024 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_BUILDER_TYPE -#define RUST_AST_BUILDER_TYPE - -#include "rust-ast-visitor.h" - -namespace Rust { -namespace AST { - -class ASTTypeBuilder : public DefaultASTVisitor -{ -protected: - using DefaultASTVisitor::visit; - -public: - static Type *build (Type &type); - - void visit (BareFunctionType &fntype) override; - void visit (TupleType &tuple) override; - void visit (TypePath &path) override; - void visit (QualifiedPathInType &path) override; - void visit (ArrayType &type) override; - void visit (ReferenceType &type) override; - void visit (RawPointerType &type) override; - void visit (SliceType &type) override; - void visit (InferredType &type) override; - void visit (NeverType &type) override; - void visit (TraitObjectTypeOneBound &type) override; - void visit (TraitObjectType &type) override; - -private: - ASTTypeBuilder (); - - Type *translated; -}; - -} // namespace AST -} // namespace Rust - -#endif // RUST_AST_BUILDER_TYPE diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 914b321279f5..914477120d2b 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -18,7 +18,6 @@ #include "rust-ast-builder.h" #include "optional.h" -#include "rust-ast-builder-type.h" #include "rust-ast.h" #include "rust-common.h" #include "rust-expr.h" @@ -552,13 +551,6 @@ Builder::discriminant_value (std::string binding_name, std::string instance) call (std::move (intrinsic), identifier (instance))); } -std::unique_ptr -Builder::new_type (Type &type) -{ - Type *t = ASTTypeBuilder::build (type); - return std::unique_ptr (t); -} - std::unique_ptr Builder::new_lifetime_param (LifetimeParam ¶m) { @@ -596,7 +588,7 @@ Builder::new_type_param ( std::unique_ptr type = nullptr; if (param.has_type ()) - type = new_type (param.get_type ()); + type = param.get_type ().reconstruct (); for (auto &&extra_bound : extra_bounds) type_param_bounds.emplace_back (std::move (extra_bound)); @@ -726,7 +718,7 @@ Builder::new_generic_args (GenericArgs &args) for (auto &binding : args.get_binding_args ()) { Type &t = *binding.get_type_ptr ().get (); - std::unique_ptr ty = new_type (t); + std::unique_ptr ty = t.reconstruct (); GenericArgsBinding b (binding.get_identifier (), std::move (ty), binding.get_locus ()); binding_args.push_back (std::move (b)); @@ -734,20 +726,25 @@ Builder::new_generic_args (GenericArgs &args) for (auto &arg : args.get_generic_args ()) { + tl::optional new_arg = tl::nullopt; + switch (arg.get_kind ()) { case GenericArg::Kind::Type: - { - std::unique_ptr ty = new_type (arg.get_type ()); - GenericArg arg = GenericArg::create_type (std::move (ty)); - } + new_arg = GenericArg::create_type (arg.get_type ().reconstruct ()); break; - - default: - // FIXME - rust_unreachable (); + case GenericArg::Kind::Either: + new_arg + = GenericArg::create_ambiguous (arg.get_path (), arg.get_locus ()); + break; + case GenericArg::Kind::Const: + new_arg + = GenericArg::create_const (arg.get_expression ().clone_expr ()); + // FIXME: Use `reconstruct()` here, not `clone_expr()` break; } + + generic_args.emplace_back (*new_arg); } return GenericArgs (std::move (lifetime_args), std::move (generic_args), diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h index fa3c95ce4fdf..843bab896c74 100644 --- a/gcc/rust/ast/rust-ast-builder.h +++ b/gcc/rust/ast/rust-ast-builder.h @@ -315,8 +315,6 @@ class Builder std::unique_ptr discriminant_value (std::string binding_name, std::string instance = "self"); - static std::unique_ptr new_type (Type &type); - static std::unique_ptr new_lifetime_param (LifetimeParam ¶m); diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc index 1b497b5923b0..26ee5461095a 100644 --- a/gcc/rust/expand/rust-derive-default.cc +++ b/gcc/rust/expand/rust-derive-default.cc @@ -98,7 +98,7 @@ DeriveDefault::visit_struct (StructStruct &item) for (auto &field : item.get_fields ()) { auto name = field.get_field_name ().as_string (); - auto type = Builder::new_type (field.get_field_type ()); + auto type = field.get_field_type ().reconstruct (); auto expr = default_call (std::move (type)); cloned_fields.emplace_back ( @@ -120,7 +120,7 @@ DeriveDefault::visit_tuple (TupleStruct &tuple_item) for (auto &field : tuple_item.get_fields ()) { - auto type = Builder::new_type (field.get_field_type ()); + auto type = field.get_field_type ().reconstruct (); defaulted_fields.emplace_back (default_call (std::move (type))); } diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc index 97651270bc55..7da137fb5c27 100644 --- a/gcc/rust/expand/rust-derive-eq.cc +++ b/gcc/rust/expand/rust-derive-eq.cc @@ -142,10 +142,7 @@ DeriveEq::visit_tuple (TupleStruct &item) auto types = std::vector> (); for (auto &field : item.get_fields ()) - { - auto type = Builder::new_type (field.get_field_type ()); - types.emplace_back (std::move (type)); - } + types.emplace_back (field.get_field_type ().reconstruct ()); expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)), item.get_identifier ().as_string (), @@ -158,10 +155,7 @@ DeriveEq::visit_struct (StructStruct &item) auto types = std::vector> (); for (auto &field : item.get_fields ()) - { - auto type = Builder::new_type (field.get_field_type ()); - types.emplace_back (std::move (type)); - } + types.emplace_back (field.get_field_type ().reconstruct ()); expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)), item.get_identifier ().as_string (), @@ -186,10 +180,7 @@ DeriveEq::visit_enum (Enum &item) auto &tuple = static_cast (*variant); for (auto &field : tuple.get_tuple_fields ()) - { - auto type = Builder::new_type (field.get_field_type ()); - types.emplace_back (std::move (type)); - } + types.emplace_back (field.get_field_type ().reconstruct ()); break; } case EnumItem::Kind::Struct: @@ -197,10 +188,7 @@ DeriveEq::visit_enum (Enum &item) auto &tuple = static_cast (*variant); for (auto &field : tuple.get_struct_fields ()) - { - auto type = Builder::new_type (field.get_field_type ()); - types.emplace_back (std::move (type)); - } + types.emplace_back (field.get_field_type ().reconstruct ()); break; } @@ -218,10 +206,7 @@ DeriveEq::visit_union (Union &item) auto types = std::vector> (); for (auto &field : item.get_variants ()) - { - auto type = Builder::new_type (field.get_field_type ()); - types.emplace_back (std::move (type)); - } + types.emplace_back (field.get_field_type ().reconstruct ()); expanded = eq_impls (assert_receiver_is_total_eq_fn (std::move (types)), item.get_identifier ().as_string (), From caaf50699672474d934b63cdeb9abf2e7ebbe1b9 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Mon, 26 May 2025 11:31:40 +0200 Subject: [PATCH 4/5] reconstruct_vec: Allocate size when creating the vector gcc/rust/ChangeLog: * ast/rust-ast.h (reconstruct_vec): Pre-allocate size of vector. --- gcc/rust/ast/rust-ast.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index ecbc29181300..0d853e744c76 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -107,6 +107,7 @@ std::vector> reconstruct_vec (const std::vector> &to_reconstruct) { std::vector> reconstructed; + reconstructed.reserve (to_reconstruct.size ()); for (const auto &elt : to_reconstruct) reconstructed.emplace_back (std::unique_ptr (elt->reconstruct_impl ())); From 3389cb54ed688a9f6ad00cfb99f5b40f46b54cc4 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Fri, 13 Jun 2025 10:04:41 +0200 Subject: [PATCH 5/5] chore: ast: Fix formatting and includes gcc/rust/ChangeLog: * ast/rust-ast-builder.cc: Remove extra include, fix new formatting. --- gcc/rust/ast/rust-ast-builder.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 914477120d2b..ed10ce7f9a18 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -28,7 +28,6 @@ #include "rust-pattern.h" #include "rust-system.h" #include "rust-token.h" -#include namespace Rust { namespace AST {