aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-collector.cc27
-rw-r--r--gcc/rust/ast/rust-ast-collector.h1
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc26
-rw-r--r--gcc/rust/ast/rust-ast-visitor.h10
-rw-r--r--gcc/rust/ast/rust-ast.cc146
-rw-r--r--gcc/rust/ast/rust-ast.h167
-rw-r--r--gcc/rust/ast/rust-expr.h1
-rw-r--r--gcc/rust/ast/rust-item.h549
-rw-r--r--gcc/rust/checks/errors/rust-ast-validation.cc15
-rw-r--r--gcc/rust/checks/errors/rust-ast-validation.h1
-rw-r--r--gcc/rust/checks/errors/rust-feature-gate.h3
-rw-r--r--gcc/rust/expand/rust-cfg-strip.cc95
-rw-r--r--gcc/rust/expand/rust-cfg-strip.h7
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc15
-rw-r--r--gcc/rust/expand/rust-derive.h3
-rw-r--r--gcc/rust/expand/rust-expand-visitor.cc45
-rw-r--r--gcc/rust/expand/rust-expand-visitor.h7
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc37
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.h5
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.h45
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc15
-rw-r--r--gcc/rust/metadata/rust-export-metadata.cc17
-rw-r--r--gcc/rust/parse/rust-parse-impl.h283
-rw-r--r--gcc/rust/parse/rust-parse.h30
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.cc12
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-base.h3
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-item.cc143
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-stmt.h26
-rw-r--r--gcc/rust/resolve/rust-default-resolver.cc34
-rw-r--r--gcc/rust/resolve/rust-default-resolver.h3
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.cc38
-rw-r--r--gcc/rust/resolve/rust-early-name-resolver.h4
-rw-r--r--gcc/rust/util/rust-attributes.cc12
-rw-r--r--gcc/rust/util/rust-attributes.h3
34 files changed, 1089 insertions, 739 deletions
diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index 8326072..05c9630 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -16,6 +16,7 @@
// along with GCC; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
#include "rust-ast-collector.h"
+#include "rust-item.h"
namespace Rust {
namespace AST {
@@ -191,6 +192,17 @@ TokenCollector::visit (FunctionParam &param)
}
void
+TokenCollector::visit (VariadicParam &param)
+{
+ if (param.has_pattern ())
+ {
+ visit (param.get_pattern ());
+ push (Rust::Token::make (COLON, UNDEF_LOCATION));
+ }
+ push (Rust::Token::make (ELLIPSIS, UNDEF_LOCATION));
+}
+
+void
TokenCollector::visit (Attribute &attrib)
{
push (Rust::Token::make (HASH, attrib.get_locus ()));
@@ -1783,13 +1795,6 @@ TokenCollector::visit (Function &function)
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));
@@ -2069,13 +2074,7 @@ TokenCollector::visit (TraitItemMethod &item)
push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (id)));
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);
- }
+ visit_items_joined_by_separator (method.get_function_params (), COMMA);
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 4765528..20ffd8e 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -163,6 +163,7 @@ public:
void visit (Literal &lit, location_t locus = UNDEF_LOCATION);
void visit (FunctionParam &param);
+ void visit (VariadicParam &param);
void visit (Attribute &attrib);
void visit (Visibility &vis);
void visit (std::vector<std::unique_ptr<GenericParam>> &params);
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index b4d1011..d839582 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -708,12 +708,6 @@ DefaultASTVisitor::visit (AST::FunctionQualifiers &qualifiers)
{}
void
-DefaultASTVisitor::visit (AST::SelfParam &self)
-{
- visit (self.get_lifetime ());
-}
-
-void
DefaultASTVisitor::visit (AST::WhereClause &where)
{
for (auto &item : where.get_items ())
@@ -726,7 +720,18 @@ DefaultASTVisitor::visit (AST::FunctionParam &param)
if (param.has_name ())
visit (param.get_pattern ());
- if (!param.is_variadic ())
+ visit (param.get_type ());
+}
+
+void
+DefaultASTVisitor::visit (AST::SelfParam &param)
+{
+ visit_outer_attrs (param);
+
+ if (param.has_lifetime ())
+ visit (param.get_lifetime ());
+
+ if (param.has_type ())
visit (param.get_type ());
}
@@ -1439,6 +1444,13 @@ DefaultASTVisitor::visit (AST::BareFunctionType &type)
}
void
+DefaultASTVisitor::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ visit (param.get_pattern ());
+}
+
+void
ContextualASTVisitor::visit (AST::Crate &crate)
{
push_context (Context::CRATE);
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index 48b3de5..00886f6 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -23,6 +23,7 @@
// full include not required - only forward decls
#include "rust-ast-full-decls.h"
#include "rust-ast.h"
+#include "rust-item.h"
#include "rust-system.h"
namespace Rust {
@@ -129,6 +130,10 @@ public:
// rust-item.h
virtual void visit (TypeParam &param) = 0;
+ virtual void visit (SelfParam &param) = 0;
+ virtual void visit (FunctionParam &param) = 0;
+ virtual void visit (VariadicParam &param) = 0;
+
// virtual void visit(WhereClauseItem& item) = 0;
virtual void visit (LifetimeWhereClauseItem &item) = 0;
virtual void visit (TypeBoundWhereClauseItem &item) = 0;
@@ -386,6 +391,9 @@ protected:
virtual void visit (AST::SliceType &type) override;
virtual void visit (AST::InferredType &type) override;
virtual void visit (AST::BareFunctionType &type) override;
+ virtual void visit (AST::SelfParam &self) override;
+ virtual void visit (AST::FunctionParam &param) override;
+ virtual void visit (AST::VariadicParam &param) override;
template <typename T> void visit (T &node);
@@ -406,9 +414,7 @@ protected:
virtual void visit (AST::MatchArm &arm);
virtual void visit (AST::Visibility &vis);
virtual void visit (AST::FunctionQualifiers &qualifiers);
- virtual void visit (AST::SelfParam &self);
virtual void visit (AST::WhereClause &where);
- virtual void visit (AST::FunctionParam &param);
virtual void visit (AST::StructField &field);
virtual void visit (AST::TupleField &field);
virtual void visit (AST::TraitFunctionDecl &decl);
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 9c6862e..d80c002 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1090,6 +1090,62 @@ Union::as_string () const
return str;
}
+Function::Function (Function const &other)
+ : VisItem (other), qualifiers (other.qualifiers),
+ function_name (other.function_name), 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 ());
+
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
+}
+
+Function &
+Function::operator= (Function const &other)
+{
+ VisItem::operator= (other);
+ function_name = other.function_name;
+ qualifiers = other.qualifiers;
+ where_clause = other.where_clause;
+ // visibility = other.visibility->clone_visibility();
+ // outer_attrs = other.outer_attrs;
+ 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 ());
+
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
+
+ return *this;
+}
std::string
Function::as_string () const
{
@@ -1149,7 +1205,7 @@ Function::as_string () const
str += "(";
for (; i != e; i++)
{
- str += (*i).as_string ();
+ str += (*i)->as_string ();
if (e != i + 1)
str += ", ";
}
@@ -2245,6 +2301,33 @@ FunctionParam::as_string () const
return param_name->as_string () + " : " + type->as_string ();
}
+void
+FunctionParam::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+SelfParam::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+void
+VariadicParam::accept_vis (ASTVisitor &vis)
+{
+ vis.visit (*this);
+}
+
+std::string
+VariadicParam::as_string () const
+{
+ if (has_pattern ())
+ return get_pattern ()->as_string () + " : ...";
+ else
+ return "...";
+}
+
std::string
FunctionQualifiers::as_string () const
{
@@ -3013,6 +3096,33 @@ NamedFunctionParam::as_string () const
return str;
}
+TraitItemFunc::TraitItemFunc (TraitItemFunc const &other)
+ : TraitItem (other.locus), outer_attrs (other.outer_attrs), decl (other.decl)
+{
+ node_id = other.node_id;
+
+ // guard to prevent null dereference
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+}
+
+TraitItemFunc &
+TraitItemFunc::operator= (TraitItemFunc const &other)
+{
+ TraitItem::operator= (other);
+ outer_attrs = other.outer_attrs;
+ decl = other.decl;
+ locus = other.locus;
+ node_id = other.node_id;
+
+ // guard to prevent null dereference
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+ else
+ block_expr = nullptr;
+
+ return *this;
+}
std::string
TraitItemFunc::as_string () const
{
@@ -3062,7 +3172,7 @@ TraitFunctionDecl::as_string () const
if (has_params ())
{
for (const auto &param : function_params)
- str += "\n " + param.as_string ();
+ str += "\n " + param->as_string ();
}
else
{
@@ -3084,6 +3194,34 @@ TraitFunctionDecl::as_string () const
return str;
}
+TraitItemMethod::TraitItemMethod (TraitItemMethod const &other)
+ : TraitItem (other.locus), outer_attrs (other.outer_attrs), decl (other.decl)
+{
+ node_id = other.node_id;
+
+ // guard to prevent null dereference
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+}
+
+TraitItemMethod &
+TraitItemMethod::operator= (TraitItemMethod const &other)
+{
+ TraitItem::operator= (other);
+ outer_attrs = other.outer_attrs;
+ decl = other.decl;
+ locus = other.locus;
+ node_id = other.node_id;
+
+ // guard to prevent null dereference
+ if (other.block_expr != nullptr)
+ block_expr = other.block_expr->clone_block_expr ();
+ else
+ block_expr = nullptr;
+
+ return *this;
+}
+
std::string
TraitItemMethod::as_string () const
{
@@ -3129,13 +3267,11 @@ TraitMethodDecl::as_string () const
}
}
- str += "\n Self param: " + self_param.as_string ();
-
str += "\n Function params: ";
if (has_params ())
{
for (const auto &param : function_params)
- str += "\n " + param.as_string ();
+ str += "\n " + param->as_string ();
}
else
{
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 0d00c48..cd0577c 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -1042,6 +1042,173 @@ protected:
Item *clone_stmt_impl () const final override { return clone_item_impl (); }
};
+// Visibility of item - if the item has it, then it is some form of public
+struct Visibility
+{
+public:
+ enum VisType
+ {
+ PRIV,
+ PUB,
+ PUB_CRATE,
+ PUB_SELF,
+ PUB_SUPER,
+ PUB_IN_PATH
+ };
+
+private:
+ VisType vis_type;
+ // Only assigned if vis_type is IN_PATH
+ SimplePath in_path;
+ location_t locus;
+
+ // should this store location info?
+
+public:
+ // Creates a Visibility - TODO make constructor protected or private?
+ Visibility (VisType vis_type, SimplePath in_path, location_t locus)
+ : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
+ {}
+
+ VisType get_vis_type () const { return vis_type; }
+
+ // Returns whether visibility is in an error state.
+ bool is_error () const
+ {
+ return vis_type == PUB_IN_PATH && in_path.is_empty ();
+ }
+
+ // Returns whether a visibility has a path
+ bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }
+
+ // Returns whether visibility is public or not.
+ bool is_public () const { return vis_type != PRIV && !is_error (); }
+
+ location_t get_locus () const { return locus; }
+
+ // empty?
+ // Creates an error visibility.
+ static Visibility create_error ()
+ {
+ return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
+ UNDEF_LOCATION);
+ }
+
+ // Unique pointer custom clone function
+ /*std::unique_ptr<Visibility> clone_visibility() const {
+ return std::unique_ptr<Visibility>(clone_visibility_impl());
+ }*/
+
+ /* TODO: think of a way to only allow valid Visibility states - polymorphism
+ * is one idea but may be too resource-intensive. */
+
+ // Creates a public visibility with no further features/arguments.
+ // empty?
+ static Visibility create_public (location_t pub_vis_location)
+ {
+ return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
+ }
+
+ // Creates a public visibility with crate-relative paths
+ static Visibility create_crate (location_t crate_tok_location,
+ location_t crate_vis_location)
+ {
+ return Visibility (PUB_CRATE,
+ SimplePath::from_str ("crate", crate_tok_location),
+ crate_vis_location);
+ }
+
+ // Creates a public visibility with self-relative paths
+ static Visibility create_self (location_t self_tok_location,
+ location_t self_vis_location)
+ {
+ return Visibility (PUB_SELF,
+ SimplePath::from_str ("self", self_tok_location),
+ self_vis_location);
+ }
+
+ // Creates a public visibility with parent module-relative paths
+ static Visibility create_super (location_t super_tok_location,
+ location_t super_vis_location)
+ {
+ return Visibility (PUB_SUPER,
+ SimplePath::from_str ("super", super_tok_location),
+ super_vis_location);
+ }
+
+ // Creates a private visibility
+ static Visibility create_private ()
+ {
+ return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
+ }
+
+ // Creates a public visibility with a given path or whatever.
+ static Visibility create_in_path (SimplePath in_path,
+ location_t in_path_vis_location)
+ {
+ return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
+ }
+
+ std::string as_string () const;
+ const SimplePath &get_path () const { return in_path; }
+ SimplePath &get_path () { return in_path; }
+
+protected:
+ // Clone function implementation - not currently virtual but may be if
+ // polymorphism used
+ /*virtual*/ Visibility *clone_visibility_impl () const
+ {
+ return new Visibility (*this);
+ }
+};
+// Item that supports visibility - abstract base class
+class VisItem : public Item
+{
+ Visibility visibility;
+ std::vector<Attribute> outer_attrs;
+
+protected:
+ // Visibility constructor
+ VisItem (Visibility visibility,
+ std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
+ : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
+ {}
+
+ // Visibility copy constructor
+ VisItem (VisItem const &other)
+ : visibility (other.visibility), outer_attrs (other.outer_attrs)
+ {}
+
+ // Overload assignment operator to clone
+ VisItem &operator= (VisItem const &other)
+ {
+ visibility = other.visibility;
+ outer_attrs = other.outer_attrs;
+
+ return *this;
+ }
+
+ // move constructors
+ VisItem (VisItem &&other) = default;
+ VisItem &operator= (VisItem &&other) = default;
+
+public:
+ /* Does the item have some kind of public visibility (non-default
+ * visibility)? */
+ bool has_visibility () const { return visibility.is_public (); }
+
+ std::string as_string () const override;
+
+ // TODO: this mutable getter seems really dodgy. Think up better way.
+ Visibility &get_visibility () { return visibility; }
+ const Visibility &get_visibility () const { return visibility; }
+
+ std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
+ const std::vector<Attribute> &get_outer_attrs () const override
+ {
+ return outer_attrs;
+ }
+};
// forward decl of ExprWithoutBlock
class ExprWithoutBlock;
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 4dc240c..4830ae0 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -3,6 +3,7 @@
#include "rust-ast.h"
#include "rust-path.h"
+#include "rust-macro.h"
#include "rust-operators.h"
namespace Rust {
diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h
index 0e38103..81bb17e 100644
--- a/gcc/rust/ast/rust-item.h
+++ b/gcc/rust/ast/rust-item.h
@@ -20,6 +20,8 @@
#define RUST_AST_ITEM_H
#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-mapping-common.h"
#include "rust-path.h"
#include "rust-common.h"
#include "rust-expr.h"
@@ -376,8 +378,46 @@ public:
}
};
+// Abstract class Param
+class Param : public Visitable
+{
+public:
+ Param (std::vector<Attribute> outer_attrs, location_t locus)
+ : outer_attrs (std::move (outer_attrs)), locus (locus),
+ node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ {}
+
+ virtual ~Param () = default;
+
+ std::unique_ptr<Param> clone_param () const
+ {
+ return std::unique_ptr<Param> (clone_param_impl ());
+ }
+
+ virtual bool is_variadic () const { return false; }
+
+ virtual bool is_self () const { return false; }
+
+ NodeId get_node_id () const { return node_id; }
+
+ location_t get_locus () const { return locus; }
+
+ std::vector<Attribute> get_outer_attrs () const { return outer_attrs; }
+
+ std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
+
+ virtual Param *clone_param_impl () const = 0;
+
+ virtual std::string as_string () const = 0;
+
+protected:
+ std::vector<Attribute> outer_attrs;
+ location_t locus;
+ NodeId node_id;
+};
+
// A self parameter in a method
-class SelfParam
+class SelfParam : public Param
{
bool has_ref;
bool is_mut;
@@ -387,14 +427,10 @@ class SelfParam
// bool has_type; // only possible if not ref
std::unique_ptr<Type> type;
- NodeId node_id;
-
- location_t locus;
-
// Unrestricted constructor used for error state
SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type)
- : has_ref (has_ref), is_mut (is_mut), lifetime (std::move (lifetime)),
- type (type), node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ : Param ({}, UNDEF_LOCATION), has_ref (has_ref), is_mut (is_mut),
+ lifetime (std::move (lifetime)), type (type)
{}
// this is ok as no outside classes can ever call this
@@ -423,22 +459,20 @@ public:
// Type-based self parameter (not ref, no lifetime)
SelfParam (std::unique_ptr<Type> type, bool is_mut, location_t locus)
- : has_ref (false), is_mut (is_mut), lifetime (Lifetime::error ()),
- type (std::move (type)),
- node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
+ : Param ({}, locus), has_ref (false), is_mut (is_mut),
+ lifetime (Lifetime::error ()), type (std::move (type))
{}
// Lifetime-based self parameter (is ref, no type)
SelfParam (Lifetime lifetime, bool is_mut, location_t locus)
- : has_ref (true), is_mut (is_mut), lifetime (std::move (lifetime)),
- node_id (Analysis::Mappings::get ()->get_next_node_id ()), locus (locus)
+ : Param ({}, locus), has_ref (true), is_mut (is_mut),
+ lifetime (std::move (lifetime))
{}
// Copy constructor requires clone
SelfParam (SelfParam const &other)
- : has_ref (other.has_ref), is_mut (other.is_mut), lifetime (other.lifetime),
- node_id (Analysis::Mappings::get ()->get_next_node_id ()),
- locus (other.locus)
+ : Param (other.get_outer_attrs (), other.get_locus ()),
+ has_ref (other.has_ref), is_mut (other.is_mut), lifetime (other.lifetime)
{
node_id = other.node_id;
if (other.type != nullptr)
@@ -453,6 +487,7 @@ public:
lifetime = other.lifetime;
locus = other.locus;
node_id = other.node_id;
+ outer_attrs = other.outer_attrs;
if (other.type != nullptr)
type = other.type->clone_type ();
@@ -466,10 +501,12 @@ public:
SelfParam (SelfParam &&other) = default;
SelfParam &operator= (SelfParam &&other) = default;
- std::string as_string () const;
+ std::string as_string () const override;
location_t get_locus () const { return locus; }
+ bool is_self () const override { return true; }
+
bool get_has_ref () const { return has_ref; };
bool get_is_mut () const { return is_mut; }
@@ -484,6 +521,13 @@ public:
rust_assert (has_type ());
return type;
}
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ SelfParam *clone_param_impl () const override
+ {
+ return new SelfParam (*this);
+ }
};
// Qualifiers for function, i.e. const, unsafe, extern etc.
@@ -521,41 +565,84 @@ public:
location_t get_locus () const { return locus; }
};
-// A function parameter
-class FunctionParam
+class VariadicParam : public Param
{
- std::vector<Attribute> outer_attrs;
- location_t locus;
std::unique_ptr<Pattern> param_name;
- std::unique_ptr<Type> type;
- bool variadic;
public:
- FunctionParam (std::unique_ptr<Pattern> param_name,
- std::unique_ptr<Type> param_type,
+ VariadicParam (std::unique_ptr<Pattern> param_name,
std::vector<Attribute> outer_attrs, location_t locus)
- : outer_attrs (std::move (outer_attrs)), locus (locus),
- param_name (std::move (param_name)), type (std::move (param_type)),
- variadic (false),
- node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ : Param (std::move (outer_attrs), std::move (locus)),
+ param_name (std::move (param_name))
{}
- FunctionParam (std::vector<Attribute> outer_attrs, location_t locus)
- : outer_attrs (std::move (outer_attrs)), locus (locus),
- param_name (nullptr), type (nullptr), variadic (true),
- node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ VariadicParam (std::vector<Attribute> outer_attrs, location_t locus)
+ : Param (std::move (outer_attrs), std::move (locus)), param_name (nullptr)
{}
+ VariadicParam (VariadicParam const &other)
+ : Param (other.get_outer_attrs (), other.locus)
+ {
+ if (other.param_name != nullptr)
+ param_name = other.param_name->clone_pattern ();
+ }
+
+ VariadicParam &operator= (VariadicParam const &other)
+ {
+ outer_attrs = other.outer_attrs;
+ locus = other.locus;
+ node_id = other.node_id;
+ if (other.param_name != nullptr)
+ param_name = other.param_name->clone_pattern ();
+ else
+ param_name = nullptr;
+
+ return *this;
+ }
+
+ bool is_variadic () const override { return true; }
+
+ VariadicParam *clone_param_impl () const override
+ {
+ return new VariadicParam (*this);
+ }
+
+ std::unique_ptr<Pattern> &get_pattern ()
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
+ const std::unique_ptr<Pattern> &get_pattern () const
+ {
+ rust_assert (param_name != nullptr);
+ return param_name;
+ }
+
+ bool has_pattern () const { return param_name != nullptr; }
+
+ void accept_vis (ASTVisitor &vis) override;
+
+ std::string as_string () const override;
+};
+
+// A function parameter
+class FunctionParam : public Param
+{
+ std::unique_ptr<Pattern> param_name;
+ std::unique_ptr<Type> type;
+
+public:
FunctionParam (std::unique_ptr<Pattern> param_name,
+ std::unique_ptr<Type> param_type,
std::vector<Attribute> outer_attrs, location_t locus)
- : outer_attrs (std::move (outer_attrs)), locus (locus),
- param_name (std::move (param_name)), type (nullptr), variadic (true),
- node_id (Analysis::Mappings::get ()->get_next_node_id ())
+ : Param (std::move (outer_attrs), locus),
+ param_name (std::move (param_name)), type (std::move (param_type))
{}
// Copy constructor uses clone
FunctionParam (FunctionParam const &other)
- : locus (other.locus), variadic (other.variadic), node_id (other.node_id)
+ : Param (other.get_outer_attrs (), other.locus)
{
// guard to prevent nullptr dereference
if (other.param_name != nullptr)
@@ -569,7 +656,6 @@ public:
{
locus = other.locus;
node_id = other.node_id;
- variadic = other.variadic;
// guard to prevent nullptr dereference
if (other.param_name != nullptr)
@@ -589,13 +675,7 @@ public:
FunctionParam &operator= (FunctionParam &&other) = default;
// Returns whether FunctionParam is in an invalid state.
- bool is_error () const
- {
- if (variadic)
- return false;
- else
- return param_name == nullptr || type == nullptr;
- }
+ bool is_error () const { return param_name == nullptr || type == nullptr; }
// Creates an error FunctionParam.
static FunctionParam create_error ()
@@ -603,9 +683,7 @@ public:
return FunctionParam (nullptr, nullptr, {}, UNDEF_LOCATION);
}
- std::string as_string () const;
-
- location_t get_locus () const { return locus; }
+ std::string as_string () const override;
// TODO: seems kinda dodgy. Think of better way.
std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
@@ -627,181 +705,12 @@ public:
return type;
}
- bool is_variadic () const { return variadic; }
-
- NodeId get_node_id () const { return node_id; }
-
-protected:
- NodeId node_id;
-};
-
-// Visibility of item - if the item has it, then it is some form of public
-struct Visibility
-{
-public:
- enum VisType
- {
- PRIV,
- PUB,
- PUB_CRATE,
- PUB_SELF,
- PUB_SUPER,
- PUB_IN_PATH
- };
-
-private:
- VisType vis_type;
- // Only assigned if vis_type is IN_PATH
- SimplePath in_path;
- location_t locus;
-
- // should this store location info?
-
-public:
- // Creates a Visibility - TODO make constructor protected or private?
- Visibility (VisType vis_type, SimplePath in_path, location_t locus)
- : vis_type (vis_type), in_path (std::move (in_path)), locus (locus)
- {}
-
- VisType get_vis_type () const { return vis_type; }
-
- // Returns whether visibility is in an error state.
- bool is_error () const
- {
- return vis_type == PUB_IN_PATH && in_path.is_empty ();
- }
-
- // Returns whether a visibility has a path
- bool has_path () const { return !is_error () && vis_type >= PUB_CRATE; }
-
- // Returns whether visibility is public or not.
- bool is_public () const { return vis_type != PRIV && !is_error (); }
-
- location_t get_locus () const { return locus; }
-
- // empty?
- // Creates an error visibility.
- static Visibility create_error ()
+ FunctionParam *clone_param_impl () const override
{
- return Visibility (PUB_IN_PATH, SimplePath::create_empty (),
- UNDEF_LOCATION);
+ return new FunctionParam (*this);
}
- // Unique pointer custom clone function
- /*std::unique_ptr<Visibility> clone_visibility() const {
- return std::unique_ptr<Visibility>(clone_visibility_impl());
- }*/
-
- /* TODO: think of a way to only allow valid Visibility states - polymorphism
- * is one idea but may be too resource-intensive. */
-
- // Creates a public visibility with no further features/arguments.
- // empty?
- static Visibility create_public (location_t pub_vis_location)
- {
- return Visibility (PUB, SimplePath::create_empty (), pub_vis_location);
- }
-
- // Creates a public visibility with crate-relative paths
- static Visibility create_crate (location_t crate_tok_location,
- location_t crate_vis_location)
- {
- return Visibility (PUB_CRATE,
- SimplePath::from_str ("crate", crate_tok_location),
- crate_vis_location);
- }
-
- // Creates a public visibility with self-relative paths
- static Visibility create_self (location_t self_tok_location,
- location_t self_vis_location)
- {
- return Visibility (PUB_SELF,
- SimplePath::from_str ("self", self_tok_location),
- self_vis_location);
- }
-
- // Creates a public visibility with parent module-relative paths
- static Visibility create_super (location_t super_tok_location,
- location_t super_vis_location)
- {
- return Visibility (PUB_SUPER,
- SimplePath::from_str ("super", super_tok_location),
- super_vis_location);
- }
-
- // Creates a private visibility
- static Visibility create_private ()
- {
- return Visibility (PRIV, SimplePath::create_empty (), UNDEF_LOCATION);
- }
-
- // Creates a public visibility with a given path or whatever.
- static Visibility create_in_path (SimplePath in_path,
- location_t in_path_vis_location)
- {
- return Visibility (PUB_IN_PATH, std::move (in_path), in_path_vis_location);
- }
-
- std::string as_string () const;
- const SimplePath &get_path () const { return in_path; }
- SimplePath &get_path () { return in_path; }
-
-protected:
- // Clone function implementation - not currently virtual but may be if
- // polymorphism used
- /*virtual*/ Visibility *clone_visibility_impl () const
- {
- return new Visibility (*this);
- }
-};
-
-// Item that supports visibility - abstract base class
-class VisItem : public Item
-{
- Visibility visibility;
- std::vector<Attribute> outer_attrs;
-
-protected:
- // Visibility constructor
- VisItem (Visibility visibility,
- std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
- : visibility (std::move (visibility)), outer_attrs (std::move (outer_attrs))
- {}
-
- // Visibility copy constructor
- VisItem (VisItem const &other)
- : visibility (other.visibility), outer_attrs (other.outer_attrs)
- {}
-
- // Overload assignment operator to clone
- VisItem &operator= (VisItem const &other)
- {
- visibility = other.visibility;
- outer_attrs = other.outer_attrs;
-
- return *this;
- }
-
- // move constructors
- VisItem (VisItem &&other) = default;
- VisItem &operator= (VisItem &&other) = default;
-
-public:
- /* Does the item have some kind of public visibility (non-default
- * visibility)? */
- bool has_visibility () const { return visibility.is_public (); }
-
- std::string as_string () const override;
-
- // TODO: this mutable getter seems really dodgy. Think up better way.
- Visibility &get_visibility () { return visibility; }
- const Visibility &get_visibility () const { return visibility; }
-
- std::vector<Attribute> &get_outer_attrs () override { return outer_attrs; }
- const std::vector<Attribute> &get_outer_attrs () const override
- {
- return outer_attrs;
- }
+ void accept_vis (ASTVisitor &vis) override;
};
// Rust module item - abstract base class
@@ -1372,8 +1281,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::vector<std::unique_ptr<Param>> function_params;
std::unique_ptr<Type> return_type;
WhereClause where_clause;
std::unique_ptr<BlockExpr> function_body;
@@ -1395,13 +1303,15 @@ 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 (); }
+ bool has_self_param () const
+ {
+ return function_params.size () > 0 && function_params[0]->is_self ();
+ }
// 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::vector<std::unique_ptr<Param>> 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,
@@ -1410,7 +1320,6 @@ 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)),
@@ -1421,58 +1330,10 @@ public:
// TODO: add constructor with less fields
// Copy constructor with clone
- Function (Function const &other)
- : VisItem (other), qualifiers (other.qualifiers),
- 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)
- {
- // 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 ());
- }
+ Function (Function const &other);
// Overloaded assignment operator to clone
- Function &operator= (Function const &other)
- {
- 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();
- // outer_attrs = other.outer_attrs;
- 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 ());
-
- return *this;
- }
+ Function &operator= (Function const &other);
// move constructors
Function (Function &&other) = default;
@@ -1485,7 +1346,7 @@ public:
bool is_variadic () const
{
return function_params.size () != 0
- && function_params.back ().is_variadic ();
+ && function_params.back ()->is_variadic ();
}
// Invalid if block is null, so base stripping on that.
@@ -1495,8 +1356,11 @@ public:
return function_body == nullptr;
}
- std::vector<FunctionParam> &get_function_params () { return function_params; }
- const std::vector<FunctionParam> &get_function_params () const
+ std::vector<std::unique_ptr<Param>> &get_function_params ()
+ {
+ return function_params;
+ }
+ const std::vector<std::unique_ptr<Param>> &get_function_params () const
{
return function_params;
}
@@ -1533,15 +1397,15 @@ public:
return return_type;
}
- SelfParam &get_self_param ()
+ std::unique_ptr<Param> &get_self_param ()
{
rust_assert (has_self_param ());
- return self_param.value ();
+ return function_params[0];
}
- const SelfParam &get_self_param () const
+ const std::unique_ptr<Param> &get_self_param () const
{
rust_assert (has_self_param ());
- return self_param.value ();
+ return function_params[0];
}
protected:
@@ -2668,7 +2532,7 @@ class TraitFunctionDecl
// bool has_params;
// FunctionParams function_params;
- std::vector<FunctionParam> function_params; // inlined
+ std::vector<std::unique_ptr<Param>> function_params; // inlined
// bool has_return_type;
std::unique_ptr<Type> return_type;
@@ -2696,7 +2560,7 @@ public:
// Mega-constructor
TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
- std::vector<FunctionParam> function_params,
+ std::vector<std::unique_ptr<Param>> function_params,
std::unique_ptr<Type> return_type,
WhereClause where_clause)
: qualifiers (std::move (qualifiers)),
@@ -2710,7 +2574,7 @@ public:
// Copy constructor with clone
TraitFunctionDecl (TraitFunctionDecl const &other)
: qualifiers (other.qualifiers), function_name (other.function_name),
- function_params (other.function_params), where_clause (other.where_clause)
+ where_clause (other.where_clause)
{
// guard to prevent nullptr dereference
if (other.return_type != nullptr)
@@ -2719,6 +2583,10 @@ public:
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
}
~TraitFunctionDecl () = default;
@@ -2728,7 +2596,6 @@ public:
{
function_name = other.function_name;
qualifiers = other.qualifiers;
- function_params = other.function_params;
where_clause = other.where_clause;
// guard to prevent nullptr dereference
@@ -2741,6 +2608,10 @@ public:
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
+
return *this;
}
@@ -2755,8 +2626,11 @@ public:
bool is_marked_for_strip () const { return function_name.empty (); }
// TODO: this mutable getter seems really dodgy. Think up better way.
- std::vector<FunctionParam> &get_function_params () { return function_params; }
- const std::vector<FunctionParam> &get_function_params () const
+ std::vector<std::unique_ptr<Param>> &get_function_params ()
+ {
+ return function_params;
+ }
+ const std::vector<std::unique_ptr<Param>> &get_function_params () const
{
return function_params;
}
@@ -2798,34 +2672,11 @@ public:
{}
// Copy constructor with clone
- TraitItemFunc (TraitItemFunc const &other)
- : TraitItem (other.locus), outer_attrs (other.outer_attrs),
- decl (other.decl)
- {
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
- }
+ TraitItemFunc (TraitItemFunc const &other);
// Overloaded assignment operator to clone
- TraitItemFunc &operator= (TraitItemFunc const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- decl = other.decl;
- locus = other.locus;
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
- else
- block_expr = nullptr;
- return *this;
- }
+ TraitItemFunc &operator= (TraitItemFunc const &other);
// move constructors
TraitItemFunc (TraitItemFunc &&other) = default;
@@ -2875,11 +2726,9 @@ class TraitMethodDecl
// Generics generic_params;
std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined
- SelfParam self_param;
-
// bool has_params;
// FunctionParams function_params;
- std::vector<FunctionParam> function_params; // inlined
+ std::vector<std::unique_ptr<Param>> function_params; // inlined
// bool has_return_type;
std::unique_ptr<Type> return_type;
@@ -2907,13 +2756,11 @@ public:
// Mega-constructor
TraitMethodDecl (Identifier function_name, FunctionQualifiers qualifiers,
std::vector<std::unique_ptr<GenericParam>> generic_params,
- SelfParam self_param,
- std::vector<FunctionParam> function_params,
+ std::vector<std::unique_ptr<Param>> function_params,
std::unique_ptr<Type> return_type, WhereClause where_clause)
: 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))
@@ -2922,7 +2769,6 @@ public:
// Copy constructor with clone
TraitMethodDecl (TraitMethodDecl const &other)
: qualifiers (other.qualifiers), function_name (other.function_name),
- self_param (other.self_param), function_params (other.function_params),
where_clause (other.where_clause)
{
// guard to prevent nullptr dereference
@@ -2932,6 +2778,10 @@ public:
generic_params.reserve (other.generic_params.size ());
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
}
~TraitMethodDecl () = default;
@@ -2941,8 +2791,6 @@ public:
{
function_name = other.function_name;
qualifiers = other.qualifiers;
- self_param = other.self_param;
- function_params = other.function_params;
where_clause = other.where_clause;
// guard to prevent nullptr dereference
@@ -2955,6 +2803,10 @@ public:
for (const auto &e : other.generic_params)
generic_params.push_back (e->clone_generic_param ());
+ function_params.reserve (other.function_params.size ());
+ for (const auto &e : other.function_params)
+ function_params.push_back (e->clone_param ());
+
return *this;
}
@@ -2969,8 +2821,11 @@ public:
bool is_marked_for_strip () const { return function_name.empty (); }
// TODO: this mutable getter seems really dodgy. Think up better way.
- std::vector<FunctionParam> &get_function_params () { return function_params; }
- const std::vector<FunctionParam> &get_function_params () const
+ std::vector<std::unique_ptr<Param>> &get_function_params ()
+ {
+ return function_params;
+ }
+ const std::vector<std::unique_ptr<Param>> &get_function_params () const
{
return function_params;
}
@@ -2990,8 +2845,21 @@ public:
// TODO: is this better? Or is a "vis_block" better?
WhereClause &get_where_clause () { return where_clause; }
- SelfParam &get_self_param () { return self_param; }
- const SelfParam &get_self_param () const { return self_param; }
+ bool has_self () const
+ {
+ return !function_params.empty () && function_params[0]->is_self ();
+ }
+
+ std::unique_ptr<Param> &get_self_param ()
+ {
+ rust_assert (has_self ());
+ return function_params[0];
+ }
+ const std::unique_ptr<Param> &get_self_param () const
+ {
+ rust_assert (has_self ());
+ return function_params[0];
+ }
FunctionQualifiers get_qualifiers () const { return qualifiers; }
@@ -3016,34 +2884,9 @@ public:
{}
// Copy constructor with clone
- TraitItemMethod (TraitItemMethod const &other)
- : TraitItem (other.locus), outer_attrs (other.outer_attrs),
- decl (other.decl)
- {
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
- }
-
+ TraitItemMethod (TraitItemMethod const &other);
// Overloaded assignment operator to clone
- TraitItemMethod &operator= (TraitItemMethod const &other)
- {
- TraitItem::operator= (other);
- outer_attrs = other.outer_attrs;
- decl = other.decl;
- locus = other.locus;
- node_id = other.node_id;
-
- // guard to prevent null dereference
- if (other.block_expr != nullptr)
- block_expr = other.block_expr->clone_block_expr ();
- else
- block_expr = nullptr;
-
- return *this;
- }
+ TraitItemMethod &operator= (TraitItemMethod const &other);
// move constructors
TraitItemMethod (TraitItemMethod &&other) = default;
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc
index a903297..f6ce45e 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -81,4 +81,19 @@ ASTValidation::visit (AST::ExternalFunctionItem &item)
AST::ContextualASTVisitor::visit (item);
}
+void
+ASTValidation::visit (AST::Function &function)
+{
+ std::set<Context> valid_context
+ = {Context::INHERENT_IMPL, Context::TRAIT_IMPL};
+
+ if (valid_context.find (context.back ()) == valid_context.end ()
+ && function.has_self_param ())
+ rust_error_at (
+ function.get_self_param ()->get_locus (),
+ "%<self%> parameter is only allowed in associated functions");
+
+ AST::ContextualASTVisitor::visit (function);
+}
+
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-ast-validation.h b/gcc/rust/checks/errors/rust-ast-validation.h
index 6028b21..44995eb 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.h
+++ b/gcc/rust/checks/errors/rust-ast-validation.h
@@ -37,6 +37,7 @@ public:
virtual void visit (AST::Lifetime &lifetime);
virtual void visit (AST::LoopLabel &label);
virtual void visit (AST::ExternalFunctionItem &item);
+ virtual void visit (AST::Function &function);
};
} // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-feature-gate.h b/gcc/rust/checks/errors/rust-feature-gate.h
index 298582d..ca61199 100644
--- a/gcc/rust/checks/errors/rust-feature-gate.h
+++ b/gcc/rust/checks/errors/rust-feature-gate.h
@@ -183,6 +183,9 @@ public:
void visit (AST::SliceType &type) override {}
void visit (AST::InferredType &type) override {}
void visit (AST::BareFunctionType &type) override {}
+ void visit (AST::FunctionParam &param) override {}
+ void visit (AST::VariadicParam &param) override {}
+ void visit (AST::SelfParam &param) override {}
private:
void gate (Feature::Name name, location_t loc, const std::string &error_msg);
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 6bf3a25..7e50db6 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -218,34 +218,37 @@ CfgStrip::maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields)
}
void
-CfgStrip::maybe_strip_function_params (std::vector<AST::FunctionParam> &params)
+CfgStrip::maybe_strip_function_params (
+ std::vector<std::unique_ptr<AST::Param>> &params)
{
for (auto it = params.begin (); it != params.end ();)
{
- auto &param = *it;
-
- auto &param_attrs = param.get_outer_attrs ();
- expand_cfg_attrs (param_attrs);
- if (fails_cfg_with_expand (param_attrs))
+ if (!(*it)->is_self () && !(*it)->is_variadic ())
{
- it = params.erase (it);
- continue;
- }
+ auto param = static_cast<AST::FunctionParam *> (it->get ());
- // TODO: should an unwanted strip lead to break out of loop?
- auto &pattern = param.get_pattern ();
- pattern->accept_vis (*this);
- if (pattern->is_marked_for_strip ())
- rust_error_at (pattern->get_locus (),
- "cannot strip pattern in this position");
+ auto &param_attrs = param->get_outer_attrs ();
+ expand_cfg_attrs (param_attrs);
+ if (fails_cfg_with_expand (param_attrs))
+ {
+ it = params.erase (it);
+ continue;
+ }
- auto &type = param.get_type ();
- type->accept_vis (*this);
+ // TODO: should an unwanted strip lead to break out of loop?
+ auto &pattern = param->get_pattern ();
+ pattern->accept_vis (*this);
+ if (pattern->is_marked_for_strip ())
+ rust_error_at (pattern->get_locus (),
+ "cannot strip pattern in this position");
- if (type->is_marked_for_strip ())
- rust_error_at (type->get_locus (),
- "cannot strip type in this position");
+ auto &type = param->get_type ();
+ type->accept_vis (*this);
+ if (type->is_marked_for_strip ())
+ rust_error_at (type->get_locus (),
+ "cannot strip type in this position");
+ }
// increment
++it;
}
@@ -360,22 +363,6 @@ CfgStrip::CfgStrip::maybe_strip_closure_params (
}
void
-CfgStrip::maybe_strip_self_param (AST::SelfParam &self_param)
-{
- if (self_param.has_type ())
- {
- auto &type = self_param.get_type ();
- type->accept_vis (*this);
-
- if (type->is_marked_for_strip ())
- rust_error_at (type->get_locus (),
- "cannot strip type in this position");
- }
- /* TODO: maybe check for invariants being violated - e.g. both type and
- * lifetime? */
-}
-
-void
CfgStrip::maybe_strip_where_clause (AST::WhereClause &where_clause)
{
// items cannot be stripped conceptually, so just accept visitor
@@ -415,11 +402,6 @@ CfgStrip::maybe_strip_trait_method_decl (AST::TraitMethodDecl &decl)
for (auto &param : decl.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 (decl.get_self_param ());
-
/* strip function parameters if required - this is specifically
* allowed by spec */
maybe_strip_function_params (decl.get_function_params ());
@@ -2029,13 +2011,6 @@ 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 ());
@@ -3167,4 +3142,28 @@ CfgStrip::visit (AST::BareFunctionType &type)
// no where clause, apparently
}
+void
+CfgStrip::visit (AST::VariadicParam &type)
+{}
+
+void
+CfgStrip::visit (AST::FunctionParam &type)
+{}
+
+void
+CfgStrip::visit (AST::SelfParam &param)
+{
+ if (param.has_type ())
+ {
+ auto &type = param.get_type ();
+ type->accept_vis (*this);
+
+ if (type->is_marked_for_strip ())
+ rust_error_at (type->get_locus (),
+ "cannot strip type in this position");
+ }
+ /* TODO: maybe check for invariants being violated - e.g. both type and
+ * lifetime? */
+}
+
} // namespace Rust
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index b3bb3fb..47c9770 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -18,6 +18,7 @@
#include "rust-ast-visitor.h"
#include "rust-ast.h"
+#include "rust-item.h"
namespace Rust {
// Visitor used to maybe_strip attributes.
@@ -32,7 +33,8 @@ public:
void maybe_strip_struct_fields (std::vector<AST::StructField> &fields);
void maybe_strip_tuple_fields (std::vector<AST::TupleField> &fields);
- void maybe_strip_function_params (std::vector<AST::FunctionParam> &params);
+ void maybe_strip_function_params (
+ std::vector<std::unique_ptr<AST::Param>> &params);
void maybe_strip_generic_args (AST::GenericArgs &args);
void maybe_strip_qualified_path_type (AST::QualifiedPathType &path_type);
void maybe_strip_closure_params (std::vector<AST::ClosureParam> &params);
@@ -222,5 +224,8 @@ public:
void visit (AST::SliceType &type) override;
void visit (AST::InferredType &) override;
void visit (AST::BareFunctionType &type) override;
+ void visit (AST::VariadicParam &type) override;
+ void visit (AST::FunctionParam &type) override;
+ void visit (AST::SelfParam &type) override;
};
} // namespace Rust
diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc
index 28ce402..cc198ee 100644
--- a/gcc/rust/expand/rust-derive-clone.cc
+++ b/gcc/rust/expand/rust-derive-clone.cc
@@ -17,6 +17,7 @@
// <http://www.gnu.org/licenses/>.
#include "rust-derive-clone.h"
+#include "rust-item.h"
namespace Rust {
namespace AST {
@@ -50,13 +51,17 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr)
loc, loc));
auto big_self_type = builder.single_type_path ("Self");
+ std::unique_ptr<SelfParam> self (new SelfParam (Lifetime::error (),
+ /* is_mut */ false, loc));
+
+ std::vector<std::unique_ptr<Param>> params;
+ params.push_back (std::move (self));
+
return std::unique_ptr<TraitImplItem> (
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));
+ /* function params */ std::move (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 915c054..d5c8b44 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -220,6 +220,9 @@ private:
virtual void visit (SliceType &type) override final{};
virtual void visit (InferredType &type) override final{};
virtual void visit (BareFunctionType &type) override final{};
+ virtual void visit (SelfParam &param) override final{};
+ virtual void visit (FunctionParam &param) override final{};
+ virtual void visit (VariadicParam &param) override final{};
};
} // namespace AST
diff --git a/gcc/rust/expand/rust-expand-visitor.cc b/gcc/rust/expand/rust-expand-visitor.cc
index 0dd6f59..3f598b7 100644
--- a/gcc/rust/expand/rust-expand-visitor.cc
+++ b/gcc/rust/expand/rust-expand-visitor.cc
@@ -373,12 +373,11 @@ ExpandVisitor::expand_tuple_fields (std::vector<AST::TupleField> &fields)
// FIXME: This can definitely be refactored with the method above
void
-ExpandVisitor::expand_function_params (std::vector<AST::FunctionParam> &params)
+ExpandVisitor::expand_function_params (
+ std::vector<std::unique_ptr<AST::Param>> &params)
{
- for (auto &param : params)
- {
- maybe_expand_type (param.get_type ());
- }
+ for (auto &p : params)
+ visit (p);
}
void
@@ -432,16 +431,6 @@ ExpandVisitor::expand_closure_params (std::vector<AST::ClosureParam> &params)
}
void
-ExpandVisitor::expand_self_param (AST::SelfParam &self_param)
-{
- if (self_param.has_type ())
- maybe_expand_type (self_param.get_type ());
-
- /* TODO: maybe check for invariants being violated - e.g. both type and
- * lifetime? */
-}
-
-void
ExpandVisitor::expand_where_clause (AST::WhereClause &where_clause)
{
for (auto &item : where_clause.get_items ())
@@ -472,11 +461,6 @@ ExpandVisitor::expand_trait_method_decl (AST::TraitMethodDecl &decl)
for (auto &param : decl.get_generic_params ())
visit (param);
- /* 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. */
- expand_self_param (decl.get_self_param ());
-
/* strip function parameters if required - this is specifically
* allowed by spec */
expand_function_params (decl.get_function_params ());
@@ -1022,8 +1006,6 @@ 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 ())
@@ -1566,6 +1548,25 @@ ExpandVisitor::visit (AST::BareFunctionType &type)
visit (type.get_return_type ());
}
+void
+ExpandVisitor::visit (AST::VariadicParam &param)
+{}
+
+void
+ExpandVisitor::visit (AST::FunctionParam &param)
+{
+ maybe_expand_type (param.get_type ());
+}
+
+void
+ExpandVisitor::visit (AST::SelfParam &param)
+{
+ /* TODO: maybe check for invariants being violated - e.g. both type and
+ * lifetime? */
+ if (param.has_type ())
+ maybe_expand_type (param.get_type ());
+}
+
template <typename T>
void
ExpandVisitor::expand_inner_attribute (T &item, AST::SimplePath &path)
diff --git a/gcc/rust/expand/rust-expand-visitor.h b/gcc/rust/expand/rust-expand-visitor.h
index d7612ac..74f2673 100644
--- a/gcc/rust/expand/rust-expand-visitor.h
+++ b/gcc/rust/expand/rust-expand-visitor.h
@@ -67,7 +67,8 @@ public:
* Expand all macro invocations in lieu of types within a list of function
* parameters
*/
- void expand_function_params (std::vector<AST::FunctionParam> &params);
+ void
+ expand_function_params (std::vector<std::unique_ptr<AST::Param>> &params);
/**
* Expand all macro invocations in lieu of types within a list of generic
@@ -82,7 +83,6 @@ public:
// FIXME: Add documentation
void expand_closure_params (std::vector<AST::ClosureParam> &params);
- void expand_self_param (AST::SelfParam &self_param);
void expand_where_clause (AST::WhereClause &where_clause);
void expand_trait_function_decl (AST::TraitFunctionDecl &decl);
void expand_trait_method_decl (AST::TraitMethodDecl &decl);
@@ -347,6 +347,9 @@ public:
void visit (AST::SliceType &type) override;
void visit (AST::InferredType &) override;
void visit (AST::BareFunctionType &type) override;
+ void visit (AST::VariadicParam &type) override;
+ void visit (AST::FunctionParam &type) override;
+ void visit (AST::SelfParam &type) override;
template <typename T>
void expand_inner_attribute (T &item, AST::SimplePath &Path);
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 5f6d6fe..051dd60 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -21,6 +21,8 @@
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-extern.h"
#include "rust-attribute-values.h"
+#include "rust-item.h"
+#include "rust-system.h"
namespace Rust {
namespace HIR {
@@ -515,6 +517,18 @@ void
ASTLoweringBase::visit (AST::BareFunctionType &)
{}
+void
+ASTLoweringBase::visit (AST::FunctionParam &param)
+{}
+
+void
+ASTLoweringBase::visit (AST::VariadicParam &param)
+{}
+
+void
+ASTLoweringBase::visit (AST::SelfParam &param)
+{}
+
HIR::Lifetime
ASTLoweringBase::lower_lifetime (AST::Lifetime &lifetime)
{
@@ -629,28 +643,31 @@ ASTLoweringBase::lower_generic_args (AST::GenericArgs &args)
}
HIR::SelfParam
-ASTLoweringBase::lower_self (AST::SelfParam &self)
+ASTLoweringBase::lower_self (std::unique_ptr<AST::Param> &param)
{
+ rust_assert (param->is_self ());
+
+ auto self = static_cast<AST::SelfParam *> (param.get ());
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, self.get_node_id (),
+ Analysis::NodeMapping mapping (crate_num, self->get_node_id (),
mappings->get_next_hir_id (crate_num),
mappings->get_next_localdef_id (crate_num));
- if (self.has_type ())
+ if (self->has_type ())
{
- HIR::Type *type = ASTLoweringType::translate (self.get_type ().get ());
+ HIR::Type *type = ASTLoweringType::translate (self->get_type ().get ());
return HIR::SelfParam (mapping, std::unique_ptr<HIR::Type> (type),
- self.get_is_mut (), self.get_locus ());
+ self->get_is_mut (), self->get_locus ());
}
- else if (!self.get_has_ref ())
+ else if (!self->get_has_ref ())
{
return HIR::SelfParam (mapping, std::unique_ptr<HIR::Type> (nullptr),
- self.get_is_mut (), self.get_locus ());
+ self->get_is_mut (), self->get_locus ());
}
- AST::Lifetime l = self.get_lifetime ();
- return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (),
- self.get_locus ());
+ AST::Lifetime l = self->get_lifetime ();
+ return HIR::SelfParam (mapping, lower_lifetime (l), self->get_is_mut (),
+ self->get_locus ());
}
HIR::Type *
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index a9411c2..510d1c9 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -251,6 +251,9 @@ public:
virtual void visit (AST::SliceType &type);
virtual void visit (AST::InferredType &type);
virtual void visit (AST::BareFunctionType &type);
+ virtual void visit (AST::FunctionParam &param);
+ virtual void visit (AST::VariadicParam &param);
+ virtual void visit (AST::SelfParam &param);
protected:
ASTLoweringBase ()
@@ -274,7 +277,7 @@ protected:
HIR::GenericArgsBinding lower_binding (AST::GenericArgsBinding &binding);
- HIR::SelfParam lower_self (AST::SelfParam &self);
+ HIR::SelfParam lower_self (std::unique_ptr<AST::Param> &self);
HIR::Type *lower_type_no_bounds (AST::TypeNoBounds *type);
diff --git a/gcc/rust/hir/rust-ast-lower-implitem.h b/gcc/rust/hir/rust-ast-lower-implitem.h
index 2a0d9fc..91602c9 100644
--- a/gcc/rust/hir/rust-ast-lower-implitem.h
+++ b/gcc/rust/hir/rust-ast-lower-implitem.h
@@ -23,6 +23,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
+#include "rust-item.h"
namespace Rust {
namespace HIR {
@@ -141,22 +142,26 @@ public:
: nullptr;
std::vector<HIR::FunctionParam> function_params;
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
+ if (p->is_self () || p->is_variadic ())
+ continue;
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
- ASTLoweringPattern::translate (param.get_pattern ().get ()));
+ ASTLoweringPattern::translate (param->get_pattern ().get ()));
auto translated_type = std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (param.get_type ().get ()));
+ ASTLoweringType::translate (param->get_type ().get ()));
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ 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 ());
+ param->get_locus ());
function_params.push_back (std::move (hir_param));
}
@@ -255,22 +260,27 @@ public:
: nullptr;
std::vector<HIR::FunctionParam> function_params;
- for (auto &param : ref.get_function_params ())
+ for (auto &p : ref.get_function_params ())
{
+ if (p->is_variadic () || p->is_self ())
+ continue;
+
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
- ASTLoweringPattern::translate (param.get_pattern ().get ()));
+ ASTLoweringPattern::translate (param->get_pattern ().get ()));
auto translated_type = std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (param.get_type ().get ()));
+ ASTLoweringType::translate (param->get_type ().get ()));
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ 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 ());
+ param->get_locus ());
function_params.push_back (std::move (hir_param));
}
@@ -329,22 +339,27 @@ public:
HIR::SelfParam self_param = lower_self (ref.get_self_param ());
std::vector<HIR::FunctionParam> function_params;
- for (auto &param : ref.get_function_params ())
+ for (auto &p : ref.get_function_params ())
{
+ if (p->is_variadic () || p->is_self ())
+ continue;
+
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
- ASTLoweringPattern::translate (param.get_pattern ().get ()));
+ ASTLoweringPattern::translate (param->get_pattern ().get ()));
auto translated_type = std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (param.get_type ().get ()));
+ ASTLoweringType::translate (param->get_type ().get ()));
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ 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 ());
+ param->get_locus ());
function_params.push_back (hir_param);
}
diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc
index d94383b..c024acf 100644
--- a/gcc/rust/hir/rust-ast-lower-item.cc
+++ b/gcc/rust/hir/rust-ast-lower-item.cc
@@ -26,6 +26,7 @@
#include "rust-ast-lower-expr.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-block.h"
+#include "rust-item.h"
namespace Rust {
namespace HIR {
@@ -420,21 +421,25 @@ ASTLoweringItem::visit (AST::Function &function)
: nullptr;
std::vector<HIR::FunctionParam> function_params;
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
+ if (p->is_variadic () || p->is_self ())
+ continue;
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+
auto translated_pattern = std::unique_ptr<HIR::Pattern> (
- ASTLoweringPattern::translate (param.get_pattern ().get ()));
+ ASTLoweringPattern::translate (param->get_pattern ().get ()));
auto translated_type = std::unique_ptr<HIR::Type> (
- ASTLoweringType::translate (param.get_type ().get ()));
+ ASTLoweringType::translate (param->get_type ().get ()));
auto crate_num = mappings->get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, param.get_node_id (),
+ 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 ());
+ std::move (translated_type), param->get_locus ());
function_params.push_back (std::move (hir_param));
}
diff --git a/gcc/rust/metadata/rust-export-metadata.cc b/gcc/rust/metadata/rust-export-metadata.cc
index 5f6aa1bd..09aad76 100644
--- a/gcc/rust/metadata/rust-export-metadata.cc
+++ b/gcc/rust/metadata/rust-export-metadata.cc
@@ -22,9 +22,11 @@
#include "rust-hir-map.h"
#include "rust-ast-dump.h"
#include "rust-abi.h"
+#include "rust-item.h"
#include "rust-object-export.h"
#include "md5.h"
+#include "rust-system.h"
namespace Rust {
namespace Metadata {
@@ -107,15 +109,18 @@ ExportContext::emit_function (const HIR::Function &fn)
}
std::vector<AST::NamedFunctionParam> function_params;
- for (AST::FunctionParam &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- std::string name = param.get_pattern ()->as_string ();
+ if (p->is_variadic () || p->is_self ())
+ rust_unreachable ();
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+ std::string name = param->get_pattern ()->as_string ();
std::unique_ptr<AST::Type> param_type
- = param.get_type ()->clone_type ();
+ = param->get_type ()->clone_type ();
- AST::NamedFunctionParam p (name, std::move (param_type), {},
- param.get_locus ());
- function_params.push_back (std::move (p));
+ AST::NamedFunctionParam np (name, std::move (param_type), {},
+ param->get_locus ());
+ function_params.push_back (std::move (np));
}
AST::ExternalItem *external_item
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h
index 44b4d74..64807b6 100644
--- a/gcc/rust/parse/rust-parse-impl.h
+++ b/gcc/rust/parse/rust-parse-impl.h
@@ -2879,12 +2879,21 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis,
return nullptr;
}
+ std::unique_ptr<AST::Param> initial_param = parse_self_param ();
+ if (initial_param != nullptr)
+ skip_token (COMMA);
+
// parse function parameters (only if next token isn't right paren)
- std::vector<AST::FunctionParam> function_params;
+ std::vector<std::unique_ptr<AST::Param>> function_params;
+
if (lexer.peek_token ()->get_id () != RIGHT_PAREN)
function_params
= parse_function_params ([] (TokenId id) { return id == RIGHT_PAREN; });
+ if (initial_param != nullptr)
+ function_params.insert (function_params.begin (),
+ std::move (initial_param));
+
if (!skip_token (RIGHT_PAREN))
{
Error error (lexer.peek_token ()->get_locus (),
@@ -2907,11 +2916,10 @@ 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),
- 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));
+ 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));
}
// Parses function or method qualifiers (i.e. const, unsafe, and extern).
@@ -3525,18 +3533,18 @@ Parser<ManagedTokenSource>::parse_type_param ()
* has end token handling. */
template <typename ManagedTokenSource>
template <typename EndTokenPred>
-std::vector<AST::FunctionParam>
+std::vector<std::unique_ptr<AST::Param>>
Parser<ManagedTokenSource>::parse_function_params (EndTokenPred is_end_token)
{
- std::vector<AST::FunctionParam> params;
+ std::vector<std::unique_ptr<AST::Param>> params;
if (is_end_token (lexer.peek_token ()->get_id ()))
return params;
- AST::FunctionParam initial_param = parse_function_param ();
+ auto initial_param = parse_function_param ();
// Return empty parameter list if no parameter there
- if (initial_param.is_error ())
+ if (initial_param == nullptr)
{
// TODO: is this an error?
return params;
@@ -3558,15 +3566,15 @@ Parser<ManagedTokenSource>::parse_function_params (EndTokenPred is_end_token)
break;
// now, as right paren would break, function param is required
- AST::FunctionParam param = parse_function_param ();
- if (param.is_error ())
+ auto param = parse_function_param ();
+ if (param == nullptr)
{
Error error (lexer.peek_token ()->get_locus (),
"failed to parse function param (in function params)");
add_error (std::move (error));
// skip somewhere?
- return std::vector<AST::FunctionParam> ();
+ return std::vector<std::unique_ptr<AST::Param>> ();
}
params.push_back (std::move (param));
@@ -3581,7 +3589,7 @@ Parser<ManagedTokenSource>::parse_function_params (EndTokenPred is_end_token)
/* Parses a single regular (i.e. non-generic) parameter in a function or
* method, i.e. the "name: type" bit. Also handles it not existing. */
template <typename ManagedTokenSource>
-AST::FunctionParam
+std::unique_ptr<AST::Param>
Parser<ManagedTokenSource>::parse_function_param ()
{
// parse outer attributes if they exist
@@ -3593,7 +3601,8 @@ Parser<ManagedTokenSource>::parse_function_param ()
if (lexer.peek_token ()->get_id () == ELLIPSIS) // Unnamed variadic
{
lexer.skip_token (); // Skip ellipsis
- return AST::FunctionParam (std::move (outer_attrs), locus);
+ return Rust::make_unique<AST::VariadicParam> (
+ AST::VariadicParam (std::move (outer_attrs), locus));
}
std::unique_ptr<AST::Pattern> param_pattern = parse_pattern ();
@@ -3602,32 +3611,32 @@ Parser<ManagedTokenSource>::parse_function_param ()
if (param_pattern == nullptr)
{
// skip after something
- return AST::FunctionParam::create_error ();
+ return nullptr;
}
if (!skip_token (COLON))
{
// skip after something
- return AST::FunctionParam::create_error ();
+ return nullptr;
}
if (lexer.peek_token ()->get_id () == ELLIPSIS) // Named variadic
{
lexer.skip_token (); // Skip ellipsis
- return AST::FunctionParam (std::move (param_pattern),
- std::move (outer_attrs), locus);
+ return Rust::make_unique<AST::VariadicParam> (
+ AST::VariadicParam (std::move (param_pattern), std::move (outer_attrs),
+ locus));
}
else
{
std::unique_ptr<AST::Type> param_type = parse_type ();
if (param_type == nullptr)
{
- // skip?
- return AST::FunctionParam::create_error ();
+ return nullptr;
}
- return AST::FunctionParam (std::move (param_pattern),
- std::move (param_type),
- std::move (outer_attrs), locus);
+ return Rust::make_unique<AST::FunctionParam> (
+ AST::FunctionParam (std::move (param_pattern), std::move (param_type),
+ std::move (outer_attrs), locus));
}
}
@@ -5051,13 +5060,14 @@ Parser<ManagedTokenSource>::parse_trait_item ()
/* now for function vs method disambiguation - method has opening
* "self" param */
- AST::SelfParam self_param = parse_self_param ();
+ std::unique_ptr<AST::Param> initial_param = parse_self_param ();
/* FIXME: ensure that self param doesn't accidently consume tokens for
* a function */
bool is_method = false;
- if (!self_param.is_error ())
+ if (initial_param != nullptr)
{
- is_method = true;
+ if (initial_param->is_self ())
+ is_method = true;
/* skip comma so function and method regular params can be parsed
* in same way */
@@ -5066,7 +5076,7 @@ Parser<ManagedTokenSource>::parse_trait_item ()
}
// parse trait function params
- std::vector<AST::FunctionParam> function_params
+ std::vector<std::unique_ptr<AST::Param>> function_params
= parse_function_params (
[] (TokenId id) { return id == RIGHT_PAREN; });
@@ -5076,6 +5086,10 @@ Parser<ManagedTokenSource>::parse_trait_item ()
return nullptr;
}
+ if (initial_param != nullptr)
+ 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 ();
@@ -5114,7 +5128,6 @@ Parser<ManagedTokenSource>::parse_trait_item ()
AST::TraitMethodDecl method_decl (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));
@@ -5592,14 +5605,15 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
// now for function vs method disambiguation - method has opening "self"
// param
- AST::SelfParam self_param = parse_self_param ();
+ std::unique_ptr<AST::Param> initial_param = parse_self_param ();
/* FIXME: ensure that self param doesn't accidently consume tokens for a
* function one idea is to lookahead up to 4 tokens to see whether self is
* one of them */
bool is_method = false;
- if (!self_param.is_error ())
+ if (initial_param != nullptr)
{
- is_method = true;
+ if (initial_param->is_self ())
+ is_method = true;
/* skip comma so function and method regular params can be parsed in
* same way */
@@ -5608,9 +5622,13 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
}
// parse trait function params
- std::vector<AST::FunctionParam> function_params
+ std::vector<std::unique_ptr<AST::Param>> function_params
= parse_function_params ([] (TokenId id) { return id == RIGHT_PAREN; });
+ if (initial_param != nullptr)
+ function_params.insert (function_params.begin (),
+ std::move (initial_param));
+
if (!skip_token (RIGHT_PAREN))
{
skip_after_end_block ();
@@ -5650,18 +5668,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::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));
+ 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),
+ 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), tl::nullopt,
+ std::move (generic_params),
std::move (function_params), std::move (return_type),
std::move (where_clause), std::move (body),
std::move (vis), std::move (outer_attrs), locus));
@@ -5795,13 +5813,14 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
// now for function vs method disambiguation - method has opening "self"
// param
- AST::SelfParam self_param = parse_self_param ();
+ std::unique_ptr<AST::Param> initial_param = parse_self_param ();
// FIXME: ensure that self param doesn't accidently consume tokens for a
// function
bool is_method = false;
- if (!self_param.is_error ())
+ if (initial_param != nullptr)
{
- is_method = true;
+ if (initial_param->is_self ())
+ is_method = true;
// skip comma so function and method regular params can be parsed in
// same way
@@ -5819,7 +5838,7 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
"started to parse function params in function or method trait impl item");
// parse trait function params (only if next token isn't right paren)
- std::vector<AST::FunctionParam> function_params;
+ std::vector<std::unique_ptr<AST::Param>> function_params;
if (lexer.peek_token ()->get_id () != RIGHT_PAREN)
{
function_params
@@ -5838,6 +5857,10 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
}
}
+ if (initial_param != nullptr)
+ function_params.insert (function_params.begin (),
+ std::move (initial_param));
+
// DEBUG
rust_debug ("successfully parsed function params in function or method "
"trait impl item");
@@ -5886,24 +5909,12 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
return nullptr;
}
- // do actual if instead of ternary for return value optimisation
- if (is_method)
- {
- 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, is_default));
- }
- else
- {
- return std::unique_ptr<AST::Function> (new AST::Function (
- std::move (ident), std::move (qualifiers), 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, is_default));
- }
+ 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), std::move (where_clause),
+ std::move (body), std::move (vis),
+ std::move (outer_attrs), locus, is_default));
}
// Parses an extern block of declarations.
@@ -7097,7 +7108,7 @@ Parser<ManagedTokenSource>::parse_qualified_path_in_type ()
// Parses a self param. Also handles self param not existing.
template <typename ManagedTokenSource>
-AST::SelfParam
+std::unique_ptr<AST::Param>
Parser<ManagedTokenSource>::parse_self_param ()
{
bool has_reference = false;
@@ -7105,6 +7116,42 @@ Parser<ManagedTokenSource>::parse_self_param ()
location_t locus = lexer.peek_token ()->get_locus ();
+ // TODO: Feels off, find a better way to clearly express this
+ std::vector<std::vector<TokenId>> ptrs
+ = {{ASTERISK, SELF} /* *self */,
+ {ASTERISK, CONST, SELF} /* *const self */,
+ {ASTERISK, MUT, SELF} /* *mut self */};
+
+ for (auto &s : ptrs)
+ {
+ size_t i = 0;
+ for (i = 0; i > s.size (); i++)
+ if (lexer.peek_token (i)->get_id () != s[i])
+ break;
+ if (i == s.size ())
+ rust_error_at (lexer.peek_token ()->get_locus (),
+ "cannot pass %<self%> by raw pointer");
+ }
+
+ // Trying to find those patterns:
+ //
+ // &'lifetime mut self
+ // &'lifetime self
+ // & mut self
+ // & self
+ // mut self
+ // self
+ //
+ // If not found, it is probably a function, exit and let function parsing
+ // handle it.
+ bool is_self = false;
+ for (size_t i = 0; i < 5; i++)
+ if (lexer.peek_token (i)->get_id () == SELF)
+ is_self = true;
+
+ if (!is_self)
+ return nullptr;
+
// test if self is a reference parameter
if (lexer.peek_token ()->get_id () == AMP)
{
@@ -7124,7 +7171,7 @@ Parser<ManagedTokenSource>::parse_self_param ()
add_error (std::move (error));
// skip after somewhere?
- return AST::SelfParam::create_error ();
+ return nullptr;
}
}
}
@@ -7142,7 +7189,7 @@ Parser<ManagedTokenSource>::parse_self_param ()
if (self_tok->get_id () != SELF)
{
// skip after somewhere?
- return AST::SelfParam::create_error ();
+ return nullptr;
}
lexer.skip_token ();
@@ -7161,7 +7208,7 @@ Parser<ManagedTokenSource>::parse_self_param ()
add_error (std::move (error));
// skip after somewhere?
- return AST::SelfParam::create_error ();
+ return nullptr;
}
}
@@ -7174,114 +7221,20 @@ Parser<ManagedTokenSource>::parse_self_param ()
add_error (std::move (error));
// skip after somewhere?
- return AST::SelfParam::create_error ();
+ return nullptr;
}
if (has_reference)
{
- return AST::SelfParam (std::move (lifetime), has_mut, locus);
+ return Rust::make_unique<AST::SelfParam> (std::move (lifetime), has_mut,
+ locus);
}
else
{
// note that type may be nullptr here and that's fine
- return AST::SelfParam (std::move (type), has_mut, locus);
- }
-}
-
-/* Parses a method. Note that this function is probably useless because using
- * lookahead to determine whether a function is a method is a PITA (maybe not
- * even doable), so most places probably parse a "function or method" and then
- * resolve it into whatever it is afterward. As such, this is only here for
- * algorithmically defining the grammar rule. */
-template <typename ManagedTokenSource>
-std::unique_ptr<AST::Function>
-Parser<ManagedTokenSource>::parse_method ()
-{
- location_t locus = lexer.peek_token ()->get_locus ();
- /* Note: as a result of the above, this will not attempt to disambiguate a
- * function parse qualifiers */
- AST::FunctionQualifiers qualifiers = parse_function_qualifiers ();
-
- skip_token (FN_TOK);
-
- const_TokenPtr ident_tok = expect_token (IDENTIFIER);
- if (ident_tok == nullptr)
- {
- skip_after_next_block ();
- return nullptr;
+ return Rust::make_unique<AST::SelfParam> (std::move (type), has_mut,
+ locus);
}
- Identifier method_name{ident_tok};
-
- // parse generic params - if exist
- std::vector<std::unique_ptr<AST::GenericParam>> generic_params
- = parse_generic_params_in_angles ();
-
- if (!skip_token (LEFT_PAREN))
- {
- Error error (lexer.peek_token ()->get_locus (),
- "method missing opening parentheses before parameter list");
- add_error (std::move (error));
-
- skip_after_next_block ();
- return nullptr;
- }
-
- // parse self param
- AST::SelfParam self_param = parse_self_param ();
- if (self_param.is_error ())
- {
- Error error (lexer.peek_token ()->get_locus (),
- "could not parse self param in method");
- add_error (std::move (error));
-
- skip_after_next_block ();
- return nullptr;
- }
-
- // skip comma if it exists
- if (lexer.peek_token ()->get_id () == COMMA)
- lexer.skip_token ();
-
- // parse function parameters
- std::vector<AST::FunctionParam> function_params
- = parse_function_params ([] (TokenId id) { return id == RIGHT_PAREN; });
-
- if (!skip_token (RIGHT_PAREN))
- {
- Error error (lexer.peek_token ()->get_locus (),
- "method declaration missing closing parentheses after "
- "parameter list");
- add_error (std::move (error));
-
- skip_after_next_block ();
- return nullptr;
- }
-
- // parse function return type - if exists
- std::unique_ptr<AST::Type> return_type = parse_function_return_type ();
-
- // parse where clause - if exists
- AST::WhereClause where_clause = parse_where_clause ();
-
- // parse block expression
- std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
- if (block_expr == nullptr)
- {
- Error error (lexer.peek_token ()->get_locus (),
- "method declaration missing block expression");
- add_error (std::move (error));
-
- skip_after_end_block ();
- return nullptr;
- }
-
- // does not parse visibility, but this method isn't used, so doesn't matter
- 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 3ff9b99..9e924e0 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -164,7 +164,7 @@ public:
std::unique_ptr<AST::InherentImplItem> parse_inherent_impl_item ();
std::unique_ptr<AST::TraitImplItem> parse_trait_impl_item ();
AST::PathInExpression parse_path_in_expression ();
- std::vector<std::unique_ptr<AST::LifetimeParam> > parse_lifetime_params ();
+ std::vector<std::unique_ptr<AST::LifetimeParam>> parse_lifetime_params ();
AST::Visibility parse_visibility ();
std::unique_ptr<AST::IdentifierPattern> parse_identifier_pattern ();
std::unique_ptr<AST::Token> parse_identifier_or_keyword_token ();
@@ -246,17 +246,17 @@ private:
std::unique_ptr<AST::Function> parse_function (AST::Visibility vis,
AST::AttrVec outer_attrs);
AST::FunctionQualifiers parse_function_qualifiers ();
- std::vector<std::unique_ptr<AST::GenericParam> >
+ std::vector<std::unique_ptr<AST::GenericParam>>
parse_generic_params_in_angles ();
template <typename EndTokenPred>
- std::vector<std::unique_ptr<AST::GenericParam> >
+ std::vector<std::unique_ptr<AST::GenericParam>>
parse_generic_params (EndTokenPred is_end_token);
template <typename EndTokenPred>
std::unique_ptr<AST::GenericParam>
parse_generic_param (EndTokenPred is_end_token);
template <typename EndTokenPred>
- std::vector<std::unique_ptr<AST::LifetimeParam> >
+ std::vector<std::unique_ptr<AST::LifetimeParam>>
parse_lifetime_params (EndTokenPred is_end_token);
std::vector<AST::LifetimeParam> parse_lifetime_params_objs ();
template <typename EndTokenPred>
@@ -268,15 +268,15 @@ private:
std::string error_msg = "failed to parse generic param in generic params")
-> std::vector<decltype (parsing_function ())>;
AST::LifetimeParam parse_lifetime_param ();
- std::vector<std::unique_ptr<AST::TypeParam> > parse_type_params ();
+ std::vector<std::unique_ptr<AST::TypeParam>> parse_type_params ();
template <typename EndTokenPred>
- std::vector<std::unique_ptr<AST::TypeParam> >
+ std::vector<std::unique_ptr<AST::TypeParam>>
parse_type_params (EndTokenPred is_end_token);
std::unique_ptr<AST::TypeParam> parse_type_param ();
template <typename EndTokenPred>
- std::vector<AST::FunctionParam>
+ std::vector<std::unique_ptr<AST::Param>>
parse_function_params (EndTokenPred is_end_token);
- AST::FunctionParam parse_function_param ();
+ std::unique_ptr<AST::Param> parse_function_param ();
std::unique_ptr<AST::Type> parse_function_return_type ();
AST::WhereClause parse_where_clause ();
std::unique_ptr<AST::WhereClauseItem> parse_where_clause_item ();
@@ -286,9 +286,9 @@ private:
parse_type_bound_where_clause_item ();
std::vector<AST::LifetimeParam> parse_for_lifetimes ();
template <typename EndTokenPred>
- std::vector<std::unique_ptr<AST::TypeParamBound> >
+ std::vector<std::unique_ptr<AST::TypeParamBound>>
parse_type_param_bounds (EndTokenPred is_end_token);
- std::vector<std::unique_ptr<AST::TypeParamBound> > parse_type_param_bounds ();
+ std::vector<std::unique_ptr<AST::TypeParamBound>> parse_type_param_bounds ();
std::unique_ptr<AST::TypeParamBound> parse_type_param_bound ();
std::unique_ptr<AST::TraitBound> parse_trait_bound ();
std::vector<AST::Lifetime> parse_lifetime_bounds ();
@@ -317,9 +317,9 @@ private:
AST::TupleField parse_tuple_field ();
std::unique_ptr<AST::Enum> parse_enum (AST::Visibility vis,
AST::AttrVec outer_attrs);
- std::vector<std::unique_ptr<AST::EnumItem> > parse_enum_items ();
+ std::vector<std::unique_ptr<AST::EnumItem>> parse_enum_items ();
template <typename EndTokenPred>
- std::vector<std::unique_ptr<AST::EnumItem> >
+ std::vector<std::unique_ptr<AST::EnumItem>>
parse_enum_items (EndTokenPred is_end_token);
std::unique_ptr<AST::EnumItem> parse_enum_item ();
std::unique_ptr<AST::Union> parse_union (AST::Visibility vis,
@@ -334,7 +334,7 @@ private:
parse_trait_type (AST::AttrVec outer_attrs);
std::unique_ptr<AST::TraitItemConst>
parse_trait_const (AST::AttrVec outer_attrs);
- AST::SelfParam parse_self_param ();
+ std::unique_ptr<AST::Param> parse_self_param ();
std::unique_ptr<AST::Impl> parse_impl (AST::Visibility vis,
AST::AttrVec outer_attrs);
std::unique_ptr<AST::InherentImplItem>
@@ -594,7 +594,7 @@ private:
parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
AST::MatchArm parse_match_arm ();
- std::vector<std::unique_ptr<AST::Pattern> >
+ std::vector<std::unique_ptr<AST::Pattern>>
parse_match_arm_patterns (TokenId end_token_id);
std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs
@@ -692,7 +692,7 @@ public:
// Parse items without parsing an entire crate. This function is the main
// parsing loop of AST::Crate::parse_crate().
- std::vector<std::unique_ptr<AST::Item> > parse_items ();
+ std::vector<std::unique_ptr<AST::Item>> parse_items ();
// Main entry point for parser.
std::unique_ptr<AST::Crate> parse_crate ();
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.cc b/gcc/rust/resolve/rust-ast-resolve-base.cc
index 14af430..994a57a 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-base.cc
@@ -646,5 +646,17 @@ void
ResolverBase::visit (AST::BareFunctionType &)
{}
+void
+ResolverBase::visit (AST::SelfParam &)
+{}
+
+void
+ResolverBase::visit (AST::VariadicParam &)
+{}
+
+void
+ResolverBase::visit (AST::FunctionParam &)
+{}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h
index 9c124b1..145fc46 100644
--- a/gcc/rust/resolve/rust-ast-resolve-base.h
+++ b/gcc/rust/resolve/rust-ast-resolve-base.h
@@ -196,6 +196,9 @@ public:
void visit (AST::SliceType &);
void visit (AST::InferredType &);
void visit (AST::BareFunctionType &);
+ void visit (AST::FunctionParam &param);
+ void visit (AST::VariadicParam &param);
+ void visit (AST::SelfParam &param);
protected:
ResolverBase ()
diff --git a/gcc/rust/resolve/rust-ast-resolve-item.cc b/gcc/rust/resolve/rust-ast-resolve-item.cc
index 5cd0a4d..6541737 100644
--- a/gcc/rust/resolve/rust-ast-resolve-item.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-item.cc
@@ -17,11 +17,13 @@
// <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 {
@@ -87,11 +89,26 @@ ResolveTraitItems::visit (AST::TraitItemFunc &func)
// we make a new scope so the names of parameters are resolved and shadowed
// correctly
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- ResolveType::go (param.get_type ().get ());
- PatternDeclaration::go (param.get_pattern ().get (), Rib::ItemType::Param,
- bindings);
+ if (p->is_variadic ())
+ {
+ auto param = static_cast<AST::VariadicParam *> (p.get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
+ else if (p->is_self ())
+ {
+ auto param = static_cast<AST::SelfParam *> (p.get ());
+ ResolveType::go (param->get_type ().get ());
+ }
+ else
+ {
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+ ResolveType::go (param->get_type ().get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
}
if (function.has_where_clause ())
@@ -133,43 +150,55 @@ ResolveTraitItems::visit (AST::TraitItemMethod &func)
ResolveType::go (function.get_return_type ().get ());
// 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> ())};
// we make a new scope so the names of parameters are resolved and shadowed
// correctly
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- ResolveType::go (param.get_type ().get ());
- PatternDeclaration::go (param.get_pattern ().get (), Rib::ItemType::Param,
- bindings);
+ if (p->is_variadic ())
+ {
+ auto param = static_cast<AST::VariadicParam *> (p.get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
+ else if (p->is_self ())
+ {
+ auto param = static_cast<AST::SelfParam *> (p.get ());
+ // 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 ().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, param->get_locus ())));
+
+ AST::TypePath self_type_path (std::move (segments),
+ param->get_locus ());
+ ResolveType::go (&self_type_path);
+ }
+ }
+ else
+ {
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+ ResolveType::go (param->get_type ().get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
}
if (function.has_where_clause ())
@@ -527,29 +556,32 @@ ResolveItem::visit (AST::Function &function)
if (function.has_self_param ())
{
// self turns into (self: Self) as a function param
- AST::SelfParam &self_param = function.get_self_param ();
+ std::unique_ptr<AST::Param> &s_param = function.get_self_param ();
+ auto self_param = static_cast<AST::SelfParam *> (s_param.get ());
+
// 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 (),
+ 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 ())
+ 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 ());
+ 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 ())));
+ new AST::TypePathSegment ("Self", false,
+ self_param->get_locus ())));
AST::TypePath self_type_path (std::move (segments),
- self_param.get_locus ());
+ self_param->get_locus ());
ResolveType::go (&self_type_path);
}
}
@@ -559,11 +591,28 @@ ResolveItem::visit (AST::Function &function)
// we make a new scope so the names of parameters are resolved and shadowed
// correctly
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- ResolveType::go (param.get_type ().get ());
- PatternDeclaration::go (param.get_pattern ().get (), Rib::ItemType::Param,
- bindings);
+ if (p->is_variadic ())
+ {
+ auto param = static_cast<AST::VariadicParam *> (p.get ());
+ if (param->has_pattern ())
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
+ else if (p->is_self ())
+ {
+ auto param = static_cast<AST::SelfParam *> (p.get ());
+ if (param->has_type ())
+ ResolveType::go (param->get_type ().get ());
+ }
+ else
+ {
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+ ResolveType::go (param->get_type ().get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
}
// resolve the function body
diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h
index 420f75e..3be5f12 100644
--- a/gcc/rust/resolve/rust-ast-resolve-stmt.h
+++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h
@@ -23,6 +23,7 @@
#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 {
@@ -352,11 +353,28 @@ public:
// we make a new scope so the names of parameters are resolved and shadowed
// correctly
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- ResolveType::go (param.get_type ().get ());
- PatternDeclaration::go (param.get_pattern ().get (),
- Rib::ItemType::Param, bindings);
+ if (p->is_variadic ())
+ {
+ auto param = static_cast<AST::VariadicParam *> (p.get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
+
+ else if (p->is_self ())
+ {
+ auto param = static_cast<AST::SelfParam *> (p.get ());
+ ResolveType::go (param->get_type ().get ());
+ }
+ else
+ {
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+
+ ResolveType::go (param->get_type ().get ());
+ PatternDeclaration::go (param->get_pattern ().get (),
+ Rib::ItemType::Param, bindings);
+ }
}
// resolve the function body
diff --git a/gcc/rust/resolve/rust-default-resolver.cc b/gcc/rust/resolve/rust-default-resolver.cc
index fc81001..1ab174b 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -18,6 +18,7 @@
#include "rust-default-resolver.h"
#include "rust-ast-full.h"
+#include "rust-item.h"
namespace Rust {
namespace Resolver2_0 {
@@ -55,10 +56,25 @@ void
DefaultResolver::visit (AST::Function &function)
{
auto def_fn = [this, &function] () {
- for (auto &param : function.get_function_params ())
+ for (auto &p : function.get_function_params ())
{
- param.get_pattern ()->accept_vis (*this);
- param.get_type ()->accept_vis (*this);
+ if (p->is_variadic ())
+ {
+ auto param = static_cast<AST::VariadicParam *> (p.get ());
+ param->get_pattern ()->accept_vis (*this);
+ }
+ else if (p->is_self ())
+ {
+ auto param = static_cast<AST::SelfParam *> (p.get ());
+ param->get_type ()->accept_vis (*this);
+ param->get_lifetime ().accept_vis (*this);
+ }
+ else
+ {
+ auto param = static_cast<AST::FunctionParam *> (p.get ());
+ param->get_pattern ()->accept_vis (*this);
+ param->get_type ()->accept_vis (*this);
+ }
}
function.get_definition ()->accept_vis (*this);
@@ -801,5 +817,17 @@ void
DefaultResolver::visit (AST::BareFunctionType &)
{}
+void
+DefaultResolver::visit (AST::SelfParam &)
+{}
+
+void
+DefaultResolver::visit (AST::FunctionParam &)
+{}
+
+void
+DefaultResolver::visit (AST::VariadicParam &)
+{}
+
} // namespace Resolver2_0
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-default-resolver.h b/gcc/rust/resolve/rust-default-resolver.h
index 8af9513..49255d3 100644
--- a/gcc/rust/resolve/rust-default-resolver.h
+++ b/gcc/rust/resolve/rust-default-resolver.h
@@ -197,6 +197,9 @@ public:
void visit (AST::SliceType &);
void visit (AST::InferredType &);
void visit (AST::BareFunctionType &);
+ void visit (AST::FunctionParam &);
+ void visit (AST::VariadicParam &);
+ void visit (AST::SelfParam &);
protected:
DefaultResolver (NameResolutionContext &ctx) : ctx (ctx) {}
diff --git a/gcc/rust/resolve/rust-early-name-resolver.cc b/gcc/rust/resolve/rust-early-name-resolver.cc
index 3a485a0..4f01406 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.cc
+++ b/gcc/rust/resolve/rust-early-name-resolver.cc
@@ -662,11 +662,8 @@ 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);
+ for (auto &p : function.get_function_params ())
+ p->accept_vis (*this);
if (function.has_return_type ())
function.get_return_type ()->accept_vis (*this);
@@ -758,8 +755,8 @@ EarlyNameResolver::visit (AST::TraitItemFunc &item)
for (auto &generic : decl.get_generic_params ())
generic->accept_vis (*this);
- for (auto &param : decl.get_function_params ())
- param.get_type ()->accept_vis (*this);
+ for (auto &p : decl.get_function_params ())
+ p->accept_vis (*this);
if (item.has_definition ())
item.get_definition ()->accept_vis (*this);
@@ -777,8 +774,8 @@ EarlyNameResolver::visit (AST::TraitItemMethod &item)
for (auto &generic : decl.get_generic_params ())
generic->accept_vis (*this);
- for (auto &param : decl.get_function_params ())
- param.get_type ()->accept_vis (*this);
+ for (auto &p : decl.get_function_params ())
+ p->accept_vis (*this);
if (item.has_definition ())
item.get_definition ()->accept_vis (*this);
@@ -1232,5 +1229,28 @@ EarlyNameResolver::visit (AST::BareFunctionType &type)
type.get_return_type ()->accept_vis (*this);
}
+void
+EarlyNameResolver::visit (AST::VariadicParam &param)
+{
+ if (param.has_pattern ())
+ param.get_pattern ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::FunctionParam &param)
+{
+ param.get_pattern ()->accept_vis (*this);
+ param.get_type ()->accept_vis (*this);
+}
+
+void
+EarlyNameResolver::visit (AST::SelfParam &param)
+{
+ if (param.has_type ())
+ param.get_type ()->accept_vis (*this);
+ if (param.has_lifetime ())
+ param.get_lifetime ().accept_vis (*this);
+}
+
} // namespace Resolver
} // namespace Rust
diff --git a/gcc/rust/resolve/rust-early-name-resolver.h b/gcc/rust/resolve/rust-early-name-resolver.h
index 005b34c..2effa76 100644
--- a/gcc/rust/resolve/rust-early-name-resolver.h
+++ b/gcc/rust/resolve/rust-early-name-resolver.h
@@ -277,6 +277,10 @@ private:
virtual void visit (AST::SliceType &type);
virtual void visit (AST::InferredType &type);
virtual void visit (AST::BareFunctionType &type);
+
+ virtual void visit (AST::VariadicParam &type);
+ virtual void visit (AST::FunctionParam &type);
+ virtual void visit (AST::SelfParam &type);
};
} // namespace Resolver
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index c386edc..99931ff 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -996,5 +996,17 @@ void
AttributeChecker::visit (AST::BareFunctionType &)
{}
+void
+AttributeChecker::visit (AST::SelfParam &)
+{}
+
+void
+AttributeChecker::visit (AST::VariadicParam &)
+{}
+
+void
+AttributeChecker::visit (AST::FunctionParam &)
+{}
+
} // namespace Analysis
} // namespace Rust
diff --git a/gcc/rust/util/rust-attributes.h b/gcc/rust/util/rust-attributes.h
index c984cb7..70cac30 100644
--- a/gcc/rust/util/rust-attributes.h
+++ b/gcc/rust/util/rust-attributes.h
@@ -264,6 +264,9 @@ private:
void visit (AST::SliceType &type);
void visit (AST::InferredType &type);
void visit (AST::BareFunctionType &type);
+ void visit (AST::FunctionParam &param);
+ void visit (AST::VariadicParam &param);
+ void visit (AST::SelfParam &param);
};
} // namespace Analysis