parent
2e0b114fdc
commit
3266585606
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"*.zig": "c",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"*.inc": "cpp",
|
||||||
|
"thread": "cpp"
|
||||||
|
}
|
||||||
|
}
|
42
src/ir.cpp
42
src/ir.cpp
|
@ -5826,11 +5826,12 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if ((other_type->id == TypeTableEntryIdNumLitFloat &&
|
} else if ((other_type->id == TypeTableEntryIdNumLitFloat && const_val->data.x_bignum.kind == BigNumKindFloat) ||
|
||||||
const_val->data.x_bignum.kind == BigNumKindFloat) ||
|
(other_type->id == TypeTableEntryIdNumLitInt && const_val->data.x_bignum.kind == BigNumKindInt )) {
|
||||||
(other_type->id == TypeTableEntryIdNumLitInt &&
|
return true;
|
||||||
const_val->data.x_bignum.kind == BigNumKindInt))
|
} else if ((other_type->id == TypeTableEntryIdMaybe &&
|
||||||
{
|
other_type->data.maybe.child_type->id == TypeTableEntryIdInt &&
|
||||||
|
const_val->data.x_bignum.kind == BigNumKindInt)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5894,6 +5895,18 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
|
||||||
return ImplicitCastMatchResultYes;
|
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
|
// implicit widening conversion
|
||||||
if (expected_type->id == TypeTableEntryIdInt &&
|
if (expected_type->id == TypeTableEntryIdInt &&
|
||||||
actual_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);
|
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 another type
|
||||||
// explicit cast from number literal to &const integer
|
// explicit cast from number literal to &const integer
|
||||||
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
|
if (actual_type->id == TypeTableEntryIdNumLitFloat ||
|
||||||
|
|
|
@ -65,7 +65,6 @@ fn testPeerResolveArrayConstSlice(b: bool) {
|
||||||
assert(mem.eql(u8, value2, "zz"));
|
assert(mem.eql(u8, value2, "zz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
test "integer literal to &const int" {
|
test "integer literal to &const int" {
|
||||||
const x: &const i32 = 3;
|
const x: &const i32 = 3;
|
||||||
assert(*x == 3);
|
assert(*x == 3);
|
||||||
|
@ -75,3 +74,41 @@ test "string literal to &const []const u8" {
|
||||||
const x: &const []const u8 = "hello";
|
const x: &const []const u8 = "hello";
|
||||||
assert(mem.eql(u8, *x, "hello"));
|
assert(mem.eql(u8, *x, "hello"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "implicitly cast from T to %?T" {
|
||||||
|
castToMaybeTypeError(1);
|
||||||
|
comptime castToMaybeTypeError(1);
|
||||||
|
}
|
||||||
|
const A = struct {
|
||||||
|
a: i32,
|
||||||
|
};
|
||||||
|
fn castToMaybeTypeError(z: i32) {
|
||||||
|
const x = i32(1);
|
||||||
|
const y: %?i32 = x;
|
||||||
|
assert(??%%y == 1);
|
||||||
|
|
||||||
|
const f = z;
|
||||||
|
const g: %?i32 = f;
|
||||||
|
|
||||||
|
const a = A{ .a = 1 };
|
||||||
|
const b: %?A = a;
|
||||||
|
assert((??%%b).a == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "implicitly cast from int to %?T" {
|
||||||
|
const f: %?i32 = 1;
|
||||||
|
comptime const g: %?i32 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
test "return null from fn() -> %?&T" {
|
||||||
|
const a = returnNullFromMaybeTypeErrorRef();
|
||||||
|
const b = returnNullLitFromMaybeTypeErrorRef();
|
||||||
|
assert(%%a == null and %%b == null);
|
||||||
|
}
|
||||||
|
fn returnNullFromMaybeTypeErrorRef() -> %?&A {
|
||||||
|
const a: ?&A = null;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
fn returnNullLitFromMaybeTypeErrorRef() -> %?&A {
|
||||||
|
return null;
|
||||||
|
}
|
Loading…
Reference in New Issue