aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/resolve
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/resolve')
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc691
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h238
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.cc816
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-expr.h105
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-implitem.h260
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc1247
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.h161
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.cc558
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-path.h52
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.cc419
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-pattern.h146
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.cc81
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h408
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.cc61
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-struct-expr-field.h54
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-toplevel.h500
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc785
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.h280
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc114
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.cc47
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver-2.0.h1
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.cc589
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.h196
-rw-r--r--gcc/rust/resolve/rust-forever-stack.hxx21
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.cc120
-rw-r--r--gcc/rust/resolve/rust-late-name-resolver-2.0.h3
-rw-r--r--gcc/rust/resolve/rust-resolve-builtins.cc125
-rw-r--r--gcc/rust/resolve/rust-resolve-builtins.h37
28 files changed, 245 insertions, 7870 deletions
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 3c7b425..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 89c5c35..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 &param);
- void visit (AST::VariadicParam &param);
- void visit (AST::SelfParam &param);
-
- 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 a410193..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 &param : 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 &param : 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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- 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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- 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<AST::IdentifierExpr &> (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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // 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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- 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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- 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 &param,
- std::vector<PatternBinding> &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 aad1605..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 &param,
- std::vector<PatternBinding> &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-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h
deleted file mode 100644
index 2081697..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ /dev/null
@@ -1,260 +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
-// <http://www.gnu.org/licenses/>.
-
-#ifndef RUST_AST_RESOLVE_IMPLITEM_H
-#define RUST_AST_RESOLVE_IMPLITEM_H
-
-#include "rust-ast-resolve-base.h"
-#include "rust-ast-resolve-type.h"
-#include "rust-ast-full.h"
-
-namespace Rust {
-namespace Resolver {
-
-class ResolveToplevelImplItem : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::AssociatedItem &item, const CanonicalPath &prefix)
- {
- if (item.is_marked_for_strip ())
- return;
-
- ResolveToplevelImplItem resolver (prefix);
- item.accept_vis (resolver);
- }
-
- void visit (AST::TypeAlias &type) override
- {
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_new_type_name ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
- }
-
- void visit (AST::ConstantItem &constant) override
- {
- auto decl = CanonicalPath::new_seg (constant.get_node_id (),
- constant.get_identifier ());
- auto path = 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);
- });
- }
-
- 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);
-
- 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);
- });
- }
-
-private:
- ResolveToplevelImplItem (const CanonicalPath &prefix)
- : ResolverBase (), prefix (prefix)
- {
- rust_assert (!prefix.is_empty ());
- }
-
- const CanonicalPath &prefix;
-};
-
-class ResolveTopLevelTraitItems : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::AssociatedItem *item, const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- {
- ResolveTopLevelTraitItems resolver (prefix, canonical_prefix);
- item->accept_vis (resolver);
- };
-
- 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);
- });
-
- mappings.insert_canonical_path (function.get_node_id (), cpath);
- }
-
- void visit (AST::TraitItemConst &constant) override
- {
- 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);
-
- 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);
- });
-
- mappings.insert_canonical_path (constant.get_node_id (), cpath);
- }
-
- void visit (AST::TraitItemType &type) override
- {
- 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);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.get_locus ());
- r.add_range (locus);
- redefined_error (r);
- });
-
- mappings.insert_canonical_path (type.get_node_id (), cpath);
- }
-
-private:
- ResolveTopLevelTraitItems (const CanonicalPath &prefix,
- const CanonicalPath &canonical_prefix)
- : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix)
- {}
-
- const CanonicalPath &prefix;
- const CanonicalPath &canonical_prefix;
-};
-
-class ResolveToplevelExternItem : public ResolverBase
-{
- using Rust::Resolver::ResolverBase::visit;
-
-public:
- static void go (AST::ExternalItem &item, const CanonicalPath &prefix)
- {
- ResolveToplevelExternItem resolver (prefix);
- item.accept_vis (resolver);
- };
-
- 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);
-
- 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);
- }
-
- void visit (AST::ExternalStaticItem &item) override
- {
- auto decl = CanonicalPath::new_seg (item.get_node_id (),
- item.get_identifier ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_name_scope ().insert (
- path, item.get_node_id (), item.get_locus (), false,
- Rib::ItemType::Static,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, item.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);
- }
-
- void visit (AST::ExternalTypeItem &type) override
- {
- auto decl = CanonicalPath::new_seg (type.get_node_id (),
- type.get_identifier ().as_string ());
- auto path = prefix.append (decl);
-
- resolver->get_type_scope ().insert (
- path, type.get_node_id (), type.get_locus (), false, Rib::ItemType::Type,
- [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
- rich_location r (line_table, type.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);
- }
-
-private:
- ResolveToplevelExternItem (const CanonicalPath &prefix)
- : ResolverBase (), prefix (prefix)
- {}
-
- const CanonicalPath &prefix;
-};
-
-} // namespace Resolver
-} // namespace Rust
-
-#endif // RUST_AST_RESOLVE_IMPLITEM_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 1d5ebed..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ /dev/null
@@ -1,1247 +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
-// <http://www.gnu.org/licenses/>.
-
-#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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // 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<AST::VariadicParam &> (*p);
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*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<AST::Pattern> (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<std::unique_ptr<AST::TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<AST::TypePathSegment> (
- 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 &param = static_cast<AST::FunctionParam &> (*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<AST::SelfParam &> (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<AST::Pattern> (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<std::unique_ptr<AST::TypePathSegment>> segments;
- segments.push_back (std::unique_ptr<AST::TypePathSegment> (
- 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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // 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<AST::VariadicParam &> (*p);
- if (param.has_pattern ())
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*p);
- if (param.has_type ())
- ResolveType::go (param.get_type ());
- }
- else
- {
- auto &param = static_cast<AST::FunctionParam &> (*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<Import> &imports);
-static void flatten_rebind (const AST::UseTreeRebind &glob,
- std::vector<Import> &imports);
-static void flatten_list (const AST::UseTreeList &glob,
- std::vector<Import> &imports);
-
-static void
-flatten (const AST::UseTree *tree, std::vector<Import> &imports)
-{
- switch (tree->get_kind ())
- {
- case AST::UseTree::Glob:
- {
- auto glob = static_cast<const AST::UseTreeGlob *> (tree);
- flatten_glob (*glob, imports);
- break;
- }
- case AST::UseTree::Rebind:
- {
- auto rebind = static_cast<const AST::UseTreeRebind *> (tree);
- flatten_rebind (*rebind, imports);
- break;
- }
- case AST::UseTree::List:
- {
- auto list = static_cast<const AST::UseTreeList *> (tree);
- flatten_list (*list, imports);
- break;
- }
- break;
- }
-}
-
-static void
-flatten_glob (const AST::UseTreeGlob &glob, std::vector<Import> &imports)
-{
- if (glob.has_path ())
- imports.emplace_back (glob.get_path (), true, std::string ());
-}
-
-static void
-flatten_rebind (const AST::UseTreeRebind &rebind, std::vector<Import> &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<Import> &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 ().push_back (
- AST::SimplePathSegment (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<Import>
-flatten_use_dec_to_imports (const AST::UseDeclaration &use_item)
-{
- auto imports = std::vector<Import> ();
-
- const auto &tree = use_item.get_tree ();
- flatten (tree.get (), imports);
-
- return imports;
-}
-
-void
-ResolveItem::visit (AST::UseDeclaration &use_item)
-{
- std::vector<Import> 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 &param : function.get_function_params ())
- if (!param->is_variadic ())
- {
- auto &p = static_cast<AST::FunctionParam &> (*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::Import> ();
- 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::Import> ();
- 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::Import> ();
- 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::Import> ();
- 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::Import> ();
- 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<Rust::AST::UseTree> (
- new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, baz,
- UNDEF_LOCATION));
- auto use1 = std::unique_ptr<Rust::AST::UseTree> (
- new Rust::AST::UseTreeRebind (Rust::AST::UseTreeRebind::NONE, bul,
- UNDEF_LOCATION));
-
- auto uses = std::vector<std::unique_ptr<Rust::AST::UseTree>> ();
- 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::Import> ();
- 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 d31f910..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 fb6715d..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 %<super%> 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<CanonicalPath &> 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,
- "%<super%> 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 %<super%> 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<CanonicalPath &> 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 cddb54a..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<AST::SimplePathSegment> &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 3b80f9f..0000000
--- a/gcc/rust/resolve/rust-ast-resolve-pattern.cc
+++ /dev/null
@@ -1,419 +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
-// <http://www.gnu.org/licenses/>.
-
-#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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
- PatternDeclaration::go (pattern, type, bindings);
-}
-
-void
-PatternDeclaration::go (AST::Pattern &pattern, Rib::ItemType type,
- std::vector<PatternBinding> &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<AST::TupleStructItemsNoRange &> (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<AST::StructPatternFieldTuplePat &> (*field);
-
- tuple.get_index_pattern ().accept_vis (*this);
- }
- break;
-
- case AST::StructPatternField::ItemType::IDENT_PAT:
- {
- AST::StructPatternFieldIdentPat &ident
- = static_cast<AST::StructPatternFieldIdentPat &> (*field);
-
- ident.get_ident_pattern ().accept_vis (*this);
- }
- break;
-
- case AST::StructPatternField::ItemType::IDENT:
- {
- auto &ident = static_cast<AST::StructPatternFieldIdent &> (*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<AST::TuplePatternItemsMultiple &> (
- pattern.get_items ());
-
- for (auto &p : ref.get_patterns ())
- p->accept_vis (*this);
- }
- break;
-
- case AST::TuplePatternItems::TuplePatternItemType::RANGED:
- {
- auto &ref
- = static_cast<AST::TuplePatternItemsRanged &> (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.push_back (
- PatternBinding (PatternBoundCtx::Or, std::set<Identifier> ()));
-
- // 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<BindingMap> 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.push_back (
- PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ()));
-
- 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<BindingMap> &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<AST::RangePatternBoundPath &> (bound);
-
- ResolvePath::go (ref.get_path ());
- }
- break;
-
- case AST::RangePatternBound::RangePatternBoundType::QUALPATH:
- {
- auto &ref = static_cast<AST::RangePatternBoundQualPath &> (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<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
-
- for (auto &p : ref.get_patterns ())
- p->accept_vis (*this);
- }
- break;
-
- case AST::SlicePatternItems::SlicePatternItemType::HAS_REST:
- {
- auto &ref
- = static_cast<AST::SlicePatternItemsHasRest &> (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 876de16..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<Identifier> idents;
-
- PatternBinding (PatternBoundCtx ctx, std::set<Identifier> 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<Identifier, BindingTypeInfo> 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<PatternBinding> &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<BindingMap> &binding_maps);
-
-private:
- PatternDeclaration (std::vector<PatternBinding> &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<PatternBinding> &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 bfba302..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 d714511..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<PatternBinding> bindings
- = {PatternBinding (PatternBoundCtx::Product, std::set<Identifier> ())};
-
- // 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<AST::VariadicParam &> (*p);
- PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param,
- bindings);
- }
-
- else if (p->is_self ())
- {
- auto &param = static_cast<AST::SelfParam &> (*p);
- ResolveType::go (param.get_type ());
- }
- else
- {
- auto &param = static_cast<AST::FunctionParam &> (*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 9b38e6a..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 87fa60d..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 f52fb8a..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 a040228..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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 &param : 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<AST::TypePathSegmentGeneric *> (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<AST::TypePathSegmentFunction *> (segment.get ());
-
- AST::TypePathFunction &fn = fnseg->get_type_path_function ();
- for (auto &param : 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<CanonicalPath &> 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<AST::TypePathSegment> &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<AST::TypePathSegmentGeneric *> (final_seg.get ());
-
- std::vector<CanonicalPath> 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 = "<dyn " + path.get () + ">";
- 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<AST::TraitBound &> (*first_bound);
-
- CanonicalPath path = CanonicalPath::create_empty ();
- bool ok = ResolveTypeToCanonicalPath::go (trait.get_type_path (), path);
-
- // right?
- rust_assert (ok);
-
- auto slice_path = "<dyn " + path.get ();
-
- for (size_t idx = 1; idx < type.get_type_param_bounds ().size (); idx++)
- {
- auto &additional_bound = type.get_type_param_bounds ()[idx];
-
- std::string str;
-
- switch (additional_bound->get_bound_type ())
- {
- case AST::TypeParamBound::TRAIT:
- {
- auto bound_path = CanonicalPath::create_empty ();
-
- auto &bound_type_path
- = static_cast<AST::TraitBound &> (*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 f1481fc..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<std::unique_ptr<AST::GenericParam>> &params,
- 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 &param : params)
- param->accept_vis (resolver);
-
- resolver.first_pass = false;
-
- for (auto &param : params)
- param->accept_vis (resolver);
- }
-
- static void go_single (AST::GenericParam &param, 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 &param) 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 &param) 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 2208f70..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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-early-name-resolver-2.0.cc b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
index 4fd1dd2..0dff831 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.cc
@@ -438,7 +438,9 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
// We don't want to insert `self` with `use module::self`
if (path.get_final_segment ().is_lower_self_seg ())
{
- rust_assert (segments.size () > 1);
+ // Erroneous `self` or `{self}` use declaration
+ if (segments.size () == 1)
+ break;
declared_name = segments[segments.size () - 2].as_string ();
}
else
@@ -447,8 +449,8 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
break;
}
case AST::UseTreeRebind::NewBindType::WILDCARD:
- rust_unreachable ();
- break;
+ // We don't want to insert it into the trie
+ return;
}
for (auto &&definition : data.definitions ())
@@ -459,6 +461,19 @@ Early::finalize_rebind_import (const Early::ImportPair &mapping)
void
Early::visit (AST::UseDeclaration &decl)
{
+ // We do not want to visit the use trees, we're only looking for top level
+ // rebind. eg. `use something;` or `use something::other;`
+ if (decl.get_tree ()->get_kind () == AST::UseTree::Kind::Rebind)
+ {
+ auto &rebind = static_cast<AST::UseTreeRebind &> (*decl.get_tree ());
+ if (rebind.get_path ().get_final_segment ().is_lower_self_seg ())
+ {
+ collect_error (
+ Error (decl.get_locus (), ErrorCode::E0429,
+ "%<self%> imports are only allowed within a { } list"));
+ }
+ }
+
auto &imports = toplevel.get_imports_to_resolve ();
auto current_import = imports.find (decl.get_node_id ());
if (current_import != imports.end ())
@@ -484,5 +499,31 @@ Early::visit (AST::UseDeclaration &decl)
DefaultResolver::visit (decl);
}
+void
+Early::visit (AST::UseTreeList &use_list)
+{
+ if (!use_list.has_path ())
+ {
+ for (auto &&tree : use_list.get_trees ())
+ {
+ if (tree->get_kind () == AST::UseTree::Kind::Rebind)
+ {
+ auto &rebind = static_cast<AST::UseTreeRebind &> (*tree);
+ auto path_size = rebind.get_path ().get_segments ().size ();
+ if (path_size == 1
+ && rebind.get_path ()
+ .get_final_segment ()
+ .is_lower_self_seg ())
+ {
+ collect_error (Error (rebind.get_locus (), ErrorCode::E0431,
+ "%<self%> import can only appear in an "
+ "import list with a non-empty prefix"));
+ }
+ }
+ }
+ }
+ DefaultResolver::visit (use_list);
+}
+
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-early-name-resolver-2.0.h b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
index 960de0e..3940386 100644
--- a/gcc/rust/resolve/rust-early-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-early-name-resolver-2.0.h
@@ -61,6 +61,7 @@ public:
void visit (AST::Function &) override;
void visit (AST::StructStruct &) override;
void visit (AST::UseDeclaration &) override;
+ void visit (AST::UseTreeList &) override;
struct ImportData
{
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 7b365ef..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<std::unique_ptr<AST::Item>>
-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<std::unique_ptr<AST::Item>> 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<AST::Module *> (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<std::unique_ptr<AST::Item>> 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<std::unique_ptr<AST::Item>> ();
-
- if (item->get_item_kind () == AST::Item::Kind::Module)
- new_macros = accumulate_escaped_macros (
- *static_cast<AST::Module *> (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<std::unique_ptr<AST::Item>> 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<std::unique_ptr<AST::Item>> ();
-
- if (item->get_item_kind () == AST::Item::Kind::Module)
- new_macros = accumulate_escaped_macros (
- *static_cast<AST::Module *> (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 d3c5225..0000000
--- 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
-// <http://www.gnu.org/licenses/>.
-
-#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<void ()> 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<std::unique_ptr<AST::Item>>
- 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 &macro_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-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx
index 1ed87b3..848f5e6 100644
--- a/gcc/rust/resolve/rust-forever-stack.hxx
+++ b/gcc/rust/resolve/rust-forever-stack.hxx
@@ -531,7 +531,7 @@ ForeverStack<N>::resolve_segments (
|| seg.is_lower_self_seg ()))
return tl::nullopt;
- tl::optional<typename ForeverStack<N>::Node &> child = tl::nullopt;
+ tl::optional<std::reference_wrapper<Node>> child = tl::nullopt;
/*
* On every iteration this loop either
@@ -583,10 +583,17 @@ ForeverStack<N>::resolve_segments (
break;
}
- if (N == Namespace::Types)
+ auto rib_lookup = current_node->rib.get (seg.as_string ());
+ if (rib_lookup && !rib_lookup->is_ambiguous ())
{
- auto rib_lookup = current_node->rib.get (seg.as_string ());
- if (rib_lookup && !rib_lookup->is_ambiguous ())
+ if (Analysis::Mappings::get ()
+ .lookup_glob_container (rib_lookup->get_node_id ())
+ .has_value ())
+ {
+ child = dfs_node (root, rib_lookup->get_node_id ()).value ();
+ break;
+ }
+ else
{
insert_segment_resolution (outer_seg,
rib_lookup->get_node_id ());
@@ -611,9 +618,9 @@ ForeverStack<N>::resolve_segments (
current_node = &current_node->parent.value ();
}
- // if child didn't contain a value
- // the while loop above should have return'd or kept looping
- current_node = &child.value ();
+ // if child didn't point to a value
+ // the while loop above would have returned or kept looping
+ current_node = &child->get ();
insert_segment_resolution (outer_seg, current_node->id);
}
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index e39ca15..96b38f4 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -24,6 +24,7 @@
#include "rust-late-name-resolver-2.0.h"
#include "rust-default-resolver.h"
#include "rust-name-resolution-context.h"
+#include "rust-resolve-builtins.h"
#include "rust-path.h"
#include "rust-system.h"
#include "rust-tyty.h"
@@ -38,84 +39,10 @@ Late::Late (NameResolutionContext &ctx)
: DefaultResolver (ctx), funny_error (false), block_big_self (false)
{}
-static NodeId
-next_node_id ()
-{
- return Analysis::Mappings::get ().get_next_node_id ();
-};
-
-static HirId
-next_hir_id ()
-{
- return Analysis::Mappings::get ().get_next_hir_id ();
-};
-
-void
-Late::setup_builtin_types ()
-{
- // access the global type context to setup the TyTys
- auto &ty_ctx = *Resolver::TypeCheckContext::get ();
-
- // Late builtin type struct helper
- struct LType
- {
- std::string name;
- NodeId node_id;
- NodeId hir_id;
- TyTy::BaseType *type;
-
- explicit LType (std::string name, TyTy::BaseType *type)
- : name (name), node_id (next_node_id ()), hir_id (type->get_ref ()),
- type (type)
- {}
- };
-
- static const LType builtins[] = {
- {LType ("bool", new TyTy::BoolType (next_hir_id ()))},
- {LType ("u8", new TyTy::UintType (next_hir_id (), TyTy::UintType::U8))},
- {LType ("u16", new TyTy::UintType (next_hir_id (), TyTy::UintType::U16))},
- {LType ("u32", new TyTy::UintType (next_hir_id (), TyTy::UintType::U32))},
- {LType ("u64", new TyTy::UintType (next_hir_id (), TyTy::UintType::U64))},
- {LType ("u128", new TyTy::UintType (next_hir_id (), TyTy::UintType::U128))},
- {LType ("i8", new TyTy::IntType (next_hir_id (), TyTy::IntType::I8))},
- {LType ("i16", new TyTy::IntType (next_hir_id (), TyTy::IntType::I16))},
- {LType ("i32", new TyTy::IntType (next_hir_id (), TyTy::IntType::I32))},
- {LType ("i64", new TyTy::IntType (next_hir_id (), TyTy::IntType::I64))},
- {LType ("i128", new TyTy::IntType (next_hir_id (), TyTy::IntType::I128))},
- {LType ("f32", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F32))},
- {LType ("f64", new TyTy::FloatType (next_hir_id (), TyTy::FloatType::F64))},
- {LType ("usize", new TyTy::USizeType (next_hir_id ()))},
- {LType ("isize", new TyTy::ISizeType (next_hir_id ()))},
- {LType ("char", new TyTy::CharType (next_hir_id ()))},
- {LType ("str", new TyTy::StrType (next_hir_id ()))},
- {LType ("!", new TyTy::NeverType (next_hir_id ()))},
-
- // the unit type `()` does not play a part in name-resolution - so we only
- // insert it in the type context...
- };
-
- // There's a special Rib for putting prelude items, since prelude items need
- // to satisfy certain special rules.
- ctx.scoped (Rib::Kind::Prelude, 0, [this, &ty_ctx] (void) -> void {
- for (const auto &builtin : builtins)
- {
- auto ok = ctx.types.insert (builtin.name, builtin.node_id);
- rust_assert (ok);
-
- ctx.mappings.insert_node_to_hir (builtin.node_id, builtin.hir_id);
- ty_ctx.insert_builtin (builtin.hir_id, builtin.node_id, builtin.type);
- }
- });
-
- // ...here!
- auto *unit_type = TyTy::TupleType::get_unit_type ();
- ty_ctx.insert_builtin (unit_type->get_ref (), next_node_id (), unit_type);
-}
-
void
Late::go (AST::Crate &crate)
{
- setup_builtin_types ();
+ Builtins::setup_type_ctx ();
visit (crate);
}
@@ -521,20 +448,22 @@ Late::visit_impl_type (AST::Type &type)
block_big_self = false;
}
-void
-Late::visit (AST::TypePath &type)
+template <typename P>
+static void
+resolve_type_path_like (NameResolutionContext &ctx, bool block_big_self,
+ P &type)
{
// should we add type path resolution in `ForeverStack` directly? Since it's
// quite more complicated.
// maybe we can overload `resolve_path<Namespace::Types>` to only do
// typepath-like path resolution? that sounds good
- DefaultResolver::visit (type);
-
// prevent "impl Self {}" and similar
if (type.get_segments ().size () == 1
- && !type.get_segments ().front ()->is_lang_item ()
- && type.get_segments ().front ()->is_big_self_seg () && block_big_self)
+ && !unwrap_segment_get_lang_item (type.get_segments ().front ())
+ .has_value ()
+ && unwrap_type_segment (type.get_segments ().front ()).is_big_self_seg ()
+ && block_big_self)
{
rust_error_at (type.get_locus (),
"%<Self%> is not valid in the self type of an impl block");
@@ -547,17 +476,17 @@ Late::visit (AST::TypePath &type)
if (!resolved.has_value ())
{
- if (!ctx.lookup (type.get_segments ().front ()->get_node_id ()))
+ if (!ctx.lookup (unwrap_segment_node_id (type.get_segments ().front ())))
rust_error_at (type.get_locus (), ErrorCode::E0412,
"could not resolve type path %qs",
- type.make_debug_string ().c_str ());
+ unwrap_segment_error_string (type).c_str ());
return;
}
if (resolved->is_ambiguous ())
{
rust_error_at (type.get_locus (), ErrorCode::E0659, "%qs is ambiguous",
- type.make_debug_string ().c_str ());
+ unwrap_segment_error_string (type).c_str ());
return;
}
@@ -574,6 +503,14 @@ Late::visit (AST::TypePath &type)
}
void
+Late::visit (AST::TypePath &type)
+{
+ DefaultResolver::visit (type);
+
+ resolve_type_path_like (ctx, block_big_self, type);
+}
+
+void
Late::visit (AST::Visibility &vis)
{
if (!vis.has_path ())
@@ -649,10 +586,7 @@ Late::visit (AST::StructExprStruct &s)
visit_inner_attrs (s);
DefaultResolver::visit (s.get_struct_name ());
- auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
-
- ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
- Definition (resolved->get_node_id ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
void
@@ -663,10 +597,7 @@ Late::visit (AST::StructExprStructBase &s)
DefaultResolver::visit (s.get_struct_name ());
visit (s.get_struct_base ());
- auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
-
- ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
- Definition (resolved->get_node_id ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
void
@@ -680,10 +611,7 @@ Late::visit (AST::StructExprStructFields &s)
for (auto &field : s.get_fields ())
visit (field);
- auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types);
-
- ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()),
- Definition (resolved->get_node_id ()));
+ resolve_type_path_like (ctx, block_big_self, s.get_struct_name ());
}
// needed because Late::visit (AST::GenericArg &) is non-virtual
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
index 95540e3..608ae38 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h
@@ -75,9 +75,6 @@ public:
private:
void resolve_label (AST::Lifetime &lifetime);
- /* Setup Rust's builtin types (u8, i32, !...) in the resolver */
- void setup_builtin_types ();
-
bool funny_error;
/* used to prevent "impl Self {}", "impl (Self, i32) {}", etc */
diff --git a/gcc/rust/resolve/rust-resolve-builtins.cc b/gcc/rust/resolve/rust-resolve-builtins.cc
new file mode 100644
index 0000000..b16db9a
--- /dev/null
+++ b/gcc/rust/resolve/rust-resolve-builtins.cc
@@ -0,0 +1,125 @@
+// Copyright (C) 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
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-resolve-builtins.h"
+#include "rust-name-resolution-context.h"
+#include "rust-tyty.h"
+#include "rust-hir-type-check.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+namespace Builtins {
+
+// Use X-macros
+
+#define TYPE_UINT(n, enum_ident) TYPE1 (n, UintType, UintType::enum_ident)
+#define TYPE_INT(n, enum_ident) TYPE1 (n, IntType, IntType::enum_ident)
+
+#define BUILTIN_TYPES \
+ TYPE0 ("bool", BoolType) \
+ TYPE_UINT ("u8", U8) \
+ TYPE_UINT ("u16", U16) \
+ TYPE_UINT ("u32", U32) \
+ TYPE_UINT ("u64", U64) \
+ TYPE_UINT ("u128", U128) \
+ TYPE_INT ("i8", I8) \
+ TYPE_INT ("i16", I16) \
+ TYPE_INT ("i32", I32) \
+ TYPE_INT ("i64", I64) \
+ TYPE_INT ("i128", I128) \
+ TYPE1 ("f32", FloatType, FloatType::F32) \
+ TYPE1 ("f64", FloatType, FloatType::F64) \
+ TYPE0 ("usize", USizeType) \
+ TYPE0 ("isize", ISizeType) \
+ TYPE0 ("char", CharType) \
+ TYPE0 ("str", StrType) \
+ TYPE0 ("!", NeverType)
+
+// Define constants using X macros
+
+#define TYPE0(...) 1 +
+#define TYPE1(...) 1 +
+static constexpr size_t builtin_count = BUILTIN_TYPES 0;
+#undef TYPE0
+#undef TYPE1
+
+#define TYPE0(n, ...) n,
+#define TYPE1(n, ...) n,
+static constexpr const char *builtin_names[] = {BUILTIN_TYPES};
+#undef TYPE0
+#undef TYPE1
+
+static NodeId builtin_node_ids[builtin_count];
+
+void
+setup_lang_prelude (NameResolutionContext &ctx)
+{
+ auto &mappings = Analysis::Mappings::get ();
+
+ // insert into prelude rib
+ ctx.scoped (Rib::Kind::Prelude, 0, [&mappings, &ctx] (void) -> void {
+ for (size_t i = 0; i < builtin_count; i++)
+ {
+ NodeId node_id = mappings.get_next_node_id ();
+ rust_assert (ctx.types.insert (Identifier (builtin_names[i]), node_id));
+ builtin_node_ids[i] = node_id;
+ }
+ });
+}
+
+void
+setup_type_ctx ()
+{
+ auto &mappings = Analysis::Mappings::get ();
+ auto &ty_ctx = *Resolver::TypeCheckContext::get ();
+
+ HirId hir_ids[builtin_count];
+ for (size_t i = 0; i < builtin_count; i++)
+ hir_ids[i] = mappings.get_next_hir_id ();
+
+ TyTy::BaseType *types[builtin_count];
+ {
+ size_t i = 0;
+#define TYPE_BASE(stub) \
+ types[i] = new TyTy::stub; \
+ i++;
+#define TYPE0(n, ty) TYPE_BASE (ty (hir_ids[i]))
+#define TYPE1(n, ty, p1) TYPE_BASE (ty (hir_ids[i], TyTy::p1))
+ BUILTIN_TYPES
+#undef TYPE_BASE
+#undef TYPE0
+#undef TYPE1
+ }
+
+ for (size_t i = 0; i < builtin_count; i++)
+ {
+ NodeId node_id = builtin_node_ids[i];
+ HirId hir_id = hir_ids[i];
+ mappings.insert_node_to_hir (node_id, hir_id);
+ ty_ctx.insert_builtin (hir_id, node_id, types[i]);
+ }
+
+ // handle unit type separately
+ auto *unit_type = TyTy::TupleType::get_unit_type ();
+ ty_ctx.insert_builtin (unit_type->get_ref (), mappings.get_next_node_id (),
+ unit_type);
+}
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-resolve-builtins.h b/gcc/rust/resolve/rust-resolve-builtins.h
new file mode 100644
index 0000000..e7e1bd2
--- /dev/null
+++ b/gcc/rust/resolve/rust-resolve-builtins.h
@@ -0,0 +1,37 @@
+// Copyright (C) 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
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_RESOLVE_BUILTINS_H
+#define RUST_RESOLVE_BUILTINS_H
+
+namespace Rust {
+namespace Resolver2_0 {
+
+// forward declare
+class NameResolutionContext;
+
+namespace Builtins {
+
+void setup_lang_prelude (NameResolutionContext &ctx);
+void setup_type_ctx ();
+
+} // namespace Builtins
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif // RUST_RESOLVE_BUILTINS_H