authorgravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-07 13:02:01+02:00
committergravatar for justus@klausecker.deJustus Klausecker <justus@klausecker.de> 2025-08-12 16:33:57+02:00
log05762ca02ff97e7abfe1b52c090663dbf99bd4fc
tree73e60e53611da67db0dd73cbde39aa93d94f44cf
parent0ef26d113ae5a8b307a3af76db61706846fea22f

address most comments


6 files changed, 61 insertions(+), 99 deletions(-)

src/InternPool.zig+5-3
......@@ -2036,6 +2036,8 @@ pub const Key = union(enum) {
20362036 /// Each element/field stored as an `Index`.
20372037 /// In the case of sentinel-terminated arrays, the sentinel value *is* stored,
20382038 /// so the slice length will be one more than the type's array length.
2039 /// There must be at least one element which is not `undefined`. If all elements are
2040 /// undefined, instead create an undefined value of the aggregate type.
20392041 aggregate: Aggregate,
20402042 /// An instance of a union.
20412043 un: Union,
......@@ -8408,7 +8410,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
84088410 if (!ip.isUndef(elem)) any_defined = true;
84098411 assert(ip.typeOf(elem) == child);
84108412 }
8411 assert(any_defined);
8413 assert(any_defined); // aggregate fields must not be all undefined
84128414 },
84138415 .struct_type => {
84148416 var any_defined = false;
......@@ -8416,7 +8418,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
84168418 if (!ip.isUndef(elem)) any_defined = true;
84178419 assert(ip.typeOf(elem) == field_ty);
84188420 }
8419 assert(any_defined);
8421 assert(any_defined); // aggregate fields must not be all undefined
84208422 },
84218423 .tuple_type => |tuple_type| {
84228424 var any_defined = false;
......@@ -8424,7 +8426,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
84248426 if (!ip.isUndef(elem)) any_defined = true;
84258427 assert(ip.typeOf(elem) == ty);
84268428 }
8427 assert(any_defined);
8429 assert(any_defined); // aggregate fields must not be all undefined
84288430 },
84298431 else => unreachable,
84308432 };
src/Sema.zig+40-32
......@@ -13637,6 +13637,8 @@ fn zirShl(
1363713637 const scalar_ty = lhs_ty.scalarType(zcu);
1363813638 const scalar_rhs_ty = rhs_ty.scalarType(zcu);
1363913639
13640 // AstGen currently forces the rhs of `<<` to coerce to the correct type before the `.shl` instruction, so
13641 // we already know `scalar_rhs_ty` is valid for `.shl` -- we only need to validate for `.shl_sat`.
1364013642 if (air_tag == .shl_sat) _ = try sema.checkIntType(block, rhs_src, scalar_rhs_ty);
1364113643
1364213644 const maybe_lhs_val = try sema.resolveValueResolveLazy(lhs);
......@@ -13645,25 +13647,29 @@ fn zirShl(
1364513647 const runtime_src = rs: {
1364613648 if (maybe_rhs_val) |rhs_val| {
1364713649 if (maybe_lhs_val) |lhs_val| {
13648 return Air.internedToRef((try arith.shl(sema, block, lhs_ty, lhs_val, rhs_val, lhs_src, rhs_src, switch (air_tag) {
13650 return .fromValue(try arith.shl(sema, block, lhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
1364913651 .shl => .shl,
1365013652 .shl_sat => .shl_sat,
1365113653 .shl_exact => .shl_exact,
1365213654 else => unreachable,
13653 })).toIntern());
13655 }));
1365413656 }
1365513657 if (rhs_val.isUndef(zcu)) switch (air_tag) {
1365613658 .shl_sat => return pt.undefRef(lhs_ty),
1365713659 .shl, .shl_exact => return sema.failWithUseOfUndef(block, rhs_src, null),
1365813660 else => unreachable,
1365913661 };
13660 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);
13662 const bits = scalar_ty.intInfo(zcu).bits;
1366113663 switch (rhs_ty.zigTypeTag(zcu)) {
1366213664 .int, .comptime_int => {
1366313665 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1366413666 .gt => {
13665 if (air_tag != .shl_sat and try rhs_val.compareHeteroSema(.gte, bits_val, pt)) {
13666 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13667 if (air_tag != .shl_sat) {
13668 var rhs_space: Value.BigIntSpace = undefined;
13669 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13670 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
13671 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
13672 }
1366713673 }
1366813674 },
1366913675 .eq => return lhs,
......@@ -13672,8 +13678,7 @@ fn zirShl(
1367213678 },
1367313679 .vector => {
1367413680 var any_positive: bool = false;
13675 var elem_idx: usize = 0;
13676 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {
13681 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
1367713682 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1367813683 if (rhs_elem.isUndef(zcu)) switch (air_tag) {
1367913684 .shl_sat => continue,
......@@ -13682,8 +13687,12 @@ fn zirShl(
1368213687 };
1368313688 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
1368413689 .gt => {
13685 if (air_tag != .shl_sat and try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {
13686 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13690 if (air_tag != .shl_sat) {
13691 var rhs_elem_space: Value.BigIntSpace = undefined;
13692 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13693 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13694 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
13695 }
1368713696 }
1368813697 any_positive = true;
1368913698 },
......@@ -13713,29 +13722,29 @@ fn zirShl(
1371313722 }
1371413723 break :rs rhs_src;
1371513724 };
13716 const rt_rhs = switch (air_tag) {
13725 const rt_rhs: Air.Inst.Ref = switch (air_tag) {
1371713726 else => unreachable,
1371813727 .shl, .shl_exact => rhs,
1371913728 // The backend can handle a large runtime rhs better than we can, but
1372013729 // we can limit a large comptime rhs better here. This also has the
1372113730 // necessary side effect of preventing rhs from being a `comptime_int`.
13722 .shl_sat => if (maybe_rhs_val) |rhs_val| Air.internedToRef(rt_rhs: {
13731 .shl_sat => if (maybe_rhs_val) |rhs_val| .fromValue(rt_rhs: {
1372313732 const bit_count = scalar_ty.intInfo(zcu).bits;
1372413733 const rt_rhs_scalar_ty = try pt.smallestUnsignedInt(bit_count);
13725 if (!rhs_ty.isVector(zcu)) break :rt_rhs (try pt.intValue(
13734 if (!rhs_ty.isVector(zcu)) break :rt_rhs try pt.intValue(
1372613735 rt_rhs_scalar_ty,
1372713736 @min(try rhs_val.getUnsignedIntSema(pt) orelse bit_count, bit_count),
13728 )).toIntern();
13737 );
1372913738 const rhs_len = rhs_ty.vectorLen(zcu);
1373013739 const rhs_elems = try sema.arena.alloc(InternPool.Index, rhs_len);
1373113740 for (rhs_elems, 0..) |*rhs_elem, i| rhs_elem.* = (try pt.intValue(
1373213741 rt_rhs_scalar_ty,
1373313742 @min(try (try rhs_val.elemValue(pt, i)).getUnsignedIntSema(pt) orelse bit_count, bit_count),
1373413743 )).toIntern();
13735 break :rt_rhs (try pt.aggregateValue(try pt.vectorType(.{
13744 break :rt_rhs try pt.aggregateValue(try pt.vectorType(.{
1373613745 .len = rhs_len,
1373713746 .child = rt_rhs_scalar_ty.toIntern(),
13738 }), rhs_elems)).toIntern();
13747 }), rhs_elems);
1373913748 }) else rhs,
1374013749 };
1374113750
......@@ -13760,7 +13769,7 @@ fn zirShl(
1376013769 const op_ov = try block.addInst(.{
1376113770 .tag = .shl_with_overflow,
1376213771 .data = .{ .ty_pl = .{
13763 .ty = Air.internedToRef(op_ov_tuple_ty.toIntern()),
13772 .ty = .fromIntern(op_ov_tuple_ty.toIntern()),
1376413773 .payload = try sema.addExtra(Air.Bin{
1376513774 .lhs = lhs,
1376613775 .rhs = rhs,
......@@ -13820,21 +13829,23 @@ fn zirShr(
1382013829 const runtime_src = rs: {
1382113830 if (maybe_rhs_val) |rhs_val| {
1382213831 if (maybe_lhs_val) |lhs_val| {
13823 return Air.internedToRef((try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
13832 return .fromValue(try arith.shr(sema, block, lhs_ty, rhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, switch (air_tag) {
1382413833 .shr => .shr,
1382513834 .shr_exact => .shr_exact,
1382613835 else => unreachable,
13827 })).toIntern());
13836 }));
1382813837 }
1382913838 if (rhs_val.isUndef(zcu)) {
1383013839 return sema.failWithUseOfUndef(block, rhs_src, null);
1383113840 }
13832 const bits_val = try pt.intValue(.comptime_int, scalar_ty.intInfo(zcu).bits);
13841 const bits = scalar_ty.intInfo(zcu).bits;
1383313842 switch (rhs_ty.zigTypeTag(zcu)) {
1383413843 .int, .comptime_int => {
1383513844 switch (try rhs_val.orderAgainstZeroSema(pt)) {
1383613845 .gt => {
13837 if (try rhs_val.compareHeteroSema(.gte, bits_val, pt)) {
13846 var rhs_space: Value.BigIntSpace = undefined;
13847 const rhs_bigint = try rhs_val.toBigIntSema(&rhs_space, pt);
13848 if (rhs_bigint.orderAgainstScalar(bits) != .lt) {
1383813849 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, null);
1383913850 }
1384013851 },
......@@ -13844,16 +13855,17 @@ fn zirShr(
1384413855 },
1384513856 .vector => {
1384613857 var any_positive: bool = false;
13847 var elem_idx: usize = 0;
13848 while (elem_idx < rhs_ty.vectorLen(zcu)) : (elem_idx += 1) {
13858 for (0..rhs_ty.vectorLen(zcu)) |elem_idx| {
1384913859 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1385013860 if (rhs_elem.isUndef(zcu)) {
1385113861 return sema.failWithUseOfUndef(block, rhs_src, elem_idx);
1385213862 }
1385313863 switch (try rhs_elem.orderAgainstZeroSema(pt)) {
1385413864 .gt => {
13855 if (try rhs_elem.compareHeteroSema(.gte, bits_val, pt)) {
13856 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_val, rhs_src, elem_idx);
13865 var rhs_elem_space: Value.BigIntSpace = undefined;
13866 const rhs_elem_bigint = try rhs_elem.toBigIntSema(&rhs_elem_space, pt);
13867 if (rhs_elem_bigint.orderAgainstScalar(bits) != .lt) {
13868 return sema.failWithTooLargeShiftAmount(block, lhs_ty, rhs_elem, rhs_src, elem_idx);
1385713869 }
1385813870 any_positive = true;
1385913871 },
......@@ -22718,7 +22730,6 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2271822730 const pt = sema.pt;
2271922731 const zcu = pt.zcu;
2272022732 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22721 const src = block.nodeOffset(inst_data.src_node);
2272222733 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2272322734 const operand = try sema.resolveInst(inst_data.operand);
2272422735 const operand_ty = sema.typeOf(operand);
......@@ -22733,30 +22744,27 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2273322744 );
2273422745 }
2273522746 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22736 return Air.internedToRef(val.toIntern());
22747 return .fromValue(val);
2273722748 }
2273822749 if (try sema.resolveValue(operand)) |operand_val| {
22739 return Air.internedToRef((try arith.byteSwap(sema, operand_val, operand_ty)).toIntern());
22750 return .fromValue(try arith.byteSwap(sema, operand_val, operand_ty));
2274022751 }
22741 try sema.requireRuntimeBlock(block, src, operand_src);
2274222752 return block.addTyOp(.byte_swap, operand_ty, operand);
2274322753}
2274422754
2274522755fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
2274622756 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].un_node;
22747 const src = block.nodeOffset(inst_data.src_node);
2274822757 const operand_src = block.builtinCallArgSrc(inst_data.src_node, 0);
2274922758 const operand = try sema.resolveInst(inst_data.operand);
2275022759 const operand_ty = sema.typeOf(operand);
2275122760 _ = try sema.checkIntOrVector(block, operand, operand_src);
2275222761
2275322762 if (try sema.typeHasOnePossibleValue(operand_ty)) |val| {
22754 return Air.internedToRef(val.toIntern());
22763 return .fromValue(val);
2275522764 }
2275622765 if (try sema.resolveValue(operand)) |operand_val| {
22757 return Air.internedToRef((try arith.bitReverse(sema, operand_val, operand_ty)).toIntern());
22766 return .fromValue(try arith.bitReverse(sema, operand_val, operand_ty));
2275822767 }
22759 try sema.requireRuntimeBlock(block, src, operand_src);
2276022768 return block.addTyOp(.bit_reverse, operand_ty, operand);
2276122769}
2276222770
src/Sema/arith.zig+14-61
......@@ -319,16 +319,7 @@ pub fn add(
319319 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
320320 result_elem.* = (try addScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
321321 }
322
323 if (is_int) {
324 const result_val = try pt.intern(.{ .aggregate = .{
325 .ty = ty.toIntern(),
326 .storage = .{ .elems = elem_vals },
327 } });
328 return .fromInterned(result_val);
329 } else {
330 return pt.aggregateValue(ty, elem_vals);
331 }
322 return pt.aggregateValue(ty, elem_vals);
332323 },
333324 else => unreachable,
334325 }
......@@ -482,16 +473,7 @@ pub fn sub(
482473 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
483474 result_elem.* = (try subScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
484475 }
485
486 if (is_int) {
487 const result_val = try pt.intern(.{ .aggregate = .{
488 .ty = ty.toIntern(),
489 .storage = .{ .elems = elem_vals },
490 } });
491 return .fromInterned(result_val);
492 } else {
493 return pt.aggregateValue(ty, elem_vals);
494 }
476 return pt.aggregateValue(ty, elem_vals);
495477 },
496478 else => unreachable,
497479 }
......@@ -654,16 +636,7 @@ pub fn mul(
654636 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
655637 result_elem.* = (try mulScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, is_int, elem_idx)).toIntern();
656638 }
657
658 if (is_int) {
659 const result_val = try pt.intern(.{ .aggregate = .{
660 .ty = ty.toIntern(),
661 .storage = .{ .elems = elem_vals },
662 } });
663 return .fromInterned(result_val);
664 } else {
665 return pt.aggregateValue(ty, elem_vals);
666 }
639 return pt.aggregateValue(ty, elem_vals);
667640 },
668641 else => unreachable,
669642 }
......@@ -829,16 +802,7 @@ pub fn div(
829802 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
830803 result_elem.* = (try divScalar(sema, block, elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, is_int, elem_idx)).toIntern();
831804 }
832
833 if (is_int) {
834 const result_val = try pt.intern(.{ .aggregate = .{
835 .ty = ty.toIntern(),
836 .storage = .{ .elems = elem_vals },
837 } });
838 return .fromInterned(result_val);
839 } else {
840 return pt.aggregateValue(ty, elem_vals);
841 }
805 return pt.aggregateValue(ty, elem_vals);
842806 },
843807 else => unreachable,
844808 }
......@@ -998,13 +962,14 @@ pub const ShlOp = enum { shl, shl_sat, shl_exact };
998962
999963/// Applies the `<<` operator to comptime-known values.
1000964/// `lhs_ty` is an int, comptime_int, or vector thereof.
1001/// If it is a vector, he type of `rhs` has to also be a vector of the same length.
965/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
1002966pub fn shl(
1003967 sema: *Sema,
1004968 block: *Block,
1005969 lhs_ty: Type,
1006970 lhs_val: Value,
1007971 rhs_val: Value,
972 src: LazySrcLoc,
1008973 lhs_src: LazySrcLoc,
1009974 rhs_src: LazySrcLoc,
1010975 op: ShlOp,
......@@ -1012,7 +977,7 @@ pub fn shl(
1012977 const pt = sema.pt;
1013978 const zcu = pt.zcu;
1014979 switch (lhs_ty.zigTypeTag(zcu)) {
1015 .int, .comptime_int => return shlScalar(sema, block, lhs_ty, lhs_val, rhs_val, lhs_src, rhs_src, op, null),
980 .int, .comptime_int => return shlScalar(sema, block, lhs_ty, lhs_val, rhs_val, src, lhs_src, rhs_src, op, null),
1016981 .vector => {
1017982 const lhs_elem_ty = lhs_ty.childType(zcu);
1018983 const len = lhs_ty.vectorLen(zcu);
......@@ -1021,22 +986,15 @@ pub fn shl(
1021986 for (elem_vals, 0..) |*result_elem, elem_idx| {
1022987 const lhs_elem = try lhs_val.elemValue(pt, elem_idx);
1023988 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
1024 result_elem.* = (try shlScalar(sema, block, lhs_elem_ty, lhs_elem, rhs_elem, lhs_src, rhs_src, op, elem_idx)).toIntern();
1025 }
1026 if (op == .shl_sat) {
1027 return pt.aggregateValue(lhs_ty, elem_vals);
1028 } else {
1029 return .fromInterned(try pt.intern(.{ .aggregate = .{
1030 .ty = lhs_ty.toIntern(),
1031 .storage = .{ .elems = elem_vals },
1032 } }));
989 result_elem.* = (try shlScalar(sema, block, lhs_elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, elem_idx)).toIntern();
1033990 }
991 return pt.aggregateValue(lhs_ty, elem_vals);
1034992 },
1035993 else => unreachable,
1036994 }
1037995}
1038996/// `lhs_ty` is an int, comptime_int, or vector thereof.
1039/// If it is a vector, he type of `rhs` has to also be a vector of the same length.
997/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
1040998pub fn shlWithOverflow(
1041999 sema: *Sema,
10421000 block: *Block,
......@@ -1084,6 +1042,7 @@ fn shlScalar(
10841042 lhs_ty: Type,
10851043 lhs_val: Value,
10861044 rhs_val: Value,
1045 src: LazySrcLoc,
10871046 lhs_src: LazySrcLoc,
10881047 rhs_src: LazySrcLoc,
10891048 op: ShlOp,
......@@ -1114,7 +1073,7 @@ fn shlScalar(
11141073 .shl_exact => {
11151074 const shifted = try intShlWithOverflow(sema, block, lhs_ty, lhs_val, rhs_val, rhs_src, false, vec_idx);
11161075 if (shifted.overflow) {
1117 return sema.failWithIntegerOverflow(block, lhs_src, lhs_ty, shifted.val, vec_idx);
1076 return sema.failWithIntegerOverflow(block, src, lhs_ty, shifted.val, vec_idx);
11181077 }
11191078 return shifted.val;
11201079 },
......@@ -1164,7 +1123,7 @@ pub const ShrOp = enum { shr, shr_exact };
11641123
11651124/// Applies the `>>` operator to comptime-known values.
11661125/// `lhs_ty` is an int, comptime_int, or vector thereof.
1167/// If it is a vector, he type of `rhs` has to also be a vector of the same length.
1126/// If it is a vector, the type of `rhs` has to also be a vector of the same length.
11681127pub fn shr(
11691128 sema: *Sema,
11701129 block: *Block,
......@@ -1193,13 +1152,7 @@ pub fn shr(
11931152 const rhs_elem = try rhs_val.elemValue(pt, elem_idx);
11941153 result_elem.* = (try shrScalar(sema, block, lhs_elem_ty, rhs_elem_ty, lhs_elem, rhs_elem, src, lhs_src, rhs_src, op, elem_idx)).toIntern();
11951154 }
1196 switch (op) {
1197 .shr => return pt.aggregateValue(lhs_ty, elem_vals),
1198 .shr_exact => return .fromInterned(try pt.intern(.{ .aggregate = .{
1199 .ty = lhs_ty.toIntern(),
1200 .storage = .{ .elems = elem_vals },
1201 } })),
1202 }
1155 return pt.aggregateValue(lhs_ty, elem_vals);
12031156 },
12041157 else => unreachable,
12051158 }
src/Zcu/PerThread.zig+1-1
......@@ -3675,7 +3675,7 @@ pub fn unionValue(pt: Zcu.PerThread, union_ty: Type, tag: Value, val: Value) All
36753675pub fn aggregateValue(pt: Zcu.PerThread, ty: Type, elems: []const InternPool.Index) Allocator.Error!Value {
36763676 for (elems) |elem| {
36773677 if (!Value.fromInterned(elem).isUndef(pt.zcu)) break;
3678 } else { // all-undef
3678 } else if (elems.len > 0) { // all-undef
36793679 return pt.undefValue(ty);
36803680 }
36813681 return .fromInterned(try pt.intern(.{ .aggregate = .{
test/cases/compile_errors/shift_by_larger_than_usize.zig-1
......@@ -4,7 +4,6 @@ export fn f() usize {
44}
55
66// error
7// backend=stage2,llvm
87// target=x86_64-linux
98//
109// :2:30: error: this implementation only supports comptime shift amounts of up to 2^64 - 1 bits
test/cases/compile_errors/shlExact_shifts_out_1_bits.zig+1-1
......@@ -7,4 +7,4 @@ comptime {
77// backend=stage2
88// target=native
99//
10// :2:25: error: overflow of integer type 'u8' with value '340'
10// :2:15: error: overflow of integer type 'u8' with value '340'