diff options
author | SimplyTheOther <simplytheother@gmail.com> | 2020-12-09 17:42:16 +0800 |
---|---|---|
committer | SimplyTheOther <simplytheother@gmail.com> | 2020-12-09 17:42:16 +0800 |
commit | 53ddea7a266c43f30702b0c24ce05e4d5dad0ecc (patch) | |
tree | df37183b3b068ea00f0e88e80d4bbb8f621fbbf8 /gcc | |
parent | b343d117f5cf7976d3c4c93d9595e2471d780acd (diff) | |
download | gcc-53ddea7a266c43f30702b0c24ce05e4d5dad0ecc.zip gcc-53ddea7a266c43f30702b0c24ce05e4d5dad0ecc.tar.gz gcc-53ddea7a266c43f30702b0c24ce05e4d5dad0ecc.tar.bz2 |
Fixed formatting to fit gcc style
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/ast/rust-ast-full-test.cc | 265 | ||||
-rw-r--r-- | gcc/rust/ast/rust-ast.h | 55 | ||||
-rw-r--r-- | gcc/rust/ast/rust-expr.h | 492 | ||||
-rw-r--r-- | gcc/rust/ast/rust-item.h | 667 | ||||
-rw-r--r-- | gcc/rust/ast/rust-macro.h | 7 | ||||
-rw-r--r-- | gcc/rust/ast/rust-path.h | 101 | ||||
-rw-r--r-- | gcc/rust/ast/rust-pattern.h | 191 | ||||
-rw-r--r-- | gcc/rust/ast/rust-stmt.h | 34 | ||||
-rw-r--r-- | gcc/rust/ast/rust-type.h | 102 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.cc | 6238 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-expand.h | 7 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 3 |
12 files changed, 4622 insertions, 3540 deletions
diff --git a/gcc/rust/ast/rust-ast-full-test.cc b/gcc/rust/ast/rust-ast-full-test.cc index 26a3356..030b0b3 100644 --- a/gcc/rust/ast/rust-ast-full-test.cc +++ b/gcc/rust/ast/rust-ast-full-test.cc @@ -171,13 +171,14 @@ Attribute::as_string () const { std::string path_str = path.as_string (); if (attr_input == nullptr) - return path_str; + return path_str; else - return path_str + attr_input->as_string (); + return path_str + attr_input->as_string (); } // Copy constructor must deep copy attr_input as unique pointer -Attribute::Attribute (Attribute const &other) : path (other.path), locus (other.locus) +Attribute::Attribute (Attribute const &other) + : path (other.path), locus (other.locus) { // guard to protect from null pointer dereference if (other.attr_input != nullptr) @@ -185,7 +186,8 @@ Attribute::Attribute (Attribute const &other) : path (other.path), locus (other. } // overload assignment operator to use custom clone method -Attribute &Attribute::operator= (Attribute const &other) +Attribute & +Attribute::operator= (Attribute const &other) { path = other.path; locus = other.locus; @@ -330,7 +332,7 @@ VisItem::as_string () const if (!outer_attrs.empty ()) { for (const auto &attr : outer_attrs) - str += attr.as_string () + "\n"; + str += attr.as_string () + "\n"; } if (has_visibility ()) @@ -678,20 +680,20 @@ Method::as_string () const else { for (const auto ¶m : function_params) - str += "\n " + param.as_string (); + str += "\n " + param.as_string (); } str += "\n Return type: "; if (has_return_type ()) - str += return_type->as_string (); + str += return_type->as_string (); else - str += "none (void)"; + str += "none (void)"; str += "\n Where clause: "; if (has_where_clause ()) - str += where_clause.as_string (); + str += where_clause.as_string (); else - str += "none"; + str += "none"; str += "\n Block expr (body): \n "; str += function_body->as_string (); @@ -1168,7 +1170,7 @@ Function::as_string () const } if (has_where_clause ()) - str += " where " + where_clause.as_string (); + str += " where " + where_clause.as_string (); str += "\n"; @@ -1199,7 +1201,7 @@ WhereClause::as_string () const else { for (const auto &item : where_clause_items) - str += "\n " + item->as_string (); + str += "\n " + item->as_string (); } return str; @@ -1224,7 +1226,7 @@ BlockExpr::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n" + indent_spaces (stay) + attr.as_string (); + str += "\n" + indent_spaces (stay) + attr.as_string (); } // statements @@ -1254,9 +1256,9 @@ BlockExpr::as_string () const // final expression str += "\n" + indent_spaces (stay) + "final expression: "; if (expr == nullptr) - str += "none"; + str += "none"; else - str += "\n" + expr->as_string (); + str += "\n" + expr->as_string (); str += "\n" + indent_spaces (out) + "}"; return str; @@ -1268,7 +1270,7 @@ TraitImpl::as_string () const std::string str = VisItem::as_string (); if (has_unsafe) - str += "unsafe "; + str += "unsafe "; str += "impl "; @@ -1281,14 +1283,14 @@ TraitImpl::as_string () const else { for (const auto ¶m : generic_params) - str += "\n " + param->as_string (); + str += "\n " + param->as_string (); } str += "\n Has exclam: "; if (has_exclam) - str += "true"; + str += "true"; else - str += "false"; + str += "false"; str += "\n TypePath (to trait): " + trait_path.as_string (); @@ -1296,9 +1298,9 @@ TraitImpl::as_string () const str += "\n Where clause: "; if (!has_where_clause ()) - str += "none"; + str += "none"; else - str += where_clause.as_string (); + str += where_clause.as_string (); // inner attributes str += "\n inner attributes: "; @@ -1311,7 +1313,7 @@ TraitImpl::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\n trait impl items: "; @@ -1322,7 +1324,7 @@ TraitImpl::as_string () const else { for (const auto &item : impl_items) - str += "\n " + item->as_string (); + str += "\n " + item->as_string (); } return str; @@ -1378,7 +1380,7 @@ MacroInvocationSemi::as_string () const if (!outer_attrs.empty ()) { for (const auto &attr : outer_attrs) - str += attr.as_string () + "\n"; + str += attr.as_string () + "\n"; } str += "\n" + path.as_string () + "!"; @@ -1438,7 +1440,7 @@ ExternBlock::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\n external items: "; @@ -1449,7 +1451,7 @@ ExternBlock::as_string () const else { for (const auto &item : extern_items) - str += "\n " + item->as_string (); + str += "\n " + item->as_string (); } return str; @@ -1478,7 +1480,7 @@ MacroRulesDefinition::as_string () const if (!outer_attrs.empty ()) { for (const auto &attr : outer_attrs) - str += attr.as_string () + "\n"; + str += attr.as_string () + "\n"; } str += "macro_rules!"; @@ -1493,7 +1495,7 @@ MacroRulesDefinition::as_string () const else { for (const auto &rule : rules) - str += "\n " + rule.as_string (); + str += "\n " + rule.as_string (); } str += "\n Delim type: "; @@ -1528,7 +1530,7 @@ PathInExpression::as_string () const std::string str; if (has_opening_scope_resolution) - str = "::"; + str = "::"; return str + PathPattern::as_string (); } @@ -1559,7 +1561,7 @@ ClosureParam::as_string () const std::string str (pattern->as_string ()); if (has_type_given ()) - str += " : " + type->as_string (); + str += " : " + type->as_string (); return str; } @@ -1569,9 +1571,9 @@ ClosureExpr::as_string () const { std::string str ("ClosureExpr:\n Has move: "); if (has_move) - str += "true"; + str += "true"; else - str += "false"; + str += "false"; str += "\n Params: "; if (params.empty ()) @@ -1581,7 +1583,7 @@ ClosureExpr::as_string () const else { for (const auto ¶m : params) - str += "\n " + param.as_string (); + str += "\n " + param.as_string (); } return str; @@ -1605,7 +1607,7 @@ PathPattern::as_string () const std::string str; for (const auto &segment : segments) - str += segment.as_string () + "::"; + str += segment.as_string () + "::"; // basically a hack - remove last two characters of string (remove final ::) str.erase (str.length () - 2); @@ -1620,7 +1622,7 @@ QualifiedPathType::as_string () const str += type_to_invoke_on->as_string (); if (has_as_clause ()) - str += " as " + trait_path.as_string (); + str += " as " + trait_path.as_string (); return str + ">"; } @@ -1637,10 +1639,10 @@ BorrowExpr::as_string () const std::string str ("&"); if (double_borrow) - str += "&"; + str += "&"; if (is_mut) - str += "mut "; + str += "mut "; str += main_or_left_expr->as_string (); @@ -1653,7 +1655,7 @@ ReturnExpr::as_string () const std::string str ("return "); if (has_returned_expr ()) - str += return_expr->as_string (); + str += return_expr->as_string (); return str; } @@ -1674,7 +1676,7 @@ GroupedExpr::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\n Expr in parens: " + expr_in_parens->as_string (); @@ -1694,7 +1696,7 @@ ContinueExpr::as_string () const std::string str ("continue "); if (has_label ()) - str += label.as_string (); + str += label.as_string (); return str; } @@ -1829,7 +1831,7 @@ MethodCallExpr::as_string () const for (const auto ¶m : params) { if (param == nullptr) - return "ERROR_MARK_STRING - method call expr param is null"; + return "ERROR_MARK_STRING - method call expr param is null"; str += "\n " + param->as_string (); } @@ -1968,7 +1970,7 @@ IfLetExpr::as_string () const else { for (const auto &pattern : match_arm_patterns) - str += "\n " + pattern->as_string (); + str += "\n " + pattern->as_string (); } str += "\n Scrutinee expr: " + value->as_string (); @@ -2157,7 +2159,7 @@ CallExpr::as_string () const for (const auto ¶m : params) { if (param == nullptr) - return "ERROR_MARK_STRING - call expr param is null"; + return "ERROR_MARK_STRING - call expr param is null"; str += "\n " + param->as_string (); } @@ -2173,9 +2175,9 @@ WhileLoopExpr::as_string () const str += "\n Label: "; if (!has_loop_label ()) - str += "none"; + str += "none"; else - str += loop_label.as_string (); + str += loop_label.as_string (); str += "\n Conditional expr: " + condition->as_string (); @@ -2191,9 +2193,9 @@ WhileLetLoopExpr::as_string () const str += "\n Label: "; if (!has_loop_label ()) - str += "none"; + str += "none"; else - str += loop_label.as_string (); + str += loop_label.as_string (); str += "\n Match arm patterns: "; if (match_arm_patterns.empty ()) @@ -2203,7 +2205,7 @@ WhileLetLoopExpr::as_string () const else { for (const auto &pattern : match_arm_patterns) - str += "\n " + pattern->as_string (); + str += "\n " + pattern->as_string (); } str += "\n Scrutinee expr: " + scrutinee->as_string (); @@ -2220,9 +2222,9 @@ LoopExpr::as_string () const str += "\n Label: "; if (!has_loop_label ()) - str += "none"; + str += "none"; else - str += loop_label.as_string (); + str += loop_label.as_string (); str += "\n Loop block: " + loop_block->as_string (); @@ -2245,14 +2247,14 @@ ArrayExpr::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\n Array elems: "; if (!has_array_elems ()) - str += "none"; + str += "none"; else - str += internal_elements->as_string (); + str += internal_elements->as_string (); return str; } @@ -2269,10 +2271,10 @@ BreakExpr::as_string () const std::string str ("break "); if (has_label ()) - str += label.as_string () + " "; + str += label.as_string () + " "; if (has_break_expr ()) - str += break_expr->as_string (); + str += break_expr->as_string (); return str; } @@ -2297,7 +2299,7 @@ MatchArm::as_string () const /* note that this does not print them with "outer attribute" syntax - * just the body */ for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\nPatterns: "; @@ -2308,14 +2310,14 @@ MatchArm::as_string () const else { for (const auto &pattern : match_arm_patterns) - str += "\n " + pattern->as_string (); + str += "\n " + pattern->as_string (); } str += "\nGuard expr: "; if (!has_match_arm_guard ()) - str += "none"; + str += "none"; else - str += guard_expr->as_string (); + str += guard_expr->as_string (); return str; } @@ -3629,7 +3631,7 @@ StructExprTuple::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n" + indent_spaces (stay) + attr.as_string (); + str += "\n" + indent_spaces (stay) + attr.as_string (); } indent_spaces (out); indent_spaces (out); @@ -3655,7 +3657,7 @@ StructExprStruct::as_string () const /* note that this does not print them with "inner attribute" syntax - * just the body */ for (const auto &attr : inner_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } return str; @@ -3665,9 +3667,9 @@ std::string StructBase::as_string () const { if (base_struct != nullptr) - return base_struct->as_string (); + return base_struct->as_string (); else - return "ERROR_MARK_STRING - invalid struct base had as string applied"; + return "ERROR_MARK_STRING - invalid struct base had as string applied"; } std::string @@ -3702,14 +3704,14 @@ StructExprStructFields::as_string () const else { for (const auto &field : fields) - str += "\n " + field->as_string (); + str += "\n " + field->as_string (); } str += "\n Struct base: "; if (!has_struct_base ()) - str += "none"; + str += "none"; else - str += struct_base.as_string (); + str += struct_base.as_string (); return str; } @@ -3729,7 +3731,7 @@ EnumExprStruct::as_string () const else { for (const auto &field : fields) - str += "\n " + field->as_string (); + str += "\n " + field->as_string (); } return str; @@ -3768,7 +3770,7 @@ EnumItem::as_string () const /* note that this does not print them with "outer attribute" syntax - * just the body */ for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } str += "\n" + variant_name; @@ -3940,7 +3942,7 @@ ExternalStaticItem::as_string () const /* note that this does not print them with "outer attribute" syntax - * just the body */ for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } // start visibility on new line and with a space @@ -3949,7 +3951,7 @@ ExternalStaticItem::as_string () const str += "static "; if (has_mut) - str += "mut "; + str += "mut "; // add name str += item_name; @@ -3974,7 +3976,7 @@ ExternalFunctionItem::as_string () const /* note that this does not print them with "outer attribute" syntax - * just the body */ for (const auto &attr : outer_attrs) - str += "\n " + attr.as_string (); + str += "\n " + attr.as_string (); } // start visibility on new line and with a space @@ -4018,21 +4020,20 @@ ExternalFunctionItem::as_string () const else { for (const auto ¶m : function_params) - str += "\n " + param.as_string (); - + str += "\n " + param.as_string (); + if (has_variadics) { - str += "\n variadic outer attrs: "; - if (has_variadic_outer_attrs ()) - { - - for (const auto &attr : variadic_outer_attrs) - str += "\n " + attr.as_string (); - } - else - { - str += "none"; - } + str += "\n variadic outer attrs: "; + if (has_variadic_outer_attrs ()) + { + for (const auto &attr : variadic_outer_attrs) + str += "\n " + attr.as_string (); + } + else + { + str += "none"; + } str += "\n ... (variadic)"; } } @@ -4043,9 +4044,9 @@ ExternalFunctionItem::as_string () const // where clause str += "\n Where clause: "; if (has_where_clause ()) - str += where_clause.as_string (); + str += where_clause.as_string (); else - str += "none"; + str += "none"; return str; } @@ -4055,14 +4056,14 @@ NamedFunctionParam::as_string () const { std::string str = "outer attributes: "; - if (!has_outer_attrs ()) + if (!has_outer_attrs ()) { str += "none"; - } - else + } + else { - for (const auto& attr : outer_attrs) - str += "\n " + attr.as_string (); + for (const auto &attr : outer_attrs) + str += "\n " + attr.as_string (); } str += "\n" + name; @@ -4735,7 +4736,8 @@ MacroParser::parse_meta_item_inner () std::vector<MetaNameValueStr> meta_name_value_str_items; for (const auto &item : meta_items) { - std::unique_ptr<MetaNameValueStr> converted_item = item->to_meta_name_value_str (); + std::unique_ptr<MetaNameValueStr> converted_item + = item->to_meta_name_value_str (); if (converted_item == nullptr) { meta_name_value_str_items.clear (); @@ -5053,7 +5055,9 @@ MacroParser::parse_meta_item_lit () bool AttrInputMetaItemContainer::check_cfg_predicate (const Session &session) const { - /* NOTE: assuming that only first item must be true - cfg should only have one item, and cfg_attr only has first item as predicate. TODO ensure that this is correct. */ + /* NOTE: assuming that only first item must be true - cfg should only have one + * item, and cfg_attr only has first item as predicate. TODO ensure that this + * is correct. */ if (items.empty ()) return false; @@ -5352,52 +5356,61 @@ MetaItemPathLit::to_attribute () const new AttrInputLiteral (lit))); } -std::vector<Attribute> AttrInputMetaItemContainer::separate_cfg_attrs () const { - rust_assert (!items.empty ()); +std::vector<Attribute> +AttrInputMetaItemContainer::separate_cfg_attrs () const +{ + rust_assert (!items.empty ()); - if (items.size () == 1) - return {}; + if (items.size () == 1) + return {}; - std::vector<Attribute> attrs; - attrs.reserve (items.size () - 1); + std::vector<Attribute> attrs; + attrs.reserve (items.size () - 1); - for (auto it = items.begin () + 1; it != items.end (); ++it) { + for (auto it = items.begin () + 1; it != items.end (); ++it) + { Attribute attr = (*it)->to_attribute (); - if (attr.is_empty ()) { - // TODO should this be an error that causes us to chuck out everything? - continue; - } + if (attr.is_empty ()) + { + // TODO should this be an error that causes us to chuck out + // everything? + continue; + } attrs.push_back (std::move (attr)); } - attrs.shrink_to_fit (); - return attrs; - } + attrs.shrink_to_fit (); + return attrs; +} -bool Attribute::check_cfg_predicate (const Session &session) - { - /* assume that cfg predicate actually can exist, i.e. attribute has cfg or - * cfg_attr path */ - if (!has_attr_input () || (path.as_string () != "cfg" && path.as_string () != "cfg_attr")) - return false; +bool +Attribute::check_cfg_predicate (const Session &session) +{ + /* assume that cfg predicate actually can exist, i.e. attribute has cfg or + * cfg_attr path */ + if (!has_attr_input () + || (path.as_string () != "cfg" && path.as_string () != "cfg_attr")) + return false; - // TODO: maybe replace with storing a "has been parsed" variable? - parse_attr_to_meta_item (); - // can't be const because of this anyway + // TODO: maybe replace with storing a "has been parsed" variable? + parse_attr_to_meta_item (); + // can't be const because of this anyway - return attr_input->check_cfg_predicate (session); - } + return attr_input->check_cfg_predicate (session); +} -std::vector<Attribute> Attribute::separate_cfg_attrs () { - if (!has_attr_input () || path.as_string () != "cfg_attr") - return {}; +std::vector<Attribute> +Attribute::separate_cfg_attrs () +{ + if (!has_attr_input () || path.as_string () != "cfg_attr") + return {}; - // TODO: maybe replace with storing a "has been parsed" variable? - parse_attr_to_meta_item (); - // can't be const because of this anyway + // TODO: maybe replace with storing a "has been parsed" variable? + parse_attr_to_meta_item (); + // can't be const because of this anyway - return attr_input->separate_cfg_attrs (); - } + return attr_input->separate_cfg_attrs (); +} /* Visitor implementations - these are short but inlining can't happen anyway * due to virtual functions and I didn't want to make the ast header includes diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index b5e56ba..d23cb81 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -83,7 +83,7 @@ public: /* Converts token tree to a flat token stream. Tokens must be pointer to avoid * mutual dependency with Token. */ - virtual std::vector<std::unique_ptr<Token>> to_token_stream () const = 0; + virtual std::vector<std::unique_ptr<Token> > to_token_stream () const = 0; protected: // pure virtual clone implementation @@ -193,7 +193,7 @@ public: void accept_vis (ASTVisitor &vis) override; // Return copy of itself but in token stream form. - std::vector<std::unique_ptr<Token>> to_token_stream () const override; + std::vector<std::unique_ptr<Token> > to_token_stream () const override; TokenId get_id () const { return token_id; } @@ -526,7 +526,7 @@ protected: class DelimTokenTree : public TokenTree, public AttrInput { DelimType delim_type; - std::vector<std::unique_ptr<TokenTree>> token_trees; + std::vector<std::unique_ptr<TokenTree> > token_trees; Location locus; protected: @@ -551,8 +551,8 @@ protected: public: DelimTokenTree (DelimType delim_type, - std::vector<std::unique_ptr<TokenTree>> token_trees - = std::vector<std::unique_ptr<TokenTree>> (), + std::vector<std::unique_ptr<TokenTree> > token_trees + = std::vector<std::unique_ptr<TokenTree> > (), Location locus = Location ()) : delim_type (delim_type), token_trees (std::move (token_trees)), locus (locus) @@ -590,8 +590,7 @@ public: void accept_vis (ASTVisitor &vis) override; - bool - check_cfg_predicate (const Session&) const override + bool check_cfg_predicate (const Session &) const override { // this should never be called - should be converted first return false; @@ -599,7 +598,7 @@ public: AttrInput *parse_to_meta_item () const override; - std::vector<std::unique_ptr<Token>> to_token_stream () const override; + std::vector<std::unique_ptr<Token> > to_token_stream () const override; std::unique_ptr<DelimTokenTree> clone_delim_token_tree () const { @@ -636,7 +635,10 @@ public: /* HACK: used to simplify parsing - creates a copy of that type, or returns * null */ - virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const { return nullptr; } + virtual std::unique_ptr<MetaNameValueStr> to_meta_name_value_str () const + { + return nullptr; + } // HACK: used to simplify parsing - same thing virtual SimplePath to_path_item () const @@ -644,7 +646,7 @@ public: return SimplePath::create_empty (); } - virtual Attribute to_attribute() const { return Attribute::create_empty (); } + virtual Attribute to_attribute () const { return Attribute::create_empty (); } virtual bool check_cfg_predicate (const Session &session) const = 0; }; @@ -652,11 +654,11 @@ public: // Container used to store MetaItems as AttrInput (bridge-ish kinda thing) class AttrInputMetaItemContainer : public AttrInput { - std::vector<std::unique_ptr<MetaItemInner>> items; + std::vector<std::unique_ptr<MetaItemInner> > items; public: AttrInputMetaItemContainer ( - std::vector<std::unique_ptr<MetaItemInner>> items) + std::vector<std::unique_ptr<MetaItemInner> > items) : items (std::move (items)) {} @@ -1001,10 +1003,7 @@ public: /* HACK: convert to trait bound. Virtual method overriden by classes that * enable this. */ - virtual TraitBound *to_trait_bound (bool) const - { - return nullptr; - } + virtual TraitBound *to_trait_bound (bool) const { return nullptr; } /* as pointer, shouldn't require definition beforehand, only forward * declaration. */ @@ -1220,7 +1219,7 @@ class MacroItem : public Item { /*public: std::string as_string() const;*/ - //std::vector<Attribute> outer_attrs; + // std::vector<Attribute> outer_attrs; protected: /*MacroItem (std::vector<Attribute> outer_attribs) @@ -1290,7 +1289,7 @@ protected: virtual TraitImplItem *clone_trait_impl_item_impl () const = 0; public: - virtual ~TraitImplItem () {}; + virtual ~TraitImplItem (){}; // Unique pointer custom clone function std::unique_ptr<TraitImplItem> clone_trait_impl_item () const @@ -1335,20 +1334,21 @@ protected: class MacroInvocationSemi : public MacroItem, public TraitItem, public InherentImplItem, - public TraitImplItem, public ExternalItem + public TraitImplItem, + public ExternalItem { std::vector<Attribute> outer_attrs; SimplePath path; // all delim types except curly must have invocation end with a semicolon DelimType delim_type; - std::vector<std::unique_ptr<TokenTree>> token_trees; + std::vector<std::unique_ptr<TokenTree> > token_trees; Location locus; public: std::string as_string () const override; MacroInvocationSemi (SimplePath macro_path, DelimType delim_type, - std::vector<std::unique_ptr<TokenTree>> token_trees, + std::vector<std::unique_ptr<TokenTree> > token_trees, std::vector<Attribute> outer_attribs, Location locus) : outer_attrs (std::move (outer_attribs)), path (std::move (macro_path)), delim_type (delim_type), token_trees (std::move (token_trees)), @@ -1358,8 +1358,8 @@ public: // Copy constructor with vector clone MacroInvocationSemi (MacroInvocationSemi const &other) : MacroItem (other), TraitItem (other), InherentImplItem (other), - TraitImplItem (other), outer_attrs(other.outer_attrs), path (other.path), delim_type (other.delim_type), - locus (other.locus) + TraitImplItem (other), outer_attrs (other.outer_attrs), path (other.path), + delim_type (other.delim_type), locus (other.locus) { token_trees.reserve (other.token_trees.size ()); for (const auto &e : other.token_trees) @@ -1458,11 +1458,11 @@ struct Crate // dodgy spacing required here /* TODO: is it better to have a vector of items here or a module (implicit * top-level one)? */ - std::vector<std::unique_ptr<Item>> items; + std::vector<std::unique_ptr<Item> > items; public: // Constructor - Crate (std::vector<std::unique_ptr<Item>> items, + Crate (std::vector<std::unique_ptr<Item> > items, std::vector<Attribute> inner_attrs, bool has_utf8bom = false, bool has_shebang = false) : has_utf8bom (has_utf8bom), has_shebang (has_shebang), @@ -1503,13 +1503,14 @@ public: std::string as_string () const; // Delete all crate information, e.g. if fails cfg. - void strip_crate () { + void strip_crate () + { inner_attrs.clear (); inner_attrs.shrink_to_fit (); items.clear (); items.shrink_to_fit (); - // TODO: is this the best way to do this? + // TODO: is this the best way to do this? } }; diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index c7302fe..f129e8c 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -119,8 +119,7 @@ public: /* this can never be a cfg predicate - cfg and cfg_attr require a token-tree * cfg */ - bool - check_cfg_predicate (const Session&) const override { return false; } + bool check_cfg_predicate (const Session &) const override { return false; } protected: /* Use covariance to implement clone function as returning this object rather @@ -241,7 +240,10 @@ public: // Invalid if expr is null, so base stripping on that. void mark_for_strip () override { main_or_left_expr = nullptr; } - bool is_marked_for_strip () const override { return main_or_left_expr == nullptr; } + bool is_marked_for_strip () const override + { + return main_or_left_expr == nullptr; + } }; /* Unary prefix & or &mut (or && and &&mut) borrow operator. Cannot be @@ -257,14 +259,16 @@ public: BorrowExpr (std::unique_ptr<Expr> borrow_lvalue, bool is_mut_borrow, bool is_double_borrow, std::vector<Attribute> outer_attribs, Location locus) - : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs), - locus), is_mut (is_mut_borrow), double_borrow (is_double_borrow) + : OperatorExpr (std::move (borrow_lvalue), std::move (outer_attribs), + locus), + is_mut (is_mut_borrow), double_borrow (is_double_borrow) {} void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_borrowed_expr () { + std::unique_ptr<Expr> &get_borrowed_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } @@ -293,7 +297,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_dereferenced_expr () { + std::unique_ptr<Expr> &get_dereferenced_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } @@ -323,7 +328,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_propagating_expr () { + std::unique_ptr<Expr> &get_propagating_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } @@ -369,7 +375,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_negated_expr () { + std::unique_ptr<Expr> &get_negated_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } @@ -446,13 +453,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_left_expr () { + std::unique_ptr<Expr> &get_left_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_right_expr () { + std::unique_ptr<Expr> &get_right_expr () + { rust_assert (right_expr != nullptr); return right_expr; } @@ -528,13 +537,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_left_expr () { + std::unique_ptr<Expr> &get_left_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_right_expr () { + std::unique_ptr<Expr> &get_right_expr () + { rust_assert (right_expr != nullptr); return right_expr; } @@ -604,13 +615,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_left_expr () { + std::unique_ptr<Expr> &get_left_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_right_expr () { + std::unique_ptr<Expr> &get_right_expr () + { rust_assert (right_expr != nullptr); return right_expr; } @@ -657,20 +670,22 @@ public: return *this; } - // move constructors + // move constructors TypeCastExpr (TypeCastExpr &&other) = default; TypeCastExpr &operator= (TypeCastExpr &&other) = default; void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_casted_expr () { + std::unique_ptr<Expr> &get_casted_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<TypeNoBounds> &get_type_to_cast_to () { + std::unique_ptr<TypeNoBounds> &get_type_to_cast_to () + { rust_assert (type_to_convert_to != nullptr); return type_to_convert_to; } @@ -727,13 +742,15 @@ public: void visit_rhs (ASTVisitor &vis) { right_expr->accept_vis (vis); } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_left_expr () { + std::unique_ptr<Expr> &get_left_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_right_expr () { + std::unique_ptr<Expr> &get_right_expr () + { rust_assert (right_expr != nullptr); return right_expr; } @@ -811,13 +828,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_left_expr () { + std::unique_ptr<Expr> &get_left_expr () + { rust_assert (main_or_left_expr != nullptr); return main_or_left_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_right_expr () { + std::unique_ptr<Expr> &get_right_expr () + { rust_assert (right_expr != nullptr); return right_expr; } @@ -891,10 +910,14 @@ public: // Invalid if inner expr is null, so base stripping on that. void mark_for_strip () override { expr_in_parens = nullptr; } - bool is_marked_for_strip () const override { return expr_in_parens == nullptr; } + bool is_marked_for_strip () const override + { + return expr_in_parens == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr_in_parens () { + std::unique_ptr<Expr> &get_expr_in_parens () + { rust_assert (expr_in_parens != nullptr); return expr_in_parens; } @@ -969,7 +992,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_values () const { return values; } + const std::vector<std::unique_ptr<Expr> > &get_values () const + { + return values; + } std::vector<std::unique_ptr<Expr> > &get_values () { return values; } size_t get_num_values () const { return values.size (); } @@ -1030,13 +1056,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_elem_to_copy () { + std::unique_ptr<Expr> &get_elem_to_copy () + { rust_assert (elem_to_copy != nullptr); return elem_to_copy; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_num_copies () { + std::unique_ptr<Expr> &get_num_copies () + { rust_assert (num_copies != nullptr); return num_copies; } @@ -1055,7 +1083,7 @@ class ArrayExpr : public ExprWithoutBlock std::unique_ptr<ArrayElems> internal_elements; Location locus; - + // TODO: find another way to store this to save memory? bool marked_for_strip = false; @@ -1121,7 +1149,8 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<ArrayElems> &get_array_elems () { + std::unique_ptr<ArrayElems> &get_array_elems () + { rust_assert (internal_elements != nullptr); return internal_elements; } @@ -1182,7 +1211,7 @@ public: // guard to prevent null dereference (only required if error state) if (other.array_expr != nullptr) array_expr = other.array_expr->clone_expr (); - else + else array_expr = nullptr; if (other.index_expr != nullptr) index_expr = other.index_expr->clone_expr (); @@ -1202,17 +1231,26 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if either expr is null, so base stripping on that. - void mark_for_strip () override { array_expr = nullptr; index_expr = nullptr; } - bool is_marked_for_strip () const override { return array_expr == nullptr && index_expr == nullptr; } + void mark_for_strip () override + { + array_expr = nullptr; + index_expr = nullptr; + } + bool is_marked_for_strip () const override + { + return array_expr == nullptr && index_expr == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_array_expr () { + std::unique_ptr<Expr> &get_array_expr () + { rust_assert (array_expr != nullptr); return array_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_index_expr () { + std::unique_ptr<Expr> &get_index_expr () + { rust_assert (index_expr != nullptr); return index_expr; } @@ -1295,8 +1333,14 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const { return tuple_elems; } - std::vector<std::unique_ptr<Expr> > &get_tuple_elems () { return tuple_elems; } + const std::vector<std::unique_ptr<Expr> > &get_tuple_elems () const + { + return tuple_elems; + } + std::vector<std::unique_ptr<Expr> > &get_tuple_elems () + { + return tuple_elems; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -1332,7 +1376,8 @@ public: // Copy constructor requires a clone for tuple_expr TupleIndexExpr (TupleIndexExpr const &other) - : ExprWithoutBlock (other), tuple_index (other.tuple_index), locus (other.locus) + : ExprWithoutBlock (other), tuple_index (other.tuple_index), + locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.tuple_expr != nullptr) @@ -1370,7 +1415,8 @@ public: bool is_marked_for_strip () const override { return tuple_expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_tuple_expr () { + std::unique_ptr<Expr> &get_tuple_expr () + { rust_assert (tuple_expr != nullptr); return tuple_expr; } @@ -1404,7 +1450,10 @@ public: std::string as_string () const override; // Invalid if path is empty, so base stripping on that. - void mark_for_strip () override { struct_name = PathInExpression::create_error (); } + void mark_for_strip () override + { + struct_name = PathInExpression::create_error (); + } bool is_marked_for_strip () const override { return struct_name.is_error (); } }; @@ -1493,7 +1542,8 @@ public: std::string as_string () const; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_base_struct () { + std::unique_ptr<Expr> &get_base_struct () + { rust_assert (base_struct != nullptr); return base_struct; } @@ -1577,7 +1627,8 @@ public: std::string as_string () const override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_value () { + std::unique_ptr<Expr> &get_value () + { rust_assert (value != nullptr); return value; } @@ -1693,8 +1744,14 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<std::unique_ptr<StructExprField> > &get_fields () { return fields; } - const std::vector<std::unique_ptr<StructExprField> > &get_fields () const { return fields; } + std::vector<std::unique_ptr<StructExprField> > &get_fields () + { + return fields; + } + const std::vector<std::unique_ptr<StructExprField> > &get_fields () const + { + return fields; + } StructBase &get_struct_base () { return struct_base; } const StructBase &get_struct_base () const { return struct_base; } @@ -1709,7 +1766,7 @@ protected: }; // AST node of the functional update struct creator -/* TODO: remove and replace with StructExprStructFields, except with empty +/* TODO: remove and replace with StructExprStructFields, except with empty * vector of fields? */ class StructExprStructBase : public StructExprStruct { @@ -1795,7 +1852,10 @@ public: void accept_vis (ASTVisitor &vis) override; - const std::vector<std::unique_ptr<Expr> > &get_elems () const { return exprs; } + const std::vector<std::unique_ptr<Expr> > &get_elems () const + { + return exprs; + } std::vector<std::unique_ptr<Expr> > &get_elems () { return exprs; } protected: @@ -1853,12 +1913,21 @@ protected: {} public: - const PathInExpression& get_enum_variant_path () const { return enum_variant_path; } - PathInExpression& get_enum_variant_path () { return enum_variant_path; } + const PathInExpression &get_enum_variant_path () const + { + return enum_variant_path; + } + PathInExpression &get_enum_variant_path () { return enum_variant_path; } // Invalid if path is in error state, so base stripping on that. - void mark_for_strip () override { enum_variant_path = PathInExpression::create_error (); } - bool is_marked_for_strip () const override { return enum_variant_path.is_error (); } + void mark_for_strip () override + { + enum_variant_path = PathInExpression::create_error (); + } + bool is_marked_for_strip () const override + { + return enum_variant_path.is_error (); + } }; /* Base AST node for a single enum expression field (in enum instance creation) @@ -1942,7 +2011,8 @@ public: std::string as_string () const override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_value () { + std::unique_ptr<Expr> &get_value () + { rust_assert (value != nullptr); return value; } @@ -2054,7 +2124,10 @@ public: // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<std::unique_ptr<EnumExprField> > &get_fields () { return fields; } - const std::vector<std::unique_ptr<EnumExprField> > &get_fields () const { return fields; } + const std::vector<std::unique_ptr<EnumExprField> > &get_fields () const + { + return fields; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -2114,7 +2187,10 @@ public: void accept_vis (ASTVisitor &vis) override; - const std::vector<std::unique_ptr<Expr> > &get_elems () const { return values; } + const std::vector<std::unique_ptr<Expr> > &get_elems () const + { + return values; + } std::vector<std::unique_ptr<Expr> > &get_elems () { return values; } protected: @@ -2186,7 +2262,8 @@ public: // copy constructor requires clone CallExpr (CallExpr const &other) - : ExprWithoutBlock (other), locus (other.locus) { + : ExprWithoutBlock (other), locus (other.locus) + { // guard to prevent null dereference (only required if error state) if (other.function != nullptr) function = other.function->clone_expr (); @@ -2233,11 +2310,15 @@ public: bool is_marked_for_strip () const override { return function == nullptr; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_params () const { return params; } + const std::vector<std::unique_ptr<Expr> > &get_params () const + { + return params; + } std::vector<std::unique_ptr<Expr> > &get_params () { return params; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_function_expr () { + std::unique_ptr<Expr> &get_function_expr () + { rust_assert (function != nullptr); return function; } @@ -2276,7 +2357,9 @@ public: // copy constructor required due to cloning MethodCallExpr (MethodCallExpr const &other) - : ExprWithoutBlock (other), method_name (other.method_name), locus (other.locus) { + : ExprWithoutBlock (other), method_name (other.method_name), + locus (other.locus) + { // guard to prevent null dereference (only required if error state) if (other.receiver != nullptr) receiver = other.receiver->clone_expr (); @@ -2321,11 +2404,15 @@ public: bool is_marked_for_strip () const override { return receiver == nullptr; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Expr> > &get_params () const { return params; } + const std::vector<std::unique_ptr<Expr> > &get_params () const + { + return params; + } std::vector<std::unique_ptr<Expr> > &get_params () { return params; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_receiver_expr () { + std::unique_ptr<Expr> &get_receiver_expr () + { rust_assert (receiver != nullptr); return receiver; } @@ -2402,7 +2489,8 @@ public: bool is_marked_for_strip () const override { return receiver == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_receiver_expr () { + std::unique_ptr<Expr> &get_receiver_expr () + { rust_assert (receiver != nullptr); return receiver; } @@ -2438,14 +2526,14 @@ public: // Constructor for closure parameter ClosureParam (std::unique_ptr<Pattern> param_pattern, - std::unique_ptr<Type> param_type = nullptr, std::vector<Attribute> outer_attrs = {}) - : outer_attrs (std::move(outer_attrs)), pattern (std::move (param_pattern)), - type (std::move (param_type)) + std::unique_ptr<Type> param_type = nullptr, + std::vector<Attribute> outer_attrs = {}) + : outer_attrs (std::move (outer_attrs)), + pattern (std::move (param_pattern)), type (std::move (param_type)) {} // Copy constructor required due to cloning as a result of unique_ptrs - ClosureParam (ClosureParam const &other) - : outer_attrs (other.outer_attrs) + ClosureParam (ClosureParam const &other) : outer_attrs (other.outer_attrs) { // guard to protect from null pointer dereference if (other.pattern != nullptr) @@ -2490,13 +2578,15 @@ public: std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Pattern> &get_pattern () { + std::unique_ptr<Pattern> &get_pattern () + { rust_assert (pattern != nullptr); return pattern; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (has_type_given ()); return type; } @@ -2550,8 +2640,7 @@ public: {} // Copy constructor must be defined to allow copying via cloning of unique_ptr - ClosureExprInner (ClosureExprInner const &other) - : ClosureExpr (other) + ClosureExprInner (ClosureExprInner const &other) : ClosureExpr (other) { // guard to prevent null dereference (only required if error state) if (other.closure_inner != nullptr) @@ -2583,10 +2672,14 @@ public: // Invalid if inner expr is null, so base stripping on that. void mark_for_strip () override { closure_inner = nullptr; } - bool is_marked_for_strip () const override { return closure_inner == nullptr; } + bool is_marked_for_strip () const override + { + return closure_inner == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_definition_expr () { + std::unique_ptr<Expr> &get_definition_expr () + { rust_assert (closure_inner != nullptr); return closure_inner; } @@ -2633,7 +2726,8 @@ public: // Copy constructor with clone BlockExpr (BlockExpr const &other) - : ExprWithBlock (other), inner_attrs (other.inner_attrs), locus (other.locus) + : ExprWithBlock (other), inner_attrs (other.inner_attrs), + locus (other.locus) { // guard to protect from null pointer dereference if (other.expr != nullptr) @@ -2681,23 +2775,30 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if has no statements or final expr, so base stripping on that. - void mark_for_strip () override - { - expr = nullptr; - statements.clear (); - statements.shrink_to_fit (); + void mark_for_strip () override + { + expr = nullptr; + statements.clear (); + statements.shrink_to_fit (); + } + bool is_marked_for_strip () const override + { + return expr == nullptr && statements.empty (); } - bool is_marked_for_strip () const override { return expr == nullptr && statements.empty (); } // TODO: this mutable getter seems really dodgy. Think up better way. const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } - const std::vector<std::unique_ptr<Stmt> > &get_statements () const { return statements; } + const std::vector<std::unique_ptr<Stmt> > &get_statements () const + { + return statements; + } std::vector<std::unique_ptr<Stmt> > &get_statements () { return statements; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<ExprWithoutBlock> &get_tail_expr () { + std::unique_ptr<ExprWithoutBlock> &get_tail_expr () + { rust_assert (expr != nullptr); return expr; } @@ -2783,19 +2884,21 @@ public: void accept_vis (ASTVisitor &vis) override; - /* Invalid if inner expr is null, so base stripping on that. Technically, + /* Invalid if inner expr is null, so base stripping on that. Technically, * type should also not be null. */ void mark_for_strip () override { expr = nullptr; } bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition_block () { + std::unique_ptr<BlockExpr> &get_definition_block () + { rust_assert (expr != nullptr); return expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (return_type != nullptr); return return_type; } @@ -2887,7 +2990,8 @@ public: // Copy constructor defined to use clone for unique pointer BreakExpr (BreakExpr const &other) - : ExprWithoutBlock (other), label (other.label), locus (other.locus), marked_for_strip (other.marked_for_strip) + : ExprWithoutBlock (other), label (other.label), locus (other.locus), + marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference if (other.break_expr != nullptr) @@ -2926,7 +3030,8 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_break_expr () { + std::unique_ptr<Expr> &get_break_expr () + { rust_assert (break_expr != nullptr); return break_expr; } @@ -2973,8 +3078,7 @@ public: {} // Copy constructor with cloning - RangeFromToExpr (RangeFromToExpr const &other) - : RangeExpr (other) + RangeFromToExpr (RangeFromToExpr const &other) : RangeExpr (other) { // guard to prevent null dereference (only required if error state) if (other.from != nullptr) @@ -3007,18 +3111,27 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if either expr is null, so base stripping on that. - void mark_for_strip () override { from = nullptr; to = nullptr; } - bool is_marked_for_strip () const override { return from == nullptr && to == nullptr; } + // Invalid if either expr is null, so base stripping on that. + void mark_for_strip () override + { + from = nullptr; + to = nullptr; + } + bool is_marked_for_strip () const override + { + return from == nullptr && to == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_from_expr () { + std::unique_ptr<Expr> &get_from_expr () + { rust_assert (from != nullptr); return from; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_to_expr () { + std::unique_ptr<Expr> &get_to_expr () + { rust_assert (to != nullptr); return to; } @@ -3046,8 +3159,7 @@ public: {} // Copy constructor with clone - RangeFromExpr (RangeFromExpr const &other) - : RangeExpr (other) + RangeFromExpr (RangeFromExpr const &other) : RangeExpr (other) { // guard to prevent null dereference (only required if error state) if (other.from != nullptr) @@ -3058,7 +3170,7 @@ public: RangeFromExpr &operator= (RangeFromExpr const &other) { RangeExpr::operator= (other); - + // guard to prevent null dereference (only required if error state) if (other.from != nullptr) from = other.from->clone_expr (); @@ -3074,12 +3186,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if expr is null, so base stripping on that. + // Invalid if expr is null, so base stripping on that. void mark_for_strip () override { from = nullptr; } bool is_marked_for_strip () const override { return from == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_from_expr () { + std::unique_ptr<Expr> &get_from_expr () + { rust_assert (from != nullptr); return from; } @@ -3108,8 +3221,7 @@ public: {} // Copy constructor with clone - RangeToExpr (RangeToExpr const &other) - : RangeExpr (other) + RangeToExpr (RangeToExpr const &other) : RangeExpr (other) { // guard to prevent null dereference (only required if error state) if (other.to != nullptr) @@ -3120,7 +3232,7 @@ public: RangeToExpr &operator= (RangeToExpr const &other) { RangeExpr::operator= (other); - + // guard to prevent null dereference (only required if error state) if (other.to != nullptr) to = other.to->clone_expr (); @@ -3136,12 +3248,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if expr is null, so base stripping on that. + // Invalid if expr is null, so base stripping on that. void mark_for_strip () override { to = nullptr; } bool is_marked_for_strip () const override { return to == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_to_expr () { + std::unique_ptr<Expr> &get_to_expr () + { rust_assert (to != nullptr); return to; } @@ -3201,8 +3314,7 @@ public: // outer attributes not allowed // Copy constructor with clone - RangeFromToInclExpr (RangeFromToInclExpr const &other) - : RangeExpr (other) + RangeFromToInclExpr (RangeFromToInclExpr const &other) : RangeExpr (other) { // guard to prevent null dereference (only required if error state) if (other.from != nullptr) @@ -3215,7 +3327,7 @@ public: RangeFromToInclExpr &operator= (RangeFromToInclExpr const &other) { RangeExpr::operator= (other); - + // guard to prevent null dereference (only required if error state) if (other.from != nullptr) from = other.from->clone_expr (); @@ -3235,18 +3347,27 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if either expr is null, so base stripping on that. - void mark_for_strip () override { from = nullptr; to = nullptr; } - bool is_marked_for_strip () const override { return from == nullptr && to == nullptr; } + // Invalid if either expr is null, so base stripping on that. + void mark_for_strip () override + { + from = nullptr; + to = nullptr; + } + bool is_marked_for_strip () const override + { + return from == nullptr && to == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_from_expr () { + std::unique_ptr<Expr> &get_from_expr () + { rust_assert (from != nullptr); return from; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_to_expr () { + std::unique_ptr<Expr> &get_to_expr () + { rust_assert (to != nullptr); return to; } @@ -3275,8 +3396,7 @@ public: // outer attributes not allowed // Copy constructor with clone - RangeToInclExpr (RangeToInclExpr const &other) - : RangeExpr (other) + RangeToInclExpr (RangeToInclExpr const &other) : RangeExpr (other) { // guard to prevent null dereference (only required if error state) if (other.to != nullptr) @@ -3287,7 +3407,7 @@ public: RangeToInclExpr &operator= (RangeToInclExpr const &other) { RangeExpr::operator= (other); - + // guard to prevent null dereference (only required if error state) if (other.to != nullptr) to = other.to->clone_expr (); @@ -3303,12 +3423,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if expr is null, so base stripping on that. + // Invalid if expr is null, so base stripping on that. void mark_for_strip () override { to = nullptr; } bool is_marked_for_strip () const override { return to == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_to_expr () { + std::unique_ptr<Expr> &get_to_expr () + { rust_assert (to != nullptr); return to; } @@ -3348,7 +3469,8 @@ public: // Copy constructor with clone ReturnExpr (ReturnExpr const &other) - : ExprWithoutBlock (other), locus (other.locus), marked_for_strip (other.marked_for_strip) + : ExprWithoutBlock (other), locus (other.locus), + marked_for_strip (other.marked_for_strip) { // guard to protect from null pointer dereference if (other.return_expr != nullptr) @@ -3386,7 +3508,8 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_returned_expr () { + std::unique_ptr<Expr> &get_returned_expr () + { rust_assert (return_expr != nullptr); return return_expr; } @@ -3453,12 +3576,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if block is null, so base stripping on that. + // Invalid if block is null, so base stripping on that. void mark_for_strip () override { expr = nullptr; } bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_block_expr () { + std::unique_ptr<BlockExpr> &get_block_expr () + { rust_assert (expr != nullptr); return expr; } @@ -3555,12 +3679,13 @@ public: Location get_locus () const { return locus; } Location get_locus_slow () const override { return get_locus (); } - // Invalid if loop block is null, so base stripping on that. + // Invalid if loop block is null, so base stripping on that. void mark_for_strip () override { loop_block = nullptr; } bool is_marked_for_strip () const override { return loop_block == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_loop_block () { + std::unique_ptr<BlockExpr> &get_loop_block () + { rust_assert (loop_block != nullptr); return loop_block; } @@ -3634,7 +3759,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_predicate_expr () { + std::unique_ptr<Expr> &get_predicate_expr () + { rust_assert (condition != nullptr); return condition; } @@ -3706,14 +3832,21 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_scrutinee_expr () { + std::unique_ptr<Expr> &get_scrutinee_expr () + { rust_assert (scrutinee != nullptr); return scrutinee; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () { return match_arm_patterns; } + const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + { + return match_arm_patterns; + } + std::vector<std::unique_ptr<Pattern> > &get_patterns () + { + return match_arm_patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -3771,13 +3904,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_iterator_expr () { + std::unique_ptr<Expr> &get_iterator_expr () + { rust_assert (iterator_expr != nullptr); return iterator_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Pattern> &get_pattern () { + std::unique_ptr<Pattern> &get_pattern () + { rust_assert (pattern != nullptr); return pattern; } @@ -3814,8 +3949,7 @@ public: // outer attributes are never allowed on IfExprs // Copy constructor with clone - IfExpr (IfExpr const &other) - : ExprWithBlock (other), locus (other.locus) + IfExpr (IfExpr const &other) : ExprWithBlock (other), locus (other.locus) { // guard to prevent null dereference (only required if error state) if (other.condition != nullptr) @@ -3866,20 +4000,29 @@ public: void vis_if_block (ASTVisitor &vis) { if_block->accept_vis (vis); } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_condition_expr () { + std::unique_ptr<Expr> &get_condition_expr () + { rust_assert (condition != nullptr); return condition; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_if_block () { + std::unique_ptr<BlockExpr> &get_if_block () + { rust_assert (if_block != nullptr); return if_block; } - // Invalid if if block or condition is null, so base stripping on that. - void mark_for_strip () override { if_block = nullptr; condition = nullptr; } - bool is_marked_for_strip () const override { return if_block == nullptr && condition == nullptr; } + // Invalid if if block or condition is null, so base stripping on that. + void mark_for_strip () override + { + if_block = nullptr; + condition = nullptr; + } + bool is_marked_for_strip () const override + { + return if_block == nullptr && condition == nullptr; + } protected: // Base clone function but still concrete as concrete base class @@ -3934,7 +4077,8 @@ public: void vis_else_block (ASTVisitor &vis) { else_block->accept_vis (vis); } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_else_block () { + std::unique_ptr<BlockExpr> &get_else_block () + { rust_assert (else_block != nullptr); return else_block; } @@ -3992,7 +4136,8 @@ public: } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<IfExpr> &get_conseq_if_expr () { + std::unique_ptr<IfExpr> &get_conseq_if_expr () + { rust_assert (conseq_if_expr != nullptr); return conseq_if_expr; } @@ -4080,25 +4225,40 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if block or value is null, so base stripping on that. - void mark_for_strip () override { if_block = nullptr; value = nullptr; } - bool is_marked_for_strip () const override { return if_block == nullptr && value == nullptr; } + // Invalid if block or value is null, so base stripping on that. + void mark_for_strip () override + { + if_block = nullptr; + value = nullptr; + } + bool is_marked_for_strip () const override + { + return if_block == nullptr && value == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_value_expr () { + std::unique_ptr<Expr> &get_value_expr () + { rust_assert (value != nullptr); return value; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_if_block () { + std::unique_ptr<BlockExpr> &get_if_block () + { rust_assert (if_block != nullptr); return if_block; } // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () { return match_arm_patterns; } + const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + { + return match_arm_patterns; + } + std::vector<std::unique_ptr<Pattern> > &get_patterns () + { + return match_arm_patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -4155,7 +4315,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<IfLetExpr> &get_conseq_if_let_expr () { + std::unique_ptr<IfLetExpr> &get_conseq_if_let_expr () + { rust_assert (if_let_expr != nullptr); return if_let_expr; } @@ -4213,7 +4374,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_else_block () { + std::unique_ptr<BlockExpr> &get_else_block () + { rust_assert (else_block != nullptr); return else_block; } @@ -4270,7 +4432,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<IfExpr> &get_conseq_if_expr () { + std::unique_ptr<IfExpr> &get_conseq_if_expr () + { rust_assert (if_expr != nullptr); return if_expr; } @@ -4327,7 +4490,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<IfLetExpr> &get_conseq_if_let_expr () { + std::unique_ptr<IfLetExpr> &get_conseq_if_let_expr () + { rust_assert (if_let_expr != nullptr); return if_let_expr; } @@ -4415,7 +4579,8 @@ public: std::string as_string () const; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_guard_expr () { + std::unique_ptr<Expr> &get_guard_expr () + { rust_assert (has_match_arm_guard ()); return guard_expr; } @@ -4424,8 +4589,14 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } - const std::vector<std::unique_ptr<Pattern> > &get_patterns () const { return match_arm_patterns; } - std::vector<std::unique_ptr<Pattern> > &get_patterns () { return match_arm_patterns; } + const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + { + return match_arm_patterns; + } + std::vector<std::unique_ptr<Pattern> > &get_patterns () + { + return match_arm_patterns; + } }; /* @@ -4493,13 +4664,15 @@ public: std::string as_string () const; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr () { + std::unique_ptr<Expr> &get_expr () + { rust_assert (expr != nullptr); return expr; } // TODO: is this better? Or is a "vis_block" better? - MatchArm &get_arm () { + MatchArm &get_arm () + { rust_assert (!arm.is_error ()); return arm; } @@ -4628,7 +4801,7 @@ public: // Copy constructor requires clone due to unique_ptr MatchExpr (MatchExpr const &other) - : ExprWithBlock (other), inner_attrs (other.inner_attrs), + : ExprWithBlock (other), inner_attrs (other.inner_attrs), match_arms (other.match_arms), locus (other.locus) { // guard to prevent null dereference (only required if error state) @@ -4671,7 +4844,7 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if branch value is null, so base stripping on that. + // Invalid if branch value is null, so base stripping on that. void mark_for_strip () override { branch_value = nullptr; } bool is_marked_for_strip () const override { return branch_value == nullptr; } @@ -4680,7 +4853,8 @@ public: std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_scrutinee_expr () { + std::unique_ptr<Expr> &get_scrutinee_expr () + { rust_assert (branch_value != nullptr); return branch_value; } @@ -4746,12 +4920,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if awaited expr is null, so base stripping on that. + // Invalid if awaited expr is null, so base stripping on that. void mark_for_strip () override { awaited_expr = nullptr; } bool is_marked_for_strip () const override { return awaited_expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_awaited_expr () { + std::unique_ptr<Expr> &get_awaited_expr () + { rust_assert (awaited_expr != nullptr); return awaited_expr; } @@ -4816,12 +4991,13 @@ public: void accept_vis (ASTVisitor &vis) override; - // Invalid if block is null, so base stripping on that. + // Invalid if block is null, so base stripping on that. void mark_for_strip () override { block_expr = nullptr; } bool is_marked_for_strip () const override { return block_expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_block_expr () { + std::unique_ptr<BlockExpr> &get_block_expr () + { rust_assert (block_expr != nullptr); return block_expr; } diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 455511c..f18124d 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -57,7 +57,7 @@ class TypeParam : public GenericParam // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form // bool has_type; @@ -76,8 +76,8 @@ public: bool has_outer_attribute () const { return !outer_attr.is_empty (); } TypeParam (Identifier type_representation, Location locus = Location (), - std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds - = std::vector<std::unique_ptr<TypeParamBound>> (), + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds + = std::vector<std::unique_ptr<TypeParamBound> > (), std::unique_ptr<Type> type = nullptr, Attribute outer_attr = Attribute::create_empty ()) : outer_attr (std::move (outer_attr)), @@ -89,8 +89,7 @@ public: // Copy constructor uses clone TypeParam (TypeParam const &other) : outer_attr (other.outer_attr), - type_representation (other.type_representation), - locus (other.locus) + type_representation (other.type_representation), locus (other.locus) { // guard to prevent null pointer dereference if (other.type != nullptr) @@ -132,14 +131,22 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } // TODO: mutable getter seems kinda dodgy - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } protected: // Clone function implementation as (not pure) virtual method @@ -211,7 +218,7 @@ class TypeBoundWhereClauseItem : public WhereClauseItem // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form // should this store location info? @@ -225,7 +232,7 @@ public: TypeBoundWhereClauseItem ( std::vector<LifetimeParam> for_lifetimes, std::unique_ptr<Type> bound_type, - std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds) + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds) : for_lifetimes (std::move (for_lifetimes)), bound_type (std::move (bound_type)), type_param_bounds (std::move (type_param_bounds)) @@ -264,14 +271,22 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (bound_type != nullptr); return bound_type; } // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } protected: // Clone function implementation as (not pure) virtual method @@ -285,13 +300,13 @@ protected: struct WhereClause { private: - std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items; + std::vector<std::unique_ptr<WhereClauseItem> > where_clause_items; // should this store location info? public: WhereClause ( - std::vector<std::unique_ptr<WhereClauseItem>> where_clause_items) + std::vector<std::unique_ptr<WhereClauseItem> > where_clause_items) : where_clause_items (std::move (where_clause_items)) {} @@ -320,7 +335,7 @@ public: // Creates a WhereClause with no items. static WhereClause create_empty () { - return WhereClause (std::vector<std::unique_ptr<WhereClauseItem>> ()); + return WhereClause (std::vector<std::unique_ptr<WhereClauseItem> > ()); } // Returns whether the WhereClause has no items. @@ -329,8 +344,14 @@ public: std::string as_string () const; // TODO: this mutable getter seems kinda dodgy - std::vector<std::unique_ptr<WhereClauseItem> > &get_items () { return where_clause_items; } - const std::vector<std::unique_ptr<WhereClauseItem> > &get_items () const { return where_clause_items; } + std::vector<std::unique_ptr<WhereClauseItem> > &get_items () + { + return where_clause_items; + } + const std::vector<std::unique_ptr<WhereClauseItem> > &get_items () const + { + return where_clause_items; + } }; // A self parameter in a method @@ -423,7 +444,8 @@ public: Location get_locus () const { return locus; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (has_type ()); return type; } @@ -479,8 +501,9 @@ private: public: FunctionParam (std::unique_ptr<Pattern> param_name, - std::unique_ptr<Type> param_type, std::vector<Attribute> outer_attrs, Location locus) - : outer_attrs (std::move (outer_attrs)), locus (locus), + std::unique_ptr<Type> param_type, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), locus (locus), param_name (std::move (param_name)), type (std::move (param_type)) {} @@ -534,13 +557,15 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Pattern> &get_pattern () { + std::unique_ptr<Pattern> &get_pattern () + { rust_assert (param_name != nullptr); return param_name; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } @@ -647,7 +672,7 @@ class Method : public InherentImplItem, public TraitImplItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined SelfParam self_param; @@ -670,14 +695,15 @@ public: // Returns whether the method is in an error state. bool is_error () const { - return function_body == nullptr || method_name.empty () || self_param.is_error (); + return function_body == nullptr || method_name.empty () + || self_param.is_error (); } // Creates an error state method. static Method create_error () { return Method ("", FunctionQualifiers (FunctionQualifiers::NONE, true), - std::vector<std::unique_ptr<GenericParam>> (), + std::vector<std::unique_ptr<GenericParam> > (), SelfParam::create_error (), std::vector<FunctionParam> (), nullptr, WhereClause::create_empty (), nullptr, Visibility::create_error (), std::vector<Attribute> (), {}); @@ -700,7 +726,7 @@ public: // Mega-constructor with all possible fields Method (Identifier method_name, FunctionQualifiers qualifiers, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, SelfParam self_param, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, @@ -712,8 +738,8 @@ public: self_param (std::move (self_param)), function_params (std::move (function_params)), return_type (std::move (return_type)), - where_clause (std::move (where_clause)), function_body (std::move (function_body)), - locus (locus) + where_clause (std::move (where_clause)), + function_body (std::move (function_body)), locus (locus) {} // TODO: add constructor with less fields @@ -728,7 +754,7 @@ public: // 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 (); @@ -779,20 +805,33 @@ public: // Invalid if block is null, so base stripping on that. void mark_for_strip () override { function_body = nullptr; } - bool is_marked_for_strip () const override { return function_body == nullptr; } + bool is_marked_for_strip () const override + { + return function_body == nullptr; + } // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } std::vector<FunctionParam> &get_function_params () { return function_params; } - const std::vector<FunctionParam> &get_function_params () const { return function_params; } + const std::vector<FunctionParam> &get_function_params () const + { + return function_params; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition () { + std::unique_ptr<BlockExpr> &get_definition () + { rust_assert (function_body != nullptr); return function_body; } @@ -801,13 +840,15 @@ public: const SelfParam &get_self_param () const { return self_param; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -838,11 +879,12 @@ 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 (std::move (visibility)), outer_attrs (std::move (outer_attrs)) {} // Visibility copy constructor - VisItem (VisItem const &other) : visibility (other.visibility), outer_attrs(other.outer_attrs) + VisItem (VisItem const &other) + : visibility (other.visibility), outer_attrs (other.outer_attrs) {} // Overload assignment operator to clone @@ -903,7 +945,7 @@ class ModuleBodied : public Module // bool has_inner_attrs; std::vector<Attribute> inner_attrs; // bool has_items; - std::vector<std::unique_ptr<Item>> items; + std::vector<std::unique_ptr<Item> > items; public: std::string as_string () const override; @@ -916,8 +958,8 @@ public: // Full constructor ModuleBodied (Identifier name, Location locus, - std::vector<std::unique_ptr<Item>> items - = std::vector<std::unique_ptr<Item>> (), + std::vector<std::unique_ptr<Item> > items + = std::vector<std::unique_ptr<Item> > (), Visibility visibility = Visibility::create_error (), std::vector<Attribute> inner_attrs = std::vector<Attribute> (), std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) @@ -959,11 +1001,14 @@ public: void add_crate_name (std::vector<std::string> &names) const override; // TODO: think of better way to do this - mutable getter seems dodgy - const std::vector<Attribute>& get_inner_attrs () const { return inner_attrs; } - std::vector<Attribute>& get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } + std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } - const std::vector<std::unique_ptr<Item>>& get_items () const { return items; } - std::vector<std::unique_ptr<Item>>& get_items () { return items; } + const std::vector<std::unique_ptr<Item> > &get_items () const + { + return items; + } + std::vector<std::unique_ptr<Item> > &get_items () { return items; } protected: /* Use covariance to implement clone function as returning this object @@ -977,9 +1022,11 @@ protected: // Module without a body, loaded from external file class ModuleNoBody : public Module { - /* TODO: are modules loaded from file unique? As in, can you load the same file into two different - * other files? Because this may make the difference between simply replacing this with the module - * "definition" (as loaded from another file) vs this having to "reference" a module with body. */ + /* TODO: are modules loaded from file unique? As in, can you load the same + * file into two different other files? Because this may make the difference + * between simply replacing this with the module + * "definition" (as loaded from another file) vs this having to "reference" a + * module with body. */ public: std::string as_string () const override; @@ -1048,7 +1095,10 @@ public: // Invalid if crate name is empty, so base stripping on that. void mark_for_strip () override { referenced_crate = ""; } - bool is_marked_for_strip () const override { return referenced_crate.empty (); } + bool is_marked_for_strip () const override + { + return referenced_crate.empty (); + } protected: /* Use covariance to implement clone function as returning this object @@ -1149,11 +1199,11 @@ private: PathType path_type; SimplePath path; - std::vector<std::unique_ptr<UseTree>> trees; + std::vector<std::unique_ptr<UseTree> > trees; public: UseTreeList (PathType path_type, SimplePath path, - std::vector<std::unique_ptr<UseTree>> trees, Location locus) + std::vector<std::unique_ptr<UseTree> > trees, Location locus) : UseTree (locus), path_type (path_type), path (std::move (path)), trees (std::move (trees)) { @@ -1337,7 +1387,7 @@ class Function : public VisItem, public InherentImplItem, public TraitImplItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_function_params; // FunctionParams function_params; @@ -1372,7 +1422,7 @@ public: // Mega-constructor with all possible fields Function (Identifier function_name, FunctionQualifiers qualifiers, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, @@ -1399,7 +1449,7 @@ public: // 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 (); @@ -1426,7 +1476,7 @@ public: 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 (); @@ -1450,17 +1500,30 @@ public: // Invalid if block is null, so base stripping on that. void mark_for_strip () override { function_body = nullptr; } - bool is_marked_for_strip () const override { return function_body == nullptr; } + bool is_marked_for_strip () const override + { + return function_body == nullptr; + } // 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 { return function_params; } + const std::vector<FunctionParam> &get_function_params () const + { + return function_params; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition () { + std::unique_ptr<BlockExpr> &get_definition () + { rust_assert (function_body != nullptr); return function_body; } @@ -1470,13 +1533,15 @@ public: Identifier get_function_name () const { return function_name; } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } @@ -1508,7 +1573,7 @@ class TypeAlias : public VisItem, public TraitImplItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; @@ -1528,7 +1593,7 @@ public: // Mega-constructor with all possible fields TypeAlias (Identifier new_type_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, std::unique_ptr<Type> existing_type, Visibility vis, std::vector<Attribute> outer_attrs, Location locus) : VisItem (std::move (vis), std::move (outer_attrs)), @@ -1585,19 +1650,30 @@ public: // Invalid if existing type is null, so base stripping on that. void mark_for_strip () override { existing_type = nullptr; } - bool is_marked_for_strip () const override { return existing_type == nullptr; } + bool is_marked_for_strip () const override + { + return existing_type == nullptr; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type_aliased () { + std::unique_ptr<Type> &get_type_aliased () + { rust_assert (existing_type != nullptr); return existing_type; } @@ -1624,7 +1700,7 @@ protected: // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; @@ -1647,18 +1723,25 @@ public: Identifier get_struct_name () const { return struct_name; } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } protected: Struct (Identifier struct_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, Visibility vis, Location locus, std::vector<Attribute> outer_attrs = std::vector<Attribute> ()) : VisItem (std::move (vis), std::move (outer_attrs)), @@ -1780,7 +1863,8 @@ public: Identifier get_field_name () const { return field_name; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_field_type () { + std::unique_ptr<Type> &get_field_type () + { rust_assert (field_type != nullptr); return field_type; } @@ -1799,7 +1883,7 @@ public: // Mega-constructor with all possible fields StructStruct (std::vector<StructField> fields, Identifier struct_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, bool is_unit, Visibility vis, std::vector<Attribute> outer_attrs, Location locus) : Struct (std::move (struct_name), std::move (generic_params), @@ -1810,12 +1894,13 @@ public: // Unit struct constructor StructStruct (Identifier struct_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, Visibility vis, std::vector<Attribute> outer_attrs, Location locus) : Struct (std::move (struct_name), std::move (generic_params), std::move (where_clause), std::move (vis), locus, - std::move (outer_attrs)), is_unit (true) + std::move (outer_attrs)), + is_unit (true) {} // TODO: can a unit struct have generic fields? assuming yes for now. @@ -1914,7 +1999,8 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_field_type () { + std::unique_ptr<Type> &get_field_type () + { rust_assert (field_type != nullptr); return field_type; } @@ -1930,7 +2016,7 @@ public: // Mega-constructor with all possible fields TupleStruct (std::vector<TupleField> fields, Identifier struct_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, Visibility vis, std::vector<Attribute> outer_attrs, Location locus) : Struct (std::move (struct_name), std::move (generic_params), @@ -2026,7 +2112,10 @@ public: // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<TupleField> &get_tuple_fields () { return tuple_fields; } - const std::vector<TupleField> &get_tuple_fields () const { return tuple_fields; } + const std::vector<TupleField> &get_tuple_fields () const + { + return tuple_fields; + } protected: // Clone function implementation as (not pure) virtual method @@ -2059,7 +2148,10 @@ public: // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<StructField> &get_struct_fields () { return struct_fields; } - const std::vector<StructField> &get_struct_fields () const { return struct_fields; } + const std::vector<StructField> &get_struct_fields () const + { + return struct_fields; + } protected: // Clone function implementation as (not pure) virtual method @@ -2106,7 +2198,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr () { + std::unique_ptr<Expr> &get_expr () + { rust_assert (expression != nullptr); return expression; } @@ -2126,12 +2219,12 @@ class Enum : public VisItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; - std::vector<std::unique_ptr<EnumItem>> items; + std::vector<std::unique_ptr<EnumItem> > items; Location locus; @@ -2150,8 +2243,8 @@ public: // Mega-constructor Enum (Identifier enum_name, Visibility vis, - std::vector<std::unique_ptr<GenericParam>> generic_params, - WhereClause where_clause, std::vector<std::unique_ptr<EnumItem>> items, + std::vector<std::unique_ptr<GenericParam> > generic_params, + WhereClause where_clause, std::vector<std::unique_ptr<EnumItem> > items, std::vector<Attribute> outer_attrs, Location locus) : VisItem (std::move (vis), std::move (outer_attrs)), enum_name (std::move (enum_name)), @@ -2208,14 +2301,24 @@ public: bool is_marked_for_strip () const override { return enum_name.empty (); } // TODO: this mutable getter seems really dodgy. Think up better way. - std::vector<std::unique_ptr<EnumItem>> &get_variants () { return items; } - const std::vector<std::unique_ptr<EnumItem>> &get_variants () const { return items; } + std::vector<std::unique_ptr<EnumItem> > &get_variants () { return items; } + const std::vector<std::unique_ptr<EnumItem> > &get_variants () const + { + return items; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -2233,7 +2336,7 @@ class Union : public VisItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_where_clause; WhereClause where_clause; @@ -2252,7 +2355,7 @@ public: bool has_where_clause () const { return !where_clause.is_empty (); } Union (Identifier union_name, Visibility vis, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, WhereClause where_clause, std::vector<StructField> variants, std::vector<Attribute> outer_attrs, Location locus) : VisItem (std::move (vis), std::move (outer_attrs)), @@ -2305,11 +2408,18 @@ public: std::vector<StructField> &get_variants () { return variants; } const std::vector<StructField> &get_variants () const { return variants; } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -2390,17 +2500,26 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if type or expression are null, so base stripping on that. - void mark_for_strip () override { type = nullptr; const_expr = nullptr; } - bool is_marked_for_strip () const override { return type == nullptr && const_expr == nullptr; } + void mark_for_strip () override + { + type = nullptr; + const_expr = nullptr; + } + bool is_marked_for_strip () const override + { + return type == nullptr && const_expr == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr () { + std::unique_ptr<Expr> &get_expr () + { rust_assert (const_expr != nullptr); return const_expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } @@ -2491,17 +2610,26 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if type or expression are null, so base stripping on that. - void mark_for_strip () override { type = nullptr; expr = nullptr; } - bool is_marked_for_strip () const override { return type == nullptr && expr == nullptr; } + void mark_for_strip () override + { + type = nullptr; + expr = nullptr; + } + bool is_marked_for_strip () const override + { + return type == nullptr && expr == nullptr; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr () { + std::unique_ptr<Expr> &get_expr () + { rust_assert (expr != nullptr); return expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } @@ -2525,7 +2653,7 @@ private: // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_params; // FunctionParams function_params; @@ -2554,7 +2682,7 @@ public: // Mega-constructor TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause) @@ -2569,8 +2697,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) + function_params (other.function_params), where_clause (other.where_clause) { // guard to prevent nullptr dereference if (other.return_type != nullptr) @@ -2616,19 +2743,30 @@ public: // 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 { return function_params; } + const std::vector<FunctionParam> &get_function_params () const + { + return function_params; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -2690,20 +2828,25 @@ public: // Invalid if trait decl is empty, so base stripping on that. void mark_for_strip () override { decl.mark_for_strip (); } - bool is_marked_for_strip () const override { return decl.is_marked_for_strip (); } + bool is_marked_for_strip () const override + { + return decl.is_marked_for_strip (); + } // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition () { + std::unique_ptr<BlockExpr> &get_definition () + { rust_assert (has_definition ()); return block_expr; } // TODO: is this better? Or is a "vis_block" better? - TraitFunctionDecl &get_trait_function_decl () { + TraitFunctionDecl &get_trait_function_decl () + { // TODO: maybe only allow access if not marked for strip? return decl; } @@ -2726,7 +2869,7 @@ private: // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined SelfParam self_param; @@ -2757,7 +2900,7 @@ public: // Mega-constructor TraitMethodDecl (Identifier function_name, FunctionQualifiers qualifiers, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, SelfParam self_param, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause) @@ -2821,19 +2964,30 @@ public: // 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 { return function_params; } + const std::vector<FunctionParam> &get_function_params () const + { + return function_params; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -2862,8 +3016,7 @@ public: // Copy constructor with clone TraitItemMethod (TraitItemMethod const &other) - : outer_attrs (other.outer_attrs), decl (other.decl), - locus (other.locus) + : outer_attrs (other.outer_attrs), decl (other.decl), locus (other.locus) { // guard to prevent null dereference if (other.block_expr != nullptr) @@ -2899,21 +3052,26 @@ public: // Invalid if trait decl is empty, so base stripping on that. void mark_for_strip () override { decl.mark_for_strip (); } - bool is_marked_for_strip () const override { return decl.is_marked_for_strip (); } + bool is_marked_for_strip () const override + { + return decl.is_marked_for_strip (); + } // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - TraitMethodDecl &get_trait_method_decl () { + TraitMethodDecl &get_trait_method_decl () + { // TODO: maybe only allow access if not marked for strip? return decl; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<BlockExpr> &get_definition () { - rust_assert (has_definition()); + std::unique_ptr<BlockExpr> &get_definition () + { + rust_assert (has_definition ()); return block_expr; } @@ -2955,7 +3113,7 @@ public: // guard to prevent null dereference if (other.expr != nullptr) expr = other.expr->clone_expr (); - + // guard to prevent null dereference (only for error state) if (other.type != nullptr) type = other.type->clone_type (); @@ -3003,13 +3161,15 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_expr () { + std::unique_ptr<Expr> &get_expr () + { rust_assert (expr != nullptr); return expr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } @@ -3031,7 +3191,7 @@ class TraitItemType : public TraitItem // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form Location locus; @@ -3042,7 +3202,7 @@ public: TraitItemType ( Identifier name, - std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds, std::vector<Attribute> outer_attrs, Location locus) : outer_attrs (std::move (outer_attrs)), name (std::move (name)), type_param_bounds (std::move (type_param_bounds)), locus (locus) @@ -3091,8 +3251,15 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: mutable getter seems kinda dodgy - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } protected: // Clone function implementation as (not pure) virtual method @@ -3110,11 +3277,11 @@ class Trait : public VisItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_type_param_bounds; // TypeParamBounds type_param_bounds; - std::vector<std::unique_ptr<TypeParamBound>> + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds; // inlined form // bool has_where_clause; @@ -3123,7 +3290,7 @@ class Trait : public VisItem std::vector<Attribute> inner_attrs; // bool has_trait_items; - std::vector<std::unique_ptr<TraitItem>> trait_items; + std::vector<std::unique_ptr<TraitItem> > trait_items; Location locus; @@ -3147,23 +3314,26 @@ public: // Mega-constructor Trait (Identifier name, bool is_unsafe, - std::vector<std::unique_ptr<GenericParam>> generic_params, - std::vector<std::unique_ptr<TypeParamBound>> type_param_bounds, + std::vector<std::unique_ptr<GenericParam> > generic_params, + std::vector<std::unique_ptr<TypeParamBound> > type_param_bounds, WhereClause where_clause, - std::vector<std::unique_ptr<TraitItem>> trait_items, Visibility vis, - std::vector<Attribute> outer_attrs, std::vector<Attribute> inner_attrs, Location locus) + std::vector<std::unique_ptr<TraitItem> > trait_items, Visibility vis, + std::vector<Attribute> outer_attrs, std::vector<Attribute> inner_attrs, + Location locus) : VisItem (std::move (vis), std::move (outer_attrs)), has_unsafe (is_unsafe), name (std::move (name)), generic_params (std::move (generic_params)), type_param_bounds (std::move (type_param_bounds)), - where_clause (std::move (where_clause)), inner_attrs (std::move (inner_attrs)), + where_clause (std::move (where_clause)), + inner_attrs (std::move (inner_attrs)), trait_items (std::move (trait_items)), locus (locus) {} // Copy constructor with vector clone Trait (Trait const &other) : VisItem (other), has_unsafe (other.has_unsafe), name (other.name), - where_clause (other.where_clause), inner_attrs (other.inner_attrs), locus (other.locus) + where_clause (other.where_clause), inner_attrs (other.inner_attrs), + locus (other.locus) { generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) @@ -3216,20 +3386,40 @@ public: bool is_marked_for_strip () const override { return name.empty (); } // TODO: think of better way to do this - const std::vector<Attribute>& get_inner_attrs () const { return inner_attrs; } - std::vector<Attribute>& get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } + std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } - const std::vector<std::unique_ptr<TraitItem>>& get_trait_items () const { return trait_items; } - std::vector<std::unique_ptr<TraitItem>>& get_trait_items () { return trait_items; } + const std::vector<std::unique_ptr<TraitItem> > &get_trait_items () const + { + return trait_items; + } + std::vector<std::unique_ptr<TraitItem> > &get_trait_items () + { + return trait_items; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } @@ -3247,7 +3437,7 @@ class Impl : public VisItem protected: // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined std::unique_ptr<Type> trait_type; @@ -3278,27 +3468,35 @@ public: bool is_marked_for_strip () const override { return trait_type == nullptr; } // TODO: think of better way to do this - const std::vector<Attribute>& get_inner_attrs () const { return inner_attrs; } - std::vector<Attribute>& get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } + std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (trait_type != nullptr); return trait_type; } protected: // Mega-constructor - Impl (std::vector<std::unique_ptr<GenericParam>> generic_params, + Impl (std::vector<std::unique_ptr<GenericParam> > generic_params, std::unique_ptr<Type> trait_type, WhereClause where_clause, Visibility vis, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) @@ -3311,7 +3509,7 @@ protected: // Copy constructor Impl (Impl const &other) - : VisItem (other), where_clause (other.where_clause), + : VisItem (other), where_clause (other.where_clause), inner_attrs (other.inner_attrs), locus (other.locus) { // guard to prevent null dereference (only required if error state) @@ -3353,7 +3551,7 @@ protected: class InherentImpl : public Impl { // bool has_impl_items; - std::vector<std::unique_ptr<InherentImplItem>> impl_items; + std::vector<std::unique_ptr<InherentImplItem> > impl_items; public: std::string as_string () const override; @@ -3362,8 +3560,8 @@ public: bool has_impl_items () const { return !impl_items.empty (); } // Mega-constructor - InherentImpl (std::vector<std::unique_ptr<InherentImplItem>> impl_items, - std::vector<std::unique_ptr<GenericParam>> generic_params, + InherentImpl (std::vector<std::unique_ptr<InherentImplItem> > impl_items, + std::vector<std::unique_ptr<GenericParam> > generic_params, std::unique_ptr<Type> trait_type, WhereClause where_clause, Visibility vis, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) @@ -3400,8 +3598,14 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: think of better way to do this - const std::vector<std::unique_ptr<InherentImplItem>>& get_impl_items () const { return impl_items; } - std::vector<std::unique_ptr<InherentImplItem>>& get_impl_items () { return impl_items; } + const std::vector<std::unique_ptr<InherentImplItem> > &get_impl_items () const + { + return impl_items; + } + std::vector<std::unique_ptr<InherentImplItem> > &get_impl_items () + { + return impl_items; + } protected: /* Use covariance to implement clone function as returning this object @@ -3420,7 +3624,7 @@ class TraitImpl : public Impl TypePath trait_path; // bool has_impl_items; - std::vector<std::unique_ptr<TraitImplItem>> impl_items; + std::vector<std::unique_ptr<TraitImplItem> > impl_items; public: std::string as_string () const override; @@ -3430,8 +3634,8 @@ public: // Mega-constructor TraitImpl (TypePath trait_path, bool is_unsafe, bool has_exclam, - std::vector<std::unique_ptr<TraitImplItem>> impl_items, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<TraitImplItem> > impl_items, + std::vector<std::unique_ptr<GenericParam> > generic_params, std::unique_ptr<Type> trait_type, WhereClause where_clause, Visibility vis, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) @@ -3476,11 +3680,18 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: think of better way to do this - const std::vector<std::unique_ptr<TraitImplItem>>& get_impl_items () const { return impl_items; } - std::vector<std::unique_ptr<TraitImplItem>>& get_impl_items () { return impl_items; } + const std::vector<std::unique_ptr<TraitImplItem> > &get_impl_items () const + { + return impl_items; + } + std::vector<std::unique_ptr<TraitImplItem> > &get_impl_items () + { + return impl_items; + } // TODO: is this better? Or is a "vis_block" better? - TypePath &get_trait_path () { + TypePath &get_trait_path () + { // TODO: assert that trait path is not empty? return trait_path; } @@ -3587,17 +3798,17 @@ class ExternalStaticItem : public ExternalItem public: ExternalStaticItem (Identifier item_name, std::unique_ptr<Type> item_type, - bool is_mut, Visibility vis, std::vector<Attribute> outer_attrs, - Location locus) - : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), - item_name (std::move (item_name)), locus (locus), has_mut (is_mut), + bool is_mut, Visibility vis, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), + item_name (std::move (item_name)), locus (locus), has_mut (is_mut), item_type (std::move (item_type)) {} // Copy constructor ExternalStaticItem (ExternalStaticItem const &other) - : outer_attrs (other.outer_attrs), visibility (other.visibility), item_name (other.item_name), - locus (other.locus), has_mut (other.has_mut) + : outer_attrs (other.outer_attrs), visibility (other.visibility), + item_name (other.item_name), locus (other.locus), has_mut (other.has_mut) { // guard to prevent null dereference (only required if error state) if (other.item_type != nullptr) @@ -3647,7 +3858,8 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (item_type != nullptr); return item_type; } @@ -3666,14 +3878,14 @@ struct NamedFunctionParam { private: // bool has_name; // otherwise is _ - std::string name; + std::string name; std::unique_ptr<Type> param_type; // TODO: should this store location data? // seemingly new since writing this node - std::vector<Attribute> outer_attrs; + std::vector<Attribute> outer_attrs; public: /* Returns whether the named function parameter has a name (i.e. name is not @@ -3695,8 +3907,10 @@ public: return NamedFunctionParam ("", nullptr, {}); } - NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type, std::vector<Attribute> outer_attrs) - : name (std::move (name)), param_type (std::move (param_type)), outer_attrs (std::move (outer_attrs)) + NamedFunctionParam (std::string name, std::unique_ptr<Type> param_type, + std::vector<Attribute> outer_attrs) + : name (std::move (name)), param_type (std::move (param_type)), + outer_attrs (std::move (outer_attrs)) {} // Copy constructor @@ -3741,7 +3955,8 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (param_type != nullptr); return param_type; } @@ -3761,7 +3976,7 @@ class ExternalFunctionItem : public ExternalItem // bool has_generics; // Generics generic_params; - std::vector<std::unique_ptr<GenericParam>> generic_params; // inlined + std::vector<std::unique_ptr<GenericParam> > generic_params; // inlined // bool has_return_type; // FunctionReturnType return_type; @@ -3794,33 +4009,41 @@ public: bool is_variadic () const { return has_variadics; } // Returns whether item has outer attributes on its variadic parameters. - bool has_variadic_outer_attrs () const { return !variadic_outer_attrs.empty (); } + bool has_variadic_outer_attrs () const + { + return !variadic_outer_attrs.empty (); + } Location get_locus () const { return locus; } ExternalFunctionItem ( Identifier item_name, - std::vector<std::unique_ptr<GenericParam>> generic_params, + std::vector<std::unique_ptr<GenericParam> > generic_params, std::unique_ptr<Type> return_type, WhereClause where_clause, - std::vector<NamedFunctionParam> function_params, bool has_variadics, std::vector<Attribute> variadic_outer_attrs, - Visibility vis, std::vector<Attribute> outer_attrs, Location locus) - : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), + std::vector<NamedFunctionParam> function_params, bool has_variadics, + std::vector<Attribute> variadic_outer_attrs, Visibility vis, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), visibility (std::move (vis)), item_name (std::move (item_name)), locus (locus), generic_params (std::move (generic_params)), return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_params (std::move (function_params)), - has_variadics (has_variadics), variadic_outer_attrs (std::move (variadic_outer_attrs)) + has_variadics (has_variadics), + variadic_outer_attrs (std::move (variadic_outer_attrs)) { - // TODO: assert that if has variadic outer attrs, then has_variadics is true? + // TODO: assert that if has variadic outer attrs, then has_variadics is + // true? } // Copy constructor with clone ExternalFunctionItem (ExternalFunctionItem const &other) - : outer_attrs (other.outer_attrs), visibility (other.visibility), item_name (other.item_name), - locus (other.locus), where_clause (other.where_clause), + : outer_attrs (other.outer_attrs), visibility (other.visibility), + item_name (other.item_name), locus (other.locus), + where_clause (other.where_clause), function_params (other.function_params), - has_variadics (other.has_variadics), variadic_outer_attrs (other.variadic_outer_attrs) + has_variadics (other.has_variadics), + variadic_outer_attrs (other.variadic_outer_attrs) { // guard to prevent null pointer dereference if (other.return_type != nullptr) @@ -3872,20 +4095,34 @@ public: std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } - std::vector<NamedFunctionParam> &get_function_params () { return function_params; } - const std::vector<NamedFunctionParam> &get_function_params () const { return function_params; } + std::vector<NamedFunctionParam> &get_function_params () + { + return function_params; + } + const std::vector<NamedFunctionParam> &get_function_params () const + { + return function_params; + } - std::vector<std::unique_ptr<GenericParam> > &get_generic_params () { return generic_params; } - const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const { return generic_params; } + std::vector<std::unique_ptr<GenericParam> > &get_generic_params () + { + return generic_params; + } + const std::vector<std::unique_ptr<GenericParam> > &get_generic_params () const + { + return generic_params; + } // TODO: is this better? Or is a "vis_block" better? - WhereClause &get_where_clause () { + WhereClause &get_where_clause () + { rust_assert (has_where_clause ()); return where_clause; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } @@ -3909,10 +4146,10 @@ class ExternBlock : public VisItem std::vector<Attribute> inner_attrs; // bool has_extern_items; - std::vector<std::unique_ptr<ExternalItem>> extern_items; + std::vector<std::unique_ptr<ExternalItem> > extern_items; Location locus; - + // TODO: find another way to store this to save memory? bool marked_for_strip = false; @@ -3929,7 +4166,7 @@ public: bool has_abi () const { return !abi.empty (); } ExternBlock (std::string abi, - std::vector<std::unique_ptr<ExternalItem>> extern_items, + std::vector<std::unique_ptr<ExternalItem> > extern_items, Visibility vis, std::vector<Attribute> inner_attrs, std::vector<Attribute> outer_attrs, Location locus) : VisItem (std::move (vis), std::move (outer_attrs)), abi (std::move (abi)), @@ -3976,12 +4213,18 @@ public: bool is_marked_for_strip () const override { return marked_for_strip; } // TODO: think of better way to do this - const std::vector<std::unique_ptr<ExternalItem>>& get_extern_items () const { return extern_items; } - std::vector<std::unique_ptr<ExternalItem>>& get_extern_items () { return extern_items; } + const std::vector<std::unique_ptr<ExternalItem> > &get_extern_items () const + { + return extern_items; + } + std::vector<std::unique_ptr<ExternalItem> > &get_extern_items () + { + return extern_items; + } // TODO: think of better way to do this - const std::vector<Attribute>& get_inner_attrs () const { return inner_attrs; } - std::vector<Attribute>& get_inner_attrs () { return inner_attrs; } + const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; } + std::vector<Attribute> &get_inner_attrs () { return inner_attrs; } protected: /* Use covariance to implement clone function as returning this object diff --git a/gcc/rust/ast/rust-macro.h b/gcc/rust/ast/rust-macro.h index 2a97854..5760392 100644 --- a/gcc/rust/ast/rust-macro.h +++ b/gcc/rust/ast/rust-macro.h @@ -132,8 +132,7 @@ public: {} // Copy constructor with clone - MacroMatchRepetition (MacroMatchRepetition const &other) - : op (other.op) + MacroMatchRepetition (MacroMatchRepetition const &other) : op (other.op) { // guard to protect from null pointer dereference if (other.sep != nullptr) @@ -291,7 +290,7 @@ class MacroRulesDefinition : public MacroItem { std::vector<Attribute> outer_attrs; Identifier rule_name; - // MacroRulesDef rules_def; + // MacroRulesDef rules_def; // only curly without required semicolon at end DelimType delim_type; // MacroRules rules; @@ -363,7 +362,7 @@ protected: { return new MacroInvocation (*this); } - + /* Use covariance to implement clone function as returning this object rather * than base */ MacroInvocation *clone_expr_without_block_impl () const override diff --git a/gcc/rust/ast/rust-path.h b/gcc/rust/ast/rust-path.h index b5d7869..392fc18 100644 --- a/gcc/rust/ast/rust-path.h +++ b/gcc/rust/ast/rust-path.h @@ -101,7 +101,8 @@ public: std::string as_string () const; // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type != nullptr); return type; } @@ -111,7 +112,7 @@ public: struct GenericArgs { std::vector<Lifetime> lifetime_args; - std::vector<std::unique_ptr<Type>> type_args; + std::vector<std::unique_ptr<Type> > type_args; std::vector<GenericArgsBinding> binding_args; Location locus; @@ -124,7 +125,7 @@ public: } GenericArgs (std::vector<Lifetime> lifetime_args, - std::vector<std::unique_ptr<Type>> type_args, + std::vector<std::unique_ptr<Type> > type_args, std::vector<GenericArgsBinding> binding_args, Location locus = Location ()) : lifetime_args (std::move (lifetime_args)), @@ -166,21 +167,17 @@ public: static GenericArgs create_empty () { return GenericArgs (std::vector<Lifetime> (), - std::vector<std::unique_ptr<Type>> (), + std::vector<std::unique_ptr<Type> > (), std::vector<GenericArgsBinding> ()); } std::string as_string () const; // TODO: is this better? Or is a "vis_pattern" better? - std::vector<std::unique_ptr<Type>> &get_type_args () { - return type_args; - } + std::vector<std::unique_ptr<Type> > &get_type_args () { return type_args; } // TODO: is this better? Or is a "vis_pattern" better? - std::vector<GenericArgsBinding> &get_binding_args () { - return binding_args; - } + std::vector<GenericArgsBinding> &get_binding_args () { return binding_args; } }; /* A segment of a path in expression, including an identifier aspect and maybe @@ -213,8 +210,8 @@ public: PathExprSegment (std::string segment_name, Location locus, std::vector<Lifetime> lifetime_args = std::vector<Lifetime> (), - std::vector<std::unique_ptr<Type>> type_args - = std::vector<std::unique_ptr<Type>> (), + std::vector<std::unique_ptr<Type> > type_args + = std::vector<std::unique_ptr<Type> > (), std::vector<GenericArgsBinding> binding_args = std::vector<GenericArgsBinding> ()) : segment_name (PathIdentSegment (std::move (segment_name))), @@ -238,7 +235,8 @@ public: Location get_locus () const { return locus; } // TODO: is this better? Or is a "vis_pattern" better? - GenericArgs &get_generic_args () { + GenericArgs &get_generic_args () + { rust_assert (has_generic_args ()); return generic_args; } @@ -262,7 +260,11 @@ protected: SimplePath convert_to_simple_path (bool with_opening_scope_resolution) const; // Removes all segments of the path. - void remove_all_segments () { segments.clear (); segments.shrink_to_fit (); } + void remove_all_segments () + { + segments.clear (); + segments.shrink_to_fit (); + } public: /* Returns whether the path is a single segment (excluding qualified path @@ -427,7 +429,7 @@ public: TypePathSegmentGeneric (std::string segment_name, bool has_separating_scope_resolution, std::vector<Lifetime> lifetime_args, - std::vector<std::unique_ptr<Type>> type_args, + std::vector<std::unique_ptr<Type> > type_args, std::vector<GenericArgsBinding> binding_args, Location locus) : TypePathSegment (std::move (segment_name), @@ -442,7 +444,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_pattern" better? - GenericArgs &get_generic_args () { + GenericArgs &get_generic_args () + { rust_assert (has_generic_args ()); return generic_args; } @@ -463,7 +466,7 @@ private: /*bool has_inputs; TypePathFnInputs inputs;*/ // inlined from TypePathFnInputs - std::vector<std::unique_ptr<Type>> inputs; + std::vector<std::unique_ptr<Type> > inputs; // bool has_type; std::unique_ptr<Type> return_type; @@ -491,7 +494,7 @@ public: static TypePathFunction create_error () { return TypePathFunction (true); } // Constructor - TypePathFunction (std::vector<std::unique_ptr<Type>> inputs, + TypePathFunction (std::vector<std::unique_ptr<Type> > inputs, std::unique_ptr<Type> type = nullptr) : inputs (std::move (inputs)), return_type (std::move (type)), is_invalid (false) @@ -537,11 +540,15 @@ public: std::string as_string () const; // TODO: this mutable getter seems really dodgy. Think up better way. - const std::vector<std::unique_ptr<Type>> &get_params () const { return inputs; } - std::vector<std::unique_ptr<Type>> &get_params () { return inputs; } + const std::vector<std::unique_ptr<Type> > &get_params () const + { + return inputs; + } + std::vector<std::unique_ptr<Type> > &get_params () { return inputs; } // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Type> &get_return_type () { + std::unique_ptr<Type> &get_return_type () + { rust_assert (has_return_type ()); return return_type; } @@ -578,7 +585,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_pattern" better? - TypePathFunction &get_type_path_function () { + TypePathFunction &get_type_path_function () + { rust_assert (!function_path.is_error ()); return function_path; } @@ -595,7 +603,7 @@ protected: class TypePath : public TypeNoBounds { bool has_opening_scope_resolution; - std::vector<std::unique_ptr<TypePathSegment>> segments; + std::vector<std::unique_ptr<TypePathSegment> > segments; Location locus; protected: @@ -620,12 +628,12 @@ public: // Creates an error state TypePath. static TypePath create_error () { - return TypePath (std::vector<std::unique_ptr<TypePathSegment>> (), + return TypePath (std::vector<std::unique_ptr<TypePathSegment> > (), Location ()); } // Constructor - TypePath (std::vector<std::unique_ptr<TypePathSegment>> segments, + TypePath (std::vector<std::unique_ptr<TypePathSegment> > segments, Location locus, bool has_opening_scope_resolution = false) : has_opening_scope_resolution (has_opening_scope_resolution), segments (std::move (segments)), locus (locus) @@ -673,8 +681,14 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: this seems kinda dodgy - std::vector<std::unique_ptr<TypePathSegment>> &get_segments () { return segments; } - const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const { return segments; } + std::vector<std::unique_ptr<TypePathSegment> > &get_segments () + { + return segments; + } + const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const + { + return segments; + } }; struct QualifiedPathType @@ -744,13 +758,15 @@ public: Location get_locus () const { return locus; } // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (type_to_invoke_on != nullptr); return type_to_invoke_on; } // TODO: is this better? Or is a "vis_pattern" better? - TypePath &get_as_type_path () { + TypePath &get_as_type_path () + { rust_assert (has_as_clause ()); return trait_path; } @@ -795,11 +811,15 @@ public: void accept_vis (ASTVisitor &vis) override; // Invalid if path_type is error, so base stripping on that. - void mark_for_strip () override { path_type = QualifiedPathType::create_error (); } + void mark_for_strip () override + { + path_type = QualifiedPathType::create_error (); + } bool is_marked_for_strip () const override { return is_error (); } // TODO: is this better? Or is a "vis_pattern" better? - QualifiedPathType &get_qualified_path_type () { + QualifiedPathType &get_qualified_path_type () + { rust_assert (!path_type.is_error ()); return path_type; } @@ -825,7 +845,7 @@ protected: class QualifiedPathInType : public TypeNoBounds { QualifiedPathType path_type; - std::vector<std::unique_ptr<TypePathSegment>> segments; + std::vector<std::unique_ptr<TypePathSegment> > segments; Location locus; protected: @@ -839,7 +859,7 @@ protected: public: QualifiedPathInType ( QualifiedPathType qual_path_type, - std::vector<std::unique_ptr<TypePathSegment>> path_segments, + std::vector<std::unique_ptr<TypePathSegment> > path_segments, Location locus = Location ()) : path_type (std::move (qual_path_type)), segments (std::move (path_segments)), locus (locus) @@ -882,7 +902,7 @@ public: { return QualifiedPathInType ( QualifiedPathType::create_error (), - std::vector<std::unique_ptr<TypePathSegment>> ()); + std::vector<std::unique_ptr<TypePathSegment> > ()); } std::string as_string () const override; @@ -890,14 +910,21 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_pattern" better? - QualifiedPathType &get_qualified_path_type () { + QualifiedPathType &get_qualified_path_type () + { rust_assert (!path_type.is_error ()); return path_type; } // TODO: this seems kinda dodgy - std::vector<std::unique_ptr<TypePathSegment>> &get_segments () { return segments; } - const std::vector<std::unique_ptr<TypePathSegment>> &get_segments () const { return segments; } + std::vector<std::unique_ptr<TypePathSegment> > &get_segments () + { + return segments; + } + const std::vector<std::unique_ptr<TypePathSegment> > &get_segments () const + { + return segments; + } Location get_locus () const { return locus; } Location get_locus_slow () const final override { return get_locus (); } diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h index 5ae68ab..3a87a83 100644 --- a/gcc/rust/ast/rust-pattern.h +++ b/gcc/rust/ast/rust-pattern.h @@ -94,7 +94,7 @@ public: // fix to prevent null pointer dereference if (other.to_bind != nullptr) to_bind = other.to_bind->clone_pattern (); - else + else to_bind = nullptr; return *this; @@ -110,12 +110,13 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Pattern> &get_pattern_to_bind () { + std::unique_ptr<Pattern> &get_pattern_to_bind () + { rust_assert (has_pattern_to_bind ()); return to_bind; } - Identifier get_ident() const { return variable_ident; } + Identifier get_ident () const { return variable_ident; } protected: /* Use covariance to implement clone function as returning this object rather @@ -319,12 +320,14 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? or is a "vis_bound" better? - std::unique_ptr<RangePatternBound>& get_lower_bound () { + std::unique_ptr<RangePatternBound> &get_lower_bound () + { rust_assert (lower != nullptr); return lower; } - std::unique_ptr<RangePatternBound>& get_upper_bound () { + std::unique_ptr<RangePatternBound> &get_upper_bound () + { rust_assert (upper != nullptr); return upper; } @@ -382,7 +385,8 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Pattern> &get_referenced_pattern () { + std::unique_ptr<Pattern> &get_referenced_pattern () + { rust_assert (pattern != nullptr); return pattern; } @@ -508,10 +512,14 @@ public: // based on idea of tuple pattern no longer existing void mark_for_strip () override { tuple_pattern = nullptr; } - bool is_marked_for_strip () const override { return tuple_pattern == nullptr; } + bool is_marked_for_strip () const override + { + return tuple_pattern == nullptr; + } // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Pattern> &get_index_pattern () { + std::unique_ptr<Pattern> &get_index_pattern () + { rust_assert (tuple_pattern != nullptr); return tuple_pattern; } @@ -577,10 +585,14 @@ public: // based on idea of identifier pattern no longer existing void mark_for_strip () override { ident_pattern = nullptr; } - bool is_marked_for_strip () const override { return ident_pattern == nullptr; } + bool is_marked_for_strip () const override + { + return ident_pattern == nullptr; + } // TODO: is this better? Or is a "vis_pattern" better? - std::unique_ptr<Pattern> &get_ident_pattern () { + std::unique_ptr<Pattern> &get_ident_pattern () + { rust_assert (ident_pattern != nullptr); return ident_pattern; } @@ -630,11 +642,11 @@ struct StructPatternElements { private: // bool has_struct_pattern_fields; - std::vector<std::unique_ptr<StructPatternField>> fields; + std::vector<std::unique_ptr<StructPatternField> > fields; bool has_struct_pattern_etc; std::vector<Attribute> struct_pattern_etc_attrs; - //StructPatternEtc etc; + // StructPatternEtc etc; // must have at least one of the two and maybe both @@ -655,7 +667,7 @@ public: // Constructor for StructPatternElements with both (potentially) StructPatternElements ( - std::vector<std::unique_ptr<StructPatternField>> fields, + std::vector<std::unique_ptr<StructPatternField> > fields, std::vector<Attribute> etc_attrs) : fields (std::move (fields)), has_struct_pattern_etc (true), struct_pattern_etc_attrs (std::move (etc_attrs)) @@ -663,14 +675,15 @@ public: // Constructor for StructPatternElements with no StructPatternEtc StructPatternElements ( - std::vector<std::unique_ptr<StructPatternField>> fields) + std::vector<std::unique_ptr<StructPatternField> > fields) : fields (std::move (fields)), has_struct_pattern_etc (false), struct_pattern_etc_attrs () {} // Copy constructor with vector clone StructPatternElements (StructPatternElements const &other) - : has_struct_pattern_etc (other.has_struct_pattern_etc), struct_pattern_etc_attrs (other.struct_pattern_etc_attrs) + : has_struct_pattern_etc (other.has_struct_pattern_etc), + struct_pattern_etc_attrs (other.struct_pattern_etc_attrs) { fields.reserve (other.fields.size ()); for (const auto &e : other.fields) @@ -698,21 +711,35 @@ public: static StructPatternElements create_empty () { return StructPatternElements ( - std::vector<std::unique_ptr<StructPatternField>> ()); + std::vector<std::unique_ptr<StructPatternField> > ()); } std::string as_string () const; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<StructPatternField>> &get_struct_pattern_fields () { return fields; } - const std::vector<std::unique_ptr<StructPatternField>> &get_struct_pattern_fields () const { return fields; } + std::vector<std::unique_ptr<StructPatternField> > & + get_struct_pattern_fields () + { + return fields; + } + const std::vector<std::unique_ptr<StructPatternField> > & + get_struct_pattern_fields () const + { + return fields; + } - std::vector<Attribute> &get_etc_outer_attrs () { return struct_pattern_etc_attrs; } - const std::vector<Attribute> &get_etc_outer_attrs () const { return struct_pattern_etc_attrs; } + std::vector<Attribute> &get_etc_outer_attrs () + { + return struct_pattern_etc_attrs; + } + const std::vector<Attribute> &get_etc_outer_attrs () const + { + return struct_pattern_etc_attrs; + } - void strip_etc () - { - has_struct_pattern_etc = false; + void strip_etc () + { + has_struct_pattern_etc = false; struct_pattern_etc_attrs.clear (); struct_pattern_etc_attrs.shrink_to_fit (); } @@ -752,7 +779,10 @@ public: // TODO: seems kinda dodgy. Think of better way. StructPatternElements &get_struct_pattern_elems () { return elems; } - const StructPatternElements &get_struct_pattern_elems () const { return elems; } + const StructPatternElements &get_struct_pattern_elems () const + { + return elems; + } PathInExpression &get_path () { return path; } const PathInExpression &get_path () const { return path; } @@ -792,10 +822,10 @@ protected: // Class for non-ranged tuple struct pattern patterns class TupleStructItemsNoRange : public TupleStructItems { - std::vector<std::unique_ptr<Pattern>> patterns; + std::vector<std::unique_ptr<Pattern> > patterns; public: - TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern>> patterns) + TupleStructItemsNoRange (std::vector<std::unique_ptr<Pattern> > patterns) : patterns (std::move (patterns)) {} @@ -827,8 +857,11 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { return patterns; } + std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; } + const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + { + return patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -842,12 +875,12 @@ protected: // Class for ranged tuple struct pattern patterns class TupleStructItemsRange : public TupleStructItems { - std::vector<std::unique_ptr<Pattern>> lower_patterns; - std::vector<std::unique_ptr<Pattern>> upper_patterns; + std::vector<std::unique_ptr<Pattern> > lower_patterns; + std::vector<std::unique_ptr<Pattern> > upper_patterns; public: - TupleStructItemsRange (std::vector<std::unique_ptr<Pattern>> lower_patterns, - std::vector<std::unique_ptr<Pattern>> upper_patterns) + TupleStructItemsRange (std::vector<std::unique_ptr<Pattern> > lower_patterns, + std::vector<std::unique_ptr<Pattern> > upper_patterns) : lower_patterns (std::move (lower_patterns)), upper_patterns (std::move (upper_patterns)) {} @@ -887,12 +920,24 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () { return lower_patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const { return lower_patterns; } + std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () + { + return lower_patterns; + } + const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const + { + return lower_patterns; + } // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () { return upper_patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const { return upper_patterns; } + std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () + { + return upper_patterns; + } + const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const + { + return upper_patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -924,8 +969,7 @@ public: {} // Copy constructor required to clone - TupleStructPattern (TupleStructPattern const &other) - : path (other.path) + TupleStructPattern (TupleStructPattern const &other) : path (other.path) { // guard to protect from null dereference if (other.items != nullptr) @@ -956,10 +1000,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::unique_ptr<TupleStructItems> &get_items () - { + std::unique_ptr<TupleStructItems> &get_items () + { rust_assert (has_items ()); - return items; + return items; } PathInExpression &get_path () { return path; } @@ -1036,10 +1080,10 @@ TuplePatternItemsSingle(*this); // Class representing TuplePattern patterns where there are multiple patterns class TuplePatternItemsMultiple : public TuplePatternItems { - std::vector<std::unique_ptr<Pattern>> patterns; + std::vector<std::unique_ptr<Pattern> > patterns; public: - TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern>> patterns) + TuplePatternItemsMultiple (std::vector<std::unique_ptr<Pattern> > patterns) : patterns (std::move (patterns)) {} @@ -1071,8 +1115,11 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_patterns () { return patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_patterns () const { return patterns; } + std::vector<std::unique_ptr<Pattern> > &get_patterns () { return patterns; } + const std::vector<std::unique_ptr<Pattern> > &get_patterns () const + { + return patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -1086,13 +1133,13 @@ protected: // Class representing TuplePattern patterns where there are a range of patterns class TuplePatternItemsRanged : public TuplePatternItems { - std::vector<std::unique_ptr<Pattern>> lower_patterns; - std::vector<std::unique_ptr<Pattern>> upper_patterns; + std::vector<std::unique_ptr<Pattern> > lower_patterns; + std::vector<std::unique_ptr<Pattern> > upper_patterns; public: TuplePatternItemsRanged ( - std::vector<std::unique_ptr<Pattern>> lower_patterns, - std::vector<std::unique_ptr<Pattern>> upper_patterns) + std::vector<std::unique_ptr<Pattern> > lower_patterns, + std::vector<std::unique_ptr<Pattern> > upper_patterns) : lower_patterns (std::move (lower_patterns)), upper_patterns (std::move (upper_patterns)) {} @@ -1133,12 +1180,24 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () { return lower_patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const { return lower_patterns; } + std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () + { + return lower_patterns; + } + const std::vector<std::unique_ptr<Pattern> > &get_lower_patterns () const + { + return lower_patterns; + } // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () { return upper_patterns; } - const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const { return upper_patterns; } + std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () + { + return upper_patterns; + } + const std::vector<std::unique_ptr<Pattern> > &get_upper_patterns () const + { + return upper_patterns; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -1167,8 +1226,7 @@ public: {} // Copy constructor requires clone - TuplePattern (TuplePattern const &other) - : locus (other.locus) + TuplePattern (TuplePattern const &other) : locus (other.locus) { // guard to prevent null dereference if (other.items != nullptr) @@ -1195,10 +1253,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::unique_ptr<TuplePatternItems> &get_items () - { + std::unique_ptr<TuplePatternItems> &get_items () + { rust_assert (has_tuple_pattern_items ()); - return items; + return items; } protected: @@ -1251,10 +1309,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::unique_ptr<Pattern> &get_pattern_in_parens () - { + std::unique_ptr<Pattern> &get_pattern_in_parens () + { rust_assert (pattern_in_parens != nullptr); - return pattern_in_parens; + return pattern_in_parens; } protected: @@ -1269,13 +1327,13 @@ protected: // AST node representing patterns that can match slices and arrays class SlicePattern : public Pattern { - std::vector<std::unique_ptr<Pattern>> items; + std::vector<std::unique_ptr<Pattern> > items; Location locus; public: std::string as_string () const override; - SlicePattern (std::vector<std::unique_ptr<Pattern>> items, Location locus) + SlicePattern (std::vector<std::unique_ptr<Pattern> > items, Location locus) : items (std::move (items)), locus (locus) {} @@ -1309,8 +1367,11 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: seems kinda dodgy. Think of better way. - std::vector<std::unique_ptr<Pattern>> &get_items () { return items; } - const std::vector<std::unique_ptr<Pattern>> &get_items () const { return items; } + std::vector<std::unique_ptr<Pattern> > &get_items () { return items; } + const std::vector<std::unique_ptr<Pattern> > &get_items () const + { + return items; + } protected: /* Use covariance to implement clone function as returning this object rather diff --git a/gcc/rust/ast/rust-stmt.h b/gcc/rust/ast/rust-stmt.h index 88be256..faea905 100644 --- a/gcc/rust/ast/rust-stmt.h +++ b/gcc/rust/ast/rust-stmt.h @@ -80,7 +80,7 @@ public: // guard to prevent null dereference (only required if error state) if (other.variables_pattern != nullptr) variables_pattern = other.variables_pattern->clone_pattern (); - + // guard to prevent null dereference (always required) if (other.init_expr != nullptr) init_expr = other.init_expr->clone_expr (); @@ -99,7 +99,7 @@ public: variables_pattern = other.variables_pattern->clone_pattern (); else variables_pattern = nullptr; - + // guard to prevent null dereference (always required) if (other.init_expr != nullptr) init_expr = other.init_expr->clone_expr (); @@ -123,24 +123,30 @@ public: // Invalid if pattern is null, so base stripping on that. void mark_for_strip () override { variables_pattern = nullptr; } - bool is_marked_for_strip () const override { return variables_pattern == nullptr; } + bool is_marked_for_strip () const override + { + return variables_pattern == nullptr; + } // TODO: this mutable getter seems really dodgy. Think up better way. std::vector<Attribute> &get_outer_attrs () { return outer_attrs; } const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<Expr> &get_init_expr () { + std::unique_ptr<Expr> &get_init_expr () + { rust_assert (has_init_expr ()); return init_expr; } - std::unique_ptr<Pattern> &get_pattern () { + std::unique_ptr<Pattern> &get_pattern () + { rust_assert (variables_pattern != nullptr); return variables_pattern; } - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (has_type ()); return type; } @@ -188,8 +194,7 @@ public: {}*/ // Copy constructor with clone - ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other) - : ExprStmt (other) + ExprStmtWithoutBlock (ExprStmtWithoutBlock const &other) : ExprStmt (other) { // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) @@ -203,7 +208,7 @@ public: ExprStmtWithoutBlock &operator= (ExprStmtWithoutBlock const &other) { ExprStmt::operator= (other); - //expr = other.expr->clone_expr (); + // expr = other.expr->clone_expr (); // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) @@ -225,7 +230,8 @@ public: bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<ExprWithoutBlock> &get_expr () { + std::unique_ptr<ExprWithoutBlock> &get_expr () + { rust_assert (expr != nullptr); return expr; } @@ -254,8 +260,7 @@ public: {} // Copy constructor with clone - ExprStmtWithBlock (ExprStmtWithBlock const &other) - : ExprStmt (other) + ExprStmtWithBlock (ExprStmtWithBlock const &other) : ExprStmt (other) { // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) @@ -266,7 +271,7 @@ public: ExprStmtWithBlock &operator= (ExprStmtWithBlock const &other) { ExprStmt::operator= (other); - + // guard to prevent null dereference (only required if error state) if (other.expr != nullptr) expr = other.expr->clone_expr_with_block (); @@ -287,7 +292,8 @@ public: bool is_marked_for_strip () const override { return expr == nullptr; } // TODO: is this better? Or is a "vis_block" better? - std::unique_ptr<ExprWithBlock> &get_expr () { + std::unique_ptr<ExprWithBlock> &get_expr () + { rust_assert (expr != nullptr); return expr; } diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index 4351017..8c175d3 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -115,8 +115,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: mutable getter seems kinda dodgy - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } }; // An opaque value of another type that implements a set of traits @@ -178,8 +185,15 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: mutable getter seems kinda dodgy - std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () { return type_param_bounds; } - const std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () const { return type_param_bounds; } + std::vector<std::unique_ptr<TypeParamBound> > &get_type_param_bounds () + { + return type_param_bounds; + } + const std::vector<std::unique_ptr<TypeParamBound> > & + get_type_param_bounds () const + { + return type_param_bounds; + } }; // A type with parentheses around it, used to avoid ambiguity. @@ -240,9 +254,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - std::unique_ptr<Type> &get_type_in_parens () { + std::unique_ptr<Type> &get_type_in_parens () + { rust_assert (type_in_parens != nullptr); - return type_in_parens; + return type_in_parens; } }; @@ -273,9 +288,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - TraitBound &get_trait_bound () { + TraitBound &get_trait_bound () + { // TODO: check to ensure invariants are met? - return trait_bound; + return trait_bound; } }; @@ -318,9 +334,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - TraitBound &get_trait_bound () { + TraitBound &get_trait_bound () + { // TODO: check to ensure invariants are met? - return trait_bound; + return trait_bound; } }; @@ -374,7 +391,10 @@ public: // TODO: mutable getter seems kinda dodgy std::vector<std::unique_ptr<Type> > &get_elems () { return elems; } - const std::vector<std::unique_ptr<Type> > &get_elems () const { return elems; } + const std::vector<std::unique_ptr<Type> > &get_elems () const + { + return elems; + } protected: /* Use covariance to implement clone function as returning this object rather @@ -464,9 +484,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - std::unique_ptr<TypeNoBounds> &get_type_pointed_to () { + std::unique_ptr<TypeNoBounds> &get_type_pointed_to () + { rust_assert (type != nullptr); - return type; + return type; } protected: @@ -531,9 +552,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - std::unique_ptr<TypeNoBounds> &get_type_referenced () { + std::unique_ptr<TypeNoBounds> &get_type_referenced () + { rust_assert (type != nullptr); - return type; + return type; } protected: @@ -586,15 +608,17 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - std::unique_ptr<Type> &get_elem_type () { + std::unique_ptr<Type> &get_elem_type () + { rust_assert (elem_type != nullptr); - return elem_type; + return elem_type; } // TODO: would a "vis_expr" be better? - std::unique_ptr<Expr> &get_size_expr () { + std::unique_ptr<Expr> &get_size_expr () + { rust_assert (size != nullptr); - return size; + return size; } protected: @@ -645,9 +669,10 @@ public: void accept_vis (ASTVisitor &vis) override; // TODO: would a "vis_type" be better? - std::unique_ptr<Type> &get_elem_type () { + std::unique_ptr<Type> &get_elem_type () + { rust_assert (elem_type != nullptr); - return elem_type; + return elem_type; } protected: @@ -710,14 +735,17 @@ private: public: MaybeNamedParam (Identifier name, ParamKind param_kind, - std::unique_ptr<Type> param_type, std::vector<Attribute> outer_attrs, Location locus) - : outer_attrs (std::move (outer_attrs)), param_type (std::move (param_type)), param_kind (param_kind), + std::unique_ptr<Type> param_type, + std::vector<Attribute> outer_attrs, Location locus) + : outer_attrs (std::move (outer_attrs)), + param_type (std::move (param_type)), param_kind (param_kind), name (std::move (name)), locus (locus) {} // Copy constructor with clone MaybeNamedParam (MaybeNamedParam const &other) - : outer_attrs (other.outer_attrs), param_kind (other.param_kind), name (other.name), locus (other.locus) + : outer_attrs (other.outer_attrs), param_kind (other.param_kind), + name (other.name), locus (other.locus) { // guard to prevent null dereference if (other.param_type != nullptr) @@ -765,9 +793,10 @@ public: const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; } // TODO: would a "vis_type" be better? - std::unique_ptr<Type> &get_type () { + std::unique_ptr<Type> &get_type () + { rust_assert (param_type != nullptr); - return param_type; + return param_type; } }; @@ -799,14 +828,16 @@ public: BareFunctionType (std::vector<LifetimeParam> lifetime_params, FunctionQualifiers qualifiers, - std::vector<MaybeNamedParam> named_params, bool is_variadic, std::vector<Attribute> variadic_attrs, + std::vector<MaybeNamedParam> named_params, bool is_variadic, + std::vector<Attribute> variadic_attrs, std::unique_ptr<TypeNoBounds> type, Location locus) : for_lifetimes (std::move (lifetime_params)), function_qualifiers (std::move (qualifiers)), params (std::move (named_params)), is_variadic (is_variadic), - variadic_attrs (std::move (variadic_attrs)), return_type (std::move (type)), locus (locus) + variadic_attrs (std::move (variadic_attrs)), + return_type (std::move (type)), locus (locus) { - if (!variadic_attrs.empty()) + if (!variadic_attrs.empty ()) is_variadic = true; } @@ -814,7 +845,8 @@ public: BareFunctionType (BareFunctionType const &other) : for_lifetimes (other.for_lifetimes), function_qualifiers (other.function_qualifiers), params (other.params), - is_variadic (other.is_variadic), variadic_attrs (other.variadic_attrs), locus (other.locus) + is_variadic (other.is_variadic), variadic_attrs (other.variadic_attrs), + locus (other.locus) { // guard to prevent null dereference if (other.return_type != nullptr) @@ -853,12 +885,16 @@ public: // TODO: this mutable getter seems kinda dodgy std::vector<MaybeNamedParam> &get_function_params () { return params; } - const std::vector<MaybeNamedParam> &get_function_params () const { return params; } + const std::vector<MaybeNamedParam> &get_function_params () const + { + return params; + } // TODO: would a "vis_type" be better? - std::unique_ptr<TypeNoBounds> &get_return_type () { + std::unique_ptr<TypeNoBounds> &get_return_type () + { rust_assert (has_return_type ()); - return return_type; + return return_type; } protected: diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index 95fb962..82941c7 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -5,2870 +5,3388 @@ #include "rust-diagnostics.h" namespace Rust { - // Visitor used to expand attributes. - class AttrVisitor : public AST::ASTVisitor { - private: - MacroExpander& expander; - - public: - AttrVisitor(MacroExpander& expander) : expander(expander) {} - - void expand_struct_fields(std::vector<AST::StructField>& fields) { - for (int i = 0; i < fields.size();) { - auto& field = fields[i]; - - auto& field_attrs = field.get_outer_attrs(); - expander.expand_cfg_attrs(field_attrs); - if (expander.fails_cfg(field_attrs)) { - fields.erase(fields.begin() + 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 = fields[i]; - - auto& field_attrs = field.get_outer_attrs(); - expander.expand_cfg_attrs(field_attrs); - if (expander.fails_cfg(field_attrs)) { - fields.erase(fields.begin() + 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 = 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; - } - - // 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? - } - void visit(AST::DelimTokenTree& delim_tok_tree) override { - // shouldn't require? - } - void visit(AST::AttrInputMetaItemContainer& input) override { - // shouldn't require? - } - void visit(AST::IdentifierExpr& ident_expr) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(ident_expr.get_outer_attrs()); - if (expander.fails_cfg(ident_expr.get_outer_attrs())) { - ident_expr.mark_for_strip(); - return; - } - } - void visit(AST::Lifetime& lifetime) override { - // shouldn't require? - } - void visit(AST::LifetimeParam& lifetime_param) override { - // supposedly does not require - cfg does nothing - } - void visit(AST::MacroInvocationSemi& macro_invoc) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(macro_invoc.get_outer_attrs()); - if (expander.fails_cfg(macro_invoc.get_outer_attrs())) { - macro_invoc.mark_for_strip(); - 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 { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(path.get_outer_attrs()); - if (expander.fails_cfg(path.get_outer_attrs())) { - 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 - } - void visit(AST::TypePathSegmentGeneric& segment) override { - // TODO: strip inside generic args - - if (!segment.has_generic_args()) - return; - - expand_generic_args(segment.get_generic_args()); - } - void visit(AST::TypePathSegmentFunction& segment) override { - 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 { - // 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 - expander.expand_cfg_attrs(path.get_outer_attrs()); - if (expander.fails_cfg(path.get_outer_attrs())) { - 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 { - 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 { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - } - void visit(AST::AttrInputLiteral& attr_input) override { - // shouldn't require? - } - void visit(AST::MetaItemLitExpr& meta_item) override { - // shouldn't require? - } - void visit(AST::MetaItemPathLit& meta_item) override { - // shouldn't require? - } - void visit(AST::BorrowExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& borrowed_expr = expr.get_borrowed_expr(); - borrowed_expr->accept_vis(*this); - if (borrowed_expr->is_marked_for_strip()) - rust_error_at(borrowed_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::DereferenceExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& dereferenced_expr = expr.get_dereferenced_expr(); - dereferenced_expr->accept_vis(*this); - if (dereferenced_expr->is_marked_for_strip()) - rust_error_at(dereferenced_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ErrorPropagationExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& propagating_expr = expr.get_propagating_expr(); - propagating_expr->accept_vis(*this); - if (propagating_expr->is_marked_for_strip()) - rust_error_at(propagating_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::NegationExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& negated_expr = expr.get_negated_expr(); - negated_expr->accept_vis(*this); - if (negated_expr->is_marked_for_strip()) - rust_error_at(negated_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ArithmeticOrLogicalExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_left_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_right_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_left_expr()->is_marked_for_strip()) - rust_error_at(expr.get_left_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before binary op exprs"); - if (expr.get_right_expr()->is_marked_for_strip()) - rust_error_at(expr.get_right_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ComparisonExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_left_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_right_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_left_expr()->is_marked_for_strip()) - rust_error_at(expr.get_left_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before binary op exprs"); - if (expr.get_right_expr()->is_marked_for_strip()) - rust_error_at(expr.get_right_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::LazyBooleanExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_left_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_right_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_left_expr()->is_marked_for_strip()) - rust_error_at(expr.get_left_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before binary op exprs"); - if (expr.get_right_expr()->is_marked_for_strip()) - rust_error_at(expr.get_right_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::TypeCastExpr& expr) override { - /* 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 */ - casted_expr->accept_vis(*this); - - // ensure that they are not marked for strip - 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 - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_left_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_right_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_left_expr()->is_marked_for_strip()) - rust_error_at(expr.get_left_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before binary op exprs"); - if (expr.get_right_expr()->is_marked_for_strip()) - rust_error_at(expr.get_right_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::CompoundAssignmentExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_left_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_right_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_left_expr()->is_marked_for_strip()) - rust_error_at(expr.get_left_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before binary op exprs"); - if (expr.get_right_expr()->is_marked_for_strip()) - rust_error_at(expr.get_right_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::GroupedExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - if (expander.fails_cfg(expr.get_inner_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& inner_expr = expr.get_expr_in_parens(); - inner_expr->accept_vis(*this); - if (inner_expr->is_marked_for_strip()) - rust_error_at(inner_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ArrayElemsValues& elems) override { - /* apparently outer attributes are allowed in "elements of array - * expressions" according to spec */ - auto& values = elems.get_values(); - for (int i = 0; i < values.size();) { - auto& value = values[i]; - - // mark for stripping if required - value->accept_vis(*this); - - if (value->is_marked_for_strip()) - values.erase(values.begin() + i); - else - i++; - } - } - void visit(AST::ArrayElemsCopied& elems) override { - /* apparently outer attributes are allowed in "elements of array - * expressions" according to spec. on the other hand, it would not - * make conceptual sense to be able to remove either expression. As - * such, not implementing. TODO clear up the ambiguity here */ - - // only intend stripping for internal sub-expressions - auto& copied_expr = elems.get_elem_to_copy(); - copied_expr->accept_vis(*this); - if (copied_expr->is_marked_for_strip()) - rust_error_at(copied_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - auto& copy_count = elems.get_num_copies(); - copy_count->accept_vis(*this); - if (copy_count->is_marked_for_strip()) - rust_error_at(copy_count->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ArrayExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says there are separate - * inner attributes, not just outer attributes of inner exprs */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - if (expander.fails_cfg(expr.get_inner_attrs())) { - expr.mark_for_strip(); - return; - } - - /* assuming you can't strip away the ArrayElems type, but can strip - * internal expressions and whatever */ - if (expr.has_array_elems()) - expr.get_array_elems()->accept_vis(*this); - } - void visit(AST::ArrayIndexExpr& expr) override { - /* it is unclear whether outer attributes are supposed to be - * allowed, but conceptually it wouldn't make much sense, but - * having expansion code anyway. TODO */ - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& array_expr = expr.get_array_expr(); - array_expr->accept_vis(*this); - if (array_expr->is_marked_for_strip()) - rust_error_at(array_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - auto& index_expr = expr.get_index_expr(); - index_expr->accept_vis(*this); - if (index_expr->is_marked_for_strip()) - rust_error_at(index_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::TupleExpr& expr) override { - /* according to spec, outer attributes are allowed on "elements of - * tuple expressions" */ - - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - if (expander.fails_cfg(expr.get_inner_attrs())) { - expr.mark_for_strip(); - return; - } - - /* apparently outer attributes are allowed in "elements of tuple - * expressions" according to spec */ - auto& values = expr.get_tuple_elems(); - for (int i = 0; i < values.size();) { - auto& value = values[i]; - - // mark for stripping if required - value->accept_vis(*this); - - if (value->is_marked_for_strip()) - values.erase(values.begin() + i); - else - i++; - } - } - void visit(AST::TupleIndexExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* wouldn't strip this directly (as outer attrs should be - * associated with this level), but any sub-expressions would be - * stripped. Thus, no need to erase when strip check called. */ - auto& tuple_expr = expr.get_tuple_expr(); - tuple_expr->accept_vis(*this); - if (tuple_expr->is_marked_for_strip()) - rust_error_at(tuple_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::StructExprStruct& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - 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"); - } - void visit(AST::StructExprFieldIdentifier& field) override { - // as no attrs (at moment, at least), no stripping possible - } - void visit(AST::StructExprFieldIdentifierValue& field) override { - /* as no attrs possible (at moment, at least), only sub-expression - * stripping is possible */ - auto& value = field.get_value(); - value->accept_vis(*this); - if (value->is_marked_for_strip()) - rust_error_at(value->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::StructExprFieldIndexValue& field) override { - /* as no attrs possible (at moment, at least), only sub-expression - * stripping is possible */ - auto& value = field.get_value(); - value->accept_vis(*this); - if (value->is_marked_for_strip()) - rust_error_at(value->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::StructExprStructFields& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - 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 - * that they would be, so operating under the assumption that only - * sub-expressions can be stripped. */ - for (auto& field : expr.get_fields()) { - field->accept_vis(*this); - // shouldn't strip in this - } - - /* struct base presumably can't be stripped, as the '..' is before - * the expression. as such, can only strip sub-expressions. */ - if (expr.has_struct_base()) { - auto& base_struct_expr = expr.get_struct_base().get_base_struct(); - base_struct_expr->accept_vis(*this); - if (base_struct_expr->is_marked_for_strip()) - rust_error_at(base_struct_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - } - void visit(AST::StructExprStructBase& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - 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"); - - /* 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()); - auto& base_struct_expr = expr.get_struct_base().get_base_struct(); - base_struct_expr->accept_vis(*this); - if (base_struct_expr->is_marked_for_strip()) - rust_error_at(base_struct_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::StructExprTuple& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says these are inner - * attributes, not outer attributes of inner expr */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - 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 says outer attributes are specifically allowed for elements - * of tuple-style struct expressions, so full stripping possible */ - auto& values = expr.get_elems(); - for (int i = 0; i < values.size();) { - auto& value = values[i]; - - // mark for stripping if required - value->accept_vis(*this); - - if (value->is_marked_for_strip()) - values.erase(values.begin() + i); - else - i++; - } - } - void visit(AST::StructExprUnit& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_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"); - } - void visit(AST::EnumExprFieldIdentifier& field) override { - // as no attrs (at moment, at least), no stripping possible - } - void visit(AST::EnumExprFieldIdentifierValue& field) override { - /* as no attrs possible (at moment, at least), only sub-expression - * stripping is possible */ - auto& value = field.get_value(); - value->accept_vis(*this); - if (value->is_marked_for_strip()) - rust_error_at(value->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::EnumExprFieldIndexValue& field) override { - /* as no attrs possible (at moment, at least), only sub-expression - * stripping is possible */ - auto& value = field.get_value(); - value->accept_vis(*this); - if (value->is_marked_for_strip()) - rust_error_at(value->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::EnumExprStruct& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // 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 - * sub-expressions can be stripped. */ - for (auto& field : expr.get_fields()) { - field->accept_vis(*this); - // shouldn't strip in this - } - } - void visit(AST::EnumExprTuple& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // 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(); - for (int i = 0; i < values.size();) { - auto& value = values[i]; - - // mark for stripping if required - value->accept_vis(*this); - - if (value->is_marked_for_strip()) - values.erase(values.begin() + i); - else - i++; - } - } - 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 - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* should not be outer attrs on "function" expression - outer attrs - * should be associated with call expr as a whole. only sub-expr - * expansion is possible. */ - auto& function = expr.get_function_expr(); - function->accept_vis(*this); - if (function->is_marked_for_strip()) - rust_error_at(function->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - /* spec says outer attributes are specifically allowed for elements - * of call expressions, so full stripping possible */ - auto& params = expr.get_params(); - for (int i = 0; i < params.size();) { - auto& param = params[i]; - - // mark for stripping if required - param->accept_vis(*this); - - if (param->is_marked_for_strip()) - params.erase(params.begin() + i); - else - i++; - } - } - void visit(AST::MethodCallExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* should not be outer attrs on "receiver" expression - outer attrs - * should be associated with call expr as a whole. only sub-expr - * expansion is possible. */ - auto& receiver = expr.get_receiver_expr(); - receiver->accept_vis(*this); - if (receiver->is_marked_for_strip()) - rust_error_at(receiver->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - 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 */ - auto& params = expr.get_params(); - for (int i = 0; i < params.size();) { - auto& param = params[i]; - - // mark for stripping if required - param->accept_vis(*this); - - if (param->is_marked_for_strip()) - params.erase(params.begin() + i); - else - i++; - } - } - void visit(AST::FieldAccessExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* should not be outer attrs on "receiver" expression - outer attrs - * should be associated with field expr as a whole. only sub-expr - * expansion is possible. */ - auto& receiver = expr.get_receiver_expr(); - receiver->accept_vis(*this); - if (receiver->is_marked_for_strip()) - rust_error_at(receiver->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ClosureExprInner& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip closure parameters if required - this is specifically - * allowed by spec */ - expand_closure_params(expr.get_params()); - - // can't strip expression itself, but can strip sub-expressions - auto& definition_expr = expr.get_definition_expr(); - definition_expr->accept_vis(*this); - if (definition_expr->is_marked_for_strip()) - rust_error_at(definition_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::BlockExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip test based on inner attrs - spec says there are inner - * attributes, not just outer attributes of inner stmts */ - expander.expand_cfg_attrs(expr.get_inner_attrs()); - if (expander.fails_cfg(expr.get_inner_attrs())) { - expr.mark_for_strip(); - return; - } - - // strip all statements - auto& stmts = expr.get_statements(); - for (int i = 0; i < stmts.size();) { - auto& stmt = stmts[i]; - - // mark for stripping if required - stmt->accept_vis(*this); - - if (stmt->is_marked_for_strip()) - stmts.erase(stmts.begin() + i); - else - i++; - } - - // strip tail expression if exists - can actually fully remove it - if (expr.has_tail_expr()) { - auto& tail_expr = expr.get_tail_expr(); - - tail_expr->accept_vis(*this); - - if (tail_expr->is_marked_for_strip()) - expr.strip_tail_expr(); - } - } - void visit(AST::ClosureExprInnerTyped& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* strip closure parameters if required - this is specifically - * allowed by spec */ - 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(); - definition_block->accept_vis(*this); - if (definition_block->is_marked_for_strip()) - rust_error_at(definition_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::ContinueExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - } - void visit(AST::BreakExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* spec does not say that you can have outer attributes on - * expression, so assuming you can't. stripping for sub-expressions - * is the only thing that can be done */ - if (expr.has_break_expr()) { - auto& break_expr = expr.get_break_expr(); - - break_expr->accept_vis(*this); - - if (break_expr->is_marked_for_strip()) - rust_error_at(break_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - } - void visit(AST::RangeFromToExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_from_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_to_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_from_expr()->is_marked_for_strip()) - rust_error_at(expr.get_from_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before range exprs"); - if (expr.get_to_expr()->is_marked_for_strip()) - rust_error_at(expr.get_to_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::RangeFromExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * direct descendant expression, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - auto& from_expr = expr.get_from_expr(); - - from_expr->accept_vis(*this); - - if (from_expr->is_marked_for_strip()) - rust_error_at(from_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before range exprs"); - } - void visit(AST::RangeToExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * direct descendant expression, can strip ones below that */ - - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - auto& to_expr = expr.get_to_expr(); - - to_expr->accept_vis(*this); - - if (to_expr->is_marked_for_strip()) - rust_error_at(to_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::RangeFullExpr& expr) override { - // outer attributes never allowed before these, so no stripping - } - void visit(AST::RangeFromToInclExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * two direct descendant expressions, can strip ones below that */ - - /* should have no possibility for outer attrs as would be parsed - * with outer expr */ - expr.get_from_expr()->accept_vis(*this); - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - expr.get_to_expr()->accept_vis(*this); - - // ensure that they are not marked for strip - if (expr.get_from_expr()->is_marked_for_strip()) - rust_error_at(expr.get_from_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes are never allowed before range exprs"); - if (expr.get_to_expr()->is_marked_for_strip()) - rust_error_at(expr.get_to_expr()->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::RangeToInclExpr& expr) override { - /* outer attributes never allowed before these. while cannot strip - * direct descendant expression, can strip ones below that */ - - /* should syntactically not have outer attributes, though this may - * not have worked in practice */ - auto& to_expr = expr.get_to_expr(); - - to_expr->accept_vis(*this); - - if (to_expr->is_marked_for_strip()) - rust_error_at(to_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::ReturnExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* spec does not say that you can have outer attributes on - * expression, so assuming you can't. stripping for sub-expressions - * is the only thing that can be done */ - if (expr.has_returned_expr()) { - auto& returned_expr = expr.get_returned_expr(); - - returned_expr->accept_vis(*this); - - if (returned_expr->is_marked_for_strip()) - rust_error_at(returned_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - /* TODO: conceptually, you would maybe be able to remove a returned - * expr - e.g. if you had conditional compilation returning void or - * returning a type. On the other hand, I think that function - * return type cannot be conditionally compiled, so I assumed you - * can't do this either. */ - } - void visit(AST::UnsafeBlockExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip block itself, but can strip sub-expressions - auto& block_expr = expr.get_block_expr(); - block_expr->accept_vis(*this); - if (block_expr->is_marked_for_strip()) - rust_error_at(block_expr->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::LoopExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip block itself, but can strip sub-expressions - auto& loop_block = expr.get_loop_block(); - loop_block->accept_vis(*this); - if (loop_block->is_marked_for_strip()) - rust_error_at(loop_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::WhileLoopExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip predicate expr itself, but can strip sub-expressions - auto& predicate_expr = expr.get_predicate_expr(); - predicate_expr->accept_vis(*this); - if (predicate_expr->is_marked_for_strip()) - rust_error_at(predicate_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip block itself, but can strip sub-expressions - auto& loop_block = expr.get_loop_block(); - loop_block->accept_vis(*this); - if (loop_block->is_marked_for_strip()) - rust_error_at(loop_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::WhileLetLoopExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (scrutinee_expr->is_marked_for_strip()) - rust_error_at(scrutinee_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip block itself, but can strip sub-expressions - auto& loop_block = expr.get_loop_block(); - loop_block->accept_vis(*this); - if (loop_block->is_marked_for_strip()) - rust_error_at(loop_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::ForLoopExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (iterator_expr->is_marked_for_strip()) - rust_error_at(iterator_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip block itself, but can strip sub-expressions - auto& loop_block = expr.get_loop_block(); - loop_block->accept_vis(*this); - if (loop_block->is_marked_for_strip()) - rust_error_at(loop_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::IfExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip condition expr itself, but can strip sub-expressions - auto& condition_expr = expr.get_condition_expr(); - condition_expr->accept_vis(*this); - if (condition_expr->is_marked_for_strip()) - rust_error_at(condition_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::IfExprConseqElse& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip condition expr itself, but can strip sub-expressions - auto& condition_expr = expr.get_condition_expr(); - condition_expr->accept_vis(*this); - if (condition_expr->is_marked_for_strip()) - rust_error_at(condition_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip else block itself, but can strip sub-expressions - auto& else_block = expr.get_else_block(); - else_block->accept_vis(*this); - if (else_block->is_marked_for_strip()) - rust_error_at(else_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::IfExprConseqIf& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip condition expr itself, but can strip sub-expressions - auto& condition_expr = expr.get_condition_expr(); - condition_expr->accept_vis(*this); - if (condition_expr->is_marked_for_strip()) - rust_error_at(condition_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip if expr itself, but can strip sub-expressions - auto& conseq_if_expr = expr.get_conseq_if_expr(); - conseq_if_expr->accept_vis(*this); - if (conseq_if_expr->is_marked_for_strip()) - rust_error_at(conseq_if_expr->get_locus_slow(), - "cannot strip consequent if expression in this position - outer attributes not allowed"); - } - void visit(AST::IfExprConseqIfLet& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip condition expr itself, but can strip sub-expressions - auto& condition_expr = expr.get_condition_expr(); - condition_expr->accept_vis(*this); - if (condition_expr->is_marked_for_strip()) - rust_error_at(condition_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip if let expr itself, but can strip sub-expressions - auto& conseq_if_let_expr = expr.get_conseq_if_let_expr(); - conseq_if_let_expr->accept_vis(*this); - if (conseq_if_let_expr->is_marked_for_strip()) - rust_error_at(conseq_if_let_expr->get_locus_slow(), - "cannot strip consequent if let expression in this position - outer attributes not allowed"); - } - void visit(AST::IfLetExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (value_expr->is_marked_for_strip()) - rust_error_at(value_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::IfLetExprConseqElse& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (value_expr->is_marked_for_strip()) - rust_error_at(value_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip else block itself, but can strip sub-expressions - auto& else_block = expr.get_else_block(); - else_block->accept_vis(*this); - if (else_block->is_marked_for_strip()) - rust_error_at(else_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::IfLetExprConseqIf& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (value_expr->is_marked_for_strip()) - rust_error_at(value_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip if expr itself, but can strip sub-expressions - auto& conseq_if_expr = expr.get_conseq_if_expr(); - conseq_if_expr->accept_vis(*this); - if (conseq_if_expr->is_marked_for_strip()) - rust_error_at(conseq_if_expr->get_locus_slow(), - "cannot strip consequent if expression in this position - outer attributes not allowed"); - } - void visit(AST::IfLetExprConseqIfLet& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - 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); - if (value_expr->is_marked_for_strip()) - rust_error_at(value_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // can't strip if block itself, but can strip sub-expressions - auto& if_block = expr.get_if_block(); - if_block->accept_vis(*this); - if (if_block->is_marked_for_strip()) - rust_error_at(if_block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - - // can't strip if let expr itself, but can strip sub-expressions - auto& conseq_if_let_expr = expr.get_conseq_if_let_expr(); - conseq_if_let_expr->accept_vis(*this); - if (conseq_if_let_expr->is_marked_for_strip()) - rust_error_at(conseq_if_let_expr->get_locus_slow(), - "cannot strip consequent if let expression in this position - outer attributes not allowed"); - } - void visit(AST::MatchExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // inner attr strip test - expander.expand_cfg_attrs(expr.get_inner_attrs()); - if (expander.fails_cfg(expr.get_inner_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip scrutinee expr itself, but can strip sub-expressions - auto& scrutinee_expr = expr.get_scrutinee_expr(); - scrutinee_expr->accept_vis(*this); - if (scrutinee_expr->is_marked_for_strip()) - rust_error_at(scrutinee_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // strip match cases - auto& match_cases = expr.get_match_cases(); - for (int i = 0; i < match_cases.size(); ) { - auto& match_case = match_cases[i]; - - // strip match case based on outer attributes in match arm - auto& match_arm = match_case.get_arm(); - expander.expand_cfg_attrs(match_arm.get_outer_attrs()); - if (expander.fails_cfg(match_arm.get_outer_attrs())) { - // strip match case - match_cases.erase(match_cases.begin() + i); - 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 - * strip sub-expressions */ - if (match_arm.has_match_arm_guard()) { - auto& guard_expr = match_arm.get_guard_expr(); - guard_expr->accept_vis(*this); - if (guard_expr->is_marked_for_strip()) - rust_error_at(guard_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - - // strip sub-expressions from match cases - auto& case_expr = match_case.get_expr(); - case_expr->accept_vis(*this); - if (case_expr->is_marked_for_strip()) - rust_error_at(case_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - - // increment to next case if haven't continued - i++; - } - } - void visit(AST::AwaitExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - /* can't strip awaited expr itself, but can strip sub-expressions - * - this is because you can't have no expr to await */ - auto& awaited_expr = expr.get_awaited_expr(); - awaited_expr->accept_vis(*this); - if (awaited_expr->is_marked_for_strip()) - rust_error_at(awaited_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::AsyncBlockExpr& expr) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(expr.get_outer_attrs()); - if (expander.fails_cfg(expr.get_outer_attrs())) { - expr.mark_for_strip(); - return; - } - - // can't strip block itself, but can strip sub-expressions - auto& block_expr = expr.get_block_expr(); - block_expr->accept_vis(*this); - if (block_expr->is_marked_for_strip()) - rust_error_at(block_expr->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - - void visit(AST::TypeParam& param) override { - // 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 - } - void visit(AST::TypeBoundWhereClauseItem& item) override { - // 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 - expander.expand_cfg_attrs(method.get_outer_attrs()); - if (expander.fails_cfg(method.get_outer_attrs())) { - method.mark_for_strip(); - return; - } - - // just expand sub-stuff - can't actually strip generic params themselves - for (auto& param : method.get_generic_params()) - param->accept_vis(*this); - - /* assuming you can't strip self param - wouldn't be a method - * anymore. spec allows outer attrs on self param, but doesn't - * specify whether cfg is used. */ - 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 - auto& block_expr = method.get_definition(); - block_expr->accept_vis(*this); - if (block_expr->is_marked_for_strip()) - rust_error_at(block_expr->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::ModuleBodied& module) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(module.get_outer_attrs()); - if (expander.fails_cfg(module.get_outer_attrs())) { - module.mark_for_strip(); - return; - } - - // strip test based on inner attrs - expander.expand_cfg_attrs(module.get_inner_attrs()); - if (expander.fails_cfg(module.get_inner_attrs())) { - module.mark_for_strip(); - return; - } - - // strip items if required - auto& items = module.get_items(); - for (int i = 0; i < items.size();) { - auto& item = items[i]; - - // mark for stripping if required - item->accept_vis(*this); - - if (item->is_marked_for_strip()) - items.erase(items.begin() + i); - else - i++; - } - } - void visit(AST::ModuleNoBody& module) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(module.get_outer_attrs()); - if (expander.fails_cfg(module.get_outer_attrs())) { - module.mark_for_strip(); - return; - } - } - void visit(AST::ExternCrate& crate) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(crate.get_outer_attrs()); - if (expander.fails_cfg(crate.get_outer_attrs())) { - crate.mark_for_strip(); - return; - } - } - void visit(AST::UseTreeGlob& use_tree) override { - // shouldn't require? - } - void visit(AST::UseTreeList& use_tree) override { - // shouldn't require? - } - void visit(AST::UseTreeRebind& use_tree) override { - // shouldn't require? - } - void visit(AST::UseDeclaration& use_decl) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(use_decl.get_outer_attrs()); - if (expander.fails_cfg(use_decl.get_outer_attrs())) { - use_decl.mark_for_strip(); - return; - } - } - void visit(AST::Function& function) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(function.get_outer_attrs()); - if (expander.fails_cfg(function.get_outer_attrs())) { - function.mark_for_strip(); - 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 - auto& block_expr = function.get_definition(); - block_expr->accept_vis(*this); - if (block_expr->is_marked_for_strip()) - rust_error_at(block_expr->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - void visit(AST::TypeAlias& type_alias) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(type_alias.get_outer_attrs()); - if (expander.fails_cfg(type_alias.get_outer_attrs())) { - 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 - expander.expand_cfg_attrs(struct_item.get_outer_attrs()); - if (expander.fails_cfg(struct_item.get_outer_attrs())) { - struct_item.mark_for_strip(); - 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()); - } - void visit(AST::TupleStruct& tuple_struct) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(tuple_struct.get_outer_attrs()); - if (expander.fails_cfg(tuple_struct.get_outer_attrs())) { - tuple_struct.mark_for_strip(); - 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 - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - } - void visit(AST::EnumItemTuple& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - - /* strip item fields if required - this is presumably - * allowed by spec */ - expand_tuple_fields(item.get_tuple_fields()); - } - void visit(AST::EnumItemStruct& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - - /* strip item fields if required - this is presumably - * allowed by spec */ - expand_struct_fields(item.get_struct_fields()); - } - void visit(AST::EnumItemDiscriminant& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& expr = item.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) - rust_error_at(expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::Enum& enum_item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(enum_item.get_outer_attrs()); - if (expander.fails_cfg(enum_item.get_outer_attrs())) { - enum_item.mark_for_strip(); - 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(); - for (int i = 0; i < variants.size();) { - auto& variant = variants[i]; - - // mark for stripping if required - variant->accept_vis(*this); - - if (variant->is_marked_for_strip()) - variants.erase(variants.begin() + i); - else - i++; - } - } - void visit(AST::Union& union_item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(union_item.get_outer_attrs()); - if (expander.fails_cfg(union_item.get_outer_attrs())) { - union_item.mark_for_strip(); - 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()); - } - void visit(AST::ConstantItem& const_item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(const_item.get_outer_attrs()); - if (expander.fails_cfg(const_item.get_outer_attrs())) { - const_item.mark_for_strip(); - 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. */ - auto& expr = const_item.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) - rust_error_at(expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::StaticItem& static_item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(static_item.get_outer_attrs()); - if (expander.fails_cfg(static_item.get_outer_attrs())) { - static_item.mark_for_strip(); - 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. */ - auto& expr = static_item.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) - rust_error_at(expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - void visit(AST::TraitItemFunc& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - - expand_trait_function_decl(item.get_trait_function_decl()); - - if (item.has_definition()) { - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& block = item.get_definition(); - block->accept_vis(*this); - if (block->is_marked_for_strip()) - rust_error_at(block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - } - void visit(AST::TraitItemMethod& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - return; - } - - expand_trait_method_decl(item.get_trait_method_decl()); - - if (item.has_definition()) { - /* strip any internal sub-expressions - expression itself isn't - * allowed to have external attributes in this position so can't be - * stripped. */ - auto& block = item.get_definition(); - block->accept_vis(*this); - if (block->is_marked_for_strip()) - rust_error_at(block->get_locus_slow(), - "cannot strip block expression in this position - outer attributes not allowed"); - } - } - void visit(AST::TraitItemConst& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - 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 */ - if (item.has_expression()) { - auto& expr = item.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) - rust_error_at(expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - } - void visit(AST::TraitItemType& item) override { - // initial test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - 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 - expander.expand_cfg_attrs(trait.get_outer_attrs()); - if (expander.fails_cfg(trait.get_outer_attrs())) { - trait.mark_for_strip(); - return; - } - - // strip test based on inner attrs - expander.expand_cfg_attrs(trait.get_inner_attrs()); - if (expander.fails_cfg(trait.get_inner_attrs())) { - trait.mark_for_strip(); - 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();) { - auto& item = trait_items[i]; - - // mark for stripping if required - item->accept_vis(*this); - - if (item->is_marked_for_strip()) - trait_items.erase(trait_items.begin() + i); - else - i++; - } - } - void visit(AST::InherentImpl& impl) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(impl.get_outer_attrs()); - if (expander.fails_cfg(impl.get_outer_attrs())) { - impl.mark_for_strip(); - return; - } - - // strip test based on inner attrs - expander.expand_cfg_attrs(impl.get_inner_attrs()); - if (expander.fails_cfg(impl.get_inner_attrs())) { - impl.mark_for_strip(); - 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();) { - auto& item = impl_items[i]; - - // mark for stripping if required - item->accept_vis(*this); - - if (item->is_marked_for_strip()) - impl_items.erase(impl_items.begin() + i); - else - i++; - } - } - void visit(AST::TraitImpl& impl) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(impl.get_outer_attrs()); - if (expander.fails_cfg(impl.get_outer_attrs())) { - impl.mark_for_strip(); - return; - } - - // strip test based on inner attrs - expander.expand_cfg_attrs(impl.get_inner_attrs()); - if (expander.fails_cfg(impl.get_inner_attrs())) { - impl.mark_for_strip(); - 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();) { - auto& item = impl_items[i]; - - // mark for stripping if required - item->accept_vis(*this); - - if (item->is_marked_for_strip()) - impl_items.erase(impl_items.begin() + i); - else - i++; - } - } - void visit(AST::ExternalStaticItem& item) override { - // strip test based on outer attrs - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - 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 - expander.expand_cfg_attrs(item.get_outer_attrs()); - if (expander.fails_cfg(item.get_outer_attrs())) { - item.mark_for_strip(); - 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 = 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& 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 - * handled separately. */ - - /* 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 - expander.expand_cfg_attrs(block.get_outer_attrs()); - if (expander.fails_cfg(block.get_outer_attrs())) { - block.mark_for_strip(); - return; - } - - // strip test based on inner attrs - expander.expand_cfg_attrs(block.get_inner_attrs()); - if (expander.fails_cfg(block.get_inner_attrs())) { - block.mark_for_strip(); - return; - } - - // strip external items if required - auto& extern_items = block.get_extern_items(); - for (int i = 0; i < extern_items.size();) { - auto& item = extern_items[i]; - - // mark for stripping if required - item->accept_vis(*this); - - if (item->is_marked_for_strip()) - extern_items.erase(extern_items.begin() + i); - else - i++; - } - } - - // I don't think it would be possible to strip macros without expansion - void visit(AST::MacroMatchFragment& match) override {} - void visit(AST::MacroMatchRepetition& match) override {} - void visit(AST::MacroMatcher& matcher) override {} - void visit(AST::MacroRulesDefinition& rules_def) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(rules_def.get_outer_attrs()); - if (expander.fails_cfg(rules_def.get_outer_attrs())) { - rules_def.mark_for_strip(); - return; - } - - // I don't think any macro rules can be stripped in any way - } - void visit(AST::MacroInvocation& macro_invoc) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(macro_invoc.get_outer_attrs()); - if (expander.fails_cfg(macro_invoc.get_outer_attrs())) { - macro_invoc.mark_for_strip(); - return; - } - - // 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 {} - void visit(AST::MetaWord& meta_item) override {} - void visit(AST::MetaNameValueStr& meta_item) override {} - void visit(AST::MetaListPaths& meta_item) override {} - void visit(AST::MetaListNameValueStr& meta_item) 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 { - // can expand path, but not strip it directly - auto& path = bound.get_path(); - visit(path); - if (path.is_marked_for_strip()) - rust_error_at(path.get_locus(), "cannot strip path in this position"); - } - void visit(AST::RangePatternBoundQualPath& bound) override { - // can expand path, but not strip it directly - auto& path = bound.get_qualified_path(); - visit(path); - if (path.is_marked_for_strip()) - rust_error_at(path.get_locus(), "cannot strip path in this position"); - } - void visit(AST::RangePattern& pattern) override { - // should have no capability to strip lower or upper bounds, only expand - pattern.get_lower_bound()->accept_vis(*this); - pattern.get_upper_bound()->accept_vis(*this); - } - 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 { - // expand (but don't strip) path - auto& path = pattern.get_path(); - visit(path); - if (path.is_marked_for_strip()) - rust_error_at(path.get_locus(), "cannot strip path in this position"); - - // 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 { - // expand (but don't strip) path - auto& path = pattern.get_path(); - visit(path); - if (path.is_marked_for_strip()) - rust_error_at(path.get_locus(), "cannot strip path in this position"); - - 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::EmptyStmt& stmt) override { - // assuming no outer attributes, so nothing can happen - } - void visit(AST::LetStmt& stmt) override { - // initial strip test based on outer attrs - expander.expand_cfg_attrs(stmt.get_outer_attrs()); - if (expander.fails_cfg(stmt.get_outer_attrs())) { - stmt.mark_for_strip(); - 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"); - - // similar for type - if (stmt.has_type()) { - auto& type = stmt.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 */ - if (stmt.has_init_expr()) { - auto& init_expr = stmt.get_init_expr(); - init_expr->accept_vis(*this); - if (init_expr->is_marked_for_strip()) - rust_error_at(init_expr->get_locus_slow(), - "cannot strip expression in this position - outer attributes not allowed"); - } - } - void visit(AST::ExprStmtWithoutBlock& stmt) override { - // outer attributes associated with expr, so rely on expr - - // guard - should prevent null pointer expr - if (stmt.is_marked_for_strip()) - return; - - // strip if expr is to be stripped - auto& expr = stmt.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) { - stmt.mark_for_strip(); - return; - } - } - void visit(AST::ExprStmtWithBlock& stmt) override { - // outer attributes associated with expr, so rely on expr - - // guard - should prevent null pointer expr - if (stmt.is_marked_for_strip()) - return; - - // strip if expr is to be stripped - auto& expr = stmt.get_expr(); - expr->accept_vis(*this); - if (expr->is_marked_for_strip()) { - stmt.mark_for_strip(); - return; - } - } - - void visit(AST::TraitBound& bound) override { - // nothing in for lifetimes to strip - - // expand but don't strip type path - auto& path = bound.get_type_path(); - visit(path); - if (path.is_marked_for_strip()) - rust_error_at(path.get_locus(), "cannot strip type path in this position"); - } - void visit(AST::ImplTraitType& type) override { - // don't strip directly, only components of bounds - for (auto& bound : type.get_type_param_bounds()) - bound->accept_vis(*this); - } - void visit(AST::TraitObjectType& type) override { - // don't strip directly, only components of bounds - for (auto& bound : type.get_type_param_bounds()) - bound->accept_vis(*this); - } - void visit(AST::ParenthesisedType& type) override { - // expand but don't strip inner type - auto& inner_type = type.get_type_in_parens(); - inner_type->accept_vis(*this); - if (inner_type->is_marked_for_strip()) - rust_error_at(inner_type->get_locus_slow(), "cannot strip type in this position"); - } - void visit(AST::ImplTraitTypeOneBound& type) override { - // no stripping possible - visit(type.get_trait_bound()); - } - void visit(AST::TraitObjectTypeOneBound& type) override { - // no stripping possible - visit(type.get_trait_bound()); - } - void visit(AST::TupleType& type) override { - // TODO: assuming that types can't be stripped as types don't have outer attributes - for (auto& elem_type : type.get_elems()) { - elem_type->accept_vis(*this); - if (elem_type->is_marked_for_strip()) - rust_error_at(elem_type->get_locus_slow(), "cannot strip type in this position"); - } - } - void visit(AST::NeverType& type) override { - // no stripping possible - } - void visit(AST::RawPointerType& type) override { - // expand but don't strip type pointed to - auto& pointed_type = type.get_type_pointed_to(); - pointed_type->accept_vis(*this); - if (pointed_type->is_marked_for_strip()) - rust_error_at(pointed_type->get_locus_slow(), "cannot strip type in this position"); - } - void visit(AST::ReferenceType& type) override { - // expand but don't strip type referenced - auto& referenced_type = type.get_type_referenced(); - referenced_type->accept_vis(*this); - if (referenced_type->is_marked_for_strip()) - rust_error_at(referenced_type->get_locus_slow(), "cannot strip type in this position"); - } - void visit(AST::ArrayType& type) override { - // expand but don't strip type referenced - auto& base_type = type.get_elem_type(); - base_type->accept_vis(*this); - if (base_type->is_marked_for_strip()) - rust_error_at(base_type->get_locus_slow(), "cannot strip type in this position"); - - // same for expression - auto& size_expr = type.get_size_expr(); - size_expr->accept_vis(*this); - if (size_expr->is_marked_for_strip()) - rust_error_at(size_expr->get_locus_slow(), "cannot strip expression in this position"); - } - void visit(AST::SliceType& type) override { - // expand but don't strip elem type - auto& elem_type = type.get_elem_type(); - elem_type->accept_vis(*this); - if (elem_type->is_marked_for_strip()) - rust_error_at(elem_type->get_locus_slow(), "cannot strip type in this position"); - } - void visit(AST::InferredType& type) override { - // none possible - } - void visit(AST::BareFunctionType& type) override { - // seem to be no generics - - // presumably function params can be stripped - auto& params = type.get_function_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& 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++; - } - - /* TODO: assuming that variadic nature cannot be stripped. If this - * is not true, then have code here to do so. */ - - if (type.has_return_type()) { - auto& return_type = type.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"); - } - - // no where clause, apparently - } - }; - - void MacroExpander::expand_invoc(std::unique_ptr<AST::MacroInvocation>& invoc) { - /* if current expansion depth > recursion limit, create an error (maybe fatal - * error) and return */ - - /* switch on type of macro: - - '!' syntax macro (inner switch) - - procedural macro - "A token-based function-like macro" - - 'macro_rules' (by example/pattern-match) macro? or not? "an - AST-based function-like macro" - - else is unreachable - - attribute syntax macro (inner switch) - - procedural macro attribute syntax - "A token-based attribute macro" - - legacy macro attribute syntax? - "an AST-based attribute macro" - - non-macro attribute: mark known - - else is unreachable - - derive macro (inner switch) - - derive or legacy derive - "token-based" vs "AST-based" - - else is unreachable - - derive container macro - unreachable*/ +// Visitor used to expand attributes. +class AttrVisitor : public AST::ASTVisitor +{ +private: + MacroExpander &expander; + +public: + AttrVisitor (MacroExpander &expander) : expander (expander) {} + + void expand_struct_fields (std::vector<AST::StructField> &fields) + { + for (int i = 0; i < fields.size ();) + { + auto &field = fields[i]; + + auto &field_attrs = field.get_outer_attrs (); + expander.expand_cfg_attrs (field_attrs); + if (expander.fails_cfg (field_attrs)) + { + fields.erase (fields.begin () + 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 = fields[i]; + + auto &field_attrs = field.get_outer_attrs (); + expander.expand_cfg_attrs (field_attrs); + if (expander.fails_cfg (field_attrs)) + { + fields.erase (fields.begin () + 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> ¶ms) + { + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + auto ¶m_attrs = param.get_outer_attrs (); + expander.expand_cfg_attrs (param_attrs); + if (expander.fails_cfg (param_attrs)) + { + params.erase (params.begin () + 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> ¶ms) + { + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + auto ¶m_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 ¶m : 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 ¶m : 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? + } + void visit (AST::DelimTokenTree &delim_tok_tree) override + { + // shouldn't require? + } + void visit (AST::AttrInputMetaItemContainer &input) override + { + // shouldn't require? + } + void visit (AST::IdentifierExpr &ident_expr) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (ident_expr.get_outer_attrs ()); + if (expander.fails_cfg (ident_expr.get_outer_attrs ())) + { + ident_expr.mark_for_strip (); + return; + } + } + void visit (AST::Lifetime &lifetime) override + { + // shouldn't require? + } + void visit (AST::LifetimeParam &lifetime_param) override + { + // supposedly does not require - cfg does nothing + } + void visit (AST::MacroInvocationSemi ¯o_invoc) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); + if (expander.fails_cfg (macro_invoc.get_outer_attrs ())) + { + macro_invoc.mark_for_strip (); + 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 + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (path.get_outer_attrs ()); + if (expander.fails_cfg (path.get_outer_attrs ())) + { + 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 + } + void visit (AST::TypePathSegmentGeneric &segment) override + { + // TODO: strip inside generic args + + if (!segment.has_generic_args ()) + return; + + expand_generic_args (segment.get_generic_args ()); + } + void visit (AST::TypePathSegmentFunction &segment) override + { + 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 + { + // 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 + expander.expand_cfg_attrs (path.get_outer_attrs ()); + if (expander.fails_cfg (path.get_outer_attrs ())) + { + 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 + { + 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 + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + } + void visit (AST::AttrInputLiteral &attr_input) override + { + // shouldn't require? + } + void visit (AST::MetaItemLitExpr &meta_item) override + { + // shouldn't require? + } + void visit (AST::MetaItemPathLit &meta_item) override + { + // shouldn't require? + } + void visit (AST::BorrowExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &borrowed_expr = expr.get_borrowed_expr (); + borrowed_expr->accept_vis (*this); + if (borrowed_expr->is_marked_for_strip ()) + rust_error_at (borrowed_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::DereferenceExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &dereferenced_expr = expr.get_dereferenced_expr (); + dereferenced_expr->accept_vis (*this); + if (dereferenced_expr->is_marked_for_strip ()) + rust_error_at (dereferenced_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ErrorPropagationExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &propagating_expr = expr.get_propagating_expr (); + propagating_expr->accept_vis (*this); + if (propagating_expr->is_marked_for_strip ()) + rust_error_at (propagating_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::NegationExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &negated_expr = expr.get_negated_expr (); + negated_expr->accept_vis (*this); + if (negated_expr->is_marked_for_strip ()) + rust_error_at (negated_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ArithmeticOrLogicalExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_left_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_right_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_left_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_left_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before binary op exprs"); + if (expr.get_right_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_right_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ComparisonExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_left_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_right_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_left_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_left_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before binary op exprs"); + if (expr.get_right_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_right_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::LazyBooleanExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_left_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_right_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_left_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_left_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before binary op exprs"); + if (expr.get_right_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_right_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::TypeCastExpr &expr) override + { + /* 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 */ + casted_expr->accept_vis (*this); + + // ensure that they are not marked for strip + 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 + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_left_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_right_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_left_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_left_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before binary op exprs"); + if (expr.get_right_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_right_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::CompoundAssignmentExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_left_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_right_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_left_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_left_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before binary op exprs"); + if (expr.get_right_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_right_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::GroupedExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + if (expander.fails_cfg (expr.get_inner_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &inner_expr = expr.get_expr_in_parens (); + inner_expr->accept_vis (*this); + if (inner_expr->is_marked_for_strip ()) + rust_error_at (inner_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ArrayElemsValues &elems) override + { + /* apparently outer attributes are allowed in "elements of array + * expressions" according to spec */ + auto &values = elems.get_values (); + for (int i = 0; i < values.size ();) + { + auto &value = values[i]; + + // mark for stripping if required + value->accept_vis (*this); + + if (value->is_marked_for_strip ()) + values.erase (values.begin () + i); + else + i++; + } + } + void visit (AST::ArrayElemsCopied &elems) override + { + /* apparently outer attributes are allowed in "elements of array + * expressions" according to spec. on the other hand, it would not + * make conceptual sense to be able to remove either expression. As + * such, not implementing. TODO clear up the ambiguity here */ + + // only intend stripping for internal sub-expressions + auto &copied_expr = elems.get_elem_to_copy (); + copied_expr->accept_vis (*this); + if (copied_expr->is_marked_for_strip ()) + rust_error_at (copied_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + auto ©_count = elems.get_num_copies (); + copy_count->accept_vis (*this); + if (copy_count->is_marked_for_strip ()) + rust_error_at (copy_count->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ArrayExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says there are separate + * inner attributes, not just outer attributes of inner exprs */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + if (expander.fails_cfg (expr.get_inner_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* assuming you can't strip away the ArrayElems type, but can strip + * internal expressions and whatever */ + if (expr.has_array_elems ()) + expr.get_array_elems ()->accept_vis (*this); + } + void visit (AST::ArrayIndexExpr &expr) override + { + /* it is unclear whether outer attributes are supposed to be + * allowed, but conceptually it wouldn't make much sense, but + * having expansion code anyway. TODO */ + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &array_expr = expr.get_array_expr (); + array_expr->accept_vis (*this); + if (array_expr->is_marked_for_strip ()) + rust_error_at (array_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + auto &index_expr = expr.get_index_expr (); + index_expr->accept_vis (*this); + if (index_expr->is_marked_for_strip ()) + rust_error_at (index_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::TupleExpr &expr) override + { + /* according to spec, outer attributes are allowed on "elements of + * tuple expressions" */ + + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + if (expander.fails_cfg (expr.get_inner_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* apparently outer attributes are allowed in "elements of tuple + * expressions" according to spec */ + auto &values = expr.get_tuple_elems (); + for (int i = 0; i < values.size ();) + { + auto &value = values[i]; + + // mark for stripping if required + value->accept_vis (*this); + + if (value->is_marked_for_strip ()) + values.erase (values.begin () + i); + else + i++; + } + } + void visit (AST::TupleIndexExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* wouldn't strip this directly (as outer attrs should be + * associated with this level), but any sub-expressions would be + * stripped. Thus, no need to erase when strip check called. */ + auto &tuple_expr = expr.get_tuple_expr (); + tuple_expr->accept_vis (*this); + if (tuple_expr->is_marked_for_strip ()) + rust_error_at (tuple_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::StructExprStruct &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + 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"); + } + void visit (AST::StructExprFieldIdentifier &field) override + { + // as no attrs (at moment, at least), no stripping possible + } + void visit (AST::StructExprFieldIdentifierValue &field) override + { + /* as no attrs possible (at moment, at least), only sub-expression + * stripping is possible */ + auto &value = field.get_value (); + value->accept_vis (*this); + if (value->is_marked_for_strip ()) + rust_error_at (value->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::StructExprFieldIndexValue &field) override + { + /* as no attrs possible (at moment, at least), only sub-expression + * stripping is possible */ + auto &value = field.get_value (); + value->accept_vis (*this); + if (value->is_marked_for_strip ()) + rust_error_at (value->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::StructExprStructFields &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + 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 + * that they would be, so operating under the assumption that only + * sub-expressions can be stripped. */ + for (auto &field : expr.get_fields ()) + { + field->accept_vis (*this); + // shouldn't strip in this + } + + /* struct base presumably can't be stripped, as the '..' is before + * the expression. as such, can only strip sub-expressions. */ + if (expr.has_struct_base ()) + { + auto &base_struct_expr = expr.get_struct_base ().get_base_struct (); + base_struct_expr->accept_vis (*this); + if (base_struct_expr->is_marked_for_strip ()) + rust_error_at (base_struct_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + } + void visit (AST::StructExprStructBase &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + 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"); + + /* 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 ()); + auto &base_struct_expr = expr.get_struct_base ().get_base_struct (); + base_struct_expr->accept_vis (*this); + if (base_struct_expr->is_marked_for_strip ()) + rust_error_at (base_struct_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::StructExprTuple &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says these are inner + * attributes, not outer attributes of inner expr */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + 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 says outer attributes are specifically allowed for elements + * of tuple-style struct expressions, so full stripping possible */ + auto &values = expr.get_elems (); + for (int i = 0; i < values.size ();) + { + auto &value = values[i]; + + // mark for stripping if required + value->accept_vis (*this); + + if (value->is_marked_for_strip ()) + values.erase (values.begin () + i); + else + i++; + } + } + void visit (AST::StructExprUnit &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_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"); + } + void visit (AST::EnumExprFieldIdentifier &field) override + { + // as no attrs (at moment, at least), no stripping possible + } + void visit (AST::EnumExprFieldIdentifierValue &field) override + { + /* as no attrs possible (at moment, at least), only sub-expression + * stripping is possible */ + auto &value = field.get_value (); + value->accept_vis (*this); + if (value->is_marked_for_strip ()) + rust_error_at (value->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::EnumExprFieldIndexValue &field) override + { + /* as no attrs possible (at moment, at least), only sub-expression + * stripping is possible */ + auto &value = field.get_value (); + value->accept_vis (*this); + if (value->is_marked_for_strip ()) + rust_error_at (value->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::EnumExprStruct &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // 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 + * sub-expressions can be stripped. */ + for (auto &field : expr.get_fields ()) + { + field->accept_vis (*this); + // shouldn't strip in this + } + } + void visit (AST::EnumExprTuple &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // 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 (); + for (int i = 0; i < values.size ();) + { + auto &value = values[i]; + + // mark for stripping if required + value->accept_vis (*this); + + if (value->is_marked_for_strip ()) + values.erase (values.begin () + i); + else + i++; + } + } + 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 + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* should not be outer attrs on "function" expression - outer attrs + * should be associated with call expr as a whole. only sub-expr + * expansion is possible. */ + auto &function = expr.get_function_expr (); + function->accept_vis (*this); + if (function->is_marked_for_strip ()) + rust_error_at (function->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + /* spec says outer attributes are specifically allowed for elements + * of call expressions, so full stripping possible */ + auto ¶ms = expr.get_params (); + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + // mark for stripping if required + param->accept_vis (*this); + + if (param->is_marked_for_strip ()) + params.erase (params.begin () + i); + else + i++; + } + } + void visit (AST::MethodCallExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* should not be outer attrs on "receiver" expression - outer attrs + * should be associated with call expr as a whole. only sub-expr + * expansion is possible. */ + auto &receiver = expr.get_receiver_expr (); + receiver->accept_vis (*this); + if (receiver->is_marked_for_strip ()) + rust_error_at (receiver->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + 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 */ + auto ¶ms = expr.get_params (); + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + // mark for stripping if required + param->accept_vis (*this); + + if (param->is_marked_for_strip ()) + params.erase (params.begin () + i); + else + i++; + } + } + void visit (AST::FieldAccessExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* should not be outer attrs on "receiver" expression - outer attrs + * should be associated with field expr as a whole. only sub-expr + * expansion is possible. */ + auto &receiver = expr.get_receiver_expr (); + receiver->accept_vis (*this); + if (receiver->is_marked_for_strip ()) + rust_error_at (receiver->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ClosureExprInner &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip closure parameters if required - this is specifically + * allowed by spec */ + expand_closure_params (expr.get_params ()); + + // can't strip expression itself, but can strip sub-expressions + auto &definition_expr = expr.get_definition_expr (); + definition_expr->accept_vis (*this); + if (definition_expr->is_marked_for_strip ()) + rust_error_at (definition_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::BlockExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip test based on inner attrs - spec says there are inner + * attributes, not just outer attributes of inner stmts */ + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + if (expander.fails_cfg (expr.get_inner_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // strip all statements + auto &stmts = expr.get_statements (); + for (int i = 0; i < stmts.size ();) + { + auto &stmt = stmts[i]; + + // mark for stripping if required + stmt->accept_vis (*this); + + if (stmt->is_marked_for_strip ()) + stmts.erase (stmts.begin () + i); + else + i++; + } + + // strip tail expression if exists - can actually fully remove it + if (expr.has_tail_expr ()) + { + auto &tail_expr = expr.get_tail_expr (); + + tail_expr->accept_vis (*this); + + if (tail_expr->is_marked_for_strip ()) + expr.strip_tail_expr (); + } + } + void visit (AST::ClosureExprInnerTyped &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* strip closure parameters if required - this is specifically + * allowed by spec */ + 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 (); + definition_block->accept_vis (*this); + if (definition_block->is_marked_for_strip ()) + rust_error_at (definition_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ContinueExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + } + void visit (AST::BreakExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* spec does not say that you can have outer attributes on + * expression, so assuming you can't. stripping for sub-expressions + * is the only thing that can be done */ + if (expr.has_break_expr ()) + { + auto &break_expr = expr.get_break_expr (); + + break_expr->accept_vis (*this); + + if (break_expr->is_marked_for_strip ()) + rust_error_at (break_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + } + void visit (AST::RangeFromToExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_from_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_to_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_from_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_from_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before range exprs"); + if (expr.get_to_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_to_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::RangeFromExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * direct descendant expression, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + auto &from_expr = expr.get_from_expr (); + + from_expr->accept_vis (*this); + + if (from_expr->is_marked_for_strip ()) + rust_error_at (from_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed before range exprs"); + } + void visit (AST::RangeToExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * direct descendant expression, can strip ones below that */ + + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + auto &to_expr = expr.get_to_expr (); + + to_expr->accept_vis (*this); + + if (to_expr->is_marked_for_strip ()) + rust_error_at (to_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::RangeFullExpr &expr) override + { + // outer attributes never allowed before these, so no stripping + } + void visit (AST::RangeFromToInclExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * two direct descendant expressions, can strip ones below that */ + + /* should have no possibility for outer attrs as would be parsed + * with outer expr */ + expr.get_from_expr ()->accept_vis (*this); + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + expr.get_to_expr ()->accept_vis (*this); + + // ensure that they are not marked for strip + if (expr.get_from_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_from_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes are never allowed " + "before range exprs"); + if (expr.get_to_expr ()->is_marked_for_strip ()) + rust_error_at (expr.get_to_expr ()->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::RangeToInclExpr &expr) override + { + /* outer attributes never allowed before these. while cannot strip + * direct descendant expression, can strip ones below that */ + + /* should syntactically not have outer attributes, though this may + * not have worked in practice */ + auto &to_expr = expr.get_to_expr (); + + to_expr->accept_vis (*this); + + if (to_expr->is_marked_for_strip ()) + rust_error_at (to_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ReturnExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* spec does not say that you can have outer attributes on + * expression, so assuming you can't. stripping for sub-expressions + * is the only thing that can be done */ + if (expr.has_returned_expr ()) + { + auto &returned_expr = expr.get_returned_expr (); + + returned_expr->accept_vis (*this); + + if (returned_expr->is_marked_for_strip ()) + rust_error_at (returned_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + /* TODO: conceptually, you would maybe be able to remove a returned + * expr - e.g. if you had conditional compilation returning void or + * returning a type. On the other hand, I think that function + * return type cannot be conditionally compiled, so I assumed you + * can't do this either. */ + } + void visit (AST::UnsafeBlockExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip block itself, but can strip sub-expressions + auto &block_expr = expr.get_block_expr (); + block_expr->accept_vis (*this); + if (block_expr->is_marked_for_strip ()) + rust_error_at (block_expr->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::LoopExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip block itself, but can strip sub-expressions + auto &loop_block = expr.get_loop_block (); + loop_block->accept_vis (*this); + if (loop_block->is_marked_for_strip ()) + rust_error_at (loop_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::WhileLoopExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip predicate expr itself, but can strip sub-expressions + auto &predicate_expr = expr.get_predicate_expr (); + predicate_expr->accept_vis (*this); + if (predicate_expr->is_marked_for_strip ()) + rust_error_at (predicate_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip block itself, but can strip sub-expressions + auto &loop_block = expr.get_loop_block (); + loop_block->accept_vis (*this); + if (loop_block->is_marked_for_strip ()) + rust_error_at (loop_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::WhileLetLoopExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (scrutinee_expr->is_marked_for_strip ()) + rust_error_at (scrutinee_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip block itself, but can strip sub-expressions + auto &loop_block = expr.get_loop_block (); + loop_block->accept_vis (*this); + if (loop_block->is_marked_for_strip ()) + rust_error_at (loop_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ForLoopExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (iterator_expr->is_marked_for_strip ()) + rust_error_at (iterator_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip block itself, but can strip sub-expressions + auto &loop_block = expr.get_loop_block (); + loop_block->accept_vis (*this); + if (loop_block->is_marked_for_strip ()) + rust_error_at (loop_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::IfExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip condition expr itself, but can strip sub-expressions + auto &condition_expr = expr.get_condition_expr (); + condition_expr->accept_vis (*this); + if (condition_expr->is_marked_for_strip ()) + rust_error_at (condition_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::IfExprConseqElse &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip condition expr itself, but can strip sub-expressions + auto &condition_expr = expr.get_condition_expr (); + condition_expr->accept_vis (*this); + if (condition_expr->is_marked_for_strip ()) + rust_error_at (condition_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip else block itself, but can strip sub-expressions + auto &else_block = expr.get_else_block (); + else_block->accept_vis (*this); + if (else_block->is_marked_for_strip ()) + rust_error_at (else_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::IfExprConseqIf &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip condition expr itself, but can strip sub-expressions + auto &condition_expr = expr.get_condition_expr (); + condition_expr->accept_vis (*this); + if (condition_expr->is_marked_for_strip ()) + rust_error_at (condition_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip if expr itself, but can strip sub-expressions + auto &conseq_if_expr = expr.get_conseq_if_expr (); + conseq_if_expr->accept_vis (*this); + if (conseq_if_expr->is_marked_for_strip ()) + rust_error_at (conseq_if_expr->get_locus_slow (), + "cannot strip consequent if expression in this " + "position - outer attributes not allowed"); + } + void visit (AST::IfExprConseqIfLet &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip condition expr itself, but can strip sub-expressions + auto &condition_expr = expr.get_condition_expr (); + condition_expr->accept_vis (*this); + if (condition_expr->is_marked_for_strip ()) + rust_error_at (condition_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip if let expr itself, but can strip sub-expressions + auto &conseq_if_let_expr = expr.get_conseq_if_let_expr (); + conseq_if_let_expr->accept_vis (*this); + if (conseq_if_let_expr->is_marked_for_strip ()) + rust_error_at (conseq_if_let_expr->get_locus_slow (), + "cannot strip consequent if let expression in this " + "position - outer attributes not " + "allowed"); + } + void visit (AST::IfLetExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (value_expr->is_marked_for_strip ()) + rust_error_at (value_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::IfLetExprConseqElse &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (value_expr->is_marked_for_strip ()) + rust_error_at (value_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip else block itself, but can strip sub-expressions + auto &else_block = expr.get_else_block (); + else_block->accept_vis (*this); + if (else_block->is_marked_for_strip ()) + rust_error_at (else_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::IfLetExprConseqIf &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (value_expr->is_marked_for_strip ()) + rust_error_at (value_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip if expr itself, but can strip sub-expressions + auto &conseq_if_expr = expr.get_conseq_if_expr (); + conseq_if_expr->accept_vis (*this); + if (conseq_if_expr->is_marked_for_strip ()) + rust_error_at (conseq_if_expr->get_locus_slow (), + "cannot strip consequent if expression in this " + "position - outer attributes not allowed"); + } + void visit (AST::IfLetExprConseqIfLet &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + 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); + if (value_expr->is_marked_for_strip ()) + rust_error_at (value_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // can't strip if block itself, but can strip sub-expressions + auto &if_block = expr.get_if_block (); + if_block->accept_vis (*this); + if (if_block->is_marked_for_strip ()) + rust_error_at (if_block->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + + // can't strip if let expr itself, but can strip sub-expressions + auto &conseq_if_let_expr = expr.get_conseq_if_let_expr (); + conseq_if_let_expr->accept_vis (*this); + if (conseq_if_let_expr->is_marked_for_strip ()) + rust_error_at (conseq_if_let_expr->get_locus_slow (), + "cannot strip consequent if let expression in this " + "position - outer attributes not " + "allowed"); + } + void visit (AST::MatchExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // inner attr strip test + expander.expand_cfg_attrs (expr.get_inner_attrs ()); + if (expander.fails_cfg (expr.get_inner_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip scrutinee expr itself, but can strip sub-expressions + auto &scrutinee_expr = expr.get_scrutinee_expr (); + scrutinee_expr->accept_vis (*this); + if (scrutinee_expr->is_marked_for_strip ()) + rust_error_at (scrutinee_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // strip match cases + auto &match_cases = expr.get_match_cases (); + for (int i = 0; i < match_cases.size ();) + { + auto &match_case = match_cases[i]; + + // strip match case based on outer attributes in match arm + auto &match_arm = match_case.get_arm (); + expander.expand_cfg_attrs (match_arm.get_outer_attrs ()); + if (expander.fails_cfg (match_arm.get_outer_attrs ())) + { + // strip match case + match_cases.erase (match_cases.begin () + i); + 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 + * strip sub-expressions */ + if (match_arm.has_match_arm_guard ()) + { + auto &guard_expr = match_arm.get_guard_expr (); + guard_expr->accept_vis (*this); + if (guard_expr->is_marked_for_strip ()) + rust_error_at (guard_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + + // strip sub-expressions from match cases + auto &case_expr = match_case.get_expr (); + case_expr->accept_vis (*this); + if (case_expr->is_marked_for_strip ()) + rust_error_at (case_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + + // increment to next case if haven't continued + i++; + } + } + void visit (AST::AwaitExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + /* can't strip awaited expr itself, but can strip sub-expressions + * - this is because you can't have no expr to await */ + auto &awaited_expr = expr.get_awaited_expr (); + awaited_expr->accept_vis (*this); + if (awaited_expr->is_marked_for_strip ()) + rust_error_at (awaited_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::AsyncBlockExpr &expr) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (expr.get_outer_attrs ()); + if (expander.fails_cfg (expr.get_outer_attrs ())) + { + expr.mark_for_strip (); + return; + } + + // can't strip block itself, but can strip sub-expressions + auto &block_expr = expr.get_block_expr (); + block_expr->accept_vis (*this); + if (block_expr->is_marked_for_strip ()) + rust_error_at (block_expr->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + + void visit (AST::TypeParam ¶m) override + { + // 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 + } + void visit (AST::TypeBoundWhereClauseItem &item) override + { + // 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 + expander.expand_cfg_attrs (method.get_outer_attrs ()); + if (expander.fails_cfg (method.get_outer_attrs ())) + { + method.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 + auto &block_expr = method.get_definition (); + block_expr->accept_vis (*this); + if (block_expr->is_marked_for_strip ()) + rust_error_at (block_expr->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::ModuleBodied &module) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (module.get_outer_attrs ()); + if (expander.fails_cfg (module.get_outer_attrs ())) + { + module.mark_for_strip (); + return; + } + + // strip test based on inner attrs + expander.expand_cfg_attrs (module.get_inner_attrs ()); + if (expander.fails_cfg (module.get_inner_attrs ())) + { + module.mark_for_strip (); + return; + } + + // strip items if required + auto &items = module.get_items (); + for (int i = 0; i < items.size ();) + { + auto &item = items[i]; + + // mark for stripping if required + item->accept_vis (*this); + + if (item->is_marked_for_strip ()) + items.erase (items.begin () + i); + else + i++; + } + } + void visit (AST::ModuleNoBody &module) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (module.get_outer_attrs ()); + if (expander.fails_cfg (module.get_outer_attrs ())) + { + module.mark_for_strip (); + return; + } + } + void visit (AST::ExternCrate &crate) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (crate.get_outer_attrs ()); + if (expander.fails_cfg (crate.get_outer_attrs ())) + { + crate.mark_for_strip (); + return; + } + } + void visit (AST::UseTreeGlob &use_tree) override + { + // shouldn't require? + } + void visit (AST::UseTreeList &use_tree) override + { + // shouldn't require? + } + void visit (AST::UseTreeRebind &use_tree) override + { + // shouldn't require? + } + void visit (AST::UseDeclaration &use_decl) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (use_decl.get_outer_attrs ()); + if (expander.fails_cfg (use_decl.get_outer_attrs ())) + { + use_decl.mark_for_strip (); + return; + } + } + void visit (AST::Function &function) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (function.get_outer_attrs ()); + if (expander.fails_cfg (function.get_outer_attrs ())) + { + function.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 + auto &block_expr = function.get_definition (); + block_expr->accept_vis (*this); + if (block_expr->is_marked_for_strip ()) + rust_error_at (block_expr->get_locus_slow (), + "cannot strip block expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::TypeAlias &type_alias) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (type_alias.get_outer_attrs ()); + if (expander.fails_cfg (type_alias.get_outer_attrs ())) + { + type_alias.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 + expander.expand_cfg_attrs (struct_item.get_outer_attrs ()); + if (expander.fails_cfg (struct_item.get_outer_attrs ())) + { + struct_item.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 ()); + } + void visit (AST::TupleStruct &tuple_struct) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (tuple_struct.get_outer_attrs ()); + if (expander.fails_cfg (tuple_struct.get_outer_attrs ())) + { + tuple_struct.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + } + void visit (AST::EnumItemTuple &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + /* strip item fields if required - this is presumably + * allowed by spec */ + expand_tuple_fields (item.get_tuple_fields ()); + } + void visit (AST::EnumItemStruct &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + /* strip item fields if required - this is presumably + * allowed by spec */ + expand_struct_fields (item.get_struct_fields ()); + } + void visit (AST::EnumItemDiscriminant &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &expr = item.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + rust_error_at (expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::Enum &enum_item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (enum_item.get_outer_attrs ()); + if (expander.fails_cfg (enum_item.get_outer_attrs ())) + { + enum_item.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 (); + for (int i = 0; i < variants.size ();) + { + auto &variant = variants[i]; + + // mark for stripping if required + variant->accept_vis (*this); + + if (variant->is_marked_for_strip ()) + variants.erase (variants.begin () + i); + else + i++; + } + } + void visit (AST::Union &union_item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (union_item.get_outer_attrs ()); + if (expander.fails_cfg (union_item.get_outer_attrs ())) + { + union_item.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 ()); + } + void visit (AST::ConstantItem &const_item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (const_item.get_outer_attrs ()); + if (expander.fails_cfg (const_item.get_outer_attrs ())) + { + const_item.mark_for_strip (); + 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. */ + auto &expr = const_item.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + rust_error_at (expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::StaticItem &static_item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (static_item.get_outer_attrs ()); + if (expander.fails_cfg (static_item.get_outer_attrs ())) + { + static_item.mark_for_strip (); + 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. */ + auto &expr = static_item.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + rust_error_at (expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + void visit (AST::TraitItemFunc &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + expand_trait_function_decl (item.get_trait_function_decl ()); + + if (item.has_definition ()) + { + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &block = item.get_definition (); + block->accept_vis (*this); + if (block->is_marked_for_strip ()) + rust_error_at (block->get_locus_slow (), + "cannot strip block expression in this " + "position - outer attributes not allowed"); + } + } + void visit (AST::TraitItemMethod &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + expand_trait_method_decl (item.get_trait_method_decl ()); + + if (item.has_definition ()) + { + /* strip any internal sub-expressions - expression itself isn't + * allowed to have external attributes in this position so can't be + * stripped. */ + auto &block = item.get_definition (); + block->accept_vis (*this); + if (block->is_marked_for_strip ()) + rust_error_at (block->get_locus_slow (), + "cannot strip block expression in this " + "position - outer attributes not allowed"); + } + } + void visit (AST::TraitItemConst &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + 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 */ + if (item.has_expression ()) + { + auto &expr = item.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + rust_error_at (expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + } + void visit (AST::TraitItemType &item) override + { + // initial test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + 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 + expander.expand_cfg_attrs (trait.get_outer_attrs ()); + if (expander.fails_cfg (trait.get_outer_attrs ())) + { + trait.mark_for_strip (); + return; + } + + // strip test based on inner attrs + expander.expand_cfg_attrs (trait.get_inner_attrs ()); + if (expander.fails_cfg (trait.get_inner_attrs ())) + { + trait.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 ();) + { + auto &item = trait_items[i]; + + // mark for stripping if required + item->accept_vis (*this); + + if (item->is_marked_for_strip ()) + trait_items.erase (trait_items.begin () + i); + else + i++; + } + } + void visit (AST::InherentImpl &impl) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (impl.get_outer_attrs ()); + if (expander.fails_cfg (impl.get_outer_attrs ())) + { + impl.mark_for_strip (); + return; + } + + // strip test based on inner attrs + expander.expand_cfg_attrs (impl.get_inner_attrs ()); + if (expander.fails_cfg (impl.get_inner_attrs ())) + { + impl.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 ();) + { + auto &item = impl_items[i]; + + // mark for stripping if required + item->accept_vis (*this); + + if (item->is_marked_for_strip ()) + impl_items.erase (impl_items.begin () + i); + else + i++; + } + } + void visit (AST::TraitImpl &impl) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (impl.get_outer_attrs ()); + if (expander.fails_cfg (impl.get_outer_attrs ())) + { + impl.mark_for_strip (); + return; + } + + // strip test based on inner attrs + expander.expand_cfg_attrs (impl.get_inner_attrs ()); + if (expander.fails_cfg (impl.get_inner_attrs ())) + { + impl.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : 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 ();) + { + auto &item = impl_items[i]; + + // mark for stripping if required + item->accept_vis (*this); + + if (item->is_marked_for_strip ()) + impl_items.erase (impl_items.begin () + i); + else + i++; + } + } + void visit (AST::ExternalStaticItem &item) override + { + // strip test based on outer attrs + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + 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 + expander.expand_cfg_attrs (item.get_outer_attrs ()); + if (expander.fails_cfg (item.get_outer_attrs ())) + { + item.mark_for_strip (); + return; + } + + // just expand sub-stuff - can't actually strip generic params themselves + for (auto ¶m : item.get_generic_params ()) + param->accept_vis (*this); + + /* strip function parameters if required - this is specifically + * allowed by spec */ + auto ¶ms = item.get_function_params (); + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + auto ¶m_attrs = param.get_outer_attrs (); + expander.expand_cfg_attrs (param_attrs); + if (expander.fails_cfg (param_attrs)) + { + params.erase (params.begin () + 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 + * handled separately. */ + + /* 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 + expander.expand_cfg_attrs (block.get_outer_attrs ()); + if (expander.fails_cfg (block.get_outer_attrs ())) + { + block.mark_for_strip (); + return; + } + + // strip test based on inner attrs + expander.expand_cfg_attrs (block.get_inner_attrs ()); + if (expander.fails_cfg (block.get_inner_attrs ())) + { + block.mark_for_strip (); + return; + } + + // strip external items if required + auto &extern_items = block.get_extern_items (); + for (int i = 0; i < extern_items.size ();) + { + auto &item = extern_items[i]; + + // mark for stripping if required + item->accept_vis (*this); + + if (item->is_marked_for_strip ()) + extern_items.erase (extern_items.begin () + i); + else + i++; + } + } + + // I don't think it would be possible to strip macros without expansion + void visit (AST::MacroMatchFragment &match) override {} + void visit (AST::MacroMatchRepetition &match) override {} + void visit (AST::MacroMatcher &matcher) override {} + void visit (AST::MacroRulesDefinition &rules_def) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (rules_def.get_outer_attrs ()); + if (expander.fails_cfg (rules_def.get_outer_attrs ())) + { + rules_def.mark_for_strip (); + return; + } + + // I don't think any macro rules can be stripped in any way + } + void visit (AST::MacroInvocation ¯o_invoc) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (macro_invoc.get_outer_attrs ()); + if (expander.fails_cfg (macro_invoc.get_outer_attrs ())) + { + macro_invoc.mark_for_strip (); + return; + } + + // 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 {} + void visit (AST::MetaWord &meta_item) override {} + void visit (AST::MetaNameValueStr &meta_item) override {} + void visit (AST::MetaListPaths &meta_item) override {} + void visit (AST::MetaListNameValueStr &meta_item) 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 + { + // can expand path, but not strip it directly + auto &path = bound.get_path (); + visit (path); + if (path.is_marked_for_strip ()) + rust_error_at (path.get_locus (), "cannot strip path in this position"); + } + void visit (AST::RangePatternBoundQualPath &bound) override + { + // can expand path, but not strip it directly + auto &path = bound.get_qualified_path (); + visit (path); + if (path.is_marked_for_strip ()) + rust_error_at (path.get_locus (), "cannot strip path in this position"); + } + void visit (AST::RangePattern &pattern) override + { + // should have no capability to strip lower or upper bounds, only expand + pattern.get_lower_bound ()->accept_vis (*this); + pattern.get_upper_bound ()->accept_vis (*this); + } + 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 + { + // expand (but don't strip) path + auto &path = pattern.get_path (); + visit (path); + if (path.is_marked_for_strip ()) + rust_error_at (path.get_locus (), "cannot strip path in this position"); + + // 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 + { + // expand (but don't strip) path + auto &path = pattern.get_path (); + visit (path); + if (path.is_marked_for_strip ()) + rust_error_at (path.get_locus (), "cannot strip path in this position"); + + 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::EmptyStmt &stmt) override + { + // assuming no outer attributes, so nothing can happen + } + void visit (AST::LetStmt &stmt) override + { + // initial strip test based on outer attrs + expander.expand_cfg_attrs (stmt.get_outer_attrs ()); + if (expander.fails_cfg (stmt.get_outer_attrs ())) + { + stmt.mark_for_strip (); + 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"); + + // similar for type + if (stmt.has_type ()) + { + auto &type = stmt.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 */ + if (stmt.has_init_expr ()) + { + auto &init_expr = stmt.get_init_expr (); + init_expr->accept_vis (*this); + if (init_expr->is_marked_for_strip ()) + rust_error_at (init_expr->get_locus_slow (), + "cannot strip expression in this position - outer " + "attributes not allowed"); + } + } + void visit (AST::ExprStmtWithoutBlock &stmt) override + { + // outer attributes associated with expr, so rely on expr + + // guard - should prevent null pointer expr + if (stmt.is_marked_for_strip ()) + return; + + // strip if expr is to be stripped + auto &expr = stmt.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + { + stmt.mark_for_strip (); + return; + } + } + void visit (AST::ExprStmtWithBlock &stmt) override + { + // outer attributes associated with expr, so rely on expr + + // guard - should prevent null pointer expr + if (stmt.is_marked_for_strip ()) + return; + + // strip if expr is to be stripped + auto &expr = stmt.get_expr (); + expr->accept_vis (*this); + if (expr->is_marked_for_strip ()) + { + stmt.mark_for_strip (); + return; + } + } + + void visit (AST::TraitBound &bound) override + { + // nothing in for lifetimes to strip + + // expand but don't strip type path + auto &path = bound.get_type_path (); + visit (path); + if (path.is_marked_for_strip ()) + rust_error_at (path.get_locus (), + "cannot strip type path in this position"); + } + void visit (AST::ImplTraitType &type) override + { + // don't strip directly, only components of bounds + for (auto &bound : type.get_type_param_bounds ()) + bound->accept_vis (*this); + } + void visit (AST::TraitObjectType &type) override + { + // don't strip directly, only components of bounds + for (auto &bound : type.get_type_param_bounds ()) + bound->accept_vis (*this); + } + void visit (AST::ParenthesisedType &type) override + { + // expand but don't strip inner type + auto &inner_type = type.get_type_in_parens (); + inner_type->accept_vis (*this); + if (inner_type->is_marked_for_strip ()) + rust_error_at (inner_type->get_locus_slow (), + "cannot strip type in this position"); + } + void visit (AST::ImplTraitTypeOneBound &type) override + { + // no stripping possible + visit (type.get_trait_bound ()); + } + void visit (AST::TraitObjectTypeOneBound &type) override + { + // no stripping possible + visit (type.get_trait_bound ()); + } + void visit (AST::TupleType &type) override + { + // TODO: assuming that types can't be stripped as types don't have outer + // attributes + for (auto &elem_type : type.get_elems ()) + { + elem_type->accept_vis (*this); + if (elem_type->is_marked_for_strip ()) + rust_error_at (elem_type->get_locus_slow (), + "cannot strip type in this position"); + } + } + void visit (AST::NeverType &type) override + { + // no stripping possible + } + void visit (AST::RawPointerType &type) override + { + // expand but don't strip type pointed to + auto &pointed_type = type.get_type_pointed_to (); + pointed_type->accept_vis (*this); + if (pointed_type->is_marked_for_strip ()) + rust_error_at (pointed_type->get_locus_slow (), + "cannot strip type in this position"); + } + void visit (AST::ReferenceType &type) override + { + // expand but don't strip type referenced + auto &referenced_type = type.get_type_referenced (); + referenced_type->accept_vis (*this); + if (referenced_type->is_marked_for_strip ()) + rust_error_at (referenced_type->get_locus_slow (), + "cannot strip type in this position"); + } + void visit (AST::ArrayType &type) override + { + // expand but don't strip type referenced + auto &base_type = type.get_elem_type (); + base_type->accept_vis (*this); + if (base_type->is_marked_for_strip ()) + rust_error_at (base_type->get_locus_slow (), + "cannot strip type in this position"); + + // same for expression + auto &size_expr = type.get_size_expr (); + size_expr->accept_vis (*this); + if (size_expr->is_marked_for_strip ()) + rust_error_at (size_expr->get_locus_slow (), + "cannot strip expression in this position"); + } + void visit (AST::SliceType &type) override + { + // expand but don't strip elem type + auto &elem_type = type.get_elem_type (); + elem_type->accept_vis (*this); + if (elem_type->is_marked_for_strip ()) + rust_error_at (elem_type->get_locus_slow (), + "cannot strip type in this position"); + } + void visit (AST::InferredType &type) override + { + // none possible + } + void visit (AST::BareFunctionType &type) override + { + // seem to be no generics + + // presumably function params can be stripped + auto ¶ms = type.get_function_params (); + for (int i = 0; i < params.size ();) + { + auto ¶m = params[i]; + + auto ¶m_attrs = param.get_outer_attrs (); + expander.expand_cfg_attrs (param_attrs); + if (expander.fails_cfg (param_attrs)) + { + params.erase (params.begin () + 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++; + } + + /* TODO: assuming that variadic nature cannot be stripped. If this + * is not true, then have code here to do so. */ + + if (type.has_return_type ()) + { + auto &return_type = type.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"); + } + + // no where clause, apparently + } +}; + +void +MacroExpander::expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc) +{ + /* if current expansion depth > recursion limit, create an error (maybe fatal + * error) and return */ + + /* switch on type of macro: + - '!' syntax macro (inner switch) + - procedural macro - "A token-based function-like macro" + - 'macro_rules' (by example/pattern-match) macro? or not? "an + AST-based function-like macro" + - else is unreachable + - attribute syntax macro (inner switch) + - procedural macro attribute syntax - "A token-based attribute macro" + - legacy macro attribute syntax? - "an AST-based attribute macro" + - non-macro attribute: mark known + - else is unreachable + - derive macro (inner switch) + - derive or legacy derive - "token-based" vs "AST-based" + - else is unreachable + - derive container macro - unreachable*/ +} + +/* Determines whether any cfg predicate is false and hence item with attributes + * should be stripped. */ +bool +MacroExpander::fails_cfg (std::vector<AST::Attribute> &attrs) +{ + for (auto &attr : attrs) + { + if (attr.get_path () == "cfg" && !attr.check_cfg_predicate (session)) + return true; } - - /* Determines whether any cfg predicate is false and hence item with attributes should - * be stripped. */ - bool MacroExpander::fails_cfg(std::vector<AST::Attribute>& attrs) { - for (auto& attr : attrs) { - if (attr.get_path() == "cfg" && !attr.check_cfg_predicate(session)) - return true; - } - return false; + return false; +} + +// Expands cfg_attr attributes. +void +MacroExpander::expand_cfg_attrs (std::vector<AST::Attribute> &attrs) +{ + for (int i = 0; i < attrs.size ();) + { + auto &attr = attrs[i]; + if (attr.get_path () == "cfg_attr") + { + if (attr.check_cfg_predicate (session)) + { + // split off cfg_attr + std::vector<AST::Attribute> new_attrs + = attr.separate_cfg_attrs (); + + // remove attr from vector + attrs.erase (attrs.begin () + i); + + // add new attrs to vector + attrs.insert (attrs.begin () + i, + std::make_move_iterator (new_attrs.begin ()), + std::make_move_iterator (new_attrs.end ())); + } + + /* do something - if feature (first token in tree) is in fact enabled, + * make tokens listed afterwards into attributes. i.e.: for + * [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add + * attributes [wow1] and [wow2] to attribute list. This can also be + * recursive, so check for expanded attributes being recursive and + * possibly recursively call the expand_attrs? */ + } + else + { + i++; + } } - - // Expands cfg_attr attributes. - void MacroExpander::expand_cfg_attrs(std::vector<AST::Attribute>& attrs) { - for (int i = 0; i < attrs.size();) { - auto& attr = attrs[i]; - if (attr.get_path() == "cfg_attr") { - if (attr.check_cfg_predicate(session)) { - // split off cfg_attr - std::vector<AST::Attribute> new_attrs = attr.separate_cfg_attrs(); - - // remove attr from vector - attrs.erase(attrs.begin() + i); - - // add new attrs to vector - attrs.insert(attrs.begin() + i, std::make_move_iterator(new_attrs.begin()), - std::make_move_iterator(new_attrs.end())); - } - - /* do something - if feature (first token in tree) is in fact enabled, - * make tokens listed afterwards into attributes. i.e.: for - * [cfg_attr(feature = "wow", wow1, wow2)], if "wow" is true, then add - * attributes [wow1] and [wow2] to attribute list. This can also be - * recursive, so check for expanded attributes being recursive and - * possibly recursively call the expand_attrs? */ - } else { - i++; - } - } - attrs.shrink_to_fit(); + attrs.shrink_to_fit (); +} + +void +MacroExpander::expand_crate () +{ + /* fill macro/decorator map from init list? not sure where init list comes + * from? */ + + // TODO: does cfg apply for inner attributes? research. + // the apparent answer (from playground test) is yes + + // expand crate cfg_attr attributes + expand_cfg_attrs (crate.inner_attrs); + + if (fails_cfg (crate.inner_attrs)) + { + // basically, delete whole crate + crate.strip_crate (); + // TODO: maybe create warning here? probably not desired behaviour } + // expand module attributes? + + // expand attributes recursively and strip items if required + AttrVisitor attr_visitor (*this); + auto &items = crate.items; + for (int i = 0; i < items.size ();) + { + auto &item = items[i]; + + // mark for stripping if required + item->accept_vis (attr_visitor); + + if (item->is_marked_for_strip ()) + items.erase (items.begin () + i); + else + i++; + } + // TODO: should recursive attribute and macro expansion be done in the same + // transversal? Or in separate ones like currently? - void MacroExpander::expand_crate() { - /* fill macro/decorator map from init list? not sure where init list comes - * from? */ - - // TODO: does cfg apply for inner attributes? research. - // the apparent answer (from playground test) is yes - - // expand crate cfg_attr attributes - expand_cfg_attrs(crate.inner_attrs); - - if (fails_cfg(crate.inner_attrs)) { - // basically, delete whole crate - crate.strip_crate(); - // TODO: maybe create warning here? probably not desired behaviour - } - // expand module attributes? - - // expand attributes recursively and strip items if required - AttrVisitor attr_visitor(*this); - auto& items = crate.items; - for (int i = 0; i < items.size();) { - auto& item = items[i]; - - // mark for stripping if required - item->accept_vis(attr_visitor); - - if (item->is_marked_for_strip()) - items.erase(items.begin() + i); - else - i++; - } - // TODO: should recursive attribute and macro expansion be done in the same transversal? Or in - // separate ones like currently? - - // expand module tree recursively + // expand module tree recursively - // post-process + // post-process - // extract exported macros? - } + // extract exported macros? +} } // namespace Rust diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index a7fe076..c8c7f35 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -27,7 +27,8 @@ struct MacroExpander ExpansionCfg cfg; unsigned int expansion_depth = 0; - MacroExpander (AST::Crate &crate, ExpansionCfg cfg, Session &session) : cfg (cfg), crate (crate), session (session) + MacroExpander (AST::Crate &crate, ExpansionCfg cfg, Session &session) + : cfg (cfg), crate (crate), session (session) {} ~MacroExpander () = default; @@ -40,8 +41,8 @@ struct MacroExpander // should this be public or private? void expand_invoc (std::unique_ptr<AST::MacroInvocation> &invoc); - void expand_cfg_attrs(std::vector<AST::Attribute>& attrs); - bool fails_cfg(std::vector<AST::Attribute>& attr); + void expand_cfg_attrs (std::vector<AST::Attribute> &attrs); + bool fails_cfg (std::vector<AST::Attribute> &attr); /* TODO: make it extend ASTVisitor so that individual items can be accessed * properly? */ diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc index 5da2764..3e573a6 100644 --- a/gcc/rust/rust-session-manager.cc +++ b/gcc/rust/rust-session-manager.cc @@ -630,7 +630,8 @@ Session::injection (AST::Crate &crate) * rustc also has a "quote" macro that is defined differently and is * supposedly not stable so eh. */ /* TODO: actually implement injection of these macros. In particular, derive - * macros, cfg, and test should be prioritised since they seem to be used the most. */ + * macros, cfg, and test should be prioritised since they seem to be used the + * most. */ // crate injection std::vector<std::string> names; |