https://gcc.gnu.org/g:9864d7fe8a6dd8abe1cf95e36e35b1762d4d34fe

commit 9864d7fe8a6dd8abe1cf95e36e35b1762d4d34fe
Author: Owen Avery <powerboat9.ga...@gmail.com>
Date:   Sat Oct 28 01:04:19 2023 -0400

    Replace AST::Method with existing AST::Function
    
    gcc/rust/ChangeLog:
    
            * ast/rust-item.h
            (class Method): Remove.
            (Function::self_param): New.
            (Function::has_self_param): New.
            (Function::Function): Initialize self_param.
            (Function::operator=): Likewise.
            (Function::get_self_param): New.
            * ast/rust-ast.cc
            (Method::as_string): Remove.
            (Method::accept_vis): Remove.
    
            * ast/rust-ast-collector.cc
            (TokenCollector::visit):
            Remove AST::Method visitor, handle self_param in AST::Function 
visitor.
            * ast/rust-ast-collector.h
            (TokenCollector::visit): Remove AST::Method visitor.
            * ast/rust-ast-full-decls.h (class Method): Remove.
    
            * ast/rust-ast-visitor.h
            (ASTVisitor::visit): Remove AST::Method visitor.
            (DefaultASTVisitor::visit): Likewise.
            * ast/rust-ast-visitor.cc
            (DefaultASTVisitor::visit):
            Remove AST::Method visitor, handle self_param in AST::Function 
visitor.
    
            * checks/errors/rust-feature-gate.cc
            (FeatureGate::visit): Remove AST::Method visitor.
            * checks/errors/rust-feature-gate.h
            (FeatureGate::visit): Likewise..
    
            * expand/rust-cfg-strip.cc
            (CfgStrip::visit):
            Remove AST::Method visitor, handle self_param in AST::Function 
visitor.
            * expand/rust-cfg-strip.h
            (CfgStrip::visit): Remove AST::Method visitor.
    
            * expand/rust-derive-clone.cc
            (DeriveClone::clone_fn): Return AST::Function instead of 
AST::Method.
            * expand/rust-derive.h (DeriveVisitor::visit): Remove AST::Method 
visitor.
    
            * expand/rust-expand-visitor.cc
            (ExpandVisitor::visit):
            Remove AST::Method visitor, handle self_param in AST::Function 
visitor.
            * expand/rust-expand-visitor.h:
            (ExpandVisitor::visit): Remove AST::Method visitor.
    
            * hir/rust-ast-lower-base.cc (ASTLoweringBase::visit): Likewise.
            * hir/rust-ast-lower-base.h (ASTLoweringBase::visit): Likewise.
    
            * hir/rust-ast-lower-implitem.h
            (ASTLowerImplItem::visit):
            Remove AST::Method visitor, handle self_param in AST::Function 
visitor.
    
            * parse/rust-parse-impl.h: Include optional.h.
            (Parser::parse_function): Adjust AST::Function construction.
            (Parser::parse_inherent_impl_function_or_method):
            Construct AST::Function instead of AST::Method,
            adjust AST::Function construction.
            (Parser::parse_trait_impl_function_or_method): Likewise.
            (Parser::parse_method):
            Return std::unique_ptr<AST::Function> instead of AST::Method.
    
            * parse/rust-parse.h
            (Parser::parse_method): Likewise.
    
            * resolve/rust-ast-resolve-base.cc
            (ResolverBase::visit): Remove AST::Method visitor.
            * resolve/rust-ast-resolve-base.h
            (ResolverBase::visit): Likewise.
    
            * resolve/rust-ast-resolve-implitem.h
            (ResolveToplevelImplItem::visit): Likewise.
    
            * resolve/rust-ast-resolve-item.cc
            (ResolveItem::visit): Remove AST::Method visitor,
            handle self_param in AST::Function visitor.
            * resolve/rust-ast-resolve-item.h
            (ResolveItem::visit): Remove AST::Method visitor.
    
            * resolve/rust-default-resolver.cc
            (DefaultResolver::visit): Remove AST::Method visitor.
            * resolve/rust-default-resolver.h
            (DefaultResolver::visit): Likewise.
    
            * resolve/rust-early-name-resolver.cc
            (EarlyNameResolver::visit): Remove AST::Method visitor,
            handle self_param in AST::Function visitor.
            * resolve/rust-early-name-resolver.h
            (EarlyNameResolver::visit): Remove AST::Method visitor.
    
            * resolve/rust-toplevel-name-resolver-2.0.cc
            (TopLevel::visit): Likewise.
            * resolve/rust-toplevel-name-resolver-2.0.h
            (TopLevel::visit): Likewise.
    
            * util/rust-attributes.cc
            (AttributeChecker::visit): Likewise.
            * util/rust-attributes.h
            (AttributeChecker::visit): Likewise.
    
    Signed-off-by: Owen Avery <powerboat9.ga...@gmail.com>

Diff:
---
 gcc/rust/ast/rust-ast-collector.cc                 |  43 +---
 gcc/rust/ast/rust-ast-collector.h                  |   1 -
 gcc/rust/ast/rust-ast-full-decls.h                 |   1 -
 gcc/rust/ast/rust-ast-visitor.cc                   |  19 +-
 gcc/rust/ast/rust-ast-visitor.h                    |   2 -
 gcc/rust/ast/rust-ast.cc                           |  69 -------
 gcc/rust/ast/rust-item.h                           | 227 ++-------------------
 gcc/rust/checks/errors/rust-feature-gate.cc        |   6 -
 gcc/rust/checks/errors/rust-feature-gate.h         |   1 -
 gcc/rust/expand/rust-cfg-strip.cc                  |  54 +----
 gcc/rust/expand/rust-cfg-strip.h                   |   1 -
 gcc/rust/expand/rust-derive-clone.cc               |  11 +-
 gcc/rust/expand/rust-derive.h                      |   1 -
 gcc/rust/expand/rust-expand-visitor.cc             |  20 +-
 gcc/rust/expand/rust-expand-visitor.h              |   1 -
 gcc/rust/hir/rust-ast-lower-base.cc                |   3 -
 gcc/rust/hir/rust-ast-lower-base.h                 |   1 -
 gcc/rust/hir/rust-ast-lower-implitem.h             | 102 ++-------
 gcc/rust/parse/rust-parse-impl.h                   |  59 +++---
 gcc/rust/parse/rust-parse.h                        |   2 +-
 gcc/rust/resolve/rust-ast-resolve-base.cc          |   4 -
 gcc/rust/resolve/rust-ast-resolve-base.h           |   1 -
 gcc/rust/resolve/rust-ast-resolve-implitem.h       |  16 --
 gcc/rust/resolve/rust-ast-resolve-item.cc          | 113 +++-------
 gcc/rust/resolve/rust-ast-resolve-item.h           |   1 -
 gcc/rust/resolve/rust-default-resolver.cc          |  16 --
 gcc/rust/resolve/rust-default-resolver.h           |   1 -
 gcc/rust/resolve/rust-early-name-resolver.cc       |  22 +-
 gcc/rust/resolve/rust-early-name-resolver.h        |   1 -
 .../resolve/rust-toplevel-name-resolver-2.0.cc     |   8 -
 gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h |   1 -
 gcc/rust/util/rust-attributes.cc                   |   6 -
 gcc/rust/util/rust-attributes.h                    |   1 -
 33 files changed, 123 insertions(+), 692 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index 999752327216..83260720aff7 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1626,41 +1626,6 @@ TokenCollector::visit (TypeBoundWhereClauseItem &item)
   visit_items_joined_by_separator (item.get_type_param_bounds (), PLUS);
 }
 
-void
-TokenCollector::visit (Method &method)
-{
-  visit (method.get_visibility ());
-  auto method_name = method.get_method_name ().as_string ();
-  auto qualifiers = method.get_qualifiers ();
-  visit (qualifiers);
-
-  push (Rust::Token::make (FN_TOK, method.get_locus ()));
-  push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move 
(method_name)));
-  push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
-
-  visit (method.get_self_param ());
-  if (!method.get_function_params ().empty ())
-    {
-      push (Rust::Token::make (COMMA, UNDEF_LOCATION));
-      visit_items_joined_by_separator (method.get_function_params (), COMMA);
-    }
-
-  push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
-
-  if (method.has_return_type ())
-    {
-      push (Rust::Token::make (RETURN_TYPE, UNDEF_LOCATION));
-      visit (method.get_return_type ());
-    }
-
-  auto &block = method.get_definition ();
-  if (!block)
-    push (Rust::Token::make (SEMICOLON, UNDEF_LOCATION));
-  else
-    visit (block);
-  newline ();
-}
-
 void
 TokenCollector::visit (Module &module)
 {
@@ -1817,6 +1782,14 @@ TokenCollector::visit (Function &function)
     visit (function.get_generic_params ());
 
   push (Rust::Token::make (LEFT_PAREN, UNDEF_LOCATION));
+
+  if (function.has_self_param ())
+    {
+      visit (function.get_self_param ());
+      if (!function.get_function_params ().empty ())
+       push (Rust::Token::make (COMMA, UNDEF_LOCATION));
+    }
+
   visit_items_joined_by_separator (function.get_function_params ());
   push (Rust::Token::make (RIGHT_PAREN, UNDEF_LOCATION));
 
diff --git a/gcc/rust/ast/rust-ast-collector.h 
b/gcc/rust/ast/rust-ast-collector.h
index 2dae423240e6..47655286dd9e 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -266,7 +266,6 @@ public:
   void visit (TypeParam &param);
   void visit (LifetimeWhereClauseItem &item);
   void visit (TypeBoundWhereClauseItem &item);
-  void visit (Method &method);
   void visit (Module &module);
   void visit (ExternCrate &crate);
   void visit (UseTreeGlob &use_tree);
diff --git a/gcc/rust/ast/rust-ast-full-decls.h 
b/gcc/rust/ast/rust-ast-full-decls.h
index 64b9b3d5f056..9e961f9878d6 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -171,7 +171,6 @@ class SelfParam;
 class FunctionQualifiers;
 class FunctionParam;
 struct Visibility;
-class Method;
 class VisItem;
 class Module;
 class ExternCrate;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index 4b954fdc9984..63f850f8c7c2 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -728,23 +728,6 @@ DefaultASTVisitor::visit (AST::FunctionParam &param)
     visit (param.get_type ());
 }
 
-void
-DefaultASTVisitor::visit (AST::Method &method)
-{
-  visit_outer_attrs (method);
-  visit (method.get_visibility ());
-  visit (method.get_qualifiers ());
-  for (auto &generic : method.get_generic_params ())
-    visit (generic);
-  visit (method.get_self_param ());
-  for (auto &param : method.get_function_params ())
-    visit (param);
-  if (method.has_return_type ())
-    visit (method.get_return_type ());
-  visit (method.get_where_clause ());
-  visit (method.get_definition ());
-}
-
 void
 DefaultASTVisitor::visit (AST::Module &module)
 {
@@ -794,6 +777,8 @@ DefaultASTVisitor::visit (AST::Function &function)
   visit (function.get_qualifiers ());
   for (auto &generic : function.get_generic_params ())
     visit (generic);
+  if (function.has_self_param ())
+    visit (function.get_self_param ());
   for (auto &param : function.get_function_params ())
     visit (param);
   if (function.has_return_type ())
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 94029479a385..98eab19ad3cf 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -132,7 +132,6 @@ public:
   // virtual void visit(WhereClauseItem& item) = 0;
   virtual void visit (LifetimeWhereClauseItem &item) = 0;
   virtual void visit (TypeBoundWhereClauseItem &item) = 0;
-  virtual void visit (Method &method) = 0;
   virtual void visit (Module &module) = 0;
   virtual void visit (ExternCrate &crate) = 0;
   // virtual void visit(UseTree& use_tree) = 0;
@@ -308,7 +307,6 @@ protected:
   virtual void visit (AST::TypeParam &param) override;
   virtual void visit (AST::LifetimeWhereClauseItem &item) override;
   virtual void visit (AST::TypeBoundWhereClauseItem &item) override;
-  virtual void visit (AST::Method &method) override;
   virtual void visit (AST::Module &module) override;
   virtual void visit (AST::ExternCrate &crate) override;
   virtual void visit (AST::UseTreeGlob &use_tree) override;
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index b67a13b95be5..9c6862e92610 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -725,69 +725,6 @@ InherentImpl::as_string () const
   return str;
 }
 
-std::string
-Method::as_string () const
-{
-  std::string str ("Method: \n ");
-
-  str += vis.as_string () + " " + qualifiers.as_string ();
-
-  str += " fn " + method_name.as_string ();
-
-  // generic params
-  str += "\n Generic params: ";
-  if (generic_params.empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &param : generic_params)
-       {
-         // DEBUG: null pointer check
-         if (param == nullptr)
-           {
-             rust_debug (
-               "something really terrible has gone wrong - null pointer "
-               "generic param in method.");
-             return "NULL_POINTER_MARK";
-           }
-
-         str += "\n  " + param->as_string ();
-       }
-    }
-
-  str += "\n Self param: " + self_param.as_string ();
-
-  str += "\n Function params: ";
-  if (function_params.empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &param : function_params)
-       str += "\n  " + param.as_string ();
-    }
-
-  str += "\n Return type: ";
-  if (has_return_type ())
-    str += return_type->as_string ();
-  else
-    str += "none (void)";
-
-  str += "\n Where clause: ";
-  if (has_where_clause ())
-    str += where_clause.as_string ();
-  else
-    str += "none";
-
-  str += "\n Block expr (body): \n  ";
-  str += function_body->as_string ();
-
-  return str;
-}
-
 std::string
 StructStruct::as_string () const
 {
@@ -4883,12 +4820,6 @@ TypeBoundWhereClauseItem::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
-void
-Method::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 Module::accept_vis (ASTVisitor &vis)
 {
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 97bc8d701966..0e38103e81d5 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -755,214 +755,6 @@ protected:
   }
 };
 
-// A method (function belonging to a type)
-class Method : public InherentImplItem, public TraitImplItem
-{
-  std::vector<Attribute> outer_attrs;
-  Visibility vis;
-  FunctionQualifiers qualifiers;
-  Identifier method_name;
-  std::vector<std::unique_ptr<GenericParam>> generic_params;
-  SelfParam self_param;
-  std::vector<FunctionParam> function_params;
-  std::unique_ptr<Type> return_type;
-  WhereClause where_clause;
-  std::unique_ptr<BlockExpr> function_body;
-  location_t locus;
-  NodeId node_id;
-  bool is_default;
-
-public:
-  // Returns whether the method is in an error state.
-  bool is_error () const
-  {
-    return function_body == nullptr || method_name.empty ()
-          || self_param.is_error ();
-  }
-
-  // Creates an error state method.
-  static Method create_error ()
-  {
-    return Method ({""}, FunctionQualifiers (UNDEF_LOCATION, NONE, true),
-                  std::vector<std::unique_ptr<GenericParam>> (),
-                  SelfParam::create_error (), std::vector<FunctionParam> (),
-                  nullptr, WhereClause::create_empty (), nullptr,
-                  Visibility::create_error (), std::vector<Attribute> (), {});
-  }
-
-  // Returns whether the method has generic parameters.
-  bool has_generics () const { return !generic_params.empty (); }
-
-  // Returns whether the method has parameters.
-  bool has_params () const { return !function_params.empty (); }
-
-  // Returns whether the method has a return type (void otherwise).
-  bool has_return_type () const { return return_type != nullptr; }
-
-  // Returns whether the where clause exists (i.e. has items)
-  bool has_where_clause () const { return !where_clause.is_empty (); }
-
-  // Returns whether method has a non-default visibility.
-  bool has_visibility () const { return !vis.is_error (); }
-
-  // Mega-constructor with all possible fields
-  Method (Identifier method_name, FunctionQualifiers qualifiers,
-         std::vector<std::unique_ptr<GenericParam>> generic_params,
-         SelfParam self_param, std::vector<FunctionParam> function_params,
-         std::unique_ptr<Type> return_type, WhereClause where_clause,
-         std::unique_ptr<BlockExpr> function_body, Visibility vis,
-         std::vector<Attribute> outer_attrs, location_t locus,
-         bool is_default = false)
-    : outer_attrs (std::move (outer_attrs)), vis (std::move (vis)),
-      qualifiers (std::move (qualifiers)),
-      method_name (std::move (method_name)),
-      generic_params (std::move (generic_params)),
-      self_param (std::move (self_param)),
-      function_params (std::move (function_params)),
-      return_type (std::move (return_type)),
-      where_clause (std::move (where_clause)),
-      function_body (std::move (function_body)), locus (locus),
-      node_id (Analysis::Mappings::get ()->get_next_node_id ()),
-      is_default (is_default)
-  {}
-
-  // TODO: add constructor with less fields
-
-  // Copy constructor with clone
-  Method (Method const &other)
-    : outer_attrs (other.outer_attrs), vis (other.vis),
-      qualifiers (other.qualifiers), method_name (other.method_name),
-      self_param (other.self_param), function_params (other.function_params),
-      where_clause (other.where_clause), locus (other.locus),
-      is_default (other.is_default)
-  {
-    // guard to prevent null dereference (always required)
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-
-    // guard to prevent null dereference (only required if error state)
-    if (other.function_body != nullptr)
-      function_body = other.function_body->clone_block_expr ();
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    node_id = other.node_id;
-  }
-
-  // Overloaded assignment operator to clone
-  Method &operator= (Method const &other)
-  {
-    method_name = other.method_name;
-    outer_attrs = other.outer_attrs;
-    vis = other.vis;
-    qualifiers = other.qualifiers;
-    self_param = other.self_param;
-    function_params = other.function_params;
-    where_clause = other.where_clause;
-    locus = other.locus;
-    is_default = other.is_default;
-
-    // guard to prevent null dereference (always required)
-    if (other.return_type != nullptr)
-      return_type = other.return_type->clone_type ();
-    else
-      return_type = nullptr;
-
-    // guard to prevent null dereference (only required if error state)
-    if (other.function_body != nullptr)
-      function_body = other.function_body->clone_block_expr ();
-    else
-      function_body = nullptr;
-
-    generic_params.reserve (other.generic_params.size ());
-    for (const auto &e : other.generic_params)
-      generic_params.push_back (e->clone_generic_param ());
-
-    node_id = other.node_id;
-
-    return *this;
-  }
-
-  // move constructors
-  Method (Method &&other) = default;
-  Method &operator= (Method &&other) = default;
-
-  std::string as_string () const override;
-
-  void accept_vis (ASTVisitor &vis) override;
-
-  // Invalid if block is null, so base stripping on that.
-  void mark_for_strip () override { function_body = nullptr; }
-  bool is_marked_for_strip () const override
-  {
-    return function_body == nullptr;
-  }
-
-  // TODO: this mutable getter seems really dodgy. Think up better way.
-  std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
-  const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; 
}
-
-  std::vector<FunctionParam> &get_function_params () { return function_params; 
}
-  const std::vector<FunctionParam> &get_function_params () const
-  {
-    return function_params;
-  }
-
-  std::vector<std::unique_ptr<GenericParam>> &get_generic_params ()
-  {
-    return generic_params;
-  }
-  const std::vector<std::unique_ptr<GenericParam>> &get_generic_params () const
-  {
-    return generic_params;
-  }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<BlockExpr> &get_definition ()
-  {
-    rust_assert (function_body != nullptr);
-    return function_body;
-  }
-
-  SelfParam &get_self_param () { return self_param; }
-  const SelfParam &get_self_param () const { return self_param; }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  std::unique_ptr<Type> &get_return_type ()
-  {
-    rust_assert (has_return_type ());
-    return return_type;
-  }
-
-  // TODO: is this better? Or is a "vis_block" better?
-  WhereClause &get_where_clause () { return where_clause; }
-
-  Identifier get_method_name () const { return method_name; }
-
-  NodeId get_node_id () const { return node_id; }
-
-  location_t get_locus () const override final { return locus; }
-
-  FunctionQualifiers get_qualifiers () const { return qualifiers; }
-
-  FunctionQualifiers &get_qualifiers () { return qualifiers; }
-
-  Visibility &get_visibility () { return vis; }
-  const Visibility &get_visibility () const { return vis; }
-
-protected:
-  /* Use covariance to implement clone function as returning this object
-   * rather than base */
-  Method *clone_associated_item_impl () const final override
-  {
-    return clone_method_impl ();
-  }
-
-  /*virtual*/ Method *clone_method_impl () const { return new Method (*this); }
-};
-
 // Item that supports visibility - abstract base class
 class VisItem : public Item
 {
@@ -1580,6 +1372,7 @@ class Function : public VisItem, public InherentImplItem, 
public TraitImplItem
   FunctionQualifiers qualifiers;
   Identifier function_name;
   std::vector<std::unique_ptr<GenericParam>> generic_params;
+  tl::optional<SelfParam> self_param;
   std::vector<FunctionParam> function_params;
   std::unique_ptr<Type> return_type;
   WhereClause where_clause;
@@ -1602,9 +1395,12 @@ public:
   // Returns whether function has a where clause.
   bool has_where_clause () const { return !where_clause.is_empty (); }
 
+  bool has_self_param () const { return self_param.has_value (); }
+
   // Mega-constructor with all possible fields
   Function (Identifier function_name, FunctionQualifiers qualifiers,
            std::vector<std::unique_ptr<GenericParam>> generic_params,
+           tl::optional<SelfParam> self_param,
            std::vector<FunctionParam> function_params,
            std::unique_ptr<Type> return_type, WhereClause where_clause,
            std::unique_ptr<BlockExpr> function_body, Visibility vis,
@@ -1614,6 +1410,7 @@ public:
       qualifiers (std::move (qualifiers)),
       function_name (std::move (function_name)),
       generic_params (std::move (generic_params)),
+      self_param (std::move (self_param)),
       function_params (std::move (function_params)),
       return_type (std::move (return_type)),
       where_clause (std::move (where_clause)),
@@ -1626,7 +1423,7 @@ public:
   // Copy constructor with clone
   Function (Function const &other)
     : VisItem (other), qualifiers (other.qualifiers),
-      function_name (other.function_name),
+      function_name (other.function_name), self_param (other.self_param),
       function_params (other.function_params),
       where_clause (other.where_clause), locus (other.locus),
       is_default (other.is_default)
@@ -1650,6 +1447,7 @@ public:
     VisItem::operator= (other);
     function_name = other.function_name;
     qualifiers = other.qualifiers;
+    self_param = other.self_param;
     function_params = other.function_params;
     where_clause = other.where_clause;
     // visibility = other.visibility->clone_visibility();
@@ -1735,6 +1533,17 @@ public:
     return return_type;
   }
 
+  SelfParam &get_self_param ()
+  {
+    rust_assert (has_self_param ());
+    return self_param.value ();
+  }
+  const SelfParam &get_self_param () const
+  {
+    rust_assert (has_self_param ());
+    return self_param.value ();
+  }
+
 protected:
   /* Use covariance to implement clone function as returning this object
    * rather than base */
diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc 
b/gcc/rust/checks/errors/rust-feature-gate.cc
index 8e940dbb5ade..91ef85edfba7 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.cc
+++ b/gcc/rust/checks/errors/rust-feature-gate.cc
@@ -147,12 +147,6 @@ FeatureGate::visit (AST::TraitImpl &impl)
     }
 }
 
-void
-FeatureGate::visit (AST::Method &method)
-{
-  check_rustc_attri (method.get_outer_attrs ());
-}
-
 void
 FeatureGate::visit (AST::Function &function)
 {
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h 
b/gcc/rust/checks/errors/rust-feature-gate.h
index f06fd8c8d7e2..298582d4e94d 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -104,7 +104,6 @@ public:
   void visit (AST::TypeParam &param) override {}
   void visit (AST::LifetimeWhereClauseItem &item) override {}
   void visit (AST::TypeBoundWhereClauseItem &item) override {}
-  void visit (AST::Method &method) override;
   void visit (AST::Module &module) override {}
   void visit (AST::ExternCrate &crate) override {}
   void visit (AST::UseTreeGlob &use_tree) override {}
diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index 731d8fd1e448..6bf3a2591963 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -1945,53 +1945,6 @@ CfgStrip::visit (AST::TypeBoundWhereClauseItem &item)
     bound->accept_vis (*this);
 }
 void
-CfgStrip::visit (AST::Method &method)
-{
-  // initial test based on outer attrs
-  expand_cfg_attrs (method.get_outer_attrs ());
-  if (fails_cfg_with_expand (method.get_outer_attrs ()))
-    {
-      method.mark_for_strip ();
-      return;
-    }
-
-  // just expand sub-stuff - can't actually strip generic params themselves
-  for (auto &param : method.get_generic_params ())
-    param->accept_vis (*this);
-
-  /* assuming you can't strip self param - wouldn't be a method
-   * anymore. spec allows outer attrs on self param, but doesn't
-   * specify whether cfg is used. */
-  maybe_strip_self_param (method.get_self_param ());
-
-  /* strip method parameters if required - this is specifically
-   * allowed by spec */
-  maybe_strip_function_params (method.get_function_params ());
-
-  if (method.has_return_type ())
-    {
-      auto &return_type = method.get_return_type ();
-      return_type->accept_vis (*this);
-
-      if (return_type->is_marked_for_strip ())
-       rust_error_at (return_type->get_locus (),
-                      "cannot strip type in this position");
-    }
-
-  if (method.has_where_clause ())
-    maybe_strip_where_clause (method.get_where_clause ());
-
-  /* body should always exist - if error state, should have returned
-   * before now */
-  // can't strip block itself, but can strip sub-expressions
-  auto &block_expr = method.get_definition ();
-  block_expr->accept_vis (*this);
-  if (block_expr->is_marked_for_strip ())
-    rust_error_at (block_expr->get_locus (),
-                  "cannot strip block expression in this position - outer "
-                  "attributes not allowed");
-}
-void
 CfgStrip::visit (AST::Module &module)
 {
   // strip test based on outer attrs
@@ -2076,6 +2029,13 @@ CfgStrip::visit (AST::Function &function)
   for (auto &param : function.get_generic_params ())
     param->accept_vis (*this);
 
+  /* assuming you can't strip self param - wouldn't be a method
+   * anymore. spec allows outer attrs on self param, but doesn't
+   * specify whether cfg is used. */
+  // TODO: verify this
+  if (function.has_self_param ())
+    maybe_strip_self_param (function.get_self_param ());
+
   /* strip function parameters if required - this is specifically
    * allowed by spec */
   maybe_strip_function_params (function.get_function_params ());
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index 7235bfa5a0e3..b3bb3fbe4cee 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -140,7 +140,6 @@ public:
   void visit (AST::TypeParam &param) override;
   void visit (AST::LifetimeWhereClauseItem &) override;
   void visit (AST::TypeBoundWhereClauseItem &item) override;
-  void visit (AST::Method &method) override;
   void visit (AST::Module &module) override;
   void visit (AST::ExternCrate &crate) override;
   void visit (AST::UseTreeGlob &) override;
diff --git a/gcc/rust/expand/rust-derive-clone.cc 
b/gcc/rust/expand/rust-derive-clone.cc
index cac309946576..28ce402dde7e 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -51,11 +51,12 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
   auto big_self_type = builder.single_type_path ("Self");
 
   return std::unique_ptr<TraitImplItem> (
-    new Method ({"clone"}, builder.fn_qualifiers (), /* generics */ {},
-               SelfParam (Lifetime::error (), /* is_mut */ false, loc),
-               /* function params */ {}, std::move (big_self_type),
-               WhereClause::create_empty (), std::move (block),
-               Visibility::create_private (), {}, loc));
+    new Function ({"clone"}, builder.fn_qualifiers (), /* generics */ {},
+                 tl::optional<SelfParam> (tl::in_place, Lifetime::error (),
+                                          /* is_mut */ false, loc),
+                 /* function params */ {}, std::move (big_self_type),
+                 WhereClause::create_empty (), std::move (block),
+                 Visibility::create_private (), {}, loc));
 }
 
 /**
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index f315f060ef81..915c0545cbe5 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -145,7 +145,6 @@ private:
   virtual void visit (TypeParam &param) override final{};
   virtual void visit (LifetimeWhereClauseItem &item) override final{};
   virtual void visit (TypeBoundWhereClauseItem &item) override final{};
-  virtual void visit (Method &method) override final{};
   virtual void visit (Module &module) override final{};
   virtual void visit (ExternCrate &crate) override final{};
   virtual void visit (UseTreeGlob &use_tree) override final{};
diff --git a/gcc/rust/expand/rust-expand-visitor.cc 
b/gcc/rust/expand/rust-expand-visitor.cc
index cb9e8b6568ab..0dd6f592dba0 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -983,24 +983,6 @@ ExpandVisitor::visit (AST::TypeBoundWhereClauseItem &item)
     visit (bound);
 }
 
-void
-ExpandVisitor::visit (AST::Method &method)
-{
-  for (auto &param : method.get_generic_params ())
-    visit (param);
-
-  expand_self_param (method.get_self_param ());
-  expand_function_params (method.get_function_params ());
-
-  if (method.has_return_type ())
-    visit (method.get_return_type ());
-
-  if (method.has_where_clause ())
-    expand_where_clause (method.get_where_clause ());
-
-  visit (method.get_definition ());
-}
-
 void
 ExpandVisitor::visit (AST::Module &module)
 {
@@ -1040,6 +1022,8 @@ ExpandVisitor::visit (AST::Function &function)
   for (auto &param : function.get_generic_params ())
     visit (param);
 
+  if (function.has_self_param ())
+    expand_self_param (function.get_self_param ());
   expand_function_params (function.get_function_params ());
 
   if (function.has_return_type ())
diff --git a/gcc/rust/expand/rust-expand-visitor.h 
b/gcc/rust/expand/rust-expand-visitor.h
index a88c91e81f8e..d7612acd385f 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -265,7 +265,6 @@ public:
   void visit (AST::TypeParam &param) override;
   void visit (AST::LifetimeWhereClauseItem &) override;
   void visit (AST::TypeBoundWhereClauseItem &item) override;
-  void visit (AST::Method &method) override;
   void visit (AST::Module &module) override;
   void visit (AST::ExternCrate &crate) override;
   void visit (AST::UseTreeGlob &) override;
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc 
b/gcc/rust/hir/rust-ast-lower-base.cc
index 75a3398e5e9a..5f6d6febb7f7 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -264,9 +264,6 @@ void
 ASTLoweringBase::visit (AST::TypeBoundWhereClauseItem &)
 {}
 void
-ASTLoweringBase::visit (AST::Method &)
-{}
-void
 ASTLoweringBase::visit (AST::Module &)
 {}
 void
diff --git a/gcc/rust/hir/rust-ast-lower-base.h 
b/gcc/rust/hir/rust-ast-lower-base.h
index 7b92e7b6e0b3..a9411c22f50f 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -158,7 +158,6 @@ public:
   //  virtual void visit(WhereClauseItem& item);
   virtual void visit (AST::LifetimeWhereClauseItem &item);
   virtual void visit (AST::TypeBoundWhereClauseItem &item);
-  virtual void visit (AST::Method &method);
   virtual void visit (AST::Module &module);
   virtual void visit (AST::ExternCrate &crate);
   //  virtual void visit(UseTree& use_tree);
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h 
b/gcc/rust/hir/rust-ast-lower-implitem.h
index abb0227426a1..2a0d9fc0e436 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -131,6 +131,10 @@ public:
     Identifier function_name = function.get_function_name ();
     location_t locus = function.get_locus ();
 
+    HIR::SelfParam self_param = HIR::SelfParam::error ();
+    if (function.has_self_param ())
+      self_param = lower_self (function.get_self_param ());
+
     std::unique_ptr<HIR::Type> return_type
       = function.has_return_type () ? std::unique_ptr<HIR::Type> (
          ASTLoweringType::translate (function.get_return_type ().get ()))
@@ -176,104 +180,26 @@ public:
                           std::move (function_params), std::move (return_type),
                           std::move (where_clause), std::move (function_body),
                           std::move (vis), function.get_outer_attrs (),
-                          HIR::SelfParam::error (), locus);
-
-    // add the mappings for the function params at the end
-    for (auto &param : fn->get_function_params ())
-      {
-       mappings->insert_hir_param (&param);
-       mappings->insert_location (mapping.get_hirid (), param.get_locus ());
-      }
-
-    translated = fn;
-    item_cast = fn;
-  }
-
-  void visit (AST::Method &method) override
-  {
-    // ignore for now and leave empty
-    std::vector<std::unique_ptr<HIR::WhereClauseItem> > where_clause_items;
-    for (auto &item : method.get_where_clause ().get_items ())
-      {
-       HIR::WhereClauseItem *i
-         = ASTLowerWhereClauseItem::translate (*item.get ());
-       where_clause_items.push_back (
-         std::unique_ptr<HIR::WhereClauseItem> (i));
-      }
-
-    HIR::WhereClause where_clause (std::move (where_clause_items));
-    HIR::FunctionQualifiers qualifiers
-      = lower_qualifiers (method.get_qualifiers ());
-    HIR::Visibility vis = translate_visibility (method.get_visibility ());
-
-    // need
-    std::vector<std::unique_ptr<HIR::GenericParam> > generic_params;
-    if (method.has_generics ())
-      {
-       generic_params = lower_generic_params (method.get_generic_params ());
-      }
-    Identifier method_name = method.get_method_name ();
-    location_t locus = method.get_locus ();
-
-    HIR::SelfParam self_param = lower_self (method.get_self_param ());
-
-    std::unique_ptr<HIR::Type> return_type
-      = method.has_return_type () ? std::unique_ptr<HIR::Type> (
-         ASTLoweringType::translate (method.get_return_type ().get ()))
-                                 : nullptr;
+                          std::move (self_param), locus);
 
-    std::vector<HIR::FunctionParam> function_params;
-    for (auto &param : method.get_function_params ())
+    if (!fn->get_self_param ().is_error ())
       {
-       auto translated_pattern = std::unique_ptr<HIR::Pattern> (
-         ASTLoweringPattern::translate (param.get_pattern ().get ()));
-       auto translated_type = std::unique_ptr<HIR::Type> (
-         ASTLoweringType::translate (param.get_type ().get ()));
-
-       auto crate_num = mappings->get_current_crate ();
-       Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
-                                      mappings->get_next_hir_id (crate_num),
-                                      UNKNOWN_LOCAL_DEFID);
-
-       auto hir_param
-         = HIR::FunctionParam (mapping, std::move (translated_pattern),
-                               std::move (translated_type),
-                               param.get_locus ());
-       function_params.push_back (std::move (hir_param));
+       // insert mappings for self
+       mappings->insert_hir_self_param (&fn->get_self_param ());
+       mappings->insert_location (
+         fn->get_self_param ().get_mappings ().get_hirid (),
+         fn->get_self_param ().get_locus ());
       }
 
-    bool terminated = false;
-    std::unique_ptr<HIR::BlockExpr> method_body
-      = std::unique_ptr<HIR::BlockExpr> (
-       ASTLoweringBlock::translate (method.get_definition ().get (),
-                                    &terminated));
-
-    auto crate_num = mappings->get_current_crate ();
-    Analysis::NodeMapping mapping (crate_num, method.get_node_id (),
-                                  mappings->get_next_hir_id (crate_num),
-                                  mappings->get_next_localdef_id (crate_num));
-    auto mth
-      = new HIR::Function (mapping, std::move (method_name),
-                          std::move (qualifiers), std::move (generic_params),
-                          std::move (function_params), std::move (return_type),
-                          std::move (where_clause), std::move (method_body),
-                          std::move (vis), method.get_outer_attrs (),
-                          std::move (self_param), locus);
-
-    // insert mappings for self
-    mappings->insert_hir_self_param (&self_param);
-    mappings->insert_location (self_param.get_mappings ().get_hirid (),
-                              self_param.get_locus ());
-
     // add the mappings for the function params at the end
-    for (auto &param : mth->get_function_params ())
+    for (auto &param : fn->get_function_params ())
       {
        mappings->insert_hir_param (&param);
        mappings->insert_location (mapping.get_hirid (), param.get_locus ());
       }
 
-    translated = mth;
-    item_cast = mth;
+    translated = fn;
+    item_cast = fn;
   }
 
 private:
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index f08ab692e983..e1d73887d864 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -29,6 +29,8 @@
 #include "rust-dir-owner.h"
 #include "rust-attribute-values.h"
 
+#include "optional.h"
+
 namespace Rust {
 // Left binding powers of operations.
 enum binding_powers
@@ -2903,10 +2905,11 @@ Parser<ManagedTokenSource>::parse_function 
(AST::Visibility vis,
 
   return std::unique_ptr<AST::Function> (
     new AST::Function (std::move (function_name), std::move (qualifiers),
-                      std::move (generic_params), std::move (function_params),
-                      std::move (return_type), std::move (where_clause),
-                      std::move (block_expr), std::move (vis),
-                      std::move (outer_attrs), locus));
+                      std::move (generic_params),
+                      tl::optional<AST::SelfParam> (),
+                      std::move (function_params), std::move (return_type),
+                      std::move (where_clause), std::move (block_expr),
+                      std::move (vis), std::move (outer_attrs), locus));
 }
 
 // Parses function or method qualifiers (i.e. const, unsafe, and extern).
@@ -5645,18 +5648,18 @@ 
Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
   // do actual if instead of ternary for return value optimisation
   if (is_method)
     {
-      return std::unique_ptr<AST::Method> (
-       new AST::Method (std::move (ident), std::move (qualifiers),
-                        std::move (generic_params), std::move (self_param),
-                        std::move (function_params), std::move (return_type),
-                        std::move (where_clause), std::move (body),
-                        std::move (vis), std::move (outer_attrs), locus));
+      return std::unique_ptr<AST::Function> (new AST::Function (
+       std::move (ident), std::move (qualifiers), std::move (generic_params),
+       tl::optional<AST::SelfParam> (tl::in_place, std::move (self_param)),
+       std::move (function_params), std::move (return_type),
+       std::move (where_clause), std::move (body), std::move (vis),
+       std::move (outer_attrs), locus));
     }
   else
     {
       return std::unique_ptr<AST::Function> (
        new AST::Function (std::move (ident), std::move (qualifiers),
-                          std::move (generic_params),
+                          std::move (generic_params), tl::nullopt,
                           std::move (function_params), std::move (return_type),
                           std::move (where_clause), std::move (body),
                           std::move (vis), std::move (outer_attrs), locus));
@@ -5884,17 +5887,18 @@ 
Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
   // do actual if instead of ternary for return value optimisation
   if (is_method)
     {
-      return std::unique_ptr<AST::Method> (new AST::Method (
+      return std::unique_ptr<AST::Function> (new AST::Function (
        std::move (ident), std::move (qualifiers), std::move (generic_params),
-       std::move (self_param), std::move (function_params),
-       std::move (return_type), std::move (where_clause), std::move (body),
-       std::move (vis), std::move (outer_attrs), locus, is_default));
+       tl::optional<AST::SelfParam> (tl::in_place, std::move (self_param)),
+       std::move (function_params), std::move (return_type),
+       std::move (where_clause), std::move (body), std::move (vis),
+       std::move (outer_attrs), locus, is_default));
     }
   else
     {
       return std::unique_ptr<AST::Function> (new AST::Function (
        std::move (ident), std::move (qualifiers), std::move (generic_params),
-       std::move (function_params), std::move (return_type),
+       tl::nullopt, std::move (function_params), std::move (return_type),
        std::move (where_clause), std::move (body), std::move (vis),
        std::move (outer_attrs), locus, is_default));
     }
@@ -7188,7 +7192,7 @@ Parser<ManagedTokenSource>::parse_self_param ()
  * resolve it into whatever it is afterward. As such, this is only here for
  * algorithmically defining the grammar rule. */
 template <typename ManagedTokenSource>
-AST::Method
+std::unique_ptr<AST::Function>
 Parser<ManagedTokenSource>::parse_method ()
 {
   location_t locus = lexer.peek_token ()->get_locus ();
@@ -7202,7 +7206,7 @@ Parser<ManagedTokenSource>::parse_method ()
   if (ident_tok == nullptr)
     {
       skip_after_next_block ();
-      return AST::Method::create_error ();
+      return nullptr;
     }
   Identifier method_name{ident_tok};
 
@@ -7217,7 +7221,7 @@ Parser<ManagedTokenSource>::parse_method ()
       add_error (std::move (error));
 
       skip_after_next_block ();
-      return AST::Method::create_error ();
+      return nullptr;
     }
 
   // parse self param
@@ -7229,7 +7233,7 @@ Parser<ManagedTokenSource>::parse_method ()
       add_error (std::move (error));
 
       skip_after_next_block ();
-      return AST::Method::create_error ();
+      return nullptr;
     }
 
   // skip comma if it exists
@@ -7248,7 +7252,7 @@ Parser<ManagedTokenSource>::parse_method ()
       add_error (std::move (error));
 
       skip_after_next_block ();
-      return AST::Method::create_error ();
+      return nullptr;
     }
 
   // parse function return type - if exists
@@ -7266,15 +7270,16 @@ Parser<ManagedTokenSource>::parse_method ()
       add_error (std::move (error));
 
       skip_after_end_block ();
-      return AST::Method::create_error ();
+      return nullptr;
     }
 
   // does not parse visibility, but this method isn't used, so doesn't matter
-  return AST::Method (std::move (method_name), std::move (qualifiers),
-                     std::move (generic_params), std::move (self_param),
-                     std::move (function_params), std::move (return_type),
-                     std::move (where_clause), std::move (block_expr),
-                     AST::Visibility::create_error (), AST::AttrVec (), locus);
+  return std::unique_ptr<AST::Function> (new AST::Function (
+    std::move (method_name), std::move (qualifiers), std::move 
(generic_params),
+    tl::optional<AST::SelfParam> (tl::in_place, std::move (self_param)),
+    std::move (function_params), std::move (return_type),
+    std::move (where_clause), std::move (block_expr),
+    AST::Visibility::create_error (), AST::AttrVec (), locus));
 }
 
 /* Parses an expression or macro statement. */
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index e4322754c701..3ff9b99caed0 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -345,7 +345,7 @@ private:
                                       AST::AttrVec outer_attrs);
   std::unique_ptr<AST::ExternBlock>
   parse_extern_block (AST::Visibility vis, AST::AttrVec outer_attrs);
-  AST::Method parse_method ();
+  std::unique_ptr<AST::Function> parse_method ();
 
   // Expression-related (Pratt parsed)
   std::unique_ptr<AST::Expr>
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc 
b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 3bd7e4a6a025..14af4307fb7f 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -330,10 +330,6 @@ void
 ResolverBase::visit (AST::TypeBoundWhereClauseItem &)
 {}
 
-void
-ResolverBase::visit (AST::Method &)
-{}
-
 void
 ResolverBase::visit (AST::Module &)
 {}
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h 
b/gcc/rust/resolve/rust-ast-resolve-base.h
index bef7f3dd2989..9c124b11999a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -107,7 +107,6 @@ public:
 
   void visit (AST::LifetimeWhereClauseItem &);
   void visit (AST::TypeBoundWhereClauseItem &);
-  void visit (AST::Method &);
   void visit (AST::Module &);
   void visit (AST::ExternCrate &);
 
diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h 
b/gcc/rust/resolve/rust-ast-resolve-implitem.h
index aa7ffe3d796b..d37562b77989 100644
--- a/gcc/rust/resolve/rust-ast-resolve-implitem.h
+++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h
@@ -88,22 +88,6 @@ public:
       });
   }
 
-  void visit (AST::Method &method) override
-  {
-    auto decl = CanonicalPath::new_seg (method.get_node_id (),
-                                       method.get_method_name ().as_string ());
-    auto path = prefix.append (decl);
-
-    resolver->get_name_scope ().insert (
-      path, method.get_node_id (), method.get_locus (), false,
-      Rib::ItemType::Function,
-      [&] (const CanonicalPath &, NodeId, location_t locus) -> void {
-       rich_location r (line_table, method.get_locus ());
-       r.add_range (locus);
-       rust_error_at (r, "redefined multiple times");
-      });
-  }
-
 private:
   ResolveToplevelImplItem (const CanonicalPath &prefix)
     : ResolverBase (), prefix (prefix)
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc 
b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 96b739cb1241..5cd0a4d02844 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -524,6 +524,36 @@ ResolveItem::visit (AST::Function &function)
   if (function.has_return_type ())
     ResolveType::go (function.get_return_type ().get ());
 
+  if (function.has_self_param ())
+    {
+      // self turns into (self: Self) as a function param
+      AST::SelfParam &self_param = function.get_self_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 ().get ());
+       }
+      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> ())};
 
@@ -619,89 +649,6 @@ ResolveItem::visit (AST::InherentImpl &impl_block)
   resolver->get_name_scope ().pop ();
 }
 
-void
-ResolveItem::visit (AST::Method &method)
-{
-  auto decl = CanonicalPath::new_seg (method.get_node_id (),
-                                     method.get_method_name ().as_string ());
-  auto path = prefix.append (decl);
-  auto cpath = canonical_prefix.append (decl);
-  mappings->insert_canonical_path (method.get_node_id (), cpath);
-
-  NodeId scope_node_id = method.get_node_id ();
-
-  resolve_visibility (method.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_type_scope ().peek ());
-
-  if (method.has_generics ())
-    for (auto &generic : method.get_generic_params ())
-      ResolveGenericParam::go (generic.get (), prefix, canonical_prefix);
-
-  // resolve any where clause items
-  if (method.has_where_clause ())
-    ResolveWhereClause::Resolve (method.get_where_clause ());
-
-  if (method.has_return_type ())
-    ResolveType::go (method.get_return_type ().get ());
-
-  // self turns into (self: Self) as a function param
-  AST::SelfParam &self_param = method.get_self_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 ().get ());
-    }
-  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 &param : method.get_function_params ())
-    {
-      ResolveType::go (param.get_type ().get ());
-      PatternDeclaration::go (param.get_pattern ().get (), 
Rib::ItemType::Param,
-                             bindings);
-    }
-
-  // resolve any where clause items
-  if (method.has_where_clause ())
-    ResolveWhereClause::Resolve (method.get_where_clause ());
-
-  // resolve the function body
-  ResolveExpr::go (method.get_definition ().get (), path, cpath);
-
-  resolver->get_name_scope ().pop ();
-  resolver->get_type_scope ().pop ();
-  resolver->get_label_scope ().pop ();
-}
-
 void
 ResolveItem::visit (AST::TraitImpl &impl_block)
 {
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.h 
b/gcc/rust/resolve/rust-ast-resolve-item.h
index 273d5c1c9efd..affcf667a5c8 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.h
+++ b/gcc/rust/resolve/rust-ast-resolve-item.h
@@ -71,7 +71,6 @@ public:
   void visit (AST::ConstantItem &constant) override;
   void visit (AST::Function &function) override;
   void visit (AST::InherentImpl &impl_block) override;
-  void visit (AST::Method &method) override;
   void visit (AST::TraitImpl &impl_block) override;
   void visit (AST::Trait &trait) override;
   void visit (AST::ExternBlock &extern_block) override;
diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index 1d54f91e644e..fc81001689b2 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -67,22 +67,6 @@ DefaultResolver::visit (AST::Function &function)
   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)
 {
diff --git a/gcc/rust/resolve/rust-default-resolver.h 
b/gcc/rust/resolve/rust-default-resolver.h
index 03b4a5421a4f..8af9513b25c3 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -43,7 +43,6 @@ public:
   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 &);
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc 
b/gcc/rust/resolve/rust-early-name-resolver.cc
index 85f87131fc74..3a485a00cc6d 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -600,25 +600,6 @@ EarlyNameResolver::visit (AST::TypeBoundWhereClauseItem 
&item)
     bound->accept_vis (*this);
 }
 
-void
-EarlyNameResolver::visit (AST::Method &method)
-{
-  if (method.has_generics ())
-    for (auto &generic : method.get_generic_params ())
-      generic->accept_vis (*this);
-
-  if (method.get_self_param ().has_type ())
-    method.get_self_param ().get_type ()->accept_vis (*this);
-
-  for (auto &param : method.get_function_params ())
-    param.get_type ()->accept_vis (*this);
-
-  if (method.has_return_type ())
-    method.get_return_type ()->accept_vis (*this);
-
-  method.get_definition ()->accept_vis (*this);
-}
-
 void
 EarlyNameResolver::visit (AST::Module &module)
 {
@@ -681,6 +662,9 @@ EarlyNameResolver::visit (AST::Function &function)
     for (auto &generic : function.get_generic_params ())
       generic->accept_vis (*this);
 
+  if (function.has_self_param () && function.get_self_param ().has_type ())
+    function.get_self_param ().get_type ()->accept_vis (*this);
+
   for (auto &param : function.get_function_params ())
     param.get_type ()->accept_vis (*this);
 
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h 
b/gcc/rust/resolve/rust-early-name-resolver.h
index 44d1a1819dbb..005b34c84dcd 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -198,7 +198,6 @@ private:
   virtual void visit (AST::TypeParam &param);
   virtual void visit (AST::LifetimeWhereClauseItem &item);
   virtual void visit (AST::TypeBoundWhereClauseItem &item);
-  virtual void visit (AST::Method &method);
   virtual void visit (AST::Module &module);
   virtual void visit (AST::ExternCrate &crate);
   virtual void visit (AST::UseTreeGlob &use_tree);
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
index 486998dc6341..fc62db729b58 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -191,14 +191,6 @@ TopLevel::visit (AST::Function &function)
   ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
 }
 
-void
-TopLevel::visit (AST::Method &method)
-{
-  insert_or_error_out (method.get_method_name (), method, Namespace::Values);
-
-  method.get_definition ()->accept_vis (*this);
-}
-
 void
 TopLevel::visit (AST::BlockExpr &expr)
 {
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h 
b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
index b8ed106167c0..95187d7b3fdb 100644
--- a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -60,7 +60,6 @@ private:
   void visit (AST::Module &module) override;
   void visit (AST::MacroRulesDefinition &macro) override;
   void visit (AST::Function &function) override;
-  void visit (AST::Method &method) override;
   void visit (AST::BlockExpr &expr) override;
   void visit (AST::StaticItem &static_item) override;
   void visit (AST::TraitItemFunc &item) override;
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index 8515cc7424ef..c386edc3bc6a 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -575,12 +575,6 @@ void
 AttributeChecker::visit (AST::TypeBoundWhereClauseItem &)
 {}
 
-void
-AttributeChecker::visit (AST::Method &method)
-{
-  method.get_definition ()->accept_vis (*this);
-}
-
 void
 AttributeChecker::visit (AST::Module &module)
 {
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index b3b280605d31..c984cb7d8810 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -173,7 +173,6 @@ private:
   void visit (AST::TypeParam &param);
   void visit (AST::LifetimeWhereClauseItem &item);
   void visit (AST::TypeBoundWhereClauseItem &item);
-  void visit (AST::Method &method);
   void visit (AST::Module &module);
   void visit (AST::ExternCrate &crate);
   void visit (AST::UseTreeGlob &use_tree);

Reply via email to