diff options
Diffstat (limited to 'gcc/rust')
75 files changed, 906 insertions, 746 deletions
diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index cdc6eec..08c52b1 100644 --- a/gcc/rust/ast/rust-ast-builder.cc +++ b/gcc/rust/ast/rust-ast-builder.cc @@ -137,7 +137,7 @@ Builder::tuple (std::vector<std::unique_ptr<Expr>> &&values) const std::unique_ptr<Param> Builder::self_ref_param (bool mutability) const { - return std::make_unique<SelfParam> (Lifetime::error (), mutability, loc); + return std::make_unique<SelfParam> (tl::nullopt, mutability, loc); } std::unique_ptr<Param> @@ -335,9 +335,9 @@ std::unique_ptr<BlockExpr> Builder::block (std::vector<std::unique_ptr<Stmt>> &&stmts, std::unique_ptr<Expr> &&tail_expr) const { - return std::unique_ptr<BlockExpr> ( - new BlockExpr (std::move (stmts), std::move (tail_expr), {}, {}, - LoopLabel::error (), loc, loc)); + return std::unique_ptr<BlockExpr> (new BlockExpr (std::move (stmts), + std::move (tail_expr), {}, + {}, tl::nullopt, loc, loc)); } std::unique_ptr<Expr> diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc index 3297407..8ee6375 100644 --- a/gcc/rust/ast/rust-ast-collector.cc +++ b/gcc/rust/ast/rust-ast-collector.cc @@ -1279,7 +1279,7 @@ TokenCollector::visit (ContinueExpr &expr) { push (Rust::Token::make (CONTINUE, expr.get_locus ())); if (expr.has_label ()) - visit (expr.get_label ()); + visit (expr.get_label_unchecked ()); } void @@ -1287,7 +1287,7 @@ TokenCollector::visit (BreakExpr &expr) { push (Rust::Token::make (BREAK, expr.get_locus ())); if (expr.has_label ()) - visit (expr.get_label ()); + visit (expr.get_label_unchecked ()); if (expr.has_break_expr ()) visit (expr.get_break_expr ()); } diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index ba5f87b..9d524c3 100644 --- a/gcc/rust/ast/rust-ast-visitor.cc +++ b/gcc/rust/ast/rust-ast-visitor.cc @@ -477,7 +477,8 @@ void DefaultASTVisitor::visit (AST::ContinueExpr &expr) { visit_outer_attrs (expr); - visit (expr.get_label ()); + if (expr.has_label ()) + visit (expr.get_label_unchecked ()); } void @@ -485,7 +486,7 @@ DefaultASTVisitor::visit (AST::BreakExpr &expr) { visit_outer_attrs (expr); if (expr.has_label ()) - visit (expr.get_label ()); + visit (expr.get_label_unchecked ()); if (expr.has_break_expr ()) visit (expr.get_break_expr ()); @@ -559,7 +560,8 @@ void DefaultASTVisitor::visit (AST::LoopExpr &expr) { visit_outer_attrs (expr); - visit (expr.get_loop_label ()); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); visit (expr.get_loop_block ()); } @@ -567,8 +569,9 @@ void DefaultASTVisitor::visit (AST::WhileLoopExpr &expr) { visit_outer_attrs (expr); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); visit (expr.get_predicate_expr ()); - visit (expr.get_loop_label ()); visit (expr.get_loop_block ()); } @@ -589,7 +592,8 @@ DefaultASTVisitor::visit (AST::ForLoopExpr &expr) visit_outer_attrs (expr); visit (expr.get_pattern ()); visit (expr.get_iterator_expr ()); - visit (expr.get_loop_label ()); + if (expr.has_loop_label ()) + visit (expr.get_loop_label ()); visit (expr.get_loop_block ()); } @@ -824,8 +828,6 @@ DefaultASTVisitor::visit (AST::Function &function) visit (function.get_qualifiers ()); for (auto &generic : function.get_generic_params ()) visit (generic); - if (function.has_self_param ()) - visit (function.get_self_param ()); for (auto ¶m : function.get_function_params ()) visit (param); if (function.has_return_type ()) diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index ab82303..06e0e7b 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1068,7 +1068,7 @@ Function::Function (Function const &other) : VisItem (other), ExternalItem (other.get_node_id ()), qualifiers (other.qualifiers), function_name (other.function_name), where_clause (other.where_clause), locus (other.locus), - is_default (other.is_default), + has_default (other.has_default), is_external_function (other.is_external_function) { // guard to prevent null dereference (always required) @@ -1100,7 +1100,7 @@ Function::operator= (Function const &other) // visibility = other.visibility->clone_visibility(); // outer_attrs = other.outer_attrs; locus = other.locus; - is_default = other.is_default; + has_default = other.has_default; is_external_function = other.is_external_function; // guard to prevent null dereference (always required) @@ -1631,7 +1631,7 @@ ContinueExpr::as_string () const std::string str ("continue "); if (has_label ()) - str += label.as_string (); + str += get_label_unchecked ().as_string (); return str; } @@ -2095,7 +2095,7 @@ WhileLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Conditional expr: " + condition->as_string (); @@ -2115,7 +2115,7 @@ WhileLetLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Match arm patterns: "; if (match_arm_patterns.empty ()) @@ -2146,7 +2146,7 @@ LoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Loop block: " + loop_block->as_string (); @@ -2183,7 +2183,7 @@ BreakExpr::as_string () const std::string str ("break "); if (has_label ()) - str += label.as_string () + " "; + str += get_label_unchecked ().as_string () + " "; if (has_break_expr ()) str += break_expr->as_string (); @@ -2485,9 +2485,6 @@ MacroMatchRepetition::as_string () const std::string Lifetime::as_string () const { - if (is_error ()) - return "error lifetime"; - switch (lifetime_type) { case NAMED: @@ -2545,7 +2542,7 @@ ForLoopExpr::as_string () const if (!has_loop_label ()) str += "none"; else - str += loop_label.as_string (); + str += get_loop_label ().as_string (); str += "\n Pattern: " + pattern->as_string (); @@ -2612,7 +2609,7 @@ ReferenceType::as_string () const std::string str ("&"); if (has_lifetime ()) - str += lifetime.as_string () + " "; + str += get_lifetime ().as_string () + " "; if (has_mut) str += "mut "; @@ -3070,7 +3067,7 @@ SelfParam::as_string () const else if (has_lifetime ()) { // ref and lifetime - std::string str = "&" + lifetime.as_string () + " "; + std::string str = "&" + get_lifetime ().as_string () + " "; if (is_mut) str += "mut "; diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h index 4d7d23d..09e0fce 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -657,6 +657,9 @@ public: // Returns whether the attribute is considered an "empty" attribute. bool is_empty () const { return attr_input == nullptr && path.is_empty (); } + // Returns whether the attribute has no input + bool empty_input () const { return !attr_input; } + location_t get_locus () const { return locus; } AttrInput &get_attr_input () const { return *attr_input; } @@ -1587,17 +1590,9 @@ public: lifetime_name (std::move (name)), locus (locus) {} - // Creates an "error" lifetime. - static Lifetime error () { return Lifetime (NAMED, ""); } - static Lifetime elided () { return Lifetime (WILDCARD, ""); } // Returns true if the lifetime is in an error state. - bool is_error () const - { - return lifetime_type == NAMED && lifetime_name.empty (); - } - std::string as_string () const override; void accept_vis (ASTVisitor &vis) override; @@ -1688,15 +1683,6 @@ public: // Returns whether the lifetime param has an outer attribute. bool has_outer_attribute () const { return !outer_attrs.empty (); } - // Creates an error state lifetime param. - static LifetimeParam create_error () - { - return LifetimeParam (Lifetime::error (), {}, {}, UNDEF_LOCATION); - } - - // Returns whether the lifetime param is in an error state. - bool is_error () const { return lifetime.is_error (); } - // Constructor LifetimeParam (Lifetime lifetime, std::vector<Lifetime> lifetime_bounds, AST::AttrVec outer_attrs, location_t locus) diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc b/gcc/rust/ast/rust-desugar-for-loops.cc index 5e5cbbc..ffc3470 100644 --- a/gcc/rust/ast/rust-desugar-for-loops.cc +++ b/gcc/rust/ast/rust-desugar-for-loops.cc @@ -59,8 +59,8 @@ DesugarForLoops::DesugarCtx::make_break_arm () auto arm = make_match_arm (std::unique_ptr<Pattern> (new PathInExpression ( builder.path_in_expression (LangItem::Kind::OPTION_NONE)))); - auto break_expr = std::unique_ptr<Expr> ( - new BreakExpr (Lifetime::error (), nullptr, {}, loc)); + auto break_expr + = std::unique_ptr<Expr> (new BreakExpr (tl::nullopt, nullptr, {}, loc)); return MatchCase (std::move (arm), std::move (break_expr)); } diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h index cff09fe..84cdfdb 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -31,11 +31,6 @@ public: {} // Returns whether the LoopLabel is in an error state. - bool is_error () const { return label.is_error (); } - - // Creates an error state LoopLabel. - static LoopLabel error () { return LoopLabel (Lifetime::error ()); } - location_t get_locus () const { return locus; } Lifetime &get_lifetime () { return label; } @@ -2590,7 +2585,7 @@ class BlockExpr : public ExprWithBlock std::vector<Attribute> inner_attrs; std::vector<std::unique_ptr<Stmt> > statements; std::unique_ptr<Expr> expr; - LoopLabel label; + tl::optional<LoopLabel> label; location_t start_locus; location_t end_locus; bool marked_for_strip = false; @@ -2607,8 +2602,9 @@ public: BlockExpr (std::vector<std::unique_ptr<Stmt> > block_statements, std::unique_ptr<Expr> block_expr, std::vector<Attribute> inner_attribs, - std::vector<Attribute> outer_attribs, LoopLabel label, - location_t start_locus, location_t end_locus) + std::vector<Attribute> outer_attribs, + tl::optional<LoopLabel> label, location_t start_locus, + location_t end_locus) : outer_attrs (std::move (outer_attribs)), inner_attrs (std::move (inner_attribs)), statements (std::move (block_statements)), expr (std::move (block_expr)), @@ -2727,8 +2723,8 @@ public: outer_attrs = std::move (new_attrs); } - bool has_label () { return !label.is_error (); } - LoopLabel &get_label () { return label; } + bool has_label () { return label.has_value (); } + LoopLabel &get_label () { return label.value (); } Expr::Kind get_expr_kind () const override { return Expr::Kind::Block; } @@ -2848,7 +2844,7 @@ protected: class ContinueExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; - Lifetime label; + tl::optional<Lifetime> label; location_t locus; // TODO: find another way to store this to save memory? @@ -2858,11 +2854,11 @@ public: std::string as_string () const override; // Returns true if the continue expr has a label. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } // Constructor for a ContinueExpr with a label. - ContinueExpr (Lifetime label, std::vector<Attribute> outer_attribs, - location_t locus) + ContinueExpr (tl::optional<Lifetime> label, + std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), label (std::move (label)), locus (locus) {} @@ -2883,7 +2879,11 @@ public: outer_attrs = std::move (new_attrs); } - Lifetime &get_label () { return label; } + Lifetime &get_label_unchecked () { return label.value (); } + const Lifetime &get_label_unchecked () const { return label.value (); } + + tl::optional<Lifetime> &get_label () { return label; } + const tl::optional<Lifetime> &get_label () const { return label; } Expr::Kind get_expr_kind () const override { return Expr::Kind::Continue; } @@ -2901,7 +2901,7 @@ protected: class BreakExpr : public ExprWithoutBlock { std::vector<Attribute> outer_attrs; - LoopLabel label; + tl::optional<LoopLabel> label; std::unique_ptr<Expr> break_expr; location_t locus; @@ -2912,14 +2912,15 @@ public: std::string as_string () const override; // Returns whether the break expression has a label or not. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } /* Returns whether the break expression has an expression used in the break or * not. */ bool has_break_expr () const { return break_expr != nullptr; } // Constructor for a break expression - BreakExpr (LoopLabel break_label, std::unique_ptr<Expr> expr_in_break, + BreakExpr (tl::optional<LoopLabel> break_label, + std::unique_ptr<Expr> expr_in_break, std::vector<Attribute> outer_attribs, location_t locus) : outer_attrs (std::move (outer_attribs)), label (std::move (break_label)), break_expr (std::move (expr_in_break)), locus (locus) @@ -2981,7 +2982,11 @@ public: outer_attrs = std::move (new_attrs); } - LoopLabel &get_label () { return label; } + LoopLabel &get_label_unchecked () { return label.value (); } + const LoopLabel &get_label_unchecked () const { return label.value (); } + + tl::optional<LoopLabel> &get_label () { return label; } + const tl::optional<LoopLabel> &get_label () const { return label; } Expr::Kind get_expr_kind () const override { return Expr::Kind::Break; } @@ -3657,7 +3662,7 @@ class BaseLoopExpr : public ExprWithBlock protected: // protected to allow subclasses better use of them std::vector<Attribute> outer_attrs; - LoopLabel loop_label; + tl::optional<LoopLabel> loop_label; std::unique_ptr<BlockExpr> loop_block; private: @@ -3666,7 +3671,7 @@ private: protected: // Constructor for BaseLoopExpr BaseLoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : outer_attrs (std::move (outer_attribs)), @@ -3706,9 +3711,10 @@ protected: BaseLoopExpr &operator= (BaseLoopExpr &&other) = default; public: - bool has_loop_label () const { return !loop_label.is_error (); } + bool has_loop_label () const { return loop_label.has_value (); } - LoopLabel &get_loop_label () { return loop_label; } + LoopLabel &get_loop_label () { return loop_label.value (); } + const LoopLabel &get_loop_label () const { return loop_label.value (); } location_t get_locus () const override final { return locus; } @@ -3752,7 +3758,7 @@ public: // Constructor for LoopExpr LoopExpr (std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)) @@ -3785,7 +3791,7 @@ public: // Constructor for while loop with loop label WhileLoopExpr (std::unique_ptr<Expr> loop_condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3851,7 +3857,7 @@ public: WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern> > match_arm_patterns, std::unique_ptr<Expr> scrutinee, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label), @@ -3938,7 +3944,7 @@ public: ForLoopExpr (std::unique_ptr<Pattern> loop_pattern, std::unique_ptr<Expr> iterator_expr, std::unique_ptr<BlockExpr> loop_body, location_t locus, - LoopLabel loop_label = LoopLabel::error (), + tl::optional<LoopLabel> loop_label = tl::nullopt, std::vector<Attribute> outer_attribs = std::vector<Attribute> ()) : BaseLoopExpr (std::move (loop_body), locus, std::move (loop_label), std::move (outer_attribs)), diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 8eb0cc5..062f85d 100644 --- a/gcc/rust/ast/rust-item.h +++ b/gcc/rust/ast/rust-item.h @@ -434,13 +434,14 @@ class SelfParam : public Param bool has_ref; bool is_mut; // bool has_lifetime; // only possible if also ref - Lifetime lifetime; + tl::optional<Lifetime> lifetime; // bool has_type; // only possible if not ref std::unique_ptr<Type> type; // Unrestricted constructor used for error state - SelfParam (Lifetime lifetime, bool has_ref, bool is_mut, Type *type) + SelfParam (tl::optional<Lifetime> lifetime, bool has_ref, bool is_mut, + Type *type) : Param ({}, UNDEF_LOCATION), has_ref (has_ref), is_mut (is_mut), lifetime (std::move (lifetime)), type (type) {} @@ -453,7 +454,7 @@ public: bool has_type () const { return type != nullptr; } // Returns whether the self-param has a valid lifetime. - bool has_lifetime () const { return !lifetime.is_error (); } + bool has_lifetime () const { return lifetime.has_value (); } // Returns whether the self-param is in an error state. bool is_error () const @@ -472,11 +473,11 @@ public: // Type-based self parameter (not ref, no lifetime) SelfParam (std::unique_ptr<Type> type, bool is_mut, location_t locus) : Param ({}, locus), has_ref (false), is_mut (is_mut), - lifetime (Lifetime::error ()), type (std::move (type)) + lifetime (tl::nullopt), type (std::move (type)) {} // Lifetime-based self parameter (is ref, no type) - SelfParam (Lifetime lifetime, bool is_mut, location_t locus) + SelfParam (tl::optional<Lifetime> lifetime, bool is_mut, location_t locus) : Param ({}, locus), has_ref (true), is_mut (is_mut), lifetime (std::move (lifetime)) {} @@ -522,8 +523,8 @@ public: bool get_has_ref () const { return has_ref; }; bool get_is_mut () const { return is_mut; } - Lifetime get_lifetime () const { return lifetime; } - Lifetime &get_lifetime () { return lifetime; } + Lifetime get_lifetime () const { return lifetime.value (); } + Lifetime &get_lifetime () { return lifetime.value (); } NodeId get_node_id () const { return node_id; } @@ -1330,7 +1331,7 @@ class Function : public VisItem, public AssociatedItem, public ExternalItem WhereClause where_clause; tl::optional<std::unique_ptr<BlockExpr>> function_body; location_t locus; - bool is_default; + bool has_default; bool is_external_function; public: @@ -1355,6 +1356,8 @@ public: bool has_body () const { return function_body.has_value (); } + bool is_default () const { return has_default; } + // Mega-constructor with all possible fields Function (Identifier function_name, FunctionQualifiers qualifiers, std::vector<std::unique_ptr<GenericParam>> generic_params, @@ -1362,7 +1365,7 @@ public: std::unique_ptr<Type> return_type, WhereClause where_clause, tl::optional<std::unique_ptr<BlockExpr>> function_body, Visibility vis, std::vector<Attribute> outer_attrs, - location_t locus, bool is_default = false, + location_t locus, bool has_default = false, bool is_external_function = false) : VisItem (std::move (vis), std::move (outer_attrs)), ExternalItem (Stmt::node_id), qualifiers (std::move (qualifiers)), @@ -1372,7 +1375,7 @@ public: return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_body (std::move (function_body)), locus (locus), - is_default (is_default), is_external_function (is_external_function) + has_default (has_default), is_external_function (is_external_function) {} // TODO: add constructor with less fields diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index 20e0232..1bb521d 100644 --- a/gcc/rust/ast/rust-type.h +++ b/gcc/rust/ast/rust-type.h @@ -542,7 +542,7 @@ protected: class ReferenceType : public TypeNoBounds { // bool has_lifetime; // TODO: handle in lifetime or something? - Lifetime lifetime; + tl::optional<Lifetime> lifetime; bool has_mut; std::unique_ptr<TypeNoBounds> type; @@ -553,11 +553,12 @@ public: bool is_mut () const { return has_mut; } // Returns whether the reference has a lifetime. - bool has_lifetime () const { return !lifetime.is_error (); } + bool has_lifetime () const { return lifetime.has_value (); } // Constructor ReferenceType (bool is_mut, std::unique_ptr<TypeNoBounds> type_no_bounds, - location_t locus, Lifetime lifetime = Lifetime::elided ()) + location_t locus, + tl::optional<Lifetime> lifetime = Lifetime::elided ()) : lifetime (std::move (lifetime)), has_mut (is_mut), type (std::move (type_no_bounds)), locus (locus) {} @@ -598,7 +599,8 @@ public: bool get_has_mut () const { return has_mut; } - Lifetime &get_lifetime () { return lifetime; } + Lifetime &get_lifetime () { return lifetime.value (); } + const Lifetime &get_lifetime () const { return lifetime.value (); } TypeNoBounds &get_base_type () { return *type; } diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc index fdbca7f..12b9561 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -549,7 +549,7 @@ HIRCompileBase::mark_addressable (tree exp, location_t locus) } tree -HIRCompileBase::address_expression (tree expr, location_t location) +HIRCompileBase::address_expression (tree expr, location_t location, tree ptrty) { if (expr == error_mark_node) return error_mark_node; @@ -557,7 +557,10 @@ HIRCompileBase::address_expression (tree expr, location_t location) if (!mark_addressable (expr, location)) return error_mark_node; - return build_fold_addr_expr_loc (location, expr); + if (ptrty == NULL || ptrty == error_mark_node) + ptrty = build_pointer_type (TREE_TYPE (expr)); + + return build_fold_addr_expr_with_type_loc (location, expr, ptrty); } tree @@ -663,7 +666,8 @@ get_abi (const AST::AttrVec &outer_attrs, tree HIRCompileBase::compile_function ( - const std::string &fn_name, HIR::SelfParam &self_param, + bool is_root_item, const std::string &fn_name, + tl::optional<HIR::SelfParam> &self_param, std::vector<HIR::FunctionParam> &function_params, const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility, AST::AttrVec &outer_attrs, location_t locus, HIR::BlockExpr *function_body, @@ -674,7 +678,7 @@ HIRCompileBase::compile_function ( = canonical_path.get () + fntype->subst_as_string (); // we don't mangle the main fn since we haven't implemented the main shim - bool is_main_fn = fn_name.compare ("main") == 0; + bool is_main_fn = fn_name.compare ("main") == 0 && is_root_item; if (is_main_fn) { rust_assert (!main_identifier_node); @@ -710,24 +714,24 @@ HIRCompileBase::compile_function ( // setup the params TyTy::BaseType *tyret = fntype->get_return_type (); std::vector<Bvariable *> param_vars; - if (!self_param.is_error ()) + if (self_param) { rust_assert (fntype->is_method ()); TyTy::BaseType *self_tyty_lookup = fntype->get_self_type (); tree self_type = TyTyResolveCompile::compile (ctx, self_tyty_lookup); Bvariable *compiled_self_param - = CompileSelfParam::compile (ctx, fndecl, self_param, self_type, - self_param.get_locus ()); + = CompileSelfParam::compile (ctx, fndecl, self_param.value (), + self_type, self_param->get_locus ()); param_vars.push_back (compiled_self_param); - ctx->insert_var_decl (self_param.get_mappings ().get_hirid (), + ctx->insert_var_decl (self_param->get_mappings ().get_hirid (), compiled_self_param); } // offset from + 1 for the TyTy::FnType being used when this is a method to // skip over Self on the FnType - bool is_method = !self_param.is_error (); + bool is_method = self_param.has_value (); size_t i = is_method ? 1 : 0; for (auto &referenced_param : function_params) { diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h index 4b4f8b0..6814abc 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -29,7 +29,8 @@ class HIRCompileBase public: virtual ~HIRCompileBase () {} - static tree address_expression (tree expr, location_t locus); + static tree address_expression (tree expr, location_t locus, + tree ptrty = NULL_TREE); static tree compile_constant_expr ( Context *ctx, HirId coercion_id, TyTy::BaseType *resolved_type, @@ -102,7 +103,8 @@ protected: HIR::Expr &const_value_expr, location_t locus, location_t expr_locus); - tree compile_function (const std::string &fn_name, HIR::SelfParam &self_param, + tree compile_function (bool is_root_item, const std::string &fn_name, + tl::optional<HIR::SelfParam> &self_param, std::vector<HIR::FunctionParam> &function_params, const HIR::FunctionQualifiers &qualifiers, HIR::Visibility &visibility, AST::AttrVec &outer_attrs, diff --git a/gcc/rust/backend/rust-compile-expr.cc b/gcc/rust/backend/rust-compile-expr.cc index e4ab9f0..37856a7 100644 --- a/gcc/rust/backend/rust-compile-expr.cc +++ b/gcc/rust/backend/rust-compile-expr.cc @@ -905,7 +905,8 @@ CompileExpr::visit (HIR::BorrowExpr &expr) &tyty)) return; - translated = address_expression (main_expr, expr.get_locus ()); + tree expected_type = TyTyResolveCompile::compile (ctx, tyty); + translated = address_expression (main_expr, expr.get_locus (), expected_type); } void diff --git a/gcc/rust/backend/rust-compile-extern.h b/gcc/rust/backend/rust-compile-extern.h index bacd1c0..d6aa589 100644 --- a/gcc/rust/backend/rust-compile-extern.h +++ b/gcc/rust/backend/rust-compile-extern.h @@ -34,16 +34,10 @@ class CompileExternItem : public HIRCompileBase, public: static tree compile (HIR::ExternalItem *item, Context *ctx, TyTy::BaseType *concrete = nullptr, - bool is_query_mode = false, location_t ref_locus = UNDEF_LOCATION) { CompileExternItem compiler (ctx, concrete, ref_locus); item->accept_vis (compiler); - - if (is_query_mode && compiler.reference == error_mark_node) - rust_internal_error_at (ref_locus, "failed to compile extern item: %s", - item->as_string ().c_str ()); - return compiler.reference; } diff --git a/gcc/rust/backend/rust-compile-implitem.cc b/gcc/rust/backend/rust-compile-implitem.cc index 71b3e8d..1230c85 100644 --- a/gcc/rust/backend/rust-compile-implitem.cc +++ b/gcc/rust/backend/rust-compile-implitem.cc @@ -117,7 +117,7 @@ CompileTraitItem::visit (HIR::TraitItemFunc &func) auto vis = HIR::Visibility (HIR::Visibility::VisType::PUBLIC); HIR::TraitFunctionDecl &function = func.get_decl (); tree fndecl - = compile_function (function.get_function_name ().as_string (), + = compile_function (false, function.get_function_name ().as_string (), function.get_self (), function.get_function_params (), function.get_qualifiers (), vis, func.get_outer_attrs (), func.get_locus (), diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h index d2ef989..2d18dbf 100644 --- a/gcc/rust/backend/rust-compile-implitem.h +++ b/gcc/rust/backend/rust-compile-implitem.h @@ -30,16 +30,10 @@ class CompileInherentImplItem : public CompileItem public: static tree Compile (HIR::ImplItem *item, Context *ctx, TyTy::BaseType *concrete = nullptr, - bool is_query_mode = false, location_t ref_locus = UNDEF_LOCATION) { CompileInherentImplItem compiler (ctx, concrete, ref_locus); item->accept_vis (compiler); - - if (is_query_mode && compiler.reference == error_mark_node) - rust_internal_error_at (ref_locus, "failed to compile impl item: %s", - item->as_string ().c_str ()); - return compiler.reference; } diff --git a/gcc/rust/backend/rust-compile-item.cc b/gcc/rust/backend/rust-compile-item.cc index 7ce9848..9666990 100644 --- a/gcc/rust/backend/rust-compile-item.cc +++ b/gcc/rust/backend/rust-compile-item.cc @@ -252,8 +252,12 @@ CompileItem::visit (HIR::Function &function) if (function.get_qualifiers ().is_const ()) ctx->push_const_context (); + auto lookup_root_item = ctx->get_mappings ().lookup_hir_item ( + function.get_mappings ().get_hirid ()); + bool is_root_item = lookup_root_item.has_value (); tree fndecl - = compile_function (function.get_function_name ().as_string (), + = compile_function (is_root_item, + function.get_function_name ().as_string (), function.get_self_param (), function.get_function_params (), function.get_qualifiers (), function.get_visibility (), diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index eccb040..d9d946d 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -35,10 +35,6 @@ public: { CompileItem compiler (ctx, concrete, ref_locus); item->accept_vis (compiler); - - if (compiler.reference == error_mark_node) - rust_debug ("failed to compile item: %s", item->as_string ().c_str ()); - return compiler.reference; } diff --git a/gcc/rust/backend/rust-compile-resolve-path.cc b/gcc/rust/backend/rust-compile-resolve-path.cc index 115dd04..81d2dbb 100644 --- a/gcc/rust/backend/rust-compile-resolve-path.cc +++ b/gcc/rust/backend/rust-compile-resolve-path.cc @@ -105,7 +105,9 @@ ResolvePathRef::attempt_constructor_expression_lookup ( // make the ctor for the union HIR::Expr &discrim_expr = variant->get_discriminant (); + ctx->push_const_context (); tree discrim_expr_node = CompileExpr::Compile (discrim_expr, ctx); + ctx->pop_const_context (); tree folded_discrim_expr = fold_expr (discrim_expr_node); tree qualifier = folded_discrim_expr; @@ -259,10 +261,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, HIR::ExternalItem *resolved_extern_item = hir_extern_item->first; if (!lookup->has_substitutions_defined ()) return CompileExternItem::compile (resolved_extern_item, ctx, nullptr, - true, expr_locus); + expr_locus); else return CompileExternItem::compile (resolved_extern_item, ctx, lookup, - true, expr_locus); + expr_locus); } else { @@ -284,10 +286,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, { if (!lookup->has_substitutions_defined ()) return CompileInherentImplItem::Compile (resolved_item->first, ctx, - nullptr, true, expr_locus); + nullptr, expr_locus); else return CompileInherentImplItem::Compile (resolved_item->first, ctx, - lookup, true, expr_locus); + lookup, expr_locus); } else if (auto trait_item = ctx->get_mappings ().lookup_hir_trait_item (ref)) @@ -370,11 +372,10 @@ HIRCompileBase::query_compile (HirId ref, TyTy::BaseType *lookup, if (!lookup->has_substitutions_defined ()) return CompileInherentImplItem::Compile (impl_item, ctx, - nullptr, true, - expr_locus); + nullptr, expr_locus); else return CompileInherentImplItem::Compile (impl_item, ctx, lookup, - true, expr_locus); + expr_locus); } } } diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc index 7b00066..dbd8515 100644 --- a/gcc/rust/backend/rust-compile.cc +++ b/gcc/rust/backend/rust-compile.cc @@ -338,7 +338,7 @@ HIRCompileBase::compute_address_for_trait_item ( } return CompileInherentImplItem::Compile (associated_function, ctx, - lookup_fntype, true, locus); + lookup_fntype, locus); } // we can only compile trait-items with a body diff --git a/gcc/rust/checks/errors/rust-feature-gate.cc b/gcc/rust/checks/errors/rust-feature-gate.cc index f3daa61..44007f9 100644 --- a/gcc/rust/checks/errors/rust-feature-gate.cc +++ b/gcc/rust/checks/errors/rust-feature-gate.cc @@ -40,6 +40,13 @@ FeatureGate::visit (AST::Crate &crate) { if (attr.get_path ().as_string () == "feature") { + // check for empty feature, such as `#![feature], this is an error + if (attr.empty_input ()) + { + rust_error_at (attr.get_locus (), ErrorCode::E0556, + "malformed %<feature%> attribute input"); + continue; + } const auto &attr_input = attr.get_attr_input (); auto type = attr_input.get_attr_input_type (); if (type == AST::AttrInput::AttrInputType::TOKEN_TREE) diff --git a/gcc/rust/checks/errors/rust-feature.cc b/gcc/rust/checks/errors/rust-feature.cc index 25af46c..441a1b2 100644 --- a/gcc/rust/checks/errors/rust-feature.cc +++ b/gcc/rust/checks/errors/rust-feature.cc @@ -55,6 +55,9 @@ Feature::create (Feature::Name f) "1.11.0", 37854); case Feature::Name::PRELUDE_IMPORT: return Feature (f, Feature::State::ACTIVE, "prelude_import", "1.0.0"); + case Feature::Name::MIN_SPECIALIZATION: + return Feature (f, Feature::State::ACTIVE, "min_specialization", + "1.0.0" /* FIXME: What version here? */, 31844); case Feature::Name::AUTO_TRAITS: return Feature (f, Feature::State::ACTIVE, "optin_builtin_traits", "1.0.0", 13231); @@ -80,6 +83,7 @@ const std::map<std::string, Feature::Name> Feature::name_hash_map = { {"raw_ref_op", Feature::Name::RAW_REF_OP}, {"exclusive_range_pattern", Feature::Name::EXCLUSIVE_RANGE_PATTERN}, {"prelude_import", Feature::Name::PRELUDE_IMPORT}, + {"min_specialization", Feature::Name::MIN_SPECIALIZATION}, }; // namespace Rust tl::optional<Feature::Name> diff --git a/gcc/rust/checks/errors/rust-feature.h b/gcc/rust/checks/errors/rust-feature.h index 9edae6d..e7cb0af 100644 --- a/gcc/rust/checks/errors/rust-feature.h +++ b/gcc/rust/checks/errors/rust-feature.h @@ -51,6 +51,7 @@ public: RAW_REF_OP, EXCLUSIVE_RANGE_PATTERN, PRELUDE_IMPORT, + MIN_SPECIALIZATION, }; const std::string &as_string () { return m_name_str; } diff --git a/gcc/rust/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index 074ea01..a955b58 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -61,11 +61,10 @@ std::unique_ptr<AssociatedItem> DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr) { auto block = std::unique_ptr<BlockExpr> ( - new BlockExpr ({}, std::move (clone_expr), {}, {}, AST::LoopLabel::error (), - loc, loc)); + new BlockExpr ({}, std::move (clone_expr), {}, {}, tl::nullopt, loc, loc)); auto big_self_type = builder.single_type_path ("Self"); - std::unique_ptr<SelfParam> self (new SelfParam (Lifetime::error (), + std::unique_ptr<SelfParam> self (new SelfParam (tl::nullopt, /* is_mut */ false, loc)); std::vector<std::unique_ptr<Param>> params; diff --git a/gcc/rust/expand/rust-derive-debug.cc b/gcc/rust/expand/rust-derive-debug.cc index 7ad3908..a0bf9d8 100644 --- a/gcc/rust/expand/rust-derive-debug.cc +++ b/gcc/rust/expand/rust-derive-debug.cc @@ -50,8 +50,7 @@ DeriveDebug::stub_debug_fn () // we can't use builder.block() here as it returns a unique_ptr<Expr> and // Function's constructor expects a unique_ptr<BlockExpr> auto block = std::unique_ptr<BlockExpr> ( - new BlockExpr ({}, std::move (stub_return), {}, {}, - AST::LoopLabel::error (), loc, loc)); + new BlockExpr ({}, std::move (stub_return), {}, {}, tl::nullopt, loc, loc)); auto self = builder.self_ref_param (); diff --git a/gcc/rust/expand/rust-derive-default.cc b/gcc/rust/expand/rust-derive-default.cc index c54f8c3..2e8b456 100644 --- a/gcc/rust/expand/rust-derive-default.cc +++ b/gcc/rust/expand/rust-derive-default.cc @@ -58,8 +58,7 @@ DeriveDefault::default_fn (std::unique_ptr<Expr> &&return_expr) = std::unique_ptr<Type> (new TypePath (builder.type_path ("Self"))); auto block = std::unique_ptr<BlockExpr> ( - new BlockExpr ({}, std::move (return_expr), {}, {}, - AST::LoopLabel::error (), loc, loc)); + new BlockExpr ({}, std::move (return_expr), {}, {}, tl::nullopt, loc, loc)); return builder.function ("default", {}, std::move (self_ty), std::move (block)); diff --git a/gcc/rust/expand/rust-derive-eq.cc b/gcc/rust/expand/rust-derive-eq.cc index dc173de..5e7a894 100644 --- a/gcc/rust/expand/rust-derive-eq.cc +++ b/gcc/rust/expand/rust-derive-eq.cc @@ -49,8 +49,7 @@ DeriveEq::assert_receiver_is_total_eq_fn ( stmts.emplace_back (assert_type_is_eq (std::move (type))); auto block = std::unique_ptr<BlockExpr> ( - new BlockExpr (std::move (stmts), nullptr, {}, {}, AST::LoopLabel::error (), - loc, loc)); + new BlockExpr (std::move (stmts), nullptr, {}, {}, tl::nullopt, loc, loc)); auto self = builder.self_ref_param (); diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index b0d347e..5039798 100644 --- a/gcc/rust/hir/rust-ast-lower-base.cc +++ b/gcc/rust/hir/rust-ast-lower-base.cc @@ -690,8 +690,12 @@ ASTLoweringBase::lower_self (AST::Param ¶m) self.get_is_mut (), self.get_locus ()); } - AST::Lifetime l = self.get_lifetime (); - return HIR::SelfParam (mapping, lower_lifetime (l), self.get_is_mut (), + tl::optional<HIR::Lifetime> lifetime = tl::nullopt; + + if (self.has_lifetime ()) + lifetime = lower_lifetime (self.get_lifetime ()); + + return HIR::SelfParam (mapping, lifetime, self.get_is_mut (), self.get_locus ()); } diff --git a/gcc/rust/hir/rust-ast-lower-block.h b/gcc/rust/hir/rust-ast-lower-block.h index a39c010..93cd443 100644 --- a/gcc/rust/hir/rust-ast-lower-block.h +++ b/gcc/rust/hir/rust-ast-lower-block.h @@ -195,7 +195,9 @@ public: HIR::BlockExpr *loop_block = ASTLoweringBlock::translate (expr.get_loop_block (), &terminated); - HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ()); + tl::optional<HIR::LoopLabel> loop_label = tl::nullopt; + if (expr.has_loop_label ()) + loop_label = lower_loop_label (expr.get_loop_label ()); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc b/gcc/rust/hir/rust-ast-lower-expr.cc index 9f363c0..3784e74 100644 --- a/gcc/rust/hir/rust-ast-lower-expr.cc +++ b/gcc/rust/hir/rust-ast-lower-expr.cc @@ -597,8 +597,10 @@ ASTLoweringExpr::visit (AST::ForLoopExpr &expr) void ASTLoweringExpr::visit (AST::BreakExpr &expr) { - HIR::Lifetime break_label - = lower_lifetime (expr.get_label ().get_lifetime ()); + tl::optional<HIR::Lifetime> break_label = tl::nullopt; + if (expr.has_label ()) + break_label = lower_lifetime (expr.get_label_unchecked ().get_lifetime ()); + HIR::Expr *break_expr = expr.has_break_expr () ? ASTLoweringExpr::translate (expr.get_break_expr ()) @@ -618,7 +620,9 @@ ASTLoweringExpr::visit (AST::BreakExpr &expr) void ASTLoweringExpr::visit (AST::ContinueExpr &expr) { - HIR::Lifetime break_label = lower_lifetime (expr.get_label ()); + tl::optional<HIR::Lifetime> break_label; + if (expr.has_label ()) + break_label = lower_lifetime (expr.get_label_unchecked ()); auto crate_num = mappings.get_current_crate (); Analysis::NodeMapping mapping (crate_num, expr.get_node_id (), @@ -633,9 +637,6 @@ ASTLoweringExpr::visit (AST::ContinueExpr &expr) void ASTLoweringExpr::visit (AST::BorrowExpr &expr) { - if (expr.is_raw_borrow ()) - rust_unreachable (); - HIR::Expr *borrow_lvalue = ASTLoweringExpr::translate (expr.get_borrowed_expr ()); @@ -646,8 +647,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr) auto *borrow_expr = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_lvalue), - expr.get_mutability (), expr.get_outer_attrs (), - expr.get_locus ()); + expr.get_mutability (), expr.is_raw_borrow (), + expr.get_outer_attrs (), expr.get_locus ()); if (expr.get_is_double_borrow ()) { @@ -659,8 +660,8 @@ ASTLoweringExpr::visit (AST::BorrowExpr &expr) borrow_expr = new HIR::BorrowExpr (mapping, std::unique_ptr<HIR::Expr> (borrow_expr), - expr.get_mutability (), expr.get_outer_attrs (), - expr.get_locus ()); + expr.get_mutability (), expr.is_raw_borrow (), + expr.get_outer_attrs (), expr.get_locus ()); } translated = borrow_expr; diff --git a/gcc/rust/hir/rust-ast-lower-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 5380d25..d815a71 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -22,6 +22,7 @@ #include "rust-ast-lower-expr.h" #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-block.h" +#include "rust-hir-item.h" #include "rust-item.h" namespace Rust { @@ -131,7 +132,7 @@ ASTLowerImplItem::visit (AST::Function &function) Identifier function_name = function.get_function_name (); location_t locus = function.get_locus (); - HIR::SelfParam self_param = HIR::SelfParam::error (); + tl::optional<HIR::SelfParam> self_param = tl::nullopt; if (function.has_self_param ()) self_param = lower_self (function.get_self_param ()); @@ -140,6 +141,9 @@ ASTLowerImplItem::visit (AST::Function &function) ASTLoweringType::translate (function.get_return_type ())) : nullptr; + Defaultness defaultness + = function.is_default () ? Defaultness::Default : Defaultness::Final; + std::vector<HIR::FunctionParam> function_params; for (auto &p : function.get_function_params ()) { @@ -183,15 +187,15 @@ ASTLowerImplItem::visit (AST::Function &function) std::move (function_params), std::move (return_type), std::move (where_clause), std::move (function_body), std::move (vis), function.get_outer_attrs (), - std::move (self_param), locus); + std::move (self_param), defaultness, locus); - if (!fn->get_self_param ().is_error ()) + if (fn->is_method ()) { // insert mappings for self - mappings.insert_hir_self_param (&fn->get_self_param ()); + mappings.insert_hir_self_param (&fn->get_self_param_unchecked ()); mappings.insert_location ( - fn->get_self_param ().get_mappings ().get_hirid (), - fn->get_self_param ().get_locus ()); + fn->get_self_param_unchecked ().get_mappings ().get_hirid (), + fn->get_self_param_unchecked ().get_locus ()); } // add the mappings for the function params at the end @@ -245,9 +249,9 @@ ASTLowerTraitItem::visit (AST::Function &func) // set self parameter to error if this is a method // else lower to hir - HIR::SelfParam self_param = func.has_self_param () - ? lower_self (func.get_self_param ()) - : HIR::SelfParam::error (); + tl::optional<HIR::SelfParam> self_param = tl::nullopt; + if (func.has_self_param ()) + self_param = lower_self (func.get_self_param ()); std::vector<HIR::FunctionParam> function_params; for (auto &p : func.get_function_params ()) @@ -299,9 +303,10 @@ ASTLowerTraitItem::visit (AST::Function &func) if (func.has_self_param ()) { // insert mappings for self - mappings.insert_hir_self_param (&self_param); - mappings.insert_location (self_param.get_mappings ().get_hirid (), - self_param.get_locus ()); + // TODO: Is this correct ? Looks fishy + mappings.insert_hir_self_param (&*self_param); + mappings.insert_location (self_param->get_mappings ().get_hirid (), + self_param->get_locus ()); } // add the mappings for the function params at the end diff --git a/gcc/rust/hir/rust-ast-lower-item.cc b/gcc/rust/hir/rust-ast-lower-item.cc index 5dbcad5..f4396b5 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -451,13 +451,16 @@ ASTLoweringItem::visit (AST::Function &function) mappings.insert_location (function_body->get_mappings ().get_hirid (), function.get_locus ()); + Defaultness defaultness + = function.is_default () ? Defaultness::Default : Defaultness::Final; + auto fn = new HIR::Function (mapping, std::move (function_name), std::move (qualifiers), std::move (generic_params), std::move (function_params), std::move (return_type), std::move (where_clause), std::move (function_body), std::move (vis), function.get_outer_attrs (), - HIR::SelfParam::error (), locus); + tl::nullopt, defaultness, locus); // add the mappings for the function params at the end for (auto ¶m : fn->get_function_params ()) diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc index ebdf981..76bd135 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -97,7 +97,11 @@ ASTLowering::go () void ASTLoweringBlock::visit (AST::BlockExpr &expr) { - auto label = lower_loop_label (expr.get_label ()); + tl::optional<HIR::LoopLabel> label; + if (expr.has_label ()) + label = lower_loop_label (expr.get_label ()); + else + label = tl::nullopt; std::vector<std::unique_ptr<HIR::Stmt>> block_stmts; bool block_did_terminate = false; @@ -398,7 +402,10 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr) HIR::BlockExpr *loop_block = ASTLoweringBlock::translate (expr.get_loop_block (), &terminated); - HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ()); + tl::optional<HIR::LoopLabel> loop_label; + if (expr.has_loop_label ()) + loop_label = lower_loop_label (expr.get_loop_label ()); + HIR::Expr *loop_condition = ASTLoweringExpr::translate (expr.get_predicate_expr (), &terminated); diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc index 89fcc3d..dafa823 100644 --- a/gcc/rust/hir/rust-hir-dump.cc +++ b/gcc/rust/hir/rust-hir-dump.cc @@ -546,7 +546,8 @@ Dump::do_traitfunctiondecl (TraitFunctionDecl &e) else put_field ("where_clause", "none"); - put_field ("self", e.get_self ().as_string ()); + if (e.is_method ()) + put_field ("self", e.get_self_unchecked ().as_string ()); end ("TraitFunctionDecl"); } @@ -1693,7 +1694,8 @@ Dump::visit (Function &e) put_field ("where clause", e.get_where_clause ().as_string ()); visit_field ("function_body", e.get_definition ()); - put_field ("self", e.get_self_param ().as_string ()); + if (e.is_method ()) + put_field ("self", e.get_self_param_unchecked ().as_string ()); end ("Function"); } diff --git a/gcc/rust/hir/tree/rust-hir-bound.h b/gcc/rust/hir/tree/rust-hir-bound.h index 78bb133..8fa6a22 100644 --- a/gcc/rust/hir/tree/rust-hir-bound.h +++ b/gcc/rust/hir/tree/rust-hir-bound.h @@ -44,18 +44,6 @@ public: {} // Returns true if the lifetime is in an error state. - bool is_error () const - { - return lifetime_type == AST::Lifetime::LifetimeType::NAMED - && lifetime_name.empty (); - } - - static Lifetime error () - { - return Lifetime (Analysis::NodeMapping::get_error (), - AST::Lifetime::LifetimeType::NAMED, "", UNDEF_LOCATION); - } - std::string as_string () const override; void accept_vis (HIRFullVisitor &vis) override; diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc b/gcc/rust/hir/tree/rust-hir-expr.cc index 2ded789..266c79c 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -81,10 +81,10 @@ OperatorExpr::operator= (OperatorExpr const &other) BorrowExpr::BorrowExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> borrow_lvalue, Mutability mut, - AST::AttrVec outer_attribs, location_t locus) + bool raw, AST::AttrVec outer_attribs, location_t locus) : OperatorExpr (std::move (mappings), std::move (borrow_lvalue), std::move (outer_attribs), locus), - mut (mut) + mut (mut), raw (raw) {} DereferenceExpr::DereferenceExpr (Analysis::NodeMapping mappings, @@ -749,7 +749,7 @@ BlockExpr::BlockExpr (Analysis::NodeMapping mappings, std::vector<std::unique_ptr<Stmt>> block_statements, std::unique_ptr<Expr> block_expr, bool tail_reachable, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - LoopLabel label, location_t start_locus, + tl::optional<LoopLabel> label, location_t start_locus, location_t end_locus) : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), WithInnerAttrs (std::move (inner_attribs)), @@ -791,13 +791,15 @@ BlockExpr::operator= (BlockExpr const &other) } ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus, - Lifetime label, AST::AttrVec outer_attribs) + tl::optional<Lifetime> label, + AST::AttrVec outer_attribs) : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), label (std::move (label)), locus (locus) {} BreakExpr::BreakExpr (Analysis::NodeMapping mappings, location_t locus, - Lifetime break_label, std::unique_ptr<Expr> expr_in_break, + tl::optional<Lifetime> break_label, + std::unique_ptr<Expr> expr_in_break, AST::AttrVec outer_attribs) : ExprWithoutBlock (std::move (mappings), std::move (outer_attribs)), label (std::move (break_label)), break_expr (std::move (expr_in_break)), @@ -985,7 +987,8 @@ UnsafeBlockExpr::operator= (UnsafeBlockExpr const &other) BaseLoopExpr::BaseLoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, - location_t locus, LoopLabel loop_label, + location_t locus, + tl::optional<LoopLabel> loop_label, AST::AttrVec outer_attribs) : ExprWithBlock (std::move (mappings), std::move (outer_attribs)), loop_label (std::move (loop_label)), loop_block (std::move (loop_block)), @@ -1011,7 +1014,8 @@ BaseLoopExpr::operator= (BaseLoopExpr const &other) LoopExpr::LoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, AST::AttrVec outer_attribs) + tl::optional<LoopLabel> loop_label, + AST::AttrVec outer_attribs) : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)) {} @@ -1019,7 +1023,8 @@ LoopExpr::LoopExpr (Analysis::NodeMapping mappings, WhileLoopExpr::WhileLoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> loop_condition, std::unique_ptr<BlockExpr> loop_block, - location_t locus, LoopLabel loop_label, + location_t locus, + tl::optional<LoopLabel> loop_label, AST::AttrVec outer_attribs) : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)), @@ -1046,7 +1051,8 @@ WhileLetLoopExpr::WhileLetLoopExpr ( Analysis::NodeMapping mappings, std::vector<std::unique_ptr<Pattern>> match_arm_patterns, std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block, - location_t locus, LoopLabel loop_label, AST::AttrVec outer_attribs) + location_t locus, tl::optional<LoopLabel> loop_label, + AST::AttrVec outer_attribs) : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus, std::move (loop_label), std::move (outer_attribs)), match_arm_patterns (std::move (match_arm_patterns)), diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index f8f2128..96f0cf6 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.h +++ b/gcc/rust/hir/tree/rust-hir-expr.h @@ -45,9 +45,6 @@ public: LoopLabel (Analysis::NodeMapping mapping, Lifetime loop_label, location_t locus); - // Returns whether the LoopLabel is in an error state. - bool is_error () const { return label.is_error (); } - location_t get_locus () const { return locus; } Analysis::NodeMapping &get_mappings () { return mappings; } @@ -199,12 +196,13 @@ public: class BorrowExpr : public OperatorExpr { Mutability mut; + bool raw; public: std::string as_string () const override; BorrowExpr (Analysis::NodeMapping mappings, - std::unique_ptr<Expr> borrow_lvalue, Mutability mut, + std::unique_ptr<Expr> borrow_lvalue, Mutability mut, bool raw, AST::AttrVec outer_attribs, location_t locus); void accept_vis (HIRFullVisitor &vis) override; @@ -212,6 +210,7 @@ public: Mutability get_mut () const { return mut; } bool is_mut () const { return mut == Mutability::Mut; } + bool is_raw_borrow () const { return raw; } protected: /* Use covariance to implement clone function as returning this object rather @@ -1715,7 +1714,7 @@ public: std::vector<std::unique_ptr<Stmt>> statements; std::unique_ptr<Expr> expr; bool tail_reachable; - LoopLabel label; + tl::optional<LoopLabel> label; location_t start_locus; location_t end_locus; @@ -1735,7 +1734,8 @@ public: std::vector<std::unique_ptr<Stmt>> block_statements, std::unique_ptr<Expr> block_expr, bool tail_reachable, AST::AttrVec inner_attribs, AST::AttrVec outer_attribs, - LoopLabel label, location_t start_locus, location_t end_locus); + tl::optional<LoopLabel> label, location_t start_locus, + location_t end_locus); // Copy constructor with clone BlockExpr (BlockExpr const &other); @@ -1774,8 +1774,8 @@ public: return ExprType::Block; } - bool has_label () const { return !label.is_error (); } - LoopLabel &get_label () { return label; } + bool has_label () const { return label.has_value (); } + LoopLabel &get_label () { return label.value (); } protected: /* Use covariance to implement clone function as returning this object rather @@ -1803,25 +1803,27 @@ protected: // HIR node representing continue expression within loops class ContinueExpr : public ExprWithoutBlock { - Lifetime label; + tl::optional<Lifetime> label; location_t locus; public: std::string as_string () const override; // Returns true if the continue expr has a label. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } // Constructor for a ContinueExpr with a label. ContinueExpr (Analysis::NodeMapping mappings, location_t locus, - Lifetime label, AST::AttrVec outer_attribs = AST::AttrVec ()); + tl::optional<Lifetime> label, + AST::AttrVec outer_attribs = AST::AttrVec ()); location_t get_locus () const override final { return locus; } void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - Lifetime &get_label () { return label; } + Lifetime &get_label () { return label.value (); } + const Lifetime &get_label () const { return label.value (); } ExprType get_expression_type () const final override { @@ -1848,7 +1850,7 @@ protected: class BreakExpr : public ExprWithoutBlock { // bool has_label; - Lifetime label; + tl::optional<Lifetime> label; // bool has_break_expr; std::unique_ptr<Expr> break_expr; @@ -1859,7 +1861,7 @@ public: std::string as_string () const override; // Returns whether the break expression has a label or not. - bool has_label () const { return !label.is_error (); } + bool has_label () const { return label.has_value (); } /* Returns whether the break expression has an expression used in the break or * not. */ @@ -1867,7 +1869,7 @@ public: // Constructor for a break expression BreakExpr (Analysis::NodeMapping mappings, location_t locus, - Lifetime break_label, + tl::optional<Lifetime> break_label, std::unique_ptr<Expr> expr_in_break = nullptr, AST::AttrVec outer_attribs = AST::AttrVec ()); @@ -1886,7 +1888,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; - Lifetime &get_label () { return label; } + Lifetime &get_label () { return label.value (); } + const Lifetime &get_label () const { return label.value (); } Expr &get_expr () { return *break_expr; } @@ -2293,7 +2296,7 @@ protected: class BaseLoopExpr : public ExprWithBlock { protected: - LoopLabel loop_label; + tl::optional<LoopLabel> loop_label; std::unique_ptr<BlockExpr> loop_block; private: @@ -2303,7 +2306,7 @@ protected: // Constructor for BaseLoopExpr BaseLoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, + tl::optional<LoopLabel> loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor for BaseLoopExpr with clone @@ -2322,13 +2325,14 @@ protected: } public: - bool has_loop_label () const { return !loop_label.is_error (); } + bool has_loop_label () const { return loop_label.has_value (); } location_t get_locus () const override final { return locus; } HIR::BlockExpr &get_loop_block () { return *loop_block; }; - LoopLabel &get_loop_label () { return loop_label; } + LoopLabel &get_loop_label () { return loop_label.value (); } + const LoopLabel &get_loop_label () const { return loop_label.value (); } }; // 'Loop' expression (i.e. the infinite loop) HIR node @@ -2340,7 +2344,8 @@ public: // Constructor for LoopExpr LoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()); + tl::optional<LoopLabel> loop_label, + AST::AttrVec outer_attribs = AST::AttrVec ()); void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRExpressionVisitor &vis) override; @@ -2370,7 +2375,7 @@ public: WhileLoopExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> loop_condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, + tl::optional<LoopLabel> loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor with clone @@ -2419,7 +2424,7 @@ public: std::vector<std::unique_ptr<Pattern>> match_arm_patterns, std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block, location_t locus, - LoopLabel loop_label, + tl::optional<LoopLabel> loop_label, AST::AttrVec outer_attribs = AST::AttrVec ()); // Copy constructor with clone diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.h b/gcc/rust/hir/tree/rust-hir-generic-param.h index a1c59bf..960de56 100644 --- a/gcc/rust/hir/tree/rust-hir-generic-param.h +++ b/gcc/rust/hir/tree/rust-hir-generic-param.h @@ -97,9 +97,6 @@ public: AST::AttrVec &get_outer_attrs () override { return outer_attrs; } - // Returns whether the lifetime param is in an error state. - bool is_error () const { return lifetime.is_error (); } - // Constructor LifetimeParam (Analysis::NodeMapping mappings, Lifetime lifetime, location_t locus = UNDEF_LOCATION, diff --git a/gcc/rust/hir/tree/rust-hir-item.cc b/gcc/rust/hir/tree/rust-hir-item.cc index cff06d3..160f710 100644 --- a/gcc/rust/hir/tree/rust-hir-item.cc +++ b/gcc/rust/hir/tree/rust-hir-item.cc @@ -123,7 +123,8 @@ TypeBoundWhereClauseItem::get_type_param_bounds () } SelfParam::SelfParam (Analysis::NodeMapping mappings, - ImplicitSelfKind self_kind, Lifetime lifetime, Type *type) + ImplicitSelfKind self_kind, + tl::optional<Lifetime> lifetime, Type *type) : self_kind (self_kind), lifetime (std::move (lifetime)), type (type), mappings (mappings) {} @@ -131,13 +132,13 @@ SelfParam::SelfParam (Analysis::NodeMapping mappings, SelfParam::SelfParam (Analysis::NodeMapping mappings, std::unique_ptr<Type> type, bool is_mut, location_t locus) : self_kind (is_mut ? ImplicitSelfKind::MUT : ImplicitSelfKind::IMM), - lifetime ( - Lifetime (mappings, AST::Lifetime::LifetimeType::NAMED, "", locus)), - type (std::move (type)), locus (locus), mappings (mappings) + lifetime (tl::nullopt), type (std::move (type)), locus (locus), + mappings (mappings) {} -SelfParam::SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, - bool is_mut, location_t locus) +SelfParam::SelfParam (Analysis::NodeMapping mappings, + tl::optional<Lifetime> lifetime, bool is_mut, + location_t locus) : self_kind (is_mut ? ImplicitSelfKind::MUT_REF : ImplicitSelfKind::IMM_REF), lifetime (std::move (lifetime)), locus (locus), mappings (mappings) {} @@ -263,7 +264,8 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name, std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, - AST::AttrVec outer_attrs, SelfParam self, location_t locus) + AST::AttrVec outer_attrs, tl::optional<SelfParam> self, + Defaultness defaultness, location_t locus) : VisItem (std::move (mappings), std::move (vis), std::move (outer_attrs)), qualifiers (std::move (qualifiers)), function_name (std::move (function_name)), @@ -272,7 +274,7 @@ Function::Function (Analysis::NodeMapping mappings, Identifier function_name, return_type (std::move (return_type)), where_clause (std::move (where_clause)), function_body (std::move (function_body)), self (std::move (self)), - locus (locus) + locus (locus), defaultness (defaultness) {} Function::Function (Function const &other) @@ -280,7 +282,7 @@ Function::Function (Function const &other) function_name (other.function_name), function_params (other.function_params), where_clause (other.where_clause), function_body (other.function_body->clone_block_expr ()), self (other.self), - locus (other.locus) + locus (other.locus), defaultness (other.defaultness) { // guard to prevent null dereference (always required) if (other.return_type != nullptr) @@ -312,6 +314,8 @@ Function::operator= (Function const &other) locus = other.locus; self = other.self; + defaultness = other.defaultness; + generic_params.reserve (other.generic_params.size ()); for (const auto &e : other.generic_params) generic_params.push_back (e->clone_generic_param ()); @@ -609,9 +613,9 @@ StaticItem::operator= (StaticItem const &other) TraitFunctionDecl::TraitFunctionDecl ( Identifier function_name, FunctionQualifiers qualifiers, - std::vector<std::unique_ptr<GenericParam>> generic_params, SelfParam self, - std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, - WhereClause where_clause) + std::vector<std::unique_ptr<GenericParam>> generic_params, + tl::optional<SelfParam> self, std::vector<FunctionParam> function_params, + std::unique_ptr<Type> return_type, WhereClause where_clause) : qualifiers (std::move (qualifiers)), function_name (std::move (function_name)), generic_params (std::move (generic_params)), diff --git a/gcc/rust/hir/tree/rust-hir-item.h b/gcc/rust/hir/tree/rust-hir-item.h index 4744717..b9b105b 100644 --- a/gcc/rust/hir/tree/rust-hir-item.h +++ b/gcc/rust/hir/tree/rust-hir-item.h @@ -371,13 +371,13 @@ public: private: ImplicitSelfKind self_kind; - Lifetime lifetime; + tl::optional<Lifetime> lifetime; std::unique_ptr<Type> type; location_t locus; Analysis::NodeMapping mappings; SelfParam (Analysis::NodeMapping mappings, ImplicitSelfKind self_kind, - Lifetime lifetime, Type *type); + tl::optional<Lifetime> lifetime, Type *type); public: // Type-based self parameter (not ref, no lifetime) @@ -385,8 +385,8 @@ public: bool is_mut, location_t locus); // Lifetime-based self parameter (is ref, no type) - SelfParam (Analysis::NodeMapping mappings, Lifetime lifetime, bool is_mut, - location_t locus); + SelfParam (Analysis::NodeMapping mappings, tl::optional<Lifetime> lifetime, + bool is_mut, location_t locus); // Copy constructor requires clone SelfParam (SelfParam const &other); @@ -398,22 +398,13 @@ public: SelfParam (SelfParam &&other) = default; SelfParam &operator= (SelfParam &&other) = default; - static SelfParam error () - { - return SelfParam (Analysis::NodeMapping::get_error (), - ImplicitSelfKind::NONE, Lifetime::error (), nullptr); - } - // Returns whether the self-param has a type field. bool has_type () const { return type != nullptr; } // Returns whether the self-param has a valid lifetime. - bool has_lifetime () const { return !lifetime.is_error (); } - - const Lifetime &get_lifetime () const { return lifetime; } + bool has_lifetime () const { return lifetime.has_value (); } - // Returns whether the self-param is in an error state. - bool is_error () const { return self_kind == ImplicitSelfKind::NONE; } + const Lifetime &get_lifetime () const { return lifetime.value (); } std::string as_string () const; @@ -945,6 +936,12 @@ protected: class LetStmt; +enum class Defaultness +{ + Default, + Final, +}; + // Rust function declaration HIR node class Function : public VisItem, public ImplItem { @@ -955,9 +952,14 @@ class Function : public VisItem, public ImplItem std::unique_ptr<Type> return_type; WhereClause where_clause; std::unique_ptr<BlockExpr> function_body; - SelfParam self; + tl::optional<SelfParam> self; location_t locus; + // NOTE: This should be moved to the trait item base class once we start + // implementing specialization for real, instead of just stubbing out the + // feature + Defaultness defaultness; + public: std::string as_string () const override; @@ -973,6 +975,9 @@ public: // Returns whether function has a where clause. bool has_where_clause () const { return !where_clause.is_empty (); } + // Returns whether function has a default qualifier + bool is_default () const { return defaultness == Defaultness::Default; } + ImplItemType get_impl_item_type () const override final { return ImplItem::ImplItemType::FUNCTION; @@ -987,7 +992,8 @@ public: std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause, std::unique_ptr<BlockExpr> function_body, Visibility vis, - AST::AttrVec outer_attrs, SelfParam self, location_t locus); + AST::AttrVec outer_attrs, tl::optional<SelfParam> self, + Defaultness defaultness, location_t locus); // Copy constructor with clone Function (Function const &other); @@ -1041,9 +1047,13 @@ public: // TODO: is this better? Or is a "vis_block" better? Type &get_return_type () { return *return_type; } - bool is_method () const { return !self.is_error (); } + bool is_method () const { return self.has_value (); } + + tl::optional<SelfParam> &get_self_param () { return self; } + const tl::optional<SelfParam> &get_self_param () const { return self; } - SelfParam &get_self_param () { return self; } + SelfParam &get_self_param_unchecked () { return self.value (); } + const SelfParam &get_self_param_unchecked () const { return self.value (); } std::string get_impl_item_name () const override final { @@ -1898,13 +1908,14 @@ private: std::vector<FunctionParam> function_params; std::unique_ptr<Type> return_type; WhereClause where_clause; - SelfParam self; + tl::optional<SelfParam> self; public: // Mega-constructor TraitFunctionDecl (Identifier function_name, FunctionQualifiers qualifiers, std::vector<std::unique_ptr<GenericParam>> generic_params, - SelfParam self, std::vector<FunctionParam> function_params, + tl::optional<SelfParam> self, + std::vector<FunctionParam> function_params, std::unique_ptr<Type> return_type, WhereClause where_clause); @@ -1936,9 +1947,13 @@ public: WhereClause &get_where_clause () { return where_clause; } - bool is_method () const { return !self.is_error (); } + bool is_method () const { return self.has_value (); } + + SelfParam &get_self_unchecked () { return self.value (); } + const SelfParam &get_self_unchecked () const { return self.value (); } - SelfParam &get_self () { return self; } + tl::optional<SelfParam> &get_self () { return self; } + const tl::optional<SelfParam> &get_self () const { return self; } Identifier get_function_name () const { return function_name; } diff --git a/gcc/rust/hir/tree/rust-hir-type.cc b/gcc/rust/hir/tree/rust-hir-type.cc index 6a6c319..ec48425 100644 --- a/gcc/rust/hir/tree/rust-hir-type.cc +++ b/gcc/rust/hir/tree/rust-hir-type.cc @@ -162,7 +162,7 @@ RawPointerType::operator= (RawPointerType const &other) ReferenceType::ReferenceType (Analysis::NodeMapping mappings, Mutability mut, std::unique_ptr<Type> type_no_bounds, - location_t locus, Lifetime lifetime) + location_t locus, tl::optional<Lifetime> lifetime) : TypeNoBounds (mappings, locus), lifetime (std::move (lifetime)), mut (mut), type (std::move (type_no_bounds)) {} diff --git a/gcc/rust/hir/tree/rust-hir-type.h b/gcc/rust/hir/tree/rust-hir-type.h index bd0f2b6..cbc20ff 100644 --- a/gcc/rust/hir/tree/rust-hir-type.h +++ b/gcc/rust/hir/tree/rust-hir-type.h @@ -291,7 +291,7 @@ protected: class ReferenceType : public TypeNoBounds { // bool has_lifetime; // TODO: handle in lifetime or something? - Lifetime lifetime; + tl::optional<Lifetime> lifetime; Mutability mut; std::unique_ptr<Type> type; @@ -301,12 +301,12 @@ public: bool is_mut () const { return mut == Mutability::Mut; } // Returns whether the reference has a lifetime. - bool has_lifetime () const { return !lifetime.is_error (); } + bool has_lifetime () const { return lifetime.has_value (); } // Constructor ReferenceType (Analysis::NodeMapping mappings, Mutability mut, std::unique_ptr<Type> type_no_bounds, location_t locus, - Lifetime lifetime); + tl::optional<Lifetime> lifetime); // Copy constructor with custom clone method ReferenceType (ReferenceType const &other); @@ -323,7 +323,8 @@ public: void accept_vis (HIRFullVisitor &vis) override; void accept_vis (HIRTypeVisitor &vis) override; - Lifetime &get_lifetime () { return lifetime; } + Lifetime &get_lifetime () { return lifetime.value (); } + const Lifetime &get_lifetime () const { return lifetime.value (); } Mutability get_mut () const { return mut; } diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc index 822eaff..c8bf9da 100644 --- a/gcc/rust/hir/tree/rust-hir.cc +++ b/gcc/rust/hir/tree/rust-hir.cc @@ -1314,7 +1314,7 @@ ContinueExpr::as_string () const if (has_label ()) { - str += label.as_string (); + str += get_label ().as_string (); } return str; @@ -1704,7 +1704,7 @@ WhileLoopExpr::as_string () const } else { - str += loop_label.as_string (); + str += get_loop_label ().as_string (); } str += "\n Conditional expr: " + condition->as_string (); @@ -1726,7 +1726,7 @@ WhileLetLoopExpr::as_string () const } else { - str += loop_label.as_string (); + str += get_loop_label ().as_string (); } str += "\n Match arm patterns: "; @@ -1761,7 +1761,7 @@ LoopExpr::as_string () const } else { - str += loop_label.as_string (); + str += get_loop_label ().as_string (); } str += "\n Loop block: " + loop_block->as_string (); @@ -1816,7 +1816,7 @@ BreakExpr::as_string () const if (has_label ()) { - str += label.as_string () + " "; + str += get_label ().as_string () + " "; } if (has_break_expr ()) @@ -2101,11 +2101,6 @@ QualifiedPathInType::as_string () const std::string Lifetime::as_string () const { - if (is_error ()) - { - return "error lifetime"; - } - switch (lifetime_type) { case AST::Lifetime::LifetimeType::NAMED: @@ -2760,7 +2755,7 @@ ReferenceType::as_string () const if (has_lifetime ()) { - str += lifetime.as_string () + " "; + str += get_lifetime ().as_string () + " "; } if (is_mut ()) @@ -3411,7 +3406,7 @@ TraitFunctionDecl::as_string () const str += "\n Function params: "; if (is_method ()) { - str += self.as_string () + (has_params () ? ", " : ""); + str += get_self_unchecked ().as_string () + (has_params () ? ", " : ""); } if (has_params ()) @@ -3525,70 +3520,63 @@ TraitItemType::as_string () const std::string SelfParam::as_string () const { - if (is_error ()) - { - return "error"; - } - else + if (has_type ()) { - if (has_type ()) + // type (i.e. not ref, no lifetime) + std::string str; + + if (is_mut ()) { - // type (i.e. not ref, no lifetime) - std::string str; + str += "mut "; + } - if (is_mut ()) - { - str += "mut "; - } + str += "self : "; - str += "self : "; + str += type->as_string (); - str += type->as_string (); + return str; + } + else if (has_lifetime ()) + { + // ref and lifetime + std::string str = "&" + get_lifetime ().as_string () + " "; - return str; - } - else if (has_lifetime ()) + if (is_mut ()) { - // ref and lifetime - std::string str = "&" + lifetime.as_string () + " "; + str += "mut "; + } - if (is_mut ()) - { - str += "mut "; - } + str += "self"; - str += "self"; + return str; + } + else if (is_ref ()) + { + // ref with no lifetime + std::string str = "&"; - return str; - } - else if (is_ref ()) + if (is_mut ()) { - // ref with no lifetime - std::string str = "&"; + str += " mut "; + } - if (is_mut ()) - { - str += " mut "; - } + str += "self"; - str += "self"; + return str; + } + else + { + // no ref, no type + std::string str; - return str; - } - else + if (is_mut ()) { - // no ref, no type - std::string str; - - if (is_mut ()) - { - str += "mut "; - } + str += "mut "; + } - str += "self"; + str += "self"; - return str; - } + return str; } } diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 71d7250..3bb758e 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -3102,7 +3102,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token) { case LIFETIME: { auto lifetime = parse_lifetime (false); - if (lifetime.is_error ()) + if (!lifetime) { rust_error_at ( token->get_locus (), @@ -3122,7 +3122,7 @@ Parser<ManagedTokenSource>::parse_generic_param (EndTokenPred is_end_token) } param = std::unique_ptr<AST::LifetimeParam> (new AST::LifetimeParam ( - std::move (lifetime), std::move (lifetime_bounds), + std::move (lifetime.value ()), std::move (lifetime_bounds), std::move (outer_attrs), token->get_locus ())); break; } @@ -3276,16 +3276,16 @@ Parser<ManagedTokenSource>::parse_lifetime_params () while (lexer.peek_token ()->get_id () != END_OF_FILE) { - AST::LifetimeParam lifetime_param = parse_lifetime_param (); + auto lifetime_param = parse_lifetime_param (); - if (lifetime_param.is_error ()) + if (!lifetime_param) { // can't treat as error as only way to get out with trailing comma break; } lifetime_params.push_back (std::unique_ptr<AST::LifetimeParam> ( - new AST::LifetimeParam (std::move (lifetime_param)))); + new AST::LifetimeParam (std::move (lifetime_param.value ())))); if (lexer.peek_token ()->get_id () != COMMA) break; @@ -3311,9 +3311,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params (EndTokenPred is_end_token) // if end_token is not specified, it defaults to EOF, so should work fine while (!is_end_token (lexer.peek_token ()->get_id ())) { - AST::LifetimeParam lifetime_param = parse_lifetime_param (); + auto lifetime_param = parse_lifetime_param (); - if (lifetime_param.is_error ()) + if (!lifetime_param) { /* TODO: is it worth throwing away all lifetime params just because * one failed? */ @@ -3351,9 +3351,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs () // bad control structure as end token cannot be guaranteed while (true) { - AST::LifetimeParam lifetime_param = parse_lifetime_param (); + auto lifetime_param = parse_lifetime_param (); - if (lifetime_param.is_error ()) + if (!lifetime_param) { // not an error as only way to exit if trailing comma break; @@ -3386,9 +3386,9 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs ( while (!is_end_token (lexer.peek_token ()->get_id ())) { - AST::LifetimeParam lifetime_param = parse_lifetime_param (); + auto lifetime_param = parse_lifetime_param (); - if (lifetime_param.is_error ()) + if (!lifetime_param) { /* TODO: is it worth throwing away all lifetime params just because * one failed? */ @@ -3399,7 +3399,7 @@ Parser<ManagedTokenSource>::parse_lifetime_params_objs ( return {}; } - lifetime_params.push_back (std::move (lifetime_param)); + lifetime_params.push_back (std::move (lifetime_param.value ())); if (lexer.peek_token ()->get_id () != COMMA) break; @@ -3458,7 +3458,7 @@ Parser<ManagedTokenSource>::parse_non_ptr_sequence ( /* Parses a single lifetime generic parameter (not including comma). */ template <typename ManagedTokenSource> -AST::LifetimeParam +tl::expected<AST::LifetimeParam, ParseLifetimeParamError> Parser<ManagedTokenSource>::parse_lifetime_param () { // parse outer attributes, which are optional and may not exist @@ -3468,8 +3468,8 @@ Parser<ManagedTokenSource>::parse_lifetime_param () const_TokenPtr lifetime_tok = lexer.peek_token (); if (lifetime_tok->get_id () != LIFETIME) { - // if lifetime is missing, must not be a lifetime param, so return null - return AST::LifetimeParam::create_error (); + // if lifetime is missing, must not be a lifetime param, so return error + return tl::make_unexpected<ParseLifetimeParamError> ({}); } lexer.skip_token (); AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (), @@ -3815,12 +3815,13 @@ template <typename ManagedTokenSource> std::unique_ptr<AST::LifetimeWhereClauseItem> Parser<ManagedTokenSource>::parse_lifetime_where_clause_item () { - AST::Lifetime lifetime = parse_lifetime (false); - if (lifetime.is_error ()) + auto parsed_lifetime = parse_lifetime (false); + if (!parsed_lifetime) { // TODO: error here? return nullptr; } + auto lifetime = parsed_lifetime.value (); if (!skip_token (COLON)) { @@ -4013,7 +4014,7 @@ Parser<ManagedTokenSource>::parse_type_param_bound () { case LIFETIME: return std::unique_ptr<AST::Lifetime> ( - new AST::Lifetime (parse_lifetime (false))); + new AST::Lifetime (parse_lifetime (false).value ())); case LEFT_PAREN: case QUESTION_MARK: case FOR: @@ -4086,13 +4087,13 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds () while (true) { - AST::Lifetime lifetime = parse_lifetime (false); + auto lifetime = parse_lifetime (false); // quick exit for parsing failure - if (lifetime.is_error ()) + if (!lifetime) break; - lifetime_bounds.push_back (std::move (lifetime)); + lifetime_bounds.push_back (std::move (lifetime.value ())); /* plus is maybe not allowed at end - spec defines it weirdly, so * assuming allowed at end */ @@ -4116,9 +4117,9 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token) while (!is_end_token (lexer.peek_token ()->get_id ())) { - AST::Lifetime lifetime = parse_lifetime (false); + auto lifetime = parse_lifetime (false); - if (lifetime.is_error ()) + if (!lifetime) { /* TODO: is it worth throwing away all lifetime bound info just * because one failed? */ @@ -4129,7 +4130,7 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token) return {}; } - lifetime_bounds.push_back (std::move (lifetime)); + lifetime_bounds.push_back (std::move (lifetime.value ())); /* plus is maybe not allowed at end - spec defines it weirdly, so * assuming allowed at end */ @@ -4146,14 +4147,20 @@ Parser<ManagedTokenSource>::parse_lifetime_bounds (EndTokenPred is_end_token) /* Parses a lifetime token (named, 'static, or '_). Also handles lifetime not * existing. */ template <typename ManagedTokenSource> -AST::Lifetime +tl::expected<AST::Lifetime, ParseLifetimeError> Parser<ManagedTokenSource>::parse_lifetime (bool allow_elided) { const_TokenPtr lifetime_tok = lexer.peek_token (); if (lifetime_tok->get_id () != LIFETIME) { - return (allow_elided) ? AST::Lifetime::elided () - : AST::Lifetime::error (); + if (allow_elided) + { + return AST::Lifetime::elided (); + } + else + { + return tl::make_unexpected<ParseLifetimeError> ({}); + } } lexer.skip_token (); @@ -6340,14 +6347,14 @@ Parser<ManagedTokenSource>::parse_path_generic_args () location_t locus = t->get_locus (); while (!is_right_angle_tok (t->get_id ())) { - AST::Lifetime lifetime = parse_lifetime (false); - if (lifetime.is_error ()) + auto lifetime = parse_lifetime (false); + if (!lifetime) { // not necessarily an error break; } - lifetime_args.push_back (std::move (lifetime)); + lifetime_args.push_back (std::move (lifetime.value ())); // if next token isn't comma, then it must be end of list if (lexer.peek_token ()->get_id () != COMMA) @@ -6961,10 +6968,12 @@ Parser<ManagedTokenSource>::parse_self_param () // now test whether it has a lifetime if (lexer.peek_token ()->get_id () == LIFETIME) { - lifetime = parse_lifetime (true); - // something went wrong somehow - if (lifetime.is_error ()) + if (auto parsed_lifetime = parse_lifetime (true)) + { + lifetime = parsed_lifetime.value (); + } + else { Error error (lexer.peek_token ()->get_locus (), "failed to parse lifetime in self param"); @@ -7153,9 +7162,9 @@ Parser<ManagedTokenSource>::parse_expr_stmt (AST::AttrVec outer_attrs, // Parses a block expression, including the curly braces at start and end. template <typename ManagedTokenSource> std::unique_ptr<AST::BlockExpr> -Parser<ManagedTokenSource>::parse_block_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, - location_t pratt_parsed_loc) +Parser<ManagedTokenSource>::parse_block_expr ( + AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label, + location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) @@ -7519,12 +7528,10 @@ Parser<ManagedTokenSource>::parse_break_expr (AST::AttrVec outer_attrs, skip_token (BREAK); } - // parse label (lifetime) if it exists - create dummy first - AST::Lifetime label = AST::Lifetime::error (); - if (lexer.peek_token ()->get_id () == LIFETIME) - { - label = parse_lifetime (false); - } + auto parsed_label = parse_lifetime (false); + auto label = (parsed_label) + ? tl::optional<AST::Lifetime> (parsed_label.value ()) + : tl::nullopt; // parse break return expression if it exists ParseRestrictions restrictions; @@ -7550,12 +7557,10 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs, skip_token (CONTINUE); } - // parse label (lifetime) if it exists - create dummy first - AST::Lifetime label = AST::Lifetime::error (); - if (lexer.peek_token ()->get_id () == LIFETIME) - { - label = parse_lifetime (false); - } + auto parsed_label = parse_lifetime (false); + auto label = (parsed_label) + ? tl::optional<AST::Lifetime> (parsed_label.value ()) + : tl::nullopt; return std::unique_ptr<AST::ContinueExpr> ( new AST::ContinueExpr (std::move (label), std::move (outer_attrs), locus)); @@ -7563,14 +7568,15 @@ Parser<ManagedTokenSource>::parse_continue_expr (AST::AttrVec outer_attrs, // Parses a loop label used in loop expressions. template <typename ManagedTokenSource> -AST::LoopLabel +tl::expected<AST::LoopLabel, ParseLoopLabelError> Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok) { // parse lifetime - if doesn't exist, assume no label if (tok->get_id () != LIFETIME) { // not necessarily an error - return AST::LoopLabel::error (); + return tl::unexpected<ParseLoopLabelError> ( + ParseLoopLabelError::NOT_LOOP_LABEL); } /* FIXME: check for named lifetime requirement here? or check in semantic * analysis phase? */ @@ -7579,10 +7585,12 @@ Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok) if (!skip_token (COLON)) { // skip somewhere? - return AST::LoopLabel::error (); + return tl::unexpected<ParseLoopLabelError> ( + ParseLoopLabelError::MISSING_COLON); } - return AST::LoopLabel (std::move (label), tok->get_locus ()); + return tl::expected<AST::LoopLabel, ParseLoopLabelError> ( + AST::LoopLabel (std::move (label), tok->get_locus ())); } /* Parses an if expression of any kind, including with else, else if, else if @@ -7935,16 +7943,16 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec outer_attrs, template <typename ManagedTokenSource> std::unique_ptr<AST::LoopExpr> Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, + tl::optional<AST::LoopLabel> label, location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) { - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); if (!skip_token (LOOP)) { @@ -7954,8 +7962,8 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs, } else { - if (!label.is_error ()) - locus = label.get_locus (); + if (label) + locus = label->get_locus (); } // parse loop body, which is required @@ -7978,17 +7986,17 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec outer_attrs, * via parse_labelled_loop_expr, which would call this. */ template <typename ManagedTokenSource> std::unique_ptr<AST::WhileLoopExpr> -Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label, - location_t pratt_parsed_loc) +Parser<ManagedTokenSource>::parse_while_loop_expr ( + AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label, + location_t pratt_parsed_loc) { location_t locus = pratt_parsed_loc; if (locus == UNKNOWN_LOCATION) { - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); if (!skip_token (WHILE)) { @@ -7998,8 +8006,8 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs, } else { - if (!label.is_error ()) - locus = label.get_locus (); + if (label) + locus = label->get_locus (); } // ensure it isn't a while let loop @@ -8051,14 +8059,14 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (AST::AttrVec outer_attrs, * parsed via parse_labelled_loop_expr, which would call this. */ template <typename ManagedTokenSource> std::unique_ptr<AST::WhileLetLoopExpr> -Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label) +Parser<ManagedTokenSource>::parse_while_let_loop_expr ( + AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label) { location_t locus = UNKNOWN_LOCATION; - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); maybe_skip_token (WHILE); /* check for possible accidental recognition of a while loop as a while let @@ -8125,14 +8133,14 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (AST::AttrVec outer_attrs, * parse_labelled_loop_expr, which would call this. */ template <typename ManagedTokenSource> std::unique_ptr<AST::ForLoopExpr> -Parser<ManagedTokenSource>::parse_for_loop_expr (AST::AttrVec outer_attrs, - AST::LoopLabel label) +Parser<ManagedTokenSource>::parse_for_loop_expr ( + AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label) { location_t locus = UNKNOWN_LOCATION; - if (label.is_error ()) - locus = lexer.peek_token ()->get_locus (); + if (label) + locus = label->get_locus (); else - locus = label.get_locus (); + locus = lexer.peek_token ()->get_locus (); maybe_skip_token (FOR); // parse pattern, which is required @@ -8210,8 +8218,9 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok, } // parse loop label (required) - AST::LoopLabel label = parse_loop_label (tok); - if (label.is_error ()) + // TODO: Convert this return type to tl::expected instead of tl::optional + auto parsed_label = parse_loop_label (tok); + if (!parsed_label) { Error error (lexer.peek_token ()->get_locus (), "failed to parse loop label in labelled loop expr"); @@ -8221,6 +8230,10 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok, return nullptr; } + auto label = parsed_label + ? tl::optional<AST::LoopLabel> (parsed_label.value ()) + : tl::nullopt; + // branch on next token const_TokenPtr t = lexer.peek_token (); switch (t->get_id ()) @@ -9598,8 +9611,12 @@ Parser<ManagedTokenSource>::parse_reference_type_inner (location_t locus) AST::Lifetime lifetime = AST::Lifetime::elided (); if (lexer.peek_token ()->get_id () == LIFETIME) { - lifetime = parse_lifetime (true); - if (lifetime.is_error ()) + auto parsed_lifetime = parse_lifetime (true); + if (parsed_lifetime) + { + lifetime = parsed_lifetime.value (); + } + else { Error error (lexer.peek_token ()->get_locus (), "failed to parse lifetime in reference type"); @@ -12400,8 +12417,8 @@ Parser<ManagedTokenSource>::null_denotation_not_path ( return parse_continue_expr (std::move (outer_attrs), tok->get_locus ()); case LEFT_CURLY: // ok - this is an expression with block for once. - return parse_block_expr (std::move (outer_attrs), - AST::LoopLabel::error (), tok->get_locus ()); + return parse_block_expr (std::move (outer_attrs), tl::nullopt, + tok->get_locus ()); case IF: // if or if let, so more lookahead to find out if (lexer.peek_token ()->get_id () == LET) @@ -12417,7 +12434,7 @@ Parser<ManagedTokenSource>::null_denotation_not_path ( case LIFETIME: return parse_labelled_loop_expr (tok, std::move (outer_attrs)); case LOOP: - return parse_loop_expr (std::move (outer_attrs), AST::LoopLabel::error (), + return parse_loop_expr (std::move (outer_attrs), tl::nullopt, tok->get_locus ()); case WHILE: if (lexer.peek_token ()->get_id () == LET) @@ -12426,13 +12443,11 @@ Parser<ManagedTokenSource>::null_denotation_not_path ( } else { - return parse_while_loop_expr (std::move (outer_attrs), - AST::LoopLabel::error (), + return parse_while_loop_expr (std::move (outer_attrs), tl::nullopt, tok->get_locus ()); } case FOR: - return parse_for_loop_expr (std::move (outer_attrs), - AST::LoopLabel::error ()); + return parse_for_loop_expr (std::move (outer_attrs), tl::nullopt); case MATCH_KW: // also an expression with block return parse_match_expr (std::move (outer_attrs), tok->get_locus ()); diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 6c50ba9..ff79879 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -25,6 +25,26 @@ along with GCC; see the file COPYING3. If not see #include "expected.h" namespace Rust { + +class ParseLifetimeParamError +{ +}; + +class ParseLifetimeError +{ +}; +enum class ParseLoopLabelError +{ + NOT_LOOP_LABEL, + MISSING_COLON, +}; +enum ParseSelfError +{ + SELF_PTR, + PARSING, + NOT_SELF, +}; + /* HACK: used to resolve the expression-or-statement problem at the end of a * block by allowing either to be returned (technically). Tagged union would * probably take up the same amount of space. */ @@ -95,12 +115,6 @@ struct ParseRestrictions bool allow_close_after_expr_stmt = false; }; -enum ParseSelfError -{ - SELF_PTR, - PARSING, - NOT_SELF, -}; // Parser implementation for gccrs. // TODO: if updated to C++20, ManagedTokenSource would be useful as a concept template <typename ManagedTokenSource> class Parser @@ -148,7 +162,7 @@ public: std::unique_ptr<AST::BlockExpr> parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional<AST::LoopLabel> = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); bool is_macro_rules_def (const_TokenPtr t); @@ -277,7 +291,8 @@ private: ParseFunction parsing_function, EndTokenPred is_end_token, std::string error_msg = "failed to parse generic param in generic params") -> std::vector<decltype (parsing_function ())>; - AST::LifetimeParam parse_lifetime_param (); + tl::expected<AST::LifetimeParam, ParseLifetimeParamError> + parse_lifetime_param (); std::vector<std::unique_ptr<AST::TypeParam>> parse_type_params (); template <typename EndTokenPred> std::vector<std::unique_ptr<AST::TypeParam>> @@ -306,7 +321,8 @@ private: std::vector<AST::Lifetime> parse_lifetime_bounds (); template <typename EndTokenPred> std::vector<AST::Lifetime> parse_lifetime_bounds (EndTokenPred is_end_token); - AST::Lifetime parse_lifetime (bool allow_elided); + tl::expected<AST::Lifetime, ParseLifetimeError> + parse_lifetime (bool allow_elided); AST::Lifetime lifetime_from_token (const_TokenPtr tok); std::unique_ptr<AST::ExternalTypeItem> parse_external_type_item (AST::Visibility vis, AST::AttrVec outer_attrs); @@ -588,18 +604,18 @@ private: location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr<AST::LoopExpr> parse_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional<AST::LoopLabel> label = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr<AST::WhileLoopExpr> parse_while_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error (), + tl::optional<AST::LoopLabel> label = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); std::unique_ptr<AST::WhileLetLoopExpr> parse_while_let_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error ()); + tl::optional<AST::LoopLabel> label = tl::nullopt); std::unique_ptr<AST::ForLoopExpr> parse_for_loop_expr (AST::AttrVec outer_attrs = AST::AttrVec (), - AST::LoopLabel label = AST::LoopLabel::error ()); + tl::optional<AST::LoopLabel> label = tl::nullopt); std::unique_ptr<AST::MatchExpr> parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (), location_t pratt_parsed_loc = UNKNOWN_LOCATION); @@ -609,7 +625,8 @@ private: std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok, AST::AttrVec outer_attrs = AST::AttrVec ()); - AST::LoopLabel parse_loop_label (const_TokenPtr tok); + tl::expected<AST::LoopLabel, ParseLoopLabelError> + parse_loop_label (const_TokenPtr tok); std::unique_ptr<AST::AsyncBlockExpr> parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); std::unique_ptr<AST::GroupedExpr> parse_grouped_expr (AST::AttrVec outer_attrs diff --git a/gcc/rust/resolve/rust-ast-resolve-base.h b/gcc/rust/resolve/rust-ast-resolve-base.h index 0d497f8..ab74e84 100644 --- a/gcc/rust/resolve/rust-ast-resolve-base.h +++ b/gcc/rust/resolve/rust-ast-resolve-base.h @@ -27,6 +27,11 @@ namespace Rust { namespace Resolver { +inline void +redefined_error (const rich_location &loc) +{ + rust_error_at (loc, "redefined multiple times"); +} class ResolverBase : public AST::ASTVisitor { diff --git a/gcc/rust/resolve/rust-ast-resolve-expr.cc b/gcc/rust/resolve/rust-ast-resolve-expr.cc index dc7f76d..8070fc1 100644 --- a/gcc/rust/resolve/rust-ast-resolve-expr.cc +++ b/gcc/rust/resolve/rust-ast-resolve-expr.cc @@ -471,7 +471,7 @@ ResolveExpr::visit (AST::BreakExpr &expr) { if (expr.has_label ()) { - auto label = expr.get_label ().get_lifetime (); + auto label = expr.get_label_unchecked ().get_lifetime (); if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) { rust_error_at (label.get_locus (), @@ -486,8 +486,8 @@ ResolveExpr::visit (AST::BreakExpr &expr) &resolved_node)) { rust_error_at (label.get_locus (), ErrorCode::E0426, - "use of undeclared label %qs in %<break%>", - label.get_lifetime_name ().c_str ()); + "use of undeclared label %qs", + label.as_string ().c_str ()); return; } resolver->insert_resolved_label (label.get_node_id (), resolved_node); @@ -594,7 +594,7 @@ ResolveExpr::visit (AST::ContinueExpr &expr) { if (expr.has_label ()) { - auto label = expr.get_label (); + auto label = expr.get_label_unchecked (); if (label.get_lifetime_type () != AST::Lifetime::LifetimeType::NAMED) { rust_error_at (label.get_locus (), @@ -608,9 +608,9 @@ ResolveExpr::visit (AST::ContinueExpr &expr) label.get_lifetime_name ()), &resolved_node)) { - rust_error_at (expr.get_label ().get_locus (), ErrorCode::E0426, - "use of undeclared label %qs in %<continue%>", - label.get_lifetime_name ().c_str ()); + rust_error_at (expr.get_label_unchecked ().get_locus (), + ErrorCode::E0426, "use of undeclared label %qs", + label.as_string ().c_str ()); return; } resolver->insert_resolved_label (label.get_node_id (), resolved_node); diff --git a/gcc/rust/resolve/rust-ast-resolve-implitem.h b/gcc/rust/resolve/rust-ast-resolve-implitem.h index 971bf8f..2081697 100644 --- a/gcc/rust/resolve/rust-ast-resolve-implitem.h +++ b/gcc/rust/resolve/rust-ast-resolve-implitem.h @@ -51,7 +51,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -67,7 +67,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -84,7 +84,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } @@ -124,7 +124,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (function.get_node_id (), cpath); @@ -144,7 +144,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (constant.get_node_id (), cpath); @@ -162,7 +162,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (type.get_node_id (), cpath); @@ -202,7 +202,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -221,7 +221,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -239,8 +239,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, type.get_locus ()); r.add_range (locus); - - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.cc b/gcc/rust/resolve/rust-ast-resolve-stmt.cc index fefb522..bfba302 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.cc +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.cc @@ -70,7 +70,7 @@ ResolveStmt::visit (AST::StaticItem &var) [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, var.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); ResolveType::go (var.get_type ()); diff --git a/gcc/rust/resolve/rust-ast-resolve-stmt.h b/gcc/rust/resolve/rust-ast-resolve-stmt.h index 6c99d6a..d413a7c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-stmt.h +++ b/gcc/rust/resolve/rust-ast-resolve-stmt.h @@ -63,7 +63,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); ResolveType::go (constant.get_type ()); @@ -98,7 +98,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = struct_decl.get_node_id (); @@ -129,7 +129,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, enum_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = enum_decl.get_node_id (); @@ -159,7 +159,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); // Done, no fields. @@ -179,7 +179,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &field : item.get_tuple_fields ()) @@ -205,7 +205,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &field : item.get_struct_fields ()) @@ -231,7 +231,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); // Done, no fields. @@ -252,7 +252,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = struct_decl.get_node_id (); @@ -288,7 +288,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, union_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = union_decl.get_node_id (); @@ -324,7 +324,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId scope_node_id = function.get_node_id (); diff --git a/gcc/rust/resolve/rust-ast-resolve-toplevel.h b/gcc/rust/resolve/rust-ast-resolve-toplevel.h index 379ccab..f52fb8a 100644 --- a/gcc/rust/resolve/rust-ast-resolve-toplevel.h +++ b/gcc/rust/resolve/rust-ast-resolve-toplevel.h @@ -58,7 +58,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, module.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -88,7 +88,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, alias.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -110,7 +110,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -132,7 +132,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, enum_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); resolver->push_new_module_scope (enum_decl.get_node_id ()); @@ -158,7 +158,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -180,7 +180,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -202,7 +202,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -224,7 +224,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, item.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); mappings.insert_canonical_path (item.get_node_id (), cpath); @@ -246,7 +246,7 @@ public: = [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, struct_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }; resolver->get_type_scope ().insert (path, struct_decl.get_node_id (), @@ -277,7 +277,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, union_decl.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -297,7 +297,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, var.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -318,7 +318,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, constant.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -340,7 +340,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, function.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); NodeId current_module = resolver->peek_current_module_scope (); @@ -388,7 +388,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, impl_block.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &impl_item : impl_block.get_impl_items ()) @@ -408,7 +408,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, trait.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); for (auto &item : trait.get_trait_items ()) @@ -480,7 +480,7 @@ public: [&] (const CanonicalPath &, NodeId, location_t locus) -> void { rich_location r (line_table, extern_crate.get_locus ()); r.add_range (locus); - rust_error_at (r, "defined multiple times"); + redefined_error (r); }); } diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc index 5ab0c44..606141c 100644 --- a/gcc/rust/resolve/rust-ast-resolve-type.cc +++ b/gcc/rust/resolve/rust-ast-resolve-type.cc @@ -357,7 +357,7 @@ ResolveRelativeTypePath::go (AST::TypePath &path, NodeId &resolved_node_id) { rust_error_at (segment->get_locus (), ErrorCode::E0412, "could not resolve type path %qs", - segment->as_string ().c_str ()); + segment->get_ident_segment ().as_string ().c_str ()); return false; } } diff --git a/gcc/rust/resolve/rust-forever-stack.h b/gcc/rust/resolve/rust-forever-stack.h index f390e38..cf02651 100644 --- a/gcc/rust/resolve/rust-forever-stack.h +++ b/gcc/rust/resolve/rust-forever-stack.h @@ -549,6 +549,7 @@ public: ForeverStack () : root (Node (Rib (Rib::Kind::Normal), UNKNOWN_NODEID)), lang_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID, root)), + extern_prelude (Node (Rib (Rib::Kind::Prelude), UNKNOWN_NODEID)), cursor_reference (root) { rust_assert (root.is_root ()); @@ -671,7 +672,7 @@ public: */ template <typename S> tl::optional<Rib::Definition> resolve_path ( - const std::vector<S> &segments, + const std::vector<S> &segments, bool has_opening_scope_resolution, std::function<void (const S &, NodeId)> insert_segment_resolution); // FIXME: Documentation @@ -768,6 +769,10 @@ private: * resolution */ Node lang_prelude; + /* + * The extern prelude, used for resolving external crates + */ + Node extern_prelude; std::reference_wrapper<Node> cursor_reference; diff --git a/gcc/rust/resolve/rust-forever-stack.hxx b/gcc/rust/resolve/rust-forever-stack.hxx index 885f282..993e2d4 100644 --- a/gcc/rust/resolve/rust-forever-stack.hxx +++ b/gcc/rust/resolve/rust-forever-stack.hxx @@ -20,6 +20,7 @@ #include "rust-ast.h" #include "rust-diagnostics.h" #include "rust-forever-stack.h" +#include "rust-edition.h" #include "rust-rib.h" #include "rust-unwrap-segment.h" #include "optional.h" @@ -618,11 +619,24 @@ template <Namespace N> template <typename S> tl::optional<Rib::Definition> ForeverStack<N>::resolve_path ( - const std::vector<S> &segments, + const std::vector<S> &segments, bool has_opening_scope_resolution, std::function<void (const S &, NodeId)> insert_segment_resolution) { // TODO: What to do if segments.empty() ? + // handle paths with opening scopes + std::function<void (void)> cleanup_current = [] () {}; + if (has_opening_scope_resolution) + { + Node *last_current = &cursor_reference.get (); + if (get_rust_edition () == Edition::E2015) + cursor_reference = root; + else + cursor_reference = extern_prelude; + cleanup_current + = [this, last_current] () { cursor_reference = *last_current; }; + } + // if there's only one segment, we just use `get` if (segments.size () == 1) { @@ -633,6 +647,7 @@ ForeverStack<N>::resolve_path ( lang_item.value ()); insert_segment_resolution (seg, seg_id); + cleanup_current (); // TODO: does NonShadowable matter? return Rib::Definition::NonShadowable (seg_id); } @@ -646,40 +661,44 @@ ForeverStack<N>::resolve_path ( if (res && !res->is_ambiguous ()) insert_segment_resolution (segments.back (), res->get_node_id ()); + cleanup_current (); return res; } std::reference_wrapper<Node> starting_point = cursor (); - return find_starting_point (segments, starting_point, - insert_segment_resolution) - .and_then ([this, &segments, &starting_point, &insert_segment_resolution] ( - typename std::vector<S>::const_iterator iterator) { - return resolve_segments (starting_point.get (), segments, iterator, - insert_segment_resolution); - }) - .and_then ([this, &segments, &insert_segment_resolution] ( - Node final_node) -> tl::optional<Rib::Definition> { - // leave resolution within impl blocks to type checker - if (final_node.rib.kind == Rib::Kind::TraitOrImpl) - return tl::nullopt; - - auto &seg = unwrap_type_segment (segments.back ()); - std::string seg_name = seg.as_string (); - - // assuming this can't be a lang item segment - tl::optional<Rib::Definition> res - = resolve_final_segment (final_node, seg_name, - seg.is_lower_self_seg ()); - // Ok we didn't find it in the rib, Lets try the prelude... - if (!res) - res = get_lang_prelude (seg_name); - - if (res && !res->is_ambiguous ()) - insert_segment_resolution (segments.back (), res->get_node_id ()); - - return res; - }); + auto res + = find_starting_point (segments, starting_point, insert_segment_resolution) + .and_then ( + [this, &segments, &starting_point, &insert_segment_resolution] ( + typename std::vector<S>::const_iterator iterator) { + return resolve_segments (starting_point.get (), segments, iterator, + insert_segment_resolution); + }) + .and_then ([this, &segments, &insert_segment_resolution] ( + Node final_node) -> tl::optional<Rib::Definition> { + // leave resolution within impl blocks to type checker + if (final_node.rib.kind == Rib::Kind::TraitOrImpl) + return tl::nullopt; + + auto &seg = unwrap_type_segment (segments.back ()); + std::string seg_name = seg.as_string (); + + // assuming this can't be a lang item segment + tl::optional<Rib::Definition> res + = resolve_final_segment (final_node, seg_name, + seg.is_lower_self_seg ()); + // Ok we didn't find it in the rib, Lets try the prelude... + if (!res) + res = get_lang_prelude (seg_name); + + if (res && !res->is_ambiguous ()) + insert_segment_resolution (segments.back (), res->get_node_id ()); + + return res; + }); + cleanup_current (); + return res; } template <Namespace N> diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc index 7d32374..f743e1e 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc @@ -187,6 +187,9 @@ Late::visit (AST::SelfParam ¶m) void Late::visit (AST::BreakExpr &expr) { + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ().get_lifetime ()); + if (expr.has_break_expr ()) { auto &break_expr = expr.get_break_expr (); @@ -213,6 +216,38 @@ Late::visit (AST::BreakExpr &expr) } void +Late::visit (AST::LoopLabel &label) +{ + auto &lifetime = label.get_lifetime (); + ctx.labels.insert (Identifier (lifetime.as_string (), lifetime.get_locus ()), + lifetime.get_node_id ()); +} + +void +Late::resolve_label (AST::Lifetime &lifetime) +{ + if (auto resolved = ctx.labels.get (lifetime.as_string ())) + { + if (resolved->get_node_id () != lifetime.get_node_id ()) + ctx.map_usage (Usage (lifetime.get_node_id ()), + Definition (resolved->get_node_id ())); + } + else + rust_error_at (lifetime.get_locus (), ErrorCode::E0426, + "use of undeclared label %qs", + lifetime.as_string ().c_str ()); +} + +void +Late::visit (AST::ContinueExpr &expr) +{ + if (expr.has_label ()) + resolve_label (expr.get_label_unchecked ()); + + DefaultResolver::visit (expr); +} + +void Late::visit (AST::IdentifierExpr &expr) { // TODO: same thing as visit(PathInExpression) here? @@ -307,8 +342,7 @@ Late::visit (AST::PathInExpression &expr) return; } - auto resolved = ctx.resolve_path (expr.get_segments (), Namespace::Values, - Namespace::Types); + auto resolved = ctx.resolve_path (expr, Namespace::Values, Namespace::Types); if (!resolved) { @@ -340,13 +374,9 @@ Late::visit (AST::TypePath &type) DefaultResolver::visit (type); - // take care of only simple cases - // TODO: remove this? - rust_assert (!type.has_opening_scope_resolution_op ()); - // this *should* mostly work // TODO: make sure typepath-like path resolution (?) is working - auto resolved = ctx.resolve_path (type.get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (type, Namespace::Types); if (!resolved.has_value ()) { @@ -394,8 +424,7 @@ Late::visit (AST::StructExprStruct &s) visit_inner_attrs (s); DefaultResolver::visit (s.get_struct_name ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -409,8 +438,7 @@ Late::visit (AST::StructExprStructBase &s) DefaultResolver::visit (s.get_struct_name ()); visit (s.get_struct_base ()); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); @@ -427,8 +455,7 @@ Late::visit (AST::StructExprStructFields &s) for (auto &field : s.get_fields ()) visit (field); - auto resolved - = ctx.resolve_path (s.get_struct_name ().get_segments (), Namespace::Types); + auto resolved = ctx.resolve_path (s.get_struct_name (), Namespace::Types); ctx.map_usage (Usage (s.get_struct_name ().get_node_id ()), Definition (resolved->get_node_id ())); diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.h b/gcc/rust/resolve/rust-late-name-resolver-2.0.h index ac376b5..5703b15 100644 --- a/gcc/rust/resolve/rust-late-name-resolver-2.0.h +++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.h @@ -48,6 +48,8 @@ public: void visit (AST::IdentifierExpr &) override; void visit (AST::StructExprFieldIdentifier &) override; void visit (AST::BreakExpr &) override; + void visit (AST::ContinueExpr &) override; + void visit (AST::LoopLabel &) override; void visit (AST::PathInExpression &) override; void visit (AST::TypePath &) override; void visit (AST::Trait &) override; @@ -61,6 +63,8 @@ public: void visit (AST::ClosureExprInnerTyped &) override; private: + void resolve_label (AST::Lifetime &lifetime); + /* Setup Rust's builtin types (u8, i32, !...) in the resolver */ void setup_builtin_types (); diff --git a/gcc/rust/resolve/rust-name-resolution-context.h b/gcc/rust/resolve/rust-name-resolution-context.h index ea81bde..84c0800 100644 --- a/gcc/rust/resolve/rust-name-resolution-context.h +++ b/gcc/rust/resolve/rust-name-resolution-context.h @@ -221,6 +221,7 @@ public: template <typename S> tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments, + bool has_opening_scope_resolution, Namespace ns) { std::function<void (const S &, NodeId)> insert_segment_resolution @@ -232,13 +233,17 @@ public: switch (ns) { case Namespace::Values: - return values.resolve_path (segments, insert_segment_resolution); + return values.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Types: - return types.resolve_path (segments, insert_segment_resolution); + return types.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Macros: - return macros.resolve_path (segments, insert_segment_resolution); + return macros.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); case Namespace::Labels: - return labels.resolve_path (segments, insert_segment_resolution); + return labels.resolve_path (segments, has_opening_scope_resolution, + insert_segment_resolution); default: rust_unreachable (); } @@ -246,19 +251,45 @@ public: template <typename S, typename... Args> tl::optional<Rib::Definition> resolve_path (const std::vector<S> &segments, + bool has_opening_scope_resolution, Args... ns_args) { std::initializer_list<Namespace> namespaces = {ns_args...}; for (auto ns : namespaces) { - if (auto ret = resolve_path (segments, ns)) + if (auto ret + = resolve_path (segments, has_opening_scope_resolution, ns)) return ret; } return tl::nullopt; } + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::SimplePath &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), + path.has_opening_scope_resolution (), ns_args...); + } + + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::PathInExpression &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), path.opening_scope_resolution (), + ns_args...); + } + + template <typename... Args> + tl::optional<Rib::Definition> resolve_path (const AST::TypePath &path, + Args... ns_args) + { + return resolve_path (path.get_segments (), + path.has_opening_scope_resolution_op (), ns_args...); + } + private: /* Map of "usage" nodes which have been resolved to a "definition" node */ std::map<Usage, Definition> resolved_nodes; diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc index a6e8ea9..72aef08 100644 --- a/gcc/rust/rust-gcc.cc +++ b/gcc/rust/rust-gcc.cc @@ -1074,6 +1074,12 @@ arithmetic_or_logical_expression (ArithmeticOrLogicalOperator op, tree left, if (left == error_mark_node || right == error_mark_node) return error_mark_node; + // unwrap the const decls if set + if (TREE_CODE (left) == CONST_DECL) + left = DECL_INITIAL (left); + if (TREE_CODE (right) == CONST_DECL) + right = DECL_INITIAL (right); + /* We need to determine if we're doing floating point arithmetics of integer arithmetics. */ bool floating_point = is_floating_point (left); diff --git a/gcc/rust/typecheck/rust-hir-trait-resolve.cc b/gcc/rust/typecheck/rust-hir-trait-resolve.cc index e4a61bd..e78c192 100644 --- a/gcc/rust/typecheck/rust-hir-trait-resolve.cc +++ b/gcc/rust/typecheck/rust-hir-trait-resolve.cc @@ -157,7 +157,13 @@ TraitResolver::resolve_path_to_trait (const HIR::TypePath &path, } auto resolved_item = mappings.lookup_hir_item (hid.value ()); - rust_assert (resolved_item.has_value ()); + if (!resolved_item.has_value ()) + { + rust_error_at (path.get_locus (), + "Failed to resolve trait by looking up hir node"); + return false; + } + if (resolved_item.value ()->get_item_kind () != HIR::Item::ItemKind::Trait) { rich_location r (line_table, path.get_locus ()); @@ -228,7 +234,9 @@ TraitResolver::resolve_trait (HIR::Trait *trait_reference) // The one exception is the implicit Self type of a trait bool apply_sized = !is_self; auto param_type - = TypeResolveGenericParam::Resolve (*generic_param, apply_sized); + = TypeResolveGenericParam::Resolve (*generic_param, true, + apply_sized); + context->insert_type (generic_param->get_mappings (), param_type); substitutions.push_back ( TyTy::SubstitutionParamMapping (typaram, param_type)); diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.cc b/gcc/rust/typecheck/rust-hir-type-check-base.cc index 34a726c..beee91e 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-base.cc @@ -31,6 +31,16 @@ TypeCheckBase::TypeCheckBase () context (TypeCheckContext::get ()) {} +void +TypeCheckBase::ResolveGenericParams ( + const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params, + std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign, + ABI abi) +{ + TypeCheckBase ctx; + ctx.resolve_generic_params (generic_params, substitutions, is_foreign, abi); +} + static void walk_types_to_constrain (std::set<HirId> &constrained_symbols, const TyTy::SubstitutionArgumentMappings &constraints) @@ -387,7 +397,8 @@ TypeCheckBase::parse_repr_options (const AST::AttrVec &attrs, location_t locus) void TypeCheckBase::resolve_generic_params ( const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params, - std::vector<TyTy::SubstitutionParamMapping> &substitutions) + std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign, + ABI abi) { for (auto &generic_param : generic_params) { @@ -397,15 +408,18 @@ TypeCheckBase::resolve_generic_params ( auto lifetime_param = static_cast<HIR::LifetimeParam &> (*generic_param); auto lifetime = lifetime_param.get_lifetime (); - rust_assert (lifetime.get_lifetime_type () - == AST::Lifetime::LifetimeType::NAMED); context->get_lifetime_resolver ().insert_mapping ( context->intern_lifetime (lifetime)); } - break; case HIR::GenericParam::GenericKind::CONST: { + if (is_foreign && abi != Rust::ABI::INTRINSIC) + { + rust_error_at (generic_param->get_locus (), ErrorCode::E0044, + "foreign items may not have const parameters"); + } + auto ¶m = static_cast<HIR::ConstGenericParam &> (*generic_param); auto specified_type = TypeCheckType::Resolve (param.get_type ()); @@ -429,15 +443,31 @@ TypeCheckBase::resolve_generic_params ( break; case HIR::GenericParam::GenericKind::TYPE: { - auto param_type = TypeResolveGenericParam::Resolve (*generic_param); + if (is_foreign && abi != Rust::ABI::INTRINSIC) + { + rust_error_at (generic_param->get_locus (), ErrorCode::E0044, + "foreign items may not have type parameters"); + } + + auto param_type = TypeResolveGenericParam::Resolve ( + *generic_param, false /*resolve_trait_bounds*/); context->insert_type (generic_param->get_mappings (), param_type); - substitutions.push_back (TyTy::SubstitutionParamMapping ( - static_cast<HIR::TypeParam &> (*generic_param), param_type)); + auto ¶m = static_cast<HIR::TypeParam &> (*generic_param); + TyTy::SubstitutionParamMapping p (param, param_type); + substitutions.push_back (p); } break; } } + + // now walk them to setup any specified type param bounds + for (auto &subst : substitutions) + { + auto pty = subst.get_param_ty (); + TypeResolveGenericParam::ApplyAnyTraitBounds (subst.get_generic_param (), + pty); + } } TyTy::TypeBoundPredicate diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h index 8a1bf6f..580082a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-base.h +++ b/gcc/rust/typecheck/rust-hir-type-check-base.h @@ -32,6 +32,11 @@ class TypeCheckBase public: virtual ~TypeCheckBase () {} + static void ResolveGenericParams ( + const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params, + std::vector<TyTy::SubstitutionParamMapping> &substitutions, bool is_foreign, + ABI abi); + protected: TypeCheckBase (); @@ -57,7 +62,8 @@ protected: void resolve_generic_params ( const std::vector<std::unique_ptr<HIR::GenericParam>> &generic_params, - std::vector<TyTy::SubstitutionParamMapping> &substitutions); + std::vector<TyTy::SubstitutionParamMapping> &substitutions, + bool is_foreign = false, ABI abi = ABI::RUST); TyTy::TypeBoundPredicate get_marker_predicate (LangItem::Kind item_type, location_t locus); diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc b/gcc/rust/typecheck/rust-hir-type-check-expr.cc index b7fdc13..791795f 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc @@ -1463,6 +1463,15 @@ TypeCheckExpr::visit (HIR::BorrowExpr &expr) } } + if (expr.is_raw_borrow ()) + { + infered = new TyTy::PointerType (expr.get_mappings ().get_hirid (), + TyTy::TyVar (resolved_base->get_ref ()), + expr.get_mut ()); + + return; + } + infered = new TyTy::ReferenceType (expr.get_mappings ().get_hirid (), TyTy::TyVar (resolved_base->get_ref ()), expr.get_mut ()); diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc index a5ae54b..bc7f6dc 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc @@ -73,44 +73,8 @@ TypeCheckTopLevelExternItem::visit (HIR::ExternalFunctionItem &function) std::vector<TyTy::SubstitutionParamMapping> substitutions; if (function.has_generics ()) { - for (auto &generic_param : function.get_generic_params ()) - { - switch (generic_param.get ()->get_kind ()) - { - case HIR::GenericParam::GenericKind::LIFETIME: - context->intern_and_insert_lifetime ( - static_cast<HIR::LifetimeParam &> (*generic_param) - .get_lifetime ()); - // TODO: handle bounds - break; - case HIR::GenericParam::GenericKind::CONST: - // FIXME: Skipping Lifetime and Const completely until better - // handling. - if (parent.get_abi () != Rust::ABI::INTRINSIC) - { - rust_error_at (function.get_locus (), ErrorCode::E0044, - "foreign items may not have const parameters"); - } - break; - - case HIR::GenericParam::GenericKind::TYPE: { - if (parent.get_abi () != Rust::ABI::INTRINSIC) - { - rust_error_at ( - function.get_locus (), ErrorCode::E0044, - "foreign items may not have type parameters"); - } - auto param_type - = TypeResolveGenericParam::Resolve (*generic_param); - context->insert_type (generic_param->get_mappings (), - param_type); - - substitutions.push_back (TyTy::SubstitutionParamMapping ( - static_cast<HIR::TypeParam &> (*generic_param), param_type)); - } - break; - } - } + resolve_generic_params (function.get_generic_params (), substitutions, + true /*is_foreign*/, parent.get_abi ()); } TyTy::RegionConstraints region_constraints; @@ -200,128 +164,7 @@ void TypeCheckTopLevelExternItem::visit (HIR::ExternalTypeItem &type) { rust_sorry_at (type.get_locus (), "extern types are not supported yet"); - // auto binder_pin = context->push_clean_lifetime_resolver (); - - // std::vector<TyTy::SubstitutionParamMapping> substitutions; - // if (function.has_generics ()) - // { - // for (auto &generic_param : function.get_generic_params ()) - // { - // switch (generic_param.get ()->get_kind ()) - // { - // case HIR::GenericParam::GenericKind::LIFETIME: - // context->intern_and_insert_lifetime ( - // static_cast<HIR::LifetimeParam &> (*generic_param) - // .get_lifetime ()); - // // TODO: handle bounds - // break; - // case HIR::GenericParam::GenericKind::CONST: - // // FIXME: Skipping Lifetime and Const completely until better - // // handling. - // break; - - // case HIR::GenericParam::GenericKind::TYPE: { - // auto param_type - // = TypeResolveGenericParam::Resolve (generic_param.get ()); - // context->insert_type (generic_param->get_mappings (), - // param_type); - - // substitutions.push_back (TyTy::SubstitutionParamMapping ( - // static_cast<HIR::TypeParam &> (*generic_param), param_type)); - // } - // break; - // } - // } - // } - - // TyTy::RegionConstraints region_constraints; - // if (function.has_where_clause ()) - // { - // for (auto &where_clause_item : function.get_where_clause ().get_items - // ()) - // { - // ResolveWhereClauseItem::Resolve (*where_clause_item.get (), - // region_constraints); - // } - // } - - // TyTy::BaseType *ret_type = nullptr; - // if (!function.has_return_type ()) - // ret_type - // = TyTy::TupleType::get_unit_type (function.get_mappings ().get_hirid - // ()); - // else - // { - // auto resolved - // = TypeCheckType::Resolve (function.get_return_type ().get ()); - // if (resolved == nullptr) - // { - // rust_error_at (function.get_locus (), - // "failed to resolve return type"); - // return; - // } - - // ret_type = resolved->clone (); - // ret_type->set_ref ( - // function.get_return_type ()->get_mappings ().get_hirid ()); - // } - - // std::vector<std::pair<HIR::Pattern *, TyTy::BaseType *> > params; - // for (auto ¶m : function.get_function_params ()) - // { - // // get the name as well required for later on - // auto param_tyty = TypeCheckType::Resolve (param.get_type ().get ()); - - // // these are implicit mappings and not used - // auto crate_num = mappings->get_current_crate (); - // Analysis::NodeMapping mapping (crate_num, mappings->get_next_node_id - // (), - // mappings->get_next_hir_id (crate_num), - // UNKNOWN_LOCAL_DEFID); - - // HIR::IdentifierPattern *param_pattern - // = new HIR::IdentifierPattern (mapping, param.get_param_name (), - // UNDEF_LOCATION, false, Mutability::Imm, - // std::unique_ptr<HIR::Pattern> (nullptr)); - - // params.push_back ( - // std::pair<HIR::Pattern *, TyTy::BaseType *> (param_pattern, - // param_tyty)); - - // context->insert_type (param.get_mappings (), param_tyty); - - // // FIXME do we need error checking for patterns here? - // // see https://github.com/Rust-GCC/gccrs/issues/995 - // } - - // uint8_t flags = TyTy::FnType::FNTYPE_IS_EXTERN_FLAG; - // if (function.is_variadic ()) - // { - // flags |= TyTy::FnType::FNTYPE_IS_VARADIC_FLAG; - // if (parent.get_abi () != Rust::ABI::C) - // { - // rust_error_at ( - // function.get_locus (), ErrorCode::E0045, - // "C-variadic function must have C or cdecl calling convention"); - // } - // } - - // RustIdent ident{ - // CanonicalPath::new_seg (function.get_mappings ().get_nodeid (), - // function.get_item_name ().as_string ()), - // function.get_locus ()}; - - // auto fnType = new TyTy::FnType ( - // function.get_mappings ().get_hirid (), - // function.get_mappings ().get_defid (), - // function.get_item_name ().as_string (), ident, flags, parent.get_abi (), - // std::move (params), ret_type, std::move (substitutions), - // TyTy::SubstitutionArgumentMappings::empty ( - // context->get_lifetime_resolver ().get_num_bound_regions ()), - // region_constraints); - - // context->insert_type (function.get_mappings (), fnType); - // resolved = fnType; + // TODO } TypeCheckImplItem::TypeCheckImplItem ( @@ -399,7 +242,7 @@ TypeCheckImplItem::visit (HIR::Function &function) // add the synthetic self param at the front, this is a placeholder for // compilation to know parameter names. The types are ignored but we // reuse the HIR identifier pattern which requires it - HIR::SelfParam &self_param = function.get_self_param (); + HIR::SelfParam &self_param = function.get_self_param_unchecked (); // FIXME: which location should be used for Rust::Identifier for `self`? std::unique_ptr<HIR::Pattern> self_pattern = std::make_unique<HIR::IdentifierPattern> ( @@ -424,13 +267,21 @@ TypeCheckImplItem::visit (HIR::Function &function) break; case HIR::SelfParam::IMM_REF: { - auto region = context->lookup_and_resolve_lifetime ( - self_param.get_lifetime ()); - if (!region.has_value ()) + tl::optional<TyTy::Region> region; + if (self_param.has_lifetime ()) { - rust_inform (self_param.get_locus (), - "failed to resolve lifetime"); - region = TyTy::Region::make_anonymous (); // FIXME + region = context->lookup_and_resolve_lifetime ( + self_param.get_lifetime ()); + if (!region.has_value ()) + { + rust_inform (self_param.get_locus (), + "failed to resolve lifetime"); + return; + } + } + else + { + region = TyTy::Region::make_anonymous (); } self_type = new TyTy::ReferenceType ( self_param.get_mappings ().get_hirid (), @@ -440,13 +291,21 @@ TypeCheckImplItem::visit (HIR::Function &function) break; case HIR::SelfParam::MUT_REF: { - auto region = context->lookup_and_resolve_lifetime ( - self_param.get_lifetime ()); - if (!region.has_value ()) + tl::optional<TyTy::Region> region; + if (self_param.has_lifetime ()) + { + region = context->lookup_and_resolve_lifetime ( + self_param.get_lifetime ()); + if (!region.has_value ()) + { + rust_error_at (self_param.get_locus (), + "failed to resolve lifetime"); + return; + } + } + else { - rust_error_at (self_param.get_locus (), - "failed to resolve lifetime"); - return; + region = TyTy::Region::make_anonymous (); } self_type = new TyTy::ReferenceType ( self_param.get_mappings ().get_hirid (), diff --git a/gcc/rust/typecheck/rust-hir-type-check-path.cc b/gcc/rust/typecheck/rust-hir-type-check-path.cc index 1fe39aae..5662da5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-path.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-path.cc @@ -336,7 +336,7 @@ TypeCheckExpr::resolve_root_path (HIR::PathInExpression &expr, size_t *offset, TyTy::BaseType *lookup = nullptr; if (!query_type (ref, &lookup)) { - if (is_root) + if (is_root || root_tyty == nullptr) { rust_error_at (expr.get_locus (), ErrorCode::E0425, "cannot find value %qs in this scope", diff --git a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc index 3f9557a..bd13f7a 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-pattern.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-pattern.cc @@ -277,7 +277,15 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern) infered = pattern_ty; TyTy::ADTType *adt = static_cast<TyTy::ADTType *> (infered); - rust_assert (adt->number_of_variants () > 0); + if (adt->number_of_variants () == 0) + { + HIR::PathInExpression &path = pattern.get_path (); + const AST::SimplePath &sp = path.as_simple_path (); + rust_error_at (pattern.get_locus (), ErrorCode::E0574, + "expected struct, variant or union type, found enum %qs", + sp.as_string ().c_str ()); + return; + } TyTy::VariantDef *variant = adt->get_variants ().at (0); if (adt->is_enum ()) @@ -285,7 +293,16 @@ TypeCheckPattern::visit (HIR::StructPattern &pattern) HirId variant_id = UNKNOWN_HIRID; bool ok = context->lookup_variant_definition ( pattern.get_path ().get_mappings ().get_hirid (), &variant_id); - rust_assert (ok); + if (!ok) + { + HIR::PathInExpression &path = pattern.get_path (); + const AST::SimplePath &sp = path.as_simple_path (); + rust_error_at ( + pattern.get_locus (), ErrorCode::E0574, + "expected struct, variant or union type, found enum %qs", + sp.as_string ().c_str ()); + return; + } ok = adt->lookup_variant_by_id (variant_id, &variant); rust_assert (ok); diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.cc b/gcc/rust/typecheck/rust-hir-type-check-type.cc index 54f50ec..6919093 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-type.cc @@ -417,8 +417,13 @@ TypeCheckType::resolve_root_path (HIR::TypePath &path, size_t *offset, TyTy::BaseType *lookup = nullptr; if (!query_type (ref, &lookup)) { - if (is_root) - return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + if (is_root || root_tyty == nullptr) + { + rust_error_at (seg->get_locus (), + "failed to resolve type path segment: %qs", + seg->as_string ().c_str ()); + return new TyTy::ErrorType (path.get_mappings ().get_hirid ()); + } return root_tyty; } @@ -573,6 +578,7 @@ TypeCheckType::resolve_segments ( ignore_mandatory_trait_items); if (candidates.size () == 0) { + prev_segment->debug (); rust_error_at ( seg->get_locus (), "failed to resolve path segment using an impl Probe"); @@ -797,9 +803,10 @@ TypeCheckType::visit (HIR::ImplTraitType &type) } TyTy::ParamType * -TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, bool apply_sized) +TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, + bool resolve_trait_bounds, bool apply_sized) { - TypeResolveGenericParam resolver (apply_sized); + TypeResolveGenericParam resolver (apply_sized, resolve_trait_bounds); switch (param.get_kind ()) { case HIR::GenericParam::GenericKind::TYPE: @@ -818,6 +825,14 @@ TypeResolveGenericParam::Resolve (HIR::GenericParam ¶m, bool apply_sized) } void +TypeResolveGenericParam::ApplyAnyTraitBounds (HIR::TypeParam ¶m, + TyTy::ParamType *pty) +{ + TypeResolveGenericParam resolver (true, true); + resolver.apply_trait_bounds (param, pty); +} + +void TypeResolveGenericParam::visit (HIR::LifetimeParam ¶m) { // nothing to do @@ -835,6 +850,19 @@ TypeResolveGenericParam::visit (HIR::TypeParam ¶m) if (param.has_type ()) TypeCheckType::Resolve (param.get_type ()); + resolved + = new TyTy::ParamType (param.get_type_representation ().as_string (), + param.get_locus (), + param.get_mappings ().get_hirid (), param, {}); + + if (resolve_trait_bounds) + apply_trait_bounds (param, resolved); +} + +void +TypeResolveGenericParam::apply_trait_bounds (HIR::TypeParam ¶m, + TyTy::ParamType *pty) +{ std::unique_ptr<HIR::Type> implicit_self_bound = nullptr; if (param.has_type_param_bounds ()) { @@ -865,8 +893,6 @@ TypeResolveGenericParam::visit (HIR::TypeParam ¶m) // // We can only do this when we are not resolving the implicit Self for Sized // itself - rust_debug_loc (param.get_locus (), "apply_sized: %s", - apply_sized ? "true" : "false"); if (apply_sized) { TyTy::TypeBoundPredicate sized_predicate @@ -941,10 +967,8 @@ TypeResolveGenericParam::visit (HIR::TypeParam ¶m) } } - resolved = new TyTy::ParamType (param.get_type_representation ().as_string (), - param.get_locus (), - param.get_mappings ().get_hirid (), param, - specified_bounds); + // inherit them + pty->inherit_bounds (specified_bounds); } void diff --git a/gcc/rust/typecheck/rust-hir-type-check-type.h b/gcc/rust/typecheck/rust-hir-type-check-type.h index fc272e6..cc991b6 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-type.h +++ b/gcc/rust/typecheck/rust-hir-type-check-type.h @@ -91,20 +91,27 @@ class TypeResolveGenericParam : public TypeCheckBase { public: static TyTy::ParamType *Resolve (HIR::GenericParam ¶m, + bool resolve_trait_bounds = true, bool apply_sized = true); + static void ApplyAnyTraitBounds (HIR::TypeParam ¶m, TyTy::ParamType *pty); + protected: void visit (HIR::TypeParam ¶m); void visit (HIR::LifetimeParam ¶m); void visit (HIR::ConstGenericParam ¶m); + void apply_trait_bounds (HIR::TypeParam ¶m, TyTy::ParamType *pty); + private: - TypeResolveGenericParam (bool apply_sized) - : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized) + TypeResolveGenericParam (bool apply_sized, bool resolve_trait_bounds) + : TypeCheckBase (), resolved (nullptr), apply_sized (apply_sized), + resolve_trait_bounds (resolve_trait_bounds) {} TyTy::ParamType *resolved; bool apply_sized; + bool resolve_trait_bounds; }; class ResolveWhereClauseItem : public TypeCheckBase diff --git a/gcc/rust/typecheck/rust-hir-type-check.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index a198ad3..fbaf323 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -165,36 +165,9 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const HIR::TraitFunctionDecl &function = fn.get_decl (); if (function.has_generics ()) { - for (auto &generic_param : function.get_generic_params ()) - { - switch (generic_param.get ()->get_kind ()) - { - case HIR::GenericParam::GenericKind::LIFETIME: { - auto lifetime_param - = static_cast<HIR::LifetimeParam &> (*generic_param); - - context->intern_and_insert_lifetime ( - lifetime_param.get_lifetime ()); - // TODO: Handle lifetime bounds - } - break; - case HIR::GenericParam::GenericKind::CONST: - // FIXME: Skipping Lifetime and Const completely until better - // handling. - break; - - case HIR::GenericParam::GenericKind::TYPE: { - auto param_type - = TypeResolveGenericParam::Resolve (*generic_param); - context->insert_type (generic_param->get_mappings (), - param_type); - - substitutions.push_back (TyTy::SubstitutionParamMapping ( - static_cast<HIR::TypeParam &> (*generic_param), param_type)); - } - break; - } - } + TypeCheckBase::ResolveGenericParams (function.get_generic_params (), + substitutions, false /*is_foreign*/, + ABI::RUST); } if (function.has_where_clause ()) @@ -235,7 +208,7 @@ TraitItemReference::get_type_from_fn (/*const*/ HIR::TraitItemFunc &fn) const // add the synthetic self param at the front, this is a placeholder // for compilation to know parameter names. The types are ignored // but we reuse the HIR identifier pattern which requires it - HIR::SelfParam &self_param = function.get_self (); + HIR::SelfParam &self_param = function.get_self_unchecked (); std::unique_ptr<HIR::Pattern> self_pattern = std::make_unique<HIR::IdentifierPattern> (HIR::IdentifierPattern ( mapping, {"self"}, self_param.get_locus (), self_param.is_ref (), diff --git a/gcc/rust/typecheck/rust-substitution-mapper.cc b/gcc/rust/typecheck/rust-substitution-mapper.cc index 212ab3f..f0bd1f8 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.cc +++ b/gcc/rust/typecheck/rust-substitution-mapper.cc @@ -34,6 +34,15 @@ SubstMapper::Resolve (TyTy::BaseType *base, location_t locus, HIR::GenericArgs *generics, const std::vector<TyTy::Region> ®ions) { + if (!valid_type (base)) + { + rich_location r (line_table, locus); + r.add_fixit_remove (generics->get_locus ()); + rust_error_at (r, ErrorCode::E0109, + "generic arguments are not allowed for this type"); + return base; + } + SubstMapper mapper (base->get_ref (), generics, regions, locus); base->accept_vis (mapper); rust_assert (mapper.resolved != nullptr); @@ -47,6 +56,17 @@ SubstMapper::InferSubst (TyTy::BaseType *base, location_t locus) } bool +SubstMapper::valid_type (TyTy::BaseType *base) +{ + bool is_fn = base->is<TyTy::FnType> (); + bool is_adt = base->is<TyTy::ADTType> (); + bool is_placeholder = base->is<TyTy::PlaceholderType> (); + bool is_projection = base->is<TyTy::ProjectionType> (); + + return is_fn || is_adt || is_placeholder || is_projection; +} + +bool SubstMapper::have_generic_args () const { return generics != nullptr; @@ -103,7 +123,12 @@ SubstMapper::visit (TyTy::ADTType &type) void SubstMapper::visit (TyTy::PlaceholderType &type) { - rust_assert (type.can_resolve ()); + if (!type.can_resolve ()) + { + resolved = &type; + return; + } + resolved = SubstMapper::Resolve (type.resolve (), locus, generics, regions); } diff --git a/gcc/rust/typecheck/rust-substitution-mapper.h b/gcc/rust/typecheck/rust-substitution-mapper.h index bc54f56..32ab71c 100644 --- a/gcc/rust/typecheck/rust-substitution-mapper.h +++ b/gcc/rust/typecheck/rust-substitution-mapper.h @@ -37,6 +37,8 @@ public: bool have_generic_args () const; + static bool valid_type (TyTy::BaseType *base); + void visit (TyTy::FnType &type) override; void visit (TyTy::ADTType &type) override; void visit (TyTy::PlaceholderType &type) override; diff --git a/gcc/rust/typecheck/rust-type-util.cc b/gcc/rust/typecheck/rust-type-util.cc index 4abfbae..c6c5b4b 100644 --- a/gcc/rust/typecheck/rust-type-util.cc +++ b/gcc/rust/typecheck/rust-type-util.cc @@ -22,10 +22,13 @@ #include "rust-hir-type-check-implitem.h" #include "rust-hir-type-check-item.h" #include "rust-hir-type-check.h" +#include "rust-hir-type-check-type.h" #include "rust-casts.h" #include "rust-unify.h" #include "rust-coercion.h" #include "rust-hir-type-bounds.h" +#include "rust-immutable-name-resolution-context.h" +#include "options.h" namespace Rust { namespace Resolver { @@ -34,6 +37,7 @@ bool query_type (HirId reference, TyTy::BaseType **result) { auto &mappings = Analysis::Mappings::get (); + auto &resolver = *Resolver::get (); TypeCheckContext *context = TypeCheckContext::get (); if (context->query_in_progress (reference)) @@ -91,6 +95,39 @@ query_type (HirId reference, TyTy::BaseType **result) HIR::ImplBlock *impl = impl_block_by_type.value (); rust_debug_loc (impl->get_locus (), "resolved impl block type {%u} to", reference); + + // this could be recursive to the root type + if (impl->has_type ()) + { + HIR::Type &ty = impl->get_type (); + NodeId ref_node_id = UNKNOWN_NODEID; + NodeId ast_node_id = ty.get_mappings ().get_nodeid (); + + if (flag_name_resolution_2_0) + { + auto &nr_ctx = Resolver2_0::ImmutableNameResolutionContext::get () + .resolver (); + + // assign the ref_node_id if we've found something + nr_ctx.lookup (ast_node_id) + .map ( + [&ref_node_id] (NodeId resolved) { ref_node_id = resolved; }); + } + else if (!resolver.lookup_resolved_name (ast_node_id, &ref_node_id)) + resolver.lookup_resolved_type (ast_node_id, &ref_node_id); + + if (ref_node_id != UNKNOWN_NODEID) + { + tl::optional<HirId> hid + = mappings.lookup_node_to_hir (ref_node_id); + if (hid.has_value () && context->query_in_progress (hid.value ())) + { + context->query_completed (reference); + return false; + } + } + } + *result = TypeCheckItem::ResolveImplBlockSelf (*impl); context->query_completed (reference); return true; diff --git a/gcc/rust/typecheck/rust-typecheck-context.cc b/gcc/rust/typecheck/rust-typecheck-context.cc index f02e484..9112b99 100644 --- a/gcc/rust/typecheck/rust-typecheck-context.cc +++ b/gcc/rust/typecheck/rust-typecheck-context.cc @@ -514,7 +514,16 @@ TypeCheckContext::lookup_lifetime (const HIR::Lifetime &lifetime) const { if (lifetime.get_lifetime_type () == AST::Lifetime::NAMED) { - rust_assert (lifetime.get_name () != "static"); + if (lifetime.get_name () == "static") + { + rich_location r (line_table, lifetime.get_locus ()); + r.add_fixit_insert_after (lifetime.get_locus (), + "static is a reserved lifetime name"); + rust_error_at (r, ErrorCode::E0262, + "invalid lifetime parameter name: %qs", + lifetime.get_name ().c_str ()); + return tl::nullopt; + } const auto name = lifetime.get_name (); auto it = lifetime_name_interner.find (name); if (it == lifetime_name_interner.end ()) diff --git a/gcc/rust/typecheck/rust-tyty-subst.cc b/gcc/rust/typecheck/rust-tyty-subst.cc index 95f18b9..bdb6474 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.cc +++ b/gcc/rust/typecheck/rust-tyty-subst.cc @@ -28,8 +28,8 @@ namespace Rust { namespace TyTy { -SubstitutionParamMapping::SubstitutionParamMapping ( - const HIR::TypeParam &generic, ParamType *param) +SubstitutionParamMapping::SubstitutionParamMapping (HIR::TypeParam &generic, + ParamType *param) : generic (generic), param (param) {} @@ -66,8 +66,8 @@ SubstitutionParamMapping::get_param_ty () const return param; } -const HIR::TypeParam & -SubstitutionParamMapping::get_generic_param () const +HIR::TypeParam & +SubstitutionParamMapping::get_generic_param () { return generic; } diff --git a/gcc/rust/typecheck/rust-tyty-subst.h b/gcc/rust/typecheck/rust-tyty-subst.h index 3f0b912..e6ed1fc 100644 --- a/gcc/rust/typecheck/rust-tyty-subst.h +++ b/gcc/rust/typecheck/rust-tyty-subst.h @@ -44,7 +44,7 @@ class SubstitutionArgumentMappings; class SubstitutionParamMapping { public: - SubstitutionParamMapping (const HIR::TypeParam &generic, ParamType *param); + SubstitutionParamMapping (HIR::TypeParam &generic, ParamType *param); SubstitutionParamMapping (const SubstitutionParamMapping &other); @@ -59,7 +59,7 @@ public: const ParamType *get_param_ty () const; - const HIR::TypeParam &get_generic_param () const; + HIR::TypeParam &get_generic_param (); // this is used for the backend to override the HirId ref of the param to // what the concrete type is for the rest of the context @@ -76,7 +76,7 @@ public: bool need_substitution () const; private: - const HIR::TypeParam &generic; + HIR::TypeParam &generic; ParamType *param; }; diff --git a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc index 1aba576..38f9d52 100644 --- a/gcc/rust/typecheck/rust-tyty-variance-analysis.cc +++ b/gcc/rust/typecheck/rust-tyty-variance-analysis.cc @@ -238,7 +238,7 @@ GenericTyVisitorCtx::process_type (ADTType &ty) first_lifetime = lookup_or_add_type (ty.get_orig_ref ()); first_type = first_lifetime + ty.get_used_arguments ().get_regions ().size (); - for (const auto ¶m : ty.get_substs ()) + for (auto ¶m : ty.get_substs ()) param_names.push_back ( param.get_generic_param ().get_type_representation ().as_string ()); diff --git a/gcc/rust/util/expected.h b/gcc/rust/util/expected.h index a9e3bc2..07ba877 100644 --- a/gcc/rust/util/expected.h +++ b/gcc/rust/util/expected.h @@ -212,10 +212,8 @@ template <typename E> throw std::forward<E>(e); #else (void)e; -#ifdef _MSC_VER gcc_unreachable(); #endif -#endif } #ifndef TL_TRAITS_MUTEX @@ -2437,4 +2435,4 @@ void swap(expected<T, E> &lhs, } } // namespace tl -#endif
\ No newline at end of file +#endif |