https://gcc.gnu.org/g:46673ec062176f4c2826dabbde6a401167d73441
commit 46673ec062176f4c2826dabbde6a401167d73441 Author: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Date: Tue Apr 1 19:55:28 2025 +0200 Migrate error state to optionals gcc/rust/ChangeLog: * ast/rust-ast-builder.cc (Builder::self_ref_param): Remove error state and use optional. * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit): Check label before visiting. * ast/rust-ast.cc (ContinueExpr::as_string): Retrieve label value. (Lifetime::as_string): Retrieve lifetime value. (ReferenceType::as_string): Likewise. (SelfParam::as_string): Likewise. * ast/rust-ast.h: Remove lifetime and LifetimeParam error state. * ast/rust-desugar-for-loops.cc (DesugarForLoops::DesugarCtx::make_break_arm): Use optional instead of error state. * ast/rust-expr.h (class ContinueExpr): Make label optional. * ast/rust-item.h (class SelfParam): Make lifetime optional. * ast/rust-type.h (class ReferenceType): Likewise. * backend/rust-compile-base.cc: Use optional for self param instead of error state. * backend/rust-compile-base.h: Update function prototype. * expand/rust-derive-clone.cc (DeriveClone::clone_fn): Use optional. * hir/rust-ast-lower-base.cc (ASTLoweringBase::lower_self): Lower lifetime only if it exists. * hir/rust-ast-lower-block.h: Lower loop label only if it exists. * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise. * hir/rust-ast-lower-implitem.cc (ASTLowerImplItem::visit): Remove references to error state. (ASTLowerTraitItem::visit): Lower self param only if it exists. * hir/rust-ast-lower-item.cc (ASTLoweringItem::visit): Use nullopt for default value instead of SelfParam error state. * hir/rust-ast-lower.cc (ASTLoweringExprWithBlock::visit): Lower label only if it exists. * hir/rust-hir-dump.cc (Dump::do_traitfunctiondecl): Print self only if it exists. (Dump::visit): Liewise. * hir/tree/rust-hir-bound.h: Remove error state. * hir/tree/rust-hir-expr.cc (ContinueExpr::ContinueExpr): Use optional in constructor for loop label. (BreakExpr::BreakExpr): Likewise. * hir/tree/rust-hir-expr.h (class ContinueExpr): Remove error state implementation. (class BreakExpr): Likewise. * hir/tree/rust-hir-generic-param.h: Likewise. * hir/tree/rust-hir-item.cc (SelfParam::SelfParam): Make lifetime optional. (Function::Function): Make self param optional. * hir/tree/rust-hir-item.h (class Function): Likewise. * hir/tree/rust-hir-type.cc (ReferenceType::ReferenceType): Make lifetime optional. * hir/tree/rust-hir-type.h (class ReferenceType): Likewise. * hir/tree/rust-hir.cc (ContinueExpr::as_string): Use new getter. (BreakExpr::as_string): Likewise. (Lifetime::as_string): Likewise. (ReferenceType::as_string): Likewise. (TraitFunctionDecl::as_string): Likewise. (SelfParam::as_string): Remove error state checking. * parse/rust-parse-impl.h (Parser::parse_generic_param): Adapt to optional. (Parser::parse_lifetime_params): Likewise. (Parser::parse_lifetime_params_objs): Likewise. (Parser::parse_lifetime_param): Likewise. (Parser::parse_lifetime_where_clause_item): Likewise. (Parser::parse_type_param_bound): Likewise. (Parser::parse_lifetime_bounds): Likewise. (Parser::parse_path_generic_args): Likewise. (Parser::parse_self_param): Likewise. (Parser::parse_break_expr): Likewise. (Parser::parse_continue_expr): Likewise. (Parser::parse_reference_type_inner): Likewise. * parse/rust-parse.h (class ParseLifetimeParamError): Add new class for lifetime param parsing errors. (class ParseLifetimeError): Add new class for lifetime parsing errors. (enum ParseSelfError): Add new class for self param parsing errors. * typecheck/rust-hir-type-check-implitem.cc (TypeCheckImplItem::visit): Use unchecked getter in checked context. And make anonymous region. * typecheck/rust-hir-type-check.cc (TraitItemReference::get_type_from_fn): Likewise. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Diff: --- gcc/rust/ast/rust-ast-builder.cc | 2 +- gcc/rust/ast/rust-ast-visitor.cc | 6 +- gcc/rust/ast/rust-ast.cc | 9 +- gcc/rust/ast/rust-ast.h | 17 ---- gcc/rust/ast/rust-desugar-for-loops.cc | 4 +- gcc/rust/ast/rust-expr.h | 14 +-- gcc/rust/ast/rust-item.h | 15 +-- gcc/rust/ast/rust-type.h | 10 +- gcc/rust/backend/rust-compile-base.cc | 13 +-- gcc/rust/backend/rust-compile-base.h | 2 +- gcc/rust/expand/rust-derive-clone.cc | 2 +- gcc/rust/hir/rust-ast-lower-base.cc | 8 +- gcc/rust/hir/rust-ast-lower-block.h | 4 +- gcc/rust/hir/rust-ast-lower-expr.cc | 10 +- gcc/rust/hir/rust-ast-lower-implitem.cc | 23 ++--- gcc/rust/hir/rust-ast-lower-item.cc | 2 +- gcc/rust/hir/rust-ast-lower.cc | 5 +- gcc/rust/hir/rust-hir-dump.cc | 6 +- gcc/rust/hir/tree/rust-hir-bound.h | 12 --- gcc/rust/hir/tree/rust-hir-expr.cc | 6 +- gcc/rust/hir/tree/rust-hir-expr.h | 22 ++--- gcc/rust/hir/tree/rust-hir-generic-param.h | 3 - gcc/rust/hir/tree/rust-hir-item.cc | 21 +++-- gcc/rust/hir/tree/rust-hir-item.h | 48 +++++----- gcc/rust/hir/tree/rust-hir-type.cc | 2 +- gcc/rust/hir/tree/rust-hir-type.h | 9 +- gcc/rust/hir/tree/rust-hir.cc | 100 +++++++++----------- gcc/rust/parse/rust-parse-impl.h | 103 +++++++++++---------- gcc/rust/parse/rust-parse.h | 27 ++++-- gcc/rust/typecheck/rust-hir-type-check-implitem.cc | 42 ++++++--- gcc/rust/typecheck/rust-hir-type-check.cc | 2 +- 31 files changed, 283 insertions(+), 266 deletions(-) diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc index 437ba1b56ea0..1f49c6411975 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> diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc index 3a06d2ddc4b7..87364a0b0f5b 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 ()); } void @@ -591,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 ()); } diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 2d286cdf3d70..bba4b156b5f7 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -1631,7 +1631,7 @@ ContinueExpr::as_string () const std::string str ("continue "); if (has_label ()) - str += label.as_string (); + str += get_label ().as_string (); return str; } @@ -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: @@ -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 c74b1c46448a..53bf1bc1c86c 100644 --- a/gcc/rust/ast/rust-ast.h +++ b/gcc/rust/ast/rust-ast.h @@ -1587,17 +1587,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 +1680,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 5e5cbbc6b383..ffc3470b656e 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 e6cfa2709f93..70cb6d403551 100644 --- a/gcc/rust/ast/rust-expr.h +++ b/gcc/rust/ast/rust-expr.h @@ -2844,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? @@ -2854,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) {} @@ -2879,7 +2879,8 @@ public: outer_attrs = std::move (new_attrs); } - Lifetime &get_label () { return label; } + Lifetime &get_label () { return label.value (); } + const Lifetime &get_label () const { return label.value (); } Expr::Kind get_expr_kind () const override { return Expr::Kind::Continue; } @@ -2915,7 +2916,8 @@ public: 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) diff --git a/gcc/rust/ast/rust-item.h b/gcc/rust/ast/rust-item.h index 0c94f168f869..f507c90dc962 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; } diff --git a/gcc/rust/ast/rust-type.h b/gcc/rust/ast/rust-type.h index b6b76497d3ba..48539a23cebe 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 04e3e75ed7d0..f4b578d78112 100644 --- a/gcc/rust/backend/rust-compile-base.cc +++ b/gcc/rust/backend/rust-compile-base.cc @@ -666,7 +666,8 @@ get_abi (const AST::AttrVec &outer_attrs, tree HIRCompileBase::compile_function ( - bool is_root_item, 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, @@ -713,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 69f565cea2b4..65dc350f1611 100644 --- a/gcc/rust/backend/rust-compile-base.h +++ b/gcc/rust/backend/rust-compile-base.h @@ -104,7 +104,7 @@ protected: location_t expr_locus); tree compile_function (bool is_root_item, const std::string &fn_name, - HIR::SelfParam &self_param, + 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/expand/rust-derive-clone.cc b/gcc/rust/expand/rust-derive-clone.cc index d8f79d00106d..ca5ef0e69a93 100644 --- a/gcc/rust/expand/rust-derive-clone.cc +++ b/gcc/rust/expand/rust-derive-clone.cc @@ -64,7 +64,7 @@ DeriveClone::clone_fn (std::unique_ptr<Expr> &&clone_expr) 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/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc index 749fe09f3baa..a933f1baa589 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 55541a5ad684..d60088bba70c 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 575eea6b6248..7bb732033cb7 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 ().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 ()); 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-implitem.cc b/gcc/rust/hir/rust-ast-lower-implitem.cc index 3229f57c38f2..66488ac7892d 100644 --- a/gcc/rust/hir/rust-ast-lower-implitem.cc +++ b/gcc/rust/hir/rust-ast-lower-implitem.cc @@ -132,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 ()); @@ -189,13 +189,13 @@ ASTLowerImplItem::visit (AST::Function &function) std::move (vis), function.get_outer_attrs (), 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 @@ -249,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 ()) @@ -303,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 73ddedf117de..47b4b71974a4 100644 --- a/gcc/rust/hir/rust-ast-lower-item.cc +++ b/gcc/rust/hir/rust-ast-lower-item.cc @@ -460,7 +460,7 @@ ASTLoweringItem::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 (), - HIR::SelfParam::error (), defaultness, 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 c6446aa1bcbd..f70c7878216e 100644 --- a/gcc/rust/hir/rust-ast-lower.cc +++ b/gcc/rust/hir/rust-ast-lower.cc @@ -402,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 b6dcf184ae4e..468d85527961 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 78bb133f6d4b..8fa6a2258b16 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 82a09e935887..266c79c2fe89 100644 --- a/gcc/rust/hir/tree/rust-hir-expr.cc +++ b/gcc/rust/hir/tree/rust-hir-expr.cc @@ -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)), diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h index b304d27fc590..20287b830f9c 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; } @@ -1806,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 { @@ -1851,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; @@ -1862,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. */ @@ -1870,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 ()); @@ -1889,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; } diff --git a/gcc/rust/hir/tree/rust-hir-generic-param.h b/gcc/rust/hir/tree/rust-hir-generic-param.h index a1c59bf0d6bf..960de565c142 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 14f53ce3771d..160f710408af 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,7 @@ 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, + 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)), @@ -612,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 0a59a537da1c..f45d743dceb6 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; @@ -961,7 +952,7 @@ 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 @@ -1001,8 +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, Defaultness defaultness, - location_t locus); + AST::AttrVec outer_attrs, tl::optional<SelfParam> self, + Defaultness defaultness, location_t locus); // Copy constructor with clone Function (Function const &other); @@ -1056,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 (); } - SelfParam &get_self_param () { return self; } + tl::optional<SelfParam> &get_self_param () { return self; } + const tl::optional<SelfParam> &get_self_param () const { 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 { @@ -1913,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); @@ -1951,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 6a6c319fc98e..ec484254138b 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 bf733e7261ad..d6a0e0972bd4 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 14f8646418c1..4fc6b1ae18f0 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; @@ -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 e2a3440efa93..32177c5ce2c0 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"); @@ -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)); @@ -9600,8 +9605,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"); diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index fc548141c44f..5373106c1890 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -25,6 +25,21 @@ along with GCC; see the file COPYING3. If not see #include "expected.h" namespace Rust { + +class ParseLifetimeParamError +{ +}; + +class ParseLifetimeError +{ +}; +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 +110,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 @@ -277,7 +286,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 +316,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); diff --git a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc index 55dd9514127c..ad1c7671f0a5 100644 --- a/gcc/rust/typecheck/rust-hir-type-check-implitem.cc +++ b/gcc/rust/typecheck/rust-hir-type-check-implitem.cc @@ -242,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> ( @@ -267,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 (), @@ -283,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.cc b/gcc/rust/typecheck/rust-hir-type-check.cc index 3deb5b7ea496..ed3e8ec037a4 100644 --- a/gcc/rust/typecheck/rust-hir-type-check.cc +++ b/gcc/rust/typecheck/rust-hir-type-check.cc @@ -208,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 (),