From b85c3628c0182dd1703f25d80122000972bcd85d Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Fri, 24 Jan 2025 10:42:54 +0100 Subject: [PATCH] backend: Improve handling of lang-item PathInExpressions gcc/rust/ChangeLog: * backend/rust-compile-resolve-path.cc (ResolvePathRef::visit): Call into resolve_path_like instead. (ResolvePathRef::resolve_path_like): New. (ResolvePathRef::resolve): Call into resolve_with_node_id. * backend/rust-compile-resolve-path.h: Declare new functions and document them. --- gcc/rust/backend/rust-compile-resolve-path.cc | 116 ++++++++++-------- gcc/rust/backend/rust-compile-resolve-path.h | 16 +++ 2 files changed, 84 insertions(+), 48 deletions(-) diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 3af3431f8490..d4e8fbe3b99d 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -32,32 +32,37 @@ namespace Rust { namespace Compile { -void -ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr) +template +tree +ResolvePathRef::resolve_path_like (T &expr) { - auto final_segment = HIR::PathIdentSegment::create_error (); if (expr.is_lang_item ()) - final_segment - = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ())); - else - final_segment = expr.get_final_segment ().get_segment (); + { + auto lang_item + = Analysis::Mappings::get ().get_lang_item_node (expr.get_lang_item ()); + + // FIXME: Is that correct? :/ + auto final_segment + = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ())); - resolved - = resolve (final_segment, expr.get_mappings (), expr.get_locus (), true); + return resolve_with_node_id (final_segment, expr.get_mappings (), + expr.get_locus (), true, lang_item); + } + + return resolve (expr.get_final_segment ().get_segment (), + expr.get_mappings (), expr.get_locus (), true); } void -ResolvePathRef::visit (HIR::PathInExpression &expr) +ResolvePathRef::visit (HIR::QualifiedPathInExpression &expr) { - auto final_segment = HIR::PathIdentSegment::create_error (); - if (expr.is_lang_item ()) - final_segment - = HIR::PathIdentSegment (LangItem::ToString (expr.get_lang_item ())); - else - final_segment = expr.get_final_segment ().get_segment (); + resolved = resolve_path_like (expr); +} - resolved - = resolve (final_segment, expr.get_mappings (), expr.get_locus (), true); +void +ResolvePathRef::visit (HIR::PathInExpression &expr) +{ + resolved = resolve_path_like (expr); } tree @@ -106,42 +111,17 @@ ResolvePathRef::attempt_constructor_expression_lookup ( } tree -ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, - const Analysis::NodeMapping &mappings, - location_t expr_locus, bool is_qualified_path) +ResolvePathRef::resolve_with_node_id ( + const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, location_t expr_locus, + bool is_qualified_path, NodeId resolved_node_id) { TyTy::BaseType *lookup = nullptr; bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup); rust_assert (ok); - // need to look up the reference for this identifier - - // this can fail because it might be a Constructor for something - // in that case the caller should attempt ResolvePathType::Compile - NodeId ref_node_id = UNKNOWN_NODEID; - if (flag_name_resolution_2_0) - { - auto nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - - auto resolved = nr_ctx.lookup (mappings.get_nodeid ()); - - if (!resolved) - return attempt_constructor_expression_lookup (lookup, ctx, mappings, - expr_locus); - - ref_node_id = *resolved; - } - else - { - if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (), - &ref_node_id)) - return attempt_constructor_expression_lookup (lookup, ctx, mappings, - expr_locus); - } - tl::optional hid - = ctx->get_mappings ().lookup_node_to_hir (ref_node_id); + = ctx->get_mappings ().lookup_node_to_hir (resolved_node_id); if (!hid.has_value ()) { rust_error_at (expr_locus, "reverse call path lookup failure"); @@ -207,9 +187,49 @@ ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, { TREE_USED (resolved_item) = 1; } + return resolved_item; } +tree +ResolvePathRef::resolve (const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, + location_t expr_locus, bool is_qualified_path) +{ + TyTy::BaseType *lookup = nullptr; + bool ok = ctx->get_tyctx ()->lookup_type (mappings.get_hirid (), &lookup); + rust_assert (ok); + + // need to look up the reference for this identifier + + // this can fail because it might be a Constructor for something + // in that case the caller should attempt ResolvePathType::Compile + NodeId ref_node_id = UNKNOWN_NODEID; + if (flag_name_resolution_2_0) + { + auto nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + auto resolved = nr_ctx.lookup (mappings.get_nodeid ()); + + if (!resolved) + return attempt_constructor_expression_lookup (lookup, ctx, mappings, + expr_locus); + + ref_node_id = *resolved; + } + else + { + if (!ctx->get_resolver ()->lookup_resolved_name (mappings.get_nodeid (), + &ref_node_id)) + return attempt_constructor_expression_lookup (lookup, ctx, mappings, + expr_locus); + } + + return resolve_with_node_id (final_segment, mappings, expr_locus, + is_qualified_path, ref_node_id); +} + tree HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, const HIR::PathIdentSegment &final_segment, diff --git a/gcc/rust/backend/rust-compile-resolve-path.h b/gcc/rust/backend/rust-compile-resolve-path.h index a920fccaef38..4eb0e224ba78 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.h +++ b/gcc/rust/backend/rust-compile-resolve-path.h @@ -61,6 +61,22 @@ class ResolvePathRef : public HIRCompileBase, public HIR::HIRPatternVisitor : HIRCompileBase (ctx), resolved (error_mark_node) {} + /** + * Generic visitor for both PathInExpression and QualifiedPathInExpression + */ + template tree resolve_path_like (T &expr); + + /** + * Inner implementation of `resolve` - resolution with an already known NodeId + */ + tree resolve_with_node_id (const HIR::PathIdentSegment &final_segment, + const Analysis::NodeMapping &mappings, + location_t locus, bool is_qualified_path, + NodeId resolved_node_id); + /** + * Resolve a mappings' NodeId and call into `resolve_with_node_id` which + * performs the rest of the path resolution + */ tree resolve (const HIR::PathIdentSegment &final_segment, const Analysis::NodeMapping &mappings, location_t locus, bool is_qualified_path);