aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast.h12
-rw-r--r--gcc/rust/ast/rust-path.h54
-rw-r--r--gcc/rust/backend/rust-compile-base.cc56
-rw-r--r--gcc/rust/backend/rust-compile-expr.cc10
-rw-r--r--gcc/rust/backend/rust-compile-expr.h4
-rw-r--r--gcc/rust/backend/rust-compile-resolve-path.cc18
-rw-r--r--gcc/rust/backend/rust-compile-stmt.h8
-rw-r--r--gcc/rust/backend/rust-compile-var-decl.h70
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc2
-rw-r--r--gcc/rust/lint/rust-lint-marklive.cc23
-rw-r--r--gcc/rust/privacy/rust-visibility-resolver.cc6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc13
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h30
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc2
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc533
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.h14
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc4
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h11
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h27
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc186
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h94
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc34
-rw-r--r--gcc/rust/resolve/rust-name-resolver.cc54
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h47
-rw-r--r--gcc/rust/rust-session-manager.cc3
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-expr.h27
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-path.cc147
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.cc6
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-pattern.h2
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-stmt.h34
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-type.cc92
-rw-r--r--gcc/rust/typecheck/rust-tycheck-dump.h2
-rw-r--r--gcc/rust/util/rust-hir-map.cc40
-rw-r--r--gcc/rust/util/rust-hir-map.h4
-rw-r--r--gcc/testsuite/rust/compile/complex-path1.rs18
-rw-r--r--gcc/testsuite/rust/compile/issue-1251.rs14
37 files changed, 895 insertions, 812 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,
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 3de80d9..8fa3fa1 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -333,39 +333,33 @@ std::vector<Bvariable *>
HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
tree fndecl)
{
+ CrateNum crate = ctx->get_mappings ()->get_current_crate ();
+
std::vector<Bvariable *> locals;
for (auto it : rib.get_declarations ())
{
- auto node_id = it.first;
-
- Resolver::Definition d;
- bool ok = ctx->get_resolver ()->lookup_definition (node_id, &d);
- rust_assert (ok);
-
- HIR::Stmt *decl = nullptr;
- if (!ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl))
- {
- // might be an extern block see fix for
- // https://github.com/Rust-GCC/gccrs/issues/976
- continue;
- }
-
- // if its a function we extract this out side of this fn context
- // and it is not a local to this function
- bool is_item = ctx->get_mappings ()->lookup_hir_item (
- decl->get_mappings ().get_crate_num (),
- decl->get_mappings ().get_hirid ())
- != nullptr;
- if (is_item)
- {
- HIR::Item *item = static_cast<HIR::Item *> (decl);
- CompileItem::compile (item, ctx);
- }
-
- Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
+ NodeId node_id = it.first;
+ HirId ref = UNKNOWN_HIRID;
+ if (!ctx->get_mappings ()->lookup_node_to_hir (crate, node_id, &ref))
+ continue;
+
+ // we only care about local patterns
+ HIR::Pattern *pattern
+ = ctx->get_mappings ()->lookup_hir_pattern (crate, ref);
+ if (pattern == nullptr)
+ continue;
+
+ // lookup the type
+ TyTy::BaseType *tyty = nullptr;
+ if (!ctx->get_tyctx ()->lookup_type (ref, &tyty))
+ continue;
+
+ // compile the local
+ tree type = TyTyResolveCompile::compile (ctx, tyty);
+ Bvariable *compiled
+ = CompileVarDecl::compile (fndecl, type, pattern, ctx);
locals.push_back (compiled);
- };
-
+ }
return locals;
}
@@ -482,7 +476,9 @@ HIRCompileBase::compile_function (
compiled_param_type, param_locus);
param_vars.push_back (compiled_param_var);
- ctx->insert_var_decl (referenced_param.get_mappings ().get_hirid (),
+
+ const HIR::Pattern &param_pattern = *referenced_param.get_param_name ();
+ ctx->insert_var_decl (param_pattern.get_pattern_mappings ().get_hirid (),
compiled_param_var);
}
diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc
index b7dad12..b153451 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1432,16 +1432,6 @@ CompileExpr::visit (HIR::IdentifierExpr &expr)
NodeId ref_node_id = UNKNOWN_NODEID;
if (ctx->get_resolver ()->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Resolver::Definition def;
- if (!ctx->get_resolver ()->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
is_value = true;
}
else if (!ctx->get_resolver ()->lookup_resolved_type (ast_node_id,
diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index 593e1f9..3b729c7 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -512,8 +512,8 @@ public:
void visit (HIR::FieldAccessExpr &expr) override
{
- tree receiver_ref
- = CompileExpr::Compile (expr.get_receiver_expr ().get (), ctx);
+ HIR::Expr *receiver_expr = expr.get_receiver_expr ().get ();
+ tree receiver_ref = CompileExpr::Compile (receiver_expr, ctx);
// resolve the receiver back to ADT type
TyTy::BaseType *receiver = nullptr;
diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc
index 4423912..2cf81e0 100644
--- a/gcc/rust/backend/rust-compile-resolve-path.cc
+++ b/gcc/rust/backend/rust-compile-resolve-path.cc
@@ -53,22 +53,12 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment,
// need to look up the reference for this identifier
NodeId ref_node_id = UNKNOWN_NODEID;
- if (ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
- &ref_node_id))
+ if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (),
+ &ref_node_id))
{
- Resolver::Definition def;
- if (!ctx->get_resolver ()->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr_locus, "unknown reference for resolved name");
- return error_mark_node;
- }
- ref_node_id = def.parent;
- }
+ // this can fail because it might be a Constructor for something
+ // in that case the caller should attempt ResolvePathType::Compile
- // this can fail because it might be a Constructor for something
- // in that case the caller should attempt ResolvePathType::Compile
- if (ref_node_id == UNKNOWN_NODEID)
- {
// it might be an enum data-less enum variant
if (lookup->get_kind () != TyTy::TypeKind::ADT)
return error_mark_node;
diff --git a/gcc/rust/backend/rust-compile-stmt.h b/gcc/rust/backend/rust-compile-stmt.h
index 5f17777..aa17a4a 100644
--- a/gcc/rust/backend/rust-compile-stmt.h
+++ b/gcc/rust/backend/rust-compile-stmt.h
@@ -51,9 +51,11 @@ public:
if (!stmt.has_init_expr ())
return;
+ const HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
+ HirId stmt_id = stmt_pattern.get_pattern_mappings ().get_hirid ();
+
TyTy::BaseType *ty = nullptr;
- if (!ctx->get_tyctx ()->lookup_type (stmt.get_mappings ().get_hirid (),
- &ty))
+ if (!ctx->get_tyctx ()->lookup_type (stmt_id, &ty))
{
// FIXME this should be an assertion instead
rust_fatal_error (stmt.get_locus (),
@@ -62,7 +64,7 @@ public:
}
Bvariable *var = nullptr;
- if (!ctx->lookup_var_decl (stmt.get_mappings ().get_hirid (), &var))
+ if (!ctx->lookup_var_decl (stmt_id, &var))
{
// FIXME this should be an assertion instead and use error mark node
rust_fatal_error (stmt.get_locus (),
diff --git a/gcc/rust/backend/rust-compile-var-decl.h b/gcc/rust/backend/rust-compile-var-decl.h
index 2dab39e..e2ee05b 100644
--- a/gcc/rust/backend/rust-compile-var-decl.h
+++ b/gcc/rust/backend/rust-compile-var-decl.h
@@ -25,36 +25,19 @@
namespace Rust {
namespace Compile {
-class CompileVarDecl : public HIRCompileBase,
- public HIR::HIRPatternVisitor,
- public HIR::HIRStmtVisitor
+class CompileVarDecl : public HIRCompileBase, public HIR::HIRPatternVisitor
{
using HIR::HIRPatternVisitor::visit;
- using HIR::HIRStmtVisitor::visit;
public:
- static ::Bvariable *compile (tree fndecl, HIR::Stmt *stmt, Context *ctx)
+ static ::Bvariable *compile (tree fndecl, tree translated_type,
+ HIR::Pattern *pattern, Context *ctx)
{
- CompileVarDecl compiler (ctx, fndecl);
- stmt->accept_vis (compiler);
- ctx->insert_var_decl (stmt->get_mappings ().get_hirid (),
- compiler.compiled_variable);
+ CompileVarDecl compiler (ctx, fndecl, translated_type);
+ pattern->accept_vis (compiler);
return compiler.compiled_variable;
}
- void visit (HIR::LetStmt &stmt) override
- {
- locus = stmt.get_locus ();
- TyTy::BaseType *resolved_type = nullptr;
- bool ok = ctx->get_tyctx ()->lookup_type (stmt.get_mappings ().get_hirid (),
- &resolved_type);
- rust_assert (ok);
-
- translated_type = TyTyResolveCompile::compile (ctx, resolved_type);
- stmt.get_pattern ()->accept_vis (
- static_cast<HIR::HIRPatternVisitor &> (*this));
- }
-
void visit (HIR::IdentifierPattern &pattern) override
{
if (!pattern.is_mut ())
@@ -63,7 +46,10 @@ public:
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, pattern.get_identifier (),
translated_type, NULL /*decl_var*/,
- locus);
+ pattern.get_locus ());
+
+ HirId stmt_id = pattern.get_pattern_mappings ().get_hirid ();
+ ctx->insert_var_decl (stmt_id, compiled_variable);
}
void visit (HIR::WildcardPattern &pattern) override
@@ -72,7 +58,11 @@ public:
compiled_variable
= ctx->get_backend ()->local_variable (fndecl, "_", translated_type,
- NULL /*decl_var*/, locus);
+ NULL /*decl_var*/,
+ pattern.get_locus ());
+
+ HirId stmt_id = pattern.get_pattern_mappings ().get_hirid ();
+ ctx->insert_var_decl (stmt_id, compiled_variable);
}
// Empty visit for unused Pattern HIR nodes.
@@ -87,41 +77,15 @@ public:
void visit (HIR::TuplePattern &) override {}
void visit (HIR::TupleStructPattern &) override {}
- // Empty visit for unused Stmt HIR nodes.
- void visit (HIR::EnumItemTuple &) override {}
- void visit (HIR::EnumItemStruct &) override {}
- void visit (HIR::EnumItem &item) override {}
- void visit (HIR::TupleStruct &tuple_struct) override {}
- void visit (HIR::EnumItemDiscriminant &) override {}
- void visit (HIR::TypePathSegmentFunction &segment) override {}
- void visit (HIR::TypePath &path) override {}
- void visit (HIR::QualifiedPathInType &path) override {}
- void visit (HIR::Module &module) override {}
- void visit (HIR::ExternCrate &crate) override {}
- void visit (HIR::UseDeclaration &use_decl) override {}
- void visit (HIR::Function &function) override {}
- void visit (HIR::TypeAlias &type_alias) override {}
- void visit (HIR::StructStruct &struct_item) override {}
- void visit (HIR::Enum &enum_item) override {}
- void visit (HIR::Union &union_item) override {}
- void visit (HIR::ConstantItem &const_item) override {}
- void visit (HIR::StaticItem &static_item) override {}
- void visit (HIR::Trait &trait) override {}
- void visit (HIR::ImplBlock &impl) override {}
- void visit (HIR::ExternBlock &block) override {}
- void visit (HIR::EmptyStmt &stmt) override {}
- void visit (HIR::ExprStmtWithoutBlock &stmt) override {}
- void visit (HIR::ExprStmtWithBlock &stmt) override {}
-
private:
- CompileVarDecl (Context *ctx, tree fndecl)
- : HIRCompileBase (ctx), fndecl (fndecl), translated_type (error_mark_node),
+ CompileVarDecl (Context *ctx, tree fndecl, tree translated_type)
+ : HIRCompileBase (ctx), fndecl (fndecl), translated_type (translated_type),
compiled_variable (ctx->get_backend ()->error_variable ())
{}
tree fndecl;
tree translated_type;
- Location locus;
+
Bvariable *compiled_variable;
};
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index b3b0ee8..0072d30 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -79,7 +79,7 @@ ASTLowering::go ()
auto mappings = Analysis::Mappings::get ();
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, UNKNOWN_NODEID,
+ Analysis::NodeMapping mapping (crate_num, astCrate.get_node_id (),
mappings->get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
diff --git a/gcc/rust/lint/rust-lint-marklive.cc b/gcc/rust/lint/rust-lint-marklive.cc
index 3776aea..2b01abc 100644
--- a/gcc/rust/lint/rust-lint-marklive.cc
+++ b/gcc/rust/lint/rust-lint-marklive.cc
@@ -179,16 +179,10 @@ MarkLive::visit_path_segment (HIR::PathExprSegment seg)
//
// We should mark them alive all and ignoring other kind of segments.
// If the segment we dont care then just return false is fine
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- Resolver::Definition def;
- bool ok = resolver->lookup_definition (ref_node_id, &def);
- rust_assert (ok);
- ref_node_id = def.parent;
- }
- else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
- {
- return false;
+ if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
+ return false;
}
HirId ref;
bool ok = mappings->lookup_node_to_hir (seg.get_mappings ().get_crate_num (),
@@ -300,16 +294,7 @@ MarkLive::mark_hir_id (HirId id)
void
MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id)
{
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Resolver::Definition def;
- bool ok = resolver->lookup_definition (ref_node_id, &def);
- rust_assert (ok);
- ref_node_id = def.parent;
- }
- else
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
bool ok = resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
rust_assert (ok);
diff --git a/gcc/rust/privacy/rust-visibility-resolver.cc b/gcc/rust/privacy/rust-visibility-resolver.cc
index 421dff0..fdae5aa 100644
--- a/gcc/rust/privacy/rust-visibility-resolver.cc
+++ b/gcc/rust/privacy/rust-visibility-resolver.cc
@@ -71,12 +71,6 @@ VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction,
// TODO: For the hint, can we point to the original item's definition if
// present?
- Resolver::Definition def;
- rust_assert (resolver.lookup_definition (ref_node_id, &def));
-
- // FIXME: Is that what we want?
- ref_node_id = def.parent;
-
HirId ref;
rust_assert (
mappings.lookup_node_to_hir (restriction.get_mappings ().get_crate_num (),
diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc
index 4bf35ef..0ae1847 100644
--- a/gcc/rust/resolve/rust-ast-resolve-expr.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc
@@ -113,16 +113,12 @@ ResolveExpr::visit (AST::IdentifierExpr &expr)
&resolved_node))
{
resolver->insert_resolved_name (expr.get_node_id (), resolved_node);
- resolver->insert_new_definition (expr.get_node_id (),
- Definition{expr.get_node_id (), parent});
}
else if (resolver->get_type_scope ().lookup (
CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()),
&resolved_node))
{
resolver->insert_resolved_type (expr.get_node_id (), resolved_node);
- resolver->insert_new_definition (expr.get_node_id (),
- Definition{expr.get_node_id (), parent});
}
else
{
@@ -352,9 +348,6 @@ ResolveExpr::visit (AST::LoopExpr &expr)
rust_error_at (label.get_locus (), "label redefined multiple times");
rust_error_at (locus, "was defined here");
});
- resolver->insert_new_definition (label_lifetime_node_id,
- Definition{label_lifetime_node_id,
- label.get_node_id ()});
}
resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ());
}
@@ -412,9 +405,6 @@ ResolveExpr::visit (AST::WhileLoopExpr &expr)
rust_error_at (label.get_locus (), "label redefined multiple times");
rust_error_at (locus, "was defined here");
});
- resolver->insert_new_definition (label_lifetime_node_id,
- Definition{label_lifetime_node_id,
- label.get_node_id ()});
}
resolve_expr (expr.get_predicate_expr ().get (), expr.get_node_id ());
resolve_expr (expr.get_loop_block ().get (), expr.get_node_id ());
@@ -443,9 +433,6 @@ ResolveExpr::visit (AST::ForLoopExpr &expr)
rust_error_at (label.get_locus (), "label redefined multiple times");
rust_error_at (locus, "was defined here");
});
- resolver->insert_new_definition (label_lifetime_node_id,
- Definition{label_lifetime_node_id,
- label.get_node_id ()});
}
// this needs a new rib to contain the pattern
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index f17b222..ba184e4 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -76,9 +76,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (constant.get_node_id (),
- Definition{constant.get_node_id (),
- constant.get_node_id ()});
}
void visit (AST::Function &function) override
@@ -93,9 +90,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (function.get_node_id (),
- Definition{function.get_node_id (),
- function.get_node_id ()});
}
void visit (AST::Method &method) override
@@ -110,9 +104,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (method.get_node_id (),
- Definition{method.get_node_id (),
- method.get_node_id ()});
}
private:
@@ -150,9 +141,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (function.get_node_id (),
- Definition{function.get_node_id (),
- function.get_node_id ()});
mappings->insert_canonical_path (mappings->get_current_crate (),
function.get_node_id (), cpath);
@@ -171,9 +159,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (method.get_node_id (),
- Definition{method.get_node_id (),
- method.get_node_id ()});
mappings->insert_canonical_path (mappings->get_current_crate (),
method.get_node_id (), cpath);
@@ -192,9 +177,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (constant.get_node_id (),
- Definition{constant.get_node_id (),
- constant.get_node_id ()});
mappings->insert_canonical_path (mappings->get_current_crate (),
constant.get_node_id (), cpath);
@@ -253,9 +235,9 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (function.get_node_id (),
- Definition{function.get_node_id (),
- function.get_node_id ()});
+
+ NodeId current_module = resolver->peek_current_module_scope ();
+ mappings->insert_module_child_item (current_module, decl);
}
void visit (AST::ExternalStaticItem &item) override
@@ -271,9 +253,9 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (item.get_node_id (),
- Definition{item.get_node_id (),
- item.get_node_id ()});
+
+ NodeId current_module = resolver->peek_current_module_scope ();
+ mappings->insert_module_child_item (current_module, decl);
}
private:
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 198c9c0..9f550ad 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -528,6 +528,7 @@ ResolveItem::visit (AST::Function &function)
auto decl = ResolveFunctionItemToCanonicalPath::resolve (function);
auto path = prefix.append (decl);
auto cpath = canonical_prefix.append (decl);
+
mappings->insert_canonical_path (mappings->get_current_crate (),
function.get_node_id (), cpath);
@@ -788,6 +789,7 @@ ResolveItem::visit (AST::TraitImpl &impl_block)
resolver->get_name_scope ().pop ();
return;
}
+ rust_assert (!canonical_impl_type.is_empty ());
// setup paths
bool canonicalize_type_args = !impl_block.has_generics ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc
index c7597a2..dbf2df7 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-path.cc
@@ -47,301 +47,326 @@ ResolvePath::go (AST::SimplePath *expr, NodeId parent)
void
ResolvePath::resolve_path (AST::PathInExpression *expr)
{
- // resolve root segment first then apply segments in turn
- std::vector<AST::PathExprSegment> &segs = expr->get_segments ();
- AST::PathExprSegment &root_segment = segs.at (0);
- AST::PathIdentSegment &root_ident_seg = root_segment.get_ident_segment ();
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ NodeId module_scope_id = resolver->peek_current_module_scope ();
+ NodeId previous_resolved_node_id = module_scope_id;
+ for (size_t i = 0; i < expr->get_segments ().size (); i++)
+ {
+ auto &segment = expr->get_segments ().at (i);
+ const AST::PathIdentSegment &ident_seg = segment.get_ident_segment ();
+ bool is_first_segment = i == 0;
+ resolved_node_id = UNKNOWN_NODEID;
- bool segment_is_type = false;
- CanonicalPath root_seg_path
- = CanonicalPath::new_seg (root_segment.get_node_id (),
- root_ident_seg.as_string ());
+ NodeId crate_scope_id = resolver->peek_crate_module_scope ();
+ if (segment.is_crate_path_seg ())
+ {
+ // what is the current crate scope node id?
+ module_scope_id = crate_scope_id;
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
+ continue;
+ }
+ else if (segment.is_super_path_seg ())
+ {
+ if (module_scope_id == crate_scope_id)
+ {
+ rust_error_at (segment.get_locus (),
+ "cannot use %<super%> at the crate scope");
+ return;
+ }
+
+ module_scope_id = resolver->peek_parent_module_scope ();
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
+ continue;
+ }
- // name scope first
- if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = false;
- resolver->insert_resolved_name (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = true;
- resolver->insert_resolved_type (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- else
- {
- rust_error_at (expr->get_locus (),
- "Cannot find path %<%s%> in this scope",
- root_segment.as_string ().c_str ());
- return;
- }
+ // resolve any generic args
+ if (segment.has_generic_args ())
+ {
+ bool ok = ResolveTypeToCanonicalPath::type_resolve_generic_args (
+ segment.get_generic_args ());
+ if (!ok)
+ {
+ rust_error_at (segment.get_locus (),
+ "failed to resolve generic arguments");
+ return;
+ }
+ }
- if (root_segment.has_generic_args ())
- {
- bool ok = ResolveTypeToCanonicalPath::type_resolve_generic_args (
- root_segment.get_generic_args ());
- if (!ok)
+ // logic is awkward here there are a few cases
+ //
+ // T::Default
+ // mod::foo::impl_item
+ // super::super::module::item
+ // self
+ // self::foo
+ // self::foo::baz
+ //
+ // T::Default we can only resolve the T and cant do anything about Default
+ // its dependant on associated types
+ //
+ // mod::foo::impl_item
+ // we can resolve mod::foo but nothing about impl_item but we need to
+ // _always resolve generic arguments
+ //
+ // self is a simple single lookup
+ //
+ // we have module_scope_id for the next module_scope to lookup
+ // resolved_node_id is the thing we have resolve this segment to
+ //
+ // new algo?
+ // we can only use module resolution when the previous segment is either
+ // unknown or equal to this module_scope_id
+ //
+ // can only use old resolution when previous segment is unkown
+
+ if (previous_resolved_node_id == module_scope_id)
{
- rust_error_at (root_segment.get_locus (),
- "failed to resolve generic arguments");
- return;
+ Optional<CanonicalPath &> resolved_child
+ = mappings->lookup_module_child (module_scope_id,
+ ident_seg.as_string ());
+ if (resolved_child.is_some ())
+ {
+ NodeId resolved_node = resolved_child->get_node_id ();
+ if (resolver->get_name_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
+ }
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
+ }
+ else
+ {
+ rust_error_at (segment.get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ segment.as_string ().c_str ());
+ return;
+ }
+ }
+ }
+
+ if (resolved_node_id == UNKNOWN_NODEID && is_first_segment)
+ {
+ // name scope first
+ NodeId resolved_node = UNKNOWN_NODEID;
+ const CanonicalPath path
+ = CanonicalPath::new_seg (segment.get_node_id (),
+ ident_seg.as_string ());
+ if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
+ }
+ else
+ {
+ rust_error_at (segment.get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ segment.as_string ().c_str ());
+ return;
+ }
+
+ resolved_node_id = resolved_node;
+ }
+
+ if (resolved_node_id != UNKNOWN_NODEID)
+ {
+ if (mappings->node_is_module (resolved_node_id))
+ {
+ module_scope_id = resolved_node_id;
+ }
+ previous_resolved_node_id = resolved_node_id;
}
}
- bool is_single_segment = segs.size () == 1;
- if (is_single_segment)
+ resolved_node = resolved_node_id;
+ if (resolved_node_id != UNKNOWN_NODEID)
{
- if (segment_is_type)
- resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
+ // name scope first
+ if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ {
+ resolver->insert_resolved_name (expr->get_node_id (),
+ resolved_node_id);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node_id))
+ {
+ resolver->insert_resolved_type (expr->get_node_id (),
+ resolved_node_id);
+ }
else
- resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
-
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- return;
+ {
+ gcc_unreachable ();
+ }
}
-
- resolve_segments (root_seg_path, 1, expr->get_segments (),
- expr->get_node_id (), expr->get_locus ());
}
void
ResolvePath::resolve_path (AST::QualifiedPathInExpression *expr)
{
AST::QualifiedPathType &root_segment = expr->get_qualified_path_type ();
-
- bool canonicalize_type_with_generics = false;
ResolveType::go (&root_segment.get_as_type_path (),
- root_segment.get_node_id (),
- canonicalize_type_with_generics);
-
- ResolveType::go (root_segment.get_type ().get (), root_segment.get_node_id (),
- canonicalize_type_with_generics);
-
- bool type_resolve_generic_args = true;
- CanonicalPath impl_type_seg
- = ResolveTypeToCanonicalPath::resolve (*root_segment.get_type ().get (),
- canonicalize_type_with_generics,
- type_resolve_generic_args);
-
- CanonicalPath trait_type_seg
- = ResolveTypeToCanonicalPath::resolve (root_segment.get_as_type_path (),
- canonicalize_type_with_generics,
- type_resolve_generic_args);
- CanonicalPath root_seg_path
- = TraitImplProjection::resolve (root_segment.get_node_id (), trait_type_seg,
- impl_type_seg);
- bool segment_is_type = false;
+ root_segment.get_node_id ());
+ ResolveType::go (root_segment.get_type ().get (),
+ root_segment.get_node_id ());
- // name scope first
- if (resolver->get_name_scope ().lookup (root_seg_path, &resolved_node))
+ for (auto &segment : expr->get_segments ())
{
- segment_is_type = false;
- resolver->insert_resolved_name (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- // check the type scope
- else if (resolver->get_type_scope ().lookup (root_seg_path, &resolved_node))
- {
- segment_is_type = true;
- resolver->insert_resolved_type (root_segment.get_node_id (),
- resolved_node);
- resolver->insert_new_definition (root_segment.get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- }
- else
- {
- rust_error_at (expr->get_locus (),
- "Cannot find path %<%s%> in this scope",
- root_segment.as_string ().c_str ());
- return;
- }
-
- bool is_single_segment = expr->get_segments ().empty ();
- if (is_single_segment)
- {
- if (segment_is_type)
- resolver->insert_resolved_type (expr->get_node_id (), resolved_node);
- else
- resolver->insert_resolved_name (expr->get_node_id (), resolved_node);
-
- resolver->insert_new_definition (expr->get_node_id (),
- Definition{expr->get_node_id (),
- parent});
- return;
+ // we cant actually do anything with the segment itself since this is all
+ // the job of the type system to figure it out but we can resolve any
+ // generic arguments used
+ if (segment.has_generic_args ())
+ {
+ bool ok = ResolveTypeToCanonicalPath::type_resolve_generic_args (
+ segment.get_generic_args ());
+ if (!ok)
+ {
+ rust_error_at (segment.get_locus (),
+ "failed to resolve generic arguments");
+ return;
+ }
+ }
}
-
- resolve_segments (root_seg_path, 0, expr->get_segments (),
- expr->get_node_id (), expr->get_locus ());
}
void
-ResolvePath::resolve_segments (CanonicalPath prefix, size_t offs,
- std::vector<AST::PathExprSegment> &segs,
- NodeId expr_node_id, Location expr_locus)
+ResolvePath::resolve_path (AST::SimplePath *expr)
{
- // we can attempt to resolve this path fully
- CanonicalPath path = prefix;
- bool segment_is_type = false;
- for (size_t i = offs; i < segs.size (); i++)
- {
- AST::PathExprSegment &seg = segs.at (i);
- auto s = ResolvePathSegmentToCanonicalPath::resolve (seg);
- path = path.append (s);
+ NodeId crate_scope_id = resolver->peek_crate_module_scope ();
+ NodeId module_scope_id = resolver->peek_current_module_scope ();
- // reset state
- segment_is_type = false;
- resolved_node = UNKNOWN_NODEID;
+ NodeId resolved_node_id = UNKNOWN_NODEID;
+ for (size_t i = 0; i < expr->get_segments ().size (); i++)
+ {
+ auto &segment = expr->get_segments ().at (i);
+ bool is_first_segment = i == 0;
+ resolved_node_id = UNKNOWN_NODEID;
- if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ if (segment.is_crate_path_seg ())
{
- resolver->insert_resolved_name (seg.get_node_id (), resolved_node);
- resolver->insert_new_definition (seg.get_node_id (),
- Definition{expr_node_id, parent});
+ // what is the current crate scope node id?
+ module_scope_id = crate_scope_id;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
+ continue;
}
- // check the type scope
- else if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ else if (segment.is_super_path_seg ())
{
- segment_is_type = true;
- resolver->insert_resolved_type (seg.get_node_id (), resolved_node);
- resolver->insert_new_definition (seg.get_node_id (),
- Definition{expr_node_id, parent});
+ if (module_scope_id == crate_scope_id)
+ {
+ rust_error_at (segment.get_locus (),
+ "cannot use %<super%> at the crate scope");
+ return;
+ }
+
+ module_scope_id = resolver->peek_parent_module_scope ();
+ resolver->insert_resolved_name (segment.get_node_id (),
+ module_scope_id);
+ continue;
}
- else
- {
- // attempt to fully resolve the path which is allowed to fail given
- // the following scenario
- //
- // https://github.com/Rust-GCC/gccrs/issues/355 Paths are
- // resolved fully here, there are limitations though imagine:
- //
- // struct Foo<A> (A);
- //
- // impl Foo<isize> {
- // fn test() -> ...
- //
- // impl Foo<f32> {
- // fn test() -> ...
- //
- // fn main() {
- // let a:i32 = Foo::test();
- //
- // there are multiple paths that test can resolve to Foo::<?>::test
- // here so we cannot resolve this case
- //
- // canonical names:
- //
- // struct Foo<A> -> Foo
- // impl Foo<isize>::fn test -> Foo::isize::test
- // impl Foo<f32>::fn test -> Foo::f32::test
- //
- // Since there is the case we have the following paths for test:
- //
- // Foo::isize::test
- // Foo::f32::test
- // vs
- // Foo::test
- //
- // but the lookup was simply Foo::test we must rely on type resolution
- // to figure this type out in a similar fashion to method resolution
- // with a probe phase
- // nothing more we can do we need the type resolver to try and resolve
- // this
- return;
+ Optional<CanonicalPath &> resolved_child
+ = mappings->lookup_module_child (module_scope_id,
+ segment.get_segment_name ());
+ if (resolved_child.is_some ())
+ {
+ NodeId resolved_node = resolved_child->get_node_id ();
+ if (resolver->get_name_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
+ }
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
+ }
+ else
+ {
+ rust_error_at (segment.get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ segment.as_string ().c_str ());
+ return;
+ }
}
- }
-
- // its fully resolved lets mark it as such
- if (resolved_node != UNKNOWN_NODEID)
- {
- if (segment_is_type)
- resolver->insert_resolved_type (expr_node_id, resolved_node);
- else
- resolver->insert_resolved_name (expr_node_id, resolved_node);
-
- resolver->insert_new_definition (expr_node_id,
- Definition{expr_node_id, parent});
- }
-}
-
-static bool
-lookup_and_insert_segment (Resolver *resolver, CanonicalPath path,
- NodeId segment_id, NodeId *to_resolve, bool &is_type)
-{
- if (resolver->get_name_scope ().lookup (path, to_resolve))
- {
- resolver->insert_resolved_name (segment_id, *to_resolve);
- }
- else if (resolver->get_type_scope ().lookup (path, to_resolve))
- {
- is_type = true;
- resolver->insert_resolved_type (segment_id, *to_resolve);
- }
- else
- {
- return false;
- }
- return true;
-}
-
-void
-ResolvePath::resolve_path (AST::SimplePath *simple_path)
-{
- // resolve root segment first then apply segments in turn
- auto expr_node_id = simple_path->get_node_id ();
- auto is_type = false;
-
- auto path = CanonicalPath::create_empty ();
- for (const auto &seg : simple_path->get_segments ())
- {
- auto s = ResolveSimplePathSegmentToCanonicalPath::resolve (seg);
- path = path.append (s);
-
- // Reset state
- resolved_node = UNKNOWN_NODEID;
- is_type = false;
+ if (resolved_node_id == UNKNOWN_NODEID && is_first_segment)
+ {
+ // name scope first
+ NodeId resolved_node = UNKNOWN_NODEID;
+ const CanonicalPath path
+ = CanonicalPath::new_seg (segment.get_node_id (),
+ segment.get_segment_name ());
+ if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_name (segment.get_node_id (),
+ resolved_node);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_type (segment.get_node_id (),
+ resolved_node);
+ }
+ }
- if (!lookup_and_insert_segment (resolver, path, seg.get_node_id (),
- &resolved_node, is_type))
+ if (resolved_node_id == UNKNOWN_NODEID)
{
- rust_error_at (seg.get_locus (),
- "cannot find simple path segment %qs",
- seg.as_string ().c_str ());
+ rust_error_at (segment.get_locus (),
+ "cannot find simple path segment %<%s%> in this scope",
+ segment.as_string ().c_str ());
return;
}
+
+ if (mappings->node_is_module (resolved_node_id))
+ {
+ module_scope_id = resolved_node_id;
+ }
}
- if (resolved_node == UNKNOWN_NODEID)
+ resolved_node = resolved_node_id;
+ if (resolved_node_id != UNKNOWN_NODEID)
{
- rust_error_at (simple_path->get_locus (),
- "could not resolve simple path %qs",
- simple_path->as_string ().c_str ());
- return;
+ // name scope first
+ if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ {
+ resolver->insert_resolved_name (expr->get_node_id (),
+ resolved_node_id);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node_id))
+ {
+ resolver->insert_resolved_type (expr->get_node_id (),
+ resolved_node_id);
+ }
+ else
+ {
+ gcc_unreachable ();
+ }
}
-
- if (is_type)
- resolver->insert_resolved_type (expr_node_id, resolved_node);
- else
- resolver->insert_resolved_name (expr_node_id, resolved_node);
-
- resolver->insert_new_definition (expr_node_id,
- Definition{expr_node_id, parent});
}
} // namespace Resolver
diff --git a/gcc/rust/resolve/rust-ast-resolve-path.h b/gcc/rust/resolve/rust-ast-resolve-path.h
index cbfe967..fc8785f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-path.h
+++ b/gcc/rust/resolve/rust-ast-resolve-path.h
@@ -40,26 +40,12 @@ private:
void resolve_path (AST::QualifiedPathInExpression *expr);
void resolve_path (AST::SimplePath *expr);
- void resolve_segments (CanonicalPath prefix, size_t offs,
- std::vector<AST::PathExprSegment> &segs,
- NodeId expr_node_id, Location expr_locus);
-
void
resolve_simple_path_segments (CanonicalPath prefix, size_t offs,
const std::vector<AST::SimplePathSegment> &segs,
NodeId expr_node_id, Location expr_locus);
};
-class ResolveSimplePathSegmentToCanonicalPath
-{
-public:
- static CanonicalPath resolve (const AST::SimplePathSegment &seg)
- {
- // FIXME: Since this is so simple, maybe it can simply be a tiny function?
- return CanonicalPath::new_seg (seg.get_node_id (), seg.get_segment_name ());
- }
-};
-
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
index dc2cca4..1947212 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.cc
@@ -87,9 +87,7 @@ PatternDeclaration::visit (AST::StructPattern &pattern)
CanonicalPath::new_seg (ident.get_node_id (),
ident.get_identifier ()),
ident.get_node_id (), ident.get_locus ());
- resolver->insert_new_definition (ident.get_node_id (),
- Definition{ident.get_node_id (),
- ident.get_node_id ()});
+
resolver->mark_decl_mutability (ident.get_node_id (),
ident.is_mut ());
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h
index dfb05d3..b899754 100644
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.h
+++ b/gcc/rust/resolve/rust-ast-resolve-pattern.h
@@ -48,9 +48,6 @@ public:
&resolved_node))
{
resolver->insert_resolved_name (pattern.get_node_id (), resolved_node);
- resolver->insert_new_definition (pattern.get_node_id (),
- Definition{pattern.get_node_id (),
- parent});
}
}
@@ -76,9 +73,7 @@ public:
resolver->get_name_scope ().insert (
CanonicalPath::new_seg (pattern.get_node_id (), pattern.get_ident ()),
pattern.get_node_id (), pattern.get_locus ());
- resolver->insert_new_definition (pattern.get_node_id (),
- Definition{pattern.get_node_id (),
- parent});
+
resolver->mark_decl_mutability (pattern.get_node_id (),
pattern.get_is_mut ());
}
@@ -88,9 +83,7 @@ public:
resolver->get_name_scope ().insert (
CanonicalPath::new_seg (pattern.get_node_id (), "_"),
pattern.get_node_id (), pattern.get_locus ());
- resolver->insert_new_definition (pattern.get_node_id (),
- Definition{pattern.get_node_id (),
- parent});
+
resolver->mark_decl_mutability (pattern.get_node_id (), false);
}
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index c8d42bc..3556b68 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -71,9 +71,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (constant.get_node_id (),
- Definition{constant.get_node_id (),
- constant.get_node_id ()});
ResolveType::go (constant.get_type ().get (), constant.get_node_id ());
ResolveExpr::go (constant.get_expr ().get (), constant.get_node_id (),
@@ -361,9 +358,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (function.get_node_id (),
- Definition{function.get_node_id (),
- function.get_node_id ()});
NodeId scope_node_id = function.get_node_id ();
resolver->get_name_scope ().push (scope_node_id);
diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
index 7a1458e..78b786a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h
+++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h
@@ -62,10 +62,6 @@ public:
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (module.get_node_id (),
- Definition{module.get_node_id (),
- module.get_node_id ()});
-
NodeId current_module = resolver->peek_current_module_scope ();
mappings->insert_module_child_item (current_module, mod);
mappings->insert_module_child (current_module, module.get_node_id ());
@@ -278,9 +274,7 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (var.get_node_id (),
- Definition{var.get_node_id (),
- var.get_node_id ()});
+
resolver->mark_decl_mutability (var.get_node_id (), var.is_mutable ());
NodeId current_module = resolver->peek_current_module_scope ();
@@ -302,9 +296,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (constant.get_node_id (),
- Definition{constant.get_node_id (),
- constant.get_node_id ()});
NodeId current_module = resolver->peek_current_module_scope ();
mappings->insert_module_child_item (current_module, decl);
@@ -325,17 +316,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (function.get_node_id (),
- Definition{function.get_node_id (),
- function.get_node_id ()});
-
- // if this does not get a reference it will be determined to be unused
- // lets give it a fake reference to itself
- if (function.get_function_name ().compare ("main") == 0)
- {
- resolver->insert_resolved_name (function.get_node_id (),
- function.get_node_id ());
- }
NodeId current_module = resolver->peek_current_module_scope ();
mappings->insert_module_child_item (current_module, decl);
@@ -386,11 +366,6 @@ public:
r.add_range (locus);
rust_error_at (r, "redefined multiple times");
});
- resolver->insert_new_definition (impl_block.get_node_id (),
- Definition{impl_block.get_node_id (),
- impl_block.get_node_id ()});
- resolver->insert_resolved_name (impl_block.get_node_id (),
- impl_block.get_node_id ());
for (auto &impl_item : impl_block.get_impl_items ())
ResolveToplevelImplItem::go (impl_item.get (), impl_prefix);
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 2b5c684..ce9c0d1 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -133,15 +133,12 @@ ResolveType::visit (AST::ArrayType &type)
void
ResolveType::visit (AST::TraitObjectTypeOneBound &type)
{
- NodeId bound_resolved_id
- = ResolveTypeBound::go (&type.get_trait_bound (), type.get_node_id ());
- ok = bound_resolved_id != UNKNOWN_NODEID;
+ ResolveTypeBound::go (&type.get_trait_bound (), type.get_node_id ());
}
void
ResolveType::visit (AST::TraitObjectType &type)
{
- ok = true;
for (auto &bound : type.get_type_param_bounds ())
{
/* NodeId bound_resolved_id = */
@@ -270,30 +267,183 @@ ResolveRelativeTypePath::ResolveRelativeTypePath (CanonicalPath qualified_path)
}
bool
-ResolveRelativeTypePath::go (AST::QualifiedPathInType &path)
+ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id)
{
- // resolve the type and trait path
- auto &qualified_path = path.get_qualified_path_type ();
CanonicalPath result = CanonicalPath::create_empty ();
- if (!resolve_qual_seg (qualified_path, result))
- return false;
+ ResolveRelativeTypePath o (result);
+ auto &resolver = o.resolver;
+ auto &mappings = o.mappings;
- // resolve the associated impl if available but it can also be from a trait
- // and this is allowed to fail
- auto resolver = Resolver::get ();
- NodeId projection_resolved_id = UNKNOWN_NODEID;
- if (resolver->get_name_scope ().lookup (result, &projection_resolved_id))
+ NodeId module_scope_id = resolver->peek_current_module_scope ();
+ NodeId previous_resolved_node_id = module_scope_id;
+ for (size_t i = 0; i < path.get_segments ().size (); i++)
{
- // mark the resolution for this
- resolver->insert_resolved_name (qualified_path.get_node_id (),
- projection_resolved_id);
+ auto &segment = path.get_segments ().at (i);
+ const AST::PathIdentSegment &ident_seg = segment->get_ident_segment ();
+ bool is_first_segment = i == 0;
+ resolved_node_id = UNKNOWN_NODEID;
+
+ NodeId crate_scope_id = resolver->peek_crate_module_scope ();
+ if (segment->is_crate_path_seg ())
+ {
+ // what is the current crate scope node id?
+ module_scope_id = crate_scope_id;
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
+
+ continue;
+ }
+ else if (segment->is_super_path_seg ())
+ {
+ if (module_scope_id == crate_scope_id)
+ {
+ rust_error_at (segment->get_locus (),
+ "cannot use super at the crate scope");
+ return false;
+ }
+
+ module_scope_id = resolver->peek_parent_module_scope ();
+ previous_resolved_node_id = module_scope_id;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ module_scope_id);
+ continue;
+ }
+
+ switch (segment->get_type ())
+ {
+ case AST::TypePathSegment::SegmentType::GENERIC: {
+ AST::TypePathSegmentGeneric *s
+ = static_cast<AST::TypePathSegmentGeneric *> (segment.get ());
+ if (s->has_generic_args ())
+ {
+ for (auto &gt : s->get_generic_args ().get_type_args ())
+ {
+ ResolveType::go (gt.get (), UNKNOWN_NODEID);
+ }
+ }
+ }
+ break;
+
+ case AST::TypePathSegment::SegmentType::REG:
+ // nothing to do
+ break;
+
+ case AST::TypePathSegment::SegmentType::FUNCTION:
+ gcc_unreachable ();
+ break;
+ }
+
+ if (previous_resolved_node_id == module_scope_id
+ && path.get_segments ().size () > 1)
+ {
+ Optional<CanonicalPath &> resolved_child
+ = mappings->lookup_module_child (module_scope_id,
+ ident_seg.as_string ());
+ if (resolved_child.is_some ())
+ {
+ NodeId resolved_node = resolved_child->get_node_id ();
+ if (resolver->get_name_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_name (segment->get_node_id (),
+ resolved_node);
+ }
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node))
+ {
+ resolved_node_id = resolved_node;
+ resolver->insert_resolved_type (segment->get_node_id (),
+ resolved_node);
+ }
+ else
+ {
+ rust_error_at (segment->get_locus (),
+ "Cannot find path %<%s%> in this scope",
+ segment->as_string ().c_str ());
+ return false;
+ }
+ }
+ }
+
+ if (resolved_node_id == UNKNOWN_NODEID && is_first_segment)
+ {
+ // name scope first
+ NodeId resolved_node = UNKNOWN_NODEID;
+ const CanonicalPath path
+ = CanonicalPath::new_seg (segment->get_node_id (),
+ ident_seg.as_string ());
+ if (resolver->get_type_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_type (segment->get_node_id (),
+ resolved_node);
+ }
+ else if (resolver->get_name_scope ().lookup (path, &resolved_node))
+ {
+ resolver->insert_resolved_name (segment->get_node_id (),
+ resolved_node);
+ }
+ else
+ {
+ rust_error_at (segment->get_locus (),
+ "failed to resolve TypePath: %s in this scope",
+ segment->as_string ().c_str ());
+ return false;
+ }
+
+ resolved_node_id = resolved_node;
+ }
+
+ if (resolved_node_id != UNKNOWN_NODEID)
+ {
+ if (mappings->node_is_module (resolved_node_id))
+ {
+ module_scope_id = resolved_node_id;
+ }
+ previous_resolved_node_id = resolved_node_id;
+ }
}
+ if (resolved_node_id != UNKNOWN_NODEID)
+ {
+ // name scope first
+ if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ {
+ resolver->insert_resolved_name (path.get_node_id (),
+ resolved_node_id);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node_id))
+ {
+ resolver->insert_resolved_type (path.get_node_id (),
+ resolved_node_id);
+ }
+ else
+ {
+ gcc_unreachable ();
+ }
+ }
+
+ return true;
+}
+
+bool
+ResolveRelativeTypePath::go (AST::QualifiedPathInType &path)
+{
+ CanonicalPath result = CanonicalPath::create_empty ();
+ ResolveRelativeTypePath o (result);
+
+ // resolve the type and trait path
+ auto &qualified_path = path.get_qualified_path_type ();
+ if (!o.resolve_qual_seg (qualified_path, result))
+ return false;
+
// 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 ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h
index d10cec2..cc117ec 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.h
+++ b/gcc/rust/resolve/rust-ast-resolve-type.h
@@ -190,13 +190,13 @@ class ResolveRelativeTypePath : public ResolveTypeToCanonicalPath
using ResolveTypeToCanonicalPath::visit;
public:
+ static bool go (AST::TypePath &path, NodeId &resolved_node_id);
static bool go (AST::QualifiedPathInType &path);
private:
ResolveRelativeTypePath (CanonicalPath qualified_path);
- static bool resolve_qual_seg (AST::QualifiedPathType &seg,
- CanonicalPath &result);
+ bool resolve_qual_seg (AST::QualifiedPathType &seg, CanonicalPath &result);
};
class ResolveType : public ResolverBase
@@ -211,7 +211,6 @@ public:
ResolveType resolver (parent, canonicalize_type_with_generics,
canonical_path);
type->accept_vis (resolver);
-
return resolver.resolved_node;
};
@@ -226,7 +225,6 @@ public:
void visit (AST::TupleType &tuple) override
{
- ok = true;
if (tuple.is_unit_type ())
{
resolved_node = resolver->get_unit_type_node_id ();
@@ -239,87 +237,16 @@ public:
void visit (AST::TypePath &path) override
{
- auto rel_canonical_path
- = ResolveTypeToCanonicalPath::resolve (path,
- canonicalize_type_with_generics,
- true);
- if (rel_canonical_path.is_empty ())
- {
- rust_error_at (path.get_locus (),
- "Failed to resolve canonical path for TypePath");
- return;
- }
-
- // lets try and resolve in one go else leave it up to the type resolver to
- // figure outer
-
- if (resolver->get_type_scope ().lookup (rel_canonical_path, &resolved_node))
- {
- resolver->insert_resolved_type (path.get_node_id (), resolved_node);
- resolver->insert_new_definition (path.get_node_id (),
- Definition{path.get_node_id (),
- parent});
-
- if (canonical_path != nullptr)
- {
- const CanonicalPath *cpath = nullptr;
- bool ok
- = mappings->lookup_canonical_path (mappings->get_current_crate (),
- resolved_node, &cpath);
- if (!ok)
- {
- *canonical_path = rel_canonical_path;
- }
- else
- {
- *canonical_path = *cpath;
- }
- }
-
- return;
- }
-
- // lets resolve as many segments as we can and leave it up to the type
- // resolver otherwise
- size_t nprocessed = 0;
- rel_canonical_path.iterate ([&] (const CanonicalPath &seg) -> bool {
- resolved_node = UNKNOWN_NODEID;
-
- if (!resolver->get_type_scope ().lookup (seg, &resolved_node))
- return false;
-
- resolver->insert_resolved_type (seg.get_node_id (), resolved_node);
- resolver->insert_new_definition (seg.get_node_id (),
- Definition{path.get_node_id (), parent});
- nprocessed++;
- return true;
- });
-
- if (nprocessed == 0)
+ if (ResolveRelativeTypePath::go (path, resolved_node))
{
- rust_error_at (path.get_locus (), "failed to resolve TypePath: %s",
- path.as_string ().c_str ());
- return;
- }
-
- // its ok if this fails since the type resolver sometimes will need to
- // investigate the bounds of a type for the associated type for example see:
- // https://github.com/Rust-GCC/gccrs/issues/746
- if (nprocessed == rel_canonical_path.size ())
- {
- resolver->insert_resolved_type (path.get_node_id (), resolved_node);
- resolver->insert_new_definition (path.get_node_id (),
- Definition{path.get_node_id (),
- parent});
+ if (canonical_path == nullptr)
+ return;
- if (canonical_path != nullptr)
+ const CanonicalPath *type_path = nullptr;
+ if (mappings->lookup_canonical_path (mappings->get_current_crate (),
+ resolved_node, &type_path))
{
- const CanonicalPath *cpath = nullptr;
- bool ok
- = mappings->lookup_canonical_path (mappings->get_current_crate (),
- resolved_node, &cpath);
- rust_assert (ok);
- *canonical_path = *cpath;
+ *canonical_path = *type_path;
}
}
}
@@ -350,11 +277,10 @@ private:
CanonicalPath *canonical_path)
: ResolverBase (parent),
canonicalize_type_with_generics (canonicalize_type_with_generics),
- ok (false), canonical_path (canonical_path)
+ canonical_path (canonical_path)
{}
bool canonicalize_type_with_generics;
- bool ok;
CanonicalPath *canonical_path;
};
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 8465162..169237a 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -81,6 +81,11 @@ NameResolution::go (AST::Crate &crate)
= CanonicalPath::new_seg (scope_node_id, crate_name);
crate_prefix.set_crate_num (cnum);
+ // setup a dummy crate node
+ resolver->get_name_scope ().insert (
+ CanonicalPath::new_seg (crate.get_node_id (), "__$$crate__"),
+ crate.get_node_id (), Location ());
+
// setup the root scope
resolver->push_new_module_scope (scope_node_id);
@@ -167,19 +172,21 @@ ResolveRelativeTypePath::resolve_qual_seg (AST::QualifiedPathType &seg,
seg.as_string ().c_str ());
return false;
}
- bool include_generic_args_in_path = false;
- NodeId type_resolved_node
- = ResolveType::go (seg.get_type ().get (), seg.get_node_id ());
+ auto type = seg.get_type ().get ();
+ NodeId type_resolved_node = ResolveType::go (type, seg.get_node_id ());
if (type_resolved_node == UNKNOWN_NODEID)
return false;
- CanonicalPath impl_type_seg
- = ResolveTypeToCanonicalPath::resolve (*seg.get_type ().get (),
- include_generic_args_in_path);
+ const CanonicalPath *impl_type_seg = nullptr;
+ bool ok
+ = mappings->lookup_canonical_path (mappings->get_current_crate (),
+ type_resolved_node, &impl_type_seg);
+ rust_assert (ok);
+
if (!seg.has_as_clause ())
{
- result = result.append (impl_type_seg);
+ result = result.append (*impl_type_seg);
return true;
}
@@ -188,12 +195,15 @@ ResolveRelativeTypePath::resolve_qual_seg (AST::QualifiedPathType &seg,
if (trait_resolved_node == UNKNOWN_NODEID)
return false;
- CanonicalPath trait_type_seg
- = ResolveTypeToCanonicalPath::resolve (seg.get_as_type_path (),
- include_generic_args_in_path);
+ const CanonicalPath *trait_type_seg = nullptr;
+ ok = mappings->lookup_canonical_path (mappings->get_current_crate (),
+ trait_resolved_node, &trait_type_seg);
+ rust_assert (ok);
+
CanonicalPath projection
- = TraitImplProjection::resolve (seg.get_node_id (), trait_type_seg,
- impl_type_seg);
+ = TraitImplProjection::resolve (seg.get_node_id (), *trait_type_seg,
+ *impl_type_seg);
+
result = result.append (projection);
return true;
}
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
index fc1f361..fcf7190 100644
--- a/gcc/rust/resolve/rust-name-resolver.cc
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -34,6 +34,12 @@
_R.push_back (builtin_type); \
tyctx->insert_builtin (_TY->get_ref (), builtin_type->get_node_id (), \
_TY); \
+ mappings->insert_node_to_hir (mappings->get_current_crate (), \
+ builtin_type->get_node_id (), \
+ _TY->get_ref ()); \
+ mappings->insert_canonical_path ( \
+ mappings->get_current_crate (), builtin_type->get_node_id (), \
+ CanonicalPath::new_seg (builtin_type->get_node_id (), _X)); \
} \
while (0)
@@ -165,6 +171,16 @@ Scope::iterate (std::function<bool (Rib *)> cb)
}
}
+void
+Scope::iterate (std::function<bool (const Rib *)> cb) const
+{
+ for (auto it = stack.rbegin (); it != stack.rend (); ++it)
+ {
+ if (!cb (*it))
+ return;
+ }
+}
+
Rib *
Scope::peek ()
{
@@ -200,6 +216,21 @@ Scope::append_reference_for_def (NodeId refId, NodeId defId)
rust_assert (ok);
}
+bool
+Scope::decl_was_declared_here (NodeId def) const
+{
+ bool found = false;
+ iterate ([&] (const Rib *r) -> bool {
+ if (r->decl_was_declared_here (def))
+ {
+ found = true;
+ return false;
+ }
+ return true;
+ });
+ return found;
+}
+
Resolver::Resolver ()
: mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()),
name_scope (Scope (mappings->get_current_crate ())),
@@ -371,29 +402,6 @@ Resolver::generate_builtins ()
}
void
-Resolver::insert_new_definition (NodeId id, Definition def)
-{
- auto it = name_definitions.find (id);
- if (it != name_definitions.end ())
- {
- rust_assert (it->second.is_equal (def));
- return;
- }
- name_definitions[id] = def;
-}
-
-bool
-Resolver::lookup_definition (NodeId id, Definition *def)
-{
- auto it = name_definitions.find (id);
- if (it == name_definitions.end ())
- return false;
-
- *def = it->second;
- return true;
-}
-
-void
Resolver::insert_resolved_name (NodeId refId, NodeId defId)
{
resolved_names[refId] = defId;
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 23a9d82..6b611b2 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -73,11 +73,13 @@ public:
bool lookup (const CanonicalPath &ident, NodeId *id);
void iterate (std::function<bool (Rib *)> cb);
+ void iterate (std::function<bool (const Rib *)> cb) const;
Rib *peek ();
void push (NodeId id);
Rib *pop ();
+ bool decl_was_declared_here (NodeId def) const;
void append_reference_for_def (NodeId refId, NodeId defId);
CrateNum get_crate_num () const { return crate_num; }
@@ -87,32 +89,6 @@ private:
std::vector<Rib *> stack;
};
-// This can map simple NodeIds for names to their parent node
-// for example:
-//
-// var x = y + 1;
-//
-// say y has node id=1 and the plus_expression has id=2
-// then the Definition will have
-// Definition { node=1, parent=2 }
-// this will be used later to gather the ribs for the type inferences context
-//
-// if parent is UNKNOWN_NODEID then this is a root declaration
-// say the var_decl hasa node_id=4;
-// the parent could be a BLOCK_Expr node_id but lets make it UNKNOWN_NODE_ID
-// so we know when it terminates
-struct Definition
-{
- NodeId node;
- NodeId parent;
- // add kind ?
-
- bool is_equal (const Definition &other)
- {
- return node == other.node && parent == other.parent;
- }
-};
-
class Resolver
{
public:
@@ -136,9 +112,6 @@ public:
bool find_label_rib (NodeId id, Rib **rib);
bool find_macro_rib (NodeId id, Rib **rib);
- void insert_new_definition (NodeId id, Definition def);
- bool lookup_definition (NodeId id, Definition *def);
-
void insert_resolved_name (NodeId refId, NodeId defId);
bool lookup_resolved_name (NodeId refId, NodeId *defId);
@@ -183,6 +156,18 @@ public:
return current_module_stack.back ();
}
+ NodeId peek_crate_module_scope () const
+ {
+ rust_assert (!current_module_stack.empty ());
+ return current_module_stack.front ();
+ }
+
+ NodeId peek_parent_module_scope () const
+ {
+ rust_assert (current_module_stack.size () > 1);
+ return current_module_stack.at (current_module_stack.size () - 2);
+ }
+
private:
Resolver ();
@@ -207,10 +192,6 @@ private:
std::map<NodeId, Rib *> label_ribs;
std::map<NodeId, Rib *> macro_ribs;
- // map any Node to its Definition
- // ie any name or type usage
- std::map<NodeId, Definition> name_definitions;
-
// Rust uses DefIds to namespace these under a crate_num
// but then it uses the def_collector to assign local_defids
// to each ast node as well. not sure if this is going to fit
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 0b0e5af..5706375 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -737,6 +737,9 @@ Session::parse_file (const char *filename)
if (saw_errors ())
return;
+ // add the mappings to it
+ mappings->insert_hir_crate (&hir);
+
// type resolve
Resolver::TypeResolution::Resolve (hir);
if (options.dump_option_enabled (CompileOptions::TYPE_RESOLUTION_DUMP))
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 8427cc9..e84f5e8 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -423,35 +423,14 @@ public:
// then lookup the reference_node_id
NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
- // these ref_node_ids will resolve to a pattern declaration but we are
- // interested in the definition that this refers to get the parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- // FIXME
- // this is an internal error
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return;
- }
- ref_node_id = def.parent;
- }
- else if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id))
- {
- // FIXME
- // this is an internal error
- rust_error_at (expr.get_locus (),
- "Failed to lookup type reference for node: %s",
- expr.as_string ().c_str ());
- return;
+ resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
}
if (ref_node_id == UNKNOWN_NODEID)
{
- // FIXME
- // this is an internal error
+ // FIXME this needs to go away and just return error node
rust_error_at (expr.get_locus (), "unresolved node: %s",
expr.as_string ().c_str ());
return;
diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc
index 3823c57..a059611 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-path.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc
@@ -67,6 +67,36 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
// inherit the bound
root->inherit_bounds ({specified_bound});
+ // setup the associated types
+ const TraitReference *specified_bound_ref = specified_bound.get ();
+ auto candidates = TypeBoundsProbe::Probe (root);
+ AssociatedImplTrait *associated_impl_trait = nullptr;
+ for (auto &probed_bound : candidates)
+ {
+ const TraitReference *bound_trait_ref = probed_bound.first;
+ const HIR::ImplBlock *associated_impl = probed_bound.second;
+
+ HirId impl_block_id = associated_impl->get_mappings ().get_hirid ();
+ AssociatedImplTrait *associated = nullptr;
+ bool found_impl_trait
+ = context->lookup_associated_trait_impl (impl_block_id, &associated);
+ if (found_impl_trait)
+ {
+ bool found_trait = specified_bound_ref->is_equal (*bound_trait_ref);
+ bool found_self = associated->get_self ()->can_eq (root, false);
+ if (found_trait && found_self)
+ {
+ associated_impl_trait = associated;
+ break;
+ }
+ }
+ }
+
+ if (associated_impl_trait != nullptr)
+ {
+ associated_impl_trait->setup_associated_types (root, specified_bound);
+ }
+
// lookup the associated item from the specified bound
HIR::PathExprSegment &item_seg = expr.get_segments ().at (0);
HIR::PathIdentSegment item_seg_identifier = item_seg.get_segment ();
@@ -81,28 +111,6 @@ TypeCheckExpr::visit (HIR::QualifiedPathInExpression &expr)
// infer the root type
infered = item.get_tyty_for_receiver (root);
- // we need resolve to the impl block
- NodeId impl_resolved_id = UNKNOWN_NODEID;
- bool have_associated_impl = resolver->lookup_resolved_name (
- qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id);
- AssociatedImplTrait *lookup_associated = nullptr;
- if (have_associated_impl)
- {
- HirId impl_block_id;
- bool ok
- = mappings->lookup_node_to_hir (expr.get_mappings ().get_crate_num (),
- impl_resolved_id, &impl_block_id);
- rust_assert (ok);
-
- bool found_impl_trait
- = context->lookup_associated_trait_impl (impl_block_id,
- &lookup_associated);
- if (found_impl_trait)
- {
- lookup_associated->setup_associated_types (root, specified_bound);
- }
- }
-
// turbo-fish segment path::<ty>
if (item_seg.has_generic_args ())
{
@@ -145,7 +153,9 @@ TypeCheckExpr::visit (HIR::PathInExpression &expr)
return;
if (tyseg->needs_generic_substitutions ())
- tyseg = SubstMapper::InferSubst (tyseg, expr.get_locus ());
+ {
+ tyseg = SubstMapper::InferSubst (tyseg, expr.get_locus ());
+ }
bool fully_resolved = offset == expr.get_segments ().size ();
if (fully_resolved)
@@ -162,30 +172,19 @@ TyTy::BaseType *
TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
NodeId *root_resolved_node_id)
{
+ TyTy::BaseType *root_tyty = nullptr;
*offset = 0;
for (size_t i = 0; i < expr.get_num_segments (); i++)
{
HIR::PathExprSegment &seg = expr.get_segments ().at (i);
+
bool have_more_segments = (expr.get_num_segments () - 1 != i);
+ bool is_root = *offset == 0;
NodeId ast_node_id = seg.get_mappings ().get_nodeid ();
// then lookup the reference_node_id
NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we
- // are interested in the definition that this refers to get the
- // parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (expr.get_locus (),
- "unknown reference for resolved name");
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
- }
- ref_node_id = def.parent;
- }
- else
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
}
@@ -193,6 +192,12 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
// ref_node_id is the NodeId that the segments refers to.
if (ref_node_id == UNKNOWN_NODEID)
{
+ if (root_tyty != nullptr && *offset > 0)
+ {
+ // then we can let the impl path probe take over now
+ return root_tyty;
+ }
+
rust_error_at (seg.get_locus (),
"failed to type resolve root segment");
return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
@@ -217,7 +222,8 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
= (nullptr
!= mappings->lookup_module (expr.get_mappings ().get_crate_num (),
ref));
- if (seg_is_module)
+ auto seg_is_crate = mappings->is_local_hirid_crate (ref);
+ if (seg_is_module || seg_is_crate)
{
// A::B::C::this_is_a_module::D::E::F
// ^^^^^^^^^^^^^^^^
@@ -239,8 +245,33 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
TyTy::BaseType *lookup = nullptr;
if (!context->lookup_type (ref, &lookup))
{
- rust_error_at (seg.get_locus (), "failed to resolve root segment");
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
+ if (is_root)
+ {
+ rust_error_at (seg.get_locus (),
+ "failed to resolve root segment");
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
+ }
+ return root_tyty;
+ }
+
+ // if we have a previous segment type
+ if (root_tyty != nullptr)
+ {
+ // if this next segment needs substitution we must apply the
+ // previous type arguments
+ //
+ // such as: GenericStruct::<_>::new(123, 456)
+ if (lookup->needs_generic_substitutions ())
+ {
+ if (!root_tyty->needs_generic_substitutions ())
+ {
+ auto used_args_in_prev_segment
+ = GetUsedSubstArgs::From (root_tyty);
+ lookup
+ = SubstMapperInternal::Resolve (lookup,
+ used_args_in_prev_segment);
+ }
+ }
}
// turbo-fish segment path::<ty>
@@ -248,21 +279,24 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset,
{
if (!lookup->can_substitute ())
{
- rust_error_at (seg.get_locus (),
+ rust_error_at (expr.get_locus (),
"substitutions not supported for %s",
- lookup->as_string ().c_str ());
- return new TyTy::ErrorType (lookup->get_ref ());
+ root_tyty->as_string ().c_str ());
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
- lookup = SubstMapper::Resolve (lookup, seg.get_locus (),
+
+ lookup = SubstMapper::Resolve (lookup, expr.get_locus (),
&seg.get_generic_args ());
+ if (lookup->get_kind () == TyTy::TypeKind::ERROR)
+ return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
}
*root_resolved_node_id = ref_node_id;
*offset = *offset + 1;
- return lookup;
+ root_tyty = lookup;
}
- return new TyTy::ErrorType (expr.get_mappings ().get_hirid ());
+ return root_tyty;
}
void
@@ -423,22 +457,17 @@ TypeCheckExpr::resolve_segments (NodeId root_resolved_node_id,
context->insert_receiver (expr_mappings.get_hirid (), prev_segment);
- // lookup if the name resolver was able to canonically resolve this or not
- NodeId path_resolved_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (expr_mappings.get_nodeid (),
- &path_resolved_id))
+ // name scope first
+ if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
{
- rust_assert (path_resolved_id == resolved_node_id);
+ resolver->insert_resolved_name (expr_mappings.get_nodeid (),
+ resolved_node_id);
}
// check the type scope
- else if (resolver->lookup_resolved_type (expr_mappings.get_nodeid (),
- &path_resolved_id))
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node_id))
{
- rust_assert (path_resolved_id == resolved_node_id);
- }
- else
- {
- resolver->insert_resolved_name (expr_mappings.get_nodeid (),
+ resolver->insert_resolved_type (expr_mappings.get_nodeid (),
resolved_node_id);
}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
index be3b8e4..1018f81 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc
@@ -350,5 +350,11 @@ TypeCheckPattern::visit (HIR::RangePattern &pattern)
infered = upper->unify (lower);
}
+void
+TypeCheckPattern::visit (HIR::IdentifierPattern &pattern)
+{
+ infered = parent;
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.h b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
index 03c4977..860aca9 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-pattern.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.h
@@ -58,6 +58,8 @@ public:
void visit (HIR::RangePattern &pattern) override;
+ void visit (HIR::IdentifierPattern &pattern) override;
+
private:
TypeCheckPattern (TyTy::BaseType *parent)
: TypeCheckBase (), parent (parent), infered (nullptr)
diff --git a/gcc/rust/typecheck/rust-hir-type-check-stmt.h b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
index 327bffa..96e92b4 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-stmt.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-stmt.h
@@ -79,6 +79,7 @@ public:
infered
= TyTy::TupleType::get_unit_type (stmt.get_mappings ().get_hirid ());
+ const HIR::Pattern &stmt_pattern = *stmt.get_pattern ();
TyTy::BaseType *init_expr_ty = nullptr;
if (stmt.has_init_expr ())
{
@@ -86,10 +87,8 @@ public:
if (init_expr_ty->get_kind () == TyTy::TypeKind::ERROR)
return;
- init_expr_ty = init_expr_ty->clone ();
- auto ref = init_expr_ty->get_ref ();
- init_expr_ty->set_ref (stmt.get_mappings ().get_hirid ());
- init_expr_ty->append_reference (ref);
+ init_expr_ty->append_reference (
+ stmt_pattern.get_pattern_mappings ().get_hirid ());
}
TyTy::BaseType *specified_ty = nullptr;
@@ -99,38 +98,35 @@ public:
// let x:i32 = 123;
if (specified_ty != nullptr && init_expr_ty != nullptr)
{
- auto unified_ty = specified_ty->coerce (init_expr_ty);
- if (unified_ty->get_kind () == TyTy::TypeKind::ERROR)
- return;
-
- context->insert_type (stmt.get_mappings (), specified_ty);
+ // FIXME use this result and look at the regressions
+ specified_ty->coerce (init_expr_ty);
+ context->insert_type (stmt_pattern.get_pattern_mappings (),
+ specified_ty);
}
else
{
// let x:i32;
if (specified_ty != nullptr)
{
- context->insert_type (stmt.get_mappings (), specified_ty);
+ context->insert_type (stmt_pattern.get_pattern_mappings (),
+ specified_ty);
}
// let x = 123;
else if (init_expr_ty != nullptr)
{
- context->insert_type (stmt.get_mappings (), init_expr_ty);
+ context->insert_type (stmt_pattern.get_pattern_mappings (),
+ init_expr_ty);
}
// let x;
else
{
context->insert_type (
- stmt.get_mappings (),
- new TyTy::InferType (stmt.get_mappings ().get_hirid (),
- TyTy::InferType::InferTypeKind::GENERAL,
- stmt.get_locus ()));
+ stmt_pattern.get_pattern_mappings (),
+ new TyTy::InferType (
+ stmt_pattern.get_pattern_mappings ().get_hirid (),
+ TyTy::InferType::InferTypeKind::GENERAL, stmt.get_locus ()));
}
}
-
- TyTy::BaseType *lookup = nullptr;
- bool ok = context->lookup_type (stmt.get_mappings ().get_hirid (), &lookup);
- rust_assert (ok);
}
void visit (HIR::TupleStruct &struct_decl) override
diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc
index 85de3a1..a5597be 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-type.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc
@@ -151,6 +151,36 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// inherit the bound
root->inherit_bounds ({specified_bound});
+ // setup the associated types
+ const TraitReference *specified_bound_ref = specified_bound.get ();
+ auto candidates = TypeBoundsProbe::Probe (root);
+ AssociatedImplTrait *associated_impl_trait = nullptr;
+ for (auto &probed_bound : candidates)
+ {
+ const TraitReference *bound_trait_ref = probed_bound.first;
+ const HIR::ImplBlock *associated_impl = probed_bound.second;
+
+ HirId impl_block_id = associated_impl->get_mappings ().get_hirid ();
+ AssociatedImplTrait *associated = nullptr;
+ bool found_impl_trait
+ = context->lookup_associated_trait_impl (impl_block_id, &associated);
+ if (found_impl_trait)
+ {
+ bool found_trait = specified_bound_ref->is_equal (*bound_trait_ref);
+ bool found_self = associated->get_self ()->can_eq (root, false);
+ if (found_trait && found_self)
+ {
+ associated_impl_trait = associated;
+ break;
+ }
+ }
+ }
+
+ if (associated_impl_trait != nullptr)
+ {
+ associated_impl_trait->setup_associated_types (root, specified_bound);
+ }
+
// lookup the associated item from the specified bound
std::unique_ptr<HIR::TypePathSegment> &item_seg
= path.get_associated_segment ();
@@ -166,28 +196,6 @@ TypeCheckType::visit (HIR::QualifiedPathInType &path)
// infer the root type
translated = item.get_tyty_for_receiver (root);
- // we need resolve to the impl block
- NodeId impl_resolved_id = UNKNOWN_NODEID;
- bool have_associated_impl = resolver->lookup_resolved_name (
- qual_path_type.get_mappings ().get_nodeid (), &impl_resolved_id);
- AssociatedImplTrait *lookup_associated = nullptr;
- if (have_associated_impl)
- {
- HirId impl_block_id;
- bool ok
- = mappings->lookup_node_to_hir (path.get_mappings ().get_crate_num (),
- impl_resolved_id, &impl_block_id);
- rust_assert (ok);
-
- bool found_impl_trait
- = context->lookup_associated_trait_impl (impl_block_id,
- &lookup_associated);
- if (found_impl_trait)
- {
- lookup_associated->setup_associated_types (root, specified_bound);
- }
- }
-
// turbo-fish segment path::<ty>
if (item_seg->get_type () == HIR::TypePathSegment::SegmentType::GENERIC)
{
@@ -245,21 +253,7 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
// then lookup the reference_node_id
NodeId ref_node_id = UNKNOWN_NODEID;
- if (resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
- {
- // these ref_node_ids will resolve to a pattern declaration but we
- // are interested in the definition that this refers to get the
- // parent id
- Definition def;
- if (!resolver->lookup_definition (ref_node_id, &def))
- {
- rust_error_at (path.get_locus (),
- "unknown reference for resolved name");
- return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
- }
- ref_node_id = def.parent;
- }
- else
+ if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id))
{
resolver->lookup_resolved_type (ast_node_id, &ref_node_id);
}
@@ -270,14 +264,15 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
if (is_root)
{
rust_error_at (seg->get_locus (),
- "failed to type resolve root segment");
+ "unknown reference for resolved name: %<%s%>",
+ seg->get_ident_segment ().as_string ().c_str ());
return new TyTy::ErrorType (path.get_mappings ().get_hirid ());
}
return root_tyty;
}
// node back to HIR
- HirId ref;
+ HirId ref = UNKNOWN_HIRID;
if (!mappings->lookup_node_to_hir (path.get_mappings ().get_crate_num (),
ref_node_id, &ref))
{
@@ -300,8 +295,8 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset,
= (nullptr
!= mappings->lookup_module (path.get_mappings ().get_crate_num (),
ref));
-
- if (seg_is_module)
+ auto seg_is_crate = mappings->is_local_hirid_crate (ref);
+ if (seg_is_module || seg_is_crate)
{
// A::B::C::this_is_a_module::D::E::F
// ^^^^^^^^^^^^^^^^
@@ -498,8 +493,19 @@ TypeCheckType::resolve_segments (
}
else
{
- resolver->insert_resolved_type (expr_mappings.get_nodeid (),
- resolved_node_id);
+ // name scope first
+ if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id))
+ {
+ resolver->insert_resolved_name (expr_mappings.get_nodeid (),
+ resolved_node_id);
+ }
+ // check the type scope
+ else if (resolver->get_type_scope ().decl_was_declared_here (
+ resolved_node_id))
+ {
+ resolver->insert_resolved_type (expr_mappings.get_nodeid (),
+ resolved_node_id);
+ }
}
return tyseg;
diff --git a/gcc/rust/typecheck/rust-tycheck-dump.h b/gcc/rust/typecheck/rust-tycheck-dump.h
index ab7f59a..36963e5 100644
--- a/gcc/rust/typecheck/rust-tycheck-dump.h
+++ b/gcc/rust/typecheck/rust-tycheck-dump.h
@@ -128,7 +128,7 @@ public:
void visit (HIR::LetStmt &stmt) override
{
dump += "let " + stmt.get_pattern ()->as_string () + ":"
- + type_string (stmt.get_mappings ());
+ + type_string (stmt.get_pattern ()->get_pattern_mappings ());
if (stmt.has_init_expr ())
{
dump += " = ";
diff --git a/gcc/rust/util/rust-hir-map.cc b/gcc/rust/util/rust-hir-map.cc
index f9932a4..c21b681 100644
--- a/gcc/rust/util/rust-hir-map.cc
+++ b/gcc/rust/util/rust-hir-map.cc
@@ -201,6 +201,18 @@ Mappings::get_hir_crate (CrateNum crateNum)
return it->second;
}
+bool
+Mappings::is_local_hirid_crate (HirId crateNum)
+{
+ for (const auto &it : hirCrateMappings)
+ {
+ const HIR::Crate *crate = it.second;
+ if (crate->get_mappings ().get_hirid () == crateNum)
+ return true;
+ }
+ return false;
+}
+
void
Mappings::insert_hir_crate (HIR::Crate *crate)
{
@@ -208,6 +220,9 @@ Mappings::insert_hir_crate (HIR::Crate *crate)
rust_assert (get_hir_crate (crateNum) == nullptr);
hirCrateMappings[crateNum] = crate;
+ insert_node_to_hir (crate->get_mappings ().get_crate_num (),
+ crate->get_mappings ().get_nodeid (),
+ crate->get_mappings ().get_hirid ());
}
void
@@ -908,6 +923,25 @@ Mappings::lookup_module_chidren_items (NodeId module)
return Optional<std::vector<Resolver::CanonicalPath> &>::some (it->second);
}
+Optional<Resolver::CanonicalPath &>
+Mappings::lookup_module_child (NodeId module, const std::string &item_name)
+{
+ Optional<std::vector<Resolver::CanonicalPath> &> children
+ = lookup_module_chidren_items (module);
+ if (children.is_none ())
+ return Optional<Resolver::CanonicalPath &>::none ();
+
+ // lookup the children to match the name if we can
+ for (auto &child : children.get ())
+ {
+ const std::string &raw_identifier = child.get ();
+ bool found = raw_identifier.compare (item_name) == 0;
+ if (found)
+ return Optional<Resolver::CanonicalPath &>::some (child);
+ }
+ return Optional<Resolver::CanonicalPath &>::none ();
+}
+
void
Mappings::insert_child_item_to_parent_module_mapping (NodeId child_item,
NodeId parent_module)
@@ -925,5 +959,11 @@ Mappings::lookup_parent_module (NodeId child_item)
return Optional<NodeId>::some (it->second);
}
+bool
+Mappings::node_is_module (NodeId query)
+{
+ return module_child_items.find (query) != module_child_items.end ();
+}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h
index a48d4be..4360ae2 100644
--- a/gcc/rust/util/rust-hir-map.h
+++ b/gcc/rust/util/rust-hir-map.h
@@ -122,6 +122,7 @@ public:
void insert_ast_crate (AST::Crate *crate);
HIR::Crate *get_hir_crate (CrateNum crateNum);
+ bool is_local_hirid_crate (HirId crateNum);
void insert_hir_crate (HIR::Crate *crate);
void insert_defid_mapping (DefId id, HIR::Item *item);
@@ -329,10 +330,13 @@ public:
void insert_module_child_item (NodeId module, Resolver::CanonicalPath item);
Optional<std::vector<Resolver::CanonicalPath> &>
lookup_module_chidren_items (NodeId module);
+ Optional<Resolver::CanonicalPath &>
+ lookup_module_child (NodeId module, const std::string &item_name);
void insert_child_item_to_parent_module_mapping (NodeId child_item,
NodeId parent_module);
Optional<NodeId> lookup_parent_module (NodeId child_item);
+ bool node_is_module (NodeId query);
private:
Mappings ();
diff --git a/gcc/testsuite/rust/compile/complex-path1.rs b/gcc/testsuite/rust/compile/complex-path1.rs
new file mode 100644
index 0000000..54011bd
--- /dev/null
+++ b/gcc/testsuite/rust/compile/complex-path1.rs
@@ -0,0 +1,18 @@
+// { dg-additional-options "-w" }
+mod a {
+ pub fn foo() {}
+}
+
+mod b {
+ pub fn foo() {
+ super::a::foo();
+ }
+}
+
+mod foo {
+ pub struct bar(pub i32);
+}
+
+fn test() -> crate::foo::bar {
+ foo::bar(123)
+}
diff --git a/gcc/testsuite/rust/compile/issue-1251.rs b/gcc/testsuite/rust/compile/issue-1251.rs
new file mode 100644
index 0000000..b16e1e0
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue-1251.rs
@@ -0,0 +1,14 @@
+// { dg-additional-options "-w" }
+mod a {
+ pub mod b {
+ pub mod a {
+ pub fn foo() {}
+ }
+ }
+
+ pub fn bidule() {
+ crate::a::b::a::foo()
+ }
+}
+
+fn main() {}