mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Allow (Foo) { 1, 2 } syntax for compound literals.
This commit is contained in:
@@ -430,6 +430,7 @@
|
||||
- Add `$member.get(value)` to replace `value.$eval($member.nameof)`
|
||||
- Improve the error message when the compilation does not produce any files #1390.
|
||||
- Add `fmod` implementation for nolibc.
|
||||
- Allow `(Foo) { 1, 2 }` syntax for compound literals.
|
||||
|
||||
### Fixes
|
||||
|
||||
|
||||
1337
resources/grammar/grammar_proposal.y
Normal file
1337
resources/grammar/grammar_proposal.y
Normal file
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@
|
||||
|
||||
typedef Expr *(*ParseFn)(ParseContext *context, Expr *);
|
||||
static Expr *parse_subscript_expr(ParseContext *c, Expr *left);
|
||||
static Expr *parse_initializer_list(ParseContext *c, Expr *left);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -840,11 +841,6 @@ static Expr *parse_grouping_expr(ParseContext *c, Expr *left)
|
||||
case EXPR_TYPEINFO:
|
||||
{
|
||||
TypeInfo *info = expr->type_expr;
|
||||
if (tok_is(c, TOKEN_LBRACE) && info->resolve_status != RESOLVE_DONE)
|
||||
{
|
||||
PRINT_ERROR_HERE("Unexpected start of a block '{' here. If you intended a compound literal, remove the () around the type.");
|
||||
return poisoned_expr;
|
||||
}
|
||||
// Create a cast expr
|
||||
if (rules[c->tok].prefix)
|
||||
{
|
||||
@@ -883,7 +879,7 @@ static Expr *parse_grouping_expr(ParseContext *c, Expr *left)
|
||||
* ;
|
||||
*
|
||||
*/
|
||||
Expr *parse_initializer_list(ParseContext *c, Expr *left)
|
||||
static Expr *parse_initializer_list(ParseContext *c, Expr *left)
|
||||
{
|
||||
ASSERT(!left && "Unexpected left hand side");
|
||||
Expr *initializer_list = EXPR_NEW_TOKEN(EXPR_INITIALIZER_LIST);
|
||||
|
||||
@@ -5651,6 +5651,12 @@ static inline bool sema_expr_analyse_cast(SemaContext *context, Expr *expr, bool
|
||||
if (invalid_cast_ref) *invalid_cast_ref = false;
|
||||
Expr *inner = exprptr(expr->cast_expr.expr);
|
||||
TypeInfo *type_info = type_infoptr(expr->cast_expr.type_info);
|
||||
if (inner->expr_kind == EXPR_INITIALIZER_LIST)
|
||||
{
|
||||
expr->expr_kind = EXPR_COMPOUND_LITERAL;
|
||||
expr->expr_compound_literal = (ExprCompoundLiteral) { .initializer = inner, .type_info = type_info };
|
||||
return sema_expr_analyse_compound_literal(context, expr);
|
||||
}
|
||||
bool success = sema_resolve_type_info(context, type_info, RESOLVE_TYPE_ALLOW_INFER);
|
||||
if (!sema_analyse_expr(context, inner) || !success) return false;
|
||||
|
||||
@@ -9027,8 +9033,7 @@ static inline bool sema_expr_analyse_generic_ident(SemaContext *context, Expr *e
|
||||
Expr *parent = exprptr(expr->generic_ident_expr.parent);
|
||||
if (parent->expr_kind != EXPR_UNRESOLVED_IDENTIFIER)
|
||||
{
|
||||
SEMA_ERROR(parent, "Expected an identifier to parameterize.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(parent, "Expected an identifier to parameterize.");
|
||||
}
|
||||
Decl *symbol = sema_analyse_parameterized_identifier(context, parent->unresolved_ident_expr.path,
|
||||
parent->unresolved_ident_expr.ident, parent->span,
|
||||
|
||||
@@ -836,8 +836,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
||||
expr_rewrite_to_const_zero(expr, to);
|
||||
return true;
|
||||
}
|
||||
SEMA_ERROR(expr, "Pointers cannot be initialized using an initializer list, instead you need to take the address of an array.");
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(expr, "Pointers cannot be initialized using an initializer list, instead you need to take the address of an array.");
|
||||
case TYPE_VOID:
|
||||
case TYPE_POISONED:
|
||||
case TYPE_FUNC_RAW:
|
||||
@@ -845,7 +844,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
||||
case TYPE_OPTIONAL:
|
||||
case TYPE_TYPEINFO:
|
||||
case TYPE_MEMBER:
|
||||
break;
|
||||
RETURN_SEMA_ERROR(expr, "You cannot use %s with an initializer list.", type_quoted_error_string(to));
|
||||
default:
|
||||
if (is_zero_init)
|
||||
{
|
||||
@@ -855,8 +854,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex
|
||||
}
|
||||
break;
|
||||
}
|
||||
SEMA_ERROR(expr, "'%s' cannot use compound literal initialization, did you intend to use a cast?", type_to_error_string(to));
|
||||
return false;
|
||||
RETURN_SEMA_ERROR(expr, "You cannot use %s with a non-empty initializer list.", type_quoted_error_string(to));
|
||||
}
|
||||
|
||||
void const_init_rewrite_to_value(ConstInitializer *const_init, Expr *value)
|
||||
|
||||
@@ -2,7 +2,7 @@ struct Foo { int a; }
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
int x = int{ 32 }; // #error: 'int' cannot use compound literal initialization, did you intend to use a cast
|
||||
int x = int{ 32 }; // #error: 'int' with a non-empty initializer list
|
||||
}
|
||||
|
||||
fn void test3()
|
||||
|
||||
@@ -2,5 +2,5 @@ module testing;
|
||||
|
||||
fn void main()
|
||||
{
|
||||
(void){}; // #error: You cannot cast 'untyped_list' to 'void'
|
||||
(void){}; // #error: You cannot use 'void' with an initializer list
|
||||
}
|
||||
Reference in New Issue
Block a user