Skip to content

Commit 09d92fc

Browse files
vishruth-thimmaiahCohenArthur
authored andcommitted
gccrs: Fix ICE with non-trailing const defaults
When a const generic with a default value is not trailing, emit an error. gcc/rust/ChangeLog: * parse/rust-parse-impl.h (Parser::parse_generic_params): Emit an error when const generics with a default value is not trailing. gcc/testsuite/ChangeLog: * rust/compile/const_generics_17.rs: New test. * rust/compile/generics14.rs: New test. Signed-off-by: vishruth-thimmaiah <[email protected]>
1 parent da052c3 commit 09d92fc

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

gcc/rust/parse/rust-parse-impl.h

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,21 +3262,42 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
32623262

32633263
// Did we parse a generic type param yet
32643264
auto type_seen = false;
3265+
// Did we parse a const param with a default value yet
3266+
auto const_with_default_seen = false;
32653267
// Did the user write a lifetime parameter after a type one
32663268
auto order_error = false;
3269+
// Did the user write a const param with a default value after a type one
3270+
auto const_with_default_order_error = false;
32673271

32683272
// parse lifetime params
32693273
while (!is_end_token (lexer.peek_token ()->get_id ()))
32703274
{
32713275
auto param = parse_generic_param (is_end_token);
32723276
if (param)
32733277
{
3274-
// TODO: Handle `Const` here as well if necessary
32753278
if (param->get_kind () == AST::GenericParam::Kind::Type)
3276-
type_seen = true;
3279+
{
3280+
type_seen = true;
3281+
if (const_with_default_seen)
3282+
const_with_default_order_error = true;
3283+
}
32773284
else if (param->get_kind () == AST::GenericParam::Kind::Lifetime
32783285
&& type_seen)
3279-
order_error = true;
3286+
{
3287+
order_error = true;
3288+
if (const_with_default_seen)
3289+
const_with_default_order_error = true;
3290+
}
3291+
else if (param->get_kind () == AST::GenericParam::Kind::Const)
3292+
{
3293+
type_seen = true;
3294+
AST::ConstGenericParam *const_param
3295+
= static_cast<AST::ConstGenericParam *> (param.get ());
3296+
if (const_param->has_default_value ())
3297+
const_with_default_seen = true;
3298+
else if (const_with_default_seen)
3299+
const_with_default_order_error = true;
3300+
}
32803301

32813302
generic_params.emplace_back (std::move (param));
32823303
maybe_skip_token (COMMA);
@@ -3293,6 +3314,13 @@ Parser<ManagedTokenSource>::parse_generic_params (EndTokenPred is_end_token)
32933314
"must be declared prior to type and const parameters");
32943315
add_error (std::move (error));
32953316
}
3317+
if (const_with_default_order_error)
3318+
{
3319+
Error error (generic_params.front ()->get_locus (),
3320+
"invalid order for generic parameters: generic parameters "
3321+
"with a default must be trailing");
3322+
add_error (std::move (error));
3323+
}
32963324

32973325
generic_params.shrink_to_fit ();
32983326
return generic_params;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct Foo<const N: u32 = 1, const O: bool>; // { dg-error "invalid order for generic parameters: generic parameters with a default must be trailing" }
2+
3+
impl<const N: u32> Foo<N> {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
struct Foo<const N: i32, 'a>; // { dg-error "invalid order for generic parameters: lifetime parameters must be declared prior to type and const parameters" }

0 commit comments

Comments
 (0)