aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast/rust-path.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/ast/rust-path.h')
-rw-r--r--gcc/rust/ast/rust-path.h408
1 files changed, 175 insertions, 233 deletions
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 98fde5a..805be8e 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"
@@ -55,10 +56,16 @@ public:
location_t get_locus () const { return locus; }
- bool is_super_segment () const { return as_string ().compare ("super") == 0; }
- bool is_crate_segment () const { return as_string ().compare ("crate") == 0; }
- bool is_lower_self () const { return as_string ().compare ("self") == 0; }
- bool is_big_self () const { return as_string ().compare ("Self") == 0; }
+ bool is_super_path_seg () const
+ {
+ return as_string ().compare ("super") == 0;
+ }
+ bool is_crate_path_seg () const
+ {
+ return as_string ().compare ("crate") == 0;
+ }
+ bool is_lower_self_seg () const { return as_string ().compare ("self") == 0; }
+ bool is_big_self_seg () const { return as_string ().compare ("Self") == 0; }
};
// A binding of an identifier to a type used in generic arguments in paths
@@ -560,17 +567,17 @@ public:
bool is_super_path_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_super_segment ();
+ return !has_generic_args () && get_ident_segment ().is_super_path_seg ();
}
bool is_crate_path_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_crate_segment ();
+ return !has_generic_args () && get_ident_segment ().is_crate_path_seg ();
}
bool is_lower_self_seg () const
{
- return !has_generic_args () && get_ident_segment ().is_lower_self ();
+ return !has_generic_args () && get_ident_segment ().is_lower_self_seg ();
}
};
@@ -585,104 +592,75 @@ public:
Regular,
};
- virtual Kind get_path_kind () const = 0;
-
- Pattern::Kind get_pattern_kind () override final
- {
- return Pattern::Kind::Path;
- }
-
- location_t get_locus () const override final { return locus; }
- NodeId get_node_id () const override final { return node_id; }
-
- 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:
- location_t locus;
- NodeId node_id;
-
- Path (location_t locus, NodeId node_id) : locus (locus), node_id (node_id) {}
-
- virtual Path *clone_path_impl () const = 0;
-};
-
-class RegularPath : public Path
-{
- std::vector<PathExprSegment> segments;
-
-public:
- explicit RegularPath (std::vector<PathExprSegment> &&segments,
- location_t locus, NodeId node_id)
- : Path (locus, node_id), segments (std::move (segments))
+ 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;
}
-};
-class LangItemPath : public Path
-{
- NodeId lang_item;
- // TODO: Add LangItemKind or w/ever here as well
-
- // TODO: This constructor is wrong
- explicit LangItemPath (NodeId lang_item, location_t locus)
- : Path (locus, lang_item), lang_item (lang_item)
- {}
+ std::string as_string () const override;
- Path::Kind get_path_kind () const override { return Path::Kind::LangItem; }
+ bool is_lang_item () const { return kind == Kind::LangItem; }
- 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 (lang_item, 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; }
+
+protected:
+ std::vector<PathExprSegment> segments;
+ tl::optional<LangItem::Kind> lang_item;
+
+ 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:
@@ -692,61 +670,41 @@ 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 (Rust::make_unique<RegularPath> (std::move (path_segments), locus,
- _node_id)),
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 (LangItem::Kind lang_item,
+ std::vector<Attribute> outer_attrs, location_t locus)
+ : 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 ()),
+ marked_for_strip (false)
{}
- 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 ()
{
- return PathInExpression ({}, {}, UNDEF_LOCATION);
+ return PathInExpression (std::vector<PathExprSegment> (), {},
+ UNDEF_LOCATION);
}
// Returns whether path in expression is in an error state.
- bool is_error () const
- {
- // FIXME: Cleanup
- if (path->get_path_kind () == Path::Kind::Regular)
- return !static_cast<RegularPath &> (*path).has_segments ();
-
- return false;
- }
+ 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; }
@@ -771,63 +729,18 @@ public:
outer_attrs = std::move (new_attrs);
}
- 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 ();
- }
-
- 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 ();
+ return get_segments ().back ();
}
- bool is_single_segment () const
+ Expr::Kind get_expr_kind () const override
{
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
-
- return false;
+ return Expr::Kind::PathInExpression;
}
- Pattern::Kind get_pattern_kind () override { return Pattern::Kind::Path; }
-
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
@@ -861,7 +774,8 @@ public:
};
private:
- PathIdentSegment ident_segment;
+ tl::optional<LangItem::Kind> lang_item;
+ tl::optional<PathIdentSegment> ident_segment;
location_t locus;
protected:
@@ -891,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)
{}
@@ -913,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;
@@ -923,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
@@ -943,23 +879,41 @@ 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; }
bool is_crate_path_seg () const
{
- return get_ident_segment ().is_crate_segment ();
+ return get_ident_segment ().is_crate_path_seg ();
}
bool is_super_path_seg () const
{
- return get_ident_segment ().is_super_segment ();
+ return get_ident_segment ().is_super_path_seg ();
+ }
+ bool is_big_self_seg () const
+ {
+ return get_ident_segment ().is_big_self_seg ();
}
- bool is_big_self_seg () const { return get_ident_segment ().is_big_self (); }
bool is_lower_self_seg () const
{
- return get_ident_segment ().is_lower_self ();
+ return get_ident_segment ().is_lower_self_seg ();
}
};
@@ -984,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,
@@ -1041,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;
@@ -1074,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)
{}
@@ -1120,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 ()
@@ -1188,11 +1148,10 @@ public:
}
};
-// Path used inside types
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:
@@ -1217,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),
@@ -1268,15 +1235,19 @@ public:
TraitBound *to_trait_bound (bool in_parens) const override;
location_t get_locus () const override final { return locus; }
+ NodeId get_node_id () const { return node_id; }
+
+ void mark_for_strip () override {}
+ bool is_marked_for_strip () const override { return false; }
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;
}
@@ -1297,9 +1268,8 @@ 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::move (trait_path)), locus (locus),
- node_id (Analysis::Mappings::get ().get_next_node_id ())
+ : 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
@@ -1376,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;
@@ -1390,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 (Rust::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
@@ -1415,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;
@@ -1443,30 +1404,11 @@ 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 ();
- }
+ NodeId get_node_id () const override { return _node_id; }
- bool is_single_segment () const
+ Expr::Kind get_expr_kind () const override
{
- if (path->get_path_kind () == Path::Kind::Regular)
- return static_cast<RegularPath &> (*path).get_segments ().size () == 1;
-
- return false;
+ return Expr::Kind::QualifiedPathInExpression;
}
protected:
@@ -1498,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:
@@ -1513,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)),
@@ -1560,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;
@@ -1580,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;
}