mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Compiler assert when using generic parameters list without any parameters. #2369
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
- Fixed: regression in comments for `@deprecated` and `@pure`.
|
||||
- Detect recursive creation of generics #2366.
|
||||
- Compiler assertion when defining a function with return type untyped_list #2368.
|
||||
- Compiler assert when using generic parameters list without any parameters. #2369
|
||||
|
||||
### Stdlib changes
|
||||
- Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`.
|
||||
|
||||
@@ -872,7 +872,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
ExprId parent;
|
||||
Expr **parmeters;
|
||||
Expr **parameters;
|
||||
} ExprGenericIdent;
|
||||
|
||||
typedef struct
|
||||
|
||||
@@ -319,7 +319,7 @@ Expr *copy_expr(CopyStruct *c, Expr *source_expr)
|
||||
return expr;
|
||||
case EXPR_GENERIC_IDENT:
|
||||
MACRO_COPY_EXPRID(expr->generic_ident_expr.parent);
|
||||
MACRO_COPY_EXPR_LIST(expr->generic_ident_expr.parmeters);
|
||||
MACRO_COPY_EXPR_LIST(expr->generic_ident_expr.parameters);
|
||||
return expr;
|
||||
case EXPR_MACRO_BODY_EXPANSION:
|
||||
MACRO_COPY_EXPR_LIST(expr->body_expansion_expr.values);
|
||||
|
||||
@@ -73,8 +73,29 @@ bool parse_range(ParseContext *c, Range *range)
|
||||
range->end = 0;
|
||||
return true;
|
||||
}
|
||||
bool parse_generic_expr_list(ParseContext *c, Expr ***exprs_ref)
|
||||
{
|
||||
SourceSpan start = c->span;
|
||||
advance_and_verify(c, TOKEN_LBRACE);
|
||||
if (try_consume(c, TOKEN_RBRACE))
|
||||
{
|
||||
print_error_at(extend_span_with_token(start, c->prev_span), "At least one generic parameter was expected here.");
|
||||
return false;
|
||||
}
|
||||
do
|
||||
{
|
||||
ASSIGN_EXPR_OR_RET(Expr *expr, parse_expr(c), false);
|
||||
vec_add(*exprs_ref, expr);
|
||||
if (!try_consume(c, TOKEN_COMMA))
|
||||
{
|
||||
CONSUME_OR_RET(TOKEN_RBRACE, false);
|
||||
return true;
|
||||
}
|
||||
} while (!try_consume(c, TOKEN_RBRACE));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_expr_list(ParseContext *c, Expr ***exprs_ref, TokenType end_token)
|
||||
static bool parse_expr_list(ParseContext *c, Expr ***exprs_ref, TokenType end_token)
|
||||
{
|
||||
while (!try_consume(c, end_token))
|
||||
{
|
||||
@@ -1080,8 +1101,7 @@ static Expr *parse_generic_expr(ParseContext *c, Expr *left, SourceSpan lhs_star
|
||||
ASSERT(left && expr_ok(left));
|
||||
Expr *subs_expr = expr_new(EXPR_GENERIC_IDENT, lhs_start);
|
||||
subs_expr->generic_ident_expr.parent = exprid(left);
|
||||
advance_and_verify(c, TOKEN_LBRACE);
|
||||
if (!parse_expr_list(c, &subs_expr->generic_ident_expr.parmeters, TOKEN_RBRACE)) return poisoned_expr;
|
||||
if (!parse_generic_expr_list(c, &subs_expr->generic_ident_expr.parameters)) return poisoned_expr;
|
||||
RANGE_EXTEND_PREV(subs_expr);
|
||||
return subs_expr;
|
||||
}
|
||||
|
||||
@@ -499,8 +499,7 @@ static inline TypeInfo *parse_generic_type(ParseContext *c, TypeInfo *type)
|
||||
{
|
||||
ASSERT(type_info_ok(type));
|
||||
TypeInfo *generic_type = type_info_new(TYPE_INFO_GENERIC, type->span);
|
||||
advance_and_verify(c, TOKEN_LBRACE);
|
||||
if (!parse_expr_list(c, &generic_type->generic.params, TOKEN_RBRACE)) return poisoned_type_info;
|
||||
if (!parse_generic_expr_list(c, &generic_type->generic.params)) return poisoned_type_info;
|
||||
generic_type->generic.base = type;
|
||||
return generic_type;
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ Decl *parse_local_decl_after_type(ParseContext *c, TypeInfo *type);
|
||||
Decl *parse_var_decl(ParseContext *c);
|
||||
bool parse_current_is_expr(ParseContext *c);
|
||||
bool parse_joined_strings(ParseContext *c, const char **str_ref, size_t *len_ref);
|
||||
bool parse_expr_list(ParseContext *c, Expr ***exprs_ref, TokenType end_token);
|
||||
bool parse_generic_expr_list(ParseContext *c, Expr ***exprs_ref);
|
||||
bool parse_parameters(ParseContext *c, Decl ***params_ref,
|
||||
Variadic *variadic, int *vararg_index_ref, ParameterParseKind parse_kind);
|
||||
|
||||
|
||||
@@ -5164,7 +5164,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
|
||||
ASSERT(parameter_count > 0);
|
||||
if (parameter_count != vec_size(params))
|
||||
{
|
||||
ASSERT(vec_size(params));
|
||||
ASSERT_AT(span, vec_size(params));
|
||||
sema_error_at(c, extend_span_with_token(params[0]->span, vectail(params)->span),
|
||||
"The generic module expected %d arguments, but you supplied %d, did you make a mistake?",
|
||||
parameter_count,
|
||||
|
||||
@@ -10073,7 +10073,7 @@ static inline bool sema_expr_analyse_generic_ident(SemaContext *context, Expr *e
|
||||
}
|
||||
Decl *symbol = sema_analyse_parameterized_identifier(context, parent->unresolved_ident_expr.path,
|
||||
parent->unresolved_ident_expr.ident, parent->span,
|
||||
expr->generic_ident_expr.parmeters, NULL);
|
||||
expr->generic_ident_expr.parameters, NULL);
|
||||
if (!decl_ok(symbol)) return false;
|
||||
expr_resolve_ident(expr, symbol);
|
||||
return true;
|
||||
|
||||
31
test/test_suite/generic/generic_no_params.c3
Normal file
31
test/test_suite/generic/generic_no_params.c3
Normal file
@@ -0,0 +1,31 @@
|
||||
module values {Type};
|
||||
|
||||
struct Values
|
||||
{
|
||||
Type[] values;
|
||||
int count;
|
||||
}
|
||||
|
||||
fn void test()
|
||||
{
|
||||
|
||||
}
|
||||
module main;
|
||||
|
||||
import values;
|
||||
import std::collections::list;
|
||||
|
||||
fn void test1()
|
||||
{
|
||||
int x = values::test{}(); // #error: At least one generic parameter
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
List{Values{ }} v1s; // #error: At least one generic parameter
|
||||
}
|
||||
|
||||
fn void main()
|
||||
{
|
||||
List{Values{int}} v2s;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
struct Foo {
|
||||
void bar; // #error: Members cannot be of
|
||||
void bar; // #error: Members cannot
|
||||
}
|
||||
|
||||
alias Void = void;
|
||||
struct Foo2 {
|
||||
Void bar; // #error: Members cannot be of
|
||||
Void bar; // #error: Members cannot
|
||||
}
|
||||
|
||||
typedef Void2 = void;
|
||||
|
||||
Reference in New Issue
Block a user