if (param.has_default_value ())
{
push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
- visit (param.get_default_value ());
+ visit (param.get_default_value_unchecked ());
}
}
push (Rust::Token::make_identifier (UNDEF_LOCATION, std::move (path)));
}
break;
- case GenericArg::Kind::Error:
- rust_unreachable ();
}
}
if (const_param.has_type ())
visit (const_param.get_type ());
if (const_param.has_default_value ())
- visit (const_param.get_default_value ());
+ visit (const_param.get_default_value_unchecked ());
}
void
str += "const " + name.as_string () + ": " + type->as_string ();
if (has_default_value ())
- str += " = " + get_default_value ().as_string ();
+ str += " = " + get_default_value_unchecked ().as_string ();
return str;
}
*/
enum class Kind
{
- Error,
Const, // A const value
Type, // A type argument (not discernable during parsing)
Either, // Either a type or a const value, cleared up during resolving
};
- static GenericArg create_error ()
- {
- return GenericArg (nullptr, nullptr, {""}, Kind::Error, UNDEF_LOCATION);
- }
-
static GenericArg create_const (std::unique_ptr<Expr> expression)
{
auto locus = expression->get_locus ();
GenericArg (GenericArg &&other) = default;
GenericArg &operator= (GenericArg &&other) = default;
- bool is_error () const { return kind == Kind::Error; }
-
Kind get_kind () const { return kind; }
location_t get_locus () const { return locus; }
break;
case Kind::Either:
break;
- case Kind::Error:
- rust_unreachable ();
}
}
{
switch (get_kind ())
{
- case Kind::Error:
- rust_unreachable ();
case Kind::Either:
return "Ambiguous: " + path.as_string ();
case Kind::Const:
/**
* Default value for the const generic parameter
*/
- GenericArg default_value;
+ tl::optional<GenericArg> default_value;
AST::AttrVec outer_attrs;
location_t locus;
public:
ConstGenericParam (Identifier name, std::unique_ptr<AST::Type> type,
- GenericArg default_value, AST::AttrVec outer_attrs,
- location_t locus)
+ tl::optional<GenericArg> default_value,
+ AST::AttrVec outer_attrs, location_t locus)
: name (name), type (std::move (type)),
default_value (std::move (default_value)), outer_attrs (outer_attrs),
locus (locus)
{}
bool has_type () const { return type != nullptr; }
- bool has_default_value () const { return !default_value.is_error (); }
+ bool has_default_value () const { return default_value.has_value (); }
const Identifier &get_name () const { return name; }
return *type;
}
- GenericArg &get_default_value ()
+ GenericArg &get_default_value_unchecked ()
{
rust_assert (has_default_value ());
- return default_value;
+ return default_value.value ();
}
- const GenericArg &get_default_value () const
+ const GenericArg &get_default_value_unchecked () const
{
rust_assert (has_default_value ());
- return default_value;
+ return default_value.value ();
}
std::string as_string () const override;
HIR::Expr *default_expr = nullptr;
if (param.has_default_value ())
default_expr = ASTLoweringExpr::translate (
- param.get_default_value ().get_expression ());
+ param.get_default_value_unchecked ().get_expression ());
translated = new HIR::ConstGenericParam (param.get_name ().as_string (),
std::unique_ptr<Type> (type),
return nullptr;
// optional default value
- auto default_expr = AST::GenericArg::create_error ();
+ tl::optional<AST::GenericArg> default_expr = tl::nullopt;
if (lexer.peek_token ()->get_id () == EQUAL)
{
lexer.skip_token ();
auto tok = lexer.peek_token ();
default_expr = parse_generic_arg ();
- if (default_expr.is_error ())
- rust_error_at (tok->get_locus (),
- "invalid token for start of default value for "
- "const generic parameter: expected %<block%>, "
- "%<identifier%> or %<literal%>, got %qs",
- token_id_to_str (tok->get_id ()));
+ if (!default_expr)
+ {
+ rust_error_at (tok->get_locus (),
+ "invalid token for start of default value for "
+ "const generic parameter: expected %<block%>, "
+ "%<identifier%> or %<literal%>, got %qs",
+ token_id_to_str (tok->get_id ()));
+ return nullptr;
+ }
// At this point, we *know* that we are parsing a const
// expression
- if (default_expr.get_kind () == AST::GenericArg::Kind::Either)
- default_expr = default_expr.disambiguate_to_const ();
+ if (default_expr.value ().get_kind ()
+ == AST::GenericArg::Kind::Either)
+ default_expr = default_expr.value ().disambiguate_to_const ();
}
param = std::unique_ptr<AST::ConstGenericParam> (
}
template <typename ManagedTokenSource>
-AST::GenericArg
+tl::optional<AST::GenericArg>
Parser<ManagedTokenSource>::parse_generic_arg ()
{
auto tok = lexer.peek_token ();
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
else if (next_tok->get_id () == COLON)
{
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
lexer.skip_token ();
return AST::GenericArg::create_ambiguous (tok->get_str (),
if (type)
return AST::GenericArg::create_type (std::move (type));
else
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
}
}
if (!expr)
- return AST::GenericArg::create_error ();
+ return tl::nullopt;
return AST::GenericArg::create_const (std::move (expr));
}
break;
auto arg = parse_generic_arg ();
- if (!arg.is_error ())
+ if (arg)
{
- generic_args.emplace_back (std::move (arg));
+ generic_args.emplace_back (std::move (arg.value ()));
}
// FIXME: Do we need to break if we encounter an error?
AST::TypePath parse_type_path ();
std::unique_ptr<AST::TypePathSegment> parse_type_path_segment ();
AST::PathIdentSegment parse_path_ident_segment ();
- AST::GenericArg parse_generic_arg ();
+ tl::optional<AST::GenericArg> parse_generic_arg ();
AST::GenericArgs parse_path_generic_args ();
AST::GenericArgsBinding parse_generic_args_binding ();
AST::TypePathFunction parse_type_path_function (location_t locus);
if (first_pass)
ResolveType::go (param.get_type ());
else if (param.has_default_value ())
- ResolveExpr::go (param.get_default_value ().get_expression (), prefix,
- canonical_prefix);
+ ResolveExpr::go (param.get_default_value_unchecked ().get_expression (),
+ prefix, canonical_prefix);
}
void visit (AST::TypeParam ¶m) override