diff options
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-base.h | 5 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-expr.cc | 14 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-implitem.h | 19 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-path.cc | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.cc | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-stmt.h | 27 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-toplevel.h | 32 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.cc | 2 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-early-name-resolver-2.0.cc | 17 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.h | 19 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-forever-stack.hxx | 113 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-late-name-resolver-2.0.cc | 58 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-late-name-resolver-2.0.h | 4 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolution-context.h | 41 |
14 files changed, 247 insertions, 112 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 0d497f8..ab74e84 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -27,6 +27,11 @@ namespace Rust { namespace Resolver { +inline void +redefined_error (const rich_location &loc) +{ + rust_error_at (loc, "redefined multiple times"); +} class ResolverBase : public AST::ASTVisitor { diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index dc7f76d..8070fc1 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -471,7 +471,7 @@ ResolveExpr::visit (AST::BreakExpr &expr) { if (expr.has_label ()) { - auto label = expr.get_label ().get_lifetime (); + auto label = expr.get_label_unchecked ().get_lifetime (); if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) { rust_error_at (label.get_locus (), @@ -486,8 +486,8 @@ ResolveExpr::visit (AST::BreakExpr &expr) &resolved_node)) { rust_error_at (label.get_locus (), ErrorCode::E0426, - "use of undeclared label %qs in %<break%>", - label.get_lifetime_name ().c_str ()); + "use of undeclared label %qs", + label.as_string ().c_str ()); return; } resolver->insert_resolved_label (label.get_node_id (), resolved_node); @@ -594,7 +594,7 @@ ResolveExpr::visit (AST::ContinueExpr &expr) { if (expr.has_label ()) { - auto label = expr.get_label (); + auto label = expr.get_label_unchecked (); if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) { rust_error_at (label.get_locus (), @@ -608,9 +608,9 @@ ResolveExpr::visit (AST::ContinueExpr &expr) label.get_lifetime_name ()), &resolved_node)) { - rust_error_at (expr.get_label ().get_locus (), ErrorCode::E0426, - "use of undeclared label %qs in %<continue%>", - label.get_lifetime_name ().c_str ()); + rust_error_at (expr.get_label_unchecked ().get_locus (), + ErrorCode::E0426, "use of undeclared label %qs", + label.as_string ().c_str ()); return; } resolver->insert_resolved_label (label.get_node_id (), resolved_node); diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 971bf8f..2081697 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -51,7 +51,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -67,7 +67,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -84,7 +84,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -124,7 +124,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (function.get_node_id (), cpath); @@ -144,7 +144,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (constant.get_node_id (), cpath); @@ -162,7 +162,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (type.get_node_id (), cpath); @@ -202,7 +202,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -221,7 +221,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -239,8 +239,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc index b2b1071..530926d 100644 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ b/gcc/rust/resolve/rust-ast-resolve-path.cc @@ -370,6 +370,12 @@ ResolvePath::resolve_path (AST::SimplePath &expr) } else if (segment.is_super_path_seg ()) { + if (!is_first_segment) + { + rust_error_at (segment.get_locus (), + "%<super%> can only be used in start position"); + return UNKNOWN_NODEID; + } if (module_scope_id == crate_scope_id) { rust_error_at (segment.get_locus (), diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc index fefb522..bfba302 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc @@ -70,7 +70,7 @@ ResolveStmt::visit (AST::StaticItem &var) [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, var.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); ResolveType::go (var.get_type ()); diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index d3ff14f..d413a7c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -63,7 +63,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); ResolveType::go (constant.get_type ()); @@ -73,9 +73,10 @@ public: void visit (AST::LetStmt &stmt) override { if (stmt.has_init_expr ()) - { - ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix); - } + ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix); + + if (stmt.has_else_expr ()) + ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix); PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var); if (stmt.has_type ()) @@ -97,7 +98,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = struct_decl.get_node_id (); @@ -128,7 +129,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, enum_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = enum_decl.get_node_id (); @@ -158,7 +159,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); // Done, no fields. @@ -178,7 +179,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &field : item.get_tuple_fields ()) @@ -204,7 +205,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &field : item.get_struct_fields ()) @@ -230,7 +231,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); // Done, no fields. @@ -251,7 +252,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = struct_decl.get_node_id (); @@ -287,7 +288,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, union_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = union_decl.get_node_id (); @@ -323,7 +324,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = function.get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 379ccab..f52fb8a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -58,7 +58,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, module.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -88,7 +88,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, alias.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -110,7 +110,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -132,7 +132,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, enum_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); resolver->push_new_module_scope (enum_decl.get_node_id ()); @@ -158,7 +158,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -180,7 +180,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -202,7 +202,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -224,7 +224,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -246,7 +246,7 @@ public: = [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }; resolver->get_type_scope ().insert (path, struct_decl.get_node_id (), @@ -277,7 +277,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, union_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -297,7 +297,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, var.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -318,7 +318,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -340,7 +340,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -388,7 +388,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, impl_block.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &impl_item : impl_block.get_impl_items ()) @@ -408,7 +408,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, trait.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &item : trait.get_trait_items ()) @@ -480,7 +480,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, extern_crate.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index 5ab0c44..606141c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ b/gcc/rust/resolve/rust-ast-resolve-type.cc @@ -357,7 +357,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) { rust_error_at (segment->get_locus (), ErrorCode::E0412, "could not resolve type path %qs", - segment->as_string ().c_str ()); + segment->get_ident_segment ().as_string ().c_str ()); return false; } } diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc index 492a665..afaca1f 100644 --- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc @@ -417,10 +417,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping) declared_name = rebind.get_identifier ().as_string (); locus = rebind.get_identifier ().get_locus (); break; - case AST::UseTreeRebind::NewBindType::NONE: - declared_name = path.get_final_segment ().as_string (); - locus = path.get_final_segment ().get_locus (); - break; + case AST::UseTreeRebind::NewBindType::NONE: { + const auto &segments = path.get_segments (); + // We don't want to insert `self` with `use module::self` + if (path.get_final_segment ().is_lower_self_seg ()) + { + rust_assert (segments.size () > 1); + declared_name = segments[segments.size () - 2].as_string (); + } + else + declared_name = path.get_final_segment ().as_string (); + locus = path.get_final_segment ().get_locus (); + break; + } case AST::UseTreeRebind::NewBindType::WILDCARD: rust_unreachable (); break; diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index 2a4c734..cf02651 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -548,7 +548,8 @@ template <Namespace N> class ForeverStack public: ForeverStack () : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)), - prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)), + lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)), + extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)), cursor_reference (root) { rust_assert (root.is_root ()); @@ -658,8 +659,8 @@ public: * the current map, an empty one otherwise. */ tl::optional<Rib::Definition> get (const Identifier &name); - tl::optional<Rib::Definition> get_prelude (const Identifier &name); - tl::optional<Rib::Definition> get_prelude (const std::string &name); + tl::optional<Rib::Definition> get_lang_prelude (const Identifier &name); + tl::optional<Rib::Definition> get_lang_prelude (const std::string &name); /** * Resolve a path to its definition in the current `ForeverStack` @@ -671,7 +672,7 @@ public: */ template <typename S> tl::optional<Rib::Definition> resolve_path ( - const std::vector<S> &segments, + const std::vector<S> &segments, bool has_opening_scope_resolution, std::function<void (const S &, NodeId)> insert_segment_resolution); // FIXME: Documentation @@ -767,7 +768,11 @@ private: * It has the root node as a parent, and acts as a "special case" for name * resolution */ - Node prelude; + Node lang_prelude; + /* + * The extern prelude, used for resolving external crates + */ + Node extern_prelude; std::reference_wrapper<Node> cursor_reference; @@ -795,6 +800,10 @@ private: SegIterator<S> iterator, std::function<void (const S &, NodeId)> insert_segment_resolution); + tl::optional<Rib::Definition> resolve_final_segment (Node &final_node, + std::string &seg_name, + bool is_lower_self); + /* Helper functions for forward resolution (to_canonical_path, to_rib...) */ struct DfsResult { diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index a6e0b30..993e2d4 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -20,6 +20,7 @@ #include "rust-ast.h" #include "rust-diagnostics.h" #include "rust-forever-stack.h" +#include "rust-edition.h" #include "rust-rib.h" #include "rust-unwrap-segment.h" #include "optional.h" @@ -77,7 +78,7 @@ ForeverStack<N>::push_inner (Rib rib, Link link) rust_assert (&cursor_reference.get () == &root); // Prelude doesn't have an access path rust_assert (!link.path); - update_cursor (this->prelude); + update_cursor (this->lang_prelude); return; } // If the link does not exist, we create it and emplace a new `Node` with the @@ -319,16 +320,16 @@ ForeverStack<N>::get (const Identifier &name) template <Namespace N> tl::optional<Rib::Definition> -ForeverStack<N>::get_prelude (const Identifier &name) +ForeverStack<N>::get_lang_prelude (const Identifier &name) { - return prelude.rib.get (name.as_string ()); + return lang_prelude.rib.get (name.as_string ()); } template <Namespace N> tl::optional<Rib::Definition> -ForeverStack<N>::get_prelude (const std::string &name) +ForeverStack<N>::get_lang_prelude (const std::string &name) { - return prelude.rib.get (name); + return lang_prelude.rib.get (name); } template <> @@ -571,7 +572,7 @@ ForeverStack<N>::resolve_segments ( if (current_node->is_root () && !searched_prelude) { searched_prelude = true; - current_node = &prelude; + current_node = &lang_prelude; continue; } @@ -594,15 +595,48 @@ ForeverStack<N>::resolve_segments ( return *current_node; } +template <> +inline tl::optional<Rib::Definition> +ForeverStack<Namespace::Types>::resolve_final_segment (Node &final_node, + std::string &seg_name, + bool is_lower_self) +{ + if (is_lower_self) + return Rib::Definition::NonShadowable (final_node.id); + else + return final_node.rib.get (seg_name); +} + +template <Namespace N> +tl::optional<Rib::Definition> +ForeverStack<N>::resolve_final_segment (Node &final_node, std::string &seg_name, + bool is_lower_self) +{ + return final_node.rib.get (seg_name); +} + template <Namespace N> template <typename S> tl::optional<Rib::Definition> ForeverStack<N>::resolve_path ( - const std::vector<S> &segments, + const std::vector<S> &segments, bool has_opening_scope_resolution, std::function<void (const S &, NodeId)> insert_segment_resolution) { // TODO: What to do if segments.empty() ? + // handle paths with opening scopes + std::function<void (void)> cleanup_current = [] () {}; + if (has_opening_scope_resolution) + { + Node *last_current = &cursor_reference.get (); + if (get_rust_edition () == Edition::E2015) + cursor_reference = root; + else + cursor_reference = extern_prelude; + cleanup_current + = [this, last_current] () { cursor_reference = *last_current; }; + } + // if there's only one segment, we just use `get` if (segments.size () == 1) { @@ -613,6 +647,7 @@ ForeverStack<N>::resolve_path ( lang_item.value ()); insert_segment_resolution (seg, seg_id); + cleanup_current (); // TODO: does NonShadowable matter? return Rib::Definition::NonShadowable (seg_id); } @@ -621,43 +656,49 @@ ForeverStack<N>::resolve_path ( = get (unwrap_type_segment (segments.back ()).as_string ()); if (!res) - res = get_prelude (unwrap_type_segment (segments.back ()).as_string ()); + res = get_lang_prelude ( + unwrap_type_segment (segments.back ()).as_string ()); if (res && !res->is_ambiguous ()) insert_segment_resolution (segments.back (), res->get_node_id ()); + cleanup_current (); return res; } std::reference_wrapper<Node> starting_point = cursor (); - return find_starting_point (segments, starting_point, - insert_segment_resolution) - .and_then ([this, &segments, &starting_point, &insert_segment_resolution] ( - typename std::vector<S>::const_iterator iterator) { - return resolve_segments (starting_point.get (), segments, iterator, - insert_segment_resolution); - }) - .and_then ([this, &segments, &insert_segment_resolution] ( - Node final_node) -> tl::optional<Rib::Definition> { - // leave resolution within impl blocks to type checker - if (final_node.rib.kind == Rib::Kind::TraitOrImpl) - return tl::nullopt; - - std::string seg_name - = unwrap_type_segment (segments.back ()).as_string (); - - // assuming this can't be a lang item segment - tl::optional<Rib::Definition> res = final_node.rib.get (seg_name); - - // Ok we didn't find it in the rib, Lets try the prelude... - if (!res) - res = get_prelude (seg_name); - - if (res && !res->is_ambiguous ()) - insert_segment_resolution (segments.back (), res->get_node_id ()); - - return res; - }); + auto res + = find_starting_point (segments, starting_point, insert_segment_resolution) + .and_then ( + [this, &segments, &starting_point, &insert_segment_resolution] ( + typename std::vector<S>::const_iterator iterator) { + return resolve_segments (starting_point.get (), segments, iterator, + insert_segment_resolution); + }) + .and_then ([this, &segments, &insert_segment_resolution] ( + Node final_node) -> tl::optional<Rib::Definition> { + // leave resolution within impl blocks to type checker + if (final_node.rib.kind == Rib::Kind::TraitOrImpl) + return tl::nullopt; + + auto &seg = unwrap_type_segment (segments.back ()); + std::string seg_name = seg.as_string (); + + // assuming this can't be a lang item segment + tl::optional<Rib::Definition> res + = resolve_final_segment (final_node, seg_name, + seg.is_lower_self_seg ()); + // Ok we didn't find it in the rib, Lets try the prelude... + if (!res) + res = get_lang_prelude (seg_name); + + if (res && !res->is_ambiguous ()) + insert_segment_resolution (segments.back (), res->get_node_id ()); + + return res; + }); + cleanup_current (); + return res; } template <Namespace N> 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 cf7b7dc..f743e1e 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -140,6 +140,9 @@ Late::visit (AST::LetStmt &let) visit (let.get_init_expr ()); visit (let.get_pattern ()); + if (let.has_else_expr ()) + visit (let.get_init_expr ()); + // how do we deal with the fact that `let a = blipbloup` should look for a // label and cannot go through function ribs, but `let a = blipbloup()` can? @@ -184,6 +187,9 @@ Late::visit (AST::SelfParam ¶m) void Late::visit (AST::BreakExpr &expr) { + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ().get_lifetime ()); + if (expr.has_break_expr ()) { auto &break_expr = expr.get_break_expr (); @@ -210,6 +216,38 @@ Late::visit (AST::BreakExpr &expr) } void +Late::visit (AST::LoopLabel &label) +{ + auto &lifetime = label.get_lifetime (); + ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()), + lifetime.get_node_id ()); +} + +void +Late::resolve_label (AST::Lifetime &lifetime) +{ + if (auto resolved = ctx.labels.get (lifetime.as_string ())) + { + if (resolved->get_node_id () != lifetime.get_node_id ()) + ctx.map_usage (Usage (lifetime.get_node_id ()), + Definition (resolved->get_node_id ())); + } + else + rust_error_at (lifetime.get_locus (), ErrorCode::E0426, + "use of undeclared label %qs", + lifetime.as_string ().c_str ()); +} + +void +Late::visit (AST::ContinueExpr &expr) +{ + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ()); + + DefaultResolver::visit (expr); +} + +void Late::visit (AST::IdentifierExpr &expr) { // TODO: same thing as visit(PathInExpression) here? @@ -232,7 +270,7 @@ Late::visit (AST::IdentifierExpr &expr) } else { - if (auto type = ctx.types.get_prelude (expr.get_ident ())) + if (auto type = ctx.types.get_lang_prelude (expr.get_ident ())) { resolved = type; } @@ -304,8 +342,7 @@ Late::visit (AST::PathInExpression &expr) return; } - auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values, - Namespace::Types); + auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types); if (!resolved) { @@ -337,13 +374,9 @@ Late::visit (AST::TypePath &type) DefaultResolver::visit (type); - // take care of only simple cases - // TODO: remove this? - rust_assert (!type.has_opening_scope_resolution_op ()); - // this *should* mostly work // TODO: make sure typepath-like path resolution (?) is working - auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (type, Namespace::Types); if (!resolved.has_value ()) { @@ -391,8 +424,7 @@ Late::visit (AST::StructExprStruct &s) visit_inner_attrs (s); DefaultResolver::visit (s.get_struct_name ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -406,8 +438,7 @@ Late::visit (AST::StructExprStructBase &s) DefaultResolver::visit (s.get_struct_name ()); visit (s.get_struct_base ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -424,8 +455,7 @@ Late::visit (AST::StructExprStructFields &s) for (auto &field : s.get_fields ()) visit (field); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); 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 ac376b5..5703b15 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h @@ -48,6 +48,8 @@ public: void visit (AST::IdentifierExpr &) override; void visit (AST::StructExprFieldIdentifier &) override; void visit (AST::BreakExpr &) override; + void visit (AST::ContinueExpr &) override; + void visit (AST::LoopLabel &) override; void visit (AST::PathInExpression &) override; void visit (AST::TypePath &) override; void visit (AST::Trait &) override; @@ -61,6 +63,8 @@ public: void visit (AST::ClosureExprInnerTyped &) override; private: + void resolve_label (AST::Lifetime &lifetime); + /* Setup Rust's builtin types (u8, i32, !...) in the resolver */ void setup_builtin_types (); diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index ea81bde..84c0800 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -221,6 +221,7 @@ public: template <typename S> tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments, + bool has_opening_scope_resolution, Namespace ns) { std::function<void (const S &, NodeId)> insert_segment_resolution @@ -232,13 +233,17 @@ public: switch (ns) { case Namespace::Values: - return values.resolve_path (segments, insert_segment_resolution); + return values.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Types: - return types.resolve_path (segments, insert_segment_resolution); + return types.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Macros: - return macros.resolve_path (segments, insert_segment_resolution); + return macros.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Labels: - return labels.resolve_path (segments, insert_segment_resolution); + return labels.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); default: rust_unreachable (); } @@ -246,19 +251,45 @@ public: template <typename S, typename... Args> tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments, + bool has_opening_scope_resolution, Args... ns_args) { std::initializer_list<Namespace> namespaces = {ns_args...}; for (auto ns : namespaces) { - if (auto ret = resolve_path (segments, ns)) + if (auto ret + = resolve_path (segments, has_opening_scope_resolution, ns)) return ret; } return tl::nullopt; } + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), + path.has_opening_scope_resolution (), ns_args...); + } + + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), path.opening_scope_resolution (), + ns_args...); + } + + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), + path.has_opening_scope_resolution_op (), ns_args...); + } + private: /* Map of "usage" nodes which have been resolved to a "definition" node */ std::map<Usage, Definition> resolved_nodes; |