From d27b76fc31c33d9381a95ecd5e8567c93bf12eb0 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 27 Jan 2016 12:28:05 -0700 Subject: [PATCH] add error for `@typeof` or `&` of number literal closes #85 --- src/analyze.cpp | 34 ++++++++++++++++++++++++++++++---- test/run_tests.cpp | 14 +++++++++++++- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 78402d661..79a332396 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3426,10 +3426,30 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry AstNode *expr_node = node->data.fn_call_expr.params.at(0); TypeTableEntry *type_entry = analyze_expression(g, import, context, nullptr, expr_node); - if (type_entry->id == TypeTableEntryIdInvalid) { - return g->builtin_types.entry_invalid; - } else { - return resolve_expr_const_val_as_type(g, node, type_entry); + switch (type_entry->id) { + case TypeTableEntryIdInvalid: + return type_entry; + case TypeTableEntryIdNumLitFloat: + case TypeTableEntryIdNumLitInt: + case TypeTableEntryIdUndefLit: + add_node_error(g, expr_node, + buf_sprintf("type '%s' not eligible for @typeof", buf_ptr(&type_entry->name))); + return g->builtin_types.entry_invalid; + case TypeTableEntryIdMetaType: + case TypeTableEntryIdVoid: + case TypeTableEntryIdBool: + case TypeTableEntryIdUnreachable: + case TypeTableEntryIdInt: + case TypeTableEntryIdFloat: + case TypeTableEntryIdPointer: + case TypeTableEntryIdArray: + case TypeTableEntryIdStruct: + case TypeTableEntryIdMaybe: + case TypeTableEntryIdErrorUnion: + case TypeTableEntryIdPureError: + case TypeTableEntryIdEnum: + case TypeTableEntryIdFn: + return resolve_expr_const_val_as_type(g, node, type_entry); } } case BuiltinFnIdCInclude: @@ -3729,6 +3749,12 @@ static TypeTableEntry *analyze_prefix_op_expr(CodeGen *g, ImportTableEntry *impo return resolve_expr_const_val_as_type(g, node, get_pointer_to_type(g, meta_type, is_const)); } + } else if (child_type->id == TypeTableEntryIdNumLitInt || + child_type->id == TypeTableEntryIdNumLitFloat) + { + add_node_error(g, expr_node, + buf_sprintf("unable to get address of type '%s'", buf_ptr(&child_type->name))); + return g->builtin_types.entry_invalid; } else { return get_pointer_to_type(g, child_type, is_const); } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 5825dba01..ed833b285 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -999,7 +999,7 @@ pub fn main(args: [][]u8) -> %void { add_simple_case("order-independent declarations", R"SOURCE( import "std.zig"; -const z : @typeof(stdin_fileno) = 0; +const z = stdin_fileno; const x : @typeof(y) = 1234; const y : u16 = 5678; pub fn main(args: [][]u8) -> %void { @@ -1683,6 +1683,18 @@ c_import { add_compile_fail_case("empty file", "", 1, ".tmp_source.zig:1:1: error: missing export declaration and output name not provided"); + add_compile_fail_case("address of number literal", R"SOURCE( +const x = 3; +const y = &x; + )SOURCE", 1, ".tmp_source.zig:3:12: error: unable to get address of type '(integer literal)'"); + + add_compile_fail_case("@typeof number literal", R"SOURCE( +const x = 3; +struct Foo { + index: @typeof(x), +} + )SOURCE", 1, ".tmp_source.zig:4:20: error: type '(integer literal)' not eligible for @typeof"); + } static void print_compiler_invocation(TestCase *test_case) {