aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/expand/rust-macro-expand.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/expand/rust-macro-expand.cc')
-rw-r--r--gcc/rust/expand/rust-macro-expand.cc786
1 files changed, 709 insertions, 77 deletions
diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc
index 7dd9750..2fe84cb 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -15,37 +15,197 @@ namespace Rust {
void expand_struct_fields(std::vector<AST::StructField>& fields) {
for (int i = 0; i < fields.size();) {
- auto& field_attrs = fields[i].get_outer_attrs();
+ auto& field = fields[i];
+
+ auto& field_attrs = field.get_outer_attrs();
expander.expand_cfg_attrs(field_attrs);
- if (expander.fails_cfg(field_attrs))
+ if (expander.fails_cfg(field_attrs)) {
fields.erase(fields.begin() + i);
- else
- i++;
+ continue;
+ }
+
+ // expand sub-types of type, but can't strip type itself
+ auto& type = field.get_field_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ // if nothing else happens, increment
+ i++;
}
}
void expand_tuple_fields(std::vector<AST::TupleField>& fields) {
for (int i = 0; i < fields.size();) {
- auto& field_attrs = fields[i].get_outer_attrs();
+ auto& field = fields[i];
+
+ auto& field_attrs = field.get_outer_attrs();
expander.expand_cfg_attrs(field_attrs);
- if (expander.fails_cfg(field_attrs))
+ if (expander.fails_cfg(field_attrs)) {
fields.erase(fields.begin() + i);
- else
- i++;
+ continue;
+ }
+
+ // expand sub-types of type, but can't strip type itself
+ auto& type = field.get_field_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ // if nothing else happens, increment
+ i++;
}
}
void expand_function_params(std::vector<AST::FunctionParam>& params) {
for (int i = 0; i < params.size();) {
- auto& param_attrs = params[i].get_outer_attrs();
+ auto& param = params[i];
+
+ auto& param_attrs = param.get_outer_attrs();
expander.expand_cfg_attrs(param_attrs);
- if (expander.fails_cfg(param_attrs))
+ if (expander.fails_cfg(param_attrs)) {
params.erase(params.begin() + i);
- else
- i++;
+ continue;
+ }
+
+ // 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_slow(), "cannot strip pattern in this position");
+
+ auto& type = param.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ // increment
+ i++;
+ }
+ }
+
+ void expand_generic_args(AST::GenericArgs& args) {
+ // lifetime args can't be expanded
+
+ // expand type args - strip sub-types only
+ for (auto& type : args.get_type_args()) {
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ // expand binding args - strip sub-types only
+ for (auto& binding : args.get_binding_args()) {
+ auto& type = binding.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+ }
+ }
+
+ void expand_qualified_path_type(AST::QualifiedPathType& path_type) {
+ auto& type = path_type.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ if (path_type.has_as_clause()) {
+ auto& type_path = path_type.get_as_type_path();
+ visit(type_path);
+ if (type_path.is_marked_for_strip())
+ rust_error_at(type_path.get_locus(), "cannot strip type path in this position");
+ }
+ }
+
+ void expand_closure_params(std::vector<AST::ClosureParam>& params) {
+ for (int i = 0; i < params.size();) {
+ auto& param = params[i];
+
+ auto& param_attrs = param.get_outer_attrs();
+ expander.expand_cfg_attrs(param_attrs);
+ if (expander.fails_cfg(param_attrs)) {
+ params.erase(params.begin() + i);
+ continue;
+ }
+
+ auto& pattern = param.get_pattern();
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+
+ if (param.has_type_given()) {
+ auto& type = param.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ // increment if found nothing else so far
+ i++;
}
}
+ void expand_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_slow(), "cannot strip type in this position");
+ }
+ // TODO: maybe check for invariants being violated - e.g. both type and lifetime?
+ }
+
+ void expand_where_clause(AST::WhereClause& where_clause) {
+ // items cannot be stripped conceptually, so just accept visitor
+ for (auto& item : where_clause.get_items())
+ item->accept_vis(*this);
+ }
+
+ void expand_trait_function_decl(AST::TraitFunctionDecl& decl) {
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : decl.get_generic_params())
+ param->accept_vis(*this);
+
+ /* strip function parameters if required - this is specifically
+ * allowed by spec */
+ expand_function_params(decl.get_function_params());
+
+ if (decl.has_return_type()) {
+ auto& return_type = decl.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (decl.has_where_clause())
+ expand_where_clause(decl.get_where_clause());
+ }
+
+ void expand_trait_method_decl(AST::TraitMethodDecl& decl) {
+ // just expand sub-stuff - can't actually strip generic params themselves
+ 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. */
+ 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());
+
+ if (decl.has_return_type()) {
+ auto& return_type = decl.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (decl.has_where_clause())
+ expand_where_clause(decl.get_where_clause());
+ }
+
void visit(AST::Token& tok) override {
// shouldn't require?
}
@@ -77,7 +237,11 @@ namespace Rust {
return;
}
+ // can't strip simple path
+
// I don't think any macro token trees can be stripped in any way
+
+ // TODO: maybe have cfg! macro stripping behaviour here?
}
void visit(AST::PathInExpression& path) override {
@@ -87,18 +251,43 @@ namespace Rust {
path.mark_for_strip();
return;
}
+
+ for (auto& segment : path.get_segments()) {
+ if (segment.has_generic_args())
+ expand_generic_args(segment.get_generic_args());
+ }
}
void visit(AST::TypePathSegment& segment) override {
- // shouldn't require?
+ // shouldn't require
}
void visit(AST::TypePathSegmentGeneric& segment) override {
- // shouldn't require?
+ // TODO: strip inside generic args
+
+ if (!segment.has_generic_args())
+ return;
+
+ expand_generic_args(segment.get_generic_args());
}
void visit(AST::TypePathSegmentFunction& segment) override {
- // shouldn't require?
+ auto& type_path_function = segment.get_type_path_function();
+
+ for (auto& type : type_path_function.get_params()) {
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (type_path_function.has_return_type()) {
+ auto& return_type = type_path_function.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
}
void visit(AST::TypePath& path) override {
- // shouldn't require?
+ // this shouldn't strip any segments, but can strip inside them
+ for (auto& segment : path.get_segments())
+ segment->accept_vis(*this);
}
void visit(AST::QualifiedPathInExpression& path) override {
// initial strip test based on outer attrs
@@ -107,9 +296,20 @@ namespace Rust {
path.mark_for_strip();
return;
}
+
+ expand_qualified_path_type(path.get_qualified_path_type());
+
+ for (auto& segment : path.get_segments()) {
+ if (segment.has_generic_args())
+ expand_generic_args(segment.get_generic_args());
+ }
}
void visit(AST::QualifiedPathInType& path) override {
- // shouldn't require?
+ expand_qualified_path_type(path.get_qualified_path_type());
+
+ // this shouldn't strip any segments, but can strip inside them
+ for (auto& segment : path.get_segments())
+ segment->accept_vis(*this);
}
void visit(AST::LiteralExpr& expr) override {
@@ -258,14 +458,21 @@ namespace Rust {
/* outer attributes never allowed before these. while cannot strip
* direct descendant expression, can strip ones below that */
+ auto& casted_expr = expr.get_casted_expr();
/* should have no possibility for outer attrs as would be parsed
* with outer expr */
- expr.get_casted_expr()->accept_vis(*this);
+ casted_expr->accept_vis(*this);
// ensure that they are not marked for strip
- if (expr.get_casted_expr()->is_marked_for_strip())
- rust_error_at(expr.get_casted_expr()->get_locus_slow(),
+ if (casted_expr->is_marked_for_strip())
+ rust_error_at(casted_expr->get_locus_slow(),
"cannot strip expression in this position - outer attributes are never allowed before cast exprs");
+
+ // TODO: strip sub-types of type
+ auto& type = expr.get_type_to_cast_to();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
}
void visit(AST::AssignmentExpr& expr) override {
/* outer attributes never allowed before these. while cannot strip
@@ -478,6 +685,12 @@ namespace Rust {
expr.mark_for_strip();
return;
}
+
+ // strip sub-exprs of path
+ auto& struct_name = expr.get_struct_name();
+ visit(struct_name);
+ if (struct_name.is_marked_for_strip())
+ rust_error_at(struct_name.get_locus(), "cannot strip path in this position");
}
void visit(AST::StructExprFieldIdentifier& field) override {
// as no attrs (at moment, at least), no stripping possible
@@ -514,7 +727,13 @@ namespace Rust {
if (expander.fails_cfg(expr.get_inner_attrs())) {
expr.mark_for_strip();
return;
- }
+ }
+
+ // strip sub-exprs of path
+ auto& struct_name = expr.get_struct_name();
+ visit(struct_name);
+ if (struct_name.is_marked_for_strip())
+ rust_error_at(struct_name.get_locus(), "cannot strip path in this position");
/* spec does not specify whether expressions are allowed to be
* stripped at top level of struct fields, but I wouldn't think
@@ -551,6 +770,12 @@ namespace Rust {
return;
}
+ // strip sub-exprs of path
+ auto& struct_name = expr.get_struct_name();
+ visit(struct_name);
+ if (struct_name.is_marked_for_strip())
+ rust_error_at(struct_name.get_locus(), "cannot strip path in this position");
+
/* struct base presumably can't be stripped, as the '..' is before
* the expression. as such, can only strip sub-expressions. */
rust_assert(!expr.get_struct_base().is_invalid());
@@ -576,6 +801,12 @@ namespace Rust {
return;
}
+ // strip sub-exprs of path
+ auto& struct_name = expr.get_struct_name();
+ visit(struct_name);
+ if (struct_name.is_marked_for_strip())
+ rust_error_at(struct_name.get_locus(), "cannot strip path in this position");
+
/* spec says outer attributes are specifically allowed for elements
* of tuple-style struct expressions, so full stripping possible */
auto& values = expr.get_elems();
@@ -598,6 +829,12 @@ namespace Rust {
expr.mark_for_strip();
return;
}
+
+ // strip sub-exprs of path
+ auto& struct_name = expr.get_struct_name();
+ visit(struct_name);
+ if (struct_name.is_marked_for_strip())
+ rust_error_at(struct_name.get_locus(), "cannot strip path in this position");
}
void visit(AST::EnumExprFieldIdentifier& field) override {
// as no attrs (at moment, at least), no stripping possible
@@ -630,6 +867,12 @@ namespace Rust {
// supposedly spec doesn't allow inner attributes in enum exprs
+ // strip sub-exprs of path
+ auto& enum_path = expr.get_enum_variant_path();
+ visit(enum_path);
+ if (enum_path.is_marked_for_strip())
+ rust_error_at(enum_path.get_locus(), "cannot strip path in this position");
+
/* spec does not specify whether expressions are allowed to be
* stripped at top level of expression fields, but I wouldn't think
* that they would be, so operating under the assumption that only
@@ -649,6 +892,12 @@ namespace Rust {
// supposedly spec doesn't allow inner attributes in enum exprs
+ // strip sub-exprs of path
+ auto& enum_path = expr.get_enum_variant_path();
+ visit(enum_path);
+ if (enum_path.is_marked_for_strip())
+ rust_error_at(enum_path.get_locus(), "cannot strip path in this position");
+
/* spec says outer attributes are specifically allowed for elements
* of tuple-style enum expressions, so full stripping possible */
auto& values = expr.get_elems();
@@ -666,6 +915,12 @@ namespace Rust {
}
void visit(AST::EnumExprFieldless& expr) override {
// can't be stripped as no attrs
+
+ // strip sub-exprs of path
+ auto& enum_path = expr.get_enum_variant_path();
+ visit(enum_path);
+ if (enum_path.is_marked_for_strip())
+ rust_error_at(enum_path.get_locus(), "cannot strip path in this position");
}
void visit(AST::CallExpr& expr) override {
// initial strip test based on outer attrs
@@ -716,7 +971,9 @@ namespace Rust {
rust_error_at(receiver->get_locus_slow(),
"cannot strip expression in this position - outer attributes not allowed");
- // no outer attrs on paths possible
+ auto& method_name = expr.get_method_name();
+ if (method_name.has_generic_args())
+ expand_generic_args(method_name.get_generic_args());
/* spec says outer attributes are specifically allowed for elements
* of method call expressions, so full stripping possible */
@@ -760,15 +1017,7 @@ namespace Rust {
/* strip closure parameters if required - this is specifically
* allowed by spec */
- auto& params = expr.get_params();
- for (int i = 0; i < params.size();) {
- auto& param_attrs = params[i].get_outer_attrs();
- expander.expand_cfg_attrs(param_attrs);
- if (expander.fails_cfg(param_attrs))
- params.erase(params.begin() + i);
- else
- i++;
- }
+ expand_closure_params(expr.get_params());
// can't strip expression itself, but can strip sub-expressions
auto& definition_expr = expr.get_definition_expr();
@@ -827,15 +1076,13 @@ namespace Rust {
/* strip closure parameters if required - this is specifically
* allowed by spec */
- auto& params = expr.get_params();
- for (int i = 0; i < params.size();) {
- auto& param_attrs = params[i].get_outer_attrs();
- expander.expand_cfg_attrs(param_attrs);
- if (expander.fails_cfg(param_attrs))
- params.erase(params.begin() + i);
- else
- i++;
- }
+ expand_closure_params(expr.get_params());
+
+ // can't strip return type, but can strip sub-types
+ auto& type = expr.get_return_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
// can't strip expression itself, but can strip sub-expressions
auto& definition_block = expr.get_definition_block();
@@ -1042,6 +1289,12 @@ namespace Rust {
return;
}
+ for (auto& pattern : expr.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
// can't strip scrutinee expr itself, but can strip sub-expressions
auto& scrutinee_expr = expr.get_scrutinee_expr();
scrutinee_expr->accept_vis(*this);
@@ -1064,6 +1317,12 @@ namespace Rust {
return;
}
+ // TODO: strip sub-patterns of pattern
+ auto& pattern = expr.get_pattern();
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+
// can't strip scrutinee expr itself, but can strip sub-expressions
auto& iterator_expr = expr.get_iterator_expr();
iterator_expr->accept_vis(*this);
@@ -1195,6 +1454,12 @@ namespace Rust {
return;
}
+ for (auto& pattern : expr.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
// can't strip value expr itself, but can strip sub-expressions
auto& value_expr = expr.get_value_expr();
value_expr->accept_vis(*this);
@@ -1217,6 +1482,12 @@ namespace Rust {
return;
}
+ for (auto& pattern : expr.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
// can't strip value expr itself, but can strip sub-expressions
auto& value_expr = expr.get_value_expr();
value_expr->accept_vis(*this);
@@ -1246,6 +1517,12 @@ namespace Rust {
return;
}
+ for (auto& pattern : expr.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
// can't strip value expr itself, but can strip sub-expressions
auto& value_expr = expr.get_value_expr();
value_expr->accept_vis(*this);
@@ -1275,6 +1552,12 @@ namespace Rust {
return;
}
+ for (auto& pattern : expr.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
// can't strip value expr itself, but can strip sub-expressions
auto& value_expr = expr.get_value_expr();
value_expr->accept_vis(*this);
@@ -1332,6 +1615,12 @@ namespace Rust {
continue;
}
+ for (auto& pattern : match_arm.get_patterns()) {
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+
/* assuming that guard expression cannot be stripped as
* strictly speaking you would have to strip the whole guard to
* make syntactical sense, which you can't do. as such, only
@@ -1388,13 +1677,35 @@ namespace Rust {
}
void visit(AST::TypeParam& param) override {
- // shouldn't require?
+ // outer attributes don't actually do anything, so ignore them
+
+ if (param.has_type_param_bounds()) {
+ // don't strip directly, only components of bounds
+ for (auto& bound : param.get_type_param_bounds())
+ bound->accept_vis(*this);
+ }
+
+ 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_slow(), "cannot strip type in this position");
+ }
}
void visit(AST::LifetimeWhereClauseItem& item) override {
- // shouldn't require?
+ // shouldn't require
}
void visit(AST::TypeBoundWhereClauseItem& item) override {
- // shouldn't require?
+ // for lifetimes shouldn't require
+
+ auto& type = item.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ // don't strip directly, only components of bounds
+ for (auto& bound : item.get_type_param_bounds())
+ bound->accept_vis(*this);
}
void visit(AST::Method& method) override {
// initial test based on outer attrs
@@ -1404,14 +1715,29 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : method.get_generic_params())
+ param->accept_vis(*this);
+
/* assuming you can't strip self param - wouldn't be a method
* anymore. spec allows outer attrs on self param, but doesn't
* specify whether cfg is used. */
+ expand_self_param(method.get_self_param());
/* strip method parameters if required - this is specifically
* allowed by spec */
expand_function_params(method.get_function_params());
+ if (method.has_return_type()) {
+ auto& return_type = method.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (method.has_where_clause())
+ expand_where_clause(method.get_where_clause());
+
/* body should always exist - if error state, should have returned
* before now */
// can't strip block itself, but can strip sub-expressions
@@ -1491,10 +1817,24 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : function.get_generic_params())
+ param->accept_vis(*this);
+
/* strip function parameters if required - this is specifically
* allowed by spec */
expand_function_params(function.get_function_params());
+ if (function.has_return_type()) {
+ auto& return_type = function.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (function.has_where_clause())
+ expand_where_clause(function.get_where_clause());
+
/* body should always exist - if error state, should have returned
* before now */
// can't strip block itself, but can strip sub-expressions
@@ -1511,6 +1851,18 @@ namespace Rust {
type_alias.mark_for_strip();
return;
}
+
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : type_alias.get_generic_params())
+ param->accept_vis(*this);
+
+ if (type_alias.has_where_clause())
+ expand_where_clause(type_alias.get_where_clause());
+
+ auto& type = type_alias.get_type_aliased();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
}
void visit(AST::StructStruct& struct_item) override {
// initial test based on outer attrs
@@ -1520,6 +1872,13 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : struct_item.get_generic_params())
+ param->accept_vis(*this);
+
+ if (struct_item.has_where_clause())
+ expand_where_clause(struct_item.get_where_clause());
+
/* strip struct fields if required - this is presumably
* allowed by spec */
expand_struct_fields(struct_item.get_fields());
@@ -1532,9 +1891,16 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : tuple_struct.get_generic_params())
+ param->accept_vis(*this);
+
/* strip struct fields if required - this is presumably
* allowed by spec */
expand_tuple_fields(tuple_struct.get_fields());
+
+ if (tuple_struct.has_where_clause())
+ expand_where_clause(tuple_struct.get_where_clause());
}
void visit(AST::EnumItem& item) override {
// initial test based on outer attrs
@@ -1593,6 +1959,13 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : enum_item.get_generic_params())
+ param->accept_vis(*this);
+
+ if (enum_item.has_where_clause())
+ expand_where_clause(enum_item.get_where_clause());
+
/* strip enum fields if required - this is presumably
* allowed by spec */
auto& variants = enum_item.get_variants();
@@ -1616,6 +1989,13 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : union_item.get_generic_params())
+ param->accept_vis(*this);
+
+ if (union_item.has_where_clause())
+ expand_where_clause(union_item.get_where_clause());
+
/* strip union fields if required - this is presumably
* allowed by spec */
expand_struct_fields(union_item.get_variants());
@@ -1628,6 +2008,12 @@ namespace Rust {
return;
}
+ // strip any sub-types
+ auto& type = const_item.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
/* strip any internal sub-expressions - expression itself isn't
* allowed to have external attributes in this position so can't be
* stripped. */
@@ -1645,6 +2031,12 @@ namespace Rust {
return;
}
+ // strip any sub-types
+ auto& type = static_item.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
/* strip any internal sub-expressions - expression itself isn't
* allowed to have external attributes in this position so can't be
* stripped. */
@@ -1662,9 +2054,7 @@ namespace Rust {
return;
}
- /* strip function parameters if required - this is specifically
- * allowed by spec */
- expand_function_params(item.get_function_params());
+ expand_trait_function_decl(item.get_trait_function_decl());
if (item.has_definition()) {
/* strip any internal sub-expressions - expression itself isn't
@@ -1685,13 +2075,7 @@ namespace Rust {
return;
}
- /* 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. */
-
- /* strip function parameters if required - this is specifically
- * allowed by spec */
- expand_function_params(item.get_function_params());
+ expand_trait_method_decl(item.get_trait_method_decl());
if (item.has_definition()) {
/* strip any internal sub-expressions - expression itself isn't
@@ -1712,6 +2096,12 @@ namespace Rust {
return;
}
+ // strip any sub-types
+ auto& type = item.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
/* strip any internal sub-expressions - expression itself isn't
* allowed to have external attributes in this position so can't be
* stripped */
@@ -1730,6 +2120,12 @@ namespace Rust {
item.mark_for_strip();
return;
}
+
+ if (item.has_type_param_bounds()) {
+ // don't strip directly, only components of bounds
+ for (auto& bound : item.get_type_param_bounds())
+ bound->accept_vis(*this);
+ }
}
void visit(AST::Trait& trait) override {
// initial strip test based on outer attrs
@@ -1746,6 +2142,19 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : trait.get_generic_params())
+ param->accept_vis(*this);
+
+ if (trait.has_type_param_bounds()) {
+ // don't strip directly, only components of bounds
+ for (auto& bound : trait.get_type_param_bounds())
+ bound->accept_vis(*this);
+ }
+
+ if (trait.has_where_clause())
+ expand_where_clause(trait.get_where_clause());
+
// strip trait items if required
auto& trait_items = trait.get_trait_items();
for (int i = 0; i < trait_items.size();) {
@@ -1775,6 +2184,18 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : impl.get_generic_params())
+ param->accept_vis(*this);
+
+ auto& type = impl.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ if (impl.has_where_clause())
+ expand_where_clause(impl.get_where_clause());
+
// strip inherent impl items if required
auto& impl_items = impl.get_impl_items();
for (int i = 0; i < impl_items.size();) {
@@ -1804,6 +2225,23 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : impl.get_generic_params())
+ param->accept_vis(*this);
+
+ auto& type = impl.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ auto& trait_path = impl.get_trait_path();
+ visit(trait_path);
+ if (trait_path.is_marked_for_strip())
+ rust_error_at(trait_path.get_locus(), "cannot strip typepath in this position");
+
+ if (impl.has_where_clause())
+ expand_where_clause(impl.get_where_clause());
+
// strip trait impl items if required
auto& impl_items = impl.get_impl_items();
for (int i = 0; i < impl_items.size();) {
@@ -1825,6 +2263,11 @@ namespace Rust {
item.mark_for_strip();
return;
}
+
+ auto& type = item.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
}
void visit(AST::ExternalFunctionItem& item) override {
// strip test based on outer attrs
@@ -1834,16 +2277,30 @@ namespace Rust {
return;
}
+ // just expand sub-stuff - can't actually strip generic params themselves
+ for (auto& param : item.get_generic_params())
+ param->accept_vis(*this);
+
/* strip function parameters if required - this is specifically
* allowed by spec */
auto& params = item.get_function_params();
for (int i = 0; i < params.size();) {
- auto& param_attrs = params[i].get_outer_attrs();
+ auto& param = params[i];
+
+ auto& param_attrs = param.get_outer_attrs();
expander.expand_cfg_attrs(param_attrs);
- if (expander.fails_cfg(param_attrs))
+ if (expander.fails_cfg(param_attrs)) {
params.erase(params.begin() + i);
- else
- i++;
+ continue;
+ }
+
+ auto& type = param.get_type();
+ type->accept_vis(*this);
+ if (type->is_marked_for_strip())
+ rust_error_at(type->get_locus_slow(), "cannot strip type in this position");
+
+ // increment if nothing else happens
+ i++;
}
/* NOTE: these are extern function params, which may have different
* rules and restrictions to "normal" function params. So expansion
@@ -1851,6 +2308,16 @@ namespace Rust {
/* TODO: assuming that variadic nature cannot be stripped. If this
* is not true, then have code here to do so. */
+
+ if (item.has_return_type()) {
+ auto& return_type = item.get_return_type();
+ return_type->accept_vis(*this);
+ if (return_type->is_marked_for_strip())
+ rust_error_at(return_type->get_locus_slow(), "cannot strip type in this position");
+ }
+
+ if (item.has_where_clause())
+ expand_where_clause(item.get_where_clause());
}
void visit(AST::ExternBlock& block) override {
// initial strip test based on outer attrs
@@ -1904,6 +2371,8 @@ namespace Rust {
}
// I don't think any macro token trees can be stripped in any way
+
+ // TODO: maybe have stripping behaviour for the cfg! macro here?
}
void visit(AST::MetaItemPath& meta_item) override {}
void visit(AST::MetaItemSeq& meta_item) override {}
@@ -1912,29 +2381,186 @@ namespace Rust {
void visit(AST::MetaListPaths& meta_item) override {}
void visit(AST::MetaListNameValueStr& meta_item) override {}
- // stripping shouldn't be required or possible for patterns
- void visit(AST::LiteralPattern& pattern) override {}
- void visit(AST::IdentifierPattern& pattern) override {}
- void visit(AST::WildcardPattern& pattern) override {}
- void visit(AST::RangePatternBoundLiteral& bound) override {}
- void visit(AST::RangePatternBoundPath& bound) override {}
- void visit(AST::RangePatternBoundQualPath& bound) override {}
- void visit(AST::RangePattern& pattern) override {}
- void visit(AST::ReferencePattern& pattern) override {}
- void visit(AST::StructPatternFieldTuplePat& field) override {}
- void visit(AST::StructPatternFieldIdentPat& field) override {}
- void visit(AST::StructPatternFieldIdent& field) override {}
+ void visit(AST::LiteralPattern& pattern) override {
+ // not possible
+ }
+ void visit(AST::IdentifierPattern& pattern) override {
+ // can only strip sub-patterns of the inner pattern to bind
+ if (!pattern.has_pattern_to_bind())
+ return;
+
+ auto& sub_pattern = pattern.get_pattern_to_bind();
+ sub_pattern->accept_vis(*this);
+ if (sub_pattern->is_marked_for_strip())
+ rust_error_at(sub_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+ void visit(AST::WildcardPattern& pattern) override {
+ // not possible
+ }
+ void visit(AST::RangePatternBoundLiteral& bound) override {
+ // not possible
+ }
+ void visit(AST::RangePatternBoundPath& bound) override {
+ // TODO: maybe possible if path is possible
+ }
+ void visit(AST::RangePatternBoundQualPath& bound) override {
+ // TODO: maybe possible if path is possible
+ }
+ void visit(AST::RangePattern& pattern) override {
+ // TODO: possible if any bounds are possible
+ }
+ void visit(AST::ReferencePattern& pattern) override {
+ auto& sub_pattern = pattern.get_referenced_pattern();
+ sub_pattern->accept_vis(*this);
+ if (sub_pattern->is_marked_for_strip())
+ rust_error_at(sub_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+ void visit(AST::StructPatternFieldTuplePat& field) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(field.get_outer_attrs());
+ if (expander.fails_cfg(field.get_outer_attrs())) {
+ field.mark_for_strip();
+ return;
+ }
+
+ // strip sub-patterns (can't strip top-level pattern)
+ auto& sub_pattern = field.get_index_pattern();
+ sub_pattern->accept_vis(*this);
+ if (sub_pattern->is_marked_for_strip())
+ rust_error_at(sub_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+ void visit(AST::StructPatternFieldIdentPat& field) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(field.get_outer_attrs());
+ if (expander.fails_cfg(field.get_outer_attrs())) {
+ field.mark_for_strip();
+ return;
+ }
+
+ // strip sub-patterns (can't strip top-level pattern)
+ auto& sub_pattern = field.get_ident_pattern();
+ sub_pattern->accept_vis(*this);
+ if (sub_pattern->is_marked_for_strip())
+ rust_error_at(sub_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ }
+ void visit(AST::StructPatternFieldIdent& field) override {
+ // initial strip test based on outer attrs
+ expander.expand_cfg_attrs(field.get_outer_attrs());
+ if (expander.fails_cfg(field.get_outer_attrs())) {
+ field.mark_for_strip();
+ return;
+ }
+ }
void visit(AST::StructPattern& pattern) override {
// TODO: apparently struct pattern fields can have outer attrs. so can they be stripped?
+ if (!pattern.has_struct_pattern_elems())
+ return;
+
+ auto& elems = pattern.get_struct_pattern_elems();
+
+ // assuming you can strip struct pattern fields
+ auto& fields = elems.get_struct_pattern_fields();
+ for (int i = 0; i < fields.size();) {
+ auto& field = fields[i];
+
+ field->accept_vis(*this);
+
+ if (field->is_marked_for_strip())
+ fields.erase(fields.begin() + i);
+ else
+ i++;
+ }
+
+ // assuming you can strip the ".." part
+ if (elems.has_etc()) {
+ expander.expand_cfg_attrs(elems.get_etc_outer_attrs());
+ if (expander.fails_cfg(elems.get_etc_outer_attrs()))
+ elems.strip_etc();
+ }
+ }
+ void visit(AST::TupleStructItemsNoRange& tuple_items) override {
+ // can't strip individual patterns, only sub-patterns
+ for (auto& pattern : tuple_items.get_patterns()) {
+ pattern->accept_vis(*this);
+
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ }
+ void visit(AST::TupleStructItemsRange& tuple_items) override {
+ // can't strip individual patterns, only sub-patterns
+ for (auto& lower_pattern : tuple_items.get_lower_patterns()) {
+ lower_pattern->accept_vis(*this);
+
+ if (lower_pattern->is_marked_for_strip())
+ rust_error_at(lower_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ for (auto& upper_pattern : tuple_items.get_upper_patterns()) {
+ upper_pattern->accept_vis(*this);
+
+ if (upper_pattern->is_marked_for_strip())
+ rust_error_at(upper_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ }
+ void visit(AST::TupleStructPattern& pattern) override {
+ // TODO: stripping of path?
+
+ if (pattern.has_items())
+ pattern.get_items()->accept_vis(*this);
+ }
+ void visit(AST::TuplePatternItemsMultiple& tuple_items) override {
+ // can't strip individual patterns, only sub-patterns
+ for (auto& pattern : tuple_items.get_patterns()) {
+ pattern->accept_vis(*this);
+
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ }
+ void visit(AST::TuplePatternItemsRanged& tuple_items) override {
+ // can't strip individual patterns, only sub-patterns
+ for (auto& lower_pattern : tuple_items.get_lower_patterns()) {
+ lower_pattern->accept_vis(*this);
+
+ if (lower_pattern->is_marked_for_strip())
+ rust_error_at(lower_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ for (auto& upper_pattern : tuple_items.get_upper_patterns()) {
+ upper_pattern->accept_vis(*this);
+
+ if (upper_pattern->is_marked_for_strip())
+ rust_error_at(upper_pattern->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
+ }
+ void visit(AST::TuplePattern& pattern) override {
+ if (pattern.has_tuple_pattern_items())
+ pattern.get_items()->accept_vis(*this);
+ }
+ void visit(AST::GroupedPattern& pattern) override {
+ // can't strip inner pattern, only sub-patterns
+ auto& pattern_in_parens = pattern.get_pattern_in_parens();
+
+ pattern_in_parens->accept_vis(*this);
+
+ if (pattern_in_parens->is_marked_for_strip())
+ rust_error_at(pattern_in_parens->get_locus_slow(), "cannot strip pattern in this position");
+ }
+ void visit(AST::SlicePattern& pattern) override {
+ // can't strip individual patterns, only sub-patterns
+ for (auto& item : pattern.get_items()) {
+ item->accept_vis(*this);
+
+ if (item->is_marked_for_strip())
+ rust_error_at(item->get_locus_slow(), "cannot strip pattern in this position");
+ // TODO: quit stripping now? or keep going?
+ }
}
- void visit(AST::TupleStructItemsNoRange& tuple_items) override {}
- void visit(AST::TupleStructItemsRange& tuple_items) override {}
- void visit(AST::TupleStructPattern& pattern) override {}
- void visit(AST::TuplePatternItemsMultiple& tuple_items) override {}
- void visit(AST::TuplePatternItemsRanged& tuple_items) override {}
- void visit(AST::TuplePattern& pattern) override {}
- void visit(AST::GroupedPattern& pattern) override {}
- void visit(AST::SlicePattern& pattern) override {}
void visit(AST::EmptyStmt& stmt) override {
// assuming no outer attributes, so nothing can happen
@@ -1947,6 +2573,12 @@ namespace Rust {
return;
}
+ // can't strip pattern, but call for sub-patterns
+ auto& pattern = stmt.get_pattern();
+ pattern->accept_vis(*this);
+ if (pattern->is_marked_for_strip())
+ rust_error_at(pattern->get_locus_slow(), "cannot strip pattern in this position");
+
/* strip any internal sub-expressions - expression itself isn't
* allowed to have external attributes in this position so can't be
* stripped */