From 4a4ba3a86d3d721a84f2c5461cae671e78ea99e0 Mon Sep 17 00:00:00 2001 From: Owen Avery Date: Thu, 3 Jul 2025 17:48:57 -0400 Subject: [PATCH 1/2] nr1.0: Remove rust/checks support gcc/rust/ChangeLog: * checks/errors/borrowck/rust-bir-builder-internal.h (BuilderContext::resolver): Remove member variable. (BuilderContext::BuilderContext): Remove initialization of resolver member variable. (AbstractBuilder::resolve_label): Assume nr2.0 is enabled. (AbstractBuilder::resolve_variable): Likewise. (AbstractBuilder::resolve_variable_or_fn): Likewise. * checks/errors/privacy/rust-privacy-check.cc (Resolver::resolve): Avoid passing the 1.0 name resolver to VisibilityResolver or PrivacyReporter. * checks/errors/privacy/rust-privacy-reporter.cc (PrivacyReporter::PrivacyReporter): Remove initialization of resolver field. (is_child_module): Assume nr2.0 is enabled. (PrivacyReporter::check_for_privacy_violation): Likewise. * checks/errors/privacy/rust-privacy-reporter.h (PrivacyReporter::PrivacyReporter): Remove 1.0 resolver parameter. (PrivacyReporter::resolver): Remove member variable. * checks/errors/privacy/rust-visibility-resolver.cc: Remove "options.h" inclusion. (VisibilityResolver::VisibilityResolver): Remove 1.0 resolver parameter. (VisibilityResolver::resolve_module_path): Assume nr2.0 is enabled. * checks/errors/privacy/rust-visibility-resolver.h (VisibilityResolver::VisibilityResolver): Remove 1.0 resolver parameter. (VisibilityResolver::resolver): Remove member variable. * checks/errors/rust-const-checker.cc: Remove "options.h" inclusion. (ConstChecker::ConstChecker): Remove 1.0 resolver parameter. (ConstChecker::visit): Assume nr2.0 is enabled. * checks/errors/rust-const-checker.h (ConstChecker::resolver): Remove member variable. * checks/errors/rust-hir-pattern-analysis.cc: Remove "options.h" inclusion. (PatternChecker::PatternChecker): Remove 1.0 resolver parameter. (PatternChecker::visit): Assume nr2.0 is enabled. * checks/errors/rust-hir-pattern-analysis.h (PatternChecker::resolver): Remove member variable. * checks/errors/rust-readonly-check2.cc (ReadonlyChecker::ReadonlyChecker): Remove initialization of resolver member variable. * checks/errors/rust-readonly-check2.h (ReadonlyChecker::resolver): Remove member variable. * checks/errors/rust-unsafe-checker.cc: Remove "options.h" inclusion. (UnsafeChecker::UnsafeChecker): Remove 1.0 resolver parameter. (UnsafeChecker::visit): Assume nr2.0 is enabled. * checks/errors/rust-unsafe-checker.h (UnsafeChecker::resolver): Remove member variable. * checks/lints/rust-lint-marklive.cc (MarkLive::visit_path_segment): Assume nr2.0 is enabled. (MarkLive::visit): Likewise. (MarkLive::find_ref_node_id): Likewise. * checks/lints/rust-lint-marklive.h (MarkLive::resolver): Remove member variable. (MarkLive::MarkLive): Remove initialization of resolver member variable. * checks/lints/rust-lint-scan-deadcode.h (ScanDeadCode::resolver): Remove member variable. (ScanDeadCode::ScanDeadCode): Remove initialization of resolver member variable. Signed-off-by: Owen Avery --- .../borrowck/rust-bir-builder-internal.h | 77 ++++++------------- .../errors/privacy/rust-privacy-check.cc | 5 +- .../errors/privacy/rust-privacy-reporter.cc | 46 +++-------- .../errors/privacy/rust-privacy-reporter.h | 2 - .../privacy/rust-visibility-resolver.cc | 31 +++----- .../errors/privacy/rust-visibility-resolver.h | 4 +- gcc/rust/checks/errors/rust-const-checker.cc | 24 ++---- gcc/rust/checks/errors/rust-const-checker.h | 1 - .../errors/rust-hir-pattern-analysis.cc | 20 ++--- .../checks/errors/rust-hir-pattern-analysis.h | 1 - .../checks/errors/rust-readonly-check2.cc | 3 +- gcc/rust/checks/errors/rust-readonly-check2.h | 1 - gcc/rust/checks/errors/rust-unsafe-checker.cc | 47 +++-------- gcc/rust/checks/errors/rust-unsafe-checker.h | 1 - gcc/rust/checks/lints/rust-lint-marklive.cc | 65 +++++----------- gcc/rust/checks/lints/rust-lint-marklive.h | 2 - .../checks/lints/rust-lint-scan-deadcode.h | 4 +- 17 files changed, 90 insertions(+), 244 deletions(-) diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h index e2cc2ddb0d87..10367a93238d 100644 --- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h +++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-internal.h @@ -75,7 +75,6 @@ struct BuilderContext // External context. Resolver::TypeCheckContext &tyctx; - Resolver::Resolver &resolver; // BIR output BasicBlocks basic_blocks; @@ -102,9 +101,7 @@ struct BuilderContext FreeRegions fn_free_regions{{}}; public: - BuilderContext () - : tyctx (*Resolver::TypeCheckContext::get ()), - resolver (*Resolver::Resolver::get ()) + BuilderContext () : tyctx (*Resolver::TypeCheckContext::get ()) { basic_blocks.emplace_back (); // StartBB } @@ -403,69 +400,43 @@ class AbstractBuilder template NodeId resolve_label (T &expr) { - NodeId resolved_label; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - auto res = nr_ctx.lookup (expr.get_mappings ().get_nodeid ()); - rust_assert (res.has_value ()); - resolved_label = res.value (); - } - else - { - bool ok = ctx.resolver.lookup_resolved_label ( - expr.get_mappings ().get_nodeid (), &resolved_label); - rust_assert (ok); - } - return resolved_label; + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + auto res = nr_ctx.lookup (expr.get_mappings ().get_nodeid ()); + rust_assert (res.has_value ()); + + return *res; } template PlaceId resolve_variable (T &variable) { - NodeId variable_id; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ()); - rust_assert (res.has_value ()); - variable_id = res.value (); - } - else - { - bool ok = ctx.resolver.lookup_resolved_name ( - variable.get_mappings ().get_nodeid (), &variable_id); - rust_assert (ok); - } - return ctx.place_db.lookup_variable (variable_id); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ()); + rust_assert (res.has_value ()); + + return ctx.place_db.lookup_variable (*res); } template PlaceId resolve_variable_or_fn (T &variable, TyTy::BaseType *ty) { ty = (ty) ? ty : lookup_type (variable); + // Unlike variables, // functions do not have to be declared in PlaceDB before use. - NodeId variable_id; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ()); - rust_assert (res.has_value ()); - variable_id = res.value (); - } - else - { - bool ok = ctx.resolver.lookup_resolved_name ( - variable.get_mappings ().get_nodeid (), &variable_id); - rust_assert (ok); - } if (ty->is ()) return ctx.place_db.get_constant (ty); - else - return ctx.place_db.lookup_or_add_variable (variable_id, ty); + + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + auto res = nr_ctx.lookup (variable.get_mappings ().get_nodeid ()); + rust_assert (res.has_value ()); + + return ctx.place_db.lookup_or_add_variable (*res, ty); } protected: // Implicit conversions. diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc index 5291276a7a37..3b94cbf3f1b5 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-check.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-check.cc @@ -35,12 +35,11 @@ Resolver::resolve (HIR::Crate &crate) { PrivacyContext ctx; auto &mappings = Analysis::Mappings::get (); - auto resolver = Rust::Resolver::Resolver::get (); auto ty_ctx = ::Rust::Resolver::TypeCheckContext::get (); - VisibilityResolver (mappings, *resolver).go (crate); + VisibilityResolver (mappings).go (crate); PubRestrictedVisitor (mappings).go (crate); - PrivacyReporter (mappings, *resolver, *ty_ctx).go (crate); + PrivacyReporter (mappings, *ty_ctx).go (crate); auto visitor = ReachabilityVisitor (ctx, *ty_ctx); diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc index 4af9639c38ff..1d7352f4f86d 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc @@ -28,10 +28,8 @@ namespace Rust { namespace Privacy { PrivacyReporter::PrivacyReporter ( - Analysis::Mappings &mappings, Resolver::Resolver &resolver, - const Rust::Resolver::TypeCheckContext &ty_ctx) - : mappings (mappings), resolver (resolver), ty_ctx (ty_ctx), - current_module (tl::nullopt) + Analysis::Mappings &mappings, const Rust::Resolver::TypeCheckContext &ty_ctx) + : mappings (mappings), ty_ctx (ty_ctx), current_module (tl::nullopt) {} // Find a proc_macro, proc_macro_derive or proc_macro_attribute @@ -94,30 +92,10 @@ static bool is_child_module (Analysis::Mappings &mappings, NodeId parent, NodeId possible_child) { - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - - return nr_ctx.values.is_module_descendant (parent, possible_child); - } - - auto children = mappings.lookup_module_children (parent); - - if (!children) - return false; + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - // Visit all toplevel children - for (auto &child : *children) - if (child == possible_child) - return true; - - // Now descend recursively in the child module tree - for (auto &child : *children) - if (is_child_module (mappings, child, possible_child)) - return true; - - return false; + return nr_ctx.values.is_module_descendant (parent, possible_child); } // FIXME: This function needs a lot of refactoring @@ -127,17 +105,11 @@ PrivacyReporter::check_for_privacy_violation (const NodeId &use_id, { NodeId ref_node_id = UNKNOWN_NODEID; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - if (auto id = nr_ctx.lookup (use_id)) - ref_node_id = *id; - } - // FIXME: Don't assert here - we might be dealing with a type - else if (!resolver.lookup_resolved_name (use_id, &ref_node_id)) - resolver.lookup_resolved_type (use_id, &ref_node_id); + if (auto id = nr_ctx.lookup (use_id)) + ref_node_id = *id; // FIXME: Assert here. For now, we return since this causes issues when // checking inferred types (#1260) diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h index 72716a6aa8a3..cc48f9ada0ea 100644 --- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h +++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h @@ -38,7 +38,6 @@ class PrivacyReporter : public HIR::HIRExpressionVisitor, { public: PrivacyReporter (Analysis::Mappings &mappings, - Rust::Resolver::Resolver &resolver, const Rust::Resolver::TypeCheckContext &ty_ctx); /** @@ -157,7 +156,6 @@ types virtual void visit (HIR::ExprStmt &stmt); Analysis::Mappings &mappings; - Rust::Resolver::Resolver &resolver; const Rust::Resolver::TypeCheckContext &ty_ctx; // `None` means we're in the root module - the crate diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc index c59763d73782..dfaed1b340d4 100644 --- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc +++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.cc @@ -22,15 +22,11 @@ #include "rust-hir-item.h" #include "rust-immutable-name-resolution-context.h" -// for flag_name_resolution_2_0 -#include "options.h" - namespace Rust { namespace Privacy { -VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings, - Resolver::Resolver &resolver) - : mappings (mappings), resolver (resolver) +VisibilityResolver::VisibilityResolver (Analysis::Mappings &mappings) + : mappings (mappings) {} void @@ -64,27 +60,20 @@ VisibilityResolver::resolve_module_path (const HIR::SimplePath &restriction, = Error (restriction.get_locus (), "cannot use non-module path as privacy restrictor"); - NodeId ref_node_id = UNKNOWN_NODEID; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - if (auto id = nr_ctx.lookup (ast_node_id)) - { - ref_node_id = *id; - } - else - { - invalid_path.emit (); - return false; - } + NodeId ref_node_id; + if (auto id = nr_ctx.lookup (ast_node_id)) + { + ref_node_id = *id; } - else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) + else { invalid_path.emit (); return false; } + // FIXME: Add a hint here if we can find the path in another scope, such as // a type or something else // TODO: For the hint, can we point to the original item's definition if diff --git a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h index 4dfba4cb86b4..4252b2853300 100644 --- a/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h +++ b/gcc/rust/checks/errors/privacy/rust-visibility-resolver.h @@ -33,8 +33,7 @@ namespace Privacy { class VisibilityResolver : public HIR::HIRVisItemVisitor { public: - VisibilityResolver (Analysis::Mappings &mappings, - Rust::Resolver::Resolver &resolver); + VisibilityResolver (Analysis::Mappings &mappings); /** * Perform visibility resolving on an entire crate @@ -93,7 +92,6 @@ class VisibilityResolver : public HIR::HIRVisItemVisitor private: Analysis::Mappings &mappings; - Rust::Resolver::Resolver &resolver; DefId current_module; }; diff --git a/gcc/rust/checks/errors/rust-const-checker.cc b/gcc/rust/checks/errors/rust-const-checker.cc index 845e5b68187f..1e58d9139eea 100644 --- a/gcc/rust/checks/errors/rust-const-checker.cc +++ b/gcc/rust/checks/errors/rust-const-checker.cc @@ -24,16 +24,10 @@ #include "rust-system.h" #include "rust-immutable-name-resolution-context.h" -// for flag_name_resolution_2_0 -#include "options.h" - namespace Rust { namespace HIR { -ConstChecker::ConstChecker () - : resolver (*Resolver::Resolver::get ()), - mappings (Analysis::Mappings::get ()) -{} +ConstChecker::ConstChecker () : mappings (Analysis::Mappings::get ()) {} void ConstChecker::go (HIR::Crate &crate) @@ -358,18 +352,12 @@ ConstChecker::visit (CallExpr &expr) NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid (); NodeId ref_node_id; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - if (auto id = nr_ctx.lookup (ast_node_id)) - ref_node_id = *id; - else - return; - } - // We don't care about types here - else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) + if (auto id = nr_ctx.lookup (ast_node_id)) + ref_node_id = *id; + else return; if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id)) diff --git a/gcc/rust/checks/errors/rust-const-checker.h b/gcc/rust/checks/errors/rust-const-checker.h index 66138bdc851a..0514fecddb3f 100644 --- a/gcc/rust/checks/errors/rust-const-checker.h +++ b/gcc/rust/checks/errors/rust-const-checker.h @@ -72,7 +72,6 @@ class ConstChecker : public HIRFullVisitor std::vector> ¶m, ConstGenericCtx context); StackedContexts const_context; - Resolver::Resolver &resolver; Analysis::Mappings &mappings; virtual void visit (Lifetime &lifetime) override; diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc index 7fe7f029f2aa..90b05e25480b 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc @@ -28,15 +28,11 @@ #include "rust-tyty.h" #include "rust-immutable-name-resolution-context.h" -// for flag_name_resolution_2_0 -#include "options.h" - namespace Rust { namespace Analysis { PatternChecker::PatternChecker () : tyctx (*Resolver::TypeCheckContext::get ()), - resolver (*Resolver::Resolver::get ()), mappings (Analysis::Mappings::get ()) {} @@ -238,17 +234,13 @@ PatternChecker::visit (CallExpr &expr) NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid (); NodeId ref_node_id; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - if (auto id = nr_ctx.lookup (ast_node_id)) - ref_node_id = *id; - else - return; - } - else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + if (auto id = nr_ctx.lookup (ast_node_id)) + ref_node_id = *id; + else return; if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id)) diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h index 6aefaeca63fc..a73c5a33b0e0 100644 --- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h +++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h @@ -46,7 +46,6 @@ class PatternChecker : public HIR::HIRFullVisitor private: Resolver::TypeCheckContext &tyctx; - Resolver::Resolver &resolver; Analysis::Mappings &mappings; virtual void visit (Lifetime &lifetime) override; diff --git a/gcc/rust/checks/errors/rust-readonly-check2.cc b/gcc/rust/checks/errors/rust-readonly-check2.cc index 9ff09a96702a..2884a90adec2 100644 --- a/gcc/rust/checks/errors/rust-readonly-check2.cc +++ b/gcc/rust/checks/errors/rust-readonly-check2.cc @@ -33,8 +33,7 @@ namespace HIR { static std::set already_assigned_variables = {}; ReadonlyChecker::ReadonlyChecker () - : resolver (*Resolver::Resolver::get ()), - mappings (Analysis::Mappings::get ()), + : mappings (Analysis::Mappings::get ()), context (*Resolver::TypeCheckContext::get ()) {} diff --git a/gcc/rust/checks/errors/rust-readonly-check2.h b/gcc/rust/checks/errors/rust-readonly-check2.h index 06af9dbd17c7..2a981aea8e4d 100644 --- a/gcc/rust/checks/errors/rust-readonly-check2.h +++ b/gcc/rust/checks/errors/rust-readonly-check2.h @@ -38,7 +38,6 @@ class ReadonlyChecker : public DefaultHIRVisitor decrement, }; - Resolver::Resolver &resolver; Analysis::Mappings &mappings; Resolver::TypeCheckContext &context; StackedContexts mutable_context; diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc b/gcc/rust/checks/errors/rust-unsafe-checker.cc index 41ed698db778..c1390295a2eb 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.cc +++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc @@ -25,15 +25,11 @@ #include "rust-system.h" #include "rust-immutable-name-resolution-context.h" -// for flag_name_resolution_2_0 -#include "options.h" - namespace Rust { namespace HIR { UnsafeChecker::UnsafeChecker () : context (*Resolver::TypeCheckContext::get ()), - resolver (*Resolver::Resolver::get ()), mappings (Analysis::Mappings::get ()) {} @@ -220,23 +216,15 @@ UnsafeChecker::visit (PathInExpression &path) NodeId ast_node_id = path.get_mappings ().get_nodeid (); NodeId ref_node_id; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - auto resolved = nr_ctx.lookup (ast_node_id); + auto resolved = nr_ctx.lookup (ast_node_id); - if (!resolved.has_value ()) - return; + if (!resolved.has_value ()) + return; - ref_node_id = resolved.value (); - } - else - { - if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) - return; - } + ref_node_id = resolved.value (); if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id)) { @@ -434,26 +422,15 @@ UnsafeChecker::visit (CallExpr &expr) NodeId ast_node_id = expr.get_fnexpr ().get_mappings ().get_nodeid (); NodeId ref_node_id; - // There are no unsafe types, and functions are defined in the name resolver. - // If we can't find the name, then we're dealing with a type and should return - // early. - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - auto resolved = nr_ctx.lookup (ast_node_id); + auto resolved = nr_ctx.lookup (ast_node_id); - if (!resolved.has_value ()) - return; + if (!resolved.has_value ()) + return; - ref_node_id = resolved.value (); - } - else - { - if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) - return; - } + ref_node_id = resolved.value (); if (auto definition_id = mappings.lookup_node_to_hir (ref_node_id)) { diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h b/gcc/rust/checks/errors/rust-unsafe-checker.h index 4c884ad6b047..d18f9ec3714b 100644 --- a/gcc/rust/checks/errors/rust-unsafe-checker.h +++ b/gcc/rust/checks/errors/rust-unsafe-checker.h @@ -54,7 +54,6 @@ class UnsafeChecker : public HIRFullVisitor StackedContexts unsafe_context; Resolver::TypeCheckContext &context; - Resolver::Resolver &resolver; Analysis::Mappings &mappings; virtual void visit (Lifetime &lifetime) override; diff --git a/gcc/rust/checks/lints/rust-lint-marklive.cc b/gcc/rust/checks/lints/rust-lint-marklive.cc index af7535a9826e..80c30e0c3430 100644 --- a/gcc/rust/checks/lints/rust-lint-marklive.cc +++ b/gcc/rust/checks/lints/rust-lint-marklive.cc @@ -163,21 +163,14 @@ 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 (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + + if (auto id = nr_ctx.lookup (ast_node_id)) + ref_node_id = *id; + else + return false; - if (auto id = nr_ctx.lookup (ast_node_id)) - ref_node_id = *id; - else - return false; - } - else if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) - return false; - } if (auto hid = mappings.lookup_node_to_hir (ref_node_id)) { mark_hir_id (*hid); @@ -250,21 +243,13 @@ MarkLive::visit (HIR::TupleIndexExpr &expr) void MarkLive::visit (HIR::TypeAlias &alias) { - NodeId ast_node_id = UNKNOWN_NODEID; - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - if (auto id = nr_ctx.lookup ( - alias.get_type_aliased ().get_mappings ().get_nodeid ())) - ast_node_id = *id; - } - else - { - resolver->lookup_resolved_type ( - alias.get_type_aliased ().get_mappings ().get_nodeid (), &ast_node_id); - } + NodeId ast_node_id = UNKNOWN_NODEID; + if (auto id + = nr_ctx.lookup (alias.get_type_aliased ().get_mappings ().get_nodeid ())) + ast_node_id = *id; if (auto hid = mappings.lookup_node_to_hir (ast_node_id)) mark_hir_id (*hid); @@ -285,27 +270,13 @@ MarkLive::mark_hir_id (HirId id) void MarkLive::find_ref_node_id (NodeId ast_node_id, NodeId &ref_node_id) { - if (flag_name_resolution_2_0) - { - auto &nr_ctx - = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); + auto &nr_ctx + = Resolver2_0::ImmutableNameResolutionContext::get ().resolver (); - nr_ctx.lookup (ast_node_id).map ([&ref_node_id] (NodeId resolved) { - ref_node_id = resolved; - }); - } + if (auto res = nr_ctx.lookup (ast_node_id)) + ref_node_id = *res; else - { - if (!resolver->lookup_resolved_name (ast_node_id, &ref_node_id)) - { - if (!resolver->lookup_resolved_type (ast_node_id, &ref_node_id)) - { - bool ok - = resolver->lookup_resolved_misc (ast_node_id, &ref_node_id); - rust_assert (ok); - } - } - } + rust_unreachable (); } } // namespace Analysis diff --git a/gcc/rust/checks/lints/rust-lint-marklive.h b/gcc/rust/checks/lints/rust-lint-marklive.h index 86d96fc93673..6b3dafd64e44 100644 --- a/gcc/rust/checks/lints/rust-lint-marklive.h +++ b/gcc/rust/checks/lints/rust-lint-marklive.h @@ -277,11 +277,9 @@ class MarkLive : public MarkLiveBase std::set liveSymbols; std::set scannedSymbols; Analysis::Mappings &mappings; - Resolver::Resolver *resolver; Resolver::TypeCheckContext *tyctx; MarkLive (std::vector worklist) : worklist (worklist), mappings (Analysis::Mappings::get ()), - resolver (Resolver::Resolver::get ()), tyctx (Resolver::TypeCheckContext::get ()){}; void mark_hir_id (HirId); diff --git a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h index 0fc203b03189..bacf8f693523 100644 --- a/gcc/rust/checks/lints/rust-lint-scan-deadcode.h +++ b/gcc/rust/checks/lints/rust-lint-scan-deadcode.h @@ -135,12 +135,10 @@ class ScanDeadcode : public MarkLiveBase private: std::set live_symbols; - Resolver::Resolver *resolver; Analysis::Mappings &mappings; ScanDeadcode (std::set &live_symbols) - : live_symbols (live_symbols), resolver (Resolver::Resolver::get ()), - mappings (Analysis::Mappings::get ()){}; + : live_symbols (live_symbols), mappings (Analysis::Mappings::get ()){}; bool should_warn (HirId hirId) { From d0e754756e76bc3eb754656345e81057d4d72ba0 Mon Sep 17 00:00:00 2001 From: Owen Avery Date: Thu, 3 Jul 2025 17:48:39 -0400 Subject: [PATCH 2/2] nr1.0: Remove This patch removes the old name resolver, leaving only the 2.0 name resolver. gcc/rust/ChangeLog: * Make-lang.in (GRS_OBJS): Remove entries for deleted files. * expand/rust-macro-builtins-helpers.h: Remove inclusion of "rust-early-name-resolver.h". * expand/rust-macro-builtins.cc: Likewise. * expand/rust-macro-expand.cc: Likewise. (MacroExpander::expand_crate): Remove usage of nr1.0 resolver. * expand/rust-macro-expand.h: Remove inclusion of "rust-early-name-resolver.h". (MacroExpander::MacroExpander): Remove initialization of resolver member variable. (MacroExpander::resolver): Remove member variable. * lang.opt (frust-name-resolution-2.0): Remove option. * resolve/rust-name-resolver.cc: Remove inclusion of "options.h". (Resolver::Resolver): Remove member function definition. (Resolver::get): Likewise. (Resolver::push_new_name_rib): Likewise. (Resolver::push_new_type_rib): Likewise. (Resolver::push_new_label_rib): Likewise. (Resolver::push_new_macro_rib): Likewise. (Resolver::find_name_rib): Likewise. (Resolver::find_type_rib): Likewise. (Resolver::find_macro_rib): Likewise. (Resolver::insert_builtin_types): Likewise. (Resolver::get_builtin_types): Likewise. (Resolver::generate_builtins): Likewise. (Resolver::setup_builtin): Likewise. (Resolver::insert_resolved_name): Likewise. (Resolver::lookup_resolved_name): Likewise. (Resolver::insert_resolved_type): Likewise. (Resolver::lookup_resolved_type): Likewise. (Resolver::insert_resolved_label): Likewise. (Resolver::lookup_resolved_label): Likewise. (Resolver::insert_resolved_macro): Likewise. (Resolver::lookup_resolved_macro): Likewise. (Resolver::insert_resolved_misc): Likewise. (Resolver::lookup_resolved_misc): Likewise. (Resolver::push_closure_context): Likewise. (Resolver::pop_closure_context): Likewise. (Resolver::insert_captured_item): Likewise. (Resolver::decl_needs_capture): Likewise. (Resolver::get_captures): Likewise. * resolve/rust-name-resolver.h (class Resolver): Remove. * rust-lang.cc: Remove inclusion of "rust-ast-resolve-item.h". (run_rust_tests): Remove call to rust_simple_path_resolve_test. * rust-session-manager.cc: Remove inclusions of "rust-ast-resolve.h" and "rust-early-name-resolver.h". (Session::compile_crate): Assume nr2.0 is enabled. (Session::expansion): Likewise. (Session::load_extern_crate): Likewise. * resolve/rust-ast-resolve-base.cc: Removed. * resolve/rust-ast-resolve-base.h: Removed. * resolve/rust-ast-resolve-expr.cc: Removed. * resolve/rust-ast-resolve-expr.h: Removed. * resolve/rust-ast-resolve-item.cc: Removed. * resolve/rust-ast-resolve-item.h: Removed. * resolve/rust-ast-resolve-path.cc: Removed. * resolve/rust-ast-resolve-path.h: Removed. * resolve/rust-ast-resolve-pattern.cc: Removed. * resolve/rust-ast-resolve-pattern.h: Removed. * resolve/rust-ast-resolve-stmt.cc: Removed. * resolve/rust-ast-resolve-stmt.h: Removed. * resolve/rust-ast-resolve-struct-expr-field.cc: Removed. * resolve/rust-ast-resolve-struct-expr-field.h: Removed. * resolve/rust-ast-resolve-toplevel.h: Removed. * resolve/rust-ast-resolve-type.cc: Removed. * resolve/rust-ast-resolve-type.h: Removed. * resolve/rust-ast-resolve.cc: Removed. * resolve/rust-ast-resolve.h: Removed. * resolve/rust-early-name-resolver.cc: Removed. * resolve/rust-early-name-resolver.h: Removed. Signed-off-by: Owen Avery --- gcc/rust/Make-lang.in | 10 - gcc/rust/expand/rust-macro-builtins-helpers.h | 1 - gcc/rust/expand/rust-macro-builtins.cc | 1 - gcc/rust/expand/rust-macro-expand.cc | 4 - gcc/rust/expand/rust-macro-expand.h | 5 +- gcc/rust/lang.opt | 4 - gcc/rust/resolve/rust-ast-resolve-base.cc | 691 --------- gcc/rust/resolve/rust-ast-resolve-base.h | 238 ---- gcc/rust/resolve/rust-ast-resolve-expr.cc | 816 ----------- gcc/rust/resolve/rust-ast-resolve-expr.h | 105 -- gcc/rust/resolve/rust-ast-resolve-item.cc | 1246 ----------------- gcc/rust/resolve/rust-ast-resolve-item.h | 161 --- gcc/rust/resolve/rust-ast-resolve-path.cc | 558 -------- gcc/rust/resolve/rust-ast-resolve-path.h | 52 - gcc/rust/resolve/rust-ast-resolve-pattern.cc | 418 ------ gcc/rust/resolve/rust-ast-resolve-pattern.h | 146 -- gcc/rust/resolve/rust-ast-resolve-stmt.cc | 81 -- gcc/rust/resolve/rust-ast-resolve-stmt.h | 408 ------ .../rust-ast-resolve-struct-expr-field.cc | 61 - .../rust-ast-resolve-struct-expr-field.h | 54 - gcc/rust/resolve/rust-ast-resolve-toplevel.h | 500 ------- gcc/rust/resolve/rust-ast-resolve-type.cc | 785 ----------- gcc/rust/resolve/rust-ast-resolve-type.h | 280 ---- gcc/rust/resolve/rust-ast-resolve.cc | 114 -- gcc/rust/resolve/rust-ast-resolve.h | 49 - gcc/rust/resolve/rust-early-name-resolver.cc | 589 -------- gcc/rust/resolve/rust-early-name-resolver.h | 196 --- gcc/rust/resolve/rust-name-resolver.cc | 410 ------ gcc/rust/resolve/rust-name-resolver.h | 175 --- gcc/rust/rust-lang.cc | 2 - gcc/rust/rust-session-manager.cc | 33 +- 31 files changed, 7 insertions(+), 8186 deletions(-) delete mode 100644 gcc/rust/resolve/rust-ast-resolve-base.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-base.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-expr.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-expr.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-item.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-item.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-path.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-path.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-pattern.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-pattern.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-stmt.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-stmt.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-toplevel.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve-type.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve-type.h delete mode 100644 gcc/rust/resolve/rust-ast-resolve.cc delete mode 100644 gcc/rust/resolve/rust-ast-resolve.h delete mode 100644 gcc/rust/resolve/rust-early-name-resolver.cc delete mode 100644 gcc/rust/resolve/rust-early-name-resolver.h diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in index 8cdf6c983312..ee053a583ea3 100644 --- a/gcc/rust/Make-lang.in +++ b/gcc/rust/Make-lang.in @@ -147,17 +147,7 @@ GRS_OBJS = \ rust/rust-ice-finalizer.o \ rust/rust-late-name-resolver-2.0.o \ rust/rust-immutable-name-resolution-context.o \ - rust/rust-early-name-resolver.o \ rust/rust-name-resolver.o \ - rust/rust-ast-resolve.o \ - rust/rust-ast-resolve-base.o \ - rust/rust-ast-resolve-item.o \ - rust/rust-ast-resolve-pattern.o \ - rust/rust-ast-resolve-expr.o \ - rust/rust-ast-resolve-type.o \ - rust/rust-ast-resolve-path.o \ - rust/rust-ast-resolve-stmt.o \ - rust/rust-ast-resolve-struct-expr-field.o \ rust/rust-forever-stack.o \ rust/rust-hir-type-check.o \ rust/rust-privacy-check.o \ diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.h b/gcc/rust/expand/rust-macro-builtins-helpers.h index 32cf58fd1bed..ce63017b004f 100644 --- a/gcc/rust/expand/rust-macro-builtins-helpers.h +++ b/gcc/rust/expand/rust-macro-builtins-helpers.h @@ -22,7 +22,6 @@ #include "rust-ast.h" #include "rust-cfg-strip.h" #include "rust-diagnostics.h" -#include "rust-early-name-resolver.h" #include "rust-expr.h" #include "rust-lex.h" #include "rust-macro-builtins.h" diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc index a7ae22079852..948f3893abdb 100644 --- a/gcc/rust/expand/rust-macro-builtins.cc +++ b/gcc/rust/expand/rust-macro-builtins.cc @@ -29,7 +29,6 @@ #include "rust-ast.h" #include "rust-cfg-strip.h" #include "rust-diagnostics.h" -#include "rust-early-name-resolver.h" #include "rust-expr.h" #include "rust-lex.h" #include "rust-macro-invoc-lexer.h" diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index dfead3acc1d6..6613328ec783 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -27,7 +27,6 @@ #include "rust-macro.h" #include "rust-parse.h" #include "rust-cfg-strip.h" -#include "rust-early-name-resolver.h" #include "rust-proc-macro.h" #include "rust-token-tree-desugar.h" @@ -335,9 +334,6 @@ MacroExpander::expand_invoc (AST::MacroInvocation &invoc, void MacroExpander::expand_crate () { - NodeId scope_node_id = crate.get_node_id (); - resolver->get_macro_scope ().push (scope_node_id); - /* fill macro/decorator map from init list? not sure where init list comes * from? */ diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index 360294c6bf9f..185d50ffb46b 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -27,7 +27,6 @@ #include "rust-ast.h" #include "rust-macro.h" #include "rust-hir-map.h" -#include "rust-early-name-resolver.h" #include "rust-name-resolver.h" #include "rust-macro-invoc-lexer.h" #include "rust-proc-macro-invoc-lexer.h" @@ -300,8 +299,7 @@ struct MacroExpander : cfg (cfg), crate (crate), session (session), sub_stack (SubstitutionScope ()), expanded_fragment (AST::Fragment::create_error ()), - has_changed_flag (false), resolver (Resolver::Resolver::get ()), - mappings (Analysis::Mappings::get ()) + has_changed_flag (false), mappings (Analysis::Mappings::get ()) {} ~MacroExpander () = default; @@ -513,7 +511,6 @@ struct MacroExpander tl::optional last_invoc; public: - Resolver::Resolver *resolver; Analysis::Mappings &mappings; }; diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt index d9824f1a5ac2..8db436d30f2a 100644 --- a/gcc/rust/lang.opt +++ b/gcc/rust/lang.opt @@ -204,10 +204,6 @@ Enum(frust_compile_until) String(compilation) Value(12) EnumValue Enum(frust_compile_until) String(end) Value(13) -frust-name-resolution-2.0 -Rust Var(flag_name_resolution_2_0) Init(1) -Use the temporary and experimental name resolution pipeline instead of the stable one - frust-borrowcheck Rust Var(flag_borrowcheck) Use the WIP borrow checker. diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc deleted file mode 100644 index 3c7b425d79ff..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-base.cc +++ /dev/null @@ -1,691 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-base.h" -#include "rust-ast-resolve-expr.h" -#include "rust-ast-resolve-path.h" -#include "rust-item.h" -#include "rust-path.h" - -namespace Rust { -namespace Resolver { - -bool -ResolverBase::resolve_visibility (const AST::Visibility &vis) -{ - if (vis.has_path ()) - { - auto path = vis.get_path (); - ResolvePath::go (path); - - // Do we need to lookup something here? - // Is it just about resolving the names correctly so we can look them up - // later? - } - - return true; -} - -// Default visitors implementations - -void -ResolverBase::visit (AST::Token &) -{} - -void -ResolverBase::visit (AST::DelimTokenTree &) -{} - -void -ResolverBase::visit (AST::AttrInputMetaItemContainer &) -{} - -void -ResolverBase::visit (AST::IdentifierExpr &) -{} - -void -ResolverBase::visit (AST::Lifetime &) -{} - -void -ResolverBase::visit (AST::LifetimeParam &) -{} - -void -ResolverBase::visit (AST::ConstGenericParam &) -{} - -void -ResolverBase::visit (AST::PathInExpression &) -{} - -void -ResolverBase::visit (AST::TypePathSegment &) -{} - -void -ResolverBase::visit (AST::TypePathSegmentGeneric &) -{} - -void -ResolverBase::visit (AST::TypePathSegmentFunction &) -{} - -void -ResolverBase::visit (AST::TypePath &) -{} - -void -ResolverBase::visit (AST::QualifiedPathInExpression &) -{} - -void -ResolverBase::visit (AST::QualifiedPathInType &) -{} - -void -ResolverBase::visit (AST::LiteralExpr &) -{} - -void -ResolverBase::visit (AST::AttrInputLiteral &) -{} - -void -ResolverBase::visit (AST::AttrInputMacro &) -{} - -void -ResolverBase::visit (AST::MetaItemLitExpr &) -{} - -void -ResolverBase::visit (AST::MetaItemPathExpr &) -{} - -void -ResolverBase::visit (AST::BorrowExpr &) -{} - -void -ResolverBase::visit (AST::DereferenceExpr &) -{} - -void -ResolverBase::visit (AST::ErrorPropagationExpr &) -{} - -void -ResolverBase::visit (AST::NegationExpr &) -{} - -void -ResolverBase::visit (AST::ArithmeticOrLogicalExpr &) -{} - -void -ResolverBase::visit (AST::ComparisonExpr &) -{} - -void -ResolverBase::visit (AST::LazyBooleanExpr &) -{} - -void -ResolverBase::visit (AST::TypeCastExpr &) -{} - -void -ResolverBase::visit (AST::AssignmentExpr &) -{} - -void -ResolverBase::visit (AST::CompoundAssignmentExpr &) -{} - -void -ResolverBase::visit (AST::GroupedExpr &) -{} - -void -ResolverBase::visit (AST::ArrayElemsValues &) -{} - -void -ResolverBase::visit (AST::ArrayElemsCopied &) -{} - -void -ResolverBase::visit (AST::ArrayExpr &) -{} - -void -ResolverBase::visit (AST::ArrayIndexExpr &) -{} - -void -ResolverBase::visit (AST::TupleExpr &) -{} - -void -ResolverBase::visit (AST::TupleIndexExpr &) -{} - -void -ResolverBase::visit (AST::StructExprStruct &) -{} - -void -ResolverBase::visit (AST::StructExprFieldIdentifier &) -{} - -void -ResolverBase::visit (AST::StructExprFieldIdentifierValue &) -{} - -void -ResolverBase::visit (AST::StructExprFieldIndexValue &) -{} - -void -ResolverBase::visit (AST::StructExprStructFields &) -{} - -void -ResolverBase::visit (AST::StructExprStructBase &) -{} - -void -ResolverBase::visit (AST::CallExpr &) -{} - -void -ResolverBase::visit (AST::MethodCallExpr &) -{} - -void -ResolverBase::visit (AST::FieldAccessExpr &) -{} - -void -ResolverBase::visit (AST::ClosureExprInner &) -{} - -void -ResolverBase::visit (AST::BlockExpr &) -{} - -void -ResolverBase::visit (AST::AnonConst &) -{} - -void -ResolverBase::visit (AST::ConstBlock &) -{} - -void -ResolverBase::visit (AST::ClosureExprInnerTyped &) -{} - -void -ResolverBase::visit (AST::ContinueExpr &) -{} - -void -ResolverBase::visit (AST::BreakExpr &) -{} - -void -ResolverBase::visit (AST::RangeFromToExpr &) -{} - -void -ResolverBase::visit (AST::RangeFromExpr &) -{} - -void -ResolverBase::visit (AST::RangeToExpr &) -{} - -void -ResolverBase::visit (AST::RangeFullExpr &) -{} - -void -ResolverBase::visit (AST::RangeFromToInclExpr &) -{} - -void -ResolverBase::visit (AST::RangeToInclExpr &) -{} - -void -ResolverBase::visit (AST::BoxExpr &) -{} - -void -ResolverBase::visit (AST::ReturnExpr &) -{} - -void -ResolverBase::visit (AST::TryExpr &) -{} - -void -ResolverBase::visit (AST::UnsafeBlockExpr &) -{} - -void -ResolverBase::visit (AST::LoopExpr &) -{} - -void -ResolverBase::visit (AST::WhileLoopExpr &) -{} - -void -ResolverBase::visit (AST::WhileLetLoopExpr &) -{} - -void -ResolverBase::visit (AST::ForLoopExpr &) -{} - -void -ResolverBase::visit (AST::IfExpr &) -{} - -void -ResolverBase::visit (AST::IfExprConseqElse &) -{} - -void -ResolverBase::visit (AST::IfLetExpr &) -{} - -void -ResolverBase::visit (AST::IfLetExprConseqElse &) -{} - -void -ResolverBase::visit (AST::MatchExpr &) -{} - -void -ResolverBase::visit (AST::AwaitExpr &) -{} - -void -ResolverBase::visit (AST::AsyncBlockExpr &) -{} - -void -ResolverBase::visit (AST::InlineAsm &) -{} - -void -ResolverBase::visit (AST::LlvmInlineAsm &) -{} - -void -ResolverBase::visit (AST::TypeParam &) -{} - -void -ResolverBase::visit (AST::LifetimeWhereClauseItem &) -{} - -void -ResolverBase::visit (AST::TypeBoundWhereClauseItem &) -{} - -void -ResolverBase::visit (AST::Module &) -{} - -void -ResolverBase::visit (AST::ExternCrate &) -{} - -void -ResolverBase::visit (AST::UseTreeGlob &) -{} - -void -ResolverBase::visit (AST::UseTreeList &) -{} - -void -ResolverBase::visit (AST::UseTreeRebind &) -{} - -void -ResolverBase::visit (AST::UseDeclaration &) -{} - -void -ResolverBase::visit (AST::Function &) -{} - -void -ResolverBase::visit (AST::TypeAlias &) -{} - -void -ResolverBase::visit (AST::StructStruct &) -{} - -void -ResolverBase::visit (AST::TupleStruct &) -{} - -void -ResolverBase::visit (AST::EnumItem &) -{} - -void -ResolverBase::visit (AST::EnumItemTuple &) -{} - -void -ResolverBase::visit (AST::EnumItemStruct &) -{} - -void -ResolverBase::visit (AST::EnumItemDiscriminant &) -{} - -void -ResolverBase::visit (AST::Enum &) -{} - -void -ResolverBase::visit (AST::Union &) -{} - -void -ResolverBase::visit (AST::ConstantItem &) -{} - -void -ResolverBase::visit (AST::StaticItem &) -{} - -void -ResolverBase::visit (AST::TraitItemConst &) -{} - -void -ResolverBase::visit (AST::TraitItemType &) -{} - -void -ResolverBase::visit (AST::Trait &) -{} - -void -ResolverBase::visit (AST::InherentImpl &) -{} - -void -ResolverBase::visit (AST::TraitImpl &) -{} - -void -ResolverBase::visit (AST::ExternalTypeItem &) -{} - -void -ResolverBase::visit (AST::ExternalStaticItem &) -{} - -void -ResolverBase::visit (AST::ExternBlock &) -{} - -void -ResolverBase::visit (AST::MacroMatchFragment &) -{} - -void -ResolverBase::visit (AST::MacroMatchRepetition &) -{} - -void -ResolverBase::visit (AST::MacroMatcher &) -{} - -void -ResolverBase::visit (AST::MacroRulesDefinition &) -{} - -void -ResolverBase::visit (AST::MacroInvocation &) -{} - -void -ResolverBase::visit (AST::MetaItemPath &) -{} - -void -ResolverBase::visit (AST::MetaItemSeq &) -{} - -void -ResolverBase::visit (AST::MetaWord &) -{} - -void -ResolverBase::visit (AST::MetaNameValueStr &) -{} - -void -ResolverBase::visit (AST::MetaListPaths &) -{} - -void -ResolverBase::visit (AST::MetaListNameValueStr &) -{} - -void -ResolverBase::visit (AST::LiteralPattern &) -{} - -void -ResolverBase::visit (AST::IdentifierPattern &) -{} - -void -ResolverBase::visit (AST::WildcardPattern &) -{} - -void -ResolverBase::visit (AST::RestPattern &) -{} - -void -ResolverBase::visit (AST::RangePatternBoundLiteral &) -{} - -void -ResolverBase::visit (AST::RangePatternBoundPath &) -{} - -void -ResolverBase::visit (AST::RangePatternBoundQualPath &) -{} - -void -ResolverBase::visit (AST::RangePattern &) -{} - -void -ResolverBase::visit (AST::ReferencePattern &) -{} - -void -ResolverBase::visit (AST::StructPatternFieldTuplePat &) -{} - -void -ResolverBase::visit (AST::StructPatternFieldIdentPat &) -{} - -void -ResolverBase::visit (AST::StructPatternFieldIdent &) -{} - -void -ResolverBase::visit (AST::StructPattern &) -{} - -void -ResolverBase::visit (AST::TupleStructItemsNoRange &) -{} - -void -ResolverBase::visit (AST::TupleStructItemsRange &) -{} - -void -ResolverBase::visit (AST::TupleStructPattern &) -{} - -void -ResolverBase::visit (AST::TuplePatternItemsMultiple &) -{} - -void -ResolverBase::visit (AST::TuplePatternItemsRanged &) -{} - -void -ResolverBase::visit (AST::TuplePattern &) -{} - -void -ResolverBase::visit (AST::GroupedPattern &) -{} - -void -ResolverBase::visit (AST::SlicePatternItemsNoRest &) -{} - -void -ResolverBase::visit (AST::SlicePatternItemsHasRest &) -{} - -void -ResolverBase::visit (AST::SlicePattern &) -{} - -void -ResolverBase::visit (AST::AltPattern &) -{} - -void -ResolverBase::visit (AST::EmptyStmt &) -{} - -void -ResolverBase::visit (AST::LetStmt &) -{} - -void -ResolverBase::visit (AST::ExprStmt &) -{} - -void -ResolverBase::visit (AST::TraitBound &) -{} - -void -ResolverBase::visit (AST::ImplTraitType &) -{} - -void -ResolverBase::visit (AST::TraitObjectType &) -{} - -void -ResolverBase::visit (AST::ParenthesisedType &) -{} - -void -ResolverBase::visit (AST::ImplTraitTypeOneBound &) -{} - -void -ResolverBase::visit (AST::TraitObjectTypeOneBound &) -{} - -void -ResolverBase::visit (AST::TupleType &) -{} - -void -ResolverBase::visit (AST::NeverType &) -{} - -void -ResolverBase::visit (AST::RawPointerType &) -{} - -void -ResolverBase::visit (AST::ReferenceType &) -{} - -void -ResolverBase::visit (AST::ArrayType &) -{} - -void -ResolverBase::visit (AST::SliceType &) -{} - -void -ResolverBase::visit (AST::InferredType &) -{} - -void -ResolverBase::visit (AST::BareFunctionType &) -{} - -void -ResolverBase::visit (AST::SelfParam &) -{} - -void -ResolverBase::visit (AST::VariadicParam &) -{} - -void -ResolverBase::visit (AST::FunctionParam &) -{} - -void -ResolverBase::visit (AST::FormatArgs &fmt) -{} - -void -ResolverBase::visit (AST::OffsetOf &offset_of) -{} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h deleted file mode 100644 index 89c5c35192e3..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_BASE_H -#define RUST_AST_RESOLVE_BASE_H - -#include "rust-ast-visitor.h" -#include "rust-ast.h" -#include "rust-builtin-ast-nodes.h" -#include "rust-expr.h" -#include "rust-name-resolver.h" -#include "rust-diagnostics.h" -#include "rust-location.h" - -namespace Rust { -namespace Resolver { -inline void -redefined_error (const rich_location &loc) -{ - rust_error_at (loc, "redefined multiple times"); -} - -class ResolverBase : public AST::ASTVisitor -{ -public: - virtual ~ResolverBase () {} - - void visit (AST::Token &); - void visit (AST::DelimTokenTree &); - void visit (AST::AttrInputMetaItemContainer &); - void visit (AST::IdentifierExpr &); - void visit (AST::Lifetime &); - void visit (AST::LifetimeParam &); - void visit (AST::ConstGenericParam &); - void visit (AST::PathInExpression &); - void visit (AST::TypePathSegment &); - void visit (AST::TypePathSegmentGeneric &); - void visit (AST::TypePathSegmentFunction &); - void visit (AST::TypePath &); - void visit (AST::QualifiedPathInExpression &); - void visit (AST::QualifiedPathInType &); - void visit (AST::LiteralExpr &); - void visit (AST::AttrInputLiteral &); - void visit (AST::AttrInputMacro &); - void visit (AST::MetaItemLitExpr &); - void visit (AST::MetaItemPathExpr &); - void visit (AST::BorrowExpr &); - void visit (AST::DereferenceExpr &); - void visit (AST::ErrorPropagationExpr &); - void visit (AST::NegationExpr &); - void visit (AST::ArithmeticOrLogicalExpr &); - void visit (AST::ComparisonExpr &); - void visit (AST::LazyBooleanExpr &); - void visit (AST::TypeCastExpr &); - void visit (AST::AssignmentExpr &); - void visit (AST::CompoundAssignmentExpr &); - void visit (AST::GroupedExpr &); - void visit (AST::ArrayElemsValues &); - void visit (AST::ArrayElemsCopied &); - void visit (AST::ArrayExpr &); - void visit (AST::ArrayIndexExpr &); - void visit (AST::TupleExpr &); - void visit (AST::TupleIndexExpr &); - void visit (AST::StructExprStruct &); - void visit (AST::StructExprFieldIdentifier &); - void visit (AST::StructExprFieldIdentifierValue &); - void visit (AST::StructExprFieldIndexValue &); - void visit (AST::StructExprStructFields &); - void visit (AST::StructExprStructBase &); - void visit (AST::CallExpr &); - void visit (AST::MethodCallExpr &); - void visit (AST::FieldAccessExpr &); - void visit (AST::ClosureExprInner &); - void visit (AST::BlockExpr &); - void visit (AST::AnonConst &); - void visit (AST::ConstBlock &); - void visit (AST::ClosureExprInnerTyped &); - void visit (AST::ContinueExpr &); - void visit (AST::BreakExpr &); - void visit (AST::RangeFromToExpr &); - void visit (AST::RangeFromExpr &); - void visit (AST::RangeToExpr &); - void visit (AST::RangeFullExpr &); - void visit (AST::RangeFromToInclExpr &); - void visit (AST::RangeToInclExpr &); - void visit (AST::BoxExpr &); - void visit (AST::ReturnExpr &); - void visit (AST::TryExpr &); - void visit (AST::UnsafeBlockExpr &); - void visit (AST::LoopExpr &); - void visit (AST::WhileLoopExpr &); - void visit (AST::WhileLetLoopExpr &); - void visit (AST::ForLoopExpr &); - void visit (AST::IfExpr &); - void visit (AST::IfExprConseqElse &); - void visit (AST::IfLetExpr &); - void visit (AST::IfLetExprConseqElse &); - - void visit (AST::MatchExpr &); - void visit (AST::AwaitExpr &); - void visit (AST::AsyncBlockExpr &); - void visit (AST::InlineAsm &); - void visit (AST::LlvmInlineAsm &); - - void visit (AST::TypeParam &); - - void visit (AST::LifetimeWhereClauseItem &); - void visit (AST::TypeBoundWhereClauseItem &); - void visit (AST::Module &); - void visit (AST::ExternCrate &); - - void visit (AST::UseTreeGlob &); - void visit (AST::UseTreeList &); - void visit (AST::UseTreeRebind &); - void visit (AST::UseDeclaration &); - void visit (AST::Function &); - void visit (AST::TypeAlias &); - void visit (AST::StructStruct &); - void visit (AST::TupleStruct &); - void visit (AST::EnumItem &); - void visit (AST::EnumItemTuple &); - void visit (AST::EnumItemStruct &); - void visit (AST::EnumItemDiscriminant &); - void visit (AST::Enum &); - void visit (AST::Union &); - void visit (AST::ConstantItem &); - void visit (AST::StaticItem &); - void visit (AST::TraitItemConst &); - void visit (AST::TraitItemType &); - void visit (AST::Trait &); - void visit (AST::InherentImpl &); - void visit (AST::TraitImpl &); - - void visit (AST::ExternalTypeItem &); - void visit (AST::ExternalStaticItem &); - void visit (AST::ExternBlock &); - - void visit (AST::MacroMatchFragment &); - void visit (AST::MacroMatchRepetition &); - void visit (AST::MacroMatcher &); - void visit (AST::MacroRulesDefinition &); - void visit (AST::MacroInvocation &); - void visit (AST::MetaItemPath &); - void visit (AST::MetaItemSeq &); - void visit (AST::MetaWord &); - void visit (AST::MetaNameValueStr &); - void visit (AST::MetaListPaths &); - void visit (AST::MetaListNameValueStr &); - - void visit (AST::LiteralPattern &); - void visit (AST::IdentifierPattern &); - void visit (AST::WildcardPattern &); - void visit (AST::RestPattern &); - - void visit (AST::RangePatternBoundLiteral &); - void visit (AST::RangePatternBoundPath &); - void visit (AST::RangePatternBoundQualPath &); - void visit (AST::RangePattern &); - void visit (AST::ReferencePattern &); - - void visit (AST::StructPatternFieldTuplePat &); - void visit (AST::StructPatternFieldIdentPat &); - void visit (AST::StructPatternFieldIdent &); - void visit (AST::StructPattern &); - - void visit (AST::TupleStructItemsNoRange &); - void visit (AST::TupleStructItemsRange &); - void visit (AST::TupleStructPattern &); - - void visit (AST::TuplePatternItemsMultiple &); - void visit (AST::TuplePatternItemsRanged &); - void visit (AST::TuplePattern &); - void visit (AST::GroupedPattern &); - void visit (AST::SlicePatternItemsNoRest &); - void visit (AST::SlicePatternItemsHasRest &); - void visit (AST::SlicePattern &); - void visit (AST::AltPattern &); - - void visit (AST::EmptyStmt &); - void visit (AST::LetStmt &); - void visit (AST::ExprStmt &); - - void visit (AST::TraitBound &); - void visit (AST::ImplTraitType &); - void visit (AST::TraitObjectType &); - void visit (AST::ParenthesisedType &); - void visit (AST::ImplTraitTypeOneBound &); - void visit (AST::TraitObjectTypeOneBound &); - void visit (AST::TupleType &); - void visit (AST::NeverType &); - void visit (AST::RawPointerType &); - void visit (AST::ReferenceType &); - void visit (AST::ArrayType &); - void visit (AST::SliceType &); - void visit (AST::InferredType &); - void visit (AST::BareFunctionType &); - void visit (AST::FunctionParam ¶m); - void visit (AST::VariadicParam ¶m); - void visit (AST::SelfParam ¶m); - - void visit (AST::FormatArgs &fmt); - void visit (AST::OffsetOf &offset_of); - -protected: - ResolverBase () - : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()), - resolved_node (UNKNOWN_NODEID) - {} - - /** - * Resolve a visibility's path through the name resolver - */ - bool resolve_visibility (const AST::Visibility &vis); - - Resolver *resolver; - Analysis::Mappings &mappings; - NodeId resolved_node; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_BASE_H diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc deleted file mode 100644 index a41019371cb3..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ /dev/null @@ -1,816 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-expr.h" -#include "rust-ast-resolve-stmt.h" -#include "rust-ast-resolve-struct-expr-field.h" -#include "rust-ast-resolve-type.h" -#include "rust-ast-resolve-pattern.h" -#include "rust-ast-resolve-path.h" -#include "rust-expr.h" -#include "rust-ice-finalizer.h" - -namespace Rust { -namespace Resolver { - -void -ResolveExpr::go (AST::Expr &expr, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, bool funny_error) -{ - ResolveExpr resolver (prefix, canonical_prefix, funny_error); - expr.accept_vis (resolver); -} - -void -ResolveExpr::visit (AST::TupleIndexExpr &expr) -{ - ResolveExpr::go (expr.get_tuple_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::TupleExpr &expr) -{ - if (expr.is_unit ()) - return; - - for (auto &elem : expr.get_tuple_elems ()) - ResolveExpr::go (*elem, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::PathInExpression &expr) -{ - ResolvePath::go (expr); -} - -void -ResolveExpr::visit (AST::QualifiedPathInExpression &expr) -{ - ResolvePath::go (expr); -} - -void -ResolveExpr::visit (AST::ReturnExpr &expr) -{ - if (expr.has_returned_expr ()) - ResolveExpr::go (expr.get_returned_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::CallExpr &expr) -{ - ResolveExpr::go (expr.get_function_expr (), prefix, canonical_prefix); - for (auto ¶m : expr.get_params ()) - ResolveExpr::go (*param, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::MethodCallExpr &expr) -{ - ResolveExpr::go (expr.get_receiver_expr (), prefix, canonical_prefix); - - if (expr.get_method_name ().has_generic_args ()) - { - AST::GenericArgs &args = expr.get_method_name ().get_generic_args (); - ResolveGenericArgs::go (args, prefix, canonical_prefix); - } - - auto const &in_params = expr.get_params (); - for (auto ¶m : in_params) - ResolveExpr::go (*param, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ErrorPropagationExpr &expr) -{ - ResolveExpr::go (expr.get_propagating_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::AssignmentExpr &expr) -{ - ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IdentifierExpr &expr) -{ - if (resolver->get_name_scope ().lookup ( - CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()), - &resolved_node)) - { - resolver->insert_resolved_name (expr.get_node_id (), resolved_node); - } - 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); - } - else if (funny_error) - { - /* This was a "break rust" or "break gcc", and the identifier failed to - resolve. Emit a funny ICE. We set the finalizer to our custom one, - and use the lower-level emit_diagnostic () instead of the more common - internal_error_no_backtrace () in order to pass our locus. */ - diagnostics::text_finalizer (global_dc) = funny_ice_text_finalizer; - emit_diagnostic (diagnostics::kind::ice_nobt, expr.get_locus (), -1, - "are you trying to break %s? how dare you?", - expr.as_string ().c_str ()); - } - else - { - rust_error_at (expr.get_locus (), ErrorCode::E0425, - "cannot find value %qs in this scope", - expr.as_string ().c_str ()); - } -} - -void -ResolveExpr::visit (AST::ArithmeticOrLogicalExpr &expr) -{ - ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::CompoundAssignmentExpr &expr) -{ - ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ComparisonExpr &expr) -{ - ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::LazyBooleanExpr &expr) -{ - ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::NegationExpr &expr) -{ - ResolveExpr::go (expr.get_negated_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::TypeCastExpr &expr) -{ - ResolveType::go (expr.get_type_to_cast_to ()); - ResolveExpr::go (expr.get_casted_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfExpr &expr) -{ - ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfExprConseqElse &expr) -{ - ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_else_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfLetExpr &expr) -{ - ResolveExpr::go (expr.get_value_expr (), prefix, canonical_prefix); - - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // We know expr.get_patterns () has one pattern at most - // so there's no reason to handle it like an AltPattern. - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - for (auto &pattern : expr.get_patterns ()) - { - PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings); - } - - ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::visit (AST::IfLetExprConseqElse &expr) -{ - ResolveExpr::go (expr.get_value_expr (), prefix, canonical_prefix); - - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // We know expr.get_patterns () has one pattern at most - // so there's no reason to handle it like an AltPattern. - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - for (auto &pattern : expr.get_patterns ()) - { - PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings); - } - - ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_else_block (), prefix, canonical_prefix); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::visit (AST::BlockExpr &expr) -{ - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - if (expr.has_label ()) - { - auto label = expr.get_label (); - if (label.get_lifetime ().get_lifetime_type () - != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - auto label_name = label.get_lifetime ().get_lifetime_name (); - auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); - resolver->get_label_scope ().insert ( - CanonicalPath::new_seg (label.get_node_id (), label_name), - label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rust_error_at (label.get_locus (), "label defined multiple times"); - rust_error_at (locus, "was defined here"); - }); - } - - for (auto &s : expr.get_statements ()) - { - if (s->is_item ()) - ResolveStmt::go (*s, prefix, canonical_prefix, - CanonicalPath::create_empty ()); - } - - for (auto &s : expr.get_statements ()) - { - if (!s->is_item ()) - ResolveStmt::go (*s, prefix, canonical_prefix, - CanonicalPath::create_empty ()); - } - - if (expr.has_tail_expr ()) - ResolveExpr::go (expr.get_tail_expr (), prefix, canonical_prefix); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::visit (AST::AnonConst &expr) -{ - ResolveExpr::go (expr.get_inner_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ConstBlock &expr) -{ - ResolveExpr::go (expr.get_const_expr (), prefix, canonical_prefix); -} - -void -translate_operand (AST::InlineAsm &expr, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - const auto &operands = expr.get_operands (); - using RegisterType = AST::InlineAsmOperand::RegisterType; - for (auto &operand : operands) - { - switch (operand.get_register_type ()) - { - case RegisterType::In: - { - auto in = operand.get_in (); - ResolveExpr::go (*in.expr, prefix, canonical_prefix); - break; - } - case RegisterType::Out: - { - auto out = operand.get_out (); - ResolveExpr::go (*out.expr, prefix, canonical_prefix); - break; - } - case RegisterType::InOut: - { - auto in_out = operand.get_in_out (); - ResolveExpr::go (*in_out.expr, prefix, canonical_prefix); - break; - } - case RegisterType::SplitInOut: - { - auto split_in_out = operand.get_split_in_out (); - ResolveExpr::go (*split_in_out.in_expr, prefix, canonical_prefix); - ResolveExpr::go (*split_in_out.out_expr, prefix, canonical_prefix); - break; - } - case RegisterType::Const: - { - auto anon_const = operand.get_const ().anon_const; - ResolveExpr::go (anon_const.get_inner_expr (), prefix, - canonical_prefix); - break; - } - case RegisterType::Sym: - { - auto sym = operand.get_sym (); - ResolveExpr::go (*sym.expr, prefix, canonical_prefix); - break; - } - case RegisterType::Label: - { - auto label = operand.get_label (); - ResolveExpr::go (*label.expr, prefix, canonical_prefix); - break; - } - } - } -} -void -ResolveExpr::visit (AST::InlineAsm &expr) -{ - translate_operand (expr, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::LlvmInlineAsm &expr) -{ - for (auto &output : expr.get_outputs ()) - ResolveExpr::go (*output.expr, prefix, canonical_prefix); - - for (auto &input : expr.get_inputs ()) - ResolveExpr::go (*input.expr, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::UnsafeBlockExpr &expr) -{ - expr.get_block_expr ().accept_vis (*this); -} - -void -ResolveExpr::visit (AST::ArrayElemsValues &elems) -{ - for (auto &elem : elems.get_values ()) - ResolveExpr::go (*elem, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ArrayExpr &expr) -{ - expr.get_array_elems ()->accept_vis (*this); -} - -void -ResolveExpr::visit (AST::ArrayIndexExpr &expr) -{ - ResolveExpr::go (expr.get_array_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_index_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ArrayElemsCopied &expr) -{ - ResolveExpr::go (expr.get_num_copies (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_elem_to_copy (), prefix, canonical_prefix); -} - -// this this an empty struct constructor like 'S {}' -void -ResolveExpr::visit (AST::StructExprStruct &struct_expr) -{ - ResolveExpr::go (struct_expr.get_struct_name (), prefix, canonical_prefix); -} - -// this this a struct constructor with fields -void -ResolveExpr::visit (AST::StructExprStructFields &struct_expr) -{ - ResolveExpr::go (struct_expr.get_struct_name (), prefix, canonical_prefix); - - if (struct_expr.has_struct_base ()) - { - AST::StructBase &base = struct_expr.get_struct_base (); - ResolveExpr::go (base.get_base_struct (), prefix, canonical_prefix); - } - - auto const &struct_fields = struct_expr.get_fields (); - for (auto &struct_field : struct_fields) - { - ResolveStructExprField::go (*struct_field, prefix, canonical_prefix); - } -} - -void -ResolveExpr::visit (AST::GroupedExpr &expr) -{ - ResolveExpr::go (expr.get_expr_in_parens (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::FieldAccessExpr &expr) -{ - ResolveExpr::go (expr.get_receiver_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::LoopExpr &expr) -{ - if (expr.has_loop_label ()) - { - auto label = expr.get_loop_label (); - if (label.get_lifetime ().get_lifetime_type () - != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - auto label_name = label.get_lifetime ().get_lifetime_name (); - auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); - resolver->get_label_scope ().insert ( - CanonicalPath::new_seg (expr.get_node_id (), label_name), - label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rust_error_at (label.get_locus (), "label defined multiple times"); - rust_error_at (locus, "was defined here"); - }); - } - ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::BreakExpr &expr) -{ - if (expr.has_label ()) - { - auto label = expr.get_label_unchecked ().get_lifetime (); - if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - NodeId resolved_node = UNKNOWN_NODEID; - if (!resolver->get_label_scope ().lookup ( - CanonicalPath::new_seg (label.get_node_id (), - label.get_lifetime_name ()), - &resolved_node)) - { - rust_error_at (label.get_locus (), ErrorCode::E0426, - "use of undeclared label %qs", - label.as_string ().c_str ()); - return; - } - resolver->insert_resolved_label (label.get_node_id (), resolved_node); - } - - if (expr.has_break_expr ()) - { - bool funny_error = false; - auto &break_expr = expr.get_break_expr (); - if (break_expr.get_expr_kind () == AST::Expr::Kind::Identifier) - { - /* This is a break with an expression, and the expression is - just a single identifier. See if the identifier is either - "rust" or "gcc", in which case we have "break rust" or "break - gcc", and so may need to emit our funny error. We cannot yet - emit the error here though, because the identifier may still - be in scope, and ICE'ing on valid programs would not be very - funny. */ - std::string ident - = static_cast (break_expr).as_string (); - if (ident == "rust" || ident == "gcc") - funny_error = true; - } - ResolveExpr::go (break_expr, prefix, canonical_prefix, funny_error); - } -} - -void -ResolveExpr::visit (AST::WhileLoopExpr &expr) -{ - if (expr.has_loop_label ()) - { - auto label = expr.get_loop_label (); - if (label.get_lifetime ().get_lifetime_type () - != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - auto label_name = label.get_lifetime ().get_lifetime_name (); - auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); - resolver->get_label_scope ().insert ( - CanonicalPath::new_seg (label.get_node_id (), label_name), - label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rust_error_at (label.get_locus (), "label defined multiple times"); - rust_error_at (locus, "was defined here"); - }); - } - - ResolveExpr::go (expr.get_predicate_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ForLoopExpr &expr) -{ - if (expr.has_loop_label ()) - { - auto label = expr.get_loop_label (); - if (label.get_lifetime ().get_lifetime_type () - != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - auto label_name = label.get_lifetime ().get_lifetime_name (); - auto label_lifetime_node_id = label.get_lifetime ().get_node_id (); - resolver->get_label_scope ().insert ( - CanonicalPath::new_seg (label.get_node_id (), label_name), - label_lifetime_node_id, label.get_locus (), false, Rib::ItemType::Label, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rust_error_at (label.get_locus (), "label defined multiple times"); - rust_error_at (locus, "was defined here"); - }); - } - - // this needs a new rib to contain the pattern - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // resolve the expression - PatternDeclaration::go (expr.get_pattern (), Rib::ItemType::Var); - ResolveExpr::go (expr.get_iterator_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_loop_block (), prefix, canonical_prefix); - - // done - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::visit (AST::ContinueExpr &expr) -{ - if (expr.has_label ()) - { - auto label = expr.get_label_unchecked (); - if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) - { - rust_error_at (label.get_locus (), - "Labels must be a named lifetime value"); - return; - } - - NodeId resolved_node = UNKNOWN_NODEID; - if (!resolver->get_label_scope ().lookup ( - CanonicalPath::new_seg (label.get_node_id (), - label.get_lifetime_name ()), - &resolved_node)) - { - rust_error_at (expr.get_label_unchecked ().get_locus (), - ErrorCode::E0426, "use of undeclared label %qs", - label.as_string ().c_str ()); - return; - } - resolver->insert_resolved_label (label.get_node_id (), resolved_node); - } -} - -void -ResolveExpr::visit (AST::BorrowExpr &expr) -{ - ResolveExpr::go (expr.get_borrowed_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::DereferenceExpr &expr) -{ - ResolveExpr::go (expr.get_dereferenced_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::MatchExpr &expr) -{ - ResolveExpr::go (expr.get_scrutinee_expr (), prefix, canonical_prefix); - for (auto &match_case : expr.get_match_cases ()) - { - // each arm is in its own scope - NodeId scope_node_id = match_case.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // resolve - AST::MatchArm &arm = match_case.get_arm (); - if (arm.has_match_arm_guard ()) - ResolveExpr::go (arm.get_guard_expr (), prefix, canonical_prefix); - - // We know expr.get_patterns () has one pattern at most - // so there's no reason to handle it like an AltPattern. - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - // insert any possible new patterns - for (auto &pattern : arm.get_patterns ()) - { - PatternDeclaration::go (*pattern, Rib::ItemType::Var, bindings); - } - - // resolve the body - ResolveExpr::go (match_case.get_expr (), prefix, canonical_prefix); - - // done - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - } -} - -void -ResolveExpr::visit (AST::RangeFromToExpr &expr) -{ - ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::RangeFromExpr &expr) -{ - ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::RangeToExpr &expr) -{ - ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::RangeFullExpr &) -{ - // nothing to do -} - -void -ResolveExpr::visit (AST::RangeFromToInclExpr &expr) -{ - ResolveExpr::go (expr.get_from_expr (), prefix, canonical_prefix); - ResolveExpr::go (expr.get_to_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ClosureExprInner &expr) -{ - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - for (auto &p : expr.get_params ()) - { - resolve_closure_param (p, bindings); - } - - resolver->push_closure_context (expr.get_node_id ()); - - ResolveExpr::go (expr.get_definition_expr (), prefix, canonical_prefix); - - resolver->pop_closure_context (); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::visit (AST::ClosureExprInnerTyped &expr) -{ - NodeId scope_node_id = expr.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - for (auto &p : expr.get_params ()) - { - resolve_closure_param (p, bindings); - } - - ResolveType::go (expr.get_return_type ()); - - resolver->push_closure_context (expr.get_node_id ()); - - ResolveExpr::go (expr.get_definition_expr (), prefix, canonical_prefix); - - resolver->pop_closure_context (); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExpr::resolve_closure_param (AST::ClosureParam ¶m, - std::vector &bindings) -{ - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, bindings); - - if (param.has_type_given ()) - ResolveType::go (param.get_type ()); -} - -ResolveExpr::ResolveExpr (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, - bool funny_error) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix), - funny_error (funny_error) -{} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.h b/gcc/rust/resolve/rust-ast-resolve-expr.h deleted file mode 100644 index aad160504174..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-expr.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_EXPR_H -#define RUST_AST_RESOLVE_EXPR_H - -#include "rust-ast-resolve-base.h" -#include "rust-ast.h" -#include "rust-ast-resolve-pattern.h" -#include "rust-expr.h" - -namespace Rust { -namespace Resolver { - -class ResolveExpr : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::Expr &expr, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, - bool funny_error = false); - - void visit (AST::TupleIndexExpr &expr) override; - void visit (AST::TupleExpr &expr) override; - void visit (AST::PathInExpression &expr) override; - void visit (AST::QualifiedPathInExpression &expr) override; - void visit (AST::ReturnExpr &expr) override; - void visit (AST::CallExpr &expr) override; - void visit (AST::MethodCallExpr &expr) override; - void visit (AST::AssignmentExpr &expr) override; - void visit (AST::IdentifierExpr &expr) override; - void visit (AST::ArithmeticOrLogicalExpr &expr) override; - void visit (AST::CompoundAssignmentExpr &expr) override; - void visit (AST::ComparisonExpr &expr) override; - void visit (AST::LazyBooleanExpr &expr) override; - void visit (AST::NegationExpr &expr) override; - void visit (AST::TypeCastExpr &expr) override; - void visit (AST::IfExpr &expr) override; - void visit (AST::IfExprConseqElse &expr) override; - void visit (AST::IfLetExpr &expr) override; - void visit (AST::IfLetExprConseqElse &expr) override; - void visit (AST::BlockExpr &expr) override; - void visit (AST::AnonConst &expr) override; - void visit (AST::ConstBlock &expr) override; - void visit (AST::InlineAsm &expr) override; - void visit (AST::LlvmInlineAsm &expr) override; - void visit (AST::UnsafeBlockExpr &expr) override; - void visit (AST::ArrayElemsValues &elems) override; - void visit (AST::ArrayExpr &expr) override; - void visit (AST::ArrayIndexExpr &expr) override; - void visit (AST::ArrayElemsCopied &elems) override; - void visit (AST::StructExprStruct &struct_expr) override; - void visit (AST::StructExprStructFields &struct_expr) override; - void visit (AST::GroupedExpr &expr) override; - void visit (AST::FieldAccessExpr &expr) override; - void visit (AST::LoopExpr &expr) override; - void visit (AST::BreakExpr &expr) override; - void visit (AST::WhileLoopExpr &expr) override; - void visit (AST::ForLoopExpr &expr) override; - void visit (AST::ContinueExpr &expr) override; - void visit (AST::BorrowExpr &expr) override; - void visit (AST::DereferenceExpr &expr) override; - void visit (AST::MatchExpr &expr) override; - void visit (AST::RangeFromToExpr &expr) override; - void visit (AST::RangeFromExpr &expr) override; - void visit (AST::RangeToExpr &expr) override; - void visit (AST::RangeFullExpr &expr) override; - void visit (AST::RangeFromToInclExpr &expr) override; - void visit (AST::ClosureExprInner &expr) override; - void visit (AST::ClosureExprInnerTyped &expr) override; - void visit (AST::ErrorPropagationExpr &expr) override; - -protected: - void resolve_closure_param (AST::ClosureParam ¶m, - std::vector &bindings); - -private: - ResolveExpr (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, bool funny_error); - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; - bool funny_error; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_EXPR_H diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc deleted file mode 100644 index 99534d50ebcc..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-item.cc +++ /dev/null @@ -1,1246 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-item.h" -#include "rust-ast-full-decls.h" -#include "rust-ast-resolve-toplevel.h" -#include "rust-ast-resolve-type.h" -#include "rust-ast-resolve-pattern.h" -#include "rust-ast-resolve-path.h" - -#include "rust-item.h" -#include "selftest.h" - -namespace Rust { -namespace Resolver { - -ResolveTraitItems::ResolveTraitItems (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) -{} - -void -ResolveTraitItems::go (AST::AssociatedItem *item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - if (item->is_marked_for_strip ()) - return; - - ResolveTraitItems resolver (prefix, canonical_prefix); - item->accept_vis (resolver); -} - -void -ResolveTraitItems::visit (AST::Function &function) -{ - auto decl - = CanonicalPath::new_seg (function.get_node_id (), - function.get_function_name ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (function.get_node_id (), cpath); - - NodeId scope_node_id = function.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - if (function.has_generics ()) - ResolveGenericParams::go (function.get_generic_params (), prefix, - canonical_prefix); - - if (function.has_return_type ()) - ResolveType::go (function.get_return_type ()); - - // self turns into (self: Self) as a function param - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - // we make a new scope so the names of parameters are resolved and shadowed - // correctly - for (auto &p : function.get_function_params ()) - { - if (p->is_variadic ()) - { - auto param = static_cast (*p); - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - else if (p->is_self ()) - { - auto ¶m = static_cast (*p); - // FIXME: which location should be used for Rust::Identifier `self`? - AST::IdentifierPattern self_pattern ( - param.get_node_id (), {"self"}, param.get_locus (), - param.get_has_ref (), param.get_is_mut (), - std::unique_ptr (nullptr)); - - PatternDeclaration::go (self_pattern, Rib::ItemType::Param); - - if (param.has_type ()) - { - // This shouldn't happen the parser should already error for this - rust_assert (!param.get_has_ref ()); - ResolveType::go (param.get_type ()); - } - else - { - // here we implicitly make self have a type path of Self - std::vector> segments; - segments.emplace_back ( - new AST::TypePathSegment ("Self", false, param.get_locus ())); - - AST::TypePath self_type_path (std::move (segments), - param.get_locus ()); - ResolveType::go (self_type_path); - } - } - else - { - auto ¶m = static_cast (*p); - ResolveType::go (param.get_type ()); - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - } - - if (function.has_where_clause ()) - ResolveWhereClause::Resolve (function.get_where_clause ()); - - // trait items have an optional body - if (function.has_body ()) - ResolveExpr::go (*function.get_definition ().value (), path, cpath); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} -void -ResolveTraitItems::visit (AST::TraitItemType &type) -{ - auto decl = CanonicalPath::new_seg (type.get_node_id (), - type.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (type.get_node_id (), cpath); - - for (auto &bound : type.get_type_param_bounds ()) - ResolveTypeBound::go (*bound); -} - -void -ResolveTraitItems::visit (AST::TraitItemConst &constant) -{ - auto decl = CanonicalPath::new_seg (constant.get_node_id (), - constant.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (constant.get_node_id (), cpath); - - ResolveType::go (constant.get_type ()); - - if (constant.has_expr ()) - ResolveExpr::go (constant.get_expr (), path, cpath); -} - -ResolveItem::ResolveItem (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) -{} - -void -ResolveItem::go (AST::Item &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - ResolveItem resolver (prefix, canonical_prefix); - item.accept_vis (resolver); -} - -void -ResolveItem::visit (AST::TypeAlias &alias) -{ - auto talias - = CanonicalPath::new_seg (alias.get_node_id (), - alias.get_new_type_name ().as_string ()); - auto path = prefix.append (talias); - auto cpath = canonical_prefix.append (talias); - mappings.insert_canonical_path (alias.get_node_id (), cpath); - - NodeId scope_node_id = alias.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (alias.has_generics ()) - ResolveGenericParams::go (alias.get_generic_params (), prefix, - canonical_prefix); - - if (alias.has_where_clause ()) - ResolveWhereClause::Resolve (alias.get_where_clause ()); - - ResolveType::go (alias.get_type_aliased ()); - - resolver->get_type_scope ().pop (); -} - -void -ResolveItem::visit (AST::Module &module) -{ - auto mod = CanonicalPath::new_seg (module.get_node_id (), - module.get_name ().as_string ()); - auto path = prefix.append (mod); - auto cpath = canonical_prefix.append (mod); - mappings.insert_canonical_path (module.get_node_id (), cpath); - - resolve_visibility (module.get_visibility ()); - - NodeId scope_node_id = module.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // FIXME: Should we reinsert a child here? Any reason we ResolveTopLevel::go - // in ResolveTopLevel::visit (AST::Module) as well as here? - for (auto &item : module.get_items ()) - ResolveTopLevel::go (*item, CanonicalPath::create_empty (), cpath); - - resolver->push_new_module_scope (module.get_node_id ()); - for (auto &item : module.get_items ()) - ResolveItem::go (*item, path, cpath); - - resolver->pop_module_scope (); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveItem::visit (AST::TupleStruct &struct_decl) -{ - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - - resolve_visibility (struct_decl.get_visibility ()); - - NodeId scope_node_id = struct_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (struct_decl.has_generics ()) - ResolveGenericParams::go (struct_decl.get_generic_params (), prefix, - canonical_prefix); - - if (struct_decl.has_where_clause ()) - ResolveWhereClause::Resolve (struct_decl.get_where_clause ()); - - for (AST::TupleField &field : struct_decl.get_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - resolve_visibility (field.get_visibility ()); - - ResolveType::go (field.get_field_type ()); - } - - resolver->get_type_scope ().pop (); -} - -void -ResolveItem::visit (AST::Enum &enum_decl) -{ - auto decl = CanonicalPath::new_seg (enum_decl.get_node_id (), - enum_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (enum_decl.get_node_id (), cpath); - - resolve_visibility (enum_decl.get_visibility ()); - - NodeId scope_node_id = enum_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (enum_decl.has_generics ()) - ResolveGenericParams::go (enum_decl.get_generic_params (), prefix, - canonical_prefix); - - if (enum_decl.has_where_clause ()) - ResolveWhereClause::Resolve (enum_decl.get_where_clause ()); - - /* The actual fields are inside the variants. */ - for (auto &variant : enum_decl.get_variants ()) - ResolveItem::go (*variant, path, cpath); - - resolver->get_type_scope ().pop (); -} - -/* EnumItem doesn't need to be handled, no fields. */ -void -ResolveItem::visit (AST::EnumItem &item) -{ - // Since at this point we cannot have visibilities on enum items anymore, we - // can skip handling them - - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); -} - -void -ResolveItem::visit (AST::EnumItemTuple &item) -{ - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - for (auto &field : item.get_tuple_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } -} - -void -ResolveItem::visit (AST::EnumItemStruct &item) -{ - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - for (auto &field : item.get_struct_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } -} - -void -ResolveItem::visit (AST::EnumItemDiscriminant &item) -{ - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - mappings.insert_canonical_path (item.get_node_id (), cpath); - - ResolveExpr::go (item.get_expr (), path, cpath); -} - -void -ResolveItem::visit (AST::StructStruct &struct_decl) -{ - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - - resolve_visibility (struct_decl.get_visibility ()); - - NodeId scope_node_id = struct_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (struct_decl.has_generics ()) - ResolveGenericParams::go (struct_decl.get_generic_params (), prefix, - canonical_prefix); - - if (struct_decl.has_where_clause ()) - ResolveWhereClause::Resolve (struct_decl.get_where_clause ()); - - for (AST::StructField &field : struct_decl.get_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - resolve_visibility (field.get_visibility ()); - - ResolveType::go (field.get_field_type ()); - } - - resolver->get_type_scope ().pop (); -} - -void -ResolveItem::visit (AST::Union &union_decl) -{ - auto decl - = CanonicalPath::new_seg (union_decl.get_node_id (), - union_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (union_decl.get_node_id (), cpath); - - resolve_visibility (union_decl.get_visibility ()); - - NodeId scope_node_id = union_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (union_decl.has_generics ()) - ResolveGenericParams::go (union_decl.get_generic_params (), prefix, - canonical_prefix); - - if (union_decl.has_where_clause ()) - ResolveWhereClause::Resolve (union_decl.get_where_clause ()); - - for (AST::StructField &field : union_decl.get_variants ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } - - resolver->get_type_scope ().pop (); -} - -void -ResolveItem::visit (AST::StaticItem &var) -{ - auto decl = CanonicalPath::new_seg (var.get_node_id (), - var.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (var.get_node_id (), cpath); - - ResolveType::go (var.get_type ()); - ResolveExpr::go (var.get_expr (), path, cpath); -} - -void -ResolveItem::visit (AST::ConstantItem &constant) -{ - auto decl = CanonicalPath::new_seg (constant.get_node_id (), - constant.get_identifier ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (constant.get_node_id (), cpath); - - resolve_visibility (constant.get_visibility ()); - - ResolveType::go (constant.get_type ()); - if (constant.has_expr ()) - ResolveExpr::go (constant.get_expr (), path, cpath); -} - -void -ResolveItem::visit (AST::Function &function) -{ - auto decl - = CanonicalPath::new_seg (function.get_node_id (), - function.get_function_name ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - mappings.insert_canonical_path (function.get_node_id (), cpath); - - resolve_visibility (function.get_visibility ()); - - NodeId scope_node_id = function.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - if (function.has_generics ()) - ResolveGenericParams::go (function.get_generic_params (), prefix, - canonical_prefix); - - // resolve any where clause items - if (function.has_where_clause ()) - ResolveWhereClause::Resolve (function.get_where_clause ()); - - if (function.has_return_type ()) - ResolveType::go (function.get_return_type ()); - - if (function.has_self_param ()) - { - // self turns into (self: Self) as a function param - AST::Param &s_param = function.get_self_param (); - auto &self_param = static_cast (s_param); - - // FIXME: which location should be used for Rust::Identifier `self`? - AST::IdentifierPattern self_pattern ( - self_param.get_node_id (), {"self"}, self_param.get_locus (), - self_param.get_has_ref (), self_param.get_is_mut (), - std::unique_ptr (nullptr)); - PatternDeclaration::go (self_pattern, Rib::ItemType::Param); - - if (self_param.has_type ()) - { - // This shouldn't happen the parser should already error for this - rust_assert (!self_param.get_has_ref ()); - ResolveType::go (self_param.get_type ()); - } - else - { - // here we implicitly make self have a type path of Self - std::vector> segments; - segments.emplace_back ( - new AST::TypePathSegment ("Self", false, self_param.get_locus ())); - - AST::TypePath self_type_path (std::move (segments), - self_param.get_locus ()); - ResolveType::go (self_type_path); - } - } - - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - // we make a new scope so the names of parameters are resolved and shadowed - // correctly - for (auto &p : function.get_function_params ()) - { - if (p->is_variadic ()) - { - auto ¶m = static_cast (*p); - if (param.has_pattern ()) - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - else if (p->is_self ()) - { - auto ¶m = static_cast (*p); - if (param.has_type ()) - ResolveType::go (param.get_type ()); - } - else - { - auto ¶m = static_cast (*p); - ResolveType::go (param.get_type ()); - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - } - - // resolve the function body - ResolveExpr::go (*function.get_definition ().value (), path, cpath); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveItem::visit (AST::InherentImpl &impl_block) -{ - NodeId scope_node_id = impl_block.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - - resolve_visibility (impl_block.get_visibility ()); - - if (impl_block.has_generics ()) - ResolveGenericParams::go (impl_block.get_generic_params (), prefix, - canonical_prefix); - - // resolve any where clause items - if (impl_block.has_where_clause ()) - ResolveWhereClause::Resolve (impl_block.get_where_clause ()); - - // FIXME this needs to be protected behind nominal type-checks see: - // rustc --explain E0118 - // issue #2634 - ResolveType::go (impl_block.get_type ()); - - // Setup paths - CanonicalPath self_cpath = CanonicalPath::create_empty (); - bool ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (), self_cpath); - if (!ok) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } - - rust_debug ("AST::InherentImpl resolve Self: {%s}", - self_cpath.get ().c_str ()); - - CanonicalPath impl_type = self_cpath; - CanonicalPath impl_type_seg - = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (), impl_type); - CanonicalPath impl_prefix = prefix.append (impl_type_seg); - - // see https://godbolt.org/z/a3vMbsT6W - CanonicalPath cpath = CanonicalPath::create_empty (); - if (canonical_prefix.size () <= 1) - { - cpath = impl_prefix; - } - else - { - cpath = canonical_prefix.append (impl_type_seg); - } - - // done setup paths - - auto Self - = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ()); - - resolver->get_type_scope ().insert (Self, - impl_block.get_type ().get_node_id (), - impl_block.get_type ().get_locus ()); - - for (auto &impl_item : impl_block.get_impl_items ()) - { - rust_debug ( - "AST::InherentImpl resolve_impl_item: impl_prefix={%s} cpath={%s}", - impl_prefix.get ().c_str (), cpath.get ().c_str ()); - resolve_impl_item (*impl_item, impl_prefix, cpath); - } - - resolver->get_type_scope ().peek ()->clear_name ( - Self, impl_block.get_type ().get_node_id ()); - - resolver->get_type_scope ().pop (); - resolver->get_name_scope ().pop (); -} - -void -ResolveItem::visit (AST::TraitImpl &impl_block) -{ - NodeId scope_node_id = impl_block.get_node_id (); - - resolve_visibility (impl_block.get_visibility ()); - - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - if (impl_block.has_generics ()) - ResolveGenericParams::go (impl_block.get_generic_params (), prefix, - canonical_prefix); - - // resolve any where clause items - if (impl_block.has_where_clause ()) - ResolveWhereClause::Resolve (impl_block.get_where_clause ()); - - // CanonicalPath canonical_trait_type = CanonicalPath::create_empty (); - NodeId trait_resolved_node = ResolveType::go (impl_block.get_trait_path ()); - if (trait_resolved_node == UNKNOWN_NODEID) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } - - // CanonicalPath canonical_impl_type = CanonicalPath::create_empty (); - NodeId type_resolved_node = ResolveType::go (impl_block.get_type ()); - if (type_resolved_node == UNKNOWN_NODEID) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } - - bool ok = true; - - // setup paths - CanonicalPath canonical_trait_type = CanonicalPath::create_empty (); - - ok = ResolveTypeToCanonicalPath::go (impl_block.get_trait_path (), - canonical_trait_type); - if (!ok) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } - - rust_debug ("AST::TraitImpl resolve trait type: {%s}", - canonical_trait_type.get ().c_str ()); - - CanonicalPath canonical_impl_type = CanonicalPath::create_empty (); - ok = ResolveTypeToCanonicalPath::go (impl_block.get_type (), - canonical_impl_type); - if (!ok) - { - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - return; - } - - rust_debug ("AST::TraitImpl resolve self: {%s}", - canonical_impl_type.get ().c_str ()); - - // raw paths - CanonicalPath impl_type_seg = canonical_impl_type; - CanonicalPath trait_type_seg = canonical_trait_type; - CanonicalPath projection - = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (), - trait_type_seg, impl_type_seg); - CanonicalPath impl_prefix = prefix.append (projection); - - // setup canonical-path - CanonicalPath canonical_projection - = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (), - canonical_trait_type, - canonical_impl_type); - CanonicalPath cpath = CanonicalPath::create_empty (); - if (canonical_prefix.size () <= 1) - { - cpath = canonical_projection; - } - else - { - cpath = canonical_prefix.append (canonical_projection); - } - - // DONE setup canonical-path - - auto Self - = CanonicalPath::get_big_self (impl_block.get_type ().get_node_id ()); - - resolver->get_type_scope ().insert (Self, - impl_block.get_type ().get_node_id (), - impl_block.get_type ().get_locus ()); - - for (auto &impl_item : impl_block.get_impl_items ()) - { - rust_debug ( - "AST::TraitImpl resolve_impl_item: impl_prefix={%s} cpath={%s}", - impl_prefix.get ().c_str (), cpath.get ().c_str ()); - resolve_impl_item (*impl_item, impl_prefix, cpath); - } - - Rib *r = resolver->get_type_scope ().peek (); - r->clear_name (Self, impl_block.get_type ().get_node_id ()); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveItem::visit (AST::Trait &trait) -{ - NodeId scope_node_id = trait.get_node_id (); - - resolve_visibility (trait.get_visibility ()); - - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - - ResolveGenericParams::go_single (trait.get_implicit_self (), prefix, - canonical_prefix); - ResolveGenericParams::go (trait.get_generic_params (), prefix, - canonical_prefix); - - // Self is an implicit TypeParam so lets mark it as such - resolver->get_type_scope ().append_reference_for_def ( - trait.get_node_id (), trait.get_implicit_self ().get_node_id ()); - - if (trait.has_type_param_bounds ()) - { - for (auto &bound : trait.get_type_param_bounds ()) - { - ResolveTypeBound::go (*bound); - } - } - - // resolve any where clause items - if (trait.has_where_clause ()) - ResolveWhereClause::Resolve (trait.get_where_clause ()); - - // resolve the paths - CanonicalPath path = CanonicalPath::create_empty (); - CanonicalPath cpath = CanonicalPath::create_empty (); - // - - for (auto &item : trait.get_trait_items ()) - { - ResolveTraitItems::go (item.get (), path, cpath); - } - - resolver->get_type_scope ().pop (); - resolver->get_name_scope ().pop (); -} - -void -ResolveItem::visit (AST::ExternBlock &extern_block) -{ - resolve_visibility (extern_block.get_visibility ()); - - for (auto &item : extern_block.get_extern_items ()) - { - resolve_extern_item (*item); - } -} - -void -ResolveItem::resolve_impl_item (AST::AssociatedItem &item, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - ResolveImplItems::go (item, prefix, canonical_prefix); -} - -void -ResolveItem::resolve_extern_item (AST::ExternalItem &item) -{ - ResolveExternItem::go (item, prefix, canonical_prefix); -} - -static void flatten_glob (const AST::UseTreeGlob &glob, - std::vector &imports); -static void flatten_rebind (const AST::UseTreeRebind &glob, - std::vector &imports); -static void flatten_list (const AST::UseTreeList &glob, - std::vector &imports); - -static void -flatten (const AST::UseTree *tree, std::vector &imports) -{ - switch (tree->get_kind ()) - { - case AST::UseTree::Glob: - { - auto glob = static_cast (tree); - flatten_glob (*glob, imports); - break; - } - case AST::UseTree::Rebind: - { - auto rebind = static_cast (tree); - flatten_rebind (*rebind, imports); - break; - } - case AST::UseTree::List: - { - auto list = static_cast (tree); - flatten_list (*list, imports); - break; - } - break; - } -} - -static void -flatten_glob (const AST::UseTreeGlob &glob, std::vector &imports) -{ - if (glob.has_path ()) - imports.emplace_back (glob.get_path (), true, std::string ()); -} - -static void -flatten_rebind (const AST::UseTreeRebind &rebind, std::vector &imports) -{ - auto path = rebind.get_path (); - - std::string label; - if (rebind.has_identifier ()) - label = rebind.get_identifier ().as_string (); - else - label = path.get_final_segment ().as_string (); - - imports.emplace_back (path, false, label); -} - -static void -flatten_list (const AST::UseTreeList &list, std::vector &imports) -{ - auto prefix = AST::SimplePath::create_empty (); - if (list.has_path ()) - prefix = list.get_path (); - - for (const auto &tree : list.get_trees ()) - { - // append imports to the main list, then modify them in-place - auto start_idx = imports.size (); - flatten (tree.get (), imports); - - for (auto import = imports.begin () + start_idx; import != imports.end (); - import++) - { - // avoid duplicate node ids - auto prefix_copy - = AST::SimplePath ({}, prefix.has_opening_scope_resolution (), - prefix.get_locus ()); - for (auto &seg : prefix.get_segments ()) - prefix_copy.get_segments ().emplace_back (seg.get_segment_name (), - seg.get_locus ()); - - import->add_prefix (std::move (prefix_copy)); - } - } -} - -void -Import::add_prefix (AST::SimplePath prefix) -{ - AST::SimplePath old_path (std::move (path)); - path = std::move (prefix); - std::move (old_path.get_segments ().begin (), old_path.get_segments ().end (), - std::back_inserter (path.get_segments ())); -} - -/** - * Flatten a UseDeclaration's UseTree into multiple simple paths to resolve. - * - * Given the following use declarations: - * ``` - * use some::path::to_resolve; #1 - * use some::path::to_glob::*; #2 - * use some::path::{one, two}; #2 - * ``` - * - * In the first case, we simply want to return a vector with a single - * SimplePath: - * [some::path::to_resolve] - * - * In the second case, we want to resolve the glob's "origin path": - * [some::path::to_glob] - * - * Finally in the third case, we want to create two SimplePaths to resolve: - * [some::path::one, some::path::two] - */ -static std::vector -flatten_use_dec_to_imports (const AST::UseDeclaration &use_item) -{ - auto imports = std::vector (); - - const auto &tree = use_item.get_tree (); - flatten (tree.get (), imports); - - return imports; -} - -void -ResolveItem::visit (AST::UseDeclaration &use_item) -{ - std::vector to_resolve = flatten_use_dec_to_imports (use_item); - - // FIXME: I think this does not actually resolve glob use-decls and is going - // the wrong way about it. RFC #1560 specifies the following: - // - // > When we find a glob import, we have to record a 'back link', so that when - // a public name is added for the supplying module, we can add it for the - // importing module. - // - // Which is the opposite of what we're doing if I understand correctly? - - NodeId current_module = resolver->peek_current_module_scope (); - for (auto &import : to_resolve) - { - auto &path = import.get_path (); - - rust_debug ("resolving use-decl path: [%s]", path.as_string ().c_str ()); - NodeId resolved_node_id = ResolvePath::go (path); - bool ok = resolved_node_id != UNKNOWN_NODEID; - if (!ok) - continue; - - if (import.is_glob ()) - continue; - - auto decl = CanonicalPath::new_seg (resolved_node_id, import.get_name ()); - mappings.insert_module_child_item (current_module, decl); - - resolver->get_type_scope ().insert (decl, resolved_node_id, - path.get_locus (), - Rib::ItemType::Type); - rust_debug ("use-decl rexporting: [%s]", decl.get ().c_str ()); - } -} - -ResolveImplItems::ResolveImplItems (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolveItem (prefix, canonical_prefix) -{} - -void -ResolveImplItems::go (AST::AssociatedItem &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - if (item.is_marked_for_strip ()) - return; - - ResolveImplItems resolver (prefix, canonical_prefix); - item.accept_vis (resolver); -} - -void -ResolveImplItems::visit (AST::TypeAlias &alias) -{ - ResolveItem::visit (alias); - - resolve_visibility (alias.get_visibility ()); - - // FIXME this stops the erronious unused decls which will be fixed later on - resolver->get_type_scope ().append_reference_for_def (alias.get_node_id (), - alias.get_node_id ()); -} - -void -ResolveExternItem::go (AST::ExternalItem &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - ResolveExternItem resolver (prefix, canonical_prefix); - item.accept_vis (resolver); -} - -void -ResolveExternItem::visit (AST::Function &function) -{ - NodeId scope_node_id = function.get_node_id (); - auto decl - = CanonicalPath::new_seg (function.get_node_id (), - function.get_function_name ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - mappings.insert_canonical_path (function.get_node_id (), cpath); - - resolve_visibility (function.get_visibility ()); - - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // resolve the generics - if (function.has_generics ()) - ResolveGenericParams::go (function.get_generic_params (), prefix, - canonical_prefix); - - if (function.has_return_type ()) - ResolveType::go (function.get_return_type ()); - - // we make a new scope so the names of parameters are resolved and shadowed - // correctly - for (auto ¶m : function.get_function_params ()) - if (!param->is_variadic ()) - { - auto &p = static_cast (*param); - ResolveType::go (p.get_type ()); - } - - // done - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); -} - -void -ResolveExternItem::visit (AST::ExternalStaticItem &item) -{ - resolve_visibility (item.get_visibility ()); - - ResolveType::go (item.get_type ()); -} - -} // namespace Resolver -} // namespace Rust - -#if CHECKING_P - -namespace selftest { - -static void -rust_flatten_nested_glob (void) -{ - auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION); - auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION); - auto foobar = Rust::AST::SimplePath ({foo, bar}); - - auto glob - = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED, - foobar, UNDEF_LOCATION); - - auto imports = std::vector (); - Rust::Resolver::flatten_glob (glob, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 1); - ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); -} - -static void -rust_flatten_glob (void) -{ - auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION); - - auto glob - = Rust::AST::UseTreeGlob (Rust::AST::UseTreeGlob::PathType::PATH_PREFIXED, - frob, UNDEF_LOCATION); - - auto imports = std::vector (); - Rust::Resolver::flatten_glob (glob, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 1); - ASSERT_EQ (imports[0].get_path (), "frobulator"); -} - -static void -rust_flatten_rebind_none (void) -{ - auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION); - auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION); - auto foobar = Rust::AST::SimplePath ({foo, bar}); - - auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, - foobar, UNDEF_LOCATION); - - auto imports = std::vector (); - Rust::Resolver::flatten_rebind (rebind, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 1); - ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); -} - -static void -rust_flatten_rebind (void) -{ - auto frob = Rust::AST::SimplePath::from_str ("frobulator", UNDEF_LOCATION); - - auto rebind = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER, - frob, UNDEF_LOCATION, {"saindoux"}); - - auto imports = std::vector (); - Rust::Resolver::flatten_rebind (rebind, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 1); - ASSERT_EQ (imports[0].get_path (), "frobulator"); - ASSERT_EQ (imports[0].get_name (), "saindoux"); -} - -static void -rust_flatten_rebind_nested (void) -{ - auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION); - auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION); - auto baz = Rust::AST::SimplePathSegment ("baz", UNDEF_LOCATION); - - auto foo_bar_baz = Rust::AST::SimplePath ({foo, bar, baz}); - - auto rebind - = Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::IDENTIFIER, - foo_bar_baz, UNDEF_LOCATION, {"saindoux"}); - - auto imports = std::vector (); - Rust::Resolver::flatten_rebind (rebind, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 1); - ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz"); - ASSERT_EQ (imports[0].get_name (), "saindoux"); -} - -static void -rust_flatten_list (void) -{ - auto foo = Rust::AST::SimplePathSegment ("foo", UNDEF_LOCATION); - auto bar = Rust::AST::SimplePathSegment ("bar", UNDEF_LOCATION); - auto foo_bar = Rust::AST::SimplePath ({foo, bar}); - - auto baz = Rust::AST::SimplePath::from_str ("baz", UNDEF_LOCATION); - auto bul = Rust::AST::SimplePath::from_str ("bul", UNDEF_LOCATION); - - // use foo::bar::{baz, bul}; - - auto use0 = std::unique_ptr ( - new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz, - UNDEF_LOCATION)); - auto use1 = std::unique_ptr ( - new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul, - UNDEF_LOCATION)); - - auto uses = std::vector> (); - uses.emplace_back (std::move (use0)); - uses.emplace_back (std::move (use1)); - - auto list - = Rust::AST::UseTreeList (Rust::AST::UseTreeList::PATH_PREFIXED, foo_bar, - std::move (uses), UNDEF_LOCATION); - - auto imports = std::vector (); - Rust::Resolver::flatten_list (list, imports); - - ASSERT_TRUE (!imports.empty ()); - ASSERT_EQ (imports.size (), 2); - ASSERT_EQ (imports[0].get_path ().get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (imports[0].get_path ().get_segments ()[2].as_string (), "baz"); - ASSERT_EQ (imports[1].get_path ().get_segments ()[0].as_string (), "foo"); - ASSERT_EQ (imports[1].get_path ().get_segments ()[1].as_string (), "bar"); - ASSERT_EQ (imports[1].get_path ().get_segments ()[2].as_string (), "bul"); -} - -static void -rust_use_dec_flattening (void) -{ - rust_flatten_glob (); - rust_flatten_nested_glob (); - rust_flatten_rebind_none (); - rust_flatten_rebind (); - rust_flatten_rebind_nested (); - rust_flatten_list (); -} - -void -rust_simple_path_resolve_test (void) -{ - rust_use_dec_flattening (); -} - -} // namespace selftest - -#endif // CHECKING_P diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h b/gcc/rust/resolve/rust-ast-resolve-item.h deleted file mode 100644 index d31f910c4b18..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-item.h +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_ITEM_H -#define RUST_AST_RESOLVE_ITEM_H - -#include "rust-ast-full-decls.h" -#include "rust-ast-resolve-base.h" - -#include "config.h" - -namespace Rust { -namespace Resolver { - -class ResolveTraitItems : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::AssociatedItem *item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - void visit (AST::Function &type) override; - void visit (AST::TraitItemType &type) override; - void visit (AST::TraitItemConst &constant) override; - -private: - ResolveTraitItems (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -class ResolveItem : public ResolverBase -{ -public: - using Rust::Resolver::ResolverBase::visit; - - static void go (AST::Item &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - void visit (AST::TypeAlias &alias) override; - void visit (AST::Module &module) override; - void visit (AST::TupleStruct &struct_decl) override; - void visit (AST::Enum &enum_decl) override; - /* EnumItem doesn't need to be handled, no fields. */ - void visit (AST::EnumItem &item) override; - void visit (AST::EnumItemTuple &item) override; - void visit (AST::EnumItemStruct &item) override; - void visit (AST::EnumItemDiscriminant &item) override; - void visit (AST::StructStruct &struct_decl) override; - void visit (AST::Union &union_decl) override; - void visit (AST::StaticItem &var) override; - void visit (AST::ConstantItem &constant) override; - void visit (AST::Function &function) override; - void visit (AST::InherentImpl &impl_block) override; - void visit (AST::TraitImpl &impl_block) override; - void visit (AST::Trait &trait) override; - void visit (AST::ExternBlock &extern_block) override; - void visit (AST::UseDeclaration &) override; - -protected: - void resolve_impl_item (AST::AssociatedItem &item, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - void resolve_extern_item (AST::ExternalItem &item); - - ResolveItem (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -class ResolveImplItems : public ResolveItem -{ - using Rust::Resolver::ResolveItem::visit; - -public: - static void go (AST::AssociatedItem &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - void visit (AST::TypeAlias &alias) override; - -private: - ResolveImplItems (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); -}; - -class ResolveExternItem : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::ExternalItem &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - void visit (AST::Function &function) override; - void visit (AST::ExternalStaticItem &item) override; - -private: - ResolveExternItem (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) - {} - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -class Import -{ -public: - Import (AST::SimplePath path, bool is_glob, std::string name) - : path (path), is_glob_f (is_glob), name (name) - {} - - AST::SimplePath &get_path () { return path; } - - const AST::SimplePath &get_path () const { return path; } - - bool is_glob () const { return is_glob_f; } - - const std::string &get_name () const { return name; } - - void add_prefix (AST::SimplePath prefix); - -private: - AST::SimplePath path; - bool is_glob_f; - std::string name; -}; - -} // namespace Resolver -} // namespace Rust - -#if CHECKING_P - -namespace selftest { -extern void rust_simple_path_resolve_test (void); -} // namespace selftest - -#endif // CHECKING_P - -#endif // RUST_AST_RESOLVE_ITEM_H diff --git a/gcc/rust/resolve/rust-ast-resolve-path.cc b/gcc/rust/resolve/rust-ast-resolve-path.cc deleted file mode 100644 index fb6715d9528a..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-path.cc +++ /dev/null @@ -1,558 +0,0 @@ -// Copyright (C) 2020-2024 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-path.h" -#include "rust-ast-resolve-type.h" -#include "rust-hir-map.h" -#include "rust-path.h" - -namespace Rust { -namespace Resolver { - -ResolvePath::ResolvePath () : ResolverBase () {} - -NodeId -ResolvePath::go (AST::PathInExpression &expr) -{ - ResolvePath resolver; - return resolver.resolve_path (expr); -} - -NodeId -ResolvePath::go (AST::QualifiedPathInExpression &expr) -{ - ResolvePath resolver; - return resolver.resolve_path (expr); -} - -NodeId -ResolvePath::go (AST::SimplePath &expr) -{ - ResolvePath resolver; - return resolver.resolve_path (expr); -} - -NodeId -ResolvePath::resolve_path (AST::PathInExpression &expr) -{ - if (expr.is_lang_item ()) - return Analysis::Mappings::get ().get_lang_item_node ( - expr.get_lang_item ()); - - 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 in_middle_of_path = i > 0; - if (in_middle_of_path && segment.is_lower_self_seg ()) - { - rust_error_at (segment.get_locus (), ErrorCode::E0433, - "%qs in paths can only be used in start position", - segment.as_string ().c_str ()); - return 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - 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 % at the crate scope"); - return UNKNOWN_NODEID; - } - - module_scope_id = resolver->peek_parent_module_scope (); - previous_resolved_node_id = module_scope_id; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - resolver->insert_resolved_name (segment.get_node_id (), - module_scope_id); - continue; - } - - // resolve any generic args - if (segment.has_generic_args ()) - ResolveGenericArgs::go (segment.get_generic_args ()); - - // 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 (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)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_name (segment.get_node_id (), - resolved_node); - resolved_node_id = resolved_node; - } - // check the type scope - else if (resolver->get_type_scope ().lookup (path, &resolved_node)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_type (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_type (segment.get_node_id (), - resolved_node); - resolved_node_id = resolved_node; - } - else if (segment.is_lower_self_seg ()) - { - module_scope_id = crate_scope_id; - previous_resolved_node_id = module_scope_id; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - resolver->insert_resolved_name (segment.get_node_id (), - module_scope_id); - continue; - } - else - { - // no error handling here since we might be able to resolve via - // the module hierarchy and handle errors at the end - } - } - - if (resolved_node_id == UNKNOWN_NODEID - && previous_resolved_node_id == module_scope_id) - { - tl::optional resolved_child - = mappings.lookup_module_child (module_scope_id, - ident_seg.as_string ()); - if (resolved_child.has_value ()) - { - NodeId resolved_node = resolved_child->get_node_id (); - if (resolver->get_name_scope ().decl_was_declared_here ( - resolved_node)) - { - resolved_node_id = resolved_node; - - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_type (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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 UNKNOWN_NODEID; - } - } - } - - bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID; - if (did_resolve_segment) - { - if (mappings.node_is_module (resolved_node_id) - || mappings.node_is_crate (resolved_node_id)) - { - module_scope_id = resolved_node_id; - } - previous_resolved_node_id = resolved_node_id; - } - else if (is_first_segment) - { - rust_error_at (segment.get_locus (), ErrorCode::E0433, - "Cannot find path %<%s%> in this scope", - segment.as_string ().c_str ()); - return UNKNOWN_NODEID; - } - } - - resolved_node = resolved_node_id; - if (resolved_node_id != UNKNOWN_NODEID) - { - // name scope first - if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_name (expr.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - 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)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_type (expr.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - resolver->insert_resolved_type (expr.get_node_id (), - resolved_node_id); - } - else - { - rust_unreachable (); - } - } - return resolved_node_id; -} - -NodeId -ResolvePath::resolve_path (AST::QualifiedPathInExpression &expr) -{ - auto &root_segment = expr.get_qualified_path_type (); - ResolveType::go (root_segment.get_type ()); - if (root_segment.has_as_clause ()) - ResolveType::go (root_segment.get_as_type_path ()); - - for (auto &segment : expr.get_segments ()) - { - // 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 ()) - ResolveGenericArgs::go (segment.get_generic_args ()); - } - - // cannot fully resolve a qualified path as it is dependant on associated - // items - return UNKNOWN_NODEID; -} - -NodeId -ResolvePath::resolve_path (AST::SimplePath &expr) -{ - NodeId crate_scope_id = resolver->peek_crate_module_scope (); - NodeId module_scope_id = resolver->peek_current_module_scope (); - - NodeId previous_resolved_node_id = UNKNOWN_NODEID; - NodeId resolved_node_id = UNKNOWN_NODEID; - for (size_t i = 0; i < expr.get_segments ().size (); i++) - { - AST::SimplePathSegment &segment = expr.get_segments ().at (i); - bool is_first_segment = i == 0; - bool is_final_segment = i >= (expr.get_segments ().size () - 1); - resolved_node_id = UNKNOWN_NODEID; - - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - resolver->insert_resolved_name (segment.get_node_id (), - module_scope_id); - resolved_node_id = module_scope_id; - - continue; - } - else if (segment.is_super_path_seg ()) - { - if (!is_first_segment) - { - rust_error_at ( - segment.get_locus (), ErrorCode::E0433, - "% in paths can only be used in start position"); - return UNKNOWN_NODEID; - } - if (module_scope_id == crate_scope_id) - { - rust_error_at (segment.get_locus (), - "cannot use % at the crate scope"); - return UNKNOWN_NODEID; - } - - module_scope_id = resolver->peek_parent_module_scope (); - previous_resolved_node_id = module_scope_id; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - resolver->insert_resolved_name (segment.get_node_id (), - module_scope_id); - resolved_node_id = module_scope_id; - - continue; - } - - tl::optional resolved_child - = mappings.lookup_module_child (module_scope_id, - segment.get_segment_name ()); - if (resolved_child.has_value ()) - { - NodeId resolved_node = resolved_child->get_node_id (); - if (resolver->get_name_scope ().decl_was_declared_here ( - resolved_node)) - { - resolved_node_id = resolved_node; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_type (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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 UNKNOWN_NODEID; - } - } - - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_type (segment.get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_type (segment.get_node_id (), - resolved_node); - } - } - - // if we still have not resolved and this is the final segment and the - // final segment is self its likely the case: pub use - // - // result::Result::{self, Err, Ok}; - // - // Then the resolved_node_id is just the previous one so long as it is a - // resolved node id - // rust_debug_loc (segment.get_locus (), - // "trying to resolve seg: [%s] first [%s] last [%s]", - // segment.get_segment_name ().c_str (), - // is_first_segment ? "true" : "false", - // is_final_segment ? "true" : "false"); - if (resolved_node_id == UNKNOWN_NODEID && !is_first_segment - && is_final_segment && segment.is_lower_self_seg ()) - resolved_node_id = previous_resolved_node_id; - - // final check - if (resolved_node_id == UNKNOWN_NODEID) - { - rust_error_at (segment.get_locus (), - "cannot find simple path segment %<%s%> in this scope", - segment.as_string ().c_str ()); - return UNKNOWN_NODEID; - } - - if (mappings.node_is_module (resolved_node_id)) - { - module_scope_id = resolved_node_id; - } - - previous_resolved_node_id = resolved_node_id; - } - - resolved_node = resolved_node_id; - if (resolved_node_id != UNKNOWN_NODEID) - { - // name scope first - if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_name (expr.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - 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)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_type (expr.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - resolver->insert_resolved_type (expr.get_node_id (), - resolved_node_id); - } - else - { - rust_unreachable (); - } - } - return resolved_node_id; -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-path.h b/gcc/rust/resolve/rust-ast-resolve-path.h deleted file mode 100644 index cddb54a0a6e4..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-path.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_PATH_H -#define RUST_AST_RESOLVE_PATH_H - -#include "rust-ast-resolve-base.h" - -namespace Rust { -namespace Resolver { - -class ResolvePath : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static NodeId go (AST::PathInExpression &expr); - static NodeId go (AST::QualifiedPathInExpression &expr); - static NodeId go (AST::SimplePath &expr); - -private: - ResolvePath (); - - NodeId resolve_path (AST::PathInExpression &expr); - NodeId resolve_path (AST::QualifiedPathInExpression &expr); - NodeId resolve_path (AST::SimplePath &expr); - - void - resolve_simple_path_segments (CanonicalPath prefix, size_t offs, - const std::vector &segs, - NodeId expr_node_id, location_t expr_locus); -}; - -} // namespace Resolver -} // namespace Rust - -#endif // !RUST_AST_RESOLVE_PATH_H diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.cc b/gcc/rust/resolve/rust-ast-resolve-pattern.cc deleted file mode 100644 index cc633a9cc692..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-pattern.h" -#include "rust-ast-resolve-path.h" - -namespace Rust { -namespace Resolver { - -void -PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type) -{ - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - PatternDeclaration::go (pattern, type, bindings); -} - -void -PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type, - std::vector &bindings) -{ - PatternDeclaration resolver (bindings, type); - pattern.accept_vis (resolver); - - for (auto &map_entry : resolver.missing_bindings) - { - auto ident = map_entry.first; // key - auto info = map_entry.second; // value - - rust_error_at (info.get_locus (), ErrorCode::E0408, - "variable '%s' is not bound in all patterns", - ident.as_string ().c_str ()); - } - - for (auto &map_entry : resolver.inconsistent_bindings) - { - auto ident = map_entry.first; // key - auto info = map_entry.second; // value - - rust_error_at ( - info.get_locus (), ErrorCode::E0409, - "variable '%s' is bound inconsistently across pattern alternatives", - ident.as_string ().c_str ()); - } -} - -void -PatternDeclaration::visit (AST::IdentifierPattern &pattern) -{ - if (pattern.has_subpattern ()) - { - pattern.get_subpattern ().accept_vis (*this); - } - - Mutability mut = pattern.get_is_mut () ? Mutability::Mut : Mutability::Imm; - add_new_binding (pattern.get_ident (), pattern.get_node_id (), - BindingTypeInfo (mut, pattern.get_is_ref (), - pattern.get_locus ())); -} - -void -PatternDeclaration::visit (AST::GroupedPattern &pattern) -{ - pattern.get_pattern_in_parens ().accept_vis (*this); -} - -void -PatternDeclaration::visit (AST::ReferencePattern &pattern) -{ - pattern.get_referenced_pattern ().accept_vis (*this); -} - -void -PatternDeclaration::visit (AST::PathInExpression &pattern) -{ - ResolvePath::go (pattern); -} - -void -PatternDeclaration::visit (AST::TupleStructPattern &pattern) -{ - ResolvePath::go (pattern.get_path ()); - - AST::TupleStructItems &items = pattern.get_items (); - switch (items.get_item_type ()) - { - case AST::TupleStructItems::RANGE: - { - // TODO - rust_unreachable (); - } - break; - - case AST::TupleStructItems::NO_RANGE: - { - auto &items_no_range - = static_cast (items); - - for (auto &inner_pattern : items_no_range.get_patterns ()) - { - inner_pattern->accept_vis (*this); - } - } - break; - } -} - -void -PatternDeclaration::visit (AST::StructPattern &pattern) -{ - ResolvePath::go (pattern.get_path ()); - - auto &struct_pattern_elems = pattern.get_struct_pattern_elems (); - for (auto &field : struct_pattern_elems.get_struct_pattern_fields ()) - { - switch (field->get_item_type ()) - { - case AST::StructPatternField::ItemType::TUPLE_PAT: - { - AST::StructPatternFieldTuplePat &tuple - = static_cast (*field); - - tuple.get_index_pattern ().accept_vis (*this); - } - break; - - case AST::StructPatternField::ItemType::IDENT_PAT: - { - AST::StructPatternFieldIdentPat &ident - = static_cast (*field); - - ident.get_ident_pattern ().accept_vis (*this); - } - break; - - case AST::StructPatternField::ItemType::IDENT: - { - auto &ident = static_cast (*field); - - Mutability mut - = ident.is_mut () ? Mutability::Mut : Mutability::Imm; - - add_new_binding (ident.get_identifier (), ident.get_node_id (), - BindingTypeInfo (mut, ident.is_ref (), - ident.get_locus ())); - } - break; - } - } -} - -void -PatternDeclaration::visit (AST::TuplePattern &pattern) -{ - auto &items = pattern.get_items (); - switch (items.get_pattern_type ()) - { - case AST::TuplePatternItems::TuplePatternItemType::MULTIPLE: - { - auto &ref = static_cast ( - pattern.get_items ()); - - for (auto &p : ref.get_patterns ()) - p->accept_vis (*this); - } - break; - - case AST::TuplePatternItems::TuplePatternItemType::RANGED: - { - auto &ref - = static_cast (pattern.get_items ()); - - for (auto &p : ref.get_lower_patterns ()) - p->accept_vis (*this); - for (auto &p : ref.get_upper_patterns ()) - p->accept_vis (*this); - } - break; - } -} - -void -PatternDeclaration::visit (AST::AltPattern &pattern) -{ - // push a new set of 'Or' bindings to the stack. Accounts for the - // alternatives. e.g. in `p_0 | p_1`, bindings to the same identifier between - // p_0 and p_1 shouldn't cause an error. - bindings_with_ctx.emplace_back (PatternBoundCtx::Or, std::set ()); - - // This is a hack to avoid creating a separate visitor class for the - // consistency checks. We empty out the binding_info_map before each iteration - // to separate between the alts' binding_maps. And right after the alt - // visit... - auto tmp_binding_map = binding_info_map; - binding_info_map.clear (); - - std::vector alts_binding_maps; - - for (auto &alt : pattern.get_alts ()) - { - // before this visit, the binding_info_map is guaranteed to be empty - rust_assert (binding_info_map.empty ()); - - // push a new `Product` context to correctly reject multiple bindings - // within this single alt. - bindings_with_ctx.emplace_back (PatternBoundCtx::Product, - std::set ()); - - alt->accept_vis (*this); - - // ...the binding_info_map is (potentially) populated. We copy it to the - // vector, and empty it out to be ready for the next iteration. And after - // all the iterations are finished... - alts_binding_maps.push_back (binding_info_map); - binding_info_map.clear (); - - // Remove the last (i.e. `Product`) context and add the bindings from the - // visited alt to the one before last (i.e. `Or`). Now (after checking - // with the alt internally), the bindings from this alt will reside in the - // `Or` context. - auto last_bound_idents = bindings_with_ctx.back ().idents; - bindings_with_ctx.pop_back (); - - for (auto &ident : last_bound_idents) - { - bindings_with_ctx.back ().idents.insert (ident); - } - } - - // Now we can finally check for consistency. - check_bindings_consistency (alts_binding_maps); - - // Now we remove the `Or` context we pushed earlier. - // e.g. in `(a, (p_0 | p_1), c)`: after finishing up inside the alt pattern, - // we return to the tuple (`Product`) context and push the new bindings. - auto idents = bindings_with_ctx.back ().idents; - bindings_with_ctx.pop_back (); - for (auto &ident : idents) - bindings_with_ctx.back ().idents.insert (ident.as_string ()); - - // ...we repopulate the binding_info_map correctly (the initial bindings - // stored in the tmp_binding_map + all the bindings from all the alts) - binding_info_map = tmp_binding_map; - for (auto &alt_map : alts_binding_maps) - for (auto &map_entry : alt_map) - binding_info_map.insert (map_entry); -} - -void -PatternDeclaration::add_new_binding (Identifier ident, NodeId node_id, - BindingTypeInfo info) -{ - bool has_binding_ctx = bindings_with_ctx.size () > 0; - rust_assert (has_binding_ctx); - - bool identifier_or_bound = false, identifier_product_bound = false; - - for (auto binding : bindings_with_ctx) - { - bool identifier_bound_here - = (binding.idents.find (ident) != binding.idents.end ()); - if (identifier_bound_here) - { - identifier_product_bound |= binding.ctx == PatternBoundCtx::Product; - identifier_or_bound |= binding.ctx == PatternBoundCtx::Or; - } - } - - if (identifier_product_bound) - { - if (type == Rib::ItemType::Param) - { - rust_error_at (info.get_locus (), ErrorCode::E0415, - "identifier '%s' is bound more than once in the " - "same parameter list", - ident.as_string ().c_str ()); - } - else - { - rust_error_at ( - info.get_locus (), ErrorCode::E0416, - "identifier '%s' is bound more than once in the same pattern", - ident.as_string ().c_str ()); - } - - return; - } - - if (!identifier_or_bound) - { - bindings_with_ctx.back ().idents.insert (ident); - resolver->get_name_scope ().insert ( - CanonicalPath::new_seg (node_id, ident.as_string ()), node_id, - info.get_locus (), type); - } - - binding_info_map.insert ({ident, info}); -} - -// Verifies that all the alts in an AltPattern have the same set of bindings -// with the same mutability and reference states. -void -PatternDeclaration::check_bindings_consistency ( - std::vector &binding_maps) -{ - for (size_t i = 0; i < binding_maps.size (); i++) - { - auto &outer_bindings_map = binding_maps[i]; - - for (size_t j = 0; j < binding_maps.size (); j++) - { - // skip comparing the current outer map with itself. - if (j == i) - continue; - - auto &inner_bindings_map = binding_maps[j]; - - // iterate over the inner map entries and check if they exist in outer - // map - for (auto map_entry : inner_bindings_map) - { - auto ident = map_entry.first; // key - auto inner_info = map_entry.second; // value - bool ident_is_outer_bound = outer_bindings_map.count (ident); - - if (!ident_is_outer_bound && !missing_bindings.count (ident)) - missing_bindings.insert ({ident, inner_info}); - - else if (outer_bindings_map.count (ident) - && outer_bindings_map[ident] != inner_info - && !inconsistent_bindings.count (ident)) - inconsistent_bindings.insert ({ident, inner_info}); - } - } - } -} - -static void -resolve_range_pattern_bound (AST::RangePatternBound &bound) -{ - switch (bound.get_bound_type ()) - { - case AST::RangePatternBound::RangePatternBoundType::LITERAL: - // Nothing to resolve for a literal. - break; - - case AST::RangePatternBound::RangePatternBoundType::PATH: - { - auto &ref = static_cast (bound); - - ResolvePath::go (ref.get_path ()); - } - break; - - case AST::RangePatternBound::RangePatternBoundType::QUALPATH: - { - auto &ref = static_cast (bound); - - ResolvePath::go (ref.get_qualified_path ()); - } - break; - } -} - -void -PatternDeclaration::visit (AST::RangePattern &pattern) -{ - resolve_range_pattern_bound (pattern.get_upper_bound ()); - resolve_range_pattern_bound (pattern.get_lower_bound ()); -} - -void -PatternDeclaration::visit (AST::SlicePattern &pattern) -{ - auto &items = pattern.get_items (); - switch (items.get_pattern_type ()) - { - case AST::SlicePatternItems::SlicePatternItemType::NO_REST: - { - auto &ref - = static_cast (pattern.get_items ()); - - for (auto &p : ref.get_patterns ()) - p->accept_vis (*this); - } - break; - - case AST::SlicePatternItems::SlicePatternItemType::HAS_REST: - { - auto &ref - = static_cast (pattern.get_items ()); - - for (auto &p : ref.get_lower_patterns ()) - p->accept_vis (*this); - for (auto &p : ref.get_upper_patterns ()) - p->accept_vis (*this); - } - break; - } -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-pattern.h b/gcc/rust/resolve/rust-ast-resolve-pattern.h deleted file mode 100644 index 876de1607831..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-pattern.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_PATTERN_H -#define RUST_AST_RESOLVE_PATTERN_H - -#include "rust-ast-resolve-base.h" -#include "rust-ast-full.h" - -namespace Rust { -namespace Resolver { - -// Specifies whether the set of already bound patterns are related by 'Or' or -// 'Product'. Used to check for multiple bindings to the same identifier. -enum PatternBoundCtx -{ - // A product pattern context (e.g. struct and tuple patterns) - Product, - // An or-pattern context (e.g. p_0 | p_1 | ...) - Or, -}; - -struct PatternBinding -{ - PatternBoundCtx ctx; - std::set idents; - - PatternBinding (PatternBoundCtx ctx, std::set idents) - : ctx (ctx), idents (idents) - {} -}; - -// Info that gets stored in the map. Helps us detect if two bindings to the same -// identifier have different mutability or ref states. -class BindingTypeInfo -{ - Mutability mut; - bool is_ref; - location_t locus; - -public: - BindingTypeInfo (Mutability mut, bool is_ref, location_t locus) - : mut (mut), is_ref (is_ref), locus (locus) - {} - - BindingTypeInfo (BindingTypeInfo const &other) - : mut (other.mut), is_ref (other.is_ref), locus (other.get_locus ()) - {} - - BindingTypeInfo (){}; - - location_t get_locus () const { return locus; } - Mutability get_mut () const { return mut; } - bool get_is_ref () const { return is_ref; } - - BindingTypeInfo operator= (BindingTypeInfo const &other) - { - mut = other.mut; - is_ref = other.is_ref; - locus = other.get_locus (); - - return *this; - } - - bool operator== (BindingTypeInfo const &other) - { - return mut == other.mut && is_ref == other.is_ref; - } - - bool operator!= (BindingTypeInfo const &other) - { - return !BindingTypeInfo::operator== (other); - } -}; - -typedef std::map BindingMap; - -class PatternDeclaration : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::Pattern &pattern, Rib::ItemType type); - static void go (AST::Pattern &pattern, Rib::ItemType type, - std::vector &bindings); - - void visit (AST::IdentifierPattern &pattern) override; - void visit (AST::GroupedPattern &pattern) override; - void visit (AST::ReferencePattern &pattern) override; - void visit (AST::PathInExpression &pattern) override; - void visit (AST::StructPattern &pattern) override; - void visit (AST::TupleStructPattern &pattern) override; - void visit (AST::TuplePattern &pattern) override; - void visit (AST::RangePattern &pattern) override; - void visit (AST::AltPattern &pattern) override; - void visit (AST::SlicePattern &pattern) override; - - void add_new_binding (Identifier ident, NodeId node_id, BindingTypeInfo info); - void check_bindings_consistency (std::vector &binding_maps); - -private: - PatternDeclaration (std::vector &bindings_with_ctx, - Rib::ItemType type) - : ResolverBase (), bindings_with_ctx (bindings_with_ctx), type (type) - {} - - // To avoid having a separate visitor for consistency checks, we store - // bindings in two forms: - - // 1) Bindings as a vector of context-related sets. - // Used for checking multiple bindings to the same identifier (i.e. E0415, - // E0416). - std::vector &bindings_with_ctx; - - // 2) Bindings as a map between identifiers and binding info. - // Used for checking consistency between alt patterns (i.e. E0408, E0409). - BindingMap binding_info_map; - - // we need to insert the missing and inconsistent bindings (found in - // check_bindings_consistency) into maps to avoid duplication of error - // messages. - BindingMap inconsistent_bindings; - BindingMap missing_bindings; - - Rib::ItemType type; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_PATTERN_H diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc deleted file mode 100644 index bfba302d29d1..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-toplevel.h" -#include "rust-ast-resolve-item.h" -#include "rust-ast-resolve-stmt.h" -#include "rust-ast-resolve-implitem.h" - -namespace Rust { -namespace Resolver { - -void -ResolveStmt::visit (AST::ExternBlock &extern_block) -{ - resolve_visibility (extern_block.get_visibility ()); - for (auto &item : extern_block.get_extern_items ()) - { - ResolveToplevelExternItem::go (*item, CanonicalPath::create_empty ()); - ResolveExternItem::go (*item, prefix, canonical_prefix); - } -} - -void -ResolveStmt::visit (AST::Trait &trait) -{ - ResolveTopLevel::go (trait, prefix, canonical_prefix); - ResolveItem::go (trait, prefix, canonical_prefix); -} - -void -ResolveStmt::visit (AST::InherentImpl &impl_block) -{ - ResolveTopLevel::go (impl_block, prefix, canonical_prefix); - ResolveItem::go (impl_block, prefix, canonical_prefix); -} - -void -ResolveStmt::visit (AST::TraitImpl &impl_block) -{ - ResolveTopLevel::go (impl_block, prefix, canonical_prefix); - ResolveItem::go (impl_block, prefix, canonical_prefix); -} - -void -ResolveStmt::visit (AST::StaticItem &var) -{ - auto decl = CanonicalPath::new_seg (var.get_node_id (), - var.get_identifier ().as_string ()); - auto path = decl; - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (var.get_node_id (), cpath); - - resolver->get_name_scope ().insert ( - path, var.get_node_id (), var.get_locus (), false, Rib::ItemType::Static, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, var.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - ResolveType::go (var.get_type ()); - ResolveExpr::go (var.get_expr (), path, cpath); -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h deleted file mode 100644 index d7145112c823..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ /dev/null @@ -1,408 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_STMT_H -#define RUST_AST_RESOLVE_STMT_H - -#include "rust-ast-resolve-base.h" -#include "rust-ast-resolve-type.h" -#include "rust-ast-resolve-pattern.h" -#include "rust-ast-resolve-expr.h" -#include "rust-item.h" - -namespace Rust { -namespace Resolver { - -class ResolveStmt : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::Stmt &stmt, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, - const CanonicalPath &enum_prefix) - { - if (stmt.is_marked_for_strip ()) - return; - - ResolveStmt resolver (prefix, canonical_prefix, enum_prefix); - stmt.accept_vis (resolver); - } - - void visit (AST::ExprStmt &stmt) override - { - ResolveExpr::go (stmt.get_expr (), prefix, canonical_prefix); - } - - void visit (AST::ConstantItem &constant) override - { - auto decl = CanonicalPath::new_seg (constant.get_node_id (), - constant.get_identifier ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (constant.get_node_id (), cpath); - - resolver->get_name_scope ().insert ( - path, constant.get_node_id (), constant.get_locus (), false, - Rib::ItemType::Const, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, constant.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - ResolveType::go (constant.get_type ()); - if (constant.has_expr ()) - ResolveExpr::go (constant.get_expr (), prefix, canonical_prefix); - } - - void visit (AST::LetStmt &stmt) override - { - if (stmt.has_init_expr ()) - ResolveExpr::go (stmt.get_init_expr (), prefix, canonical_prefix); - - if (stmt.has_else_expr ()) - ResolveExpr::go (stmt.get_else_expr (), prefix, canonical_prefix); - - PatternDeclaration::go (stmt.get_pattern (), Rib::ItemType::Var); - if (stmt.has_type ()) - ResolveType::go (stmt.get_type ()); - } - - void visit (AST::TupleStruct &struct_decl) override - { - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, struct_decl.get_node_id (), struct_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, struct_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId scope_node_id = struct_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (struct_decl.has_generics ()) - ResolveGenericParams::go (struct_decl.get_generic_params (), prefix, - canonical_prefix); - - for (AST::TupleField &field : struct_decl.get_fields ()) - ResolveType::go (field.get_field_type ()); - - resolver->get_type_scope ().pop (); - } - - void visit (AST::Enum &enum_decl) override - { - auto decl - = CanonicalPath::new_seg (enum_decl.get_node_id (), - enum_decl.get_identifier ().as_string ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (enum_decl.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, enum_decl.get_node_id (), enum_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, enum_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId scope_node_id = enum_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (enum_decl.has_generics ()) - ResolveGenericParams::go (enum_decl.get_generic_params (), prefix, - canonical_prefix); - - for (auto &variant : enum_decl.get_variants ()) - ResolveStmt::go (*variant, path, canonical_prefix, path); - - resolver->get_type_scope ().pop (); - } - - void visit (AST::EnumItem &item) override - { - auto decl = enum_prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ())); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - // Done, no fields. - } - - void visit (AST::EnumItemTuple &item) override - { - auto decl = enum_prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ())); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - for (auto &field : item.get_tuple_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } - } - - void visit (AST::EnumItemStruct &item) override - { - auto decl = enum_prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ())); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - for (auto &field : item.get_struct_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } - } - - void visit (AST::EnumItemDiscriminant &item) override - { - auto decl = enum_prefix.append ( - CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ())); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (item.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - // Done, no fields. - } - - void visit (AST::StructStruct &struct_decl) override - { - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, struct_decl.get_node_id (), struct_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, struct_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId scope_node_id = struct_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (struct_decl.has_generics ()) - ResolveGenericParams::go (struct_decl.get_generic_params (), prefix, - canonical_prefix); - - for (AST::StructField &field : struct_decl.get_fields ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } - - resolver->get_type_scope ().pop (); - } - - void visit (AST::Union &union_decl) override - { - auto decl - = CanonicalPath::new_seg (union_decl.get_node_id (), - union_decl.get_identifier ().as_string ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (union_decl.get_node_id (), cpath); - - resolver->get_type_scope ().insert ( - path, union_decl.get_node_id (), union_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, union_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId scope_node_id = union_decl.get_node_id (); - resolver->get_type_scope ().push (scope_node_id); - - if (union_decl.has_generics ()) - ResolveGenericParams::go (union_decl.get_generic_params (), prefix, - canonical_prefix); - - for (AST::StructField &field : union_decl.get_variants ()) - { - if (field.get_field_type ().is_marked_for_strip ()) - continue; - - ResolveType::go (field.get_field_type ()); - } - - resolver->get_type_scope ().pop (); - } - - void visit (AST::Function &function) override - { - auto decl - = CanonicalPath::new_seg (function.get_node_id (), - function.get_function_name ().as_string ()); - auto path = decl; // this ensures we have the correct relative resolution - auto cpath = canonical_prefix.append (decl); - mappings.insert_canonical_path (function.get_node_id (), cpath); - - resolver->get_name_scope ().insert ( - path, function.get_node_id (), function.get_locus (), false, - Rib::ItemType::Function, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, function.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId scope_node_id = function.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - if (function.has_generics ()) - ResolveGenericParams::go (function.get_generic_params (), prefix, - canonical_prefix); - - if (function.has_return_type ()) - ResolveType::go (function.get_return_type ()); - - std::vector bindings - = {PatternBinding (PatternBoundCtx::Product, std::set ())}; - - // we make a new scope so the names of parameters are resolved and shadowed - // correctly - for (auto &p : function.get_function_params ()) - { - if (p->is_variadic ()) - { - auto ¶m = static_cast (*p); - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - - else if (p->is_self ()) - { - auto ¶m = static_cast (*p); - ResolveType::go (param.get_type ()); - } - else - { - auto ¶m = static_cast (*p); - - ResolveType::go (param.get_type ()); - PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, - bindings); - } - } - - // resolve the function body - ResolveExpr::go (*function.get_definition ().value (), path, cpath); - - resolver->get_name_scope ().pop (); - resolver->get_type_scope ().pop (); - resolver->get_label_scope ().pop (); - } - - void visit (AST::ExternBlock &extern_block) override; - void visit (AST::Trait &trait) override; - void visit (AST::InherentImpl &impl_block) override; - void visit (AST::TraitImpl &impl_block) override; - void visit (AST::StaticItem &var) override; - -private: - ResolveStmt (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix, - const CanonicalPath &enum_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix), - enum_prefix (enum_prefix) - {} - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; - - /* item declaration statements are not given a canonical path, but enum items - * (variants) do inherit the enum path/identifier name. */ - const CanonicalPath &enum_prefix; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_STMT_H diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc deleted file mode 100644 index 9b38e6a8a44d..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-struct-expr-field.h" -#include "rust-ast-resolve-expr.h" - -namespace Rust { -namespace Resolver { - -void -ResolveStructExprField::go (AST::StructExprField &field, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - ResolveStructExprField resolver (prefix, canonical_prefix); - field.accept_vis (resolver); -} - -ResolveStructExprField::ResolveStructExprField ( - const CanonicalPath &prefix, const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) -{} - -void -ResolveStructExprField::visit (AST::StructExprFieldIdentifierValue &field) -{ - ResolveExpr::go (field.get_value (), prefix, canonical_prefix); -} - -void -ResolveStructExprField::visit (AST::StructExprFieldIndexValue &field) -{ - ResolveExpr::go (field.get_value (), prefix, canonical_prefix); -} - -void -ResolveStructExprField::visit (AST::StructExprFieldIdentifier &field) -{ - AST::IdentifierExpr expr (field.get_field_name (), {}, field.get_locus ()); - expr.set_node_id (field.get_node_id ()); - - ResolveExpr::go (expr, prefix, canonical_prefix); -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h b/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h deleted file mode 100644 index 87fa60dcc6d9..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_STRUCT_EXPR_FIELD -#define RUST_AST_RESOLVE_STRUCT_EXPR_FIELD - -#include "rust-ast-resolve-base.h" - -namespace Rust { -namespace Resolver { - -// this resolves values being assigned not that the field actually exists yet. - -class ResolveStructExprField : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::StructExprField &field, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - void visit (AST::StructExprFieldIdentifierValue &field) override; - - void visit (AST::StructExprFieldIndexValue &field) override; - - void visit (AST::StructExprFieldIdentifier &field) override; - -private: - ResolveStructExprField (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_STRUCT_EXPR_FIELD diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h deleted file mode 100644 index f52fb8a4d168..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ /dev/null @@ -1,500 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_TOPLEVEL_H -#define RUST_AST_RESOLVE_TOPLEVEL_H - -#include "rust-ast-resolve-base.h" -#include "rust-ast-resolve-implitem.h" -#include "rust-name-resolver.h" - -namespace Rust { -namespace Resolver { - -class ResolveTopLevel : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::Item &item, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - { - if (item.is_marked_for_strip ()) - return; - - ResolveTopLevel resolver (prefix, canonical_prefix); - item.accept_vis (resolver); - - NodeId current_module = resolver.resolver->peek_current_module_scope (); - resolver.mappings.insert_child_item_to_parent_module_mapping ( - item.get_node_id (), current_module); - } - - void visit (AST::Module &module) override - { - auto mod = CanonicalPath::new_seg (module.get_node_id (), - module.get_name ().as_string ()); - auto path = prefix.append (mod); - auto cpath = canonical_prefix.append (mod); - - resolver->get_name_scope ().insert ( - path, module.get_node_id (), module.get_locus (), false, - Rib::ItemType::Module, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, module.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - 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 ()); - - resolver->push_new_module_scope (module.get_node_id ()); - for (auto &item : module.get_items ()) - ResolveTopLevel::go (*item, path, cpath); - - resolver->pop_module_scope (); - - mappings.insert_canonical_path (module.get_node_id (), cpath); - } - - void visit (AST::TypeAlias &alias) override - { - auto talias - = CanonicalPath::new_seg (alias.get_node_id (), - alias.get_new_type_name ().as_string ()); - auto path = prefix.append (talias); - auto cpath = canonical_prefix.append (talias); - - resolver->get_type_scope ().insert ( - path, alias.get_node_id (), alias.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, alias.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, talias); - mappings.insert_canonical_path (alias.get_node_id (), cpath); - } - - void visit (AST::TupleStruct &struct_decl) override - { - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, struct_decl.get_node_id (), struct_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, struct_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - } - - void visit (AST::Enum &enum_decl) override - { - auto decl - = CanonicalPath::new_seg (enum_decl.get_node_id (), - enum_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, enum_decl.get_node_id (), enum_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, enum_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - resolver->push_new_module_scope (enum_decl.get_node_id ()); - for (auto &variant : enum_decl.get_variants ()) - ResolveTopLevel::go (*variant, path, cpath); - - resolver->pop_module_scope (); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (enum_decl.get_node_id (), cpath); - } - - void visit (AST::EnumItem &item) override - { - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - mappings.insert_canonical_path (item.get_node_id (), cpath); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_module_child (current_module, item.get_node_id ()); - } - - void visit (AST::EnumItemTuple &item) override - { - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - mappings.insert_canonical_path (item.get_node_id (), cpath); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_module_child (current_module, item.get_node_id ()); - } - - void visit (AST::EnumItemStruct &item) override - { - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - mappings.insert_canonical_path (item.get_node_id (), cpath); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_module_child (current_module, item.get_node_id ()); - } - - void visit (AST::EnumItemDiscriminant &item) override - { - auto decl = CanonicalPath::new_seg (item.get_node_id (), - item.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, item.get_node_id (), item.get_locus (), false, Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, item.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - mappings.insert_canonical_path (item.get_node_id (), cpath); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_module_child (current_module, item.get_node_id ()); - } - - void visit (AST::StructStruct &struct_decl) override - { - auto decl - = CanonicalPath::new_seg (struct_decl.get_node_id (), - struct_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - auto duplicate_item - = [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, struct_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }; - - resolver->get_type_scope ().insert (path, struct_decl.get_node_id (), - struct_decl.get_locus (), false, - Rib::ItemType::Type, duplicate_item); - - if (struct_decl.is_unit_struct ()) - resolver->get_name_scope ().insert (path, struct_decl.get_node_id (), - struct_decl.get_locus (), false, - Rib::ItemType::Type, duplicate_item); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (struct_decl.get_node_id (), cpath); - } - - void visit (AST::Union &union_decl) override - { - auto decl - = CanonicalPath::new_seg (union_decl.get_node_id (), - union_decl.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, union_decl.get_node_id (), union_decl.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, union_decl.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (union_decl.get_node_id (), cpath); - } - - void visit (AST::StaticItem &var) override - { - auto decl = CanonicalPath::new_seg (var.get_node_id (), - var.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_name_scope ().insert ( - path, var.get_node_id (), var.get_locus (), false, Rib::ItemType::Static, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, var.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (var.get_node_id (), cpath); - } - - void visit (AST::ConstantItem &constant) override - { - auto decl = CanonicalPath::new_seg (constant.get_node_id (), - constant.get_identifier ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_name_scope ().insert ( - path, constant.get_node_id (), constant.get_locus (), false, - Rib::ItemType::Const, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, constant.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (constant.get_node_id (), cpath); - } - - void visit (AST::Function &function) override - { - auto decl - = CanonicalPath::new_seg (function.get_node_id (), - function.get_function_name ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_name_scope ().insert ( - path, function.get_node_id (), function.get_locus (), false, - Rib::ItemType::Function, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, function.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (function.get_node_id (), cpath); - } - - void visit (AST::InherentImpl &impl_block) override - { - std::string raw_impl_type_path = impl_block.get_type ().as_string (); - CanonicalPath impl_type_seg - = CanonicalPath::new_seg (impl_block.get_type ().get_node_id (), - raw_impl_type_path); - - CanonicalPath impl_type - = CanonicalPath::inherent_impl_seg (impl_block.get_node_id (), - impl_type_seg); - CanonicalPath impl_prefix = prefix.append (impl_type_seg); - - for (auto &impl_item : impl_block.get_impl_items ()) - ResolveToplevelImplItem::go (*impl_item, impl_prefix); - } - - void visit (AST::TraitImpl &impl_block) override - { - std::string raw_impl_type_path = impl_block.get_type ().as_string (); - CanonicalPath impl_type_seg - = CanonicalPath::new_seg (impl_block.get_type ().get_node_id (), - raw_impl_type_path); - - std::string raw_trait_type_path = impl_block.get_trait_path ().as_string (); - CanonicalPath trait_type_seg - = CanonicalPath::new_seg (impl_block.get_trait_path ().get_node_id (), - raw_trait_type_path); - - CanonicalPath projection - = CanonicalPath::trait_impl_projection_seg (impl_block.get_node_id (), - trait_type_seg, - impl_type_seg); - CanonicalPath impl_prefix = prefix.append (projection); - - resolver->get_name_scope ().insert ( - impl_prefix, impl_block.get_node_id (), impl_block.get_locus (), false, - Rib::ItemType::TraitImpl, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, impl_block.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - for (auto &impl_item : impl_block.get_impl_items ()) - ResolveToplevelImplItem::go (*impl_item, impl_prefix); - } - - void visit (AST::Trait &trait) override - { - auto decl = CanonicalPath::new_seg (trait.get_node_id (), - trait.get_identifier ().as_string ()); - auto path = prefix.append (decl); - auto cpath = canonical_prefix.append (decl); - - resolver->get_type_scope ().insert ( - path, trait.get_node_id (), trait.get_locus (), false, - Rib::ItemType::Trait, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, trait.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - - for (auto &item : trait.get_trait_items ()) - ResolveTopLevelTraitItems::go (item.get (), path, cpath); - - NodeId current_module = resolver->peek_current_module_scope (); - mappings.insert_module_child_item (current_module, decl); - mappings.insert_canonical_path (trait.get_node_id (), cpath); - } - - void visit (AST::ExternBlock &extern_block) override - { - for (auto &item : extern_block.get_extern_items ()) - { - ResolveToplevelExternItem::go (*item, prefix); - } - } - - void visit (AST::ExternCrate &extern_crate) override - { - if (extern_crate.is_marked_for_strip ()) - return; - - NodeId resolved_crate = UNKNOWN_NODEID; - if (extern_crate.references_self ()) - { - CrateNum crate_num = mappings.get_current_crate (); - resolved_crate = mappings.crate_num_to_nodeid (crate_num).value (); - } - else - { - auto cnum - = mappings.lookup_crate_name (extern_crate.get_referenced_crate ()); - if (!cnum) - { - rust_error_at (extern_crate.get_locus (), "unknown crate %qs", - extern_crate.get_referenced_crate ().c_str ()); - return; - } - if (auto resolved = mappings.crate_num_to_nodeid (*cnum)) - resolved_crate = resolved.value (); - else - { - rust_internal_error_at (extern_crate.get_locus (), - "failed to resolve crate to nodeid"); - return; - } - } - - if (resolved_crate == UNKNOWN_NODEID) - { - rust_error_at (extern_crate.get_locus (), "failed to resolve crate"); - return; - } - - // mark the node as resolved - resolver->insert_resolved_name (extern_crate.get_node_id (), - resolved_crate); - CanonicalPath decl - = extern_crate.has_as_clause () - ? CanonicalPath::new_seg (extern_crate.get_node_id (), - extern_crate.get_as_clause ()) - : CanonicalPath::new_seg (extern_crate.get_node_id (), - extern_crate.get_referenced_crate ()); - - resolver->get_type_scope ().insert ( - decl, resolved_crate, extern_crate.get_locus (), false, - Rib::ItemType::ExternCrate, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rich_location r (line_table, extern_crate.get_locus ()); - r.add_range (locus); - redefined_error (r); - }); - } - -private: - ResolveTopLevel (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) - {} - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_TOPLEVEL_H diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc deleted file mode 100644 index a0402289afc4..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ /dev/null @@ -1,785 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve-type.h" -#include "rust-ast-resolve-expr.h" -#include "rust-canonical-path.h" -#include "rust-type.h" -#include "rust-hir-map.h" - -namespace Rust { -namespace Resolver { - -// rust-ast-resolve-type.h - -NodeId -ResolveType::go (AST::Type &type) -{ - ResolveType resolver; - type.accept_vis (resolver); - return resolver.resolved_node; -} - -void -ResolveType::visit (AST::BareFunctionType &fntype) -{ - for (auto ¶m : fntype.get_function_params ()) - ResolveType::go (param.get_type ()); - - if (fntype.has_return_type ()) - ResolveType::go (fntype.get_return_type ()); -} - -void -ResolveType::visit (AST::TupleType &tuple) -{ - if (tuple.is_unit_type ()) - { - resolved_node = resolver->get_unit_type_node_id (); - return; - } - - for (auto &elem : tuple.get_elems ()) - ResolveType::go (*elem); -} - -void -ResolveType::visit (AST::TypePath &path) -{ - ResolveRelativeTypePath::go (path, resolved_node); -} - -void -ResolveType::visit (AST::QualifiedPathInType &path) -{ - ResolveRelativeQualTypePath::go (path); -} - -void -ResolveType::visit (AST::ArrayType &type) -{ - type.get_elem_type ().accept_vis (*this); - ResolveExpr::go (type.get_size_expr (), CanonicalPath::create_empty (), - CanonicalPath::create_empty ()); -} - -void -ResolveType::visit (AST::TraitObjectTypeOneBound &type) -{ - ResolveTypeBound::go (type.get_trait_bound ()); -} - -void -ResolveType::visit (AST::TraitObjectType &type) -{ - for (auto &bound : type.get_type_param_bounds ()) - { - /* NodeId bound_resolved_id = */ - ResolveTypeBound::go (*bound); - } -} - -void -ResolveType::visit (AST::ParenthesisedType &type) -{ - resolved_node = ResolveType::go (*type.get_type_in_parens ()); -} - -void -ResolveType::visit (AST::ReferenceType &type) -{ - resolved_node = ResolveType::go (type.get_type_referenced ()); -} - -void -ResolveType::visit (AST::RawPointerType &type) -{ - resolved_node = ResolveType::go (type.get_type_pointed_to ()); -} - -void -ResolveType::visit (AST::InferredType &) -{ - // nothing to do -} - -void -ResolveType::visit (AST::NeverType &) -{ - resolved_node = resolver->get_never_type_node_id (); -} - -void -ResolveType::visit (AST::SliceType &type) -{ - resolved_node = ResolveType::go (type.get_elem_type ()); -} - -void -ResolveType::visit (AST::ImplTraitType &type) -{ - for (auto &bound : type.get_type_param_bounds ()) - ResolveTypeBound::go (*bound); -} - -void -ResolveType::visit (AST::ImplTraitTypeOneBound &type) -{ - ResolveTypeBound::go (*type.get_trait_bound ().get ()); -} - -// resolve relative type-paths - -bool -ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) -{ - auto resolver = Resolver::get (); - auto &mappings = Analysis::Mappings::get (); - - 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++) - { - auto &segment = path.get_segments ().at (i); - bool is_first_segment = i == 0; - NodeId crate_scope_id = resolver->peek_crate_module_scope (); - auto ident_string = segment->is_lang_item () - ? LangItem::PrettyString (segment->get_lang_item ()) - : segment->get_ident_segment ().as_string (); - - resolved_node_id = UNKNOWN_NODEID; - - if (segment->is_lang_item ()) - { - resolved_node_id = Analysis::Mappings::get ().get_lang_item_node ( - segment->get_lang_item ()); - previous_resolved_node_id = resolved_node_id; - } - else - { - bool in_middle_of_path = i > 0; - if (in_middle_of_path && segment->is_lower_self_seg ()) - { - rust_error_at (segment->get_locus (), ErrorCode::E0433, - "%qs in paths can only be used in start position", - segment->as_string ().c_str ()); - return false; - } - - 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 (segment.get ()); - if (s->has_generic_args ()) - ResolveGenericArgs::go (s->get_generic_args ()); - } - break; - - case AST::TypePathSegment::SegmentType::REG: - // nothing to do - break; - - case AST::TypePathSegment::SegmentType::FUNCTION: - AST::TypePathSegmentFunction *fnseg - = static_cast (segment.get ()); - - AST::TypePathFunction &fn = fnseg->get_type_path_function (); - for (auto ¶m : fn.get_params ()) - { - ResolveType::go (*param); - } - - if (fn.has_return_type ()) - { - ResolveType::go (fn.get_return_type ()); - } - - break; - } - - if (is_first_segment) - { - // name scope first - NodeId resolved_node = UNKNOWN_NODEID; - const CanonicalPath path - = CanonicalPath::new_seg (segment->get_node_id (), ident_string); - if (resolver->get_type_scope ().lookup (path, &resolved_node)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_type (segment->get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_type (segment->get_node_id (), - resolved_node); - resolved_node_id = resolved_node; - } - else if (resolver->get_name_scope ().lookup (path, &resolved_node)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment->get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_name (segment->get_node_id (), - resolved_node); - resolved_node_id = resolved_node; - } - else if (!segment->is_lang_item () && segment->is_lower_self_seg ()) - { - // what is the current crate scope node id? - module_scope_id = crate_scope_id; - previous_resolved_node_id = module_scope_id; - - NodeId existing = UNKNOWN_NODEID; - bool ok = resolver->lookup_resolved_name (segment->get_node_id (), - &existing); - - if (ok) - rust_assert (existing == module_scope_id); - else - resolver->insert_resolved_name (segment->get_node_id (), - module_scope_id); - - continue; - } - } - - if (resolved_node_id == UNKNOWN_NODEID - && previous_resolved_node_id == module_scope_id) - { - tl::optional resolved_child - = mappings.lookup_module_child (module_scope_id, ident_string); - if (resolved_child.has_value ()) - { - NodeId resolved_node = resolved_child->get_node_id (); - if (resolver->get_name_scope ().decl_was_declared_here ( - resolved_node)) - { - resolved_node_id = resolved_node; - - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_name (segment->get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - 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; - - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_type (segment->get_node_id (), - &existing); - - if (ok) - rust_assert (existing == resolved_node); - else - resolver->insert_resolved_type (segment->get_node_id (), - resolved_node); - } - else - { - rust_error_at (segment->get_locus (), - "Cannot find path %qs in this scope", - segment->as_string ().c_str ()); - return false; - } - } - } - - bool did_resolve_segment = resolved_node_id != UNKNOWN_NODEID; - if (did_resolve_segment) - { - if (mappings.node_is_module (resolved_node_id) - || mappings.node_is_crate (resolved_node_id)) - { - module_scope_id = resolved_node_id; - } - previous_resolved_node_id = resolved_node_id; - } - else if (is_first_segment) - { - rust_error_at (segment->get_locus (), ErrorCode::E0412, - "could not resolve type path %qs", - segment->get_ident_segment ().as_string ().c_str ()); - return false; - } - } - - if (resolved_node_id != UNKNOWN_NODEID) - { - // name scope first - if (resolver->get_name_scope ().decl_was_declared_here (resolved_node_id)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_name (path.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - 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)) - { - NodeId existing = UNKNOWN_NODEID; - bool ok - = resolver->lookup_resolved_type (path.get_node_id (), &existing); - - if (ok) - rust_assert (existing == resolved_node_id); - else - resolver->insert_resolved_type (path.get_node_id (), - resolved_node_id); - } - else - { - rust_unreachable (); - } - } - - return true; -} - -// qualified type paths - -ResolveRelativeQualTypePath::ResolveRelativeQualTypePath () - : failure_flag (false) -{} - -bool -ResolveRelativeQualTypePath::go (AST::QualifiedPathInType &path) -{ - ResolveRelativeQualTypePath o; - - // resolve the type and trait path - auto &qualified_path = path.get_qualified_path_type (); - if (!o.resolve_qual_seg (qualified_path)) - 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 - - std::unique_ptr &associated - = path.get_associated_segment (); - - associated->accept_vis (o); - if (o.failure_flag) - return false; - - for (auto &seg : path.get_segments ()) - { - seg->accept_vis (o); - if (o.failure_flag) - return false; - } - - return true; -} - -bool -ResolveRelativeQualTypePath::resolve_qual_seg (AST::QualifiedPathType &seg) -{ - if (seg.is_error ()) - { - rust_error_at (seg.get_locus (), "segment has error: %s", - seg.as_string ().c_str ()); - return false; - } - - auto &type = seg.get_type (); - ResolveType::go (type); - - if (seg.has_as_clause ()) - ResolveType::go (seg.get_as_type_path ()); - - return true; -} - -void -ResolveRelativeQualTypePath::visit (AST::TypePathSegmentGeneric &seg) -{ - if (seg.is_error ()) - { - failure_flag = true; - rust_error_at (seg.get_locus (), "segment has error: %s", - seg.as_string ().c_str ()); - return; - } - - ResolveGenericArgs::go (seg.get_generic_args ()); -} - -void -ResolveRelativeQualTypePath::visit (AST::TypePathSegment &seg) -{ - if (seg.is_error ()) - { - failure_flag = true; - rust_error_at (seg.get_locus (), "segment has error: %s", - seg.as_string ().c_str ()); - return; - } -} - -// resolve to canonical path - -bool -ResolveTypeToCanonicalPath::go (AST::Type &type, CanonicalPath &result) -{ - ResolveTypeToCanonicalPath resolver; - type.accept_vis (resolver); - result = resolver.result; - return !resolver.result.is_empty (); -} - -void -ResolveTypeToCanonicalPath::visit (AST::TypePath &path) -{ - NodeId resolved_node = UNKNOWN_NODEID; - if (!resolver->lookup_resolved_name (path.get_node_id (), &resolved_node)) - { - resolver->lookup_resolved_type (path.get_node_id (), &resolved_node); - } - - if (resolved_node == UNKNOWN_NODEID) - return; - - if (auto type_path = mappings.lookup_canonical_path (resolved_node)) - { - auto &final_seg = path.get_segments ().back (); - switch (final_seg->get_type ()) - { - case AST::TypePathSegment::SegmentType::GENERIC: - { - AST::TypePathSegmentGeneric *s - = static_cast (final_seg.get ()); - - std::vector args; - if (s->has_generic_args ()) - { - ResolveGenericArgs::go (s->get_generic_args ()); - for (auto &generic : s->get_generic_args ().get_generic_args ()) - { - // FIXME: What do we want to do here in case there is a - // constant or an ambiguous const generic? - // TODO: At that point, will all generics have been - // disambiguated? Can we thus canonical resolve types and - // const and `rust_unreachable` on ambiguous types? - // This is probably fine as we just want to canonicalize - // types, right? - if (generic.get_kind () == AST::GenericArg::Kind::Type) - { - CanonicalPath arg = CanonicalPath::create_empty (); - bool ok - = ResolveTypeToCanonicalPath::go (generic.get_type (), - arg); - if (ok) - args.push_back (std::move (arg)); - } - } - } - - result = *type_path; - if (!args.empty ()) - { - // append this onto the path - std::string buf; - for (size_t i = 0; i < args.size (); i++) - { - bool has_next = (i + 1) < args.size (); - const auto &arg = args.at (i); - - buf += arg.get (); - if (has_next) - buf += ", "; - } - - std::string arg_seg = "<" + buf + ">"; - CanonicalPath argument_seg - = CanonicalPath::new_seg (s->get_node_id (), arg_seg); - result = result.append (argument_seg); - } - } - break; - - default: - result = *type_path; - break; - } - } -} - -void -ResolveTypeToCanonicalPath::visit (AST::ReferenceType &type) -{ - CanonicalPath path = CanonicalPath::create_empty (); - bool ok = ResolveTypeToCanonicalPath::go (type.get_type_referenced (), path); - if (ok) - { - std::string ref_type_str = type.is_mut () ? "mut" : ""; - std::string ref_path = "&" + ref_type_str + " " + path.get (); - result = CanonicalPath::new_seg (type.get_node_id (), ref_path); - } -} - -void -ResolveTypeToCanonicalPath::visit (AST::RawPointerType &type) -{ - CanonicalPath path = CanonicalPath::create_empty (); - bool ok = ResolveTypeToCanonicalPath::go (type.get_type_pointed_to (), path); - if (ok) - { - std::string ptr_type_str - = type.get_pointer_type () == AST::RawPointerType::CONST ? "const" - : "mut"; - std::string ptr_path = "*" + ptr_type_str + " " + path.get (); - result = CanonicalPath::new_seg (type.get_node_id (), ptr_path); - } -} - -void -ResolveTypeToCanonicalPath::visit (AST::SliceType &type) -{ - CanonicalPath path = CanonicalPath::create_empty (); - bool ok = ResolveTypeToCanonicalPath::go (type.get_elem_type (), path); - if (ok) - { - std::string slice_path = "[" + path.get () + "]"; - result = CanonicalPath::new_seg (type.get_node_id (), slice_path); - } -} - -void -ResolveTypeToCanonicalPath::visit (AST::TraitObjectTypeOneBound &type) -{ - CanonicalPath path = CanonicalPath::create_empty (); - bool ok - = ResolveTypeToCanonicalPath::go (type.get_trait_bound ().get_type_path (), - path); - if (ok) - { - std::string slice_path = ""; - result = CanonicalPath::new_seg (type.get_node_id (), slice_path); - } -} - -void -ResolveTypeToCanonicalPath::visit (AST::TraitObjectType &type) -{ - rust_assert (!type.get_type_param_bounds ().empty ()); - - auto &first_bound = type.get_type_param_bounds ().front (); - - // Is it allowed or even possible to have a lifetime bound as a first bound? - if (first_bound->get_bound_type () == AST::TraitBound::LIFETIME) - rust_unreachable (); - - auto &trait = static_cast (*first_bound); - - CanonicalPath path = CanonicalPath::create_empty (); - bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path); - - // right? - rust_assert (ok); - - auto slice_path = "get_bound_type ()) - { - case AST::TypeParamBound::TRAIT: - { - auto bound_path = CanonicalPath::create_empty (); - - auto &bound_type_path - = static_cast (*additional_bound) - .get_type_path (); - bool ok - = ResolveTypeToCanonicalPath::go (bound_type_path, bound_path); - - if (!ok) - continue; - - str = bound_path.get (); - break; - } - case AST::TypeParamBound::LIFETIME: - rust_unreachable (); - break; - } - slice_path += " + " + str; - } - - slice_path += ">"; - - result = CanonicalPath::new_seg (type.get_node_id (), slice_path); -} - -void -ResolveTypeToCanonicalPath::visit (AST::NeverType &type) -{ - result = CanonicalPath::new_seg (type.get_node_id (), "!"); -} - -void -ResolveTypeToCanonicalPath::visit (AST::TupleType &type) -{ - if (!type.is_unit_type ()) - rust_unreachable (); - - result = CanonicalPath::new_seg (type.get_node_id (), "()"); -} - -ResolveTypeToCanonicalPath::ResolveTypeToCanonicalPath () - : ResolverBase (), result (CanonicalPath::create_empty ()) -{} - -bool -ResolveGenericArgs::is_const_value_name (const CanonicalPath &path) -{ - NodeId resolved; - auto found = resolver->get_name_scope ().lookup (path, &resolved); - - return found; -} - -bool -ResolveGenericArgs::is_type_name (const CanonicalPath &path) -{ - NodeId resolved; - auto found = resolver->get_type_scope ().lookup (path, &resolved); - - return found; -} - -void -ResolveGenericArgs::disambiguate (AST::GenericArg &arg) -{ - auto path = canonical_prefix.append ( - CanonicalPath::new_seg (UNKNOWN_NODEID, arg.get_path ())); - - auto is_type = is_type_name (path); - auto is_value = is_const_value_name (path); - - // In case we cannot find anything, we resolve the ambiguity to a type. - // This causes the typechecker to error out properly and when necessary. - // But types also take priority over const values in the case of - // ambiguities, hence the weird control flow - if (is_type || (!is_type && !is_value)) - arg = arg.disambiguate_to_type (); - else if (is_value) - arg = arg.disambiguate_to_const (); -} - -void -ResolveGenericArgs::resolve_disambiguated_generic (AST::GenericArg &arg) -{ - switch (arg.get_kind ()) - { - case AST::GenericArg::Kind::Const: - ResolveExpr::go (arg.get_expression (), prefix, canonical_prefix); - break; - case AST::GenericArg::Kind::Type: - ResolveType::go (arg.get_type ()); - break; - default: - rust_unreachable (); - } -} -void -ResolveGenericArgs::go (AST::GenericArgs &generic_args) -{ - auto empty = CanonicalPath::create_empty (); - - go (generic_args, empty, empty); -} - -void -ResolveGenericArgs::go (AST::GenericArgs &generic_args, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) -{ - auto resolver = ResolveGenericArgs (prefix, canonical_prefix); - - for (auto &arg : generic_args.get_generic_args ()) - { - if (arg.get_kind () == AST::GenericArg::Kind::Either) - resolver.disambiguate (arg); - - resolver.resolve_disambiguated_generic (arg); - } - - for (auto &binding : generic_args.get_binding_args ()) - { - ResolveType::go (binding.get_type ()); - } -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve-type.h b/gcc/rust/resolve/rust-ast-resolve-type.h deleted file mode 100644 index f1481fcc65e0..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve-type.h +++ /dev/null @@ -1,280 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_TYPE_H -#define RUST_AST_RESOLVE_TYPE_H - -#include "rust-ast-resolve-base.h" -#include "rust-ast-resolve-expr.h" -#include "rust-diagnostics.h" -#include "rust-hir-map.h" -#include "rust-path.h" -#include "rust-type.h" -#include "util/rust-hir-map.h" - -namespace Rust { -namespace Resolver { - -class ResolveRelativeTypePath -{ -public: - static bool go (AST::TypePath &path, NodeId &resolved_node_id); -}; - -class ResolveRelativeQualTypePath : public ResolverBase -{ - using ResolverBase::visit; - -public: - static bool go (AST::QualifiedPathInType &path); - - void visit (AST::TypePathSegmentGeneric &seg) override; - - void visit (AST::TypePathSegment &seg) override; - -protected: - bool resolve_qual_seg (AST::QualifiedPathType &seg); - -private: - ResolveRelativeQualTypePath (); - - bool failure_flag; -}; - -class ResolveType : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static NodeId go (AST::Type &type); - - void visit (AST::BareFunctionType &fntype) override; - void visit (AST::TupleType &tuple) override; - void visit (AST::TypePath &path) override; - void visit (AST::QualifiedPathInType &path) override; - void visit (AST::ArrayType &type) override; - void visit (AST::ReferenceType &type) override; - void visit (AST::InferredType &type) override; - void visit (AST::NeverType &type) override; - void visit (AST::RawPointerType &type) override; - void visit (AST::TraitObjectTypeOneBound &type) override; - void visit (AST::TraitObjectType &type) override; - void visit (AST::ParenthesisedType &type) override; - void visit (AST::SliceType &type) override; - void visit (AST::ImplTraitType &type) override; - void visit (AST::ImplTraitTypeOneBound &type) override; - -private: - ResolveType () : ResolverBase () {} -}; - -class ResolveTypeBound : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static NodeId go (AST::TypeParamBound &type) - { - ResolveTypeBound resolver; - type.accept_vis (resolver); - return resolver.resolved_node; - }; - - void visit (AST::TraitBound &bound) override - { - resolved_node = ResolveType::go (bound.get_type_path ()); - } - -private: - ResolveTypeBound () : ResolverBase () {} -}; - -class ResolveGenericParams : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (std::vector> ¶ms, - const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - { - ResolveGenericParams resolver (prefix, canonical_prefix); - - // this needs to be done in two phases as they can be used and defined later - // in bounds - for (auto ¶m : params) - param->accept_vis (resolver); - - resolver.first_pass = false; - - for (auto ¶m : params) - param->accept_vis (resolver); - } - - static void go_single (AST::GenericParam ¶m, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - { - ResolveGenericParams resolver (prefix, canonical_prefix); - - param.accept_vis (resolver); - resolver.first_pass = false; - param.accept_vis (resolver); - } - - void visit (AST::ConstGenericParam ¶m) override - { - if (first_pass) - ResolveType::go (param.get_type ()); - else if (param.has_default_value ()) - ResolveExpr::go (param.get_default_value_unchecked ().get_expression (), - prefix, canonical_prefix); - } - - void visit (AST::TypeParam ¶m) override - { - if (first_pass) - { - // if it has a type lets resolve it - if (param.has_type ()) - ResolveType::go (param.get_type ()); - - auto seg = CanonicalPath::new_seg ( - param.get_node_id (), param.get_type_representation ().as_string ()); - resolver->get_type_scope ().insert ( - seg, param.get_node_id (), param.get_locus (), false, - Rib::ItemType::Type, - [&] (const CanonicalPath &, NodeId, location_t locus) -> void { - rust_error_at (param.get_locus (), - "generic param defined multiple times"); - rust_error_at (locus, "was defined here"); - }); - - mappings.insert_canonical_path (param.get_node_id (), seg); - } - else if (param.has_type_param_bounds ()) - { - for (auto &bound : param.get_type_param_bounds ()) - ResolveTypeBound::go (*bound); - } - } - -private: - ResolveGenericParams (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), first_pass (true), prefix (prefix), - canonical_prefix (canonical_prefix) - {} - - bool first_pass; - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -class ResolveWhereClause : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void Resolve (AST::WhereClause &where_clause) - { - ResolveWhereClause r; - for (auto &clause : where_clause.get_items ()) - clause->accept_vis (r); - } - - void visit (AST::TypeBoundWhereClauseItem &item) override - { - ResolveType::go (item.get_type ()); - if (item.has_type_param_bounds ()) - { - for (auto &bound : item.get_type_param_bounds ()) - { - ResolveTypeBound::go (*bound); - } - } - } - -private: - ResolveWhereClause () : ResolverBase () {} -}; - -class ResolveTypeToCanonicalPath : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static bool go (AST::Type &type, CanonicalPath &result); - - void visit (AST::TypePath &path) override; - - void visit (AST::ReferenceType &type) override; - - void visit (AST::RawPointerType &type) override; - - void visit (AST::SliceType &type) override; - - void visit (AST::TraitObjectTypeOneBound &type) override; - - void visit (AST::TraitObjectType &type) override; - - void visit (AST::NeverType &type) override; - - void visit (AST::TupleType &type) override; - -private: - ResolveTypeToCanonicalPath (); - - CanonicalPath result; -}; - -class ResolveGenericArgs : public ResolverBase -{ - using Rust::Resolver::ResolverBase::visit; - -public: - static void go (AST::GenericArgs &generic_args); - static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix); - -private: - ResolveGenericArgs (const CanonicalPath &prefix, - const CanonicalPath &canonical_prefix) - : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) - {} - - bool is_type_name (const CanonicalPath &path); - bool is_const_value_name (const CanonicalPath &path); - - /** - * Resolve a disambiguated generic arg - */ - void disambiguate (AST::GenericArg &arg); - - /** - * Resolve a disambiguated generic arg - */ - void resolve_disambiguated_generic (AST::GenericArg &arg); - - const CanonicalPath &prefix; - const CanonicalPath &canonical_prefix; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_TYPE_H diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc deleted file mode 100644 index 2208f7046a7e..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve.cc +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-ast-resolve.h" -#include "rust-ast-full.h" -#include "rust-tyty.h" -#include "rust-ast-resolve-toplevel.h" -#include "rust-ast-resolve-item.h" -#include "rust-ast-resolve-expr.h" -#include "rust-ast-resolve-struct-expr-field.h" - -extern bool saw_errors (void); - -namespace Rust { -namespace Resolver { - -// NameResolution - -NameResolution * -NameResolution::get () -{ - static NameResolution *instance; - if (instance == nullptr) - instance = new NameResolution (); - - return instance; -} - -NameResolution::NameResolution () - : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()) -{ - // these are global - resolver->get_type_scope ().push (mappings.get_next_node_id ()); - resolver->insert_builtin_types (resolver->get_type_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); -} - -void -NameResolution::Resolve (AST::Crate &crate) -{ - auto resolver = get (); - resolver->go (crate); -} - -void -NameResolution::go (AST::Crate &crate) -{ - // lookup current crate name - CrateNum cnum = mappings.get_current_crate (); - - // Clones the crate name instead of references due to gcc's possibly - // dangling references warnings - const auto crate_name = mappings.get_crate_name (cnum).value (); - - // setup the ribs - NodeId scope_node_id = crate.get_node_id (); - resolver->get_name_scope ().push (scope_node_id); - resolver->get_type_scope ().push (scope_node_id); - resolver->get_label_scope ().push (scope_node_id); - resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); - resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); - resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - - // get the root segment - CanonicalPath crate_prefix - = 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 (), UNDEF_LOCATION); - - // setup the root scope - resolver->push_new_module_scope (scope_node_id); - - // first gather the top-level namespace names then we drill down so this - // allows for resolving forward declarations since an impl block might have - // a Self type Foo which is defined after the impl block for example. - for (auto &item : crate.items) - ResolveTopLevel::go (*item, CanonicalPath::create_empty (), crate_prefix); - - // FIXME remove this - if (saw_errors ()) - { - resolver->pop_module_scope (); - return; - } - - // next we can drill down into the items and their scopes - for (auto &item : crate.items) - ResolveItem::go (*item, CanonicalPath::create_empty (), crate_prefix); - - // done - resolver->pop_module_scope (); -} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-ast-resolve.h b/gcc/rust/resolve/rust-ast-resolve.h deleted file mode 100644 index a4ad71884966..000000000000 --- a/gcc/rust/resolve/rust-ast-resolve.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_AST_RESOLVE_H -#define RUST_AST_RESOLVE_H - -#include "rust-name-resolver.h" -#include "rust-hir-map.h" - -namespace Rust { -namespace Resolver { - -class NameResolution -{ -public: - static void Resolve (AST::Crate &crate); - - static NameResolution *get (); - - ~NameResolution () {} - -private: - void go (AST::Crate &crate); - - NameResolution (); - - Resolver *resolver; - Analysis::Mappings &mappings; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_H diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc deleted file mode 100644 index 7b365ef7f260..000000000000 --- a/gcc/rust/resolve/rust-early-name-resolver.cc +++ /dev/null @@ -1,589 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#include "rust-early-name-resolver.h" -#include "rust-pattern.h" -#include "rust-name-resolver.h" -#include "rust-macro-builtins.h" -#include "rust-attribute-values.h" - -namespace Rust { -namespace Resolver { - -// Check if a module contains the `#[macro_use]` attribute -static bool -is_macro_use_module (const AST::Module &mod) -{ - for (const auto &attr : mod.get_outer_attrs ()) - if (attr.get_path ().as_string () == Values::Attributes::MACRO_USE) - return true; - - return false; -} - -std::vector> -EarlyNameResolver::accumulate_escaped_macros (AST::Module &module) -{ - if (!is_macro_use_module (module)) - return {}; - - // Parse the module's items if they haven't been expanded and the file - // should be parsed (i.e isn't hidden behind an untrue or impossible cfg - // directive) - if (module.get_kind () == AST::Module::UNLOADED) - module.load_items (); - - std::vector> escaped_macros; - - scoped (module.get_node_id (), [&module, &escaped_macros, this] { - for (auto &item : module.get_items ()) - { - if (item->get_item_kind () == AST::Item::Kind::Module) - { - auto &module = *static_cast (item.get ()); - auto new_macros = accumulate_escaped_macros (module); - - std::move (new_macros.begin (), new_macros.end (), - std::back_inserter (escaped_macros)); - - continue; - } - - if (item->get_item_kind () == AST::Item::Kind::MacroRulesDefinition) - escaped_macros.emplace_back (item->clone_item ()); - } - }); - - return escaped_macros; -} - -EarlyNameResolver::EarlyNameResolver () - : current_scope (UNKNOWN_NODEID), resolver (*Resolver::get ()), - mappings (Analysis::Mappings::get ()) -{} - -void -EarlyNameResolver::go (AST::Crate &crate) -{ - visit (crate); -} - -void -EarlyNameResolver::resolve_generic_args (AST::GenericArgs &generic_args) -{ - for (auto &arg : generic_args.get_generic_args ()) - arg.accept_vis (*this); - - for (auto &arg : generic_args.get_binding_args ()) - arg.get_type ().accept_vis (*this); -} - -void -EarlyNameResolver::resolve_qualified_path_type (AST::QualifiedPathType &path) -{ - path.get_type ().accept_vis (*this); - - if (path.has_as_clause ()) - path.get_as_type_path ().accept_vis (*this); -} - -void -EarlyNameResolver::visit (AST::Crate &crate) -{ - std::vector> new_items; - auto items = crate.take_items (); - - scoped (crate.get_node_id (), [&items, &new_items, this] { - for (auto &&item : items) - { - auto new_macros = std::vector> (); - - if (item->get_item_kind () == AST::Item::Kind::Module) - new_macros = accumulate_escaped_macros ( - *static_cast (item.get ())); - - new_items.emplace_back (std::move (item)); - std::move (new_macros.begin (), new_macros.end (), - std::back_inserter (new_items)); - } - }); - - crate.set_items (std::move (new_items)); - - scoped (crate.get_node_id (), [&crate, this] () { - for (auto &item : crate.items) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::DelimTokenTree &) -{} - -void -EarlyNameResolver::visit (AST::AttrInputMetaItemContainer &) -{} - -void -EarlyNameResolver::visit (AST::IdentifierExpr &) -{} - -void -EarlyNameResolver::visit (AST::LifetimeParam &) -{} - -void -EarlyNameResolver::visit (AST::ConstGenericParam &) -{} - -// FIXME: ARTHUR: Do we need to perform macro resolution for paths as well? -// std::arch::asm!()? -void -EarlyNameResolver::visit (AST::PathInExpression &path) -{ - if (!path.is_lang_item ()) - for (auto &segment : path.get_segments ()) - if (segment.has_generic_args ()) - resolve_generic_args (segment.get_generic_args ()); -} - -void -EarlyNameResolver::visit (AST::TypePathSegmentGeneric &segment) -{ - if (segment.has_generic_args ()) - resolve_generic_args (segment.get_generic_args ()); -} - -void -EarlyNameResolver::visit (AST::QualifiedPathInExpression &path) -{ - resolve_qualified_path_type (path.get_qualified_path_type ()); - - for (auto &segment : path.get_segments ()) - if (segment.has_generic_args ()) - resolve_generic_args (segment.get_generic_args ()); -} - -void -EarlyNameResolver::visit (AST::QualifiedPathInType &path) -{ - resolve_qualified_path_type (path.get_qualified_path_type ()); - - for (auto &segment : path.get_segments ()) - segment->accept_vis (*this); -} - -void -EarlyNameResolver::visit (AST::LiteralExpr &) -{} - -void -EarlyNameResolver::visit (AST::AttrInputLiteral &) -{} - -void -EarlyNameResolver::visit (AST::AttrInputMacro &) -{} - -void -EarlyNameResolver::visit (AST::MetaItemLitExpr &) -{} - -void -EarlyNameResolver::visit (AST::MetaItemPathExpr &) -{} - -void -EarlyNameResolver::visit (AST::StructExprStruct &) -{} - -void -EarlyNameResolver::visit (AST::StructExprFieldIdentifier &) -{} - -void -EarlyNameResolver::visit (AST::StructExprStructBase &) -{} - -void -EarlyNameResolver::visit (AST::BlockExpr &expr) -{ - scoped (expr.get_node_id (), [&expr, this] () { - for (auto &stmt : expr.get_statements ()) - stmt->accept_vis (*this); - - if (expr.has_tail_expr ()) - expr.get_tail_expr ().accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::ContinueExpr &) -{} - -void -EarlyNameResolver::visit (AST::RangeFullExpr &) -{} - -void -EarlyNameResolver::visit (AST::ForLoopExpr &expr) -{ - scoped (expr.get_node_id (), [&expr, this] () { - expr.get_pattern ().accept_vis (*this); - expr.get_iterator_expr ().accept_vis (*this); - expr.get_loop_block ().accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::IfLetExpr &expr) -{ - expr.get_value_expr ().accept_vis (*this); - - scoped (expr.get_node_id (), - [&expr, this] () { expr.get_if_block ().accept_vis (*this); }); -} - -void -EarlyNameResolver::visit (AST::MatchExpr &expr) -{ - expr.get_scrutinee_expr ().accept_vis (*this); - - scoped (expr.get_node_id (), [&expr, this] () { - for (auto &arm : expr.get_match_cases ()) - { - scoped (arm.get_node_id (), [&arm, this] () { - if (arm.get_arm ().has_match_arm_guard ()) - arm.get_arm ().get_guard_expr ().accept_vis (*this); - - for (auto &pattern : arm.get_arm ().get_patterns ()) - pattern->accept_vis (*this); - - arm.get_expr ().accept_vis (*this); - }); - } - }); -} - -void -EarlyNameResolver::visit (AST::LifetimeWhereClauseItem &) -{} - -void -EarlyNameResolver::visit (AST::Module &module) -{ - if (module.get_kind () == AST::Module::UNLOADED) - module.load_items (); - - // so we need to only go "one scope down" for fetching macros. Macros within - // functions are still scoped only within that function. But we have to be - // careful because nested modules with #[macro_use] actually works! - std::vector> new_items; - auto items = module.take_items (); - - scoped (module.get_node_id (), [&items, &new_items, this] { - for (auto &&item : items) - { - auto new_macros = std::vector> (); - - if (item->get_item_kind () == AST::Item::Kind::Module) - new_macros = accumulate_escaped_macros ( - *static_cast (item.get ())); - - new_items.emplace_back (std::move (item)); - std::move (new_macros.begin (), new_macros.end (), - std::back_inserter (new_items)); - } - }); - - module.set_items (std::move (new_items)); - - scoped (module.get_node_id (), [&module, this] () { - for (auto &item : module.get_items ()) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::ExternCrate &) -{} - -void -EarlyNameResolver::visit (AST::UseTreeGlob &) -{} - -void -EarlyNameResolver::visit (AST::UseTreeList &) -{} - -void -EarlyNameResolver::visit (AST::UseTreeRebind &) -{} - -void -EarlyNameResolver::visit (AST::UseDeclaration &) -{} - -void -EarlyNameResolver::visit (AST::EnumItem &) -{} - -void -EarlyNameResolver::visit (AST::Union &) -{} - -void -EarlyNameResolver::visit (AST::TraitItemType &) -{} - -void -EarlyNameResolver::visit (AST::Trait &trait) -{ - // shouldn't need to visit trait.get_implicit_self () - - for (auto &generic : trait.get_generic_params ()) - generic->accept_vis (*this); - - scoped (trait.get_node_id (), [&trait, this] () { - for (auto &item : trait.get_trait_items ()) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::InherentImpl &impl) -{ - impl.get_type ().accept_vis (*this); - - for (auto &generic : impl.get_generic_params ()) - generic->accept_vis (*this); - - scoped (impl.get_node_id (), [&impl, this] () { - for (auto &item : impl.get_impl_items ()) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::TraitImpl &impl) -{ - impl.get_type ().accept_vis (*this); - - for (auto &generic : impl.get_generic_params ()) - generic->accept_vis (*this); - - scoped (impl.get_node_id (), [&impl, this] () { - for (auto &item : impl.get_impl_items ()) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::ExternalTypeItem &item) -{ - // nothing to do? -} - -void -EarlyNameResolver::visit (AST::ExternBlock &block) -{ - scoped (block.get_node_id (), [&block, this] () { - for (auto &item : block.get_extern_items ()) - item->accept_vis (*this); - }); -} - -void -EarlyNameResolver::visit (AST::MacroMatchRepetition &) -{} - -void -EarlyNameResolver::visit (AST::MacroMatcher &) -{} - -void -EarlyNameResolver::visit (AST::MacroRulesDefinition &rules_def) -{ - auto path = CanonicalPath::new_seg (rules_def.get_node_id (), - rules_def.get_rule_name ().as_string ()); - resolver.get_macro_scope ().insert (path, rules_def.get_node_id (), - rules_def.get_locus ()); - - /* Since the EarlyNameResolver runs multiple time (fixed point algorithm) - * we could be inserting the same macro def over and over again until we - * implement some optimizations */ - // FIXME: ARTHUR: Remove that lookup and add proper optimizations instead - if (mappings.lookup_macro_def (rules_def.get_node_id ())) - return; - - mappings.insert_macro_def (&rules_def); - rust_debug_loc (rules_def.get_locus (), "inserting macro def: [%s]", - path.get ().c_str ()); -} - -void -EarlyNameResolver::visit (AST::MacroInvocation &invoc) -{ - auto &invoc_data = invoc.get_invoc_data (); - auto has_semicolon = invoc.has_semicolon (); - - if (invoc.get_kind () == AST::MacroInvocation::InvocKind::Builtin) - for (auto &pending_invoc : invoc.get_pending_eager_invocations ()) - pending_invoc->accept_vis (*this); - - // ?? - // switch on type of macro: - // - '!' syntax macro (inner switch) - // - procedural macro - "A token-based function-like macro" - // - 'macro_rules' (by example/pattern-match) macro? or not? "an - // AST-based function-like macro" - // - else is unreachable - // - attribute syntax macro (inner switch) - // - procedural macro attribute syntax - "A token-based attribute - // macro" - // - legacy macro attribute syntax? - "an AST-based attribute macro" - // - non-macro attribute: mark known - // - else is unreachable - // - derive macro (inner switch) - // - derive or legacy derive - "token-based" vs "AST-based" - // - else is unreachable - // - derive container macro - unreachable - - // lookup the rules for this macro - NodeId resolved_node = UNKNOWN_NODEID; - NodeId source_node = UNKNOWN_NODEID; - if (has_semicolon) - source_node = invoc.get_macro_node_id (); - else - source_node = invoc.get_node_id (); - auto seg - = CanonicalPath::new_seg (source_node, invoc_data.get_path ().as_string ()); - - bool found = resolver.get_macro_scope ().lookup (seg, &resolved_node); - if (!found) - { - rust_error_at (invoc.get_locus (), ErrorCode::E0433, - "could not resolve macro invocation %qs", - seg.get ().c_str ()); - return; - } - - // lookup the rules - auto rules_def = mappings.lookup_macro_def (resolved_node); - - auto &outer_attrs = rules_def.value ()->get_outer_attrs (); - bool is_builtin - = std::any_of (outer_attrs.begin (), outer_attrs.end (), - [] (AST::Attribute attr) { - return attr.get_path () - == Values::Attributes::RUSTC_BUILTIN_MACRO; - }); - - if (is_builtin) - { - auto builtin_kind = builtin_macro_from_string ( - rules_def.value ()->get_rule_name ().as_string ()); - invoc.map_to_builtin (builtin_kind.value ()); - } - - auto attributes = rules_def.value ()->get_outer_attrs (); - - /* Since the EarlyNameResolver runs multiple time (fixed point algorithm) - * we could be inserting the same macro def over and over again until we - * implement some optimizations */ - // FIXME: ARTHUR: Remove that lookup and add proper optimizations instead - if (mappings.lookup_macro_invocation (invoc)) - return; - - mappings.insert_macro_invocation (invoc, *rules_def); -} - -// FIXME: ARTHUR: Do we need to resolve these as well here? - -void -EarlyNameResolver::visit (AST::MetaItemPath &) -{} - -void -EarlyNameResolver::visit (AST::MetaItemSeq &) -{} - -void -EarlyNameResolver::visit (AST::MetaNameValueStr &) -{} - -void -EarlyNameResolver::visit (AST::MetaListPaths &) -{} - -void -EarlyNameResolver::visit (AST::MetaListNameValueStr &) -{} - -void -EarlyNameResolver::visit (AST::RangePatternBoundLiteral &) -{} - -void -EarlyNameResolver::visit (AST::RangePatternBoundPath &) -{} - -void -EarlyNameResolver::visit (AST::RangePatternBoundQualPath &) -{} - -void -EarlyNameResolver::visit (AST::StructPatternFieldIdent &) -{} - -void -EarlyNameResolver::visit (AST::StructPattern &) -{} - -void -EarlyNameResolver::visit (AST::TupleStructPattern &pattern) -{ - pattern.get_items ().accept_vis (*this); -} - -void -EarlyNameResolver::visit (AST::TupleType &) -{} - -void -EarlyNameResolver::visit (AST::RawPointerType &) -{} - -void -EarlyNameResolver::visit (AST::ReferenceType &) -{} - -void -EarlyNameResolver::visit (AST::ArrayType &) -{} - -void -EarlyNameResolver::visit (AST::SliceType &) -{} - -void -EarlyNameResolver::visit (AST::InferredType &) -{} - -} // namespace Resolver -} // namespace Rust diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h deleted file mode 100644 index d3c522556ca7..000000000000 --- a/gcc/rust/resolve/rust-early-name-resolver.h +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright (C) 2020-2025 Free Software Foundation, Inc. - -// This file is part of GCC. - -// GCC is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3, or (at your option) any later -// version. - -// GCC is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. - -// You should have received a copy of the GNU General Public License -// along with GCC; see the file COPYING3. If not see -// . - -#ifndef RUST_EARLY_NAME_RESOLVER_H -#define RUST_EARLY_NAME_RESOLVER_H - -#include "rust-name-resolver.h" -#include "rust-system.h" -#include "rust-ast.h" -#include "rust-ast-visitor.h" - -namespace Rust { -namespace Resolver { - -class EarlyNameResolver : public AST::DefaultASTVisitor -{ -public: - EarlyNameResolver (); - - void go (AST::Crate &crate); - -private: - using AST::DefaultASTVisitor::visit; - - /** - * Execute a lambda within a scope. This is equivalent to calling - * `enter_scope` before your code and `exit_scope` after. This ensures - * no errors can be committed - */ - void scoped (NodeId scope_id, std::function fn) - { - auto old_scope = current_scope; - current_scope = scope_id; - resolver.get_macro_scope ().push (scope_id); - resolver.push_new_macro_rib (resolver.get_macro_scope ().peek ()); - - fn (); - - resolver.get_macro_scope ().pop (); - current_scope = old_scope; - } - - /** - * Accumulate all of the nested macros which escape their module through the - * use of the #[macro_use] attribute. - * - * This function recursively accumulates macros in all of the nested modules - * of an item container (an AST::Crate or an AST::Module) and returns this new - * list of items. You can then use the `take_items` and `set_items` functions - * on these containers to replace their list of items. - */ - std::vector> - accumulate_escaped_macros (AST::Module &module); - - /** - * The "scope" we are currently in. - * - * This involves lexical scopes: - * - * ```rust - * // current_scope = crate_id; - * macro_rules! foo { () => {} ) - * - * { - * // current_scope = current_block_id; - * macro_rules! foo { () => { something!(); } } - * } - * // current_scope = crate_id; - * ``` - * - * as well as any sort of scope-like structure that might impact import name - * resolution or macro name resolution: - * - * ```rust - * macro_rules! foo { - * () => { fn empty() {} } - * } - * - * - * trait Foo { - * fn foo() { - * fn inner_foo() { - * macro_rules! foo { () => {} ) - * - * foo!(); - * } - * - * foo!(); - * } - * - * foo!(); - * } - * - * foo!(); - * ``` - */ - NodeId current_scope; - - /* The crate's scope */ - NodeId crate_scope; - - Resolver &resolver; - Analysis::Mappings &mappings; - - /** - * Early name-resolve generic args, which can be macro invocations - */ - void resolve_generic_args (AST::GenericArgs &generic_args); - - /** - * Early name-resolve a qualified path type, which can contain macro - * invocations - */ - void resolve_qualified_path_type (AST::QualifiedPathType &path); - - virtual void visit (AST::Crate &crate); - virtual void visit (AST::DelimTokenTree &delim_tok_tree); - virtual void visit (AST::AttrInputMetaItemContainer &input); - virtual void visit (AST::IdentifierExpr &ident_expr); - virtual void visit (AST::LifetimeParam &lifetime_param); - virtual void visit (AST::ConstGenericParam &const_param); - virtual void visit (AST::PathInExpression &path); - virtual void visit (AST::TypePathSegmentGeneric &segment); - virtual void visit (AST::QualifiedPathInExpression &path); - virtual void visit (AST::QualifiedPathInType &path); - virtual void visit (AST::LiteralExpr &expr); - virtual void visit (AST::AttrInputLiteral &attr_input); - virtual void visit (AST::AttrInputMacro &attr_input); - virtual void visit (AST::MetaItemLitExpr &meta_item); - virtual void visit (AST::MetaItemPathExpr &meta_item); - virtual void visit (AST::StructExprStruct &expr); - virtual void visit (AST::StructExprFieldIdentifier &field); - virtual void visit (AST::StructExprStructBase &expr); - virtual void visit (AST::BlockExpr &expr); - virtual void visit (AST::ContinueExpr &expr); - virtual void visit (AST::RangeFullExpr &expr); - virtual void visit (AST::ForLoopExpr &expr); - virtual void visit (AST::IfLetExpr &expr); - virtual void visit (AST::MatchExpr &expr); - virtual void visit (AST::LifetimeWhereClauseItem &item); - virtual void visit (AST::Module &module); - virtual void visit (AST::ExternCrate &crate); - virtual void visit (AST::UseTreeGlob &use_tree); - virtual void visit (AST::UseTreeList &use_tree); - virtual void visit (AST::UseTreeRebind &use_tree); - virtual void visit (AST::UseDeclaration &use_decl); - virtual void visit (AST::EnumItem &item); - virtual void visit (AST::Union &union_item); - virtual void visit (AST::TraitItemType &item); - virtual void visit (AST::Trait &trait); - virtual void visit (AST::InherentImpl &impl); - virtual void visit (AST::TraitImpl &impl); - virtual void visit (AST::ExternalTypeItem &item); - virtual void visit (AST::ExternBlock &block); - virtual void visit (AST::MacroMatchRepetition &match); - virtual void visit (AST::MacroMatcher &matcher); - virtual void visit (AST::MacroRulesDefinition &rules_def); - virtual void visit (AST::MacroInvocation ¯o_invoc); - virtual void visit (AST::MetaItemPath &meta_item); - virtual void visit (AST::MetaItemSeq &meta_item); - virtual void visit (AST::MetaNameValueStr &meta_item); - virtual void visit (AST::MetaListPaths &meta_item); - virtual void visit (AST::MetaListNameValueStr &meta_item); - virtual void visit (AST::RangePatternBoundLiteral &bound); - virtual void visit (AST::RangePatternBoundPath &bound); - virtual void visit (AST::RangePatternBoundQualPath &bound); - virtual void visit (AST::StructPatternFieldIdent &field); - virtual void visit (AST::StructPattern &pattern); - virtual void visit (AST::TupleStructPattern &pattern); - virtual void visit (AST::TupleType &type); - virtual void visit (AST::RawPointerType &type); - virtual void visit (AST::ReferenceType &type); - virtual void visit (AST::ArrayType &type); - virtual void visit (AST::SliceType &type); - virtual void visit (AST::InferredType &type); -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_EARLY_NAME_RESOLVER_H diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc index dddaa0793010..b6b3a0a5d9bc 100644 --- a/gcc/rust/resolve/rust-name-resolver.cc +++ b/gcc/rust/resolve/rust-name-resolver.cc @@ -19,9 +19,6 @@ #include "rust-name-resolver.h" #include "rust-ast-full.h" -// for flag_name_resolution_2_0 -#include "options.h" - namespace Rust { namespace Resolver { @@ -275,412 +272,5 @@ Scope::decl_was_declared_here (NodeId def) const return found; } -Resolver::Resolver () - : mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()), - name_scope (Scope (mappings.get_current_crate ())), - type_scope (Scope (mappings.get_current_crate ())), - label_scope (Scope (mappings.get_current_crate ())), - macro_scope (Scope (mappings.get_current_crate ())), - global_type_node_id (UNKNOWN_NODEID), unit_ty_node_id (UNKNOWN_NODEID) -{ - generate_builtins (); -} - -Resolver * -Resolver::get () -{ - static Resolver *instance; - if (instance == nullptr) - instance = new Resolver (); - - return instance; -} - -void -Resolver::push_new_name_rib (Rib *r) -{ - rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ()); - name_ribs[r->get_node_id ()] = r; -} - -void -Resolver::push_new_type_rib (Rib *r) -{ - if (type_ribs.size () == 0) - global_type_node_id = r->get_node_id (); - - rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ()); - type_ribs[r->get_node_id ()] = r; -} - -void -Resolver::push_new_label_rib (Rib *r) -{ - rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ()); - label_ribs[r->get_node_id ()] = r; -} - -void -Resolver::push_new_macro_rib (Rib *r) -{ - rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ()); - macro_ribs[r->get_node_id ()] = r; -} - -bool -Resolver::find_name_rib (NodeId id, Rib **rib) -{ - auto it = name_ribs.find (id); - if (it == name_ribs.end ()) - return false; - - *rib = it->second; - return true; -} - -bool -Resolver::find_type_rib (NodeId id, Rib **rib) -{ - auto it = type_ribs.find (id); - if (it == type_ribs.end ()) - return false; - - *rib = it->second; - return true; -} - -bool -Resolver::find_macro_rib (NodeId id, Rib **rib) -{ - auto it = macro_ribs.find (id); - if (it == macro_ribs.end ()) - return false; - - *rib = it->second; - return true; -} - -void -Resolver::insert_builtin_types (Rib *r) -{ - auto builtins = get_builtin_types (); - for (auto &builtin : builtins) - { - CanonicalPath builtin_path - = CanonicalPath::new_seg (builtin->get_node_id (), - builtin->as_string ()); - r->insert_name (builtin_path, builtin->get_node_id (), BUILTINS_LOCATION, - false, Rib::ItemType::Type, - [] (const CanonicalPath &, NodeId, location_t) -> void { - }); - } -} - -std::vector & -Resolver::get_builtin_types () -{ - return builtins; -} - -void -Resolver::generate_builtins () -{ - auto u8 - = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U8); - auto u16 - = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U16); - auto u32 - = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U32); - auto u64 - = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U64); - auto u128 - = new TyTy::UintType (mappings.get_next_hir_id (), TyTy::UintType::U128); - auto i8 = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I8); - auto i16 - = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I16); - auto i32 - = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I32); - auto i64 - = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I64); - auto i128 - = new TyTy::IntType (mappings.get_next_hir_id (), TyTy::IntType::I128); - auto rbool = new TyTy::BoolType (mappings.get_next_hir_id ()); - auto f32 - = new TyTy::FloatType (mappings.get_next_hir_id (), TyTy::FloatType::F32); - auto f64 - = new TyTy::FloatType (mappings.get_next_hir_id (), TyTy::FloatType::F64); - auto usize = new TyTy::USizeType (mappings.get_next_hir_id ()); - auto isize = new TyTy::ISizeType (mappings.get_next_hir_id ()); - auto char_tyty = new TyTy::CharType (mappings.get_next_hir_id ()); - auto str = new TyTy::StrType (mappings.get_next_hir_id ()); - auto never = new TyTy::NeverType (mappings.get_next_hir_id ()); - - setup_builtin ("u8", u8); - setup_builtin ("u16", u16); - setup_builtin ("u32", u32); - setup_builtin ("u64", u64); - setup_builtin ("u128", u128); - setup_builtin ("i8", i8); - setup_builtin ("i16", i16); - setup_builtin ("i32", i32); - setup_builtin ("i64", i64); - setup_builtin ("i128", i128); - setup_builtin ("bool", rbool); - setup_builtin ("f32", f32); - setup_builtin ("f64", f64); - setup_builtin ("usize", usize); - setup_builtin ("isize", isize); - setup_builtin ("char", char_tyty); - setup_builtin ("str", str); - - // never type - NodeId never_node_id = setup_builtin ("!", never); - set_never_type_node_id (never_node_id); - - // unit type () - TyTy::TupleType *unit_tyty = TyTy::TupleType::get_unit_type (); - std::vector > elems; - AST::TupleType *unit_type - = new AST::TupleType (std::move (elems), BUILTINS_LOCATION); - builtins.push_back (unit_type); - tyctx->insert_builtin (unit_tyty->get_ref (), unit_type->get_node_id (), - unit_tyty); - set_unit_type_node_id (unit_type->get_node_id ()); -} - -NodeId -Resolver::setup_builtin (const std::string &name, TyTy::BaseType *tyty) -{ - AST::PathIdentSegment seg (name, BUILTINS_LOCATION); - auto typePath = ::std::unique_ptr ( - new AST::TypePathSegment (::std::move (seg), false, BUILTINS_LOCATION)); - ::std::vector< ::std::unique_ptr > segs; - segs.push_back (::std::move (typePath)); - auto builtin_type - = new AST::TypePath (::std::move (segs), BUILTINS_LOCATION, false); - builtins.push_back (builtin_type); - tyctx->insert_builtin (tyty->get_ref (), builtin_type->get_node_id (), tyty); - mappings.insert_node_to_hir (builtin_type->get_node_id (), tyty->get_ref ()); - mappings.insert_canonical_path ( - builtin_type->get_node_id (), - CanonicalPath::new_seg (builtin_type->get_node_id (), name)); - - return builtin_type->get_node_id (); -} - -void -Resolver::insert_resolved_name (NodeId refId, NodeId defId) -{ - rust_assert (!flag_name_resolution_2_0); - rust_assert (resolved_names.find (refId) == resolved_names.end ()); - - resolved_names[refId] = defId; - get_name_scope ().append_reference_for_def (refId, defId); - insert_captured_item (defId); -} - -bool -Resolver::lookup_resolved_name (NodeId refId, NodeId *defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_names.find (refId); - if (it == resolved_names.end ()) - return false; - - *defId = it->second; - return true; -} - -void -Resolver::insert_resolved_type (NodeId refId, NodeId defId) -{ - rust_assert (!flag_name_resolution_2_0); - rust_assert (resolved_types.find (refId) == resolved_types.end ()); - - resolved_types[refId] = defId; - get_type_scope ().append_reference_for_def (refId, defId); -} - -bool -Resolver::lookup_resolved_type (NodeId refId, NodeId *defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_types.find (refId); - if (it == resolved_types.end ()) - return false; - - *defId = it->second; - return true; -} - -void -Resolver::insert_resolved_label (NodeId refId, NodeId defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_labels.find (refId); - rust_assert (it == resolved_labels.end ()); - - resolved_labels[refId] = defId; - get_label_scope ().append_reference_for_def (refId, defId); -} - -bool -Resolver::lookup_resolved_label (NodeId refId, NodeId *defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_labels.find (refId); - if (it == resolved_labels.end ()) - return false; - - *defId = it->second; - return true; -} - -void -Resolver::insert_resolved_macro (NodeId refId, NodeId defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_macros.find (refId); - rust_assert (it == resolved_macros.end ()); - - resolved_labels[refId] = defId; - get_label_scope ().append_reference_for_def (refId, defId); -} - -bool -Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = resolved_macros.find (refId); - if (it == resolved_macros.end ()) - return false; - - *defId = it->second; - return true; -} - -void -Resolver::insert_resolved_misc (NodeId refId, NodeId defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = misc_resolved_items.find (refId); - rust_assert (it == misc_resolved_items.end ()); - - misc_resolved_items[refId] = defId; -} - -bool -Resolver::lookup_resolved_misc (NodeId refId, NodeId *defId) -{ - rust_assert (!flag_name_resolution_2_0); - auto it = misc_resolved_items.find (refId); - if (it == misc_resolved_items.end ()) - return false; - - *defId = it->second; - return true; -} - -void -Resolver::push_closure_context (NodeId closure_expr_id) -{ - auto it = closures_capture_mappings.find (closure_expr_id); - rust_assert (it == closures_capture_mappings.end ()); - - closures_capture_mappings.insert ({closure_expr_id, {}}); - closure_context.push_back (closure_expr_id); -} - -void -Resolver::pop_closure_context () -{ - rust_assert (!closure_context.empty ()); - closure_context.pop_back (); -} - -void -Resolver::insert_captured_item (NodeId id) -{ - // nothing to do unless we are in a closure context - if (closure_context.empty ()) - return; - - // check that this is a VAR_DECL? - Scope &name_scope = get_name_scope (); - Rib::ItemType type = Rib::ItemType::Unknown; - bool found = name_scope.lookup_decl_type (id, &type); - if (!found) - return; - - // RIB Function { let a, let b } id = 1; - // RIB Closure { let c } id = 2; - // RIB IfStmt { } id = 3; - // RIB ... { ... } id = 4 - // - // if we have a resolved_node_id of 'a' and the current rib is '3' we know - // this is binding exists in a rib with id < the closure rib id, other wise - // its just a normal binding and we don't care - // - // Problem the node id's dont work like this because the inner most items are - // created first so this means the root will have a larger id and a simple - // less than or greater than check wont work for more complex scoping cases - // but we can use our current rib context to figure this out by checking if - // the rib id the decl we care about exists prior to the rib for the closure - // id - - const Rib *r = nullptr; - bool ok = name_scope.lookup_rib_for_decl (id, &r); - rust_assert (ok); - NodeId decl_rib_node_id = r->get_node_id (); - - // iterate the closure context and add in the mapping for all to handle the - // case of nested closures - for (auto &closure_expr_id : closure_context) - { - if (!decl_needs_capture (decl_rib_node_id, closure_expr_id, name_scope)) - continue; - - // is this a valid binding to take - bool is_var_decl_p = type == Rib::ItemType::Var; - if (!is_var_decl_p) - { - // FIXME is this an error case? - return; - } - - // append it to the context info - auto it = closures_capture_mappings.find (closure_expr_id); - rust_assert (it != closures_capture_mappings.end ()); - - it->second.insert (id); - } -} - -bool -Resolver::decl_needs_capture (NodeId decl_rib_node_id, - NodeId closure_rib_node_id, const Scope &scope) -{ - for (const auto &rib : scope.get_context ()) - { - bool rib_is_closure = rib->get_node_id () == closure_rib_node_id; - bool rib_is_decl = rib->get_node_id () == decl_rib_node_id; - if (rib_is_closure) - return false; - else if (rib_is_decl) - return true; - } - return false; -} - -const std::set & -Resolver::get_captures (NodeId id) const -{ - rust_assert (!flag_name_resolution_2_0); - - auto it = closures_capture_mappings.find (id); - rust_assert (it != closures_capture_mappings.end ()); - return it->second; -} - } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index a3b34a9f1600..c336d3d75e11 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -118,181 +118,6 @@ class Scope std::vector stack; }; -class Resolver -{ -public: - static Resolver *get (); - ~Resolver () {} - - // these builtin types - void insert_builtin_types (Rib *r); - - // these will be required for type resolution passes to - // map back to tyty nodes - std::vector &get_builtin_types (); - - void push_new_name_rib (Rib *r); - void push_new_type_rib (Rib *r); - void push_new_label_rib (Rib *r); - void push_new_macro_rib (Rib *r); - - bool find_name_rib (NodeId id, Rib **rib); - bool find_type_rib (NodeId id, Rib **rib); - bool find_label_rib (NodeId id, Rib **rib); - bool find_macro_rib (NodeId id, Rib **rib); - - void insert_resolved_name (NodeId refId, NodeId defId); - bool lookup_resolved_name (NodeId refId, NodeId *defId); - - void insert_resolved_type (NodeId refId, NodeId defId); - bool lookup_resolved_type (NodeId refId, NodeId *defId); - - void insert_resolved_label (NodeId refId, NodeId defId); - bool lookup_resolved_label (NodeId refId, NodeId *defId); - - void insert_resolved_macro (NodeId refId, NodeId defId); - bool lookup_resolved_macro (NodeId refId, NodeId *defId); - - void insert_resolved_misc (NodeId refId, NodeId defId); - bool lookup_resolved_misc (NodeId refId, NodeId *defId); - - // proxy for scoping - Scope &get_name_scope () { return name_scope; } - Scope &get_type_scope () { return type_scope; } - Scope &get_label_scope () { return label_scope; } - Scope &get_macro_scope () { return macro_scope; } - - NodeId get_global_type_node_id () { return global_type_node_id; } - - void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; } - NodeId get_unit_type_node_id () { return unit_ty_node_id; } - - void set_never_type_node_id (NodeId id) { never_ty_node_id = id; } - NodeId get_never_type_node_id () { return never_ty_node_id; } - - void push_new_module_scope (NodeId module_id) - { - current_module_stack.push_back (module_id); - } - - void pop_module_scope () - { - rust_assert (!current_module_stack.empty ()); - current_module_stack.pop_back (); - } - - NodeId peek_current_module_scope () const - { - rust_assert (!current_module_stack.empty ()); - 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); - } - - void push_closure_context (NodeId closure_expr_id); - void pop_closure_context (); - void insert_captured_item (NodeId id); - const std::set &get_captures (NodeId id) const; - - std::string as_debug_string () const - { - std::stringstream ss; - - ss << "Names:\n"; - for (auto &n : name_ribs) - { - ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str () - << "\n"; - } - ss << "Types:\n"; - for (auto &n : type_ribs) - { - ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str () - << "\n"; - } - ss << "Macros:\n"; - - for (auto &n : macro_ribs) - { - ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str () - << "\n"; - } - - ss << "Labels:\n"; - - for (auto &n : label_ribs) - { - ss << "\tNodeID: " << n.first << " Rib: " << n.second->debug_str () - << "\n"; - } - - return ss.str (); - } - -protected: - bool decl_needs_capture (NodeId decl_rib_node_id, NodeId closure_rib_node_id, - const Scope &scope); - -private: - Resolver (); - - void generate_builtins (); - NodeId setup_builtin (const std::string &name, TyTy::BaseType *tyty); - - Analysis::Mappings &mappings; - TypeCheckContext *tyctx; - - std::vector builtins; - - Scope name_scope; - Scope type_scope; - Scope label_scope; - Scope macro_scope; - - NodeId global_type_node_id; - NodeId unit_ty_node_id; - NodeId never_ty_node_id; - - // map a AST Node to a Rib - std::map name_ribs; - std::map type_ribs; - std::map label_ribs; - std::map macro_ribs; - - // 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 - // with gcc very well to compile a full crate in one go but we will - // see. - - // these are of the form ref->Def-NodeId - // we need two namespaces one for names and ones for types - std::map resolved_names; - std::map resolved_types; - std::map resolved_labels; - std::map resolved_macros; - - // misc - std::map misc_resolved_items; - - // keep track of the current module scope ids - std::vector current_module_stack; - - // captured variables mappings - std::vector closure_context; - std::map> closures_capture_mappings; -}; - } // namespace Resolver } // namespace Rust diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc index 93ce041c2529..1088845497ef 100644 --- a/gcc/rust/rust-lang.cc +++ b/gcc/rust/rust-lang.cc @@ -34,7 +34,6 @@ #include "selftest.h" #include "rust-cfg-parser.h" #include "rust-privacy-ctx.h" -#include "rust-ast-resolve-item.h" #include "rust-lex.h" #include "optional.h" #include "rust-unicode.h" @@ -442,7 +441,6 @@ run_rust_tests () rust_cfg_parser_test (); rust_privacy_ctx_test (); rust_crate_name_validation_test (); - rust_simple_path_resolve_test (); } } // namespace selftest diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index c88f46757535..e90dadf8d292 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -29,7 +29,6 @@ #include "rust-lex.h" #include "rust-parse.h" #include "rust-macro-expand.h" -#include "rust-ast-resolve.h" #include "rust-ast-lower.h" #include "rust-hir-type-check.h" #include "rust-privacy-check.h" @@ -46,7 +45,6 @@ #include "rust-imports.h" #include "rust-extern-crate.h" #include "rust-attributes.h" -#include "rust-early-name-resolver.h" #include "rust-name-resolution-context.h" #include "rust-early-name-resolver-2.0.h" #include "rust-late-name-resolver-2.0.h" @@ -643,10 +641,7 @@ Session::compile_crate (const char *filename) return; // resolution pipeline stage - if (flag_name_resolution_2_0) - Resolver2_0::Late (name_resolution_ctx).go (parsed_crate); - else - Resolver::NameResolution::Resolve (parsed_crate); + Resolver2_0::Late (name_resolution_ctx).go (parsed_crate); if (options.dump_option_enabled (CompileOptions::RESOLUTION_DUMP)) dump_name_resolution (name_resolution_ctx); @@ -940,24 +935,17 @@ Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx) { CfgStrip ().go (crate); // Errors might happen during cfg strip pass - bool visitor_dirty = false; - if (flag_name_resolution_2_0) - { - Resolver2_0::Early early (ctx); - early.go (crate); - macro_errors = early.get_macro_resolve_errors (); - visitor_dirty = early.is_dirty (); - } - else - Resolver::EarlyNameResolver ().go (crate); + Resolver2_0::Early early (ctx); + early.go (crate); + macro_errors = early.get_macro_resolve_errors (); if (saw_errors ()) break; ExpandVisitor (expander).go (crate); - fixed_point_reached = !expander.has_changed () && !visitor_dirty; + fixed_point_reached = !expander.has_changed () && !early.is_dirty (); expander.reset_changed_state (); iterations++; @@ -992,8 +980,7 @@ Session::expansion (AST::Crate &crate, Resolver2_0::NameResolutionContext &ctx) // HACK: we may need a final TopLevel pass // however, this should not count towards the recursion limit // and we don't need a full Early pass - if (flag_name_resolution_2_0) - Resolver2_0::TopLevel (ctx).go (crate); + Resolver2_0::TopLevel (ctx).go (crate); } // error reporting - check unused macros, get missing fragment specifiers @@ -1189,14 +1176,6 @@ Session::load_extern_crate (const std::string &crate_name, location_t locus) mappings.insert_bang_proc_macros (crate_num, bang_macros); mappings.insert_derive_proc_macros (crate_num, derive_macros); - // if flag_name_resolution_2_0 is enabled - // then we perform resolution later - if (!flag_name_resolution_2_0) - { - // name resolve it - Resolver::NameResolution::Resolve (parsed_crate); - } - // always restore the crate_num mappings.set_current_crate (saved_crate_num);