authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-16 18:27:17+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-20 20:25:11+02:00
log0616d2966a623a005891a2037b49cc2b8ad5b9c4
treec082e8fc50b9a9035792ec1948c3d5f1ff997a7c
parente5a3eb9777ff165d936b0811f3825eabb8bcd6a4

Sema: allow coercing typed undefined to int

Closes #13556

2 files changed, 24 insertions(+), 4 deletions(-)

src/Sema.zig+16-4
...@@ -24307,7 +24307,10 @@ fn coerceExtra(...@@ -24307,7 +24307,10 @@ fn coerceExtra(
24307 },24307 },
24308 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {24308 .Int, .ComptimeInt => switch (inst_ty.zigTypeTag()) {
24309 .Float, .ComptimeFloat => float: {24309 .Float, .ComptimeFloat => float: {
24310 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse {24310 if (is_undef) {
24311 return sema.addConstUndef(dest_ty);
24312 }
24313 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
24311 if (dest_ty.zigTypeTag() == .ComptimeInt) {24314 if (dest_ty.zigTypeTag() == .ComptimeInt) {
24312 if (!opts.report_err) return error.NotCoercible;24315 if (!opts.report_err) return error.NotCoercible;
24313 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");24316 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_int' must be comptime-known");
...@@ -24327,7 +24330,10 @@ fn coerceExtra(...@@ -24327,7 +24330,10 @@ fn coerceExtra(
24327 return try sema.addConstant(dest_ty, result_val);24330 return try sema.addConstant(dest_ty, result_val);
24328 },24331 },
24329 .Int, .ComptimeInt => {24332 .Int, .ComptimeInt => {
24330 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {24333 if (is_undef) {
24334 return sema.addConstUndef(dest_ty);
24335 }
24336 if (try sema.resolveMaybeUndefVal(inst)) |val| {
24331 // comptime-known integer to other number24337 // comptime-known integer to other number
24332 if (!(try sema.intFitsInType(val, dest_ty, null))) {24338 if (!(try sema.intFitsInType(val, dest_ty, null))) {
24333 if (!opts.report_err) return error.NotCoercible;24339 if (!opts.report_err) return error.NotCoercible;
...@@ -24364,7 +24370,10 @@ fn coerceExtra(...@@ -24364,7 +24370,10 @@ fn coerceExtra(
24364 return try sema.addConstant(dest_ty, result_val);24370 return try sema.addConstant(dest_ty, result_val);
24365 },24371 },
24366 .Float => {24372 .Float => {
24367 if (try sema.resolveDefinedValue(block, inst_src, inst)) |val| {24373 if (is_undef) {
24374 return sema.addConstUndef(dest_ty);
24375 }
24376 if (try sema.resolveMaybeUndefVal(inst)) |val| {
24368 const result_val = try val.floatCast(sema.arena, dest_ty, target);24377 const result_val = try val.floatCast(sema.arena, dest_ty, target);
24369 if (!val.eql(result_val, dest_ty, sema.mod)) {24378 if (!val.eql(result_val, dest_ty, sema.mod)) {
24370 return sema.fail(24379 return sema.fail(
...@@ -24389,7 +24398,10 @@ fn coerceExtra(...@@ -24389,7 +24398,10 @@ fn coerceExtra(
24389 }24398 }
24390 },24399 },
24391 .Int, .ComptimeInt => int: {24400 .Int, .ComptimeInt => int: {
24392 const val = (try sema.resolveDefinedValue(block, inst_src, inst)) orelse {24401 if (is_undef) {
24402 return sema.addConstUndef(dest_ty);
24403 }
24404 const val = (try sema.resolveMaybeUndefVal(inst)) orelse {
24393 if (dest_ty.zigTypeTag() == .ComptimeFloat) {24405 if (dest_ty.zigTypeTag() == .ComptimeFloat) {
24394 if (!opts.report_err) return error.NotCoercible;24406 if (!opts.report_err) return error.NotCoercible;
24395 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");24407 return sema.failWithNeededComptime(block, inst_src, "value being casted to 'comptime_float' must be comptime-known");
test/behavior/cast.zig+8
...@@ -1429,3 +1429,11 @@ test "peer type resolution of function pointer and function body" {...@@ -1429,3 +1429,11 @@ test "peer type resolution of function pointer and function body" {
1429 try expect(@TypeOf(a, b) == *const fn () u32);1429 try expect(@TypeOf(a, b) == *const fn () u32);
1430 try expect(@TypeOf(b, a) == *const fn () u32);1430 try expect(@TypeOf(b, a) == *const fn () u32);
1431}1431}
1432
1433test "cast typed undefined to int" {
1434 comptime {
1435 const a: u16 = undefined;
1436 const b: u8 = a;
1437 _ = b;
1438 }
1439}