AstNode* strip_aliases(AstNode* node);
-AstNumLit* make_bool_literal(bh_allocator, b32 b);
-AstNumLit* make_int_literal(bh_allocator a, i64 value);
-AstNumLit* make_float_literal(bh_allocator a, f64 value);
-AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high);
-AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right);
-AstArgument* make_argument(bh_allocator a, AstTyped* value);
-AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field);
-AstAddressOf* make_address_of(bh_allocator a, AstTyped* node);
-AstLocal* make_local(bh_allocator a, OnyxToken* token, AstType* type_node);
-AstLocal* make_local_with_type(bh_allocator a, OnyxToken* token, Type* type);
-AstNode* make_symbol(bh_allocator a, OnyxToken* sym);
-AstUnaryOp* make_cast(bh_allocator a, AstTyped* expr, Type* to);
-AstZeroValue* make_zero_value(bh_allocator a, OnyxToken *token, Type* type);
+AstNumLit* make_bool_literal(bh_allocator, b32 b);
+AstNumLit* make_int_literal(bh_allocator a, i64 value);
+AstNumLit* make_float_literal(bh_allocator a, f64 value);
+AstRangeLiteral* make_range_literal(bh_allocator a, AstTyped* low, AstTyped* high);
+AstBinaryOp* make_binary_op(bh_allocator a, BinaryOp operation, AstTyped* left, AstTyped* right);
+AstArgument* make_argument(bh_allocator a, AstTyped* value);
+AstFieldAccess* make_field_access(bh_allocator a, AstTyped* node, char* field);
+AstAddressOf* make_address_of(bh_allocator a, AstTyped* node);
+AstLocal* make_local(bh_allocator a, OnyxToken* token, AstType* type_node);
+AstLocal* make_local_with_type(bh_allocator a, OnyxToken* token, Type* type);
+AstNode* make_symbol(bh_allocator a, OnyxToken* sym);
+AstUnaryOp* make_cast(bh_allocator a, AstTyped* expr, Type* to);
+AstZeroValue* make_zero_value(bh_allocator a, OnyxToken *token, Type* type);
+AstStructLiteral* make_optional_literal_some(bh_allocator a, AstTyped *expr, Type* opt_type);
void arguments_initialize(Arguments* args);
b32 fill_in_arguments(Arguments* args, AstNode* provider, char** err_msg, b32 insert_zero_values);
return legal ? TYPE_MATCH_SUCCESS : TYPE_MATCH_FAILED;
}
+ // If the destination type is an optional, and the node's type is a value of
+ // the same underlying type, then we can construct an optional with a value
+ // implicitly. This makes working with optionals barable.
+ else if (type_struct_constructed_from_poly_struct(type, builtin_optional_type)) {
+ TypeMatch match = unify_node_and_type_(pnode, type->Struct.poly_sln[0].type, permanent);
+ if (match != TYPE_MATCH_SUCCESS) return match;
+
+ AstStructLiteral *opt_lit = make_optional_literal_some(context.ast_alloc, node, type);
+
+ *(AstStructLiteral **) pnode = opt_lit;
+ return TYPE_MATCH_SUCCESS;
+ }
+
+
// If the node is a numeric literal, try to convert it to the destination type.
else if (node->kind == Ast_Kind_NumLit) {
if (convert_numlit_to_type((AstNumLit *) node, type)) return TYPE_MATCH_SUCCESS;
AstNumLit* bl = onyx_ast_node_new(a, sizeof(AstNumLit), Ast_Kind_NumLit);
bl->flags |= Ast_Flag_Comptime;
bl->type_node = (AstType *) &basic_type_bool;
+ bl->type = &basic_types[Basic_Kind_Bool];
bl->value.i = b ? 1 : 0;
return bl;
return zero_value;
}
+AstStructLiteral* make_optional_literal_some(bh_allocator a, AstTyped *expr, Type *opt_type) {
+ AstStructLiteral *opt_lit = onyx_ast_node_new(a, sizeof(AstStructLiteral), Ast_Kind_Struct_Literal);
+ opt_lit->token = expr->token;
+
+ arguments_initialize(&opt_lit->args);
+ arguments_ensure_length(&opt_lit->args, 2);
+ opt_lit->args.values[0] = make_bool_literal(a, 1);
+ opt_lit->args.values[1] = expr;
+
+ opt_lit->type = opt_type;
+ return opt_lit;
+}
+
+
+
void arguments_initialize(Arguments* args) {
if (args->values == NULL) bh_arr_new(global_heap_allocator, args->values, 2);
if (args->named_values == NULL) bh_arr_new(global_heap_allocator, args->named_values, 2);