https://gcc.gnu.org/g:3be9f2bec5fbdc99c9c2ad773c89dd43366725cb
commit r17-3066-g3be9f2bec5fbdc99c9c2ad773c89dd43366725cb Author: Pierre-Emmanuel Patry <[email protected]> Date: Fri Jun 26 15:25:18 2026 +0200 gccrs: Allow merge of CanonicalPath context Add a new function to merge one CanonicalPathCtx within another one. This move broke the references within the path segment. To avoid this breakage this commit also changes the way parent handle are stored. Instead of storing a reference to the parent, a record stores the parent's node id. gcc/rust/ChangeLog: * resolve/rust-name-resolution-context.cc (CanonicalPathRecordNormal::as_path): Use context and retrieve parent from its node id. (CanonicalPathRecordImpl::as_path): Likewise. (CanonicalPathRecordTraitImpl::as_path): Likewise. (NameResolutionContext::merge): Merge both record map. * resolve/rust-name-resolution-context.h: Change parent handle representation from reference to node id. Signed-off-by: Pierre-Emmanuel Patry <[email protected]> Diff: --- gcc/rust/resolve/rust-name-resolution-context.cc | 10 +++-- gcc/rust/resolve/rust-name-resolution-context.h | 54 ++++++++++++++---------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/gcc/rust/resolve/rust-name-resolution-context.cc b/gcc/rust/resolve/rust-name-resolution-context.cc index 07b8c163c198..9444dc3a3bbd 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.cc +++ b/gcc/rust/resolve/rust-name-resolution-context.cc @@ -144,7 +144,8 @@ Resolver::CanonicalPath CanonicalPathRecordNormal::as_path (const NameResolutionContext &ctx, Namespace ns) { - auto parent_path = get_parent ().as_path (ctx, ns); + auto &parent = ctx.canonical_ctx.get_record (get_parent ()); + auto parent_path = parent.as_path (ctx, ns); return parent_path.append (Resolver::CanonicalPath::new_seg (node_id, seg)); } @@ -177,7 +178,8 @@ Resolver::CanonicalPath CanonicalPathRecordImpl::as_path (const NameResolutionContext &ctx, Namespace ns) { - auto parent_path = get_parent ().as_path (ctx, ns); + auto parent_path + = ctx.canonical_ctx.get_record (get_parent ()).as_path (ctx, ns); return parent_path.append ( Resolver::CanonicalPath::inherent_impl_seg (impl_id, type_record.as_path (ctx, ns))); @@ -188,7 +190,8 @@ CanonicalPathRecordTraitImpl::as_path (const NameResolutionContext &ctx, Namespace ns) { // Maybe this doesn't need the namespace and will always be in the types NS? - auto parent_path = get_parent ().as_path (ctx, ns); + auto parent_path + = ctx.canonical_ctx.get_record (get_parent ()).as_path (ctx, ns); return parent_path.append ( Resolver::CanonicalPath::trait_impl_projection_seg ( impl_id, trait_path_record.as_path (ctx, ns), @@ -414,6 +417,7 @@ NameResolutionContext::merge (NameResolutionContext &other, NodeId at) merge_fstack (types, other.types); merge_fstack (macros, other.macros); merge_fstack (labels, other.labels); + canonical_ctx.merge (std::move (other.canonical_ctx)); } #if 0 diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index 3041dccb5f94..5aaea963154f 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -235,15 +235,16 @@ public: class CanonicalPathRecordWithParent : public CanonicalPathRecord { public: - CanonicalPathRecordWithParent (CanonicalPathRecord &parent) : parent (&parent) + CanonicalPathRecordWithParent (NodeId parent_node_id) + : parent_node_id (parent_node_id) {} - CanonicalPathRecord &get_parent () { return *parent; } + NodeId get_parent () { return parent_node_id; } bool is_root () const override final { return false; } private: - CanonicalPathRecord *parent; + NodeId parent_node_id; }; class CanonicalPathRecordCrateRoot : public CanonicalPathRecord @@ -270,9 +271,9 @@ private: class CanonicalPathRecordNormal : public CanonicalPathRecordWithParent { public: - CanonicalPathRecordNormal (CanonicalPathRecord &parent, NodeId node_id, + CanonicalPathRecordNormal (NodeId parent_node_id, NodeId node_id, std::string seg) - : CanonicalPathRecordWithParent (parent), node_id (node_id), + : CanonicalPathRecordWithParent (parent_node_id), node_id (node_id), seg (std::move (seg)) { rust_assert (!Analysis::Mappings::get ().node_is_crate (node_id)); @@ -306,9 +307,9 @@ private: class CanonicalPathRecordImpl : public CanonicalPathRecordWithParent { public: - CanonicalPathRecordImpl (CanonicalPathRecord &parent, NodeId impl_id, + CanonicalPathRecordImpl (NodeId parent_node_id, NodeId impl_id, NodeId type_id) - : CanonicalPathRecordWithParent (parent), impl_id (impl_id), + : CanonicalPathRecordWithParent (parent_node_id), impl_id (impl_id), type_record (type_id) {} @@ -323,9 +324,9 @@ private: class CanonicalPathRecordTraitImpl : public CanonicalPathRecordWithParent { public: - CanonicalPathRecordTraitImpl (CanonicalPathRecord &parent, NodeId impl_id, + CanonicalPathRecordTraitImpl (NodeId parent_node_id, NodeId impl_id, NodeId type_id, NodeId trait_path_id) - : CanonicalPathRecordWithParent (parent), impl_id (impl_id), + : CanonicalPathRecordWithParent (parent_node_id), impl_id (impl_id), type_record (type_id), trait_path_record (trait_path_id) {} @@ -342,7 +343,7 @@ class CanonicalPathCtx { public: CanonicalPathCtx (const NameResolutionContext &ctx) - : current_record (nullptr), nr_ctx (&ctx) + : current_record (UNKNOWN_NODEID), nr_ctx (&ctx) {} Resolver::CanonicalPath get_path (NodeId id, Namespace ns) const @@ -373,13 +374,13 @@ public: void insert_record (NodeId id, std::string seg) { - rust_assert (current_record != nullptr); + rust_assert (current_record != UNKNOWN_NODEID); auto it = records.find (id); if (it == records.end ()) { - auto record = new CanonicalPathRecordNormal (*current_record, id, - std::move (seg)); + auto record + = new CanonicalPathRecordNormal (current_record, id, std::move (seg)); bool ok = records.emplace (id, std::unique_ptr<CanonicalPathRecord> (record)) .second; @@ -394,33 +395,33 @@ public: template <typename F> void scope (NodeId id, std::string seg, F &&f) { - rust_assert (current_record != nullptr); + rust_assert (current_record != UNKNOWN_NODEID); scope_inner (id, std::forward<F> (f), [this, id, &seg] () { - return new CanonicalPathRecordNormal (*current_record, id, + return new CanonicalPathRecordNormal (current_record, id, std::move (seg)); }); } template <typename F> void scope_impl (AST::InherentImpl &impl, F &&f) { - rust_assert (current_record != nullptr); + rust_assert (current_record != UNKNOWN_NODEID); NodeId id = impl.get_node_id (); scope_inner (id, std::forward<F> (f), [this, id, &impl] () { - return new CanonicalPathRecordImpl (*current_record, id, + return new CanonicalPathRecordImpl (current_record, id, impl.get_type ().get_node_id ()); }); } template <typename F> void scope_impl (AST::TraitImpl &impl, F &&f) { - rust_assert (current_record != nullptr); + rust_assert (current_record != UNKNOWN_NODEID); NodeId id = impl.get_node_id (); scope_inner (id, std::forward<F> (f), [this, id, &impl] () { return new CanonicalPathRecordTraitImpl ( - *current_record, id, impl.get_type ().get_node_id (), + current_record, id, impl.get_type ().get_node_id (), impl.get_trait_path ().get_node_id ()); }); } @@ -433,6 +434,15 @@ public: }); } + /** Merge another CanonicalPathCtx within this one. Intended to be used when + * merging crate name resolution context. + */ + void merge (CanonicalPathCtx &&other) + { + records.insert (std::make_move_iterator (other.records.begin ()), + std::make_move_iterator (other.records.end ())); + } + private: template <typename FCreate, typename FCallback> void scope_inner (NodeId id, FCallback &&f_callback, FCreate &&f_create) @@ -446,11 +456,11 @@ private: } rust_assert (it->second->is_root () - || &static_cast<CanonicalPathRecordWithParent &> (*it->second) + || static_cast<CanonicalPathRecordWithParent &> (*it->second) .get_parent () == current_record); - CanonicalPathRecord *stash = it->second.get (); + NodeId stash = it->first; std::swap (stash, current_record); std::forward<FCallback> (f_callback) (); @@ -459,7 +469,7 @@ private: } std::unordered_map<NodeId, std::unique_ptr<CanonicalPathRecord>> records; - CanonicalPathRecord *current_record; + NodeId current_record; const NameResolutionContext *nr_ctx; };
