| ... | ... | @@ -237,6 +237,7 @@ static bool type_is_complete(TypeTableEntry *type_entry) { |
| 237 | 237 | case TypeTableEntryIdNumLitFloat: |
| 238 | 238 | case TypeTableEntryIdNumLitInt: |
| 239 | 239 | case TypeTableEntryIdUndefLit: |
| 240 | case TypeTableEntryIdNullLit: |
| 240 | 241 | case TypeTableEntryIdMaybe: |
| 241 | 242 | case TypeTableEntryIdErrorUnion: |
| 242 | 243 | case TypeTableEntryIdPureError: |
| ... | ... | @@ -925,6 +926,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor |
| 925 | 926 | case TypeTableEntryIdNumLitFloat: |
| 926 | 927 | case TypeTableEntryIdNumLitInt: |
| 927 | 928 | case TypeTableEntryIdUndefLit: |
| 929 | case TypeTableEntryIdNullLit: |
| 928 | 930 | case TypeTableEntryIdNamespace: |
| 929 | 931 | case TypeTableEntryIdGenericFn: |
| 930 | 932 | fn_proto->skip = true; |
| ... | ... | @@ -963,6 +965,7 @@ static TypeTableEntry *analyze_fn_proto_type(CodeGen *g, ImportTableEntry *impor |
| 963 | 965 | case TypeTableEntryIdNumLitFloat: |
| 964 | 966 | case TypeTableEntryIdNumLitInt: |
| 965 | 967 | case TypeTableEntryIdUndefLit: |
| 968 | case TypeTableEntryIdNullLit: |
| 966 | 969 | case TypeTableEntryIdUnreachable: |
| 967 | 970 | case TypeTableEntryIdNamespace: |
| 968 | 971 | case TypeTableEntryIdGenericFn: |
| ... | ... | @@ -1912,6 +1915,7 @@ static bool type_has_codegen_value(TypeTableEntry *type_entry) { |
| 1912 | 1915 | case TypeTableEntryIdNumLitFloat: |
| 1913 | 1916 | case TypeTableEntryIdNumLitInt: |
| 1914 | 1917 | case TypeTableEntryIdUndefLit: |
| 1918 | case TypeTableEntryIdNullLit: |
| 1915 | 1919 | case TypeTableEntryIdNamespace: |
| 1916 | 1920 | case TypeTableEntryIdGenericFn: |
| 1917 | 1921 | return false; |
| ... | ... | @@ -2167,6 +2171,13 @@ static bool types_match_with_implicit_cast(CodeGen *g, TypeTableEntry *expected_ |
| 2167 | 2171 | return true; |
| 2168 | 2172 | } |
| 2169 | 2173 | |
| 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 | 2181 | // implicit conversion from error child type to error type |
| 2171 | 2182 | if (expected_type->id == TypeTableEntryIdErrorUnion && |
| 2172 | 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 | 2982 | return g->builtin_types.entry_bool; |
| 2972 | 2983 | } |
| 2973 | 2984 | |
| 2974 | | static 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 | | |
| 2981 | 2985 | static TypeTableEntry *resolve_expr_const_val_as_non_null(CodeGen *g, AstNode *node, |
| 2982 | 2986 | TypeTableEntry *type, ConstExprValue *other_val) |
| 2983 | 2987 | { |
| ... | ... | @@ -3358,6 +3362,7 @@ static TypeTableEntry *analyze_bool_bin_op_expr(CodeGen *g, ImportTableEntry *im |
| 3358 | 3362 | case TypeTableEntryIdArray: |
| 3359 | 3363 | case TypeTableEntryIdStruct: |
| 3360 | 3364 | case TypeTableEntryIdUndefLit: |
| 3365 | case TypeTableEntryIdNullLit: |
| 3361 | 3366 | case TypeTableEntryIdMaybe: |
| 3362 | 3367 | case TypeTableEntryIdErrorUnion: |
| 3363 | 3368 | case TypeTableEntryIdUnion: |
| ... | ... | @@ -3916,26 +3921,17 @@ static TypeTableEntry *analyze_null_literal_expr(CodeGen *g, ImportTableEntry *i |
| 3916 | 3921 | { |
| 3917 | 3922 | assert(node->type == NodeTypeNullLiteral); |
| 3918 | 3923 | |
| 3919 | | if (!expected_type) { |
| 3920 | | add_node_error(g, node, buf_sprintf("unable to determine null type")); |
| 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; |
| 3924 | ConstExprValue *const_val = &get_resolved_expr(node)->const_val; |
| 3925 | const_val->ok = true; |
| 3932 | 3926 | |
| 3933 | | return resolve_expr_const_val_as_null(g, node, expected_type); |
| 3927 | return g->builtin_types.entry_null; |
| 3934 | 3928 | } |
| 3935 | 3929 | |
| 3936 | 3930 | static TypeTableEntry *analyze_undefined_literal_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 3937 | 3931 | TypeTableEntry *expected_type, AstNode *node) |
| 3938 | 3932 | { |
| 3933 | assert(node->type == NodeTypeUndefinedLiteral); |
| 3934 | |
| 3939 | 3935 | Expr *expr = get_resolved_expr(node); |
| 3940 | 3936 | ConstExprValue *const_val = &expr->const_val; |
| 3941 | 3937 | |
| ... | ... | @@ -4519,6 +4515,14 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B |
| 4519 | 4515 | } |
| 4520 | 4516 | } |
| 4521 | 4517 | |
| 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 | 4526 | // explicit cast from child type of error type to error type |
| 4523 | 4527 | if (wanted_type->id == TypeTableEntryIdErrorUnion) { |
| 4524 | 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 | 5207 | case TypeTableEntryIdNumLitFloat: |
| 5204 | 5208 | case TypeTableEntryIdNumLitInt: |
| 5205 | 5209 | case TypeTableEntryIdUndefLit: |
| 5210 | case TypeTableEntryIdNullLit: |
| 5206 | 5211 | case TypeTableEntryIdNamespace: |
| 5207 | 5212 | case TypeTableEntryIdGenericFn: |
| 5208 | 5213 | add_node_error(g, expr_node, |
| ... | ... | @@ -6252,13 +6257,12 @@ static TypeTableEntry *analyze_return_expr(CodeGen *g, ImportTableEntry *import, |
| 6252 | 6257 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| 6253 | 6258 | return resolved_type; |
| 6254 | 6259 | } else if (resolved_type->id == TypeTableEntryIdErrorUnion) { |
| 6255 | | TypeTableEntry *return_type = context->fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 6256 | | if (return_type->id != TypeTableEntryIdErrorUnion && |
| 6257 | | return_type->id != TypeTableEntryIdPureError) |
| 6260 | if (expected_return_type->id != TypeTableEntryIdErrorUnion && |
| 6261 | expected_return_type->id != TypeTableEntryIdPureError) |
| 6258 | 6262 | { |
| 6259 | 6263 | ErrorMsg *msg = add_node_error(g, node, |
| 6260 | 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 | 6266 | AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type; |
| 6263 | 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 | 6287 | if (resolved_type->id == TypeTableEntryIdInvalid) { |
| 6284 | 6288 | return resolved_type; |
| 6285 | 6289 | } else if (resolved_type->id == TypeTableEntryIdMaybe) { |
| 6286 | | TypeTableEntry *return_type = context->fn_entry->type_entry->data.fn.fn_type_id.return_type; |
| 6287 | | if (return_type->id != TypeTableEntryIdMaybe) { |
| 6290 | if (expected_return_type->id != TypeTableEntryIdMaybe) { |
| 6288 | 6291 | ErrorMsg *msg = add_node_error(g, node, |
| 6289 | 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 | 6294 | AstNode *return_type_node = context->fn_entry->fn_def_node->data.fn_def.fn_proto->data.fn_proto.return_type; |
| 6292 | 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 | 7230 | case TypeTableEntryIdNumLitFloat: |
| 7228 | 7231 | case TypeTableEntryIdNumLitInt: |
| 7229 | 7232 | case TypeTableEntryIdUndefLit: |
| 7233 | case TypeTableEntryIdNullLit: |
| 7230 | 7234 | case TypeTableEntryIdNamespace: |
| 7231 | 7235 | case TypeTableEntryIdGenericFn: |
| 7232 | 7236 | zig_unreachable(); |
| ... | ... | @@ -7335,6 +7339,8 @@ static uint32_t hash_const_val(TypeTableEntry *type, ConstExprValue *const_val) |
| 7335 | 7339 | return hash_ptr(const_val->data.x_ptr.ptr); |
| 7336 | 7340 | case TypeTableEntryIdUndefLit: |
| 7337 | 7341 | return 162837799; |
| 7342 | case TypeTableEntryIdNullLit: |
| 7343 | return 844854567; |
| 7338 | 7344 | case TypeTableEntryIdArray: |
| 7339 | 7345 | // TODO better hashing algorithm |
| 7340 | 7346 | return 1166190605; |
| ... | ... | @@ -7428,6 +7434,7 @@ static TypeTableEntry *type_of_first_thing_in_memory(TypeTableEntry *type_entry) |
| 7428 | 7434 | case TypeTableEntryIdNumLitFloat: |
| 7429 | 7435 | case TypeTableEntryIdNumLitInt: |
| 7430 | 7436 | case TypeTableEntryIdUndefLit: |
| 7437 | case TypeTableEntryIdNullLit: |
| 7431 | 7438 | case TypeTableEntryIdUnreachable: |
| 7432 | 7439 | case TypeTableEntryIdMetaType: |
| 7433 | 7440 | case TypeTableEntryIdVoid: |