aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/ast
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-06-03 15:12:00 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-06-10 17:09:34 +0100
commit7ca7362602d4e827ecbc39d5cfdf56df9044633b (patch)
tree7e149ddc7c9ffb0f72bcd4be2459abc7d1ee688a /gcc/rust/ast
parentfc3ef6c4b1fad0d88a65043df8102437416b1df3 (diff)
downloadgcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.zip
gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.gz
gcc-7ca7362602d4e827ecbc39d5cfdf56df9044633b.tar.bz2
This patch implements complex Path resolution
This patch completely reimplements our name resolution process for Paths in general. This patch gets rid of the old Resolver::Definition structures which were used so that we can map patterns back to LetStmts and establish an hierarchy of nodes. This was not nessecary and complicated name/type resolution. TypePaths and PathInExpression are similar but have a slightl tweak in the order they lookup the relevant scopes for types. But overall work the same. There are several cases of paths you must consider in type resolution: - i32 (simple type path) - Self::A (associated type reference) - mod::foo::impl_item() (reference to impl item) - super::foo (reference to impl item) - crate::foo - T::bound() In name resolution we cannot always fully resolve a path but have to rely on the type-resolution to fully resolve a path as it may require careful thought. For example a path like: mod::foo::item() might be for a generic foo<T>(), which might have two specialized impl blocks so the best the name resolution can do is resolve mod::foo then leave it up to the type resolution to figure out which item this is. We might have i32 which is just a simple lookup. Apart from that this patch introduces a module parent child hierachy so that on paths such as super::foo we resolve super to be our parent module scope then foo can be resolved with the lookup in the items for that module. More over this patch gets rid of some but not all of the awkward name canonicalization to try and patch paths directly. More cleanup is still needed here to make the name resolution step easier to read. This was notable in the Qualified path handling where we can now rely on the type resolver to setup the associated types properly rather than the name resolver requiring us to resolve this directly. Fixes #1251 #1230 Addresses #1227 #1153
Diffstat (limited to 'gcc/rust/ast')
-rw-r--r--gcc/rust/ast/rust-ast.h12
-rw-r--r--gcc/rust/ast/rust-path.h54
2 files changed, 57 insertions, 9 deletions
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 69ad6eb..8f5657f 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -350,8 +350,16 @@ public:
Location get_locus () const { return locus; }
NodeId get_node_id () const { return node_id; }
const std::string &get_segment_name () const { return segment_name; }
-
- // TODO: visitor pattern?
+ 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 () const { return as_string ().compare ("self") == 0; }
+ bool is_big_self () const { return as_string ().compare ("Self") == 0; }
};
// A simple path without generic or type arguments
diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h
index 593f979..45d08bf 100644
--- a/gcc/rust/ast/rust-path.h
+++ b/gcc/rust/ast/rust-path.h
@@ -38,12 +38,6 @@ public:
: segment_name (std::move (segment_name)), locus (locus)
{}
- /* TODO: insert check in constructor for this? Or is this a semantic error
- * best handled then? */
-
- /* TODO: does this require visitor? pretty sure this isn't polymorphic, but
- * not entirely sure */
-
// Creates an error PathIdentSegment.
static PathIdentSegment create_error ()
{
@@ -54,6 +48,11 @@ public:
bool is_error () const { return segment_name.empty (); }
std::string as_string () const { return segment_name; }
+
+ 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; }
};
// A binding of an identifier to a type used in generic arguments in paths
@@ -264,8 +263,23 @@ public:
}
PathIdentSegment &get_ident_segment () { return segment_name; }
+ const PathIdentSegment &get_ident_segment () const { return segment_name; }
NodeId get_node_id () const { return node_id; }
+
+ bool is_super_path_seg () const
+ {
+ return !has_generic_args () && get_ident_segment ().is_super_segment ();
+ }
+
+ bool is_crate_path_seg () const
+ {
+ return !has_generic_args () && get_ident_segment ().is_crate_segment ();
+ }
+ bool is_lower_self_seg () const
+ {
+ return !has_generic_args () && get_ident_segment ().is_lower_self ();
+ }
};
// AST node representing a pattern that involves a "path" - abstract base class
@@ -397,6 +411,15 @@ protected:
* ident-only segment) */
class TypePathSegment
{
+public:
+ enum SegmentType
+ {
+ REG,
+ GENERIC,
+ FUNCTION
+ };
+
+private:
PathIdentSegment ident_segment;
Location locus;
@@ -415,6 +438,8 @@ protected:
public:
virtual ~TypePathSegment () {}
+ virtual SegmentType get_type () const { return SegmentType::REG; }
+
// Unique pointer custom clone function
std::unique_ptr<TypePathSegment> clone_type_path_segment () const
{
@@ -456,9 +481,20 @@ public:
return has_separating_scope_resolution;
}
- PathIdentSegment get_ident_segment () { return ident_segment; };
+ PathIdentSegment &get_ident_segment () { return ident_segment; };
+ const PathIdentSegment &get_ident_segment () const { return ident_segment; };
NodeId get_node_id () const { return node_id; }
+
+ bool is_crate_path_seg () const
+ {
+ return get_ident_segment ().is_crate_segment ();
+ }
+ bool is_super_path_seg () const
+ {
+ return get_ident_segment ().is_super_segment ();
+ }
+ bool is_big_self_seg () const { return get_ident_segment ().is_big_self (); }
};
// Segment used in type path with generic args
@@ -467,6 +503,8 @@ class TypePathSegmentGeneric : public TypePathSegment
GenericArgs generic_args;
public:
+ SegmentType get_type () const override { return SegmentType::GENERIC; }
+
bool has_generic_args () const { return generic_args.has_generic_args (); }
bool is_ident_only () const override { return false; }
@@ -620,6 +658,8 @@ class TypePathSegmentFunction : public TypePathSegment
TypePathFunction function_path;
public:
+ SegmentType get_type () const override { return SegmentType::FUNCTION; }
+
// Constructor with PathIdentSegment and TypePathFn
TypePathSegmentFunction (PathIdentSegment ident_segment,
bool has_separating_scope_resolution,