diff options
Diffstat (limited to 'gcc/rust/resolve')
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 ¶m); -  void visit (AST::VariadicParam ¶m); -  void visit (AST::SelfParam ¶m); - -  void visit (AST::FormatArgs &fmt); -  void visit (AST::OffsetOf &offset_of); - -protected: -  ResolverBase () -    : resolver (Resolver::get ()), mappings (Analysis::Mappings::get ()), -      resolved_node (UNKNOWN_NODEID) -  {} - -  /** -   * Resolve a visibility's path through the name resolver -   */ -  bool resolve_visibility (const AST::Visibility &vis); - -  Resolver *resolver; -  Analysis::Mappings &mappings; -  NodeId resolved_node; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_BASE_H diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc deleted file mode 100644 index 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 ¶m : expr.get_params ()) -    ResolveExpr::go (*param, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::MethodCallExpr &expr) -{ -  ResolveExpr::go (expr.get_receiver_expr (), prefix, canonical_prefix); - -  if (expr.get_method_name ().has_generic_args ()) -    { -      AST::GenericArgs &args = expr.get_method_name ().get_generic_args (); -      ResolveGenericArgs::go (args, prefix, canonical_prefix); -    } - -  auto const &in_params = expr.get_params (); -  for (auto ¶m : in_params) -    ResolveExpr::go (*param, prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ErrorPropagationExpr &expr) -{ -  ResolveExpr::go (expr.get_propagating_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::AssignmentExpr &expr) -{ -  ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IdentifierExpr &expr) -{ -  if (resolver->get_name_scope ().lookup ( -	CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()), -	&resolved_node)) -    { -      resolver->insert_resolved_name (expr.get_node_id (), resolved_node); -    } -  else if (resolver->get_type_scope ().lookup ( -	     CanonicalPath::new_seg (expr.get_node_id (), expr.as_string ()), -	     &resolved_node)) -    { -      resolver->insert_resolved_type (expr.get_node_id (), resolved_node); -    } -  else if (funny_error) -    { -      /* This was a "break rust" or "break gcc", and the identifier failed to -	 resolve.  Emit a funny ICE.  We set the finalizer to our custom one, -	 and use the lower-level emit_diagnostic () instead of the more common -	 internal_error_no_backtrace () in order to pass our locus.  */ -      diagnostics::text_finalizer (global_dc) = funny_ice_text_finalizer; -      emit_diagnostic (diagnostics::kind::ice_nobt, expr.get_locus (), -1, -		       "are you trying to break %s? how dare you?", -		       expr.as_string ().c_str ()); -    } -  else -    { -      rust_error_at (expr.get_locus (), ErrorCode::E0425, -		     "cannot find value %qs in this scope", -		     expr.as_string ().c_str ()); -    } -} - -void -ResolveExpr::visit (AST::ArithmeticOrLogicalExpr &expr) -{ -  ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::CompoundAssignmentExpr &expr) -{ -  ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::ComparisonExpr &expr) -{ -  ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::LazyBooleanExpr &expr) -{ -  ResolveExpr::go (expr.get_left_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_right_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::NegationExpr &expr) -{ -  ResolveExpr::go (expr.get_negated_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::TypeCastExpr &expr) -{ -  ResolveType::go (expr.get_type_to_cast_to ()); -  ResolveExpr::go (expr.get_casted_expr (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfExpr &expr) -{ -  ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfExprConseqElse &expr) -{ -  ResolveExpr::go (expr.get_condition_expr (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_if_block (), prefix, canonical_prefix); -  ResolveExpr::go (expr.get_else_block (), prefix, canonical_prefix); -} - -void -ResolveExpr::visit (AST::IfLetExpr &expr) -{ -  ResolveExpr::go (expr.get_value_expr (), prefix, canonical_prefix); - -  NodeId scope_node_id = expr.get_node_id (); -  resolver->get_name_scope ().push (scope_node_id); -  resolver->get_type_scope ().push (scope_node_id); -  resolver->get_label_scope ().push (scope_node_id); -  resolver->push_new_name_rib (resolver->get_name_scope ().peek ()); -  resolver->push_new_type_rib (resolver->get_type_scope ().peek ()); -  resolver->push_new_label_rib (resolver->get_label_scope ().peek ()); - -  // We know expr.get_patterns () has one pattern at most -  // so there's no reason to handle it like an AltPattern. -  std::vector<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 ¶m, -				    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 ¶m, -			      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 ¶m = 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 ¶m = 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 ¶m = static_cast<AST::VariadicParam &> (*p); -	  if (param.has_pattern ()) -	    PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, -				    bindings); -	} -      else if (p->is_self ()) -	{ -	  auto ¶m = static_cast<AST::SelfParam &> (*p); -	  if (param.has_type ()) -	    ResolveType::go (param.get_type ()); -	} -      else -	{ -	  auto ¶m = 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 ¶m : 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 ¶m = static_cast<AST::VariadicParam &> (*p); -	    PatternDeclaration::go (param.get_pattern (), Rib::ItemType::Param, -				    bindings); -	  } - -	else if (p->is_self ()) -	  { -	    auto ¶m = static_cast<AST::SelfParam &> (*p); -	    ResolveType::go (param.get_type ()); -	  } -	else -	  { -	    auto ¶m = 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 ¶m : fntype.get_function_params ()) -    ResolveType::go (param.get_type ()); - -  if (fntype.has_return_type ()) -    ResolveType::go (fntype.get_return_type ()); -} - -void -ResolveType::visit (AST::TupleType &tuple) -{ -  if (tuple.is_unit_type ()) -    { -      resolved_node = resolver->get_unit_type_node_id (); -      return; -    } - -  for (auto &elem : tuple.get_elems ()) -    ResolveType::go (*elem); -} - -void -ResolveType::visit (AST::TypePath &path) -{ -  ResolveRelativeTypePath::go (path, resolved_node); -} - -void -ResolveType::visit (AST::QualifiedPathInType &path) -{ -  ResolveRelativeQualTypePath::go (path); -} - -void -ResolveType::visit (AST::ArrayType &type) -{ -  type.get_elem_type ().accept_vis (*this); -  ResolveExpr::go (type.get_size_expr (), CanonicalPath::create_empty (), -		   CanonicalPath::create_empty ()); -} - -void -ResolveType::visit (AST::TraitObjectTypeOneBound &type) -{ -  ResolveTypeBound::go (type.get_trait_bound ()); -} - -void -ResolveType::visit (AST::TraitObjectType &type) -{ -  for (auto &bound : type.get_type_param_bounds ()) -    { -      /* NodeId bound_resolved_id = */ -      ResolveTypeBound::go (*bound); -    } -} - -void -ResolveType::visit (AST::ParenthesisedType &type) -{ -  resolved_node = ResolveType::go (*type.get_type_in_parens ()); -} - -void -ResolveType::visit (AST::ReferenceType &type) -{ -  resolved_node = ResolveType::go (type.get_type_referenced ()); -} - -void -ResolveType::visit (AST::RawPointerType &type) -{ -  resolved_node = ResolveType::go (type.get_type_pointed_to ()); -} - -void -ResolveType::visit (AST::InferredType &) -{ -  // nothing to do -} - -void -ResolveType::visit (AST::NeverType &) -{ -  resolved_node = resolver->get_never_type_node_id (); -} - -void -ResolveType::visit (AST::SliceType &type) -{ -  resolved_node = ResolveType::go (type.get_elem_type ()); -} - -void -ResolveType::visit (AST::ImplTraitType &type) -{ -  for (auto &bound : type.get_type_param_bounds ()) -    ResolveTypeBound::go (*bound); -} - -void -ResolveType::visit (AST::ImplTraitTypeOneBound &type) -{ -  ResolveTypeBound::go (*type.get_trait_bound ().get ()); -} - -// resolve relative type-paths - -bool -ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) -{ -  auto resolver = Resolver::get (); -  auto &mappings = Analysis::Mappings::get (); - -  NodeId module_scope_id = resolver->peek_current_module_scope (); -  NodeId previous_resolved_node_id = module_scope_id; -  for (size_t i = 0; i < path.get_segments ().size (); i++) -    { -      auto &segment = path.get_segments ().at (i); -      bool is_first_segment = i == 0; -      NodeId crate_scope_id = resolver->peek_crate_module_scope (); -      auto ident_string = segment->is_lang_item () -			    ? LangItem::PrettyString (segment->get_lang_item ()) -			    : segment->get_ident_segment ().as_string (); - -      resolved_node_id = UNKNOWN_NODEID; - -      if (segment->is_lang_item ()) -	{ -	  resolved_node_id = Analysis::Mappings::get ().get_lang_item_node ( -	    segment->get_lang_item ()); -	  previous_resolved_node_id = resolved_node_id; -	} -      else -	{ -	  bool in_middle_of_path = i > 0; -	  if (in_middle_of_path && segment->is_lower_self_seg ()) -	    { -	      rust_error_at (segment->get_locus (), ErrorCode::E0433, -			     "%qs in paths can only be used in start position", -			     segment->as_string ().c_str ()); -	      return false; -	    } - -	  if (segment->is_crate_path_seg ()) -	    { -	      // what is the current crate scope node id? -	      module_scope_id = crate_scope_id; -	      previous_resolved_node_id = module_scope_id; -	      resolver->insert_resolved_name (segment->get_node_id (), -					      module_scope_id); - -	      continue; -	    } -	  else if (segment->is_super_path_seg ()) -	    { -	      if (module_scope_id == crate_scope_id) -		{ -		  rust_error_at (segment->get_locus (), -				 "cannot use super at the crate scope"); -		  return false; -		} - -	      module_scope_id = resolver->peek_parent_module_scope (); -	      previous_resolved_node_id = module_scope_id; -	      resolver->insert_resolved_name (segment->get_node_id (), -					      module_scope_id); -	      continue; -	    } -	} - -      switch (segment->get_type ()) -	{ -	case AST::TypePathSegment::SegmentType::GENERIC: -	  { -	    AST::TypePathSegmentGeneric *s -	      = static_cast<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 ¶m : fn.get_params ()) -	    { -	      ResolveType::go (*param); -	    } - -	  if (fn.has_return_type ()) -	    { -	      ResolveType::go (fn.get_return_type ()); -	    } - -	  break; -	} - -      if (is_first_segment) -	{ -	  // name scope first -	  NodeId resolved_node = UNKNOWN_NODEID; -	  const CanonicalPath path -	    = CanonicalPath::new_seg (segment->get_node_id (), ident_string); -	  if (resolver->get_type_scope ().lookup (path, &resolved_node)) -	    { -	      NodeId existing = UNKNOWN_NODEID; -	      bool ok = resolver->lookup_resolved_type (segment->get_node_id (), -							&existing); - -	      if (ok) -		rust_assert (existing == resolved_node); -	      else -		resolver->insert_resolved_type (segment->get_node_id (), -						resolved_node); -	      resolved_node_id = resolved_node; -	    } -	  else if (resolver->get_name_scope ().lookup (path, &resolved_node)) -	    { -	      NodeId existing = UNKNOWN_NODEID; -	      bool ok = resolver->lookup_resolved_name (segment->get_node_id (), -							&existing); - -	      if (ok) -		rust_assert (existing == resolved_node); -	      else -		resolver->insert_resolved_name (segment->get_node_id (), -						resolved_node); -	      resolved_node_id = resolved_node; -	    } -	  else if (!segment->is_lang_item () && segment->is_lower_self_seg ()) -	    { -	      // what is the current crate scope node id? -	      module_scope_id = crate_scope_id; -	      previous_resolved_node_id = module_scope_id; - -	      NodeId existing = UNKNOWN_NODEID; -	      bool ok = resolver->lookup_resolved_name (segment->get_node_id (), -							&existing); - -	      if (ok) -		rust_assert (existing == module_scope_id); -	      else -		resolver->insert_resolved_name (segment->get_node_id (), -						module_scope_id); - -	      continue; -	    } -	} - -      if (resolved_node_id == UNKNOWN_NODEID -	  && previous_resolved_node_id == module_scope_id) -	{ -	  tl::optional<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>> ¶ms, -		  const CanonicalPath &prefix, -		  const CanonicalPath &canonical_prefix) -  { -    ResolveGenericParams resolver (prefix, canonical_prefix); - -    // this needs to be done in two phases as they can be used and defined later -    // in bounds -    for (auto ¶m : params) -      param->accept_vis (resolver); - -    resolver.first_pass = false; - -    for (auto ¶m : params) -      param->accept_vis (resolver); -  } - -  static void go_single (AST::GenericParam ¶m, const CanonicalPath &prefix, -			 const CanonicalPath &canonical_prefix) -  { -    ResolveGenericParams resolver (prefix, canonical_prefix); - -    param.accept_vis (resolver); -    resolver.first_pass = false; -    param.accept_vis (resolver); -  } - -  void visit (AST::ConstGenericParam ¶m) override -  { -    if (first_pass) -      ResolveType::go (param.get_type ()); -    else if (param.has_default_value ()) -      ResolveExpr::go (param.get_default_value_unchecked ().get_expression (), -		       prefix, canonical_prefix); -  } - -  void visit (AST::TypeParam ¶m) override -  { -    if (first_pass) -      { -	// if it has a type lets resolve it -	if (param.has_type ()) -	  ResolveType::go (param.get_type ()); - -	auto seg = CanonicalPath::new_seg ( -	  param.get_node_id (), param.get_type_representation ().as_string ()); -	resolver->get_type_scope ().insert ( -	  seg, param.get_node_id (), param.get_locus (), false, -	  Rib::ItemType::Type, -	  [&] (const CanonicalPath &, NodeId, location_t locus) -> void { -	    rust_error_at (param.get_locus (), -			   "generic param defined multiple times"); -	    rust_error_at (locus, "was defined here"); -	  }); - -	mappings.insert_canonical_path (param.get_node_id (), seg); -      } -    else if (param.has_type_param_bounds ()) -      { -	for (auto &bound : param.get_type_param_bounds ()) -	  ResolveTypeBound::go (*bound); -      } -  } - -private: -  ResolveGenericParams (const CanonicalPath &prefix, -			const CanonicalPath &canonical_prefix) -    : ResolverBase (), first_pass (true), prefix (prefix), -      canonical_prefix (canonical_prefix) -  {} - -  bool first_pass; -  const CanonicalPath &prefix; -  const CanonicalPath &canonical_prefix; -}; - -class ResolveWhereClause : public ResolverBase -{ -  using Rust::Resolver::ResolverBase::visit; - -public: -  static void Resolve (AST::WhereClause &where_clause) -  { -    ResolveWhereClause r; -    for (auto &clause : where_clause.get_items ()) -      clause->accept_vis (r); -  } - -  void visit (AST::TypeBoundWhereClauseItem &item) override -  { -    ResolveType::go (item.get_type ()); -    if (item.has_type_param_bounds ()) -      { -	for (auto &bound : item.get_type_param_bounds ()) -	  { -	    ResolveTypeBound::go (*bound); -	  } -      } -  } - -private: -  ResolveWhereClause () : ResolverBase () {} -}; - -class ResolveTypeToCanonicalPath : public ResolverBase -{ -  using Rust::Resolver::ResolverBase::visit; - -public: -  static bool go (AST::Type &type, CanonicalPath &result); - -  void visit (AST::TypePath &path) override; - -  void visit (AST::ReferenceType &type) override; - -  void visit (AST::RawPointerType &type) override; - -  void visit (AST::SliceType &type) override; - -  void visit (AST::TraitObjectTypeOneBound &type) override; - -  void visit (AST::TraitObjectType &type) override; - -  void visit (AST::NeverType &type) override; - -  void visit (AST::TupleType &type) override; - -private: -  ResolveTypeToCanonicalPath (); - -  CanonicalPath result; -}; - -class ResolveGenericArgs : public ResolverBase -{ -  using Rust::Resolver::ResolverBase::visit; - -public: -  static void go (AST::GenericArgs &generic_args); -  static void go (AST::GenericArgs &generic_args, const CanonicalPath &prefix, -		  const CanonicalPath &canonical_prefix); - -private: -  ResolveGenericArgs (const CanonicalPath &prefix, -		      const CanonicalPath &canonical_prefix) -    : ResolverBase (), prefix (prefix), canonical_prefix (canonical_prefix) -  {} - -  bool is_type_name (const CanonicalPath &path); -  bool is_const_value_name (const CanonicalPath &path); - -  /** -   * Resolve a disambiguated generic arg -   */ -  void disambiguate (AST::GenericArg &arg); - -  /** -   * Resolve a disambiguated generic arg -   */ -  void resolve_disambiguated_generic (AST::GenericArg &arg); - -  const CanonicalPath &prefix; -  const CanonicalPath &canonical_prefix; -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_AST_RESOLVE_TYPE_H diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc deleted file mode 100644 index 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 ¯o_invoc); -  virtual void visit (AST::MetaItemPath &meta_item); -  virtual void visit (AST::MetaItemSeq &meta_item); -  virtual void visit (AST::MetaNameValueStr &meta_item); -  virtual void visit (AST::MetaListPaths &meta_item); -  virtual void visit (AST::MetaListNameValueStr &meta_item); -  virtual void visit (AST::RangePatternBoundLiteral &bound); -  virtual void visit (AST::RangePatternBoundPath &bound); -  virtual void visit (AST::RangePatternBoundQualPath &bound); -  virtual void visit (AST::StructPatternFieldIdent &field); -  virtual void visit (AST::StructPattern &pattern); -  virtual void visit (AST::TupleStructPattern &pattern); -  virtual void visit (AST::TupleType &type); -  virtual void visit (AST::RawPointerType &type); -  virtual void visit (AST::ReferenceType &type); -  virtual void visit (AST::ArrayType &type); -  virtual void visit (AST::SliceType &type); -  virtual void visit (AST::InferredType &type); -}; - -} // namespace Resolver -} // namespace Rust - -#endif // RUST_EARLY_NAME_RESOLVER_H diff --git a/gcc/rust/resolve/rust-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 = ¤t_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  | 
