]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: nr2.0: Add DefaultResolver visitor
authorArthur Cohen <arthur.cohen@embecosm.com>
Thu, 20 Jul 2023 13:14:54 +0000 (15:14 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 18:00:26 +0000 (19:00 +0100)
The DefaultResolver class provides a visitor framework for all three resolvers
in the new name resolution algorithm, with things such as scoping or visiting
sub items.

gcc/rust/ChangeLog:

* Make-lang.in: Add new object file.
* resolve/rust-default-resolver.cc: New file.
* resolve/rust-default-resolver.h: New file.

gcc/rust/Make-lang.in
gcc/rust/resolve/rust-default-resolver.cc [new file with mode: 0644]
gcc/rust/resolve/rust-default-resolver.h [new file with mode: 0644]

index dc56eeafedd93f93e2a8dd2d55361cb232a8565d..da4135ab6d0a34d177b8bd5bc02d9f8f9ce335c5 100644 (file)
@@ -111,6 +111,7 @@ GRS_OBJS = \
        rust/rust-ast-lower-stmt.o \
        rust/rust-rib.o \
        rust/rust-name-resolution-context.o \
+       rust/rust-default-resolver.o \
     rust/rust-toplevel-name-resolver-2.0.o \
     rust/rust-early-name-resolver.o \
     rust/rust-name-resolver.o \
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
new file mode 100644 (file)
index 0000000..5cf4fe7
--- /dev/null
@@ -0,0 +1,811 @@
+// Copyright (C) 2020-2023 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-default-resolver.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+void
+DefaultResolver::visit (AST::BlockExpr &expr)
+{
+  // extracting the lambda from the `scoped` call otherwise the code looks like
+  // a hot turd thanks to our .clang-format
+
+  auto inner_fn = [this, &expr] () {
+    for (auto &stmt : expr.get_statements ())
+      stmt->accept_vis (*this);
+
+    if (expr.has_tail_expr ())
+      expr.get_tail_expr ()->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::Module &module)
+{
+  auto item_fn = [this, &module] () {
+    for (auto &item : module.get_items ())
+      item->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Module, module.get_node_id (), item_fn,
+             module.get_name ());
+}
+
+void
+DefaultResolver::visit (AST::Function &function)
+{
+  auto def_fn = [this, &function] () {
+    for (auto &param : function.get_function_params ())
+      {
+       param.get_pattern ()->accept_vis (*this);
+       param.get_type ()->accept_vis (*this);
+      }
+
+    function.get_definition ()->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
+}
+
+void
+DefaultResolver::visit (AST::Method &method)
+{
+  auto def_fn = [this, &method] () {
+    for (auto &param : method.get_function_params ())
+      {
+       param.get_pattern ()->accept_vis (*this);
+       param.get_type ()->accept_vis (*this);
+      }
+
+    method.get_definition ()->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Function, method.get_node_id (), def_fn);
+}
+
+void
+DefaultResolver::visit (AST::ForLoopExpr &expr)
+{
+  ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), [this, &expr] () {
+    expr.get_pattern ()->accept_vis (*this);
+    expr.get_iterator_expr ()->accept_vis (*this);
+    expr.get_loop_block ()->accept_vis (*this);
+  });
+}
+
+void
+DefaultResolver::visit (AST::Trait &trait)
+{
+  auto inner_fn = [this, &trait] () {
+    for (auto &item : trait.get_trait_items ())
+      item->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::TraitOrImpl, trait.get_node_id (), inner_fn,
+             trait.get_identifier () /* FIXME: Is that valid?*/);
+}
+
+void
+DefaultResolver::visit (AST::InherentImpl &impl)
+{
+  auto inner_fn = [this, &impl] () {
+    for (auto &item : impl.get_impl_items ())
+      item->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::TraitImpl &impl)
+{
+  auto inner_fn = [this, &impl] () {
+    for (auto &item : impl.get_impl_items ())
+      item->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::TraitOrImpl, impl.get_node_id (), inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::ExternBlock &block)
+{
+  auto inner_fn = [this, &block] () {
+    for (auto &item : block.get_extern_items ())
+      item->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Normal /* FIXME: Correct? */, block.get_node_id (),
+             inner_fn);
+}
+
+void
+DefaultResolver::visit (AST::StructStruct &type)
+{
+  // do we need to scope anything here? no, right?
+
+  // we also can't visit `StructField`s by default, so there's nothing to do -
+  // correct? or should we do something like
+
+  for (auto &field : type.get_fields ())
+    field.get_field_type ()->accept_vis (*this);
+
+  // FIXME: ???
+}
+
+void
+DefaultResolver::visit (AST::TupleStruct &type)
+{
+  for (auto &field : type.get_fields ())
+    field.get_field_type ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::Union &type)
+{
+  for (auto &field : type.get_variants ())
+    field.get_field_type ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::Enum &type)
+{
+  // FIXME: Do we need to scope anything by default?
+
+  auto variant_fn = [this, &type] () {
+    for (auto &variant : type.get_variants ())
+      variant->accept_vis (*this);
+  };
+
+  ctx.scoped (Rib::Kind::Item /* FIXME: Correct? */, type.get_node_id (),
+             variant_fn, type.get_identifier ());
+}
+
+void
+DefaultResolver::visit (AST::BorrowExpr &expr)
+{
+  expr.get_borrowed_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::DereferenceExpr &expr)
+{
+  expr.get_dereferenced_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ErrorPropagationExpr &expr)
+{
+  expr.get_propagating_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::NegationExpr &expr)
+{
+  expr.get_negated_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ArithmeticOrLogicalExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ComparisonExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::LazyBooleanExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::TypeCastExpr &expr)
+{
+  expr.get_type_to_cast_to ()->accept_vis (*this);
+  expr.get_casted_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::AssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::CompoundAssignmentExpr &expr)
+{
+  expr.get_left_expr ()->accept_vis (*this);
+  expr.get_right_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::GroupedExpr &expr)
+{
+  expr.get_expr_in_parens ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ArrayElemsValues &array)
+{
+  for (auto &value : array.get_values ())
+    value->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ArrayElemsCopied &array)
+{
+  array.get_elem_to_copy ()->accept_vis (*this);
+  array.get_num_copies ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ArrayExpr &expr)
+{
+  expr.get_array_elems ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ArrayIndexExpr &expr)
+{
+  expr.get_array_expr ()->accept_vis (*this);
+  expr.get_index_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::TupleExpr &expr)
+{
+  for (auto &element : expr.get_tuple_elems ())
+    element->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::TupleIndexExpr &expr)
+{
+  expr.get_tuple_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::StructExprFieldIdentifierValue &)
+{}
+
+void
+DefaultResolver::visit (AST::StructExprFieldIndexValue &)
+{}
+
+void
+DefaultResolver::visit (AST::CallExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::MethodCallExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::FieldAccessExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::ClosureExprInner &)
+{}
+
+void
+DefaultResolver::visit (AST::ClosureExprInnerTyped &)
+{}
+
+void
+DefaultResolver::visit (AST::ContinueExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::BreakExpr &expr)
+{
+  if (expr.has_break_expr ())
+    expr.get_break_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::RangeFromToExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::RangeFromExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::RangeToExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::RangeFullExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::RangeFromToInclExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::RangeToInclExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::ReturnExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::UnsafeBlockExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::LoopExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::WhileLoopExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::WhileLetLoopExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::IfExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::IfExprConseqElse &)
+{}
+
+void
+DefaultResolver::visit (AST::IfLetExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::IfLetExprConseqElse &)
+{}
+
+void
+DefaultResolver::visit (AST::MatchExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::AwaitExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::AsyncBlockExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::LetStmt &let_stmt)
+{
+  let_stmt.get_pattern ()->accept_vis (*this);
+
+  if (let_stmt.has_type ())
+    let_stmt.get_type ()->accept_vis (*this);
+
+  if (let_stmt.has_init_expr ())
+    let_stmt.get_init_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::ExprStmt &stmt)
+{
+  stmt.get_expr ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::Token &)
+{}
+
+void
+DefaultResolver::visit (AST::DelimTokenTree &)
+{}
+
+void
+DefaultResolver::visit (AST::AttrInputMetaItemContainer &)
+{}
+
+void
+DefaultResolver::visit (AST::IdentifierExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::Lifetime &)
+{}
+
+void
+DefaultResolver::visit (AST::LifetimeParam &)
+{}
+
+void
+DefaultResolver::visit (AST::ConstGenericParam &)
+{}
+
+void
+DefaultResolver::visit (AST::PathInExpression &)
+{}
+
+void
+DefaultResolver::visit (AST::TypePathSegment &)
+{}
+
+void
+DefaultResolver::visit (AST::TypePathSegmentGeneric &)
+{}
+
+void
+DefaultResolver::visit (AST::TypePathSegmentFunction &)
+{}
+
+void
+DefaultResolver::visit (AST::TypePath &)
+{}
+
+void
+DefaultResolver::visit (AST::QualifiedPathInExpression &)
+{}
+
+void
+DefaultResolver::visit (AST::QualifiedPathInType &)
+{}
+
+void
+DefaultResolver::visit (AST::LiteralExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::AttrInputLiteral &)
+{}
+
+void
+DefaultResolver::visit (AST::AttrInputMacro &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaItemLitExpr &expr)
+{}
+
+void
+DefaultResolver::visit (AST::MetaItemPathLit &)
+{}
+
+void
+DefaultResolver::visit (AST::StructExprStruct &)
+{}
+
+void
+DefaultResolver::visit (AST::StructExprFieldIdentifier &)
+{}
+
+void
+DefaultResolver::visit (AST::StructExprStructFields &)
+{}
+
+void
+DefaultResolver::visit (AST::StructExprStructBase &)
+{}
+
+void
+DefaultResolver::visit (AST::TypeParam &)
+{}
+
+void
+DefaultResolver::visit (AST::LifetimeWhereClauseItem &)
+{}
+
+void
+DefaultResolver::visit (AST::TypeBoundWhereClauseItem &)
+{}
+
+void
+DefaultResolver::visit (AST::ExternCrate &)
+{}
+
+void
+DefaultResolver::visit (AST::UseTreeGlob &)
+{}
+
+void
+DefaultResolver::visit (AST::UseTreeList &)
+{}
+
+void
+DefaultResolver::visit (AST::UseTreeRebind &)
+{}
+
+void
+DefaultResolver::visit (AST::UseDeclaration &)
+{}
+
+void
+DefaultResolver::visit (AST::TypeAlias &)
+{}
+
+void
+DefaultResolver::visit (AST::EnumItem &)
+{}
+
+void
+DefaultResolver::visit (AST::EnumItemTuple &)
+{}
+
+void
+DefaultResolver::visit (AST::EnumItemStruct &)
+{}
+
+void
+DefaultResolver::visit (AST::EnumItemDiscriminant &)
+{}
+
+void
+DefaultResolver::visit (AST::ConstantItem &item)
+{
+  auto expr_vis = [this, &item] () { item.get_expr ()->accept_vis (*this); };
+
+  // FIXME: Why do we need a Rib here?
+  ctx.scoped (Rib::Kind::Item, item.get_node_id (), expr_vis);
+}
+
+void
+DefaultResolver::visit (AST::StaticItem &item)
+{
+  auto expr_vis = [this, &item] () { item.get_expr ()->accept_vis (*this); };
+
+  // FIXME: Why do we need a Rib here?
+  ctx.scoped (Rib::Kind::ConstantItem, item.get_node_id (), expr_vis);
+}
+
+void
+DefaultResolver::visit (AST::TraitItemFunc &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitItemMethod &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitItemConst &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitItemType &)
+{}
+
+void
+DefaultResolver::visit (AST::ExternalTypeItem &)
+{}
+
+void
+DefaultResolver::visit (AST::ExternalStaticItem &)
+{}
+
+void
+DefaultResolver::visit (AST::ExternalFunctionItem &)
+{}
+
+void
+DefaultResolver::visit (AST::MacroMatchFragment &)
+{}
+
+void
+DefaultResolver::visit (AST::MacroMatchRepetition &)
+{}
+
+void
+DefaultResolver::visit (AST::MacroMatcher &)
+{}
+
+void
+DefaultResolver::visit (AST::MacroRulesDefinition &)
+{}
+
+void
+DefaultResolver::visit (AST::MacroInvocation &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaItemPath &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaItemSeq &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaWord &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaNameValueStr &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaListPaths &)
+{}
+
+void
+DefaultResolver::visit (AST::MetaListNameValueStr &)
+{}
+
+void
+DefaultResolver::visit (AST::LiteralPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::IdentifierPattern &pattern)
+{
+  if (pattern.has_pattern_to_bind ())
+    pattern.get_pattern_to_bind ()->accept_vis (*this);
+}
+
+void
+DefaultResolver::visit (AST::WildcardPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::RestPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::RangePatternBoundLiteral &)
+{}
+
+void
+DefaultResolver::visit (AST::RangePatternBoundPath &)
+{}
+
+void
+DefaultResolver::visit (AST::RangePatternBoundQualPath &)
+{}
+
+void
+DefaultResolver::visit (AST::RangePattern &)
+{}
+
+void
+DefaultResolver::visit (AST::ReferencePattern &)
+{}
+
+void
+DefaultResolver::visit (AST::StructPatternFieldTuplePat &)
+{}
+
+void
+DefaultResolver::visit (AST::StructPatternFieldIdentPat &)
+{}
+
+void
+DefaultResolver::visit (AST::StructPatternFieldIdent &)
+{}
+
+void
+DefaultResolver::visit (AST::StructPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::TupleStructItemsNoRange &)
+{}
+
+void
+DefaultResolver::visit (AST::TupleStructItemsRange &)
+{}
+
+void
+DefaultResolver::visit (AST::TupleStructPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::TuplePatternItemsMultiple &)
+{}
+
+void
+DefaultResolver::visit (AST::TuplePatternItemsRanged &)
+{}
+
+void
+DefaultResolver::visit (AST::TuplePattern &)
+{}
+
+void
+DefaultResolver::visit (AST::GroupedPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::SlicePattern &)
+{}
+
+void
+DefaultResolver::visit (AST::AltPattern &)
+{}
+
+void
+DefaultResolver::visit (AST::EmptyStmt &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitBound &)
+{}
+
+void
+DefaultResolver::visit (AST::ImplTraitType &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitObjectType &)
+{}
+
+void
+DefaultResolver::visit (AST::ParenthesisedType &)
+{}
+
+void
+DefaultResolver::visit (AST::ImplTraitTypeOneBound &)
+{}
+
+void
+DefaultResolver::visit (AST::TraitObjectTypeOneBound &)
+{}
+
+void
+DefaultResolver::visit (AST::TupleType &)
+{}
+
+void
+DefaultResolver::visit (AST::NeverType &)
+{}
+
+void
+DefaultResolver::visit (AST::RawPointerType &)
+{}
+
+void
+DefaultResolver::visit (AST::ReferenceType &)
+{}
+
+void
+DefaultResolver::visit (AST::ArrayType &)
+{}
+
+void
+DefaultResolver::visit (AST::SliceType &)
+{}
+
+void
+DefaultResolver::visit (AST::InferredType &)
+{}
+
+void
+DefaultResolver::visit (AST::BareFunctionType &)
+{}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
new file mode 100644 (file)
index 0000000..17b87ef
--- /dev/null
@@ -0,0 +1,211 @@
+
+// Copyright (C) 2020-2023 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_DEFAULT_RESOLVER_H
+#define RUST_AST_DEFAULT_RESOLVER_H
+
+#include "rust-ast-visitor.h"
+#include "rust-name-resolution-context.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+/**
+ * The `DefaultResolver` is a base visitor for all passes of our name resolution
+ * algorithm: `TopLevel`, `Easy` and `Late`. It does not do a lot, apart from
+ * visiting each node's subnodes - a block's statements, a function call's
+ * arguments...
+ */
+class DefaultResolver : public AST::ASTVisitor
+{
+public:
+  virtual ~DefaultResolver () {}
+
+  // First, our lexical scope expressions - these visit their sub nodes, always
+  // these nodes create new scopes and ribs - they are often used to declare new
+  // variables, such as a for loop's iterator, or a function's arguments
+  void visit (AST::BlockExpr &);
+  void visit (AST::Module &);
+  void visit (AST::Function &);
+  void visit (AST::Method &);
+  void visit (AST::ForLoopExpr &);
+  void visit (AST::Trait &);
+  void visit (AST::InherentImpl &);
+  void visit (AST::TraitImpl &);
+  void visit (AST::ExternBlock &);
+
+  // type dec nodes, which visit their fields or variants by default
+  void visit (AST::StructStruct &);
+  void visit (AST::TupleStruct &);
+  void visit (AST::Union &);
+  void visit (AST::Enum &);
+
+  // Visitors that visit their expression node
+  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::StructExprFieldIdentifierValue &);
+  void visit (AST::StructExprFieldIndexValue &);
+  void visit (AST::CallExpr &);
+  void visit (AST::MethodCallExpr &);
+  void visit (AST::FieldAccessExpr &);
+  void visit (AST::ClosureExprInner &);
+  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::ReturnExpr &);
+  void visit (AST::UnsafeBlockExpr &);
+  void visit (AST::LoopExpr &);
+  void visit (AST::WhileLoopExpr &);
+  void visit (AST::WhileLetLoopExpr &);
+  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::LetStmt &);
+  void visit (AST::ExprStmt &);
+
+  // Leaf visitors, which do nothing by default
+  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::MetaItemPathLit &);
+  void visit (AST::StructExprStruct &);
+  void visit (AST::StructExprFieldIdentifier &);
+  void visit (AST::StructExprStructFields &);
+  void visit (AST::StructExprStructBase &);
+  void visit (AST::TypeParam &);
+  void visit (AST::LifetimeWhereClauseItem &);
+  void visit (AST::TypeBoundWhereClauseItem &);
+  void visit (AST::ExternCrate &);
+  void visit (AST::UseTreeGlob &);
+  void visit (AST::UseTreeList &);
+  void visit (AST::UseTreeRebind &);
+  void visit (AST::UseDeclaration &);
+  void visit (AST::TypeAlias &);
+  void visit (AST::EnumItem &);
+  void visit (AST::EnumItemTuple &);
+  void visit (AST::EnumItemStruct &);
+  void visit (AST::EnumItemDiscriminant &);
+  void visit (AST::ConstantItem &);
+  void visit (AST::StaticItem &);
+  void visit (AST::TraitItemFunc &);
+  void visit (AST::TraitItemMethod &);
+  void visit (AST::TraitItemConst &);
+  void visit (AST::TraitItemType &);
+  void visit (AST::ExternalTypeItem &);
+  void visit (AST::ExternalStaticItem &);
+  void visit (AST::ExternalFunctionItem &);
+  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::SlicePattern &);
+  void visit (AST::AltPattern &);
+  void visit (AST::EmptyStmt &);
+  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 &);
+
+protected:
+  DefaultResolver (NameResolutionContext &ctx) : ctx (ctx) {}
+
+  NameResolutionContext &ctx;
+};
+
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif // RUST_AST_DEFAULT_RESOLVER_H