diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index a7de948006b..ed264371db7 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -5108,132 +5108,9 @@ Parser<ManagedTokenSource>::parse_trait_item ()
     case ASYNC:
     case UNSAFE:
     case EXTERN_KW:
-      case FN_KW: {
-	/* function and method can't be disambiguated by lookahead alone
-	 * (without a lot of work and waste), so either make a
-	 * "parse_trait_function_or_method" or parse here mostly and pass in
-	 * most parameters (or if short enough, parse whole thing here). */
-	// parse function and method here
-
-	// parse function or method qualifiers
-	AST::FunctionQualifiers qualifiers = parse_function_qualifiers ();
-
-	skip_token (FN_KW);
-
-	// parse function or method name
-	const_TokenPtr ident_tok = expect_token (IDENTIFIER);
-	if (ident_tok == nullptr)
-	  return nullptr;
-
-	Identifier ident{ident_tok};
-
-	// parse generic params
-	std::vector<std::unique_ptr<AST::GenericParam>> generic_params
-	  = parse_generic_params_in_angles ();
-
-	if (!skip_token (LEFT_PAREN))
-	  {
-	    // skip after somewhere?
-	    return nullptr;
-	  }
-
-	/* now for function vs method disambiguation - method has opening
-	 * "self" param */
-	auto initial_param = parse_self_param ();
-	if (!initial_param.has_value () && initial_param.error () != NOT_SELF)
-	  return nullptr;
-	/* FIXME: ensure that self param doesn't accidently consume tokens for
-	 * a function */
-	bool is_method = false;
-	if (initial_param.has_value ())
-	  {
-	    if ((*initial_param)->is_self ())
-	      is_method = true;
-
-	    /* skip comma so function and method regular params can be parsed
-	     * in same way */
-	    if (lexer.peek_token ()->get_id () == COMMA)
-	      lexer.skip_token ();
-	  }
-
-	// parse trait function params
-	std::vector<std::unique_ptr<AST::Param>> function_params
-	  = parse_function_params (
-	    [] (TokenId id) { return id == RIGHT_PAREN; });
-
-	if (!skip_token (RIGHT_PAREN))
-	  {
-	    // skip after somewhere?
-	    return nullptr;
-	  }
-
-	if (initial_param.has_value ())
-	  function_params.insert (function_params.begin (),
-				  std::move (*initial_param));
-
-	// parse return type (optional)
-	std::unique_ptr<AST::Type> return_type = parse_function_return_type ();
-
-	// parse where clause (optional)
-	AST::WhereClause where_clause = parse_where_clause ();
-
-	// parse semicolon or function definition (in block)
-	const_TokenPtr t = lexer.peek_token ();
-	std::unique_ptr<AST::BlockExpr> definition = nullptr;
-	switch (t->get_id ())
-	  {
-	  case SEMICOLON:
-	    lexer.skip_token ();
-	    // definition is already nullptr, so don't need to change it
-	    break;
-	  case LEFT_CURLY:
-	    definition = parse_block_expr ();
-	    /* FIXME: are these outer attributes meant to be passed into the
-	     * block? */
-	    break;
-	  default:
-	    add_error (
-	      Error (t->get_locus (),
-		     "expected %<;%> or definiton at the end of trait %s "
-		     "definition - found %qs instead",
-		     is_method ? "method" : "function",
-		     t->get_token_description ()));
-
-	    // skip?
-	    return nullptr;
-	  }
+    case FN_KW:
+      return parse_function (std::move (vis), std::move (outer_attrs));
 
-	// do actual if instead of ternary for return value optimisation
-	if (is_method)
-	  {
-	    AST::TraitMethodDecl method_decl (std::move (ident),
-					      std::move (qualifiers),
-					      std::move (generic_params),
-					      std::move (function_params),
-					      std::move (return_type),
-					      std::move (where_clause));
-
-	    // TODO: does this (method_decl) need move?
-	    return std::unique_ptr<AST::TraitItemMethod> (
-	      new AST::TraitItemMethod (std::move (method_decl),
-					std::move (definition),
-					std::move (outer_attrs),
-					tok->get_locus ()));
-	  }
-	else
-	  {
-	    AST::TraitFunctionDecl function_decl (std::move (ident),
-						  std::move (qualifiers),
-						  std::move (generic_params),
-						  std::move (function_params),
-						  std::move (return_type),
-						  std::move (where_clause));
-
-	    return std::unique_ptr<AST::TraitItemFunc> (new AST::TraitItemFunc (
-	      std::move (function_decl), std::move (definition),
-	      std::move (outer_attrs), tok->get_locus ()));
-	  }
-      }
       default: {
 	// TODO: try and parse macro invocation semi - if fails, maybe error.
 	std::unique_ptr<AST::TraitItem> macro_invoc
