aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-08-31 12:22:18 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-08-31 12:22:18 +0100
commit2ab6f9ee9f294bcd38378905d94fe7b280524414 (patch)
treeb0047c7b6d3a1717d3f592ab5ed13447dab04e57 /gcc
parent0e3030707bfcd196fd678a25bf28fbdb925914c4 (diff)
downloadgcc-2ab6f9ee9f294bcd38378905d94fe7b280524414.zip
gcc-2ab6f9ee9f294bcd38378905d94fe7b280524414.tar.gz
gcc-2ab6f9ee9f294bcd38378905d94fe7b280524414.tar.bz2
Add name resolution for QualifiedPathInType
Qualified path types allow for TypePaths qualified with a paticular associated impl and type;
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h74
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc44
2 files changed, 116 insertions, 2 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index 97c0311..9ad465a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -97,6 +97,7 @@ public:
class ResolveTypeToCanonicalPath : public ResolverBase
{
+protected:
using Rust::Resolver::ResolverBase::visit;
public:
@@ -128,7 +129,7 @@ public:
static bool type_resolve_generic_args (AST::GenericArgs &args);
-private:
+protected:
ResolveTypeToCanonicalPath (bool include_generic_args,
bool type_resolve_generic_args)
: ResolverBase (UNKNOWN_NODEID), result (CanonicalPath::create_empty ()),
@@ -182,8 +183,10 @@ public:
}
};
-class ResolveRelativeTypePath
+class ResolveRelativeTypePath : public ResolveTypeToCanonicalPath
{
+ using ResolveTypeToCanonicalPath::visit;
+
public:
static NodeId go (AST::TypePath &path, NodeId parent,
const CanonicalPath &prefix,
@@ -218,6 +221,64 @@ public:
return resolved_node;
}
+
+ static NodeId go (AST::QualifiedPathInType &path, NodeId parent,
+ const CanonicalPath &prefix,
+ bool canonicalize_type_with_generics)
+ {
+ auto &qualified_path = path.get_qualified_path_type ();
+ CanonicalPath result = prefix;
+ if (!resolve_qual_seg (qualified_path, result))
+ return UNKNOWN_NODEID;
+
+ // resolve the associated impl
+ auto resolver = Resolver::get ();
+ NodeId projection_resolved_id = UNKNOWN_NODEID;
+ if (!resolver->get_name_scope ().lookup (result, &projection_resolved_id))
+ {
+ rust_error_at (path.get_locus (),
+ "failed to resolve associated path: %s",
+ result.get ().c_str ());
+
+ return UNKNOWN_NODEID;
+ }
+ // mark the resolution for this
+ resolver->insert_resolved_name (qualified_path.get_node_id (),
+ projection_resolved_id);
+
+ // qualified types are similar to other paths in that we cannot guarantee
+ // that we can resolve the path at name resolution. We must look up
+ // associated types and type information to figure this out properly
+
+ ResolveRelativeTypePath o (result);
+ std::unique_ptr<AST::TypePathSegment> &associated
+ = path.get_associated_segment ();
+
+ associated->accept_vis (o);
+ if (o.failure_flag)
+ return UNKNOWN_NODEID;
+
+ for (auto &seg : path.get_segments ())
+ {
+ seg->accept_vis (o);
+ if (o.failure_flag)
+ return UNKNOWN_NODEID;
+ }
+
+ // we only return the projection id for now since we need the type system to
+ // resolve the associated types in this path
+ return projection_resolved_id;
+ }
+
+private:
+ ResolveRelativeTypePath (CanonicalPath qualified_path)
+ : ResolveTypeToCanonicalPath (true, true)
+ {
+ result = qualified_path;
+ }
+
+ static bool resolve_qual_seg (AST::QualifiedPathType &seg,
+ CanonicalPath &result);
};
class ResolveType : public ResolverBase
@@ -275,6 +336,15 @@ public:
}
}
+ void visit (AST::QualifiedPathInType &path) override
+ {
+ resolved_node
+ = ResolveRelativeTypePath::go (path, parent,
+ CanonicalPath::create_empty (),
+ canonicalize_type_with_generics);
+ ok = resolved_node != UNKNOWN_NODEID;
+ }
+
void visit (AST::ArrayType &type) override;
void visit (AST::ReferenceType &type) override
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 9d79b36..1f90181 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -744,5 +744,49 @@ ResolveItem::resolve_extern_item (AST::ExternalItem *item)
ResolveExternItem::go (item);
}
+// qualified path in type
+
+bool
+ResolveRelativeTypePath::resolve_qual_seg (AST::QualifiedPathType &seg,
+ CanonicalPath &result)
+{
+ if (seg.is_error ())
+ {
+ rust_error_at (seg.get_locus (), "segment has error: %s",
+ seg.as_string ().c_str ());
+ return false;
+ }
+
+ bool canonicalize_type_with_generics = true;
+ NodeId type_resolved_node
+ = ResolveType::go (seg.get_type ().get (), seg.get_node_id (),
+ canonicalize_type_with_generics);
+ if (type_resolved_node == UNKNOWN_NODEID)
+ return false;
+
+ CanonicalPath impl_type_seg
+ = ResolveTypeToCanonicalPath::resolve (*seg.get_type ().get ());
+ if (!seg.has_as_clause ())
+ {
+ result = result.append (impl_type_seg);
+ return true;
+ }
+
+ NodeId trait_resolved_node
+ = ResolveType::go (&seg.get_as_type_path (), seg.get_node_id (),
+ canonicalize_type_with_generics);
+
+ if (trait_resolved_node == UNKNOWN_NODEID)
+ return false;
+
+ CanonicalPath trait_type_seg
+ = ResolveTypeToCanonicalPath::resolve (seg.get_as_type_path ());
+ CanonicalPath projection
+ = TraitImplProjection::resolve (seg.get_node_id (), trait_type_seg,
+ impl_type_seg);
+ result = result.append (projection);
+ return true;
+}
+
} // namespace Resolver
} // namespace Rust