authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-17 20:15:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-17 20:15:39-04:00
logdef4fbc9ab704b1add5c3af40692b3d26594e58e
tree8c7cb70fab20076fa7263d835ce53431c8644d7c
parent2e0b114fdce1a10b8433438d8e2251cf708a72ec
parentc7852bd596a632644e9e94e785f32e6ddcf00c16

Merge branch 'raulgrell-master'


2 files changed, 89 insertions(+), 5 deletions(-)

src/ir.cpp+51-4
...@@ -5826,12 +5826,26 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc...@@ -5826,12 +5826,26 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
5826 {5826 {
5827 return true;5827 return true;
5828 }5828 }
5829 } else if ((other_type->id == TypeTableEntryIdNumLitFloat &&5829 } else if ((other_type->id == TypeTableEntryIdNumLitFloat && const_val->data.x_bignum.kind == BigNumKindFloat) ||
5830 const_val->data.x_bignum.kind == BigNumKindFloat) ||5830 (other_type->id == TypeTableEntryIdNumLitInt && const_val->data.x_bignum.kind == BigNumKindInt ))
5831 (other_type->id == TypeTableEntryIdNumLitInt &&
5832 const_val->data.x_bignum.kind == BigNumKindInt))
5833 {5831 {
5834 return true;5832 return true;
5833 } else if (other_type->id == TypeTableEntryIdMaybe) {
5834 TypeTableEntry *child_type = other_type->data.maybe.child_type;
5835 if ((child_type->id == TypeTableEntryIdNumLitFloat && const_val->data.x_bignum.kind == BigNumKindFloat) ||
5836 (child_type->id == TypeTableEntryIdNumLitInt && const_val->data.x_bignum.kind == BigNumKindInt ))
5837 {
5838 return true;
5839 } else if (child_type->id == TypeTableEntryIdInt && const_val->data.x_bignum.kind == BigNumKindInt) {
5840 if (bignum_fits_in_bits(&const_val->data.x_bignum,
5841 child_type->data.integral.bit_count,
5842 child_type->data.integral.is_signed))
5843 {
5844 return true;
5845 }
5846 } else if (child_type->id == TypeTableEntryIdFloat && const_val->data.x_bignum.kind == BigNumKindFloat) {
5847 return true;
5848 }
5835 }5849 }
58365850
5837 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";5851 const char *num_lit_str = (const_val->data.x_bignum.kind == BigNumKindFloat) ? "float" : "integer";
...@@ -5894,6 +5908,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,...@@ -5894,6 +5908,16 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
5894 return ImplicitCastMatchResultYes;5908 return ImplicitCastMatchResultYes;
5895 }5909 }
58965910
5911 // implicit conversion from T to %?T
5912 if (expected_type->id == TypeTableEntryIdErrorUnion &&
5913 expected_type->data.error.child_type->id == TypeTableEntryIdMaybe &&
5914 ir_types_match_with_implicit_cast(ira,
5915 expected_type->data.error.child_type->data.maybe.child_type,
5916 actual_type, value))
5917 {
5918 return ImplicitCastMatchResultYes;
5919 }
5920
5897 // implicit widening conversion5921 // implicit widening conversion
5898 if (expected_type->id == TypeTableEntryIdInt &&5922 if (expected_type->id == TypeTableEntryIdInt &&
5899 actual_type->id == TypeTableEntryIdInt &&5923 actual_type->id == TypeTableEntryIdInt &&
...@@ -7067,6 +7091,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst...@@ -7067,6 +7091,29 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
7067 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);7091 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type);
7068 }7092 }
70697093
7094 // explicit cast from T to %?T
7095 if (wanted_type->id == TypeTableEntryIdErrorUnion &&
7096 wanted_type->data.error.child_type->id == TypeTableEntryIdMaybe &&
7097 actual_type->id != TypeTableEntryIdMaybe)
7098 {
7099 TypeTableEntry *wanted_child_type = wanted_type->data.error.child_type->data.maybe.child_type;
7100 if (types_match_const_cast_only(wanted_child_type, actual_type) ||
7101 actual_type->id == TypeTableEntryIdNullLit ||
7102 actual_type->id == TypeTableEntryIdNumLitInt ||
7103 actual_type->id == TypeTableEntryIdNumLitFloat)
7104 {
7105 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error.child_type, value);
7106 if (type_is_invalid(cast1->value.type))
7107 return ira->codegen->invalid_instruction;
7108
7109 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1);
7110 if (type_is_invalid(cast2->value.type))
7111 return ira->codegen->invalid_instruction;
7112
7113 return cast2;
7114 }
7115 }
7116
7070 // explicit cast from number literal to another type7117 // explicit cast from number literal to another type
7071 // explicit cast from number literal to &const integer7118 // explicit cast from number literal to &const integer
7072 if (actual_type->id == TypeTableEntryIdNumLitFloat ||7119 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
test/cases/cast.zig+38-1
...@@ -65,7 +65,6 @@ fn testPeerResolveArrayConstSlice(b: bool) {...@@ -65,7 +65,6 @@ fn testPeerResolveArrayConstSlice(b: bool) {
65 assert(mem.eql(u8, value2, "zz"));65 assert(mem.eql(u8, value2, "zz"));
66}66}
6767
68
69test "integer literal to &const int" {68test "integer literal to &const int" {
70 const x: &const i32 = 3;69 const x: &const i32 = 3;
71 assert(*x == 3);70 assert(*x == 3);
...@@ -75,3 +74,41 @@ test "string literal to &const []const u8" {...@@ -75,3 +74,41 @@ test "string literal to &const []const u8" {
75 const x: &const []const u8 = "hello";74 const x: &const []const u8 = "hello";
76 assert(mem.eql(u8, *x, "hello"));75 assert(mem.eql(u8, *x, "hello"));
77}76}
77
78test "implicitly cast from T to %?T" {
79 castToMaybeTypeError(1);
80 comptime castToMaybeTypeError(1);
81}
82const A = struct {
83 a: i32,
84};
85fn castToMaybeTypeError(z: i32) {
86 const x = i32(1);
87 const y: %?i32 = x;
88 assert(??%%y == 1);
89
90 const f = z;
91 const g: %?i32 = f;
92
93 const a = A{ .a = 1 };
94 const b: %?A = a;
95 assert((??%%b).a == 1);
96}
97
98test "implicitly cast from int to %?T" {
99 const f: %?i32 = 1;
100 comptime const g: %?i32 = 1;
101}
102
103test "return null from fn() -> %?&T" {
104 const a = returnNullFromMaybeTypeErrorRef();
105 const b = returnNullLitFromMaybeTypeErrorRef();
106 assert(%%a == null and %%b == null);
107}
108fn returnNullFromMaybeTypeErrorRef() -> %?&A {
109 const a: ?&A = null;
110 return a;
111}
112fn returnNullLitFromMaybeTypeErrorRef() -> %?&A {
113 return null;
114}
\ No newline at end of file