authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-08-25 17:25:18-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-08-29 22:14:09-07:00
log651dc31247c2f637925ed6a6e92c8bc1a19efd5c
tree7e75713d6c4c9b5dfc8783759b5ed60b5e9e71bf
parent1f7ec741fa5b1d9ba3826e06a8a8a0feec58876f

implement null as a literal type


8 files changed, 76 insertions(+), 35 deletions(-)

CMakeLists.txt+1
...@@ -202,6 +202,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/builtin.zig" DESTINATION "${ZIG_STD_DEST}...@@ -202,6 +202,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/builtin.zig" DESTINATION "${ZIG_STD_DEST}
202install(FILES "${CMAKE_SOURCE_DIR}/std/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}")202install(FILES "${CMAKE_SOURCE_DIR}/std/compiler_rt.zig" DESTINATION "${ZIG_STD_DEST}")
203install(FILES "${CMAKE_SOURCE_DIR}/std/cstr.zig" DESTINATION "${ZIG_STD_DEST}")203install(FILES "${CMAKE_SOURCE_DIR}/std/cstr.zig" DESTINATION "${ZIG_STD_DEST}")
204install(FILES "${CMAKE_SOURCE_DIR}/std/debug.zig" DESTINATION "${ZIG_STD_DEST}")204install(FILES "${CMAKE_SOURCE_DIR}/std/debug.zig" DESTINATION "${ZIG_STD_DEST}")
205install(FILES "${CMAKE_SOURCE_DIR}/std/dwarf.zig" DESTINATION "${ZIG_STD_DEST}")
205install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}")206install(FILES "${CMAKE_SOURCE_DIR}/std/elf.zig" DESTINATION "${ZIG_STD_DEST}")
206install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}")207install(FILES "${CMAKE_SOURCE_DIR}/std/empty.zig" DESTINATION "${ZIG_STD_DEST}")
207install(FILES "${CMAKE_SOURCE_DIR}/std/endian.zig" DESTINATION "${ZIG_STD_DEST}")208install(FILES "${CMAKE_SOURCE_DIR}/std/endian.zig" DESTINATION "${ZIG_STD_DEST}")
src/all_types.hpp+3-3
...@@ -394,6 +394,7 @@ enum CastOp {...@@ -394,6 +394,7 @@ enum CastOp {
394 CastOpWidenOrShorten,394 CastOpWidenOrShorten,
395 CastOpToUnknownSizeArray,395 CastOpToUnknownSizeArray,
396 CastOpMaybeWrap,396 CastOpMaybeWrap,
397 CastOpNullToMaybe,
397 CastOpErrorWrap,398 CastOpErrorWrap,
398 CastOpPureErrorWrap,399 CastOpPureErrorWrap,
399 CastOpPointerReinterpret,400 CastOpPointerReinterpret,
...@@ -692,19 +693,16 @@ struct AstNodeContainerInitExpr {...@@ -692,19 +693,16 @@ struct AstNodeContainerInitExpr {
692693
693struct AstNodeNullLiteral {694struct AstNodeNullLiteral {
694 // populated by semantic analyzer695 // populated by semantic analyzer
695 StructValExprCodeGen resolved_struct_val_expr;
696 Expr resolved_expr;696 Expr resolved_expr;
697};697};
698698
699struct AstNodeUndefinedLiteral {699struct AstNodeUndefinedLiteral {
700 // populated by semantic analyzer700 // populated by semantic analyzer
701 StructValExprCodeGen resolved_struct_val_expr;
702 Expr resolved_expr;701 Expr resolved_expr;
703};702};
704703
705struct AstNodeZeroesLiteral {704struct AstNodeZeroesLiteral {
706 // populated by semantic analyzer705 // populated by semantic analyzer
707 StructValExprCodeGen resolved_struct_val_expr;
708 Expr resolved_expr;706 Expr resolved_expr;
709};707};
710708
...@@ -989,6 +987,7 @@ enum TypeTableEntryId {...@@ -989,6 +987,7 @@ enum TypeTableEntryId {
989 TypeTableEntryIdNumLitFloat,987 TypeTableEntryIdNumLitFloat,
990 TypeTableEntryIdNumLitInt,988 TypeTableEntryIdNumLitInt,
991 TypeTableEntryIdUndefLit,989 TypeTableEntryIdUndefLit,
990 TypeTableEntryIdNullLit,
992 TypeTableEntryIdMaybe,991 TypeTableEntryIdMaybe,
993 TypeTableEntryIdErrorUnion,992 TypeTableEntryIdErrorUnion,
994 TypeTableEntryIdPureError,993 TypeTableEntryIdPureError,
...@@ -1228,6 +1227,7 @@ struct CodeGen {...@@ -1228,6 +1227,7 @@ struct CodeGen {
1228 TypeTableEntry *entry_num_lit_int;1227 TypeTableEntry *entry_num_lit_int;
1229 TypeTableEntry *entry_num_lit_float;1228 TypeTableEntry *entry_num_lit_float;
1230 TypeTableEntry *entry_undef;1229 TypeTableEntry *entry_undef;
1230 TypeTableEntry *entry_null;
1231 TypeTableEntry *entry_pure_error;1231 TypeTableEntry *entry_pure_error;
1232 TypeTableEntry *entry_os_enum;1232 TypeTableEntry *entry_os_enum;
1233 TypeTableEntry *entry_arch_enum;1233 TypeTableEntry *entry_arch_enum;
src/analyze.cpp+35-28
...@@ -237,6 +237,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {...@@ -237,6 +237,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) {
237 case TypeTableEntryIdNumLitFloat:237 case TypeTableEntryIdNumLitFloat:
238 case TypeTableEntryIdNumLitInt:238 case TypeTableEntryIdNumLitInt:
239 case TypeTableEntryIdUndefLit:239 case TypeTableEntryIdUndefLit:
240 case TypeTableEntryIdNullLit:
240 case TypeTableEntryIdMaybe:241 case TypeTableEntryIdMaybe:
241 case TypeTableEntryIdErrorUnion:242 case TypeTableEntryIdErrorUnion:
242 case TypeTableEntryIdPureError:243 case TypeTableEntryIdPureError:
...@@ -925,6 +926,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -925,6 +926,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
925 case TypeTableEntryIdNumLitFloat:926 case TypeTableEntryIdNumLitFloat:
926 case TypeTableEntryIdNumLitInt:927 case TypeTableEntryIdNumLitInt:
927 case TypeTableEntryIdUndefLit:928 case TypeTableEntryIdUndefLit:
929 case TypeTableEntryIdNullLit:
928 case TypeTableEntryIdNamespace:930 case TypeTableEntryIdNamespace:
929 case TypeTableEntryIdGenericFn:931 case TypeTableEntryIdGenericFn:
930 fn_proto->skip = true;932 fn_proto->skip = true;
...@@ -963,6 +965,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor...@@ -963,6 +965,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor
963 case TypeTableEntryIdNumLitFloat:965 case TypeTableEntryIdNumLitFloat:
964 case TypeTableEntryIdNumLitInt:966 case TypeTableEntryIdNumLitInt:
965 case TypeTableEntryIdUndefLit:967 case TypeTableEntryIdUndefLit:
968 case TypeTableEntryIdNullLit:
966 case TypeTableEntryIdUnreachable:969 case TypeTableEntryIdUnreachable:
967 case TypeTableEntryIdNamespace:970 case TypeTableEntryIdNamespace:
968 case TypeTableEntryIdGenericFn:971 case TypeTableEntryIdGenericFn:
...@@ -1912,6 +1915,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {...@@ -1912,6 +1915,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) {
1912 case TypeTableEntryIdNumLitFloat:1915 case TypeTableEntryIdNumLitFloat:
1913 case TypeTableEntryIdNumLitInt:1916 case TypeTableEntryIdNumLitInt:
1914 case TypeTableEntryIdUndefLit:1917 case TypeTableEntryIdUndefLit:
1918 case TypeTableEntryIdNullLit:
1915 case TypeTableEntryIdNamespace:1919 case TypeTableEntryIdNamespace:
1916 case TypeTableEntryIdGenericFn:1920 case TypeTableEntryIdGenericFn:
1917 return false;1921 return false;
...@@ -2167,6 +2171,13 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_...@@ -2167,6 +2171,13 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_
2167 return true;2171 return true;
2168 }2172 }
21692173
2174 // implicit conversion from null literal to maybe type
2175 if (expected_type->id == TypeTableEntryIdMaybe &&
2176 actual_type->id == TypeTableEntryIdNullLit)
2177 {
2178 return true;
2179 }
2180
2170 // implicit conversion from error child type to error type2181 // implicit conversion from error child type to error type
2171 if (expected_type->id == TypeTableEntryIdErrorUnion &&2182 if (expected_type->id == TypeTableEntryIdErrorUnion &&
2172 types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,2183 types_match_with_implicit_cast(g, expected_type->data.error.child_type, actual_type,
...@@ -2971,13 +2982,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node,...@@ -2971,13 +2982,6 @@ static TypeTableEntry *resolve_expr_const_val_as_bool(CodeGen *g, AstNode *node,
2971 return g->builtin_types.entry_bool;2982 return g->builtin_types.entry_bool;
2972}2983}
29732984
2974static TypeTableEntry *resolve_expr_const_val_as_null(CodeGen *g, AstNode *node, TypeTableEntry *type) {
2975 Expr *expr = get_resolved_expr(node);
2976 expr->const_val.ok = true;
2977 expr->const_val.data.x_maybe = nullptr;
2978 return type;
2979}
2980
2981static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *node,2985static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *node,
2982 TypeTableEntry *type, ConstExprValue *other_val)2986 TypeTableEntry *type, ConstExprValue *other_val)
2983{2987{
...@@ -3358,6 +3362,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im...@@ -3358,6 +3362,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im
3358 case TypeTableEntryIdArray:3362 case TypeTableEntryIdArray:
3359 case TypeTableEntryIdStruct:3363 case TypeTableEntryIdStruct:
3360 case TypeTableEntryIdUndefLit:3364 case TypeTableEntryIdUndefLit:
3365 case TypeTableEntryIdNullLit:
3361 case TypeTableEntryIdMaybe:3366 case TypeTableEntryIdMaybe:
3362 case TypeTableEntryIdErrorUnion:3367 case TypeTableEntryIdErrorUnion:
3363 case TypeTableEntryIdUnion:3368 case TypeTableEntryIdUnion:
...@@ -3916,26 +3921,17 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i...@@ -3916,26 +3921,17 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i
3916{3921{
3917 assert(node->type == NodeTypeNullLiteral);3922 assert(node->type == NodeTypeNullLiteral);
39183923
3919 if (!expected_type) {3924 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
3920 add_node_error(g, node, buf_sprintf("unable to determine null type"));3925 const_val->ok = true;
3921 return g->builtin_types.entry_invalid;
3922 }
3923
3924 if (expected_type->id != TypeTableEntryIdMaybe) {
3925 add_node_error(g, node,
3926 buf_sprintf("expected maybe type, got '%s'", buf_ptr(&expected_type->name)));
3927 return g->builtin_types.entry_invalid;
3928 }
3929
3930 node->data.null_literal.resolved_struct_val_expr.type_entry = expected_type;
3931 node->data.null_literal.resolved_struct_val_expr.source_node = node;
39323926
3933 return resolve_expr_const_val_as_null(g, node, expected_type);3927 return g->builtin_types.entry_null;
3934}3928}
39353929
3936static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,3930static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
3937 TypeTableEntry *expected_type, AstNode *node)3931 TypeTableEntry *expected_type, AstNode *node)
3938{3932{
3933 assert(node->type == NodeTypeUndefinedLiteral);
3934
3939 Expr *expr = get_resolved_expr(node);3935 Expr *expr = get_resolved_expr(node);
3940 ConstExprValue *const_val = &expr->const_val;3936 ConstExprValue *const_val = &expr->const_val;
39413937
...@@ -4519,6 +4515,14 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -4519,6 +4515,14 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
4519 }4515 }
4520 }4516 }
45214517
4518 // explicit cast from null literal to maybe type
4519 if (wanted_type->id == TypeTableEntryIdMaybe &&
4520 actual_type->id == TypeTableEntryIdNullLit)
4521 {
4522 get_resolved_expr(node)->return_knowledge = ReturnKnowledgeKnownNull;
4523 return resolve_cast(g, context, node, expr_node, wanted_type, CastOpNullToMaybe, true);
4524 }
4525
4522 // explicit cast from child type of error type to error type4526 // explicit cast from child type of error type to error type
4523 if (wanted_type->id == TypeTableEntryIdErrorUnion) {4527 if (wanted_type->id == TypeTableEntryIdErrorUnion) {
4524 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {4528 if (types_match_const_cast_only(wanted_type->data.error.child_type, actual_type)) {
...@@ -5203,6 +5207,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -5203,6 +5207,7 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
5203 case TypeTableEntryIdNumLitFloat:5207 case TypeTableEntryIdNumLitFloat:
5204 case TypeTableEntryIdNumLitInt:5208 case TypeTableEntryIdNumLitInt:
5205 case TypeTableEntryIdUndefLit:5209 case TypeTableEntryIdUndefLit:
5210 case TypeTableEntryIdNullLit:
5206 case TypeTableEntryIdNamespace:5211 case TypeTableEntryIdNamespace:
5207 case TypeTableEntryIdGenericFn:5212 case TypeTableEntryIdGenericFn:
5208 add_node_error(g, expr_node,5213 add_node_error(g, expr_node,
...@@ -6252,13 +6257,12 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,...@@ -6252,13 +6257,12 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,
6252 if (resolved_type->id == TypeTableEntryIdInvalid) {6257 if (resolved_type->id == TypeTableEntryIdInvalid) {
6253 return resolved_type;6258 return resolved_type;
6254 } else if (resolved_type->id == TypeTableEntryIdErrorUnion) {6259 } else if (resolved_type->id == TypeTableEntryIdErrorUnion) {
6255 TypeTableEntry *return_type = context->fn_entry->type_entry->data.fn.fn_type_id.return_type;6260 if (expected_return_type->id != TypeTableEntryIdErrorUnion &&
6256 if (return_type->id != TypeTableEntryIdErrorUnion &&6261 expected_return_type->id != TypeTableEntryIdPureError)
6257 return_type->id != TypeTableEntryIdPureError)
6258 {6262 {
6259 ErrorMsg *msg = add_node_error(g, node,6263 ErrorMsg *msg = add_node_error(g, node,
6260 buf_sprintf("%%return statement in function with return type '%s'",6264 buf_sprintf("%%return statement in function with return type '%s'",
6261 buf_ptr(&return_type->name)));6265 buf_ptr(&expected_return_type->name)));
6262 AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type;6266 AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type;
6263 add_error_note(g, msg, return_type_node, buf_sprintf("function return type here"));6267 add_error_note(g, msg, return_type_node, buf_sprintf("function return type here"));
6264 }6268 }
...@@ -6283,11 +6287,10 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,...@@ -6283,11 +6287,10 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import,
6283 if (resolved_type->id == TypeTableEntryIdInvalid) {6287 if (resolved_type->id == TypeTableEntryIdInvalid) {
6284 return resolved_type;6288 return resolved_type;
6285 } else if (resolved_type->id == TypeTableEntryIdMaybe) {6289 } else if (resolved_type->id == TypeTableEntryIdMaybe) {
6286 TypeTableEntry *return_type = context->fn_entry->type_entry->data.fn.fn_type_id.return_type;6290 if (expected_return_type->id != TypeTableEntryIdMaybe) {
6287 if (return_type->id != TypeTableEntryIdMaybe) {
6288 ErrorMsg *msg = add_node_error(g, node,6291 ErrorMsg *msg = add_node_error(g, node,
6289 buf_sprintf("?return statement in function with return type '%s'",6292 buf_sprintf("?return statement in function with return type '%s'",
6290 buf_ptr(&return_type->name)));6293 buf_ptr(&expected_return_type->name)));
6291 AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type;6294 AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type;
6292 add_error_note(g, msg, return_type_node, buf_sprintf("function return type here"));6295 add_error_note(g, msg, return_type_node, buf_sprintf("function return type here"));
6293 }6296 }
...@@ -7227,6 +7230,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -7227,6 +7230,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
7227 case TypeTableEntryIdNumLitFloat:7230 case TypeTableEntryIdNumLitFloat:
7228 case TypeTableEntryIdNumLitInt:7231 case TypeTableEntryIdNumLitInt:
7229 case TypeTableEntryIdUndefLit:7232 case TypeTableEntryIdUndefLit:
7233 case TypeTableEntryIdNullLit:
7230 case TypeTableEntryIdNamespace:7234 case TypeTableEntryIdNamespace:
7231 case TypeTableEntryIdGenericFn:7235 case TypeTableEntryIdGenericFn:
7232 zig_unreachable();7236 zig_unreachable();
...@@ -7335,6 +7339,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)...@@ -7335,6 +7339,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val)
7335 return hash_ptr(const_val->data.x_ptr.ptr);7339 return hash_ptr(const_val->data.x_ptr.ptr);
7336 case TypeTableEntryIdUndefLit:7340 case TypeTableEntryIdUndefLit:
7337 return 162837799;7341 return 162837799;
7342 case TypeTableEntryIdNullLit:
7343 return 844854567;
7338 case TypeTableEntryIdArray:7344 case TypeTableEntryIdArray:
7339 // TODO better hashing algorithm7345 // TODO better hashing algorithm
7340 return 1166190605;7346 return 1166190605;
...@@ -7428,6 +7434,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)...@@ -7428,6 +7434,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry)
7428 case TypeTableEntryIdNumLitFloat:7434 case TypeTableEntryIdNumLitFloat:
7429 case TypeTableEntryIdNumLitInt:7435 case TypeTableEntryIdNumLitInt:
7430 case TypeTableEntryIdUndefLit:7436 case TypeTableEntryIdUndefLit:
7437 case TypeTableEntryIdNullLit:
7431 case TypeTableEntryIdUnreachable:7438 case TypeTableEntryIdUnreachable:
7432 case TypeTableEntryIdMetaType:7439 case TypeTableEntryIdMetaType:
7433 case TypeTableEntryIdVoid:7440 case TypeTableEntryIdVoid:
src/codegen.cpp+10
...@@ -875,6 +875,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -875,6 +875,9 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
875875
876 return cast_expr->tmp_ptr;876 return cast_expr->tmp_ptr;
877 }877 }
878 case CastOpNullToMaybe:
879 // handled by constant expression evaluator
880 zig_unreachable();
878 case CastOpErrorWrap:881 case CastOpErrorWrap:
879 {882 {
880 assert(wanted_type->id == TypeTableEntryIdErrorUnion);883 assert(wanted_type->id == TypeTableEntryIdErrorUnion);
...@@ -3806,6 +3809,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -3806,6 +3809,7 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
3806 case TypeTableEntryIdNumLitFloat:3809 case TypeTableEntryIdNumLitFloat:
3807 case TypeTableEntryIdNumLitInt:3810 case TypeTableEntryIdNumLitInt:
3808 case TypeTableEntryIdUndefLit:3811 case TypeTableEntryIdUndefLit:
3812 case TypeTableEntryIdNullLit:
3809 case TypeTableEntryIdVoid:3813 case TypeTableEntryIdVoid:
3810 case TypeTableEntryIdNamespace:3814 case TypeTableEntryIdNamespace:
3811 case TypeTableEntryIdGenericFn:3815 case TypeTableEntryIdGenericFn:
...@@ -4311,6 +4315,12 @@ static void define_builtin_types(CodeGen *g) {...@@ -4311,6 +4315,12 @@ static void define_builtin_types(CodeGen *g) {
4311 entry->deep_const = true;4315 entry->deep_const = true;
4312 g->builtin_types.entry_undef = entry;4316 g->builtin_types.entry_undef = entry;
4313 }4317 }
4318 {
4319 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdNullLit);
4320 buf_init_from_str(&entry->name, "(null)");
4321 entry->deep_const = true;
4322 g->builtin_types.entry_null = entry;
4323 }
43144324
4315 for (int int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) {4325 for (int int_size_i = 0; int_size_i < array_length(int_sizes_in_bits); int_size_i += 1) {
4316 int size_in_bits = int_sizes_in_bits[int_size_i];4326 int size_in_bits = int_sizes_in_bits[int_size_i];
src/eval.cpp+6
...@@ -45,6 +45,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty...@@ -45,6 +45,8 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b, TypeTableEntry *ty
45 zig_panic("TODO");45 zig_panic("TODO");
46 case TypeTableEntryIdUndefLit:46 case TypeTableEntryIdUndefLit:
47 zig_panic("TODO");47 zig_panic("TODO");
48 case TypeTableEntryIdNullLit:
49 zig_panic("TODO");
48 case TypeTableEntryIdMaybe:50 case TypeTableEntryIdMaybe:
49 zig_panic("TODO");51 zig_panic("TODO");
50 case TypeTableEntryIdErrorUnion:52 case TypeTableEntryIdErrorUnion:
...@@ -650,6 +652,10 @@ void eval_const_expr_implicit_cast(CastOp cast_op,...@@ -650,6 +652,10 @@ void eval_const_expr_implicit_cast(CastOp cast_op,
650 const_val->data.x_maybe = other_val;652 const_val->data.x_maybe = other_val;
651 const_val->ok = true;653 const_val->ok = true;
652 break;654 break;
655 case CastOpNullToMaybe:
656 const_val->data.x_maybe = nullptr;
657 const_val->ok = true;
658 break;
653 case CastOpErrorWrap:659 case CastOpErrorWrap:
654 const_val->data.x_err.err = nullptr;660 const_val->data.x_err.err = nullptr;
655 const_val->data.x_err.payload = other_val;661 const_val->data.x_err.payload = other_val;
std/debug.zig+5-3
...@@ -40,7 +40,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {...@@ -40,7 +40,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream) -> %void {
4040
41 %return out_stream.printInt(usize, return_address);41 %return out_stream.printInt(usize, return_address);
42 %return out_stream.printf(" -> ");42 %return out_stream.printf(" -> ");
43 %return out_stream.printInt(u64, debug_info_offset);43 %return out_stream.printInt(u64, compile_unit_offset);
44 %return out_stream.printf("\n");44 %return out_stream.printf("\n");
45 maybe_fp = *(&const ?&const u8)(fp);45 maybe_fp = *(&const ?&const u8)(fp);
46 }46 }
...@@ -82,7 +82,8 @@ fn findCompileUnitOffset(st: &ElfStackTrace, target_address: usize) -> %u64 {...@@ -82,7 +82,8 @@ fn findCompileUnitOffset(st: &ElfStackTrace, target_address: usize) -> %u64 {
82}82}
8383
84fn arangesOffset(st: &ElfStackTrace, target_address: usize) -> %?u64 {84fn arangesOffset(st: &ElfStackTrace, target_address: usize) -> %?u64 {
85 const aranges = ?return st.aranges;85 // TODO ability to implicitly cast null to %?T
86 const aranges = st.aranges ?? return (?u64)(null);
8687
87 %return st.elf.seekToSection(aranges);88 %return st.elf.seekToSection(aranges);
8889
...@@ -129,7 +130,8 @@ fn arangesOffset(st: &ElfStackTrace, target_address: usize) -> %?u64 {...@@ -129,7 +130,8 @@ fn arangesOffset(st: &ElfStackTrace, target_address: usize) -> %?u64 {
129 if (address == 0 && length == 0) break;130 if (address == 0 && length == 0) break;
130131
131 if (target_address >= address && target_address < address + length) {132 if (target_address >= address && target_address < address + length) {
132 return debug_info_offset;133 // TODO ability to implicitly cast T to %?T
134 return (?u64)(debug_info_offset);
133 }135 }
134 }136 }
135 }137 }
test/cases/maybe_return.zig created+15
...@@ -0,0 +1,15 @@
1const assert = @import("std").debug.assert;
2
3#attribute("test")
4fn maybeReturn() {
5 assert(??foo(1235));
6 assert(if (const _ ?= foo(null)) false else true);
7 assert(!??foo(1234));
8}
9
10// TODO add another function with static_eval_enable(true)
11#static_eval_enable(false)
12fn foo(x: ?i32) -> ?bool {
13 const value = ?return x;
14 return value > 1234;
15}
test/run_tests.cpp+1-1
...@@ -1211,7 +1211,7 @@ fn derp(){}...@@ -1211,7 +1211,7 @@ fn derp(){}
12111211
1212 add_compile_fail_case("assign null to non-nullable pointer", R"SOURCE(1212 add_compile_fail_case("assign null to non-nullable pointer", R"SOURCE(
1213const a: &u8 = null;1213const a: &u8 = null;
1214 )SOURCE", 1, ".tmp_source.zig:2:16: error: expected maybe type, got '&u8'");1214 )SOURCE", 1, ".tmp_source.zig:2:16: error: expected type '&u8', got '(null)'");
12151215
1216 add_compile_fail_case("indexing an array of size zero", R"SOURCE(1216 add_compile_fail_case("indexing an array of size zero", R"SOURCE(
1217const array = []u8{};1217const array = []u8{};