diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 51497af7e..8612167c9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -62,7 +62,7 @@ Type * make_optional_ok_type (Type *value); void check_type_decl (CheckerContext *c, Entity *e, Ast *type_expr, Type *def); Entity * check_selector (CheckerContext *c, Operand *operand, Ast *node, Type *type_hint); Entity * check_ident (CheckerContext *c, Operand *o, Ast *n, Type *named_type, Type *type_hint, bool allow_import_name); -Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array ordered_operands); +Entity * find_polymorphic_record_entity (CheckerContext *c, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure); void check_not_tuple (CheckerContext *c, Operand *operand); void convert_to_typed (CheckerContext *c, Operand *operand, Type *target_type); gbString expr_to_string (Ast *expression); @@ -6336,12 +6336,16 @@ CallArgumentError check_polymorphic_record_type(CheckerContext *c, Operand *oper { gbAllocator a = c->allocator; - Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands); + bool failure = false; + Entity *found_entity = find_polymorphic_record_entity(c, original_type, param_count, ordered_operands, &failure); if (found_entity) { operand->mode = Addressing_Type; operand->type = found_entity->type; return err; } + if (failure) { + return CallArgumentError_NoneConstantParameter; + } String generated_name = make_string_c(expr_to_string(call)); diff --git a/src/check_type.cpp b/src/check_type.cpp index 45c59f2bc..ef68203ab 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -248,38 +248,47 @@ bool check_custom_align(CheckerContext *ctx, Ast *node, i64 *align_) { } -Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array ordered_operands) { +Entity *find_polymorphic_record_entity(CheckerContext *ctx, Type *original_type, isize param_count, Array const &ordered_operands, bool *failure) { auto *found_gen_types = map_get(&ctx->checker->info.gen_types, hash_pointer(original_type)); if (found_gen_types != nullptr) { for_array(i, *found_gen_types) { Entity *e = (*found_gen_types)[i]; Type *t = base_type(e->type); TypeTuple *tuple = get_record_polymorphic_params(t); - bool ok = true; GB_ASSERT(param_count == tuple->variables.count); + + bool skip = false; + for (isize j = 0; j < param_count; j++) { Entity *p = tuple->variables[j]; Operand o = ordered_operands[j]; if (p->kind == Entity_TypeName) { if (is_type_polymorphic(o.type)) { // NOTE(bill): Do not add polymorphic version to the gen_types - ok = false; - } - if (!are_types_identical(o.type, p->type)) { - ok = false; + skip = true; + break; + } else if (!are_types_identical(o.type, p->type)) { + skip = true; + break; } } else if (p->kind == Entity_Constant) { - if (!are_types_identical(o.type, p->type)) { - ok = false; + if (o.mode != Addressing_Constant) { + if (failure) *failure = true; + skip = true; + break; } if (!compare_exact_values(Token_CmpEq, o.value, p->Constant.value)) { - ok = false; + skip = true; + break; + } else if (!are_types_identical(o.type, p->type)) { + skip = true; + break; } } else { GB_PANIC("Unknown entity kind"); } } - if (ok) { + if (!skip) { return e; } } diff --git a/src/ir.cpp b/src/ir.cpp index d4aecebf0..e7317a960 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5647,7 +5647,8 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, Ast *left, } ir_start_block(proc, rhs); - array_add(&edges, ir_build_expr(proc, right)); + irValue *edge = ir_build_expr(proc, right); + array_add(&edges, edge); ir_emit_jump(proc, done); ir_start_block(proc, done); @@ -5656,8 +5657,6 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, TokenKind op, Ast *left, irValue *ir_emit_logical_binary_expr(irProcedure *proc, Ast *expr) { ast_node(be, BinaryExpr, expr); - irBlock *rhs = ir_new_block(proc, nullptr, "logical.cmp.rhs"); - irBlock *done = ir_new_block(proc, nullptr, "logical.cmp.done"); Type *type = type_of_expr(expr); type = default_type(type); @@ -6879,9 +6878,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { case_end; case_ast_node(be, BinaryExpr, expr); - irValue *left = ir_build_expr(proc, be->left); - Type *type = default_type(tv.type); - switch (be->op.kind) { case Token_Add: case Token_Sub: @@ -6895,6 +6891,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { case Token_AndNot: case Token_Shl: case Token_Shr: { + irValue *left = ir_build_expr(proc, be->left); + Type *type = default_type(tv.type); irValue *right = ir_build_expr(proc, be->right); return ir_emit_arith(proc, be->op.kind, left, right, type); } @@ -6906,10 +6904,11 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { case Token_LtEq: case Token_Gt: case Token_GtEq: { + irValue *left = ir_build_expr(proc, be->left); + Type *type = default_type(tv.type); irValue *right = ir_build_expr(proc, be->right); irValue *cmp = ir_emit_comp(proc, be->op.kind, left, right); return ir_emit_conv(proc, cmp, type); - break; } case Token_CmpAnd: @@ -6919,6 +6918,8 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { case Token_in: case Token_notin: { + irValue *left = ir_build_expr(proc, be->left); + Type *type = default_type(tv.type); irValue *right = ir_build_expr(proc, be->right); Type *rt = base_type(ir_type(right)); switch (rt->kind) {