https://gcc.gnu.org/g:63023c032845b5d01e25c1f2e443e43d938337b0
commit r15-8619-g63023c032845b5d01e25c1f2e443e43d938337b0 Author: Arthur Cohen <arthur.co...@embecosm.com> Date: Thu Dec 26 21:46:03 2024 +0000 gccrs: ast: Refactor how lang item paths are handled. Lang item typepaths were not handled properly, and required a complete overhaul. All old classes that concerned lang item paths are now modified to use a simpler version of `AST::LangItemPath`, which has been removed. TypePath segments can now be lang items, as this is requied for having generic lang item paths such as PhantomData<T>. gcc/rust/ChangeLog: * ast/rust-path.h: Rework how lang item paths are represented. * ast/rust-path.cc: Likewise. * ast/rust-item.h: Likewise. * ast/rust-ast.cc: Likewise. * ast/rust-ast-collector.cc: Adapt to new lang item path system. * ast/rust-ast-collector.h: Likewise. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Likewise. * ast/rust-ast-visitor.h: Likewise. * expand/rust-derive-copy.cc: Likewise. * expand/rust-derive.h: Likewise. * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise. * hir/rust-ast-lower-base.h: Likewise. * hir/rust-ast-lower-type.cc (ASTLowerTypePath::translate): Likewise. (ASTLowerTypePath::visit): Likewise. * hir/rust-ast-lower-type.h: Likewise. * resolve/rust-ast-resolve-base.cc (ResolverBase::visit): Likewise. * resolve/rust-ast-resolve-base.h: Likewise. * resolve/rust-ast-resolve-item.cc (ResolveItem::visit): Likewise. * resolve/rust-ast-resolve-type.h: Likewise. * resolve/rust-ast-resolve-type.cc (ResolveRelativeTypePath::go): Likewise. * resolve/rust-late-name-resolver-2.0.cc (Late::visit): Likewise. * resolve/rust-late-name-resolver-2.0.h: Likewise. * hir/tree/rust-hir-path.cc (TypePathSegment::TypePathSegment): Likewise. (TypePathSegmentGeneric::TypePathSegmentGeneric): Likewise. * hir/tree/rust-hir-path.h: Likewise. * typecheck/rust-hir-type-check-type.cc (TypeCheckType::resolve_root_path): Likewise. * ast/rust-ast-builder.cc: Likewise. * ast/rust-ast-builder.h: Likewise. Diff: --- gcc/rust/ast/rust-ast-builder.cc | 20 +- gcc/rust/ast/rust-ast-builder.h | 4 - gcc/rust/ast/rust-ast-collector.cc | 13 - gcc/rust/ast/rust-ast-collector.h | 2 - gcc/rust/ast/rust-ast-visitor.cc | 11 - gcc/rust/ast/rust-ast-visitor.h | 4 - gcc/rust/ast/rust-ast.cc | 4 +- gcc/rust/ast/rust-item.h | 40 +-- gcc/rust/ast/rust-path.cc | 31 +- gcc/rust/ast/rust-path.h | 405 +++++++++--------------- gcc/rust/expand/rust-derive-copy.cc | 4 +- gcc/rust/expand/rust-derive.h | 2 - gcc/rust/hir/rust-ast-lower-base.cc | 6 - gcc/rust/hir/rust-ast-lower-base.h | 2 - gcc/rust/hir/rust-ast-lower-type.cc | 75 +++-- gcc/rust/hir/rust-ast-lower-type.h | 6 +- gcc/rust/hir/tree/rust-hir-path.cc | 21 +- gcc/rust/hir/tree/rust-hir-path.h | 38 ++- gcc/rust/resolve/rust-ast-resolve-base.cc | 8 - gcc/rust/resolve/rust-ast-resolve-base.h | 2 - gcc/rust/resolve/rust-ast-resolve-item.cc | 27 +- gcc/rust/resolve/rust-ast-resolve-type.cc | 79 +++-- gcc/rust/resolve/rust-ast-resolve-type.h | 31 -- gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 19 -- gcc/rust/resolve/rust-late-name-resolver-2.0.h | 1 - gcc/rust/typecheck/rust-hir-type-check-type.cc | 2 +- 26 files changed, 311 insertions(+), 546 deletions(-) diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 22fb0d83f979..f6d0f0dc4aed 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -42,15 +42,6 @@ Builder::call (std::unique_ptr<Expr> &&path, new CallExpr (std::move (path), std::move (args), {}, loc)); } -std::unique_ptr<Expr> -Builder::call (std::unique_ptr<Path> &&path, - std::vector<std::unique_ptr<Expr>> &&args) const -{ - return call (std::unique_ptr<Expr> ( - new PathInExpression (std::move (path), {}, loc)), - std::move (args)); -} - std::unique_ptr<Expr> Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const { @@ -60,15 +51,6 @@ Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const return call (std::move (path), std::move (args)); } -std::unique_ptr<Expr> -Builder::call (std::unique_ptr<Path> &&path, std::unique_ptr<Expr> &&arg) const -{ - auto args = std::vector<std::unique_ptr<Expr>> (); - args.emplace_back (std::move (arg)); - - return call (std::move (path), std::move (args)); -} - std::unique_ptr<Expr> Builder::array (std::vector<std::unique_ptr<Expr>> &&members) const { @@ -242,7 +224,7 @@ Builder::wildcard () const std::unique_ptr<Path> Builder::lang_item_path (LangItem::Kind kind) const { - return std::unique_ptr<Path> (new LangItemPath (kind, loc)); + return std::unique_ptr<Path> (new PathInExpression (kind, {}, loc)); } std::unique_ptr<Expr> diff --git a/gcc/rust/ast/rust-ast-builder.h b/gcc/rust/ast/rust-ast-builder.h index 6e07df6e1824..aaf05c6d1fb1 100644 --- a/gcc/rust/ast/rust-ast-builder.h +++ b/gcc/rust/ast/rust-ast-builder.h @@ -72,12 +72,8 @@ public: */ std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path, std::vector<std::unique_ptr<Expr>> &&args) const; - std::unique_ptr<Expr> call (std::unique_ptr<Path> &&path, - std::vector<std::unique_ptr<Expr>> &&args) const; std::unique_ptr<Expr> call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const; - std::unique_ptr<Expr> call (std::unique_ptr<Path> &&path, - std::unique_ptr<Expr> &&arg) const; /** * Create an array expression (`[member0, member1, member2]`) diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 320611614e92..f493da3fa3fc 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -538,19 +538,6 @@ TokenCollector::visit (PathInExpression &path) visit_items_joined_by_separator (path.get_segments (), SCOPE_RESOLUTION); } -void -TokenCollector::visit (RegularPath &path) -{ - // FIXME: We probably want to have a proper implementation here, and call this - // function from things like the PathInExpression visitor -} - -void -TokenCollector::visit (LangItemPath &path) -{ - // TODO: Implement proper token collection for lang item paths -} - void TokenCollector::visit (TypePathSegment &segment) { diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h index 30aff9851051..b014c23ed0b8 100644 --- a/gcc/rust/ast/rust-ast-collector.h +++ b/gcc/rust/ast/rust-ast-collector.h @@ -233,8 +233,6 @@ public: void visit (PathExprSegment &segment); void visit (PathIdentSegment &segment); void visit (PathInExpression &path); - void visit (RegularPath &path); - void visit (LangItemPath &path); void visit (TypePathSegment &segment); void visit (TypePathSegmentGeneric &segment); void visit (TypePathSegmentFunction &segment); diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 6959c49d66a5..e2e2d9dda37b 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -85,17 +85,6 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param) visit (const_param.get_default_value ()); } -void -DefaultASTVisitor::visit (AST::RegularPath &path) -{ - for (auto &segment : path.get_segments ()) - visit (segment); -} - -void -DefaultASTVisitor::visit (AST::LangItemPath &path) -{} - void DefaultASTVisitor::visit (AST::PathInExpression &path) { diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h index a7c1cc9c62bb..51661df76b49 100644 --- a/gcc/rust/ast/rust-ast-visitor.h +++ b/gcc/rust/ast/rust-ast-visitor.h @@ -60,8 +60,6 @@ public: // virtual void visit(TraitImplItem& trait_impl_item) = 0; // rust-path.h - virtual void visit (RegularPath &path) = 0; - virtual void visit (LangItemPath &path) = 0; virtual void visit (PathInExpression &path) = 0; virtual void visit (TypePathSegment &segment) = 0; virtual void visit (TypePathSegmentGeneric &segment) = 0; @@ -252,8 +250,6 @@ public: virtual void visit (AST::Lifetime &lifetime) override; virtual void visit (AST::LifetimeParam &lifetime_param) override; virtual void visit (AST::ConstGenericParam &const_param) override; - virtual void visit (AST::RegularPath &path) override; - virtual void visit (AST::LangItemPath &path) override; virtual void visit (AST::PathInExpression &path) override; virtual void visit (AST::TypePathSegment &segment) override; virtual void visit (AST::TypePathSegmentGeneric &segment) override; diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 45189a1a4b37..ab82303879c9 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1299,7 +1299,7 @@ TraitImpl::as_string () const else str += "false"; - str += "\n TypePath (to trait): " + trait_path->as_string (); + str += "\n TypePath (to trait): " + trait_path.as_string (); str += "\n Type (struct to impl on): " + trait_type->as_string (); @@ -1561,7 +1561,7 @@ QualifiedPathType::as_string () const str += type_to_invoke_on->as_string (); if (has_as_clause ()) - str += " as " + trait_path->as_string (); + str += " as " + trait_path.as_string (); return str + ">"; } diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 261e64e4242b..8eb0cc51d5db 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -3254,7 +3254,7 @@ class TraitImpl : public Impl { bool has_unsafe; bool has_exclam; - std::unique_ptr<Path> trait_path; + TypePath trait_path; // bool has_impl_items; std::vector<std::unique_ptr<AssociatedItem>> impl_items; @@ -3266,7 +3266,7 @@ public: bool has_impl_items () const { return !impl_items.empty (); } // Mega-constructor - TraitImpl (std::unique_ptr<Path> trait_path, bool is_unsafe, bool has_exclam, + TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam, std::vector<std::unique_ptr<AssociatedItem>> impl_items, std::vector<std::unique_ptr<GenericParam>> generic_params, std::unique_ptr<Type> trait_type, WhereClause where_clause, @@ -3275,29 +3275,14 @@ public: : Impl (std::move (generic_params), std::move (trait_type), std::move (where_clause), std::move (vis), std::move (inner_attrs), std::move (outer_attrs), locus), - has_unsafe (is_unsafe), has_exclam (has_exclam), - trait_path (std::move (trait_path)), impl_items (std::move (impl_items)) - {} - - // Delegating constructor for TypePath - TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam, - std::vector<std::unique_ptr<AssociatedItem>> impl_items, - std::vector<std::unique_ptr<GenericParam>> generic_params, - std::unique_ptr<Type> trait_type, WhereClause where_clause, - Visibility vis, std::vector<Attribute> inner_attrs, - std::vector<Attribute> outer_attrs, location_t locus) - : TraitImpl (std::unique_ptr<Path> (new TypePath (trait_path)), is_unsafe, - has_exclam, std::move (impl_items), std::move (generic_params), - std::move (trait_type), std::move (where_clause), - std::move (vis), std::move (inner_attrs), - std::move (outer_attrs), locus) + has_unsafe (is_unsafe), has_exclam (has_exclam), trait_path (trait_path), + impl_items (std::move (impl_items)) {} // Copy constructor with vector clone TraitImpl (TraitImpl const &other) : Impl (other), has_unsafe (other.has_unsafe), - has_exclam (other.has_exclam), - trait_path (other.trait_path->clone_path ()) + has_exclam (other.has_exclam), trait_path (other.trait_path) { impl_items.reserve (other.impl_items.size ()); for (const auto &e : other.impl_items) @@ -3308,7 +3293,7 @@ public: TraitImpl &operator= (TraitImpl const &other) { Impl::operator= (other); - trait_path = other.trait_path->clone_path (); + trait_path = other.trait_path; has_unsafe = other.has_unsafe; has_exclam = other.has_exclam; @@ -3339,18 +3324,7 @@ public: } // TODO: is this better? Or is a "vis_block" better? - Path &get_trait_path () - { - // TODO: assert that trait path is not empty? - return *trait_path; - } - - Type &get_trait_path_type () - { - rust_assert (trait_path->get_path_kind () == Path::Kind::Type); - - return (AST::Type &) static_cast<AST::TypePath &> (*trait_path); - } + TypePath &get_trait_path () { return trait_path; } protected: /* Use covariance to implement clone function as returning this object diff --git a/gcc/rust/ast/rust-path.cc b/gcc/rust/ast/rust-path.cc index 94cf2bb15141..69627be81af3 100644 --- a/gcc/rust/ast/rust-path.cc +++ b/gcc/rust/ast/rust-path.cc @@ -136,8 +136,11 @@ PathExprSegment::as_string () const } std::string -RegularPath::as_string () const +Path::as_string () const { + // FIXME: Impl for lang items + rust_assert (kind == Kind::Regular); + std::string str; for (const auto &segment : segments) @@ -149,15 +152,11 @@ RegularPath::as_string () const return str; } -std::string -LangItemPath::as_string () const -{ - return "#[lang = \"" + LangItem::ToString (kind) + "\"]"; -} - SimplePath -RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const +Path::convert_to_simple_path (bool with_opening_scope_resolution) const { + rust_assert (kind == Kind::Regular); + if (!has_segments ()) return SimplePath::create_empty (); @@ -190,18 +189,6 @@ RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const locus); } -void -RegularPath::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - -void -LangItemPath::accept_vis (ASTVisitor &vis) -{ - vis.visit (*this); -} - void PathInExpression::accept_vis (ASTVisitor &vis) { @@ -216,7 +203,7 @@ PathInExpression::as_string () const if (has_opening_scope_resolution) str = "::"; - return str + path->as_string (); + return str + Path::as_string (); } std::string @@ -316,7 +303,7 @@ TypePathFunction::as_string () const std::string QualifiedPathInExpression::as_string () const { - return path_type.as_string () + "::" + path->as_string (); + return path_type.as_string () + "::" + Path::as_string (); } std::string diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index b7eba446540c..2a76acc48c3d 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -21,6 +21,7 @@ /* "Path" (identifier within namespaces, essentially) handling. Required include * for virtually all AST-related functionality. */ +#include "optional.h" #include "rust-ast.h" #include "rust-hir-map.h" #include "rust-mapping-common.h" @@ -589,115 +590,75 @@ public: { LangItem, Regular, - Type, }; - virtual Kind get_path_kind () const = 0; - - Pattern::Kind get_pattern_kind () override final - { - return Pattern::Kind::Path; - } - - std::unique_ptr<Path> clone_path () - { - return std::unique_ptr<Path> (clone_path_impl ()); - } - - Pattern *clone_pattern_impl () const override final - { - return clone_path_impl (); - } - -protected: - virtual Path *clone_path_impl () const = 0; -}; - -class RegularPath : public Path -{ - std::vector<PathExprSegment> segments; - NodeId node_id; - location_t locus; - -public: - explicit RegularPath (std::vector<PathExprSegment> &&segments, - location_t locus, NodeId node_id) - : segments (std::move (segments)), node_id (node_id), locus (locus) + Path (std::vector<PathExprSegment> segments) + : segments (std::move (segments)), lang_item (tl::nullopt), + kind (Kind::Regular) {} - std::string as_string () const override; + Path (LangItem::Kind lang_item) + : segments ({}), lang_item (lang_item), kind (Kind::LangItem) + {} // Returns whether path has segments. - bool has_segments () const { return !segments.empty (); } - - std::vector<PathExprSegment> &get_segments () { return segments; } - - const std::vector<PathExprSegment> &get_segments () const { return segments; } - - /* Returns whether the path is a single segment (excluding qualified path - * initial as segment). */ - bool is_single_segment () const { return segments.size () == 1; } + bool has_segments () const + { + rust_assert (kind == Kind::Regular); + return !segments.empty (); + } /* Converts path segments to their equivalent SimplePath segments if * possible, and creates a SimplePath from them. */ SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const; - Path::Kind get_path_kind () const override { return Path::Kind::Regular; } - - void accept_vis (ASTVisitor &vis) override; - - Path *clone_path_impl () const override + /* Returns whether the path is a single segment (excluding qualified path + * initial as segment). */ + bool is_single_segment () const { - return new RegularPath (std::vector<PathExprSegment> (segments), locus, - node_id); + rust_assert (kind == Kind::Regular); + return segments.size () == 1; } - NodeId get_node_id () const override { return node_id; } - location_t get_locus () const override { return locus; } -}; - -class LangItemPath : public Path -{ - LangItem::Kind kind; - NodeId node_id; - location_t locus; - - LangItemPath (LangItem::Kind kind, NodeId node_id, location_t locus) - : kind (kind), node_id (node_id), locus (locus) - {} - -public: - explicit LangItemPath (LangItem::Kind kind, location_t locus) - : kind (kind), node_id (Analysis::Mappings::get ().get_next_node_id ()), - locus (locus) - {} - - Path::Kind get_path_kind () const override { return Path::Kind::LangItem; } + std::string as_string () const override; - void accept_vis (ASTVisitor &vis) override; + // TODO: this seems kinda dodgy + std::vector<PathExprSegment> &get_segments () + { + rust_assert (kind == Kind::Regular); + return segments; + } + const std::vector<PathExprSegment> &get_segments () const + { + rust_assert (kind == Kind::Regular); + return segments; + } - Path *clone_path_impl () const override + LangItem::Kind get_lang_item () const { - return new LangItemPath (kind, node_id, locus); + rust_assert (kind == Kind::LangItem); + return *lang_item; } - std::string as_string () const override; + Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } + Path::Kind get_path_kind () { return kind; } - LangItem::Kind get_lang_item_kind () { return kind; } +protected: + std::vector<PathExprSegment> segments; + tl::optional<LangItem::Kind> lang_item; - NodeId get_node_id () const override { return node_id; } - location_t get_locus () const override { return locus; } + Path::Kind kind; }; /* AST node representing a path-in-expression pattern (path that allows * generic arguments) */ -class PathInExpression : public Pattern, public ExprWithoutBlock +class PathInExpression : public Path, public ExprWithoutBlock { std::vector<Attribute> outer_attrs; bool has_opening_scope_resolution; location_t locus; NodeId _node_id; - std::unique_ptr<Path> path; + bool marked_for_strip; public: @@ -707,52 +668,20 @@ public: PathInExpression (std::vector<PathExprSegment> path_segments, std::vector<Attribute> outer_attrs, location_t locus, bool has_opening_scope_resolution = false) - : outer_attrs (std::move (outer_attrs)), + : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)), has_opening_scope_resolution (has_opening_scope_resolution), locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()), - path (std::make_unique<RegularPath> (std::move (path_segments), locus, - _node_id)), marked_for_strip (false) {} - PathInExpression (LangItem::Kind lang_item_kind, + PathInExpression (LangItem::Kind lang_item, std::vector<Attribute> outer_attrs, location_t locus) - : outer_attrs (std::move (outer_attrs)), + : Path (lang_item), outer_attrs (std::move (outer_attrs)), has_opening_scope_resolution (false), locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()), - path (std::make_unique<LangItemPath> (lang_item_kind, locus)), marked_for_strip (false) {} - PathInExpression (std::unique_ptr<Path> path, - std::vector<Attribute> outer_attrs, location_t locus, - bool has_opening_scope_resolution = false) - : outer_attrs (std::move (outer_attrs)), - has_opening_scope_resolution (has_opening_scope_resolution), - locus (locus), _node_id (Analysis::Mappings::get ().get_next_node_id ()), - path (std::move (path)), marked_for_strip (false) - {} - - PathInExpression (const PathInExpression &other) - : outer_attrs (other.outer_attrs), - has_opening_scope_resolution (other.has_opening_scope_resolution), - locus (other.locus), _node_id (other._node_id), - path (other.path->clone_path ()), - marked_for_strip (other.marked_for_strip) - {} - - PathInExpression &operator= (const PathInExpression &other) - { - outer_attrs = other.outer_attrs; - has_opening_scope_resolution = other.has_opening_scope_resolution; - locus = other.locus; - _node_id = other._node_id; - path = other.path->clone_path (); - marked_for_strip = other.marked_for_strip; - - return *this; - } - // Creates an error state path in expression. static PathInExpression create_error () { @@ -761,25 +690,19 @@ public: } // Returns whether path in expression is in an error state. - bool is_error () const - { - if (path->get_path_kind () == Path::Kind::Regular) - return !static_cast<RegularPath &> (*path).has_segments (); - - rust_unreachable (); - } + bool is_error () const { return !has_segments (); } /* Converts PathInExpression to SimplePath if possible (i.e. no generic * arguments). Otherwise returns an empty SimplePath. */ SimplePath as_simple_path () const { - // FIXME: Cleanup - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).convert_to_simple_path ( - has_opening_scope_resolution); - else - // FIXME: lang item to simple path? - rust_unreachable (); + /* delegate to parent class as can't access segments. however, + * QualifiedPathInExpression conversion to simple path wouldn't make + * sense, so the method in the parent class should be protected, not + * public. Have to pass in opening scope resolution as parent class has no + * access to it. + */ + return convert_to_simple_path (has_opening_scope_resolution); } location_t get_locus () const override final { return locus; } @@ -806,66 +729,18 @@ public: NodeId get_pattern_node_id () const { return get_node_id (); } - PathExprSegment &get_final_segment () - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments ().back (); - - // lang item segment? - rust_unreachable (); - } - + PathExprSegment &get_final_segment () { return get_segments ().back (); } const PathExprSegment &get_final_segment () const { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments ().back (); - - // lang item segment? - rust_unreachable (); + return get_segments ().back (); } - const std::vector<PathExprSegment> &get_segments () const - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments (); - - rust_unreachable (); - } - - std::vector<PathExprSegment> &get_segments () - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments (); - - rust_unreachable (); - } - - bool is_single_segment () const - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments ().size () == 1; - - rust_unreachable (); - } - - Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } - Expr::Kind get_expr_kind () const override { return Expr::Kind::PathInExpression; } protected: - PathInExpression (std::vector<Attribute> &&outer_attrs, - bool has_opening_scope_resolution, location_t locus, - NodeId node_id, std::unique_ptr<Path> &&path, - bool marked_for_strip) - : outer_attrs (std::move (outer_attrs)), - has_opening_scope_resolution (has_opening_scope_resolution), - locus (locus), _node_id (node_id), path (std::move (path)), - marked_for_strip (marked_for_strip) - {} - /* Use covariance to implement clone function as returning this object * rather than base */ PathInExpression *clone_pattern_impl () const final override @@ -899,7 +774,8 @@ public: }; private: - PathIdentSegment ident_segment; + tl::optional<LangItem::Kind> lang_item; + tl::optional<PathIdentSegment> ident_segment; location_t locus; protected: @@ -929,21 +805,30 @@ public: TypePathSegment (PathIdentSegment ident_segment, bool has_separating_scope_resolution, location_t locus) - : ident_segment (std::move (ident_segment)), locus (locus), + : lang_item (tl::nullopt), ident_segment (std::move (ident_segment)), + locus (locus), has_separating_scope_resolution (has_separating_scope_resolution), node_id (Analysis::Mappings::get ().get_next_node_id ()) {} + TypePathSegment (LangItem::Kind lang_item, location_t locus) + : lang_item (lang_item), ident_segment (tl::nullopt), locus (locus), + has_separating_scope_resolution (false), + node_id (Analysis::Mappings::get ().get_next_node_id ()) + {} + TypePathSegment (std::string segment_name, bool has_separating_scope_resolution, location_t locus) - : ident_segment (PathIdentSegment (std::move (segment_name), locus)), + : lang_item (tl::nullopt), + ident_segment (PathIdentSegment (std::move (segment_name), locus)), locus (locus), has_separating_scope_resolution (has_separating_scope_resolution), node_id (Analysis::Mappings::get ().get_next_node_id ()) {} TypePathSegment (TypePathSegment const &other) - : ident_segment (other.ident_segment), locus (other.locus), + : lang_item (other.lang_item), ident_segment (other.ident_segment), + locus (other.locus), has_separating_scope_resolution (other.has_separating_scope_resolution), node_id (other.node_id) {} @@ -951,6 +836,7 @@ public: TypePathSegment &operator= (TypePathSegment const &other) { ident_segment = other.ident_segment; + lang_item = other.lang_item; locus = other.locus; has_separating_scope_resolution = other.has_separating_scope_resolution; node_id = other.node_id; @@ -961,16 +847,28 @@ public: TypePathSegment (TypePathSegment &&other) = default; TypePathSegment &operator= (TypePathSegment &&other) = default; - virtual std::string as_string () const { return ident_segment.as_string (); } + virtual std::string as_string () const + { + if (lang_item.has_value ()) + return LangItem::PrettyString (*lang_item); + + return ident_segment->as_string (); + } /* Returns whether the type path segment is in an error state. May be * virtual in future. */ - bool is_error () const { return ident_segment.is_error (); } + bool is_error () const + { + rust_assert (ident_segment); + return ident_segment->is_error (); + } /* Returns whether segment is identifier only (as opposed to generic args or * function). Overridden in derived classes with other segments. */ virtual bool is_ident_only () const { return true; } + bool is_lang_item () const { return lang_item.has_value (); } + location_t get_locus () const { return locus; } // not pure virtual as class not abstract @@ -981,8 +879,23 @@ public: return has_separating_scope_resolution; } - PathIdentSegment &get_ident_segment () { return ident_segment; }; - const PathIdentSegment &get_ident_segment () const { return ident_segment; }; + PathIdentSegment &get_ident_segment () + { + rust_assert (!is_lang_item ()); + return *ident_segment; + }; + + const PathIdentSegment &get_ident_segment () const + { + rust_assert (!is_lang_item ()); + return *ident_segment; + }; + + LangItem::Kind get_lang_item () const + { + rust_assert (is_lang_item ()); + return *lang_item; + } NodeId get_node_id () const { return node_id; } @@ -1025,6 +938,12 @@ public: generic_args (std::move (generic_args)) {} + TypePathSegmentGeneric (LangItem::Kind lang_item, GenericArgs generic_args, + location_t locus) + : TypePathSegment (lang_item, locus), + generic_args (std::move (generic_args)) + {} + // Constructor from segment name and all args TypePathSegmentGeneric (std::string segment_name, bool has_separating_scope_resolution, @@ -1082,7 +1001,7 @@ private: /*bool has_inputs; TypePathFnInputs inputs;*/ // inlined from TypePathFnInputs - std::vector<std::unique_ptr<Type> > inputs; + std::vector<std::unique_ptr<Type>> inputs; // bool has_type; std::unique_ptr<Type> return_type; @@ -1115,8 +1034,8 @@ public: } // Constructor - TypePathFunction (std::vector<std::unique_ptr<Type> > inputs, - location_t locus, std::unique_ptr<Type> type = nullptr) + TypePathFunction (std::vector<std::unique_ptr<Type>> inputs, location_t locus, + std::unique_ptr<Type> type = nullptr) : inputs (std::move (inputs)), return_type (std::move (type)), is_invalid (false), locus (locus) {} @@ -1161,11 +1080,11 @@ public: std::string as_string () const; // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Type> > &get_params () const + const std::vector<std::unique_ptr<Type>> &get_params () const { return inputs; } - std::vector<std::unique_ptr<Type> > &get_params () { return inputs; } + std::vector<std::unique_ptr<Type>> &get_params () { return inputs; } // TODO: is this better? Or is a "vis_pattern" better? Type &get_return_type () @@ -1229,10 +1148,10 @@ public: } }; -class TypePath : public TypeNoBounds, public Path +class TypePath : public TypeNoBounds { bool has_opening_scope_resolution; - std::vector<std::unique_ptr<TypePathSegment> > segments; + std::vector<std::unique_ptr<TypePathSegment>> segments; location_t locus; protected: @@ -1257,12 +1176,20 @@ public: // Creates an error state TypePath. static TypePath create_error () { - return TypePath (std::vector<std::unique_ptr<TypePathSegment> > (), + return TypePath (std::vector<std::unique_ptr<TypePathSegment>> (), UNDEF_LOCATION); } // Constructor - TypePath (std::vector<std::unique_ptr<TypePathSegment> > segments, + TypePath (std::vector<std::unique_ptr<TypePathSegment>> segments, + location_t locus, bool has_opening_scope_resolution = false) + : TypeNoBounds (), + has_opening_scope_resolution (has_opening_scope_resolution), + segments (std::move (segments)), locus (locus) + {} + + TypePath (LangItem::Kind lang_item, + std::vector<std::unique_ptr<TypePathSegment>> segments, location_t locus, bool has_opening_scope_resolution = false) : TypeNoBounds (), has_opening_scope_resolution (has_opening_scope_resolution), @@ -1308,7 +1235,7 @@ public: TraitBound *to_trait_bound (bool in_parens) const override; location_t get_locus () const override final { return locus; } - NodeId get_node_id () const override final { return node_id; } + NodeId get_node_id () const { return node_id; } void mark_for_strip () override {} bool is_marked_for_strip () const override { return false; } @@ -1316,27 +1243,23 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: this seems kinda dodgy - std::vector<std::unique_ptr<TypePathSegment> > &get_segments () + std::vector<std::unique_ptr<TypePathSegment>> &get_segments () { return segments; } - const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const + const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const { return segments; } size_t get_num_segments () const { return segments.size (); } - - Path::Kind get_path_kind () const override { return Path::Kind::Type; } - - Path *clone_path_impl () const override { return new TypePath (*this); } }; struct QualifiedPathType { private: std::unique_ptr<Type> type_to_invoke_on; - std::unique_ptr<Path> trait_path; + TypePath trait_path; location_t locus; NodeId node_id; @@ -1345,14 +1268,13 @@ public: QualifiedPathType (std::unique_ptr<Type> invoke_on_type, location_t locus = UNDEF_LOCATION, TypePath trait_path = TypePath::create_error ()) - : type_to_invoke_on (std::move (invoke_on_type)), - trait_path (std::unique_ptr<TypePath> (new TypePath (trait_path))), + : type_to_invoke_on (std::move (invoke_on_type)), trait_path (trait_path), locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ()) {} // Copy constructor uses custom deep copy for Type to preserve polymorphism QualifiedPathType (QualifiedPathType const &other) - : trait_path (other.trait_path->clone_path ()), locus (other.locus) + : trait_path (other.trait_path), locus (other.locus) { node_id = other.node_id; // guard to prevent null dereference @@ -1367,7 +1289,7 @@ public: QualifiedPathType &operator= (QualifiedPathType const &other) { node_id = other.node_id; - trait_path = other.trait_path->clone_path (); + trait_path = other.trait_path; locus = other.locus; // guard to prevent null dereference @@ -1384,11 +1306,7 @@ public: QualifiedPathType &operator= (QualifiedPathType &&other) = default; // Returns whether the qualified path type has a rebind as clause. - bool has_as_clause () const - { - rust_assert (trait_path->get_path_kind () == Path::Kind::Type); - return !static_cast<TypePath &> (*trait_path).is_error (); - } + bool has_as_clause () const { return !trait_path.is_error (); } // Returns whether the qualified path type is in an error state. bool is_error () const { return type_to_invoke_on == nullptr; } @@ -1417,10 +1335,10 @@ public: } // TODO: is this better? Or is a "vis_pattern" better? - Path &get_as_type_path () + TypePath &get_as_type_path () { rust_assert (has_as_clause ()); - return *trait_path; + return trait_path; } NodeId get_node_id () const { return node_id; } @@ -1428,12 +1346,12 @@ public: /* AST node representing a qualified path-in-expression pattern (path that * allows specifying trait functions) */ -class QualifiedPathInExpression : public Pattern, public ExprWithoutBlock +class QualifiedPathInExpression : public Path, public ExprWithoutBlock { std::vector<Attribute> outer_attrs; QualifiedPathType path_type; - - std::unique_ptr<Path> path; + location_t locus; + NodeId _node_id; public: std::string as_string () const override; @@ -1442,16 +1360,9 @@ public: std::vector<PathExprSegment> path_segments, std::vector<Attribute> outer_attrs, location_t locus) - : outer_attrs (std::move (outer_attrs)), - path_type (std::move (qual_path_type)), - path (std::make_unique<RegularPath> ( - std::move (path_segments), locus, - Analysis::Mappings::get ().get_next_node_id ())) - {} - - QualifiedPathInExpression (const QualifiedPathInExpression &other) - : outer_attrs (other.outer_attrs), path_type (other.path_type), - path (other.path->clone_path ()) + : Path (std::move (path_segments)), outer_attrs (std::move (outer_attrs)), + path_type (std::move (qual_path_type)), locus (locus), + _node_id (Analysis::Mappings::get ().get_next_node_id ()) {} /* TODO: maybe make a shortcut constructor that has QualifiedPathType @@ -1467,9 +1378,7 @@ public: {}, UNDEF_LOCATION); } - Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; } - - location_t get_locus () const override final { return path->get_locus (); } + location_t get_locus () const override final { return locus; } void accept_vis (ASTVisitor &vis) override; @@ -1495,31 +1404,7 @@ public: outer_attrs = std::move (new_attrs); } - NodeId get_node_id () const override { return path->get_node_id (); } - - const std::vector<PathExprSegment> &get_segments () const - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments (); - - rust_unreachable (); - } - - std::vector<PathExprSegment> &get_segments () - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments (); - - rust_unreachable (); - } - - bool is_single_segment () const - { - if (path->get_path_kind () == Path::Kind::Regular) - return static_cast<RegularPath &> (*path).get_segments ().size () == 1; - - rust_unreachable (); - } + NodeId get_node_id () const override { return _node_id; } Expr::Kind get_expr_kind () const override { @@ -1555,7 +1440,7 @@ class QualifiedPathInType : public TypeNoBounds { QualifiedPathType path_type; std::unique_ptr<TypePathSegment> associated_segment; - std::vector<std::unique_ptr<TypePathSegment> > segments; + std::vector<std::unique_ptr<TypePathSegment>> segments; location_t locus; protected: @@ -1570,7 +1455,7 @@ public: QualifiedPathInType ( QualifiedPathType qual_path_type, std::unique_ptr<TypePathSegment> associated_segment, - std::vector<std::unique_ptr<TypePathSegment> > path_segments, + std::vector<std::unique_ptr<TypePathSegment>> path_segments, location_t locus) : path_type (std::move (qual_path_type)), associated_segment (std::move (associated_segment)), @@ -1617,7 +1502,7 @@ public: { return QualifiedPathInType ( QualifiedPathType::create_error (), nullptr, - std::vector<std::unique_ptr<TypePathSegment> > (), UNDEF_LOCATION); + std::vector<std::unique_ptr<TypePathSegment>> (), UNDEF_LOCATION); } std::string as_string () const override; @@ -1637,11 +1522,11 @@ public: } // TODO: this seems kinda dodgy - std::vector<std::unique_ptr<TypePathSegment> > &get_segments () + std::vector<std::unique_ptr<TypePathSegment>> &get_segments () { return segments; } - const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const + const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const { return segments; } diff --git a/gcc/rust/expand/rust-derive-copy.cc b/gcc/rust/expand/rust-derive-copy.cc index f8007abd575e..bcfe1db6b4a1 100644 --- a/gcc/rust/expand/rust-derive-copy.cc +++ b/gcc/rust/expand/rust-derive-copy.cc @@ -46,7 +46,9 @@ DeriveCopy::copy_impl ( // `$crate::core::marker::Copy` instead auto segments = std::vector<std::unique_ptr<TypePathSegment>> (); segments.emplace_back (builder.type_path_segment ("Copy")); - auto copy = std::make_unique<LangItemPath> (LangItem::Kind::COPY, loc); + + auto copy = TypePath (std::move (segments), loc); + // auto copy = TypePath (LangItem::Kind::COPY, loc); // we need to build up the generics for this impl block which will be just a // clone of the types specified ones diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h index 967064c04208..1924432d8ed1 100644 --- a/gcc/rust/expand/rust-derive.h +++ b/gcc/rust/expand/rust-derive.h @@ -81,8 +81,6 @@ private: virtual void visit (Lifetime &lifetime) override final{}; virtual void visit (LifetimeParam &lifetime_param) override final{}; virtual void visit (ConstGenericParam &const_param) override final{}; - virtual void visit (RegularPath &path) override final{}; - virtual void visit (LangItemPath &path) override final{}; virtual void visit (PathInExpression &path) override final{}; virtual void visit (TypePathSegment &segment) override final{}; virtual void visit (TypePathSegmentGeneric &segment) override final{}; diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index f6d7f0caf5b8..35a25093b73a 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -64,12 +64,6 @@ ASTLoweringBase::visit (AST::ConstGenericParam &) // rust-path.h void -ASTLoweringBase::visit (AST::RegularPath &) -{} -void -ASTLoweringBase::visit (AST::LangItemPath &) -{} -void ASTLoweringBase::visit (AST::PathInExpression &) {} void diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h index 4cb098b7ab8e..1bd1343bd166 100644 --- a/gcc/rust/hir/rust-ast-lower-base.h +++ b/gcc/rust/hir/rust-ast-lower-base.h @@ -84,8 +84,6 @@ public: // virtual void visit(TraitImplItem& trait_impl_item); // rust-path.h - virtual void visit (AST::RegularPath &path); - virtual void visit (AST::LangItemPath &path); virtual void visit (AST::PathInExpression &path); virtual void visit (AST::TypePathSegment &segment); virtual void visit (AST::TypePathSegmentGeneric &segment); diff --git a/gcc/rust/hir/rust-ast-lower-type.cc b/gcc/rust/hir/rust-ast-lower-type.cc index d1f95edc3456..e78c1307523d 100644 --- a/gcc/rust/hir/rust-ast-lower-type.cc +++ b/gcc/rust/hir/rust-ast-lower-type.cc @@ -27,22 +27,10 @@ namespace Rust { namespace HIR { HIR::TypePath * -ASTLowerTypePath::translate (AST::Path &type) +ASTLowerTypePath::translate (AST::TypePath &type) { ASTLowerTypePath resolver; - - switch (type.get_path_kind ()) - { - case AST::Path::Kind::LangItem: - resolver.visit (static_cast<AST::LangItemPath &> (type)); - break; - case AST::Path::Kind::Type: - resolver.visit (static_cast<AST::TypePath &> (type)); - break; - default: - rust_unreachable (); - } - + type.accept_vis (resolver); rust_assert (resolver.translated != nullptr); return resolver.translated; } @@ -98,10 +86,6 @@ ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment) { std::vector<HIR::GenericArgsBinding> binding_args; // TODO - std::string segment_name = segment.get_ident_segment ().as_string (); - bool has_separating_scope_resolution - = segment.get_separating_scope_resolution (); - auto generic_args = lower_generic_args (segment.get_generic_args ()); auto crate_num = mappings.get_current_crate (); @@ -109,10 +93,24 @@ ASTLowerTypePath::visit (AST::TypePathSegmentGeneric &segment) Analysis::NodeMapping mapping (crate_num, segment.get_node_id (), hirid, UNKNOWN_LOCAL_DEFID); - translated_segment - = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name, - has_separating_scope_resolution, - generic_args, segment.get_locus ()); + if (segment.is_lang_item ()) + { + translated_segment + = new HIR::TypePathSegmentGeneric (std::move (mapping), + segment.get_lang_item (), + generic_args, segment.get_locus ()); + } + else + { + std::string segment_name = segment.get_ident_segment ().as_string (); + bool has_separating_scope_resolution + = segment.get_separating_scope_resolution (); + + translated_segment + = new HIR::TypePathSegmentGeneric (std::move (mapping), segment_name, + has_separating_scope_resolution, + generic_args, segment.get_locus ()); + } } void @@ -141,25 +139,26 @@ ASTLowerTypePath::visit (AST::TypePath &path) path.has_opening_scope_resolution_op ()); } -void -ASTLowerTypePath::visit (AST::LangItemPath &path) -{ - auto crate_num = mappings.get_current_crate (); - auto hirid = mappings.get_next_hir_id (crate_num); +// void +// ASTLowerTypePath::visit (AST::LangItemPath &path) +// { +// auto crate_num = mappings.get_current_crate (); +// auto hirid = mappings.get_next_hir_id (crate_num); - Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid, - mappings.get_next_localdef_id (crate_num)); +// Analysis::NodeMapping mapping (crate_num, path.get_node_id (), hirid, +// mappings.get_next_localdef_id (crate_num)); - std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments; - translated_segments.emplace_back (std::unique_ptr<HIR::TypePathSegment> ( - new HIR::TypePathSegment (mapping, - LangItem::ToString (path.get_lang_item_kind ()), - false, path.get_locus ()))); +// std::vector<std::unique_ptr<HIR::TypePathSegment>> translated_segments; +// translated_segments.emplace_back (std::unique_ptr<HIR::TypePathSegment> ( +// new HIR::TypePathSegment (mapping, +// LangItem::ToString (path.get_lang_item_kind ()), +// false, path.get_locus ()))); - translated - = new HIR::TypePath (std::move (mapping), std::move (translated_segments), - path.get_locus ()); -} +// translated +// = new HIR::TypePath (std::move (mapping), std::move +// (translated_segments), +// path.get_locus ()); +// } HIR::QualifiedPathInType * ASTLowerQualifiedPathInType::translate (AST::QualifiedPathInType &type) diff --git a/gcc/rust/hir/rust-ast-lower-type.h b/gcc/rust/hir/rust-ast-lower-type.h index 26ca8684083c..af0b4bec9194 100644 --- a/gcc/rust/hir/rust-ast-lower-type.h +++ b/gcc/rust/hir/rust-ast-lower-type.h @@ -33,22 +33,18 @@ protected: using Rust::HIR::ASTLoweringBase::visit; public: - static HIR::TypePath *translate (AST::Path &type); + static HIR::TypePath *translate (AST::TypePath &type); void visit (AST::TypePathSegmentFunction &segment) override; void visit (AST::TypePathSegment &segment) override; void visit (AST::TypePathSegmentGeneric &segment) override; void visit (AST::TypePath &path) override; - void visit (AST::LangItemPath &path) override; protected: HIR::TypePathSegment *translated_segment; private: HIR::TypePath *translated; - - static HIR::TypePath *translate_type_path (AST::TypePath &type); - static HIR::TypePath *translate_lang_item_type_path (AST::LangItemPath &type); }; class ASTLowerQualifiedPathInType : public ASTLowerTypePath diff --git a/gcc/rust/hir/tree/rust-hir-path.cc b/gcc/rust/hir/tree/rust-hir-path.cc index c8d3079a85e3..7db2b25b5aaf 100644 --- a/gcc/rust/hir/tree/rust-hir-path.cc +++ b/gcc/rust/hir/tree/rust-hir-path.cc @@ -17,6 +17,7 @@ // <http://www.gnu.org/licenses/>. #include "rust-hir-path.h" +#include "optional.h" #include "rust-hir-bound.h" namespace Rust { @@ -164,17 +165,25 @@ TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, bool has_separating_scope_resolution, location_t locus) : mappings (std::move (mappings)), ident_segment (std::move (ident_segment)), - locus (locus), + lang_item (tl::nullopt), locus (locus), has_separating_scope_resolution (has_separating_scope_resolution), type (SegmentType::REG) {} +TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, location_t locus) + : mappings (std::move (mappings)), ident_segment (tl::nullopt), + lang_item (lang_item), locus (locus), + has_separating_scope_resolution (false), type (SegmentType::REG) +{} + TypePathSegment::TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name, bool has_separating_scope_resolution, location_t locus) : mappings (std::move (mappings)), - ident_segment (PathIdentSegment (std::move (segment_name))), locus (locus), + ident_segment (PathIdentSegment (std::move (segment_name))), + lang_item (tl::nullopt), locus (locus), has_separating_scope_resolution (has_separating_scope_resolution), type (SegmentType::REG) {} @@ -188,6 +197,14 @@ TypePathSegmentGeneric::TypePathSegmentGeneric ( generic_args (std::move (generic_args)) {} +TypePathSegmentGeneric::TypePathSegmentGeneric (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, + GenericArgs generic_args, + location_t locus) + : TypePathSegment (std::move (mappings), lang_item, locus), + generic_args (std::move (generic_args)) +{} + TypePathSegmentGeneric::TypePathSegmentGeneric ( Analysis::NodeMapping mappings, std::string segment_name, bool has_separating_scope_resolution, std::vector<Lifetime> lifetime_args, diff --git a/gcc/rust/hir/tree/rust-hir-path.h b/gcc/rust/hir/tree/rust-hir-path.h index 7ef66b86ab0e..bbb9c2d60773 100644 --- a/gcc/rust/hir/tree/rust-hir-path.h +++ b/gcc/rust/hir/tree/rust-hir-path.h @@ -355,7 +355,8 @@ public: private: Analysis::NodeMapping mappings; - PathIdentSegment ident_segment; + tl::optional<PathIdentSegment> ident_segment; + tl::optional<LangItem::Kind> lang_item; location_t locus; protected: @@ -384,14 +385,27 @@ public: PathIdentSegment ident_segment, bool has_separating_scope_resolution, location_t locus); + TypePathSegment (Analysis::NodeMapping mappings, LangItem::Kind lang_item, + location_t locus); + TypePathSegment (Analysis::NodeMapping mappings, std::string segment_name, bool has_separating_scope_resolution, location_t locus); - virtual std::string as_string () const { return ident_segment.as_string (); } + virtual std::string as_string () const + { + if (ident_segment) + return ident_segment->as_string (); + + return LangItem::PrettyString (*lang_item); + } /* Returns whether the type path segment is in an error state. May be virtual * in future. */ - bool is_error () const { return ident_segment.is_error (); } + bool is_error () const + { + rust_assert (ident_segment); + return ident_segment->is_error (); + } /* Returns whether segment is identifier only (as opposed to generic args or * function). Overriden in derived classes with other segments. */ @@ -404,12 +418,24 @@ public: const Analysis::NodeMapping &get_mappings () const { return mappings; } - const PathIdentSegment &get_ident_segment () const { return ident_segment; } + const PathIdentSegment &get_ident_segment () const + { + rust_assert (ident_segment); + return *ident_segment; + } + + const LangItem::Kind &get_lang_item () const + { + rust_assert (lang_item); + return *lang_item; + } bool is_generic_segment () const { return get_type () == SegmentType::GENERIC; } + + bool is_lang_item () const { return lang_item.has_value (); } }; // Segment used in type path with generic args @@ -428,6 +454,10 @@ public: bool has_separating_scope_resolution, GenericArgs generic_args, location_t locus); + TypePathSegmentGeneric (Analysis::NodeMapping mappings, + LangItem::Kind lang_item, GenericArgs generic_args, + location_t locus); + // Constructor from segment name and all args TypePathSegmentGeneric (Analysis::NodeMapping mappings, std::string segment_name, diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc index b23c1eba1121..6c35a22b7f64 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ b/gcc/rust/resolve/rust-ast-resolve-base.cc @@ -71,14 +71,6 @@ void ResolverBase::visit (AST::ConstGenericParam &) {} -void -ResolverBase::visit (AST::RegularPath &) -{} - -void -ResolverBase::visit (AST::LangItemPath &) -{} - void ResolverBase::visit (AST::PathInExpression &) {} diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 703460ad0d93..0d497f81eacc 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -40,8 +40,6 @@ public: void visit (AST::Lifetime &); void visit (AST::LifetimeParam &); void visit (AST::ConstGenericParam &); - void visit (AST::RegularPath &); - void visit (AST::LangItemPath &); void visit (AST::PathInExpression &); void visit (AST::TypePathSegment &); void visit (AST::TypePathSegmentGeneric &); diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc index 33b4fc9b9792..b26ac340e926 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ b/gcc/rust/resolve/rust-ast-resolve-item.cc @@ -682,28 +682,15 @@ ResolveItem::visit (AST::TraitImpl &impl_block) // setup paths CanonicalPath canonical_trait_type = CanonicalPath::create_empty (); - if (impl_block.get_trait_path ().get_path_kind () - == AST::Path::Kind::LangItem) - { - auto &lang_item - = static_cast<AST::LangItemPath &> (impl_block.get_trait_path ()); - canonical_trait_type - = CanonicalPath::new_seg (lang_item.get_node_id (), - LangItem::ToString ( - lang_item.get_lang_item_kind ())); - } - else + ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (), + canonical_trait_type); + if (!ok) { - ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path_type (), - canonical_trait_type); - if (!ok) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } + resolver->get_name_scope ().pop (); + resolver->get_type_scope ().pop (); + resolver->get_label_scope ().pop (); + return; } rust_debug ("AST::TraitImpl resolve trait type: {%s}", diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index 1d004b1ba9bb..63c9daca565f 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ b/gcc/rust/resolve/rust-ast-resolve-type.cc @@ -20,6 +20,7 @@ #include "rust-ast-resolve-expr.h" #include "rust-canonical-path.h" #include "rust-type.h" +#include "rust-hir-map.h" namespace Rust { namespace Resolver { @@ -99,45 +100,57 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) for (size_t i = 0; i < path.get_segments ().size (); i++) { auto &segment = path.get_segments ().at (i); - const AST::PathIdentSegment &ident_seg = segment->get_ident_segment (); bool is_first_segment = i == 0; - resolved_node_id = UNKNOWN_NODEID; + NodeId crate_scope_id = resolver->peek_crate_module_scope (); + auto ident_string = segment->is_lang_item () + ? LangItem::PrettyString (segment->get_lang_item ()) + : segment->get_ident_segment ().as_string (); - bool in_middle_of_path = i > 0; - if (in_middle_of_path && segment->is_lower_self_seg ()) - { - rust_error_at (segment->get_locus (), ErrorCode::E0433, - "failed to resolve: %qs in paths can only be used " - "in start position", - segment->as_string ().c_str ()); - return false; - } + resolved_node_id = UNKNOWN_NODEID; - NodeId crate_scope_id = resolver->peek_crate_module_scope (); - if (segment->is_crate_path_seg ()) + if (segment->is_lang_item ()) { - // what is the current crate scope node id? - module_scope_id = crate_scope_id; - previous_resolved_node_id = module_scope_id; - resolver->insert_resolved_name (segment->get_node_id (), - module_scope_id); - - continue; + resolved_node_id = Analysis::Mappings::get ().get_lang_item_node ( + segment->get_lang_item ()); + previous_resolved_node_id = resolved_node_id; } - else if (segment->is_super_path_seg ()) + else { - if (module_scope_id == crate_scope_id) + bool in_middle_of_path = i > 0; + if (in_middle_of_path && segment->is_lower_self_seg ()) { - rust_error_at (segment->get_locus (), - "cannot use super at the crate scope"); + rust_error_at (segment->get_locus (), ErrorCode::E0433, + "failed to resolve: %qs in paths can only be used " + "in start position", + segment->as_string ().c_str ()); return false; } - module_scope_id = resolver->peek_parent_module_scope (); - previous_resolved_node_id = module_scope_id; - resolver->insert_resolved_name (segment->get_node_id (), - module_scope_id); - continue; + if (segment->is_crate_path_seg ()) + { + // what is the current crate scope node id? + module_scope_id = crate_scope_id; + previous_resolved_node_id = module_scope_id; + resolver->insert_resolved_name (segment->get_node_id (), + module_scope_id); + + continue; + } + else if (segment->is_super_path_seg ()) + { + if (module_scope_id == crate_scope_id) + { + rust_error_at (segment->get_locus (), + "cannot use super at the crate scope"); + return false; + } + + module_scope_id = resolver->peek_parent_module_scope (); + previous_resolved_node_id = module_scope_id; + resolver->insert_resolved_name (segment->get_node_id (), + module_scope_id); + continue; + } } switch (segment->get_type ()) @@ -177,8 +190,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) // name scope first NodeId resolved_node = UNKNOWN_NODEID; const CanonicalPath path - = CanonicalPath::new_seg (segment->get_node_id (), - ident_seg.as_string ()); + = CanonicalPath::new_seg (segment->get_node_id (), ident_string); if (resolver->get_type_scope ().lookup (path, &resolved_node)) { resolver->insert_resolved_type (segment->get_node_id (), @@ -191,7 +203,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) resolved_node); resolved_node_id = resolved_node; } - else if (segment->is_lower_self_seg ()) + else if (!segment->is_lang_item () && segment->is_lower_self_seg ()) { // what is the current crate scope node id? module_scope_id = crate_scope_id; @@ -207,8 +219,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) && previous_resolved_node_id == module_scope_id) { tl::optional<CanonicalPath &> resolved_child - = mappings.lookup_module_child (module_scope_id, - ident_seg.as_string ()); + = mappings.lookup_module_child (module_scope_id, ident_string); if (resolved_child.has_value ()) { NodeId resolved_node = resolved_child->get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index 5e8cdb11b2d7..662f2f5a6683 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -61,37 +61,6 @@ class ResolveType : public ResolverBase using Rust::Resolver::ResolverBase::visit; public: - static NodeId go (AST::TypePath &type_path) - { - return ResolveType::go ((AST::Type &) type_path); - } - - static NodeId go (AST::Path &type_path) - { - if (type_path.get_path_kind () == AST::Path::Kind::LangItem) - { - auto &type = static_cast<AST::LangItemPath &> (type_path); - - auto lang_item = Analysis::Mappings::get () - .lookup_lang_item_node (type.get_lang_item_kind ()) - .value (); - - auto resolver = Resolver::get (); - resolver->insert_resolved_type (type.get_node_id (), lang_item); - - return lang_item; - } - - rust_assert (type_path.get_path_kind () == AST::Path::Kind::Type); - - // We have to do this dance to first downcast to a typepath, and then upcast - // to a Type. The altnernative is to split `go` into `go` and `go_inner` or - // something, but eventually this will need to change as we'll need - // `ResolveType::` to resolve other kinds of `Path`s as well. - return ResolveType::go ( - (AST::Type &) static_cast<AST::TypePath &> (type_path)); - } - static NodeId go (AST::Type &type) { ResolveType resolver; diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index bb099ab68aec..9da56ea3214d 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -248,25 +248,6 @@ Late::visit (AST::PathInExpression &expr) Definition (resolved->get_node_id ())); } -void -Late::visit (AST::LangItemPath &type) -{ - auto &mappings = Rust::Analysis::Mappings::get (); - auto lang_item = mappings.lookup_lang_item_node (type.get_lang_item_kind ()); - - if (!lang_item) - { - rust_fatal_error ( - type.get_locus (), "use of undeclared lang item %qs", - LangItem::ToString (type.get_lang_item_kind ()).c_str ()); - return; - } - - ctx.map_usage (Usage (type.get_node_id ()), Definition (lang_item.value ())); - - DefaultResolver::visit (type); -} - void Late::visit (AST::TypePath &type) { diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h b/gcc/rust/resolve/rust-late-name-resolver-2.0.h index 2af73c382869..ade78c5bc5f0 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h @@ -46,7 +46,6 @@ public: // resolutions void visit (AST::IdentifierExpr &) override; void visit (AST::PathInExpression &) override; - void visit (AST::LangItemPath &) override; void visit (AST::TypePath &) override; void visit (AST::Trait &) override; void visit (AST::StructExprStruct &) override; diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index bb23f8441edd..9f19facdffe3 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -410,7 +410,7 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset, { rust_error_at (seg->get_locus (), "unknown reference for resolved name: %qs", - seg->get_ident_segment ().as_string ().c_str ()); + seg->as_string ().c_str ()); return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); } return root_tyty;