diff --git a/releasenotes.md b/releasenotes.md index d86cd820f..417b2e91f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -11,6 +11,7 @@ - Enums now work with `membersof` to return the associated values. #2571 - Deprecated `SomeEnum.associated` in favour of `SomeEnum.membersof` - Refactored `@simd` implementation. +- Improve error message for `Foo{}` when `Foo` is not a generic type #2574. ### Fixes - `Foo.is_eq` would return false if the type was a `typedef` and had an overload, but the underlying type was not comparable. diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index e8000f096..28018df03 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -75,13 +75,8 @@ bool parse_range(ParseContext *c, Range *range) } 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; - } + if (try_consume(c, TOKEN_RBRACE)) return true; do { ASSIGN_EXPR_OR_RET(Expr *expr, parse_expr(c), false); @@ -2064,7 +2059,7 @@ ADVANCE:; /** * string_literal ::= STRING+ */ -static Expr *parse_string_literal(ParseContext *c, Expr *left, SourceSpan lhs_start) +static Expr *parse_string_literal(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED) { ASSERT(!left && "Had left hand side"); Expr *expr_string = EXPR_NEW_TOKEN(EXPR_CONST); @@ -2082,7 +2077,7 @@ static Expr *parse_string_literal(ParseContext *c, Expr *left, SourceSpan lhs_st /* * bool ::= 'true' | 'false' */ -static Expr *parse_bool(ParseContext *c, Expr *left, SourceSpan lhs_start) +static Expr *parse_bool(ParseContext *c, Expr *left, SourceSpan lhs_start UNUSED) { ASSERT(!left && "Had left hand side"); Expr *number = EXPR_NEW_TOKEN(EXPR_CONST); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index be1401a18..d58d67aaf 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -5262,13 +5262,22 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con unsigned parameter_count = vec_size(module->parameters); ASSERT(parameter_count > 0); - if (parameter_count != vec_size(params)) + unsigned count = vec_size(params); + if (parameter_count != count) { - 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, - vec_size(params)); + if (!count) + { + sema_error_at(c, invocation_span, + "'%s' must be instantiatied with generic module arguments inside the '{}', did you forget them?", name, (int)parameter_count); + + } + else + { + sema_error_at(c, extend_span_with_token(params[0]->span, vectail(params)->span), + "The generic module expected %d argument(s), but you supplied %d, did you make a mistake?", + parameter_count, + vec_size(params)); + } return poisoned_decl; } if (!sema_generate_parameterized_name_to_scratch(c, module, params, true, was_recursive_ref)) return poisoned_decl; diff --git a/test/test_suite/generic/generic_no_arg.c3 b/test/test_suite/generic/generic_no_arg.c3 new file mode 100644 index 000000000..5ca842501 --- /dev/null +++ b/test/test_suite/generic/generic_no_arg.c3 @@ -0,0 +1,30 @@ +module foo; +import std, bar; +struct Foo +{ + int i; +} +fn void foo(Foo f) {} + +fn void a() +{ + List{} a; // #error: must be instantiatied with generic module arguments +} +fn void b() +{ + foo(Foo{}); // #error: 'Foo' is not a generic type +} +fn void c() +{ + bar::test{}(); // #error: must be instantiatied with generic module arguments +} + +fn int main() +{ + + return 0; +} + +module bar{Type}; +fn void test() +{} \ No newline at end of file diff --git a/test/test_suite/generic/generic_no_params.c3 b/test/test_suite/generic/generic_no_params.c3 index 3b8864612..2741e332f 100644 --- a/test/test_suite/generic/generic_no_params.c3 +++ b/test/test_suite/generic/generic_no_params.c3 @@ -17,12 +17,12 @@ import std::collections::list; fn void test1() { - int x = values::test{}(); // #error: At least one generic parameter + int x = values::test{}(); // #error: must be instantiatied with generic } fn void test2() { - List{Values{ }} v1s; // #error: At least one generic parameter + List{Values{ }} v1s; // #error: must be instantiatied with generic } fn void main()