aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorRaul Leal <raulgrell@gmail.com>2017-04-13 09:59:39 +0000
committerAndrew Kelley <superjoe30@gmail.com>2017-04-17 19:55:56 -0400
commit32665856064dde5a08a64de8641c8bec9c6f352f (patch)
treed3bfd0cac9667ab0c0cd8b70658c8f4d1011db1a /src/ir.cpp
parent2e0b114fdce1a10b8433438d8e2251cf708a72ec (diff)
downloadzig-32665856064dde5a08a64de8641c8bec9c6f352f.tar.gz
zig-32665856064dde5a08a64de8641c8bec9c6f352f.zip
Implicit cast from T to %?T
closes #171
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp42
1 files changed, 37 insertions, 5 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index e22f96fba0..1c9f1c5fe2 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5826,11 +5826,12 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
{
return true;
}
- } else if ((other_type->id == TypeTableEntryIdNumLitFloat &&
- const_val->data.x_bignum.kind == BigNumKindFloat) ||
- (other_type->id == TypeTableEntryIdNumLitInt &&
- const_val->data.x_bignum.kind == BigNumKindInt))
- {
+ } else if ((other_type->id == TypeTableEntryIdNumLitFloat && const_val->data.x_bignum.kind == BigNumKindFloat) ||
+ (other_type->id == TypeTableEntryIdNumLitInt && const_val->data.x_bignum.kind == BigNumKindInt )) {
+ return true;
+ } else if ((other_type->id == TypeTableEntryIdMaybe &&
+ other_type->data.maybe.child_type->id == TypeTableEntryIdInt &&
+ const_val->data.x_bignum.kind == BigNumKindInt)) {
return true;
}
@@ -5894,6 +5895,18 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
return ImplicitCastMatchResultYes;
}
+ // implicit conversion from T to %?T
+ if (expected_type->id == TypeTableEntryIdErrorUnion &&
+ expected_type->data.error.child_type->id == TypeTableEntryIdMaybe &&
+ ir_types_match_with_implicit_cast(
+ ira,
+ expected_type->data.error.child_type->data.maybe.child_type,
+ actual_type,
+ value))
+ {
+ return ImplicitCastMatchResultYes;
+ }
+
// implicit widening conversion
if (expected_type->id == TypeTableEntryIdInt &&
actual_type->id == TypeTableEntryIdInt &&
@@ -7067,6 +7080,25 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
}
+ // explicit cast from T to %?T
+ if (wanted_type->id == TypeTableEntryIdErrorUnion &&
+ wanted_type->data.error.child_type->id == TypeTableEntryIdMaybe &&
+ actual_type->id != TypeTableEntryIdMaybe) {
+ if (types_match_const_cast_only(wanted_type->data.error.child_type->data.maybe.child_type, actual_type) ||
+ actual_type->id == TypeTableEntryIdNullLit ||
+ actual_type->id == TypeTableEntryIdNumLitInt ) {
+ IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error.child_type, value);
+ if (type_is_invalid(cast1->value.type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
+ if (type_is_invalid(cast2->value.type))
+ return ira->codegen->invalid_instruction;
+
+ return cast2;
+ }
+ }
+
// explicit cast from number literal to another type
// explicit cast from number literal to &const integer
if (actual_type->id == TypeTableEntryIdNumLitFloat ||