// 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-default-resolver.h" #include "rust-ast-full.h" #include "rust-ast-visitor.h" #include "rust-item.h" namespace Rust { namespace Resolver2_0 { void DefaultResolver::visit (AST::BlockExpr &expr) { // extracting the lambda from the `scoped` call otherwise the code looks like // a hot turd thanks to our .clang-format auto inner_fn = [this, &expr] () { for (auto &stmt : expr.get_statements ()) stmt->accept_vis (*this); if (expr.has_tail_expr ()) expr.get_tail_expr ().accept_vis (*this); }; ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn); } void DefaultResolver::visit (AST::Module &module) { auto item_fn = [this, &module] () { for (auto &item : module.get_items ()) item->accept_vis (*this); }; ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn, module.get_name ()); } void DefaultResolver::visit (AST::Function &function) { auto def_fn = [this, &function] () { for (auto &p : function.get_function_params ()) { if (p->is_variadic ()) { auto ¶m = static_cast (*p); if (param.has_pattern ()) param.get_pattern ().accept_vis (*this); } else if (p->is_self ()) { auto ¶m = static_cast (*p); param.get_type ().accept_vis (*this); param.get_lifetime ().accept_vis (*this); } else { auto ¶m = static_cast (*p); param.get_pattern ().accept_vis (*this); param.get_type ().accept_vis (*this); } } if (function.has_return_type ()) visit (function.get_return_type ()); if (function.has_body ()) function.get_definition ().value ()->accept_vis (*this); }; ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn); } void DefaultResolver::visit (AST::ForLoopExpr &expr) { ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), [this, &expr] () { expr.get_pattern ().accept_vis (*this); expr.get_iterator_expr ().accept_vis (*this); expr.get_loop_block ().accept_vis (*this); }); } void DefaultResolver::visit (AST::Trait &trait) { auto inner_fn = [this, &trait] () { for (auto &item : trait.get_trait_items ()) item->accept_vis (*this); }; ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn, trait.get_identifier () /* FIXME: Is that valid?*/); } void DefaultResolver::visit (AST::InherentImpl &impl) { auto inner_fn = [this, &impl] () { visit (impl.get_type ()); for (auto &item : impl.get_impl_items ()) item->accept_vis (*this); }; ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); } void DefaultResolver::visit (AST::TraitImpl &impl) { auto inner_fn = [this, &impl] () { for (auto &item : impl.get_impl_items ()) item->accept_vis (*this); }; ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn); } void DefaultResolver::visit (AST::StructStruct &type) { // do we need to scope anything here? no, right? // we also can't visit `StructField`s by default, so there's nothing to do - // correct? or should we do something like AST::DefaultASTVisitor::visit (type); // FIXME: ??? } void DefaultResolver::visit (AST::Enum &type) { // FIXME: Do we need to scope anything by default? auto variant_fn = [this, &type] () { for (auto &variant : type.get_variants ()) variant->accept_vis (*this); }; ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (), variant_fn, type.get_identifier ()); } void DefaultResolver::visit (AST::StructExprFieldIdentifierValue &) {} void DefaultResolver::visit (AST::StructExprFieldIndexValue &) {} void DefaultResolver::visit (AST::ClosureExprInner &expr) { if (expr.is_marked_for_strip ()) return; for (auto ¶m : expr.get_params ()) { if (param.is_error ()) continue; param.get_pattern ().accept_vis (*this); if (param.has_type_given ()) param.get_type ().accept_vis (*this); } expr.get_definition_expr ().accept_vis (*this); } void DefaultResolver::visit (AST::ClosureExprInnerTyped &expr) { if (expr.is_marked_for_strip ()) return; for (auto ¶m : expr.get_params ()) { if (param.is_error ()) continue; param.get_pattern ().accept_vis (*this); if (param.has_type_given ()) param.get_type ().accept_vis (*this); } expr.get_definition_block ().accept_vis (*this); expr.get_return_type ().accept_vis (*this); } void DefaultResolver::visit (AST::ContinueExpr &expr) {} void DefaultResolver::visit (AST::RangeFromToExpr &expr) {} void DefaultResolver::visit (AST::RangeFromExpr &expr) {} void DefaultResolver::visit (AST::RangeToExpr &expr) {} void DefaultResolver::visit (AST::RangeFromToInclExpr &expr) {} void DefaultResolver::visit (AST::RangeToInclExpr &expr) {} void DefaultResolver::visit (AST::ReturnExpr &expr) {} void DefaultResolver::visit (AST::CallExpr &expr) { expr.get_function_expr ().accept_vis (*this); for (auto ¶m : expr.get_params ()) param->accept_vis (*this); } void DefaultResolver::visit (AST::MethodCallExpr &expr) { expr.get_receiver_expr ().accept_vis (*this); if (expr.get_method_name ().has_generic_args ()) { auto &args = expr.get_method_name ().get_generic_args (); for (auto &arg : args.get_generic_args ()) arg.accept_vis (*this); for (auto &arg : args.get_binding_args ()) if (!arg.is_error ()) arg.get_type ().accept_vis (*this); for (auto &arg : args.get_lifetime_args ()) arg.accept_vis (*this); } for (auto ¶m : expr.get_params ()) param->accept_vis (*this); } void DefaultResolver::visit (AST::LoopExpr &expr) {} void DefaultResolver::visit (AST::WhileLoopExpr &expr) {} void DefaultResolver::visit (AST::WhileLetLoopExpr &expr) {} void DefaultResolver::visit (AST::IfExpr &expr) { expr.get_condition_expr ().accept_vis (*this); expr.get_if_block ().accept_vis (*this); } void DefaultResolver::visit (AST::IfExprConseqElse &expr) { expr.get_condition_expr ().accept_vis (*this); expr.get_if_block ().accept_vis (*this); expr.get_else_block ().accept_vis (*this); } void DefaultResolver::visit (AST::IfLetExpr &expr) {} void DefaultResolver::visit (AST::IfLetExprConseqElse &) {} void DefaultResolver::visit (AST::MatchExpr &expr) { if (expr.is_marked_for_strip ()) return; expr.get_scrutinee_expr ().accept_vis (*this); for (auto &arm : expr.get_match_cases ()) { arm.get_expr ().accept_vis (*this); for (auto &pat : arm.get_arm ().get_patterns ()) pat->accept_vis (*this); if (arm.get_arm ().has_match_arm_guard ()) arm.get_arm ().get_guard_expr ().accept_vis (*this); } } void DefaultResolver::visit (AST::AwaitExpr &expr) {} void DefaultResolver::visit (AST::AsyncBlockExpr &expr) {} void DefaultResolver::visit (AST::DelimTokenTree &) {} void DefaultResolver::visit (AST::AttrInputMetaItemContainer &) {} void DefaultResolver::visit (AST::IdentifierExpr &expr) {} void DefaultResolver::visit (AST::LifetimeParam &) {} void DefaultResolver::visit (AST::ConstGenericParam &) {} void DefaultResolver::visit (AST::PathInExpression &expr) { for (auto &seg : expr.get_segments ()) if (seg.has_generic_args ()) { auto &args = seg.get_generic_args (); for (auto &arg : args.get_generic_args ()) arg.accept_vis (*this); for (auto &arg : args.get_binding_args ()) if (!arg.is_error ()) arg.get_type ().accept_vis (*this); for (auto &arg : args.get_lifetime_args ()) arg.accept_vis (*this); } } void DefaultResolver::visit (AST::TypePathSegmentGeneric &) {} void DefaultResolver::visit (AST::TypePathSegmentFunction &) {} void DefaultResolver::visit (AST::TypePath &) {} void DefaultResolver::visit (AST::QualifiedPathInExpression &) {} void DefaultResolver::visit (AST::QualifiedPathInType &) {} void DefaultResolver::visit (AST::LiteralExpr &expr) {} void DefaultResolver::visit (AST::AttrInputLiteral &) {} void DefaultResolver::visit (AST::AttrInputMacro &) {} void DefaultResolver::visit (AST::MetaItemLitExpr &expr) {} void DefaultResolver::visit (AST::MetaItemPathLit &) {} void DefaultResolver::visit (AST::StructExprStruct &) {} void DefaultResolver::visit (AST::StructExprStructFields &) {} void DefaultResolver::visit (AST::StructExprStructBase &) {} void DefaultResolver::visit (AST::TypeParam &) {} void DefaultResolver::visit (AST::LifetimeWhereClauseItem &) {} void DefaultResolver::visit (AST::TypeBoundWhereClauseItem &) {} void DefaultResolver::visit (AST::ExternCrate &) {} void DefaultResolver::visit (AST::UseTreeGlob &) {} void DefaultResolver::visit (AST::UseTreeList &) {} void DefaultResolver::visit (AST::UseTreeRebind &) {} void DefaultResolver::visit (AST::UseDeclaration &) {} void DefaultResolver::visit (AST::TypeAlias &) {} void DefaultResolver::visit (AST::EnumItem &) {} void DefaultResolver::visit (AST::EnumItemTuple &item) { for (auto &field : item.get_tuple_fields ()) field.get_field_type ().accept_vis (*this); } void DefaultResolver::visit (AST::EnumItemStruct &item) { for (auto &field : item.get_struct_fields ()) field.get_field_type ().accept_vis (*this); } void DefaultResolver::visit (AST::EnumItemDiscriminant &item) { if (item.has_expr ()) item.get_expr ().accept_vis (*this); } void DefaultResolver::visit (AST::ConstantItem &item) { if (item.has_expr ()) { auto expr_vis = [this, &item] () { item.get_expr ().accept_vis (*this); visit (item.get_type ()); }; // FIXME: Why do we need a Rib here? ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis); } } void DefaultResolver::visit (AST::StaticItem &item) { auto expr_vis = [this, &item] () { item.get_expr ().accept_vis (*this); }; // FIXME: Why do we need a Rib here? ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis); } void DefaultResolver::visit (AST::TraitItemConst &) {} void DefaultResolver::visit (AST::TraitItemType &) {} void DefaultResolver::visit (AST::ExternalTypeItem &) {} void DefaultResolver::visit (AST::ExternalStaticItem &) {} void DefaultResolver::visit (AST::MacroMatchRepetition &) {} void DefaultResolver::visit (AST::MacroMatcher &) {} void DefaultResolver::visit (AST::MacroRulesDefinition &) {} void DefaultResolver::visit (AST::MacroInvocation &) {} void DefaultResolver::visit (AST::MetaItemPath &) {} void DefaultResolver::visit (AST::MetaItemSeq &) {} void DefaultResolver::visit (AST::MetaListPaths &) {} void DefaultResolver::visit (AST::MetaListNameValueStr &) {} void DefaultResolver::visit (AST::RangePatternBoundPath &) {} void DefaultResolver::visit (AST::RangePatternBoundQualPath &) {} void DefaultResolver::visit (AST::RangePattern &) {} void DefaultResolver::visit (AST::ReferencePattern &) {} void DefaultResolver::visit (AST::StructPatternFieldTuplePat &) {} void DefaultResolver::visit (AST::StructPatternFieldIdentPat &) {} void DefaultResolver::visit (AST::StructPatternFieldIdent &) {} void DefaultResolver::visit (AST::StructPattern &) {} void DefaultResolver::visit (AST::TupleStructItemsNoRange &) {} void DefaultResolver::visit (AST::TupleStructItemsRange &) {} void DefaultResolver::visit (AST::TupleStructPattern &) {} void DefaultResolver::visit (AST::TuplePatternItemsMultiple &) {} void DefaultResolver::visit (AST::TuplePatternItemsRanged &) {} void DefaultResolver::visit (AST::TuplePattern &) {} void DefaultResolver::visit (AST::GroupedPattern &) {} void DefaultResolver::visit (AST::SlicePattern &) {} void DefaultResolver::visit (AST::AltPattern &) {} void DefaultResolver::visit (AST::EmptyStmt &) {} void DefaultResolver::visit (AST::TraitBound &) {} void DefaultResolver::visit (AST::ImplTraitType &) {} void DefaultResolver::visit (AST::TraitObjectType &) {} void DefaultResolver::visit (AST::ParenthesisedType &) {} void DefaultResolver::visit (AST::ImplTraitTypeOneBound &) {} void DefaultResolver::visit (AST::TraitObjectTypeOneBound &) {} void DefaultResolver::visit (AST::TupleType &) {} void DefaultResolver::visit (AST::ReferenceType &) {} void DefaultResolver::visit (AST::ArrayType &) {} void DefaultResolver::visit (AST::SliceType &) {} void DefaultResolver::visit (AST::BareFunctionType &) {} void DefaultResolver::visit (AST::SelfParam &) {} void DefaultResolver::visit (AST::FunctionParam &) {} void DefaultResolver::visit (AST::VariadicParam &) {} } // namespace Resolver2_0 } // namespace Rust