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-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
14 files changed, 536 insertions, 519 deletions
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