aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2024-12-26 21:46:03 +0000
committerCohenArthur <arthur.cohen@embecosm.com>2025-01-16 14:00:31 +0000
commit432859bf783a7dc9fb81f267c5159c60435973cb (patch)
treef0581fcf770e63924f3094074b4e2266cfc3fc9e /gcc
parent955c4f7e587c082f0d364e4305c78b35822bd6ab (diff)
downloadgcc-432859bf783a7dc9fb81f267c5159c60435973cb.zip
gcc-432859bf783a7dc9fb81f267c5159c60435973cb.tar.gz
gcc-432859bf783a7dc9fb81f267c5159c60435973cb.tar.bz2
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc20
-rw-r--r--gcc/rust/ast/rust-ast-builder.h4
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc13
-rw-r--r--gcc/rust/ast/rust-ast-collector.h2
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc11
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h4
-rw-r--r--gcc/rust/ast/rust-ast.cc4
-rw-r--r--gcc/rust/ast/rust-item.h40
-rw-r--r--gcc/rust/ast/rust-path.cc31
-rw-r--r--gcc/rust/ast/rust-path.h405
-rw-r--r--gcc/rust/expand/rust-derive-copy.cc4
-rw-r--r--gcc/rust/expand/rust-derive.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc6
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h2
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.cc75
-rw-r--r--gcc/rust/hir/rust-ast-lower-type.h6
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.cc21
-rw-r--r--gcc/rust/hir/tree/rust-hir-path.h38
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc8
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc27
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc79
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h31
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc19
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h1
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc2
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 90832e2..d10b64e 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -43,15 +43,6 @@ Builder::call (std::unique_ptr<Expr> &&path,
}
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
{
auto args = std::vector<std::unique_ptr<Expr>> ();
@@ -61,15 +52,6 @@ Builder::call (std::unique_ptr<Expr> &&path, std::unique_ptr<Expr> &&arg) const
}
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
{
auto elts = std::make_unique<ArrayElemsValues> (std::move (members), loc);
@@ -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 8546909..2c7b3f8 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 da03849..d9ebaee 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -539,19 +539,6 @@ TokenCollector::visit (PathInExpression &path)
}
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)
{
// Syntax:
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index b464907..3266caf 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 28142f0..6c8aeeb 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -86,17 +86,6 @@ DefaultASTVisitor::visit (AST::ConstGenericParam &const_param)
}
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)
{
visit_outer_attrs (path);
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index eeb4e95..20f735d 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 ce4254a..0264104 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 a9ee376..1893822 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 3a7e6e3..02f1f1b 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 ();
@@ -191,18 +190,6 @@ RegularPath::convert_to_simple_path (bool with_opening_scope_resolution) const
}
void
-RegularPath::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
-LangItemPath::accept_vis (ASTVisitor &vis)
-{
- vis.visit (*this);
-}
-
-void
PathInExpression::accept_vis (ASTVisitor &vis)
{
vis.visit (*this);
@@ -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 ae40a7e..c5afc8f 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 927d1c5..358a52e 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 ef7752b..517fee6 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 eac2cba..229f6e0 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 203b702..b197b4a 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 605a2e5..83532f8 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 1e88ec2..042eacb 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 c8d3079..7db2b25 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 df5fd0c..f622add 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 74b2756..9cc980a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -72,14 +72,6 @@ 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 bc3e048..7f01d50 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 619efb0..ca09c2e 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 a4878a2..6cd8571 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: %<%s%> 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 3a7dbd6..5870aca 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 974e1fa..60b8952 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -249,25 +249,6 @@ Late::visit (AST::PathInExpression &expr)
}
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)
{
// should we add type path resolution in `ForeverStack` directly? Since it's
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 0db21f2..0efa693 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 ad4199a..7e623e0 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;