Skip to content

Commit e1dfb5f

Browse files
committed
copy elision: double implicit cast
```zig export fn entry() void { var x: error!?Foo = bar(); } ``` ```llvm define void @entry() #2 !dbg !41 { Entry: %x = alloca { i16, { %Foo, i1 } }, align 4 %0 = getelementptr inbounds { i16, { %Foo, i1 } }, { i16, { %Foo, i1 } }* %x, i32 0, i32 0, !dbg !61 store i16 0, i16* %0, align 2, !dbg !61 %1 = getelementptr inbounds { i16, { %Foo, i1 } }, { i16, { %Foo, i1 } }* %x, i32 0, i32 1, !dbg !61 %2 = getelementptr inbounds { %Foo, i1 }, { %Foo, i1 }* %1, i32 0, i32 1, !dbg !61 store i1 true, i1* %2, align 1, !dbg !61 %3 = getelementptr inbounds { %Foo, i1 }, { %Foo, i1 }* %1, i32 0, i32 0, !dbg !61 call fastcc void @bar(%Foo* sret %3), !dbg !62 ret void, !dbg !63 } ```
1 parent 5106eac commit e1dfb5f

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

Diff for: src/ir.cpp

+23-3
Original file line numberDiff line numberDiff line change
@@ -4935,9 +4935,8 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node
49354935
size_t arg_count = node->data.fn_call_expr.params.length;
49364936
IrInstruction **args = allocate<IrInstruction*>(arg_count);
49374937
for (size_t i = 0; i < arg_count; i += 1) {
4938-
IrInstruction *param_result_loc = ir_build_result_param(irb, scope, node, fn_ref, i);
49394938
AstNode *arg_node = node->data.fn_call_expr.params.at(i);
4940-
args[i] = ir_gen_node(irb, arg_node, scope, LValNone, param_result_loc);
4939+
args[i] = ir_gen_node(irb, arg_node, scope, LValNone, nullptr);
49414940
if (args[i] == irb->codegen->invalid_instruction)
49424941
return args[i];
49434942
}
@@ -10885,7 +10884,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
1088510884
}
1088610885
}
1088710886

10888-
// cast from error set to error union type
10887+
// cast from E to E!T
1088910888
if (wanted_type->id == ZigTypeIdErrorUnion &&
1089010889
actual_type->id == ZigTypeIdErrorSet)
1089110890
{
@@ -11200,6 +11199,27 @@ static IrInstruction *ir_implicit_cast_result(IrAnalyze *ira, IrInstruction *res
1120011199
return ir_analyze_result_error_union_code(ira, result_loc, needed_child_type);
1120111200
}
1120211201

11202+
// cast from T to E!?T
11203+
if (have_child_type->id == ZigTypeIdErrorUnion &&
11204+
have_child_type->data.error_union.payload_type->id == ZigTypeIdOptional &&
11205+
needed_child_type->id != ZigTypeIdOptional)
11206+
{
11207+
ZigType *wanted_child_type = have_child_type->data.error_union.payload_type->data.maybe.child_type;
11208+
if (types_match_const_cast_only(ira, wanted_child_type, needed_child_type, source_node,
11209+
false).id == ConstCastResultIdOk ||
11210+
needed_child_type->id == ZigTypeIdNull ||
11211+
needed_child_type->id == ZigTypeIdComptimeInt ||
11212+
needed_child_type->id == ZigTypeIdComptimeFloat)
11213+
{
11214+
IrInstruction *cast1 = ir_implicit_cast_result(ira, result_loc,
11215+
have_child_type->data.error_union.payload_type);
11216+
if (type_is_invalid(cast1->value.type))
11217+
return ira->codegen->invalid_instruction;
11218+
11219+
return ir_implicit_cast_result(ira, cast1, needed_child_type);
11220+
}
11221+
}
11222+
1120311223
ErrorMsg *parent_msg = ir_add_error_node(ira, source_node,
1120411224
buf_sprintf("expected type '%s', found '%s'",
1120511225
buf_ptr(&have_child_type->name),

0 commit comments

Comments
 (0)