aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>2025-04-01 19:55:28 +0200
committerP-E-P <32375388+P-E-P@users.noreply.github.com>2025-04-07 08:18:19 +0000
commit46673ec062176f4c2826dabbde6a401167d73441 (patch)
tree208e1d0741b5c494df99e159e07176510b4e259f /gcc
parent8a65b913d4c4f00c2b8aa6827c733786e4a0266e (diff)
downloadgcc-46673ec062176f4c2826dabbde6a401167d73441.zip
gcc-46673ec062176f4c2826dabbde6a401167d73441.tar.gz
gcc-46673ec062176f4c2826dabbde6a401167d73441.tar.bz2
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.patry@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/ast/rust-ast-builder.cc2
-rw-r--r--gcc/rust/ast/rust-ast-visitor.cc6
-rw-r--r--gcc/rust/ast/rust-ast.cc9
-rw-r--r--gcc/rust/ast/rust-ast.h17
-rw-r--r--gcc/rust/ast/rust-desugar-for-loops.cc4
-rw-r--r--gcc/rust/ast/rust-expr.h14
-rw-r--r--gcc/rust/ast/rust-item.h15
-rw-r--r--gcc/rust/ast/rust-type.h10
-rw-r--r--gcc/rust/backend/rust-compile-base.cc13
-rw-r--r--gcc/rust/backend/rust-compile-base.h2
-rw-r--r--gcc/rust/expand/rust-derive-clone.cc2
-rw-r--r--gcc/rust/hir/rust-ast-lower-base.cc8
-rw-r--r--gcc/rust/hir/rust-ast-lower-block.h4
-rw-r--r--gcc/rust/hir/rust-ast-lower-expr.cc10
-rw-r--r--gcc/rust/hir/rust-ast-lower-implitem.cc23
-rw-r--r--gcc/rust/hir/rust-ast-lower-item.cc2
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc5
-rw-r--r--gcc/rust/hir/rust-hir-dump.cc6
-rw-r--r--gcc/rust/hir/tree/rust-hir-bound.h12
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.cc6
-rw-r--r--gcc/rust/hir/tree/rust-hir-expr.h22
-rw-r--r--gcc/rust/hir/tree/rust-hir-generic-param.h3
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.cc21
-rw-r--r--gcc/rust/hir/tree/rust-hir-item.h48
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.cc2
-rw-r--r--gcc/rust/hir/tree/rust-hir-type.h9
-rw-r--r--gcc/rust/hir/tree/rust-hir.cc100
-rw-r--r--gcc/rust/parse/rust-parse-impl.h103
-rw-r--r--gcc/rust/parse/rust-parse.h27
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check-implitem.cc42
-rw-r--r--gcc/rust/typecheck/rust-hir-type-check.cc2
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 437ba1b..1f49c64 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 3a06d2d..87364a0 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 2d286cd..bba4b15 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 c74b1c4..53bf1bc 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 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 e6cfa27..70cb6d4 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 0c94f16..f507c90 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 b6b7649..48539a2 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 04e3e75..f4b578d 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 69f565c..65dc350 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 d8f79d0..ca5ef0e 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 749fe09..a933f1b 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 &param)
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 55541a5..d60088b 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 575eea6..7bb7320 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 3229f57..66488ac 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 73ddedf..47b4b71 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 &param : fn->get_function_params ())
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index c6446aa..f70c787 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 b6dcf18..468d855 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 82a09e9..266c79c 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 b304d27..20287b8 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 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 14f53ce..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,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 0a59a53..f45d743 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 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 bf733e7..d6a0e09 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 14f8646..4fc6b1a 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 e2a3440..32177c5 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 fc54814..5373106 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 55dd951..ad1c767 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 3deb5b7..ed3e8ec 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 (),