aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc18
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h7
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc30
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h3
-rw-r--r--gcc/rust/resolve/rust-default-resolver.cc92
-rw-r--r--gcc/rust/resolve/rust-default-resolver.h4
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc35
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h14
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.cc2
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.h2
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.cc29
-rw-r--r--gcc/rust/resolve/rust-finalize-imports-2.0.h7
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx54
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc48
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h2
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.cc59
-rw-r--r--gcc/rust/resolve/rust-name-resolution-context.h27
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc100
-rw-r--r--gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h2
20 files changed, 400 insertions, 138 deletions
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 71c4c48..3c7b425 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -116,7 +116,7 @@ ResolverBase::visit (AST::MetaItemLitExpr &)
{}
void
-ResolverBase::visit (AST::MetaItemPathLit &)
+ResolverBase::visit (AST::MetaItemPathExpr &)
{}
void
@@ -284,6 +284,10 @@ ResolverBase::visit (AST::ReturnExpr &)
{}
void
+ResolverBase::visit (AST::TryExpr &)
+{}
+
+void
ResolverBase::visit (AST::UnsafeBlockExpr &)
{}
@@ -580,6 +584,14 @@ ResolverBase::visit (AST::GroupedPattern &)
{}
void
+ResolverBase::visit (AST::SlicePatternItemsNoRest &)
+{}
+
+void
+ResolverBase::visit (AST::SlicePatternItemsHasRest &)
+{}
+
+void
ResolverBase::visit (AST::SlicePattern &)
{}
@@ -671,5 +683,9 @@ void
ResolverBase::visit (AST::FormatArgs &fmt)
{}
+void
+ResolverBase::visit (AST::OffsetOf &offset_of)
+{}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index e17bdcb..89c5c35 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -21,6 +21,7 @@
#include "rust-ast-visitor.h"
#include "rust-ast.h"
+#include "rust-builtin-ast-nodes.h"
#include "rust-expr.h"
#include "rust-name-resolver.h"
#include "rust-diagnostics.h"
@@ -57,7 +58,7 @@ public:
void visit (AST::AttrInputLiteral &);
void visit (AST::AttrInputMacro &);
void visit (AST::MetaItemLitExpr &);
- void visit (AST::MetaItemPathLit &);
+ void visit (AST::MetaItemPathExpr &);
void visit (AST::BorrowExpr &);
void visit (AST::DereferenceExpr &);
void visit (AST::ErrorPropagationExpr &);
@@ -99,6 +100,7 @@ public:
void visit (AST::RangeToInclExpr &);
void visit (AST::BoxExpr &);
void visit (AST::ReturnExpr &);
+ void visit (AST::TryExpr &);
void visit (AST::UnsafeBlockExpr &);
void visit (AST::LoopExpr &);
void visit (AST::WhileLoopExpr &);
@@ -184,6 +186,8 @@ public:
void visit (AST::TuplePatternItemsRanged &);
void visit (AST::TuplePattern &);
void visit (AST::GroupedPattern &);
+ void visit (AST::SlicePatternItemsNoRest &);
+ void visit (AST::SlicePatternItemsHasRest &);
void visit (AST::SlicePattern &);
void visit (AST::AltPattern &);
@@ -210,6 +214,7 @@ public:
void visit (AST::SelfParam &param);
void visit (AST::FormatArgs &fmt);
+ void visit (AST::OffsetOf &offset_of);
protected:
ResolverBase ()
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 0937d65..1d5ebed 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -453,7 +453,8 @@ ResolveItem::visit (AST::ConstantItem &constant)
resolve_visibility (constant.get_visibility ());
ResolveType::go (constant.get_type ());
- ResolveExpr::go (constant.get_expr (), path, cpath);
+ if (constant.has_expr ())
+ ResolveExpr::go (constant.get_expr (), path, cpath);
}
void
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index 2b5e2bf..3b80f9f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -62,6 +62,11 @@ PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type,
void
PatternDeclaration::visit (AST::IdentifierPattern &pattern)
{
+ if (pattern.has_subpattern ())
+ {
+ pattern.get_subpattern ().accept_vis (*this);
+ }
+
Mutability mut = pattern.get_is_mut () ? Mutability::Mut : Mutability::Imm;
add_new_binding (pattern.get_ident (), pattern.get_node_id (),
BindingTypeInfo (mut, pattern.get_is_ref (),
@@ -383,9 +388,30 @@ PatternDeclaration::visit (AST::RangePattern &pattern)
void
PatternDeclaration::visit (AST::SlicePattern &pattern)
{
- for (auto &p : pattern.get_items ())
+ auto &items = pattern.get_items ();
+ switch (items.get_pattern_type ())
{
- p->accept_vis (*this);
+ case AST::SlicePatternItems::SlicePatternItemType::NO_REST:
+ {
+ auto &ref
+ = static_cast<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
+
+ for (auto &p : ref.get_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
+
+ case AST::SlicePatternItems::SlicePatternItemType::HAS_REST:
+ {
+ auto &ref
+ = static_cast<AST::SlicePatternItemsHasRest &> (pattern.get_items ());
+
+ for (auto &p : ref.get_lower_patterns ())
+ p->accept_vis (*this);
+ for (auto &p : ref.get_upper_patterns ())
+ p->accept_vis (*this);
+ }
+ break;
}
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index d413a7c..d714511 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -67,7 +67,8 @@ public:
});
ResolveType::go (constant.get_type ());
- ResolveExpr::go (constant.get_expr (), prefix, canonical_prefix);
+ if (constant.has_expr ())
+ ResolveExpr::go (constant.get_expr (), prefix, canonical_prefix);
}
void visit (AST::LetStmt &stmt) override
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index 01906cf..f1c0e5c 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -111,17 +111,42 @@ DefaultResolver::visit (AST::IfLetExpr &expr)
}
void
+DefaultResolver::visit (AST::IfLetExprConseqElse &expr)
+{
+ DefaultResolver::visit (static_cast<AST::IfLetExpr &> (expr));
+ visit (expr.get_else_block ());
+}
+
+void
DefaultResolver::visit (AST::Trait &trait)
{
- auto inner_fn_1
- = [this, &trait] () { AST::DefaultASTVisitor::visit (trait); };
+ visit_outer_attrs (trait);
+ visit (trait.get_visibility ());
+ visit_inner_attrs (trait);
+
+ auto inner_fn_1 = [this, &trait] () {
+ for (auto &item : trait.get_trait_items ())
+ visit (item);
+ };
auto inner_fn_2 = [this, &trait, &inner_fn_1] () {
+ visit (trait.get_implicit_self ());
+ for (auto &generic : trait.get_generic_params ())
+ visit (generic);
+ if (trait.has_where_clause ())
+ visit (trait.get_where_clause ());
+ for (auto &bound : trait.get_type_param_bounds ())
+ visit (bound);
+
+ ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_1);
+ };
+
+ auto inner_fn_3 = [this, &trait, &inner_fn_2] () {
ctx.canonical_ctx.scope (trait.get_node_id (), trait.get_identifier (),
- std::move (inner_fn_1));
+ std::move (inner_fn_2));
};
- ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn_2,
+ ctx.scoped (Rib::Kind::Generics, trait.get_node_id (), inner_fn_3,
trait.get_identifier () /* FIXME: Is that valid?*/);
}
@@ -343,19 +368,15 @@ DefaultResolver::visit (AST::MatchExpr &expr)
void
DefaultResolver::visit (AST::ConstantItem &item)
{
- if (item.has_expr ())
- {
- auto expr_vis_1
- = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
+ auto expr_vis_1 = [this, &item] () { AST::DefaultASTVisitor::visit (item); };
- auto expr_vis_2 = [this, &item, &expr_vis_1] () {
- ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
- std::move (expr_vis_1));
- };
+ auto expr_vis_2 = [this, &item, &expr_vis_1] () {
+ ctx.canonical_ctx.scope (item.get_node_id (), item.get_identifier (),
+ std::move (expr_vis_1));
+ };
- // FIXME: Why do we need a Rib here?
- ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
- }
+ // FIXME: Why do we need a Rib here?
+ ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis_2);
}
void
@@ -380,5 +401,46 @@ DefaultResolver::visit (AST::TypeParam &param)
ctx.scoped (Rib::Kind::ForwardTypeParamBan, param.get_node_id (), expr_vis);
}
+void
+DefaultResolver::visit_extern_crate (AST::ExternCrate &extern_crate,
+ AST::Crate &crate, CrateNum num)
+{
+ visit (crate);
+}
+
+void
+DefaultResolver::visit (AST::ExternCrate &crate)
+{
+ auto &mappings = Analysis::Mappings::get ();
+ auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
+
+ if (!num_opt)
+ {
+ rust_error_at (crate.get_locus (), "unknown crate %qs",
+ crate.get_referenced_crate ().c_str ());
+ return;
+ }
+
+ CrateNum num = *num_opt;
+
+ AST::Crate &referenced_crate = mappings.get_ast_crate (num);
+
+ auto sub_visitor_1
+ = [&, this] () { visit_extern_crate (crate, referenced_crate, num); };
+
+ auto sub_visitor_2 = [&] () {
+ ctx.canonical_ctx.scope_crate (referenced_crate.get_node_id (),
+ crate.get_referenced_crate (),
+ std::move (sub_visitor_1));
+ };
+
+ if (crate.has_as_clause ())
+ ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
+ sub_visitor_2, crate.get_as_clause ());
+ else
+ ctx.scoped (Rib::Kind::Module, referenced_crate.get_node_id (),
+ sub_visitor_2, crate.get_referenced_crate ());
+}
+
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 99fd8e7..cf0df68 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -49,6 +49,7 @@ public:
void visit (AST::ForLoopExpr &expr) override;
virtual void visit_if_let_patterns (AST::IfLetExpr &expr);
void visit (AST::IfLetExpr &expr) override;
+ void visit (AST::IfLetExprConseqElse &expr) override;
void visit (AST::Trait &) override;
// used to handle Self insertion in TopLevel
virtual void maybe_insert_big_self (AST::Impl &) {}
@@ -58,6 +59,9 @@ public:
void visit (AST::TypeParam &) override;
+ virtual void visit_extern_crate (AST::ExternCrate &, AST::Crate &, CrateNum);
+ void visit (AST::ExternCrate &) override;
+
// type dec nodes, which visit their fields or variants by default
void visit (AST::StructStruct &) override;
void visit (AST::TupleStruct &) override;
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 c10379a..4fd1dd2 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -17,8 +17,11 @@
// <http://www.gnu.org/licenses/>.
#include "rust-early-name-resolver-2.0.h"
-#include "rust-ast-full.h"
+#include "optional.h"
+#include "options.h"
#include "rust-diagnostics.h"
+#include "rust-hir-map.h"
+#include "rust-item.h"
#include "rust-toplevel-name-resolver-2.0.h"
#include "rust-attributes.h"
#include "rust-finalize-imports-2.0.h"
@@ -75,8 +78,9 @@ Early::resolve_glob_import (NodeId use_dec_id, TopLevel::ImportKind &&glob)
if (!resolved.has_value ())
return false;
- auto result
- = Analysis::Mappings::get ().lookup_ast_module (resolved->get_node_id ());
+ auto result = Analysis::Mappings::get ().lookup_glob_container (
+ resolved->get_node_id ());
+
if (!result)
return false;
@@ -252,6 +256,11 @@ Early::visit (AST::MacroInvocation &invoc)
{
auto &path = invoc.get_invoc_data ().get_path ();
+ // We special case the `offset_of!()` macro if the flag is here, otherwise
+ // we accept whatever `offset_of!()` definition we resolved to.
+ auto resolve_offset_of
+ = flag_assume_builtin_offset_of && (path.as_string () == "offset_of");
+
if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin)
for (auto &pending_invoc : invoc.get_pending_eager_invocations ())
pending_invoc->accept_vis (*this);
@@ -275,12 +284,14 @@ Early::visit (AST::MacroInvocation &invoc)
if (!definition.has_value ())
definition = ctx.resolve_path (path, Namespace::Macros);
- // if the definition still does not have a value, then it's an error
+ // if the definition still does not have a value, then it's an error - unless
+ // we should automatically resolve offset_of!() calls
if (!definition.has_value ())
{
- collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
- "could not resolve macro invocation %qs",
- path.as_string ().c_str ()));
+ if (!resolve_offset_of)
+ collect_error (Error (invoc.get_locus (), ErrorCode::E0433,
+ "could not resolve macro invocation %qs",
+ path.as_string ().c_str ()));
return;
}
@@ -394,12 +405,12 @@ void
Early::finalize_glob_import (NameResolutionContext &ctx,
const Early::ImportPair &mapping)
{
- auto module = Analysis::Mappings::get ().lookup_ast_module (
- mapping.data.module ().get_node_id ());
- rust_assert (module);
+ auto container = Analysis::Mappings::get ().lookup_glob_container (
+ mapping.data.container ().get_node_id ());
+
+ rust_assert (container);
- GlobbingVisitor glob_visitor (ctx);
- glob_visitor.go (module.value ());
+ GlobbingVisitor (ctx).go (container.value ());
}
void
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index e78bec0..960de0e 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -83,15 +83,15 @@ public:
return ImportData (Kind::Rebind, std::move (definitions));
}
- static ImportData Glob (Rib::Definition module)
+ static ImportData Glob (Rib::Definition container)
{
- return ImportData (Kind::Glob, module);
+ return ImportData (Kind::Glob, container);
}
- Rib::Definition module () const
+ Rib::Definition container () const
{
rust_assert (kind == Kind::Glob);
- return glob_module;
+ return glob_container;
}
std::vector<std::pair<Rib::Definition, Namespace>> definitions () const
@@ -107,8 +107,8 @@ public:
: kind (kind), resolved_definitions (std::move (definitions))
{}
- ImportData (Kind kind, Rib::Definition module)
- : kind (kind), glob_module (module)
+ ImportData (Kind kind, Rib::Definition container)
+ : kind (kind), glob_container (container)
{}
// TODO: Should this be a union?
@@ -117,7 +117,7 @@ public:
std::vector<std::pair<Rib::Definition, Namespace>> resolved_definitions;
// For Glob
- Rib::Definition glob_module;
+ Rib::Definition glob_container;
};
struct ImportPair
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
index fc9a26c..7b365ef 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -205,7 +205,7 @@ EarlyNameResolver::visit (AST::MetaItemLitExpr &)
{}
void
-EarlyNameResolver::visit (AST::MetaItemPathLit &)
+EarlyNameResolver::visit (AST::MetaItemPathExpr &)
{}
void
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h
index 26fc84d..d3c5225 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -142,7 +142,7 @@ private:
virtual void visit (AST::AttrInputLiteral &attr_input);
virtual void visit (AST::AttrInputMacro &attr_input);
virtual void visit (AST::MetaItemLitExpr &meta_item);
- virtual void visit (AST::MetaItemPathLit &meta_item);
+ virtual void visit (AST::MetaItemPathExpr &meta_item);
virtual void visit (AST::StructExprStruct &expr);
virtual void visit (AST::StructExprFieldIdentifier &field);
virtual void visit (AST::StructExprStructBase &expr);
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.cc b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
index b0e8651..317acb0 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.cc
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.cc
@@ -21,19 +21,44 @@
#include "rust-hir-map.h"
#include "rust-name-resolution-context.h"
#include "rust-rib.h"
+#include "rust-system.h"
#include "rust-toplevel-name-resolver-2.0.h"
namespace Rust {
namespace Resolver2_0 {
void
-GlobbingVisitor::go (AST::Module *module)
+GlobbingVisitor::go (AST::Item *container)
{
- for (auto &i : module->get_items ())
+ switch (container->get_item_kind ())
+ {
+ case AST::Item::Kind::Module:
+ visit_module_container (static_cast<AST::Module &> (*container));
+ break;
+ case AST::Item::Kind::Enum:
+ visit_enum_container (static_cast<AST::Enum &> (*container));
+ break;
+ default:
+ rust_unreachable ();
+ }
+}
+
+void
+GlobbingVisitor::visit_module_container (AST::Module &module)
+{
+ for (auto &i : module.get_items ())
visit (i);
}
void
+GlobbingVisitor::visit_enum_container (AST::Enum &item)
+{
+ for (auto &variant : item.get_variants ())
+ ctx.insert_globbed (variant->get_identifier (), variant->get_node_id (),
+ Namespace::Types);
+}
+
+void
GlobbingVisitor::visit (AST::Module &module)
{
if (module.get_visibility ().is_public ())
diff --git a/gcc/rust/resolve/rust-finalize-imports-2.0.h b/gcc/rust/resolve/rust-finalize-imports-2.0.h
index d587a5e..4ae1d6d 100644
--- a/gcc/rust/resolve/rust-finalize-imports-2.0.h
+++ b/gcc/rust/resolve/rust-finalize-imports-2.0.h
@@ -18,6 +18,7 @@
#include "rust-ast.h"
#include "rust-expr.h"
+#include "rust-item.h"
#include "rust-name-resolution-context.h"
#include "rust-toplevel-name-resolver-2.0.h"
#include "rust-early-name-resolver-2.0.h"
@@ -32,7 +33,11 @@ class GlobbingVisitor : public AST::DefaultASTVisitor
public:
GlobbingVisitor (NameResolutionContext &ctx) : ctx (ctx) {}
- void go (AST::Module *module);
+ void go (AST::Item *container);
+
+ void visit_module_container (AST::Module &module);
+ void visit_enum_container (AST::Enum &item);
+
void visit (AST::Module &module) override;
void visit (AST::MacroRulesDefinition &macro) override;
void visit (AST::Function &function) override;
diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 8721386..1ed87b3 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -297,6 +297,10 @@ ForeverStack<N>::get (Node &start, const Identifier &name)
// TODO: Can we improve the API? have `reverse_iter` return an optional?
reverse_iter (start, [&resolved_definition, &name] (Node &current) {
+ // we can't reference associated types/functions like this
+ if (current.rib.kind == Rib::Kind::TraitOrImpl)
+ return KeepGoing::Yes;
+
auto candidate = current.rib.get (name.as_string ());
return candidate.map_or (
@@ -549,6 +553,14 @@ ForeverStack<N>::resolve_segments (
bool searched_prelude = false;
while (true)
{
+ if (is_start (iterator, segments)
+ && current_node->rib.kind == Rib::Kind::TraitOrImpl)
+ {
+ // we can't reference associated types/functions like this
+ current_node = &current_node->parent.value ();
+ continue;
+ }
+
// may set the value of child
for (auto &kv : current_node->children)
{
@@ -675,7 +687,7 @@ ForeverStack<N>::resolve_path (
if (!res)
res = get_lang_prelude (seg.as_string ());
- if (!res && N == Namespace::Types)
+ if (N == Namespace::Types && !res)
{
if (seg.is_crate_path_seg ())
{
@@ -707,6 +719,26 @@ ForeverStack<N>::resolve_path (
// TODO: does NonShadowable matter?
return Rib::Definition::NonShadowable (id);
}
+ else
+ {
+ // HACK: check for a module after we check the language prelude
+ for (auto &kv :
+ find_closest_module (starting_point.get ()).children)
+ {
+ auto &link = kv.first;
+
+ if (link.path.map_or (
+ [&seg] (Identifier path) {
+ auto &path_str = path.as_string ();
+ return path_str == seg.as_string ();
+ },
+ false))
+ {
+ insert_segment_resolution (outer_seg, kv.second.id);
+ return Rib::Definition::NonShadowable (kv.second.id);
+ }
+ }
+ }
}
if (res && !res->is_ambiguous ())
@@ -739,6 +771,26 @@ ForeverStack<N>::resolve_path (
if (!res)
res = get_lang_prelude (seg_name);
+ if (N == Namespace::Types && !res)
+ {
+ // HACK: check for a module after we check the language prelude
+ for (auto &kv : final_node.children)
+ {
+ auto &link = kv.first;
+
+ if (link.path.map_or (
+ [&seg_name] (Identifier path) {
+ auto &path_str = path.as_string ();
+ return path_str == seg_name;
+ },
+ false))
+ {
+ insert_segment_resolution (segments.back (), kv.second.id);
+ return Rib::Definition::NonShadowable (kv.second.id);
+ }
+ }
+ }
+
if (res && !res->is_ambiguous ())
insert_segment_resolution (segments.back (), res->get_node_id ());
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 62829e0..e39ca15 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -19,6 +19,7 @@
#include "optional.h"
#include "rust-ast-full.h"
#include "rust-diagnostics.h"
+#include "rust-expr.h"
#include "rust-hir-map.h"
#include "rust-late-name-resolver-2.0.h"
#include "rust-default-resolver.h"
@@ -141,7 +142,10 @@ Late::visit (AST::ForLoopExpr &expr)
ctx.bindings.exit ();
visit (expr.get_iterator_expr ());
- visit (expr.get_loop_label ());
+
+ if (expr.has_loop_label ())
+ visit (expr.get_loop_label ());
+
visit (expr.get_loop_block ());
}
@@ -208,10 +212,32 @@ Late::visit (AST::LetStmt &let)
// let.get_node_id (), [] () {});
}
+void
+Late::visit (AST::WhileLetLoopExpr &while_let)
+{
+ DefaultASTVisitor::visit_outer_attrs (while_let);
+
+ if (while_let.has_loop_label ())
+ visit (while_let.get_loop_label ());
+
+ // visit expression before pattern
+ // this makes variable shadowing work properly
+ visit (while_let.get_scrutinee_expr ());
+
+ ctx.bindings.enter (BindingSource::WhileLet);
+
+ for (auto &pattern : while_let.get_patterns ())
+ visit (pattern);
+
+ ctx.bindings.exit ();
+
+ visit (while_let.get_loop_block ());
+}
+
static void
visit_identifier_as_pattern (NameResolutionContext &ctx,
const Identifier &ident, location_t locus,
- NodeId node_id)
+ NodeId node_id, bool is_ref, bool is_mut)
{
// do we insert in labels or in values
// but values does not allow shadowing... since functions cannot shadow
@@ -232,7 +258,7 @@ visit_identifier_as_pattern (NameResolutionContext &ctx,
return;
}
- ctx.bindings.peek ().insert_ident (ident);
+ ctx.bindings.peek ().insert_ident (ident.as_string (), locus, is_ref, is_mut);
if (ctx.bindings.peek ().is_or_bound (ident))
{
@@ -251,9 +277,13 @@ visit_identifier_as_pattern (NameResolutionContext &ctx,
void
Late::visit (AST::IdentifierPattern &identifier)
{
+ DefaultResolver::visit (identifier);
+
visit_identifier_as_pattern (ctx, identifier.get_ident (),
identifier.get_locus (),
- identifier.get_node_id ());
+ identifier.get_node_id (),
+ identifier.get_is_ref (),
+ identifier.get_is_mut ());
}
void
@@ -284,7 +314,8 @@ void
Late::visit (AST::StructPatternFieldIdent &field)
{
visit_identifier_as_pattern (ctx, field.get_identifier (), field.get_locus (),
- field.get_node_id ());
+ field.get_node_id (), field.is_ref (),
+ field.is_mut ());
}
void
@@ -612,13 +643,6 @@ Late::visit (AST::Trait &trait)
}
void
-Late::visit (AST::StructStruct &s)
-{
- auto s_vis = [this, &s] () { AST::DefaultASTVisitor::visit (s); };
- ctx.scoped (Rib::Kind::Item, s.get_node_id (), s_vis);
-}
-
-void
Late::visit (AST::StructExprStruct &s)
{
visit_outer_attrs (s);
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 f2907c9..95540e3 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -42,6 +42,7 @@ public:
// some more label declarations
void visit (AST::LetStmt &) override;
+ void visit (AST::WhileLetLoopExpr &) override;
// TODO: Do we need this?
// void visit (AST::Method &) override;
void visit (AST::IdentifierPattern &) override;
@@ -66,7 +67,6 @@ public:
void visit (AST::StructExprStruct &) override;
void visit (AST::StructExprStructBase &) override;
void visit (AST::StructExprStructFields &) override;
- void visit (AST::StructStruct &) override;
void visit (AST::GenericArgs &) override;
void visit (AST::GenericArg &);
void visit_closure_params (AST::ClosureExpr &) override;
diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc b/gcc/rust/resolve/rust-name-resolution-context.cc
index 34615ed..1b84f1d 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.cc
+++ b/gcc/rust/resolve/rust-name-resolution-context.cc
@@ -33,7 +33,8 @@ BindingLayer::bind_test (Identifier ident, Binding::Kind kind)
{
for (auto &bind : bindings)
{
- if (bind.set.find (ident) != bind.set.cend () && bind.kind == kind)
+ if (bind.idents.find (ident.as_string ()) != bind.idents.cend ()
+ && bind.kind == kind)
{
return true;
}
@@ -60,20 +61,66 @@ BindingLayer::is_or_bound (Identifier ident)
}
void
-BindingLayer::insert_ident (Identifier ident)
+BindingLayer::insert_ident (std::string ident, location_t locus, bool is_ref,
+ bool is_mut)
{
- bindings.back ().set.insert (ident);
+ bindings.back ().idents.emplace (
+ std::move (ident), std::make_pair (locus, IdentifierMode (is_ref, is_mut)));
}
void
BindingLayer::merge ()
{
- auto last_binding = bindings.back ();
+ auto last_binding = std::move (bindings.back ());
bindings.pop_back ();
- for (auto &value : last_binding.set)
+
+ if (bindings.back ().has_expected_bindings)
{
- bindings.back ().set.insert (value);
+ for (auto &value : bindings.back ().idents)
+ {
+ auto ident = value.first;
+ if (last_binding.idents.find (ident) == last_binding.idents.end ())
+ {
+ location_t locus = value.second.first;
+ rust_error_at (locus, ErrorCode::E0408,
+ "variable %qs is not bound in all patterns",
+ ident.c_str ());
+ }
+ }
}
+
+ for (auto &value : last_binding.idents)
+ {
+ auto res = bindings.back ().idents.emplace (value);
+ if (res.second)
+ {
+ if (bindings.back ().has_expected_bindings)
+ {
+ auto &ident = value.first;
+ location_t locus = value.second.first;
+ rust_error_at (locus, ErrorCode::E0408,
+ "variable %qs is not bound in all patterns",
+ ident.c_str ());
+ }
+ }
+ else
+ {
+ auto this_mode = value.second.second;
+ auto other_mode = res.first->second.second;
+ if (this_mode != other_mode)
+ {
+ auto &ident = value.first;
+ location_t locus = value.second.first;
+ rust_error_at (locus, ErrorCode::E0409,
+ "variable %qs is bound inconsistently across "
+ "pattern alternatives",
+ ident.c_str ());
+ }
+ }
+ }
+
+ if (bindings.back ().kind == Binding::Kind::Or)
+ bindings.back ().has_expected_bindings = true;
}
BindingSource
diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h
index bb8519a..558b3ca 100644
--- a/gcc/rust/resolve/rust-name-resolution-context.h
+++ b/gcc/rust/resolve/rust-name-resolution-context.h
@@ -158,6 +158,22 @@ public:
NodeId id;
};
+struct IdentifierMode
+{
+ bool is_ref;
+ bool is_mut;
+
+ IdentifierMode (bool is_ref, bool is_mut) : is_ref (is_ref), is_mut (is_mut)
+ {}
+
+ bool operator== (const IdentifierMode &other)
+ {
+ return other.is_ref == is_ref && other.is_mut == is_mut;
+ }
+
+ bool operator!= (const IdentifierMode &other) { return !(*this == other); }
+};
+
struct Binding
{
enum class Kind
@@ -166,9 +182,12 @@ struct Binding
Or,
} kind;
- std::unordered_set<Identifier> set;
+ // used to check the correctness of or-bindings
+ bool has_expected_bindings;
+
+ std::unordered_map<std::string, std::pair<location_t, IdentifierMode>> idents;
- Binding (Binding::Kind kind) : kind (kind) {}
+ Binding (Binding::Kind kind) : kind (kind), has_expected_bindings (false) {}
};
/**
@@ -179,6 +198,7 @@ enum class BindingSource
Match,
Let,
IfLet,
+ WhileLet,
For,
/* Closure param or function param */
Param
@@ -208,7 +228,8 @@ public:
*/
bool is_or_bound (Identifier ident);
- void insert_ident (Identifier ident);
+ void insert_ident (std::string ident, location_t locus, bool is_ref,
+ bool is_mut);
void merge ();
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 3e5ed53..0930f96 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -101,34 +101,11 @@ TopLevel::go (AST::Crate &crate)
void
TopLevel::visit (AST::Module &module)
{
- insert_or_error_out (module.get_name (), module, Namespace::Types);
-
- // Parse the module's items if they haven't been expanded and the file
- // should be parsed (i.e isn't hidden behind an untrue or impossible cfg
- // directive
- // TODO: make sure this is right
- // TODO: avoid loading items if cfg attributes are present?
- // might not be needed if this runs after early resolution?
- // This was copied from the old early resolver method
- // 'accumulate_escaped_macros'
- if (module.get_kind () == AST::Module::UNLOADED)
- {
- module.load_items ();
-
- // If the module was previously unloaded, then we don't want to visit it
- // this time around as the CfgStrip hasn't run on its inner items yet.
- // Skip it for now, mark the visitor as dirty and try again
-
- dirty = true;
-
- return;
- }
-
DefaultResolver::visit (module);
- if (Analysis::Mappings::get ().lookup_ast_module (module.get_node_id ())
+ if (Analysis::Mappings::get ().lookup_glob_container (module.get_node_id ())
== tl::nullopt)
- Analysis::Mappings::get ().insert_ast_module (&module);
+ Analysis::Mappings::get ().insert_glob_container (&module);
}
void
@@ -173,19 +150,10 @@ insert_macros (std::vector<PROC_MACRO> &macros, NameResolutionContext &ctx)
}
void
-TopLevel::visit (AST::ExternCrate &crate)
+TopLevel::visit_extern_crate (AST::ExternCrate &extern_crate, AST::Crate &crate,
+ CrateNum num)
{
auto &mappings = Analysis::Mappings::get ();
- auto num_opt = mappings.lookup_crate_name (crate.get_referenced_crate ());
-
- if (!num_opt)
- {
- rust_error_at (crate.get_locus (), "unknown crate %qs",
- crate.get_referenced_crate ().c_str ());
- return;
- }
-
- CrateNum num = *num_opt;
auto attribute_macros = mappings.lookup_attribute_proc_macros (num);
@@ -193,40 +161,27 @@ TopLevel::visit (AST::ExternCrate &crate)
auto derive_macros = mappings.lookup_derive_proc_macros (num);
- auto sub_visitor_1 = [&] () {
- // TODO: Find a way to keep this part clean without the double dispatch.
- if (derive_macros.has_value ())
- {
- insert_macros (derive_macros.value (), ctx);
- for (auto &macro : derive_macros.value ())
- mappings.insert_derive_proc_macro_def (macro);
- }
- if (attribute_macros.has_value ())
- {
- insert_macros (attribute_macros.value (), ctx);
- for (auto &macro : attribute_macros.value ())
- mappings.insert_attribute_proc_macro_def (macro);
- }
- if (bang_macros.has_value ())
- {
- insert_macros (bang_macros.value (), ctx);
- for (auto &macro : bang_macros.value ())
- mappings.insert_bang_proc_macro_def (macro);
- }
- };
-
- auto sub_visitor_2 = [&] () {
- ctx.canonical_ctx.scope_crate (crate.get_node_id (),
- crate.get_referenced_crate (),
- std::move (sub_visitor_1));
- };
+ // TODO: Find a way to keep this part clean without the double dispatch.
+ if (derive_macros.has_value ())
+ {
+ insert_macros (derive_macros.value (), ctx);
+ for (auto &macro : derive_macros.value ())
+ mappings.insert_derive_proc_macro_def (macro);
+ }
+ if (attribute_macros.has_value ())
+ {
+ insert_macros (attribute_macros.value (), ctx);
+ for (auto &macro : attribute_macros.value ())
+ mappings.insert_attribute_proc_macro_def (macro);
+ }
+ if (bang_macros.has_value ())
+ {
+ insert_macros (bang_macros.value (), ctx);
+ for (auto &macro : bang_macros.value ())
+ mappings.insert_bang_proc_macro_def (macro);
+ }
- if (crate.has_as_clause ())
- ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor_2,
- crate.get_as_clause ());
- else
- ctx.scoped (Rib::Kind::Module, crate.get_node_id (), sub_visitor_2,
- crate.get_referenced_crate ());
+ visit (crate);
}
static bool
@@ -384,6 +339,13 @@ TopLevel::visit (AST::Enum &enum_item)
Namespace::Types);
DefaultResolver::visit (enum_item);
+
+ // Since enums can be containers for imports, we need to insert them like we
+ // do for modules
+ if (Analysis::Mappings::get ().lookup_glob_container (
+ enum_item.get_node_id ())
+ == tl::nullopt)
+ Analysis::Mappings::get ().insert_glob_container (&enum_item);
}
void
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index 0dfd654..8d3da92 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -176,7 +176,7 @@ private:
void visit (AST::Union &union_item) override;
void visit (AST::ConstantItem &const_item) override;
void visit (AST::TypeAlias &type_item) override;
- void visit (AST::ExternCrate &crate) override;
+ void visit_extern_crate (AST::ExternCrate &, AST::Crate &, CrateNum) override;
void visit (AST::TypeParam &type_param) override;
void visit (AST::ConstGenericParam &const_param) override;