diff --git a/releasenotes.md b/releasenotes.md index 943b0d2ae..ff4de6109 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -7,6 +7,7 @@ - Casting to / from an enum is now possible again. No need to use `.ordinal` and `.from_ordinal`. - Inline associated enum values are deprecated, use `--use-old-enums` to re-enable them. - `$typeof` may return a compile time type. +- Improved error messages on missing qualifier on enum value. #2260 ### Fixes - mkdir/rmdir would not work properly with substring paths on non-windows platforms. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 6c438757d..bd3e9a970 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1110,6 +1110,26 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, // Rerun if we can't do inference. if (!decl) { + if (!expr->unresolved_ident_expr.path && expr->unresolved_ident_expr.is_const && (!to || to->canonical->type_kind != TYPE_ENUM)) + { + CompilationUnit **units = context->unit->module->units; + FOREACH (CompilationUnit *, unit, units) + { + FOREACH(Decl *, decl, unit->enums) + { + FOREACH(Decl *, enum_val, decl->enums.values) + { + if (enum_val->name == expr->unresolved_ident_expr.ident) + { + RETURN_SEMA_ERROR(expr, "No constant named '%s' was found in the current scope. Did you " + "mean the value '%s' of the enum '%s'? The enum type cannot be inferred%s, so in that case you need to use " + "the qualified name: '%s.%s'.", + enum_val->name, enum_val->name, decl->name, to ? " correctly" : "", decl->name, enum_val->name); + } + } + } + } + } decl = sema_resolve_symbol(context, expr->unresolved_ident_expr.ident, expr->unresolved_ident_expr.path, expr->span); (void)decl; ASSERT_SPAN(expr, !decl); diff --git a/test/test_suite/enumerations/enum_infer_err.c3 b/test/test_suite/enumerations/enum_infer_err.c3 new file mode 100644 index 000000000..1883387cb --- /dev/null +++ b/test/test_suite/enumerations/enum_infer_err.c3 @@ -0,0 +1,16 @@ +import std::io; + +enum Foo +{ + BAR +} + +fn void test() +{ + int x = BAR; // #error: type cannot be inferred correctly, +} + +fn void main() +{ + io::printn(BAR); // #error: type cannot be inferred, +} \ No newline at end of file