Visibility (Kind kind) : kind (kind) {}
};
+class LifetimeParam
+{
+};
+
+class Lifetime
+{
+};
+
+enum class AnonConst
+{
+ InvalidSizeExpr,
+};
+
+struct LoopLabel
+{
+ static tl::expected<AST::LoopLabel, LoopLabel> make_not_loop_label ()
+ {
+ return tl::unexpected<LoopLabel> (LoopLabel (Kind::NOT_LOOP_LABEL));
+ }
+
+ static tl::expected<AST::LoopLabel, LoopLabel> make_missing_colon ()
+ {
+ return tl::unexpected<LoopLabel> (LoopLabel (Kind::MISSING_COLON));
+ }
+
+ enum class Kind
+ {
+ // Not an hard error
+ NOT_LOOP_LABEL,
+ // Hard error
+ MISSING_COLON,
+ } kind;
+
+private:
+ LoopLabel (Kind kind) : kind (kind) {}
+};
+
+struct Self
+{
+ static tl::expected<std::unique_ptr<AST::Param>, Self>
+ make_self_raw_pointer ()
+ {
+ return tl::unexpected<Self> (Self (Kind::SELF_RAW_PTR));
+ }
+
+ static tl::expected<std::unique_ptr<AST::Param>, Self> make_not_self ()
+ {
+ return tl::unexpected<Self> (Self (Kind::NOT_SELF));
+ }
+
+ static tl::expected<std::unique_ptr<AST::Param>, Self> make_parsing_error ()
+ {
+ return tl::unexpected<Self> (Self (Kind::PARSING));
+ }
+
+ enum class Kind
+ {
+ SELF_RAW_PTR,
+ PARSING,
+ NOT_SELF,
+ } kind;
+
+private:
+ Self (Kind kind) : kind (kind) {}
+};
+
} // namespace Error
} // namespace Parse
} // namespace Rust
/* Parse an anonymous const expression. This can be a regular const expression
* or an underscore for deferred const inference */
template <typename ManagedTokenSource>
-tl::expected<AST::AnonConst, AnonConstError>
+tl::expected<AST::AnonConst, Parse::Error::AnonConst>
Parser<ManagedTokenSource>::parse_anon_const ()
{
auto current = lexer.peek_token ();
auto expr = parse_expr ();
if (!expr)
- return tl::make_unexpected (AnonConstError::InvalidSizeExpr);
+ return tl::make_unexpected (Parse::Error::AnonConst::InvalidSizeExpr);
return AST::AnonConst (std::move (expr), locus);
}
Parser<ManagedTokenSource>::parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs)
{
- /* TODO: decide whether it should not work if there is no label, or parse it
- * with no label at the moment, I will make it not work with no label
- * because that's the implication. */
-
- if (tok->get_id () != LIFETIME)
- {
- Error error (tok->get_locus (),
- "expected lifetime in labelled loop expr (to parse loop "
- "label) - found %qs",
- tok->get_token_description ());
- add_error (std::move (error));
-
- // skip?
- return nullptr;
- }
-
// parse loop label (required)
- // TODO: Convert this return type to tl::expected instead of tl::optional
auto parsed_label = parse_loop_label (tok);
if (!parsed_label)
{
- Error error (lexer.peek_token ()->get_locus (),
- "failed to parse loop label in labelled loop expr");
- add_error (std::move (error));
+ /* TODO: decide whether it should not work if there is no label, or parse
+ * it with no label at the moment, I will make it not work with no label
+ * because that's the implication. */
- // skip?
- return nullptr;
+ if (parsed_label.error ().kind
+ == Parse::Error::LoopLabel::Kind::NOT_LOOP_LABEL)
+ {
+ Error error (tok->get_locus (),
+ "expected lifetime in labelled loop expr (to parse loop "
+ "label) - found %qs",
+ tok->get_token_description ());
+ add_error (std::move (error));
+ return nullptr;
+ }
+
+ else
+ {
+ Error error (lexer.peek_token ()->get_locus (),
+ "failed to parse loop label in labelled loop expr");
+ add_error (std::move (error));
+
+ // skip?
+ return nullptr;
+ }
}
auto label = parsed_label
auto initial_param = parse_self_param ();
if (!initial_param.has_value ()
- && initial_param.error () != ParseSelfError::NOT_SELF)
+ && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF)
return nullptr;
if (initial_param.has_value () && lexer.peek_token ()->get_id () == COMMA)
/* Parses a single lifetime generic parameter (not including comma). */
template <typename ManagedTokenSource>
-tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
+tl::expected<AST::LifetimeParam, Parse::Error::LifetimeParam>
Parser<ManagedTokenSource>::parse_lifetime_param ()
{
// parse outer attributes, which are optional and may not exist
if (lifetime_tok->get_id () != LIFETIME)
{
// if lifetime is missing, must not be a lifetime param, so return error
- return tl::make_unexpected<ParseLifetimeParamError> ({});
+ return tl::make_unexpected<Parse::Error::LifetimeParam> ({});
}
lexer.skip_token ();
AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (),
/* Parses a lifetime token (named, 'static, or '_). Also handles lifetime not
* existing. */
template <typename ManagedTokenSource>
-tl::expected<AST::Lifetime, ParseLifetimeError>
+tl::expected<AST::Lifetime, Parse::Error::Lifetime>
Parser<ManagedTokenSource>::parse_lifetime (bool allow_elided)
{
const_TokenPtr lifetime_tok = lexer.peek_token ();
}
else
{
- return tl::make_unexpected<ParseLifetimeError> ({});
+ return tl::make_unexpected<Parse::Error::Lifetime> ({});
}
}
lexer.skip_token ();
auto initial_param = parse_self_param ();
if (!initial_param.has_value ()
- && initial_param.error () != ParseSelfError::NOT_SELF)
+ && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF)
return nullptr;
/* FIXME: ensure that self param doesn't accidently consume tokens for a
auto initial_param = parse_self_param ();
if (!initial_param.has_value ()
- && initial_param.error () != ParseSelfError::NOT_SELF)
+ && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF)
return nullptr;
// FIXME: ensure that self param doesn't accidently consume tokens for a
// Parses a self param. Also handles self param not existing.
template <typename ManagedTokenSource>
-tl::expected<std::unique_ptr<AST::Param>, ParseSelfError>
+tl::expected<std::unique_ptr<AST::Param>, Parse::Error::Self>
Parser<ManagedTokenSource>::parse_self_param ()
{
bool has_reference = false;
{
rust_error_at (lexer.peek_token ()->get_locus (),
"cannot pass %<self%> by raw pointer");
- return tl::make_unexpected (ParseSelfError::SELF_PTR);
+ return Parse::Error::Self::make_self_raw_pointer ();
}
}
is_self = true;
if (!is_self)
- return tl::make_unexpected (ParseSelfError::NOT_SELF);
+ return Parse::Error::Self::make_not_self ();
// test if self is a reference parameter
if (lexer.peek_token ()->get_id () == AMP)
add_error (std::move (error));
// skip after somewhere?
- return tl::make_unexpected (ParseSelfError::PARSING);
+ return Parse::Error::Self::make_parsing_error ();
}
}
}
if (self_tok->get_id () != SELF)
{
// skip after somewhere?
- return tl::make_unexpected (ParseSelfError::NOT_SELF);
+ return Parse::Error::Self::make_not_self ();
}
lexer.skip_token ();
add_error (std::move (error));
// skip after somewhere?
- return tl::make_unexpected (ParseSelfError::PARSING);
+ return Parse::Error::Self::make_parsing_error ();
}
}
add_error (std::move (error));
// skip after somewhere?
- return tl::make_unexpected (ParseSelfError::PARSING);
+ return Parse::Error::Self::make_parsing_error ();
}
if (has_reference)
// Parses a loop label used in loop expressions.
template <typename ManagedTokenSource>
-tl::expected<AST::LoopLabel, ParseLoopLabelError>
+tl::expected<AST::LoopLabel, Parse::Error::LoopLabel>
Parser<ManagedTokenSource>::parse_loop_label (const_TokenPtr tok)
{
// parse lifetime - if doesn't exist, assume no label
if (tok->get_id () != LIFETIME)
{
// not necessarily an error
- return tl::unexpected<ParseLoopLabelError> (
- ParseLoopLabelError::NOT_LOOP_LABEL);
+ return Parse::Error::LoopLabel::make_not_loop_label ();
}
/* FIXME: check for named lifetime requirement here? or check in semantic
* analysis phase? */
if (!skip_token (COLON))
{
// skip somewhere?
- return tl::unexpected<ParseLoopLabelError> (
- ParseLoopLabelError::MISSING_COLON);
+ Parse::Error::LoopLabel::make_missing_colon ();
}
- return tl::expected<AST::LoopLabel, ParseLoopLabelError> (
+ return tl::expected<AST::LoopLabel, Parse::Error::LoopLabel> (
AST::LoopLabel (std::move (label), tok->get_locus ()));
}
namespace Rust {
-class ParseLifetimeParamError
-{
-};
-
-class ParseLifetimeError
-{
-};
-
-enum class AnonConstError
-{
- InvalidSizeExpr,
-};
-
-enum class ParseLoopLabelError
-{
- NOT_LOOP_LABEL,
- MISSING_COLON,
-};
-
-enum class ParseSelfError
-{
- SELF_PTR,
- PARSING,
- NOT_SELF,
-};
-
// Left binding powers of operations.
enum binding_powers
{
tl::optional<AST::LoopLabel> = tl::nullopt,
location_t pratt_parsed_loc = UNKNOWN_LOCATION);
- tl::expected<AST::AnonConst, AnonConstError> parse_anon_const ();
+ tl::expected<AST::AnonConst, Parse::Error::AnonConst> parse_anon_const ();
std::unique_ptr<AST::ConstBlock>
parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
ParseFunction parsing_function, EndTokenPred is_end_token,
std::string error_msg = "failed to parse generic param in generic params")
-> std::vector<decltype (parsing_function ())>;
- tl::expected<AST::LifetimeParam, ParseLifetimeParamError>
+ tl::expected<AST::LifetimeParam, Parse::Error::LifetimeParam>
parse_lifetime_param ();
std::vector<std::unique_ptr<AST::TypeParam>> parse_type_params ();
template <typename EndTokenPred>
std::vector<AST::Lifetime> parse_lifetime_bounds ();
template <typename EndTokenPred>
std::vector<AST::Lifetime> parse_lifetime_bounds (EndTokenPred is_end_token);
- tl::expected<AST::Lifetime, ParseLifetimeError>
+ tl::expected<AST::Lifetime, Parse::Error::Lifetime>
parse_lifetime (bool allow_elided);
AST::Lifetime lifetime_from_token (const_TokenPtr tok);
std::unique_ptr<AST::ExternalTypeItem>
std::unique_ptr<AST::ConstantItem>
parse_trait_const (AST::AttrVec outer_attrs);
- tl::expected<std::unique_ptr<AST::Param>, ParseSelfError> parse_self_param ();
+ tl::expected<std::unique_ptr<AST::Param>, Parse::Error::Self>
+ parse_self_param ();
std::unique_ptr<AST::Impl> parse_impl (AST::Visibility vis,
AST::AttrVec outer_attrs);
std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
AST::AttrVec outer_attrs
= AST::AttrVec ());
- tl::expected<AST::LoopLabel, ParseLoopLabelError>
+ tl::expected<AST::LoopLabel, Parse::Error::LoopLabel>
parse_loop_label (const_TokenPtr tok);
std::unique_ptr<AST::AsyncBlockExpr>
parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ());