diff options
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-implitem.h | 22 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-item.h | 12 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.h | 67 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 29 |
4 files changed, 88 insertions, 42 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index d76cbac..d88b275f 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -34,13 +34,19 @@ public: static void go (AST::InherentImplItem *item, AST::Type *base) { ResolveToplevelImplItem resolver (base); + if (resolver.base_path.is_empty ()) + { + rust_error_at (base->get_locus_slow (), + "failed to resolve simple path"); + return; + } item->accept_vis (resolver); - }; + } void visit (AST::ConstantItem &constant) override { std::string identifier - = base->as_string () + "::" + constant.get_identifier (); + = base_path.as_string () + "::" + constant.get_identifier (); resolver->get_name_scope ().insert ( identifier, constant.get_node_id (), constant.get_locus (), false, [&] (std::string, NodeId, Location locus) -> void { @@ -55,7 +61,7 @@ public: void visit (AST::Function &function) override { std::string identifier - = base->as_string () + "::" + function.get_function_name (); + = base_path.as_string () + "::" + function.get_function_name (); resolver->get_name_scope ().insert ( identifier, function.get_node_id (), function.get_locus (), false, [&] (std::string, NodeId, Location locus) -> void { @@ -70,7 +76,7 @@ public: void visit (AST::Method &method) override { std::string identifier - = base->as_string () + "::" + method.get_method_name (); + = base_path.as_string () + "::" + method.get_method_name (); resolver->get_name_scope ().insert ( identifier, method.get_node_id (), method.get_locus (), false, [&] (std::string, NodeId, Location locus) -> void { @@ -84,10 +90,14 @@ public: private: ResolveToplevelImplItem (AST::Type *base) - : ResolverBase (UNKNOWN_NODEID), base (base) - {} + : ResolverBase (UNKNOWN_NODEID), base (base), + base_path (AST::SimplePath::create_empty ()) + { + ResolveTypeToSimplePath::go (base, base_path, true); + } AST::Type *base; + AST::SimplePath base_path; }; } // namespace Resolver diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h index 95e335b..1074031 100644 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ b/gcc/rust/resolve/rust-ast-resolve-item.h @@ -152,6 +152,17 @@ public: void visit (AST::InherentImpl &impl_block) override { + NodeId scope_node_id = impl_block.get_node_id (); + resolver->get_type_scope ().push (scope_node_id); + + if (impl_block.has_generics ()) + { + for (auto &generic : impl_block.get_generic_params ()) + { + ResolveGenericParam::go (generic.get (), impl_block.get_node_id ()); + } + } + NodeId resolved_node = ResolveType::go (impl_block.get_type ().get (), impl_block.get_node_id ()); if (resolved_node == UNKNOWN_NODEID) @@ -164,6 +175,7 @@ public: impl_item->accept_vis (*this); resolver->get_type_scope ().peek ()->clear_name ("Self", resolved_node); + resolver->get_type_scope ().pop (); } void visit (AST::Method &method) override diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h index c829ed0..9e7568e 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ b/gcc/rust/resolve/rust-ast-resolve-type.h @@ -25,25 +25,22 @@ namespace Rust { namespace Resolver { -class ResolveTypePath : public ResolverBase +class ResolveTypeToSimplePath : public ResolverBase { using Rust::Resolver::ResolverBase::visit; public: - static NodeId go (AST::TypePath &path, NodeId parent) + static bool go (AST::Type *type, AST::SimplePath &simple_path_result, + bool path_only = false) { - ResolveTypePath resolver (parent); - resolver.resolve (path); - return resolver.resolved_node; + ResolveTypeToSimplePath resolver (simple_path_result, path_only); + type->accept_vis (resolver); + return !resolver.type_seg_failed_flag; } - void visit (AST::TypePathSegmentGeneric &seg) override; - - void visit (AST::TypePathSegment &seg) override; - -private: - void resolve (AST::TypePath &path) + void visit (AST::TypePath &path) override { + segs.reserve (path.get_num_segments ()); for (auto &seg : path.get_segments ()) { seg->accept_vis (*this); @@ -51,27 +48,55 @@ private: return; } - if (path_buffer.empty ()) + if (segs.empty ()) { rust_error_at (path.get_locus (), "failed to resolve path: %s", path.as_string ().c_str ()); return; } - if (!resolver->get_type_scope ().lookup (path_buffer, &resolved_node)) - { - rust_error_at (path.get_locus (), "failed to resolve TypePath: %s", - path_buffer.c_str ()); - return; - } + bool has_opening_scope_res = false; + result = AST::SimplePath (std::move (segs), has_opening_scope_res, + path.get_locus ()); } - ResolveTypePath (NodeId parent) - : ResolverBase (parent), type_seg_failed_flag (false) + void visit (AST::TypePathSegmentGeneric &seg) override; + + void visit (AST::TypePathSegment &seg) override; + +private: + ResolveTypeToSimplePath (AST::SimplePath &simple_path_result, bool path_only) + : ResolverBase (UNKNOWN_NODEID), type_seg_failed_flag (false), + result (simple_path_result), path_only_flag (path_only) {} - std::string path_buffer; bool type_seg_failed_flag; + std::vector<AST::SimplePathSegment> segs; + AST::SimplePath &result; + bool path_only_flag; +}; + +class ResolveTypePath +{ +public: + static NodeId go (AST::TypePath &path, NodeId parent) + { + AST::SimplePath path_buffer = AST::SimplePath::create_empty (); + if (!ResolveTypeToSimplePath::go (&path, path_buffer)) + return UNKNOWN_NODEID; + + auto resolver = Resolver::get (); + NodeId resolved_node = UNKNOWN_NODEID; + if (!resolver->get_type_scope ().lookup (path_buffer.as_string (), + &resolved_node)) + { + rust_error_at (path.get_locus_slow (), "failed to resolve TypePath: %s", + path_buffer.as_string ().c_str ()); + return UNKNOWN_NODEID; + } + + return resolved_node; + } }; class ResolveType : public ResolverBase diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc index b4ca34f..4cc1a93 100644 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ b/gcc/rust/resolve/rust-ast-resolve.cc @@ -375,11 +375,14 @@ ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field) // rust-ast-resolve-type.h void -ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg) +ResolveTypeToSimplePath::visit (AST::TypePathSegmentGeneric &seg) { - AST::GenericArgs &generics = seg.get_generic_args (); - for (auto > : generics.get_type_args ()) - ResolveType::go (gt.get (), UNKNOWN_NODEID); + if (!path_only_flag) + { + AST::GenericArgs &generics = seg.get_generic_args (); + for (auto > : generics.get_type_args ()) + ResolveType::go (gt.get (), UNKNOWN_NODEID); + } if (seg.is_error ()) { @@ -389,14 +392,12 @@ ResolveTypePath::visit (AST::TypePathSegmentGeneric &seg) return; } - if (seg.get_separating_scope_resolution ()) - path_buffer += "::"; - - path_buffer += seg.get_ident_segment ().as_string (); + segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (), + seg.get_locus ())); } void -ResolveTypePath::visit (AST::TypePathSegment &seg) +ResolveTypeToSimplePath::visit (AST::TypePathSegment &seg) { if (seg.is_error ()) { @@ -406,10 +407,8 @@ ResolveTypePath::visit (AST::TypePathSegment &seg) return; } - if (seg.get_separating_scope_resolution ()) - path_buffer += "::"; - - path_buffer += seg.get_ident_segment ().as_string (); + segs.push_back (AST::SimplePathSegment (seg.get_ident_segment ().as_string (), + seg.get_locus ())); } // rust-ast-resolve-expr.h @@ -465,8 +464,8 @@ ResolvePath::resolve_path (AST::PathInExpression *expr) } else { - rust_error_at (expr->get_locus (), "unknown path %s", - expr->as_string ().c_str ()); + rust_error_at (expr->get_locus (), "unknown path %s lookup %s", + expr->as_string ().c_str (), path_buf.c_str ()); } } |